develooper Front page | perl.cvs.parrot | Postings from December 2008

[svn:parrot] r34471 - trunk/compilers/pirc/new

From:
kjs
Date:
December 28, 2008 01:53
Subject:
[svn:parrot] r34471 - trunk/compilers/pirc/new
Message ID:
20081228095335.3CB07CB9B0@x12.develooper.com
Author: kjs
Date: Sun Dec 28 01:53:33 2008
New Revision: 34471

Modified:
   trunk/compilers/pirc/new/pircompiler.h
   trunk/compilers/pirc/new/pircompunit.c

Log:
[pirc] refactoring of conversion function for invocation object to instruction sequences.
+ layout stuff.

Modified: trunk/compilers/pirc/new/pircompiler.h
==============================================================================
--- trunk/compilers/pirc/new/pircompiler.h	(original)
+++ trunk/compilers/pirc/new/pircompiler.h	Sun Dec 28 01:53:33 2008
@@ -37,7 +37,7 @@
     LEXER_FLAG_NOOUTPUT            = 1 << 6, /* don't print anything on success, except 'ok' */
     LEXER_FLAG_REGALLOC            = 1 << 7, /* use register allocation optimizer */
     LEXER_FLAG_PASMFILE            = 1 << 8, /* the input is PASM, not PIR code */
-    LEXER_FLAG_OUTPUTPBC         = 1 << 9  /* generate PBC file */
+    LEXER_FLAG_OUTPUTPBC           = 1 << 9  /* generate PBC file */
 
 } lexer_flags;
 
@@ -80,6 +80,7 @@
 #endif
 
 /* macros can store up to 4K characters, after which the buffer must be resized.
+ * This value is the default, and can be changed through PIRC's command line option.
  */
 #define INIT_MACRO_SIZE     4096
 
@@ -148,7 +149,7 @@
 } lexer_state;
 
 /* accessor for current macro; always first on the list. */
-#define CURRENT_MACRO(X)    X->macros->definitions
+#define CURRENT_MACRO(X)    (X)->macros->definitions
 
 
 /* constructor for a lexer_state object */

Modified: trunk/compilers/pirc/new/pircompunit.c
==============================================================================
--- trunk/compilers/pirc/new/pircompunit.c	(original)
+++ trunk/compilers/pirc/new/pircompunit.c	Sun Dec 28 01:53:33 2008
@@ -259,15 +259,13 @@
 */
 void
 new_subr(lexer_state * const lexer, char const * const subname) {
-    subroutine *newsub  = pir_mem_allocate_zeroed_typed(lexer, subroutine);
-    int index;
+    subroutine *newsub       = pir_mem_allocate_zeroed_typed(lexer, subroutine);
+    int         index;
 
     /* set the sub fields */
     newsub->info.subname     = subname;
-
     /* set default lexid */
     newsub->info.subid       = subname;
-
     /* take namespace of this sub of the lexer, which keeps track of that */
     newsub->name_space       = lexer->current_ns;
 
@@ -276,6 +274,7 @@
     newsub->flags            = 0;
     newsub->info.startoffset = lexer->codesize; /* start offset in bytecode */
 
+    /* initialize hashtables for .local and label identifiers */
     init_hashtable(lexer, &newsub->symbols, HASHTABLE_SIZE_INIT);
     init_hashtable(lexer, &newsub->labels, HASHTABLE_SIZE_INIT);
 
@@ -290,8 +289,8 @@
     }
     else { /* there is at least 1 other subroutine */
         /* lexer->subs points to "end of list", to the last added one */
-        newsub->next             = CURRENT_SUB(lexer)->next; /* set newsub's next to the
-                                                                first item in the list */
+        newsub->next = CURRENT_SUB(lexer)->next; /* set newsub's next to the
+                                                    first item in the list */
         CURRENT_SUB(lexer)->next = newsub;    /* set current sub's next to the new sub. */
     }
     CURRENT_SUB(lexer) = newsub;
@@ -302,7 +301,6 @@
     /* vanilla register allocator is reset for each sub */
     reset_register_allocator(lexer);
 
