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

[svn:parrot] r32569 - in branches/calling_conventions: include/parrot src

From:
allison
Date:
November 11, 2008 22:59
Subject:
[svn:parrot] r32569 - in branches/calling_conventions: include/parrot src
Message ID:
20081112065836.88D7CCB9AF@x12.develooper.com
Author: allison
Date: Tue Nov 11 22:58:34 2008
New Revision: 32569

Modified:
   branches/calling_conventions/include/parrot/inter_call.h
   branches/calling_conventions/include/parrot/multidispatch.h
   branches/calling_conventions/src/inter_call.c
   branches/calling_conventions/src/multidispatch.c

Log:
[calling_conventions] Standardize parameter processing so the invocant is
handled while iterating through the paramters, rather than being a special
case.


Modified: branches/calling_conventions/include/parrot/inter_call.h
==============================================================================
--- branches/calling_conventions/include/parrot/inter_call.h	(original)
+++ branches/calling_conventions/include/parrot/inter_call.h	Tue Nov 11 22:58:34 2008
@@ -184,15 +184,6 @@
         __attribute__nonnull__(3);
 
 PARROT_API
-void Parrot_pcc_invoke_from_sig_object(PARROT_INTERP,
-    ARGIN(PMC *obj),
-    ARGIN(PMC *sub_obj),
-    ARGIN(PMC *sig_obj))
-        __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3);
-
-PARROT_API
 void Parrot_PCCINVOKE(PARROT_INTERP,
     ARGIN(PMC* pmc),
     ARGMOD(STRING *method_name),
@@ -229,6 +220,13 @@
         __attribute__nonnull__(4)
         FUNC_MODIFIES(*dest);
 
+void Parrot_pcc_invoke_from_sig_object(PARROT_INTERP,
+    ARGIN(PMC *sub_obj),
+    ARGIN(PMC *sig_obj))
+        __attribute__nonnull__(1)
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
+
 PARROT_WARN_UNUSED_RESULT
 PARROT_CAN_RETURN_NULL
 void * set_retval(PARROT_INTERP, int sig_ret, ARGIN(Parrot_Context *ctx))

Modified: branches/calling_conventions/include/parrot/multidispatch.h
==============================================================================
--- branches/calling_conventions/include/parrot/multidispatch.h	(original)
+++ branches/calling_conventions/include/parrot/multidispatch.h	Tue Nov 11 22:58:34 2008
@@ -70,22 +70,22 @@
 PARROT_API
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-PMC* Parrot_build_sig_object_from_varargs2(PARROT_INTERP,
-    ARGIN(PMC* obj),
+PMC* Parrot_build_sig_object_from_varargs(PARROT_INTERP,
     ARGIN(const char *sig),
     va_list args)
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2)
-        __attribute__nonnull__(3);
+        __attribute__nonnull__(2);
 
 PARROT_API
 PARROT_WARN_UNUSED_RESULT
 PARROT_CANNOT_RETURN_NULL
-PMC* Parrot_build_sig_object_from_varargs(PARROT_INTERP,
+PMC* Parrot_build_sig_object_from_varargs2(PARROT_INTERP,
+    ARGIN(PMC* obj),
     ARGIN(const char *sig),
     va_list args)
         __attribute__nonnull__(1)
-        __attribute__nonnull__(2);
+        __attribute__nonnull__(2)
+        __attribute__nonnull__(3);
 
 PARROT_API
 void Parrot_mmd_add_by_class(PARROT_INTERP,

Modified: branches/calling_conventions/src/inter_call.c
==============================================================================
--- branches/calling_conventions/src/inter_call.c	(original)
+++ branches/calling_conventions/src/inter_call.c	Tue Nov 11 22:58:34 2008
@@ -70,7 +70,6 @@
     ARGIN(PMC * const *sigs),
     ARGMOD(opcode_t **indexes),
     ARGMOD(Parrot_Context *ctx),
-    ARGIN(PMC* obj),
     ARGIN(PMC *sig_obj))
         __attribute__nonnull__(1)
         __attribute__nonnull__(4)
@@ -78,7 +77,6 @@
         __attribute__nonnull__(7)
         __attribute__nonnull__(8)
         __attribute__nonnull__(9)
-        __attribute__nonnull__(10)
         FUNC_MODIFIES(*n_regs_used)
         FUNC_MODIFIES(*indexes)
         FUNC_MODIFIES(*ctx);
@@ -103,11 +101,12 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*st);
 
+PARROT_CANNOT_RETURN_NULL
 static Parrot_Context * count_signature_elements(PARROT_INTERP,
     ARGIN(const char *signature),
     ARGMOD(PMC *args_sig),
     ARGMOD(PMC *results_sig),
-    int flag)
+    int old_pcc_invoke_flag)
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
         __attribute__nonnull__(3)
