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

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

From:
kjs
Date:
December 28, 2008 05:40
Subject:
[svn:parrot] r34487 - trunk/compilers/pirc/new
Message ID:
20081228133954.757EACB9F9@x12.develooper.com
Author: kjs
Date: Sun Dec 28 05:39:53 2008
New Revision: 34487

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

Log:
[pirc] work on parameter passing bytecode.

Modified: trunk/compilers/pirc/new/bcgen.c
==============================================================================
--- trunk/compilers/pirc/new/bcgen.c	(original)
+++ trunk/compilers/pirc/new/bcgen.c	Sun Dec 28 05:39:53 2008
@@ -202,6 +202,26 @@
 
 /*
 
+=item C<PMC *
+get_pmc_const(bytecode * const bc, unsigned index)>
+
+Get the PMC constant at index C<index> in the PBC constant table.
+
+=cut
+
+*/
+PMC *
+get_pmc_const(bytecode * const bc, unsigned index) {
+    /* make sure the requested PMC exists. */
+    PARROT_ASSERT(index < bc->interp->code->const_table->const_count);
+    /* make sure the requested constant is a PMC */
+    PARROT_ASSERT(bc->interp->code->const_table->constants[index]->type == PFC_PMC);
+
+    return bc->interp->code->const_table->constants[index]->u.key;
+}
+
+/*
+
 =item C<bytecode *
 new_bytecode(Interp *interp, char const * const filename)>
 

Modified: trunk/compilers/pirc/new/bcgen.h
==============================================================================
--- trunk/compilers/pirc/new/bcgen.h	(original)
+++ trunk/compilers/pirc/new/bcgen.h	Sun Dec 28 05:39:53 2008
@@ -66,6 +66,8 @@
 
 int add_pmc_const(bytecode * const bc, PMC * pmc) ;
 
+PMC *get_pmc_const(bytecode * const bc, unsigned index);
+
 /* for adding constants */
 
 /* returns the id in the constant table */

Modified: trunk/compilers/pirc/new/pircompunit.c
==============================================================================
--- trunk/compilers/pirc/new/pircompunit.c	(original)
+++ trunk/compilers/pirc/new/pircompunit.c	Sun Dec 28 05:39:53 2008
@@ -1883,8 +1883,28 @@
 
 }
 
+/*
+
+=item C<static pir_type
+get_expression_pirtype(expression * const expr)>
 
+Get the PIR type of the expression C<expr>.
 
+=cut
+
+*/
+static pir_type
+get_expression_pirtype(expression * const expr) {
+    switch (expr->type) {
+        case EXPR_TARGET:
+            return expr->expr.t->info->type;
+        case EXPR_CONSTANT:
+            return expr->expr.c->type;
+        default:
+            PARROT_ASSERT(0); /* should never happen */
+            return UNKNOWN_TYPE;
+    }
+}
 /*
 
 =item C<static void
@@ -1901,6 +1921,8 @@
 arguments_to_operands(lexer_state * const lexer, argument * const args, unsigned num_arguments) {
     argument *argiter;
     int       array_index;
+    unsigned  i;
+    PMC      *signature_array;
 
     /* create a FixedIntegerArray object as first argument, which encodes
      * the number of arguments and their flags.
@@ -1909,97 +1931,39 @@
     /* add the index (of the signature PMC) in the PBC constant table as operand */
     push_operand(lexer, expr_from_const(lexer, new_const(lexer, INT_TYPE, array_index)));
 