-
 }
 
 /*
@@ -2104,6 +2102,158 @@
 
 /*
 
+=item C<static void
+convert_pcc_call(lexer_state * const lexer, invocation * const inv)>
+
+Generate instructions for a normal invocation using the Parrot Calling
+Conventions (PCC). This is the sequence of the following instructions:
+
+For $P0():
+
+ set_args_pc
+ get_results_pc
+ invokecc_p / invoke_p_p
+
+For "foo"() and foo():
+
+ set_args_pc
+ get_results_pc
+ set_p_pc / find_sub_not_null_p_sc
+ invokecc_p
+
+=cut
+
+*/
+static void
+convert_pcc_call(lexer_state * const lexer, invocation * const inv) {
+    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
+    arguments_to_operands(lexer, inv->arguments);
+
+    new_sub_instr(lexer, PARROT_OP_get_results_pc, "get_results_pc");
+    targets_to_operands(lexer, inv->results);
+
+    /* if the target is a register, invoke that. */
+    if (TEST_FLAG(inv->sub->flags, TARGET_FLAG_IS_REG)) {
+        target *sub = new_reg(lexer, PMC_TYPE, inv->sub->info->color);
+
+        if (inv->retcc) { /* return continuation present? */
+            new_sub_instr(lexer, PARROT_OP_invoke_p_p, "invoke_p_p");
+            add_operands(lexer, "%T%T", inv->sub, inv->retcc);
+        }
+        else {
+            new_sub_instr(lexer, PARROT_OP_invokecc_p, "invokecc_p");
+            add_operands(lexer, "%T", sub);
+        }
+    }
+    else { /* find the global label in the current file, or find it during runtime */
+        target *sub        = generate_unique_pir_reg(lexer, PMC_TYPE);
+        global_label *glob = find_global_label(lexer, inv->sub->info->id.name);
+
+        if (glob) {
+            new_sub_instr(lexer, PARROT_OP_set_p_pc, "set_p_pc");
+            add_operands(lexer, "%T%i", sub, 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");
+
+            add_operands(lexer, "%T%s", sub, inv->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), inv->sub->info->id.name);
+        }
+
+        new_sub_instr(lexer, PARROT_OP_invokecc_p, "invokecc_p");
+        add_operands(lexer, "%T", sub);
+
+    }
+}
+
+/*
+
+=item C<static void
+convert_pcc_return(lexer_state * const lexer, invocation * const inv)>
+
+Generate instructions for a normal return statement using the Parrot Calling
+Conventions (PCC). The sequence of instructions is:
+
+ set_returns_pc
+ returncc
+
+=cut
+
+*/
+static void
+convert_pcc_return(lexer_state * const lexer, invocation * const inv) {
+    new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc");
+    arguments_to_operands(lexer, inv->arguments);
+    new_sub_instr(lexer, PARROT_OP_returncc, "returncc");
+}
+
+static void
+convert_nci_call(lexer_state * const lexer, invocation * const inv) {
+    set_instr(lexer, "invokecc_p");
+}
+
+static void
+convert_pcc_yield(lexer_state * const lexer, invocation * const inv) {
+    new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc");
+    arguments_to_operands(lexer, inv->arguments);
+
+    new_sub_instr(lexer, PARROT_OP_yield, "yield");
+}
+
+static void
+convert_pcc_tailcall(lexer_state * const lexer, invocation * const inv) {
+    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
+    arguments_to_operands(lexer, inv->arguments);
+
+    new_sub_instr(lexer, PARROT_OP_tailcall_p, "tailcall_pc");
+}
+
+static void
+convert_pcc_methodcall(lexer_state * const lexer, invocation * const inv) {
+    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
+    arguments_to_operands(lexer, inv->arguments);
+    /* in a methodcall, the invocant object is passed as the first argument */
+    unshift_operand(lexer, expr_from_target(lexer, inv->sub));
+
+    new_sub_instr(lexer, PARROT_OP_get_results_pc, "get_results_pc");
+    targets_to_operands(lexer, inv->results);
+
+    new_sub_instr(lexer, PARROT_OP_callmethodcc_p_sc, "callmethodcc_p_sc");
+    add_operands(lexer, "%T%E", inv->sub, inv->method);
+}
+
+static void
+convert_pcc_methodtailcall(lexer_state * const lexer, invocation * const inv) {
+    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
+    arguments_to_operands(lexer, inv->arguments);
+
+    /* check out the type of the method expression; it may be a PMC or a STRING. */
+    if (inv->method->type == EXPR_TARGET)
+        new_sub_instr(lexer, PARROT_OP_tailcallmethod_p_p, "tailcallmethod_p_p");
+    else if (inv->method->type == EXPR_CONSTANT)
+        new_sub_instr(lexer, PARROT_OP_tailcallmethod_p_p, "tailcallmethod_p_sc");
+    else
+        panic(lexer, "unknown expression type in tailcallmethod instruction");
+
+}
+
+/*
+
 =item C<void
 convert_inv_to_instr(lexer_state * const lexer, invocation * const inv)>
 
@@ -2116,108 +2266,25 @@
 convert_inv_to_instr(lexer_state * const lexer, invocation * const inv) {
     switch (inv->type) {
         case CALL_PCC:
-            new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
-            arguments_to_operands(lexer, inv->arguments);
-
-            new_sub_instr(lexer, PARROT_OP_get_results_pc, "get_results_pc");
-            targets_to_operands(lexer, inv->results);
-
-            /* if the target is a register, invoke that. */
-            if (TEST_FLAG(inv->sub->flags, TARGET_FLAG_IS_REG)) {
-                target *sub = new_reg(lexer, PMC_TYPE, inv->sub->info->color);
-                if (inv->retcc) { /* return continuation present? */
-                    new_sub_instr(lexer, PARROT_OP_invoke_p_p, "invoke_p_p");
-                    add_operands(lexer, "%T%T", inv->sub, inv->retcc);
-                }
-                else {
-                    new_sub_instr(lexer, PARROT_OP_invokecc_p, "invokecc_p");
-                    add_operands(lexer, "%T", sub);
-                }
-            }
-            else { /* find the global label in the current file, or find it during runtime */
-                target *sub        = generate_unique_pir_reg(lexer, PMC_TYPE);
-                global_label *glob = find_global_label(lexer, inv->sub->info->id.name);
-
-                if (glob) {
-                    new_sub_instr(lexer, PARROT_OP_set_p_pc, "set_p_pc");
-                    add_operands(lexer, "%T%i", sub, 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");
-
-                    add_operands(lexer, "%T%s", sub, inv->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),
-                                          inv->sub->info->id.name);
-                }
-
-                new_sub_instr(lexer, PARROT_OP_invokecc_p, "invokecc_p");
-                add_operands(lexer, "%T", sub);
-
-            }
+            convert_pcc_call(lexer, inv);
             break;
         case CALL_RETURN:
-            new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc");
-            arguments_to_operands(lexer, inv->arguments);
-
-            new_sub_instr(lexer, PARROT_OP_returncc, "returncc");
+            convert_pcc_return(lexer, inv);
             break;
         case CALL_NCI:
-            set_instr(lexer, "invokecc_p");
+            convert_nci_call(lexer, inv);
             break;
         case CALL_YIELD:
-            new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc");
-            arguments_to_operands(lexer, inv->arguments);
-
-            new_sub_instr(lexer, PARROT_OP_yield, "yield");
+            convert_pcc_yield(lexer, inv);
             break;
         case CALL_TAILCALL:
-            new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
-            arguments_to_operands(lexer, inv->arguments);
-
-            new_sub_instr(lexer, PARROT_OP_tailcall_p, "tailcall_pc");
+            convert_pcc_tailcall(lexer, inv);
             break;
         case CALL_METHOD:
-            new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
-            arguments_to_operands(lexer, inv->arguments);
-            /* in a methodcall, the invocant object is passed as the first argument */
-            unshift_operand(lexer, expr_from_target(lexer, inv->sub));
-
-            new_sub_instr(lexer, PARROT_OP_get_results_pc, "get_results_pc");
-            targets_to_operands(lexer, inv->results);
-
-            new_sub_instr(lexer, PARROT_OP_callmethodcc_p_sc, "callmethodcc_p_sc");
-            add_operands(lexer, "%T%E", inv->sub, inv->method);
-
+            convert_pcc_methodcall(lexer, inv);
             break;
         case CALL_METHOD_TAILCALL:
-            new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
-            arguments_to_operands(lexer, inv->arguments);
-
-            /* check out the type of the method expression; it may be a PMC or a STRING. */
-            if (inv->method->type == EXPR_TARGET)
-                new_sub_instr(lexer, PARROT_OP_tailcallmethod_p_p, "tailcallmethod_p_p");
-            else if (inv->method->type == EXPR_CONSTANT)
-                new_sub_instr(lexer, PARROT_OP_tailcallmethod_p_p, "tailcallmethod_p_sc");
-            else
-                panic(lexer, "unknown expression type in tailcallmethod instruction");
-
+            convert_pcc_methodtailcall(lexer, inv);
             break;
         default:
             panic(lexer, "Unknown invocation type in convert_inv_to_instr()");



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