develooper Front page | perl.cvs.parrot | Postings from January 2009

[svn:parrot] r35045 - trunk/compilers/pirc/src

From:
kjs
Date:
January 6, 2009 08:21
Subject:
[svn:parrot] r35045 - trunk/compilers/pirc/src
Message ID:
20090106162143.1E2FBCB9F9@x12.develooper.com
Author: kjs
Date: Tue Jan  6 08:21:42 2009
New Revision: 35045

Modified:
   trunk/compilers/pirc/src/pirpcc.c
   trunk/compilers/pirc/src/pirsymbol.c

Log:
[pirc] improve handling of different cases for invoking a .sub: .local, global_label and find-during-runtime options. (Too complex for a commit message, but it fixes some innocent bugs).

Modified: trunk/compilers/pirc/src/pirpcc.c
==============================================================================
--- trunk/compilers/pirc/src/pirpcc.c	(original)
+++ trunk/compilers/pirc/src/pirpcc.c	Tue Jan  6 08:21:42 2009
@@ -125,6 +125,7 @@
 */
 static target *
 generate_unique_pir_reg(lexer_state * const lexer, pir_type type) {
+    fprintf(stderr, "unique reg of type %d: %d\n", type, lexer->pir_reg_generator - 1);
     return new_reg(lexer, type, --lexer->pir_reg_generator);
 }
 
@@ -395,48 +396,66 @@
 =item C<static target *
 get_invoked_sub(lexer_state * const lexer, target * const sub)>
 