-    return; /* XXX just handle no-args calls/returns for now */
-
-
-{   /* XXXXXXXXX */
+    fprintf(stderr, "args2ops: %u arguments\n", num_arguments);
 
-    /* XXX in compilers/imcc/pcc.c there's a maximum number of 15 values;
-     * do the same here to Get Things To Work, but fix later.
-     */
-
-    int flags_arg[15];
-    int index         = 0;
-    int forindex      = 0;
-    int len;
-    char *flagsstring, *strwriter;
-
-    if (args == NULL) {
-        push_operand(lexer, expr_from_const(lexer, new_const(lexer, PMC_TYPE, "")));
+    /* no need to continue if there's no arguments */
+    if (num_arguments == 0)
         return;
-    }
-    else {
-
-        argiter = args;
-        do {
-            int flag = 0;
-            expression *argvalue;
-
-            argiter  = argiter->next;
-            argvalue = argiter->value;
-            /*
-            fprintf(stderr, "converting arg to operand %d\n", ++numargs);
-            */
-
-
-            switch (argvalue->type) {
-                case EXPR_TARGET:
-                    flag |= argvalue->expr.t->info->type;
-                    break;
-                case EXPR_CONSTANT:
-                    flag |= argvalue->expr.c->type;
-                    break;
-                default:
-                    yypirerror(lexer->yyscanner, lexer, "invalid expression type for argument");
-                    break;
-            }
-            /* store the flag for this argument */
-            flags_arg[index++] = flag;
-        }
-        while (argiter != args);
 
-        /* allocate space for each flag, + commas (index - 1) and 2 quotes */
-        strwriter = flagsstring = (char *)mem_sys_allocate((index + index - 1 + 2) * sizeof (char));
-        *strwriter++ = '"';
+    /* retrieve the signature array PMC */
+    signature_array = get_pmc_const(lexer->bc, array_index);
 
-        while (forindex < index) {
-            sprintf(strwriter++, "%d", flags_arg[forindex]);
+    fprintf(stderr, "signature array has size: %d\n",
+            VTABLE_get_integer(lexer->interp, signature_array));
 
-            if (forindex < index - 1) {
-                *strwriter++ = ',';
-            }
-
-            ++forindex;
-        }
-        /* write closing quote and NULL character */
-        *strwriter++ = '"';
-        *strwriter++ = '\0';
 
-        /*
-        fprintf(stderr, "args2operands: [%s]\n", flagsstring);
-        */
+    /* initialize the argument iterator for the loop */
+    argiter = args->next;
 
-        /* don't add it now, it will break tests. */
-        /*
-        push_operand(lexer, expr_from_const(lexer, new_const(lexer, STRING_TYPE, flagsstring)));
-        */
+    for (i = 0; i < num_arguments; ++i) {
+        int flag = 0;
+        /* calculate the right flags for the current argument */
+        SET_FLAG(flag, get_expression_pirtype(argiter->value));
 
+        fprintf(stderr, "Setting flag %d on argument %u\n", flag, i);
 
-        /* XXX Yes, this is a hacky attempt. Cleanups will follow. */
-    }
-
+        /* set the flags for this argument in the right position in the array */
+        VTABLE_set_integer_keyed_int(lexer->interp, signature_array, i, flag);
 
-    /* go over the arguments again, and add them as operands */
-    argiter = args;
+        /* and add the current argument as an operand; operands are always expression nodes. */
+        push_operand(lexer, argiter->value);
 
-    do {
         argiter = argiter->next;
-        /* how to handle named args? */
-        push_operand(lexer, argiter->value);
     }
-    while (argiter != args);
 
-} /* XXXXXXXXX */
+    fprintf(stderr, "args2ops done\n");
 
 }
 