@@ -147,13 +146,13 @@
         __attribute__nonnull__(2)
         FUNC_MODIFIES(*st);
 
+PARROT_CANNOT_RETURN_NULL
 static const char * set_context_sig_params(PARROT_INTERP,
     ARGIN(const char *signature),
     ARGMOD(INTVAL *n_regs_used),
     ARGMOD(PMC **sigs),
     ARGMOD(opcode_t **indexes),
     ARGMOD(Parrot_Context *ctx),
-    ARGMOD(PMC* obj),
     ARGMOD(PMC *sig_obj))
         __attribute__nonnull__(1)
         __attribute__nonnull__(2)
@@ -162,12 +161,10 @@
         __attribute__nonnull__(5)
         __attribute__nonnull__(6)
         __attribute__nonnull__(7)
-        __attribute__nonnull__(8)
         FUNC_MODIFIES(*n_regs_used)
         FUNC_MODIFIES(*sigs)
         FUNC_MODIFIES(*indexes)
         FUNC_MODIFIES(*ctx)
-        FUNC_MODIFIES(* obj)
         FUNC_MODIFIES(*sig_obj);
 
 static void set_context_sig_returns(PARROT_INTERP,
@@ -1939,9 +1936,10 @@
 
 */
 
+PARROT_CANNOT_RETURN_NULL
 static Parrot_Context *
 count_signature_elements(PARROT_INTERP, ARGIN(const char *signature),
-    ARGMOD(PMC *args_sig), ARGMOD(PMC *results_sig), int flag)
+    ARGMOD(PMC *args_sig), ARGMOD(PMC *results_sig), int old_pcc_invoke_flag)
 {
     const char  *x;
     unsigned int seen_arrow  = 0;
@@ -1956,12 +1954,15 @@
     /* # of args, # of results */
     int arg_ret_cnt[2]       = { 0, 0 };
 
-    /* Increment these values if we are invoking a method on an object */
-    if (flag) {
+    /* Increment these values if we are invoking a method on an object. Delete
+     * this check and the corresponding parameter when the old Parrot_PCCINVOKE
+     * goes away. */
+    if (old_pcc_invoke_flag) {
         arg_ret_cnt[seen_arrow]++;
         max_regs[REGNO_PMC]++;
     }
 
+
     /* Loop through the signature string to count the number of each
        type of object required. We need to know so we can allocate
        an appropriate number of registers for it. */
@@ -1974,7 +1975,7 @@
                 if (*x != '>')
                     Parrot_ex_throw_from_c_args(interp, NULL,
                         EXCEPTION_INVALID_OPERATION,
-                        "PCCINVOKE: invalid signature separator %c!",
+                        "PCCINVOKE: invalid signature separator -%c!",
                         *x);
                 break;
             case 'I':
@@ -1991,7 +1992,16 @@
                 break;
             case 'P':
                 arg_ret_cnt[seen_arrow]++;
-                max_regs[seen_arrow * 4 + REGNO_PMC]++;
+                {
+                    /* Lookahead to see if PMC is marked as invocant */
+                    if (*(++x) == 'i') {
+                        max_regs[REGNO_PMC]++;
+                    }
+                    else {
+                        x--; /* Undo lookahead */
+                        max_regs[seen_arrow * 4 + REGNO_PMC]++;
+                    }
+                }
                 break;
             case 'f':
             case 'n':
@@ -2038,20 +2048,10 @@
 commit_last_arg_sig_object(PARROT_INTERP, int index, int cur,
     ARGMOD(opcode_t *n_regs_used), int seen_arrow, ARGIN(PMC * const *sigs),
     ARGMOD(opcode_t **indexes), ARGMOD(Parrot_Context *ctx),
-    ARGIN(PMC* obj), ARGIN(PMC *sig_obj))
+    ARGIN(PMC *sig_obj))
 {
     int reg_offset = 0;
 
-    /* If we're in the args part of the signature, and if we have an invocant,
-       we need to increment our indexes by one to account for the additional
-       parameter */
-    const int has_invocant = (!seen_arrow && obj && !PMC_IS_NULL(obj))?(1):(0);
-
-    /* If we're calling a method and this is the first parameter, it's the
-       object so we can safely return. */
-    /* if (seen_arrow == 0 && index == 0 && !PMC_IS_NULL(obj))
-        return; */
-
     /* calculate arg's register offset */
     switch (cur & PARROT_ARG_TYPE_MASK) { /* calc reg offset */
         case PARROT_ARG_INTVAL:
@@ -2061,14 +2061,30 @@
         case PARROT_ARG_STRING:
             reg_offset = n_regs_used[seen_arrow * 4 + REGNO_STR]++; break;
         case PARROT_ARG_PMC :
-            reg_offset = n_regs_used[seen_arrow * 4 + REGNO_PMC]++; break;
+            {
+                if (cur & PARROT_ARG_INVOCANT) {
+                    if (seen_arrow == 0 && index == 0) {
+                        n_regs_used[REGNO_PMC]++;
+                        reg_offset = 0;
+                    }
+                    else {
+                        Parrot_ex_throw_from_c_args(interp, NULL,
+                                EXCEPTION_INVALID_OPERATION,
+                                "Parrot_pcc_invoke: Only the first parameter can be an invocant %d, %d", seen_arrow, index);
+                    }
+                }
+                else {
+                    reg_offset = n_regs_used[seen_arrow * 4 + REGNO_PMC]++;
+                }
+            }
+            break;
         default:
             Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                 "Parrot_PCCINVOKE: invalid reg type");
     }
 
     /* set the register offset into the index int[] */
-    indexes[seen_arrow][index + has_invocant] = reg_offset;
+    indexes[seen_arrow][index] = reg_offset;
 
     /* set the PARROT_ARG_FLAGS into the signature FIA */
     VTABLE_set_integer_keyed_int(interp, sigs[seen_arrow], index, cur);
@@ -2078,16 +2094,19 @@
     if (!seen_arrow) {
         switch (cur & PARROT_ARG_TYPE_MASK) {
             case PARROT_ARG_INTVAL:
-                CTX_REG_INT(ctx, reg_offset) = VTABLE_get_integer_keyed_int(interp, sig_obj, index + has_invocant);
+                CTX_REG_INT(ctx, reg_offset) = VTABLE_get_integer_keyed_int(interp, sig_obj, index);
                 break;
             case PARROT_ARG_FLOATVAL:
-                CTX_REG_NUM(ctx, reg_offset) = VTABLE_get_number_keyed_int(interp, sig_obj, index + has_invocant);
+                CTX_REG_NUM(ctx, reg_offset) = VTABLE_get_number_keyed_int(interp, sig_obj, index);
                 break;
             case PARROT_ARG_STRING:
-                CTX_REG_STR(ctx, reg_offset) = VTABLE_get_string_keyed_int(interp, sig_obj, index + has_invocant);
+                CTX_REG_STR(ctx, reg_offset) = VTABLE_get_string_keyed_int(interp, sig_obj, index);
                 break;
             case PARROT_ARG_PMC:
-                CTX_REG_PMC(ctx, reg_offset) = VTABLE_get_pmc_keyed_int(interp, sig_obj, index + has_invocant);
+                CTX_REG_PMC(ctx, reg_offset) = VTABLE_get_pmc_keyed_int(interp, sig_obj, index);
+                if (cur & PARROT_ARG_INVOCANT) {
+                    interp->current_object = CTX_REG_PMC(ctx, reg_offset);
+                }
                 break;
             default:
                 Parrot_ex_throw_from_c_args(interp, NULL,
@@ -2241,11 +2260,12 @@
 
 */
 
+PARROT_CANNOT_RETURN_NULL
 static const char *
 set_context_sig_params(PARROT_INTERP, ARGIN(const char *signature),
     ARGMOD(INTVAL *n_regs_used), ARGMOD(PMC **sigs),
     ARGMOD(opcode_t **indexes), ARGMOD(Parrot_Context *ctx),
-    ARGMOD(PMC* obj), ARGMOD(PMC *sig_obj))
+    ARGMOD(PMC *sig_obj))
 {
     /* second loop through signature to build all index and arg_flag
      * loop also assigns args(up to the ->) to registers */
@@ -2271,7 +2291,7 @@
 
             if (index >= 0)
                 commit_last_arg_sig_object(interp, index, cur, n_regs_used,
-                    seen_arrow, sigs, indexes, ctx, obj, sig_obj);
+                    seen_arrow, sigs, indexes, ctx, sig_obj);
 
             /* reset parsing state so we can now handle results */
             seen_arrow =  1;
@@ -2287,7 +2307,7 @@
         else if (isupper((unsigned char)*x)) {
             if (index >= 0)
                 commit_last_arg_sig_object(interp, index, cur, n_regs_used, seen_arrow,
-                    sigs, indexes, ctx, obj, sig_obj);
+                    sigs, indexes, ctx, sig_obj);
 
             index++;
 
@@ -2322,7 +2342,7 @@
 
     if (index >= 0)
         commit_last_arg_sig_object(interp, index, cur, n_regs_used, seen_arrow, sigs,
-            indexes, ctx, obj, sig_obj);
+            indexes, ctx, sig_obj);
 
     interp->current_args   = indexes[0];
     interp->args_signature = sigs[0];
@@ -2354,7 +2374,7 @@
     sig_obj = Parrot_build_sig_object_from_varargs(interp, sig, args);
     va_end(args);
 
-    Parrot_pcc_invoke_from_sig_object(interp, PMCNULL, sub_obj, sig_obj);
+    Parrot_pcc_invoke_from_sig_object(interp, sub_obj, sig_obj);
     dod_unregister_pmc(interp, sig_obj);
 }
 
@@ -2419,7 +2439,6 @@
 Parrot_PCCINVOKE(PARROT_INTERP, ARGIN(PMC* pmc), ARGMOD(STRING *method_name),
         ARGIN(const char *signature), ...)
 {
-
 /* Set this flag to 1 if we are using the "new" unified version of this
    function. The new version breaks the build and all sorts of tests,
    so turn it off when you're done with it. */
@@ -2447,7 +2466,7 @@
             "Method '%Ss' not found", method_name);
 
     /* Invoke the subroutine object with the given CallSignature object */
-    Parrot_pcc_invoke_from_sig_object(interp, pmc, sub_obj, sig_obj);
+    Parrot_pcc_invoke_from_sig_object(interp, sub_obj, sig_obj);
     dod_unregister_pmc(interp, sig_obj);
 
 #else
@@ -2620,21 +2639,17 @@
 
 /*
 
-=item C<static void Parrot_pcc_invoke_from_sig_object>
+=item C<void Parrot_pcc_invoke_from_sig_object>
 
-Handles the actual function call. Takes a PMC object (for method calls, can
-be C<PMCNULL> if this isn't a method call), a sub object, and a sig object
+Handles the actual function call. Takes a sub object, and a sig object
 to make the function call.
 
-Eventually, all calls to Parrot_PCCINVOKE (and maybe a few others) will
-all be converted to be calls to this function directly.
-
 =cut
 
 */
 
 void
-Parrot_pcc_invoke_from_sig_object(PARROT_INTERP, ARGIN(PMC* obj), ARGIN(PMC *sub_obj),
+Parrot_pcc_invoke_from_sig_object(PARROT_INTERP, ARGIN(PMC *sub_obj),
         ARGIN(PMC *sig_obj))
 {
 #define PCC_ARG_MAX 1024
@@ -2673,15 +2688,6 @@
     const char *ret_x  = NULL;
     int         index  = -1;
     int         cur    = 0;
-    int   has_invocant = 0;
-
-    /* Just make sure, we don't want to have to check for both NULL
-       and PMCNULL throughout the entire function, so we will force
-       everything to be PMCNULL */
-    if (obj == NULL)
-        obj = PMCNULL;
-    if (!PMC_IS_NULL(obj))
-        has_invocant = 1;
 
     indexes[0] = arg_indexes;
     indexes[1] = result_indexes;
@@ -2689,28 +2695,9 @@
     sigs[1]    = results_sig;
 
     /* Count the number of objects of each type that need to be allocated by
-       the caller to perform this function call. The final argument is a
-       flag to determine whether we're making an ordinary subroutine call
-       or a method call. */
-    ctx = count_signature_elements(interp, signature, args_sig, results_sig,
-        has_invocant);
-
-    /* This section here is a little bit of a hack, and I'm not sure it's
-       doing all it should be doing and doing things it shouldn't be */
-    if (has_invocant) {
-        PARROT_ASSERT(obj == VTABLE_get_pmc_keyed_int(interp, sig_obj, 0));
-        indexes[0][0] = 0; /* Not sure what this does, exactly */
-
-        /* set the first argument value to a PMC, since we're passing a
-           PMC invocant as the first parameter. */
-        VTABLE_set_integer_keyed_int(interp, sigs[0], 0, PARROT_ARG_PMC);
+       the caller to perform this function call. */
+    ctx = count_signature_elements(interp, signature, args_sig, results_sig, 0);
 
-        /* Add the invocant to the context as the first parameter. */
-        CTX_REG_PMC(ctx, 0) = obj;
-
-        /* Count the invocant as a register that's used. */
-        n_regs_used[REGNO_PMC]++;
-    }
 
     /* code from PCCINVOKE impl in PCCMETHOD.pm */
     /* Save the current values of the interpreter arguments so that additional
@@ -2719,13 +2706,16 @@
     save_args_signature    = interp->args_signature;
     save_current_object    = interp->current_object;
 
+    /* Method calls will reset this to the invocant inside
+     * 'set_context_sig_params'. */
+    interp->current_object = PMCNULL;
+
     /* Set the function input parameters in the context structure, and return the
        offset in the signature where the return params start. */
     ret_x = set_context_sig_params(interp, signature, n_regs_used, sigs,
-        indexes, ctx, obj, sig_obj);
+        indexes, ctx, sig_obj);
 
-    /* Set up the context object for the function invokation */
-    interp->current_object       = obj;
+    /* Set up the context object for the function invocation */
     interp->current_cont         = NEED_CONTINUATION;
     ctx->current_cont            = ret_cont;
     PMC_cont(ret_cont)->from_ctx = ctx;
@@ -2734,8 +2724,9 @@
     /* Invoke the function */
     dest = VTABLE_invoke(interp, sub_obj, NULL);
 
-    /* PIR Subs need runops to run their opcodes. */
-    if (!has_invocant && sub_obj->vtable->base_type == enum_class_Sub) {
+    /* PIR Subs not invoked as methods  need runops to run their opcodes. */
+    if (sub_obj->vtable->base_type == enum_class_Sub
+            && PMC_IS_NULL(interp->current_object)) {
         /* can't re-enter the runloop from here with CGP: RT #60048 */
         INTVAL old_core  = interp->run_core;
         opcode_t offset  = dest - interp->code->base.data;

Modified: branches/calling_conventions/src/multidispatch.c
==============================================================================
--- branches/calling_conventions/src/multidispatch.c	(original)
+++ branches/calling_conventions/src/multidispatch.c	Tue Nov 11 22:58:34 2008
@@ -577,7 +577,6 @@
     INTVAL  sig_len          = strlen(sig);
     STRING *s_sig            = string_from_cstring(interp, sig, sig_len);
     STRING *string_sig       = NULL;
-    INTVAL  has_invocant     = 0;
 
     /* Protect call signature object from collection. */
     dod_register_pmc(interp, call_object);
@@ -591,24 +590,13 @@
         STRING *invocant_sig = CONST_STRING(interp, "Pi");
         string_sig = string_concat(interp, invocant_sig, s_sig, 0);
         sig_len = sig_len + 2;
-        has_invocant = 1;
     }
 
-    /* Create an extra item on the array, in case we need to store the
-       invocant. I don't know if the length of this array is going
-       to be some kind of factor later or not. */
-    VTABLE_set_integer_native(interp, type_tuple, sig_len + 1);
+    VTABLE_set_integer_native(interp, type_tuple, sig_len);
     VTABLE_set_pmc(interp, call_object, type_tuple);
 
     VTABLE_set_string_native(interp, call_object, string_sig);
 
-    /* if we have a valid invocant, push it on here. */
-    if (has_invocant) {
-        VTABLE_set_integer_keyed_int(interp, type_tuple, 0,
-            VTABLE_type(interp, obj));
-        VTABLE_push_pmc(interp, call_object, obj);
-    }
-
     for (i = 0; i < sig_len; ++i) {
         INTVAL type = string_index(interp, string_sig, i);
 
@@ -659,36 +647,41 @@
                 case 'I':
                     VTABLE_push_integer(interp, call_object, va_arg(args, INTVAL));
                     VTABLE_set_integer_keyed_int(interp, type_tuple,
-                            i + has_invocant, enum_type_INTVAL);
+                            i, enum_type_INTVAL);
                     break;
                 case 'N':
                     VTABLE_push_float(interp, call_object, va_arg(args, FLOATVAL));
                     VTABLE_set_integer_keyed_int(interp, type_tuple,
-                            i + has_invocant, enum_type_FLOATVAL);
+                            i, enum_type_FLOATVAL);
                     break;
                 case 'S':
                     VTABLE_push_string(interp, call_object, va_arg(args, STRING *));
                     VTABLE_set_integer_keyed_int(interp, type_tuple,
-                            i + has_invocant, enum_type_STRING);
+                            i, enum_type_STRING);
                     break;
                 case 'P':
                 {
-                    PMC *pmc_arg = va_arg(args, PMC *);
-                    if (!PMC_IS_NULL(pmc_arg))
-                        VTABLE_set_integer_keyed_int(interp, type_tuple,
-                            i + has_invocant, VTABLE_type(interp, pmc_arg));
+                    INTVAL type_lookahead = string_index(interp, string_sig, (i + 1));
+                    if (type_lookahead == 'i') {
+                        if (i != 0)
+                            Parrot_ex_throw_from_c_args(interp, NULL,
+                                EXCEPTION_INVALID_OPERATION,
+                                "Multiple Dispatch: 'i' adverb modifier may only be used on the invocant");
+                        VTABLE_set_integer_keyed_int(interp, type_tuple, 0,
+                                VTABLE_type(interp, obj));
+                        VTABLE_push_pmc(interp, call_object, obj);
+                        i++; /* skip the 'i' modifier */
+                    }
+                    else {
+                        PMC *pmc_arg = va_arg(args, PMC *);
+                        if (!PMC_IS_NULL(pmc_arg))
+                            VTABLE_set_integer_keyed_int(interp, type_tuple,
+                                i, VTABLE_type(interp, pmc_arg));
 
-                    VTABLE_push_pmc(interp, call_object, pmc_arg);
+                        VTABLE_push_pmc(interp, call_object, pmc_arg);
+                    }
                     break;
                 }
-                case 'i':
-                    if (i != 1)
-                        Parrot_ex_throw_from_c_args(interp, NULL,
-                            EXCEPTION_INVALID_OPERATION,
-                            "Multiple Dispatch: 'i' adverb modifier may only be used on the invocant");
-                    /* I don't think we need to do any additional
-                       processing here. */
-                    break;
                 case '-':
                     i++; /* skip '>' */
                     in_return_sig = 1;
@@ -746,7 +739,7 @@
             string_to_cstring(interp, VTABLE_name(interp, sub)));
 #endif
 
-    Parrot_pcc_invoke_from_sig_object(interp, PMCNULL, sub, sig_object);
+    Parrot_pcc_invoke_from_sig_object(interp, sub, sig_object);
     dod_unregister_pmc(interp, sig_object);
 }
 



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