+Return a C<target> node that represents the sub to invoke.
+If C<sub> is a register, that is returned. If it's a declared C<.local>,
+then a target node representing that symbol is returned. If it's
+just the name of a .sub, then there's 2 possibilities: either the
+sub was already parsed, in which case it's stored as a global_label,
+or the sub was not parsed yet, in which case a runtime resolving
+instruction is emitted.
+
 =cut
 
 */
 static target *
 get_invoked_sub(lexer_state * const lexer, target * const sub) {
-    target *subreg = NULL;
+    target       *subreg = NULL;
+    symbol       *sym    = NULL;
+    global_label *glob   = NULL;
 
     /* if the target is a register, invoke that. */
-    if (TEST_FLAG(sub->flags, TARGET_FLAG_IS_REG)) {
-        subreg = new_reg(lexer, PMC_TYPE, sub->info->color);
-    }
-    else { /* find the global label in the current file, or find it during runtime */
-        global_label *glob = find_global_label(lexer, sub->info->id.name);
-        subreg             = generate_unique_pir_reg(lexer, PMC_TYPE);
-
-        if (glob) {
-            new_sub_instr(lexer, PARROT_OP_set_p_pc, "set_p_pc", 0);
-            add_operands(lexer, "%T%i", subreg, glob->const_table_index);
-        }
-        else { /* find it during runtime (hopefully, otherwise exception) */
-            new_sub_instr(lexer, PARROT_OP_find_sub_not_null_p_sc, "find_sub_not_null_p_sc", 0);
+    if (TEST_FLAG(sub->flags, TARGET_FLAG_IS_REG))
+        return sub;
 
-            add_operands(lexer, "%T%s", subreg, sub->info->id.name);
 
-            /* save the current instruction in a list; entries in this list will be
-             * fixed up, if possible, after the parsing phase.
-             *
-             * Instead of the instruction
-             *
-             *   set_p_pc
-             *
-             * that is generated when the global label C<glob> was found (see above),
-             * another instructions is generated. After the parse, we'll re-try
-             * to find the global label that is referenced. For now, just generate
-             * this instruction to do the resolving of the label during runtime:
-             *
-             *   find_sub_not_null_p_sc
-             */
-            save_global_reference(lexer, CURRENT_INSTRUCTION(lexer), sub->info->id.name);
-        }
+    /* find the global label in the current file, or find it during runtime */
+    sym  = find_symbol(lexer, sub->info->id.name);
+
+    /* if the invoked object was declared as a .local, return that */
+    if (sym)
+        return target_from_symbol(lexer, sym);
 
+    /* it was not a .local, so check whether it's a declared .sub */
+    glob   = find_global_label(lexer, sub->info->id.name);
+    subreg = generate_unique_pir_reg(lexer, PMC_TYPE);
+
+    if (glob) {
+        new_sub_instr(lexer, PARROT_OP_set_p_pc, "set_p_pc", 0);
+        add_operands(lexer, "%T%i", subreg, glob->const_table_index);
+        return subreg;
     }
+
+    /* find it during runtime (hopefully, otherwise exception) */
+    new_sub_instr(lexer, PARROT_OP_find_sub_not_null_p_sc, "find_sub_not_null_p_sc", 0);
+
+    add_operands(lexer, "%T%s", subreg, sub->info->id.name);
+
+    /* save the current instruction in a list; entries in this list will be
+     * fixed up, if possible, after the parsing phase.
+     *
+     * Instead of the instruction
+     *
+     *   set_p_pc
+     *
+     * that is generated when the global label C<glob> was found (see above),
+     * another instructions is generated. After the parse, we'll re-try
+     * to find the global label that is referenced. For now, just generate
+     * this instruction to do the resolving of the label during runtime:
+     *
+     *   find_sub_not_null_p_sc
+     */
+    save_global_reference(lexer, CURRENT_INSTRUCTION(lexer), sub->info->id.name);
+
     return subreg;
 
 }

Modified: trunk/compilers/pirc/src/pirsymbol.c
==============================================================================
--- trunk/compilers/pirc/src/pirsymbol.c	(original)
+++ trunk/compilers/pirc/src/pirsymbol.c	Tue Jan  6 08:21:42 2009
@@ -95,6 +95,7 @@
 static int
 next_register(NOTNULL(lexer_state * const lexer), pir_type type) {
     CURRENT_SUB(lexer)->info.regs_used[type]++; /* count number of registers used */
+    /* fprintf(stderr, "vanilla reg: %d of type %d\n", lexer->curregister[type], type); */
     return lexer->curregister[type]++;
 }
 
@@ -112,6 +113,9 @@
 void
 assign_vanilla_register(NOTNULL(lexer_state * const lexer), symbol * const sym) {
     sym->info.color    = next_register(lexer, sym->info.type);
+    /* fprintf(stderr, "assigning vanilla reg %d to symbol %s\n", sym->info.color,
+                    sym->info.id.name);
+    */
 
     if (TEST_FLAG(lexer->flags, LEXER_FLAG_REGALLOC)) {
         sym->info.interval = new_live_interval(lexer->lsr, lexer->stmt_counter, sym->info.type);
@@ -257,7 +261,7 @@
             bucket_symbol(b) = iter;
             store_bucket(table, b, hash);
             iter->info.type  = type;
-            fprintf(stderr, "declare_local(): [%s]\n", iter->info.id.name);
+            /* fprintf(stderr, "declare_local(): [%s]\n", iter->info.id.name); */
         }
 
         iter = iter->next;
@@ -333,9 +337,10 @@
 
         if (STREQ(sym->info.id.name, name)) {
 
-            if (sym->info.color == NO_REG_ALLOCATED)  /* no PASM register assigned yet */
+            if (sym->info.color == NO_REG_ALLOCATED) { /* no PASM register assigned yet */
                 /* get a new reg from vanilla reg. allocator */
                 assign_vanilla_register(lexer, sym);
+            }
             else  /* update end point of interval */
                 if (TEST_FLAG(lexer->flags, LEXER_FLAG_REGALLOC)) {
                     sym->info.interval->endpoint = lexer->stmt_counter;
@@ -535,7 +540,9 @@
          * a new PASM register through the vanilla reg. allocator and
          * store the register as "used".
          */
-        return use_register(lexer, type, regno, next_register(lexer, type));
+        int nextreg = next_register(lexer, type);
+        fprintf(stderr, "mapping reg %d to %d\n", regno, nextreg);
+        return use_register(lexer, type, regno, nextreg);
     }
 }
 



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About