@@ -2017,30 +1981,34 @@
 */
 static void
 targets_to_operands(lexer_state * const lexer, target * const targets, unsigned num_targets) {
-    target *iter;
+    target  *iter;
+    int      array_index;
+    PMC     *signature_array;
+    unsigned i;
 
-    int  array_index = generate_signature_pmc(lexer, num_targets);
+    array_index = generate_signature_pmc(lexer, num_targets);
     push_operand(lexer, expr_from_const(lexer, new_const(lexer, INT_TYPE, array_index)));
-    return; /* XXX just handle no-args calls/returns for now */
 
+    if (num_targets == 0)
+        return;
 
-{ /* XXXXXXXXX */
+    signature_array = get_pmc_const(lexer->bc, array_index);
 
-    if (targets == NULL) {
-        push_operand(lexer, expr_from_const(lexer, new_const(lexer, PMC_TYPE, "")));
-        return;
-    }
+    iter = targets->next;
 
-    iter = targets;
+    for (i = 0; i < num_targets; ++i) {
+        int flag = 0;
+
+        SET_FLAG(flag, iter->info->type);
+
+        VTABLE_set_integer_keyed_int(lexer->interp, signature_array, i, flag);
+
+        push_operand(lexer, expr_from_const(lexer, new_const(lexer, INT_TYPE, iter->info->color)));
 
-    do {
         iter = iter->next;
-        push_operand(lexer, expr_from_target(lexer, iter));
     }
-    while (iter != targets);
 
 }
-}
 
 
 /*
@@ -2068,7 +2036,8 @@
 /*
 
 =item C<static void
-new_sub_instr(lexer_state * const lexer, int opcode, char * const opname)>
+new_sub_instr(lexer_state * const lexer, int opcode, char const * const opname,
+              unsigned num_var_args)>
 
 Create a new instruction node, and initialize the opcode and opinfo on that
 node. This function can be used to create an instruction of which the signature
@@ -2076,22 +2045,28 @@
 This is useful for generating special subroutine instructions, such as
 C<get_params_pc> etc.
 
+The parameter C<num_var_args> passes the number of variable arguments (if any)
+that C<opcode> has.
+
 =cut
 
 */
 static void
-new_sub_instr(lexer_state * const lexer, int opcode, char const * const opname, ...) {
+new_sub_instr(lexer_state * const lexer, int opcode, char const * const opname,
+              unsigned num_var_args)
+
+{
     new_statement(lexer, opname);
     CURRENT_INSTRUCTION(lexer)->opinfo = &lexer->interp->op_info_table[opcode];
     CURRENT_INSTRUCTION(lexer)->opcode = opcode;
 
-    /* XXX how to calculate size of var-arg ops? that's 1 for the op,
-    1 for the fixed integer array, and n for the variable number of arguments.
-    So, 2 + n, where n is the number of arguments.
-    */
+    /* The size of a var-arg op (get_params, etc.) is 1 for the op,
+     * 1 for the fixed integer array, and n for the variable number of arguments.
+     * So, 2 + n, where n is the number of arguments.
+     */
 
     /* count number of ints needed to store this instruction in bytecode */
-    lexer->codesize += CURRENT_INSTRUCTION(lexer)->opinfo->op_count /* + "number of args" */;
+    lexer->codesize += CURRENT_INSTRUCTION(lexer)->opinfo->op_count + num_var_args;
 }
 
 /*
@@ -2129,7 +2104,8 @@
 /*
 
 =item C<static void
-save_global_reference(lexer_state * const lexer, instruction *instr, char * const label)>
+save_global_reference(lexer_state * const lexer, instruction * const instr,
+                      char const * const label)>
 
 Store the instruction C<instr>, which references the global label C<label> in a list.
 After the parse phase, this instruction can be patched, if C<label> can be resolved
@@ -2139,7 +2115,10 @@
 
 */
 static void
-save_global_reference(lexer_state * const lexer, instruction * const instr, char const * const label) {
+save_global_reference(lexer_state * const lexer, instruction * const instr,
+                      char const * const label)
+
+{
     global_fixup *ref = pir_mem_allocate_zeroed_typed(lexer, global_fixup);
 
     ref->instr = instr;
@@ -2176,10 +2155,10 @@
 */
 static void
 convert_pcc_call(lexer_state * const lexer, invocation * const inv) {
-    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
+    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc", inv->num_arguments);
     arguments_to_operands(lexer, inv->arguments, inv->num_arguments);
 
-    new_sub_instr(lexer, PARROT_OP_get_results_pc, "get_results_pc");
+    new_sub_instr(lexer, PARROT_OP_get_results_pc, "get_results_pc", inv->num_results);
     targets_to_operands(lexer, inv->results, inv->num_results);
 
     /* if the target is a register, invoke that. */
@@ -2187,11 +2166,11 @@
         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");
+            new_sub_instr(lexer, PARROT_OP_invoke_p_p, "invoke_p_p", 0);
             add_operands(lexer, "%T%T", inv->sub, inv->retcc);
         }
         else {
-            new_sub_instr(lexer, PARROT_OP_invokecc_p, "invokecc_p");
+            new_sub_instr(lexer, PARROT_OP_invokecc_p, "invokecc_p", 0);
             add_operands(lexer, "%T", sub);
         }
     }
@@ -2200,11 +2179,11 @@
         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");
+            new_sub_instr(lexer, PARROT_OP_set_p_pc, "set_p_pc", 0);
             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");
+            new_sub_instr(lexer, PARROT_OP_find_sub_not_null_p_sc, "find_sub_not_null_p_sc", 0);
 
             add_operands(lexer, "%T%s", sub, inv->sub->info->id.name);
 
@@ -2225,7 +2204,7 @@
             save_global_reference(lexer, CURRENT_INSTRUCTION(lexer), inv->sub->info->id.name);
         }
 
-        new_sub_instr(lexer, PARROT_OP_invokecc_p, "invokecc_p");
+        new_sub_instr(lexer, PARROT_OP_invokecc_p, "invokecc_p", 0);
         add_operands(lexer, "%T", sub);
 
     }
@@ -2247,9 +2226,9 @@
 */
 static void
 convert_pcc_return(lexer_state * const lexer, invocation * const inv) {
-    new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc");
+    new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc", inv->num_arguments);
     arguments_to_operands(lexer, inv->arguments, inv->num_arguments);
-    new_sub_instr(lexer, PARROT_OP_returncc, "returncc");
+    new_sub_instr(lexer, PARROT_OP_returncc, "returncc", 0);
 }
 
 /*
@@ -2288,10 +2267,10 @@
 */
 static void
 convert_pcc_yield(lexer_state * const lexer, invocation * const inv) {
-    new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc");
+    new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc", inv->num_arguments);
     arguments_to_operands(lexer, inv->arguments, inv->num_arguments);
 
-    new_sub_instr(lexer, PARROT_OP_yield, "yield");
+    new_sub_instr(lexer, PARROT_OP_yield, "yield", 0);
 }
 
 /*
@@ -2310,10 +2289,10 @@
 */
 static void
 convert_pcc_tailcall(lexer_state * const lexer, invocation * const inv) {
-    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
+    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc", inv->num_arguments);
     arguments_to_operands(lexer, inv->arguments, inv->num_arguments);
 
-    new_sub_instr(lexer, PARROT_OP_tailcall_p, "tailcall_pc");
+    new_sub_instr(lexer, PARROT_OP_tailcall_p, "tailcall_pc", 0);
 }
 
 /*
@@ -2333,15 +2312,15 @@
 */
 static void
 convert_pcc_methodcall(lexer_state * const lexer, invocation * const inv) {
-    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
+    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc", inv->num_arguments);
     arguments_to_operands(lexer, inv->arguments, inv->num_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");
+    new_sub_instr(lexer, PARROT_OP_get_results_pc, "get_results_pc", inv->num_results);
     targets_to_operands(lexer, inv->results, inv->num_results);
 
-    new_sub_instr(lexer, PARROT_OP_callmethodcc_p_sc, "callmethodcc_p_sc");
+    new_sub_instr(lexer, PARROT_OP_callmethodcc_p_sc, "callmethodcc_p_sc", 0);
     add_operands(lexer, "%T%E", inv->sub, inv->method);
 }
 
@@ -2361,14 +2340,14 @@
 */
 static void
 convert_pcc_methodtailcall(lexer_state * const lexer, invocation * const inv) {
-    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc");
+    new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc", inv->num_arguments);
     arguments_to_operands(lexer, inv->arguments, inv->num_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");
+        new_sub_instr(lexer, PARROT_OP_tailcallmethod_p_p, "tailcallmethod_p_p", 0);
     else if (inv->method->type == EXPR_CONSTANT)
-        new_sub_instr(lexer, PARROT_OP_tailcallmethod_p_p, "tailcallmethod_p_sc");
+        new_sub_instr(lexer, PARROT_OP_tailcallmethod_p_p, "tailcallmethod_p_sc", 0);
     else
         panic(lexer, "unknown expression type in tailcallmethod instruction");
 
@@ -2582,14 +2561,14 @@
      *    returncc
      */
     if (TEST_FLAG(lexer->subs->flags, SUB_FLAG_MAIN))
-        new_sub_instr(lexer, PARROT_OP_end, "end");
+        new_sub_instr(lexer, PARROT_OP_end, "end", 0);
     else {
         /* default sub epilogue; no return values, hence 0 */
         int array_index = generate_signature_pmc(lexer, 0);
-        new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc");
+        new_sub_instr(lexer, PARROT_OP_set_returns_pc, "set_returns_pc", 0);
         push_operand(lexer, expr_from_const(lexer, new_const(lexer, INT_TYPE, array_index)));
 
-        new_sub_instr(lexer, PARROT_OP_returncc, "returncc");
+        new_sub_instr(lexer, PARROT_OP_returncc, "returncc", 0);
     }
 }
 



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