Author: tewk
Date: Sat Jan  6 12:17:44 2007
New Revision: 16438

Modified:
   trunk/include/parrot/enums.h
   trunk/include/parrot/inter_call.h
   trunk/include/parrot/sub.h
   trunk/src/inter_call.c

Log:
inter_call.c refactor


Modified: trunk/include/parrot/enums.h
==============================================================================
--- trunk/include/parrot/enums.h        (original)
+++ trunk/include/parrot/enums.h        Sat Jan  6 12:17:44 2007
@@ -68,6 +68,19 @@
 
 /* &end_gen */
 
+#define PARROT_ARG_INTVAL_ISSET(o)        (o & PARROT_ARG_INTVAL)
+#define PARROT_ARG_STRING_ISSET(o)        (o & PARROT_ARG_STRING)
+#define PARROT_ARG_PMC_ISSET(o)           (o & PARROT_ARG_PMC)
+#define PARROT_ARG_FLOATVAL_ISSET(o)      (o & PARROT_ARG_FLOATVAL)
+#define PARROT_ARG_TYPE_MASK_MASK(o)      (o & PARROT_ARG_TYPE_MASK)
+#define PARROT_ARG_CONSTANT_ISSET(o)      (o & PARROT_ARG_CONSTANT)
+#define PARROT_ARG_FLATTEN_ISSET(o)       (o & PARROT_ARG_FLATTEN)
+#define PARROT_ARG_SLURPY_ARRAY_ISSET(o)  (o & PARROT_ARG_SLURPY_ARRAY)
+#define PARROT_ARG_OPTIONAL_ISSET(o)      (o & PARROT_ARG_OPTIONAL)
+#define PARROT_ARG_OPT_FLAG_ISSET(o)      (o & PARROT_ARG_OPT_FLAG)
+#define PARROT_ARG_NAME_ISSET(o)          (o & PARROT_ARG_NAME)
+
+
 #endif /* PARROT_ENUMS_H_GUARD */
 
 /*

Modified: trunk/include/parrot/inter_call.h
==============================================================================
--- trunk/include/parrot/inter_call.h   (original)
+++ trunk/include/parrot/inter_call.h   Sat Jan  6 12:17:44 2007
@@ -51,6 +51,27 @@
 
 };
 
+#define CALL_STATE_x_ISSET(o, x) (o & CALL_STATE_ ## x)
+#define CALL_STATE_x_SET(o, x) (o |= CALL_STATE_ ## x)
+#define CALL_STATE_x_UNSET(o, x) (o &= ~CALL_STATE_ ## x)
+
+#define CALL_STATE_MASK_MASK(o)       (CALL_STATE_X_ISSET(o, MASK))
+#define CALL_STATE_SIG_ISSET(o)       (CALL_STATE_X_ISSET(o, SIG))
+#define CALL_STATE_OP_ISSET(o)        (CALL_STATE_X_ISSET(o, OP))
+#define CALL_S_D_MASK_MASK(o)         (o & CALL_S_D_MASK)
+#define CALL_STATE_FLATTEN_ISSET(o)   (CALL_STATE_X_ISSET(o, FLATTEN))
+#define CALL_STATE_NEXT_ARG_ISSET(o)  (CALL_STATE_X_ISSET(o, NEXT_ARG))
+
+#define CALL_STATE_SIG_SET(o)       (CALL_STATE_X_SET(o, SIG))
+#define CALL_STATE_OP_SET(o)        (CALL_STATE_X_SET(o, OP))
+#define CALL_STATE_FLATTEN_SET(o)   (CALL_STATE_X_SET(o, FLATTEN))
+#define CALL_STATE_NEXT_ARG_SET(o)  (CALL_STATE_X_SET(o, NEXT_ARG))
+
+#define CALL_STATE_SIG_UNSET(o)       (CALL_STATE_X_UNSET(o, SIG))
+#define CALL_STATE_OP_UNSET(o)        (CALL_STATE_X_UNSET(o, OP))
+#define CALL_STATE_FLATTEN_UNSET(o)   (CALL_STATE_X_UNSET(o, FLATTEN))
+#define CALL_STATE_NEXT_ARG_UNSET(o)  (CALL_STATE_X_UNSET(o, NEXT_ARG))
+
 struct call_state_item {
     int mode;       /* from_sig, from_set_ops, flatten ...*/
     union {
@@ -107,9 +128,11 @@
 parrot_pass_args_to_result(Interp *interp, const char *sig,
         opcode_t *dest, parrot_context_t * old_ctxp, va_list ap);
 
-FLOATVAL set_retval_f(Interp*, int sig_ret, parrot_context_t *ctx);
 void* set_retval(Interp*, int sig_ret, parrot_context_t *ctx);
 INTVAL set_retval_i(Interp*, int sig_ret, parrot_context_t *ctx);
+FLOATVAL set_retval_f(Interp*, int sig_ret, parrot_context_t *ctx);
+STRING* set_retval_s(Interp*, int sig_ret, parrot_context_t *ctx);
+PMC* set_retval_p(Interp*, int sig_ret, parrot_context_t *ctx);
 
 #define ASSERT_SIG_PMC(sig) \
     assert(PObj_is_PMC_TEST(sig) && \

Modified: trunk/include/parrot/sub.h
==============================================================================
--- trunk/include/parrot/sub.h  (original)
+++ trunk/include/parrot/sub.h  Sat Jan  6 12:17:44 2007
@@ -39,6 +39,21 @@
     SUB_FLAG_PF_MASK      = 0xfa   /* anon ... postcomp, is_outer*/
 } sub_flags_enum;
 
+#define SUB_FLAG_get_FLAGS(o) (PObj_get_FLAGS(o))
+#define SUB_FLAG_flag_TEST(flag, o) (SUB_FLAG_get_FLAGS(o) & SUB_FLAG_ ## flag)
+#define SUB_FLAG_flag_SET(flag, o) (SUB_FLAG_get_FLAGS(o) |= SUB_FLAG_ ## flag)
+#define SUB_FLAG_flag_CLEAR(flag, o) (SUB_FLAG_get_FLAGS(o) &= 
~(UINTVAL)(SUB_FLAG_ ## flag))
+
+#define SUB_FLAG_flags_SETTO(o, f) SUB_FLAG_get_FLAGS(o) = (f)
+#define SUB_FLAG_flags_CLEARALL(o) SUB_FLAG_flags_SETTO(o, 0)
+
+#define SUB_FLAG_TAILCALL_TEST(o) SUB_FLAG_flag_TEST(TAILCALL, o)
+#define SUB_FLAG_TAILCALL_ISSET(o) SUB_FLAG_flag_TEST(TAILCALL, o)
+#define SUB_FLAG_TAILCALL_NOTSET(o) (!SUB_FLAG_flag_TEST(TAILCALL, o))
+#define SUB_FLAG_TAILCALL_SET(o) SUB_FLAG_flag_SET(TAILCALL, o)
+#define SUB_FLAG_TAILCALL_CLEAR(o) SUB_FLAG_flag_CLEAR(TAILCALL, o)
+
+
 typedef enum {
     SUB_COMP_FLAG_BIT_0 = 1 << 0,
     SUB_COMP_FLAG_BIT_1 = 1 << 1,

Modified: trunk/src/inter_call.c
==============================================================================
--- trunk/src/inter_call.c      (original)
+++ trunk/src/inter_call.c      Sat Jan  6 12:17:44 2007
@@ -28,6 +28,9 @@
 
 
 static int next_arg(Interp *, struct call_state_item *st);
+static void next_arg_sig(Interp *interp, struct call_state_item *st);
+static int set_retval_util(Parrot_Interp interp, const char *sig, 
parrot_context_t *ctx,
+        struct call_state *st);
 
 /*
 
@@ -54,19 +57,16 @@
 int
 Parrot_init_ret_nci(Interp *interp, struct call_state *st, const char *sig)
 {
-    PMC *current_cont;
-    struct Parrot_Context *ctx;
+    struct Parrot_Context *ctx = CONTEXT(interp->ctx);
+    PMC *current_cont = ctx->current_cont;
     /*
      * if this NCI call was a taicall, return results to caller's get_results
      * this also means that we pass the caller's register base pointer
      */
-    current_cont = CONTEXT(interp->ctx)->current_cont;
-    if ((PObj_get_FLAGS(current_cont) & SUB_FLAG_TAILCALL)) {
+    if (SUB_FLAG_TAILCALL_ISSET(current_cont)) {
         ctx = PMC_cont(current_cont)->to_ctx;
     }
-    else {
-        ctx = CONTEXT(interp->ctx);
-    }
+
     /* TODO simplify all */
     Parrot_init_arg_sig(interp, CONTEXT(interp->ctx), sig, NULL, &st->src);
     Parrot_init_arg_op(interp, ctx, ctx->current_results, &st->dest);
@@ -117,7 +117,8 @@
         st->n = SIG_ELEMS(sig_pmc);
         /* initialize st->sig */
         if (st->n)
-            st->sig = SIG_ITEM(sig_pmc, 0);
+            next_arg_sig(interp, st);
+
     }
     return st->n > 0;
 }
@@ -134,28 +135,11 @@
 
     if (*sig) {
         st->u.sig.sig = sig;
-        if (ap)
-            st->u.sig.ap = ap;
-        else
-            st->u.sig.ap = NULL;
+        st->u.sig.ap = ap;
         st->n = strlen(sig);
-        if (st->n) {
-            switch (sig[0]) {
-                case 'I':
-                    st->sig = PARROT_ARG_INTVAL; break;
-                case 'N':
-                    st->sig = PARROT_ARG_FLOATVAL; break;
-                case 'S':
-                    st->sig = PARROT_ARG_STRING; break;
-                case 'O':
-                case 'P':
-                    st->sig = PARROT_ARG_PMC; break;
-                case '@':
-                    st->sig = PARROT_ARG_PMC | PARROT_ARG_SLURPY_ARRAY; break;
-                case 'F':
-                    st->sig = PARROT_ARG_PMC | PARROT_ARG_FLATTEN; break;
-            }
-        }
+        /* initialize st->sig */
+        if (st->n)
+          next_arg_sig(interp, st);
     }
     return st->n > 0;
 }
@@ -176,53 +160,6 @@
 }
 
 static void
-fetch_arg_int_op(Interp *interp, struct call_state *st)
-{
-    INTVAL idx;
-
-    idx = st->src.u.op.pc[st->src.i];
-    if (!(st->src.sig & PARROT_ARG_CONSTANT)) {
-        idx = CTX_REG_INT(st->src.ctx, idx);
-    }
-    UVal_int(st->val) = idx;
-    st->src.mode |= CALL_STATE_NEXT_ARG;
-}
-
-static void
-fetch_arg_str_op(Interp *interp, struct call_state *st)
-{
-    INTVAL idx;
-    STRING *s_arg;
-
-    idx = st->src.u.op.pc[st->src.i];
-    if ((st->src.sig & PARROT_ARG_CONSTANT)) {
-        s_arg = st->src.ctx->constants[idx]->u.string;
-    }
-    else {
-        s_arg = CTX_REG_STR(st->src.ctx, idx);
-    }
-    UVal_str(st->val) = s_arg;
-    st->src.mode |= CALL_STATE_NEXT_ARG;
-}
-
-static void
-fetch_arg_num_op(Interp *interp, struct call_state *st)
-{
-    INTVAL idx;
-    FLOATVAL f_arg;
-
-    idx = st->src.u.op.pc[st->src.i];
-    if ((st->src.sig & PARROT_ARG_CONSTANT)) {
-        f_arg = st->src.ctx->constants[idx]->u.number;
-    }
-    else {
-        f_arg = CTX_REG_NUM(st->src.ctx, idx);
-    }
-    UVal_num(st->val) = f_arg;
-    st->src.mode |= CALL_STATE_NEXT_ARG;
-}
-
-static void
 fetch_arg_pmc_op(Interp *interp, struct call_state *st)
 {
     INTVAL idx;
@@ -230,34 +167,30 @@
     STRING *_array, *_hash;
 
     idx = st->src.u.op.pc[st->src.i];
-    if ((st->src.sig & PARROT_ARG_CONSTANT)) {
+    if ((st->src.sig & PARROT_ARG_CONSTANT))
         p_arg = st->src.ctx->constants[idx]->u.key;
-    }
-    else {
+    else
         p_arg = CTX_REG_PMC(st->src.ctx, idx);
-    }
+
     if (st->src.sig & PARROT_ARG_FLATTEN) {
         if (st->src.sig & PARROT_ARG_NAME) {
-            _hash = CONST_STRING(interp, "hash");
-            if (!VTABLE_does(interp, p_arg, _hash)) {
-                /* src ought to be an hash */
-                real_exception(interp, NULL, E_ValueError,
-                        "argument doesn't hash");
+            /* src ought to be an hash */
+            if (!VTABLE_does(interp, p_arg, CONST_STRING(interp, "hash"))) {
+                real_exception(interp, NULL, E_ValueError, "argument doesn't 
hash");
             }
-            st->src.mode |= CALL_STATE_FLATTEN;
-            /* need a key to iterate the hash */
+
+            /* create key needed to iterate the hash */
             st->key = pmc_new(interp, enum_class_Key);
             PMC_int_val(st->key) = 0;
             PMC_data(st->key)    = (void*)INITBucketIndex;
         }
         else {
-            _array = CONST_STRING(interp, "array");
-            if (!VTABLE_does(interp, p_arg, _array)) {
-                /* src ought to be an array */
-                real_exception(interp, NULL, E_ValueError,
-                        "argument doesn't array");
+            /* src ought to be an array */
+            if (!VTABLE_does(interp, p_arg, CONST_STRING(interp, "array"))) {
+                real_exception(interp, NULL, E_ValueError, "argument doesn't 
array");
             }
         }
+
         make_flattened(interp, st, p_arg);
         return;
     }
@@ -307,15 +240,9 @@
     }
 }
 
-static int
-next_arg(Interp *interp, struct call_state_item *st)
+static void
+next_arg_sig(Interp *interp, struct call_state_item *st)
 {
-    st->i++;
-    if (st->i >= st->n) {
-        st->sig = 0;
-        return 0;
-    }
-    st->mode &= ~CALL_STATE_NEXT_ARG;
     switch (st->mode & CALL_S_D_MASK) {
         case CALL_STATE_OP:
             st->sig = SIG_ITEM(st->u.op.signature, st->i);
@@ -338,6 +265,18 @@
             }
             break;
     }
+}
+
+static int
+next_arg(Interp *interp, struct call_state_item *st)
+{
+    st->i++;
+    if (st->i >= st->n) {
+        st->sig = 0;
+        return 0;
+    }
+    st->mode &= ~CALL_STATE_NEXT_ARG;
+    next_arg_sig(interp, st);
     return 1;
 }
 
@@ -373,15 +312,29 @@
 static void
 fetch_arg_op(Interp *interp, struct call_state *st)
 {
-    switch (st->src.sig & PARROT_ARG_TYPE_MASK) {
+    int constant = PARROT_ARG_CONSTANT_ISSET(st->src.sig);
+    INTVAL idx = st->src.u.op.pc[st->src.i];
+
+    switch (PARROT_ARG_TYPE_MASK_MASK(st->src.sig)) {
         case PARROT_ARG_INTVAL:
-            fetch_arg_int_op(interp, st);
+            if (!constant)
+                idx = CTX_REG_INT(st->src.ctx, idx);
+            UVal_int(st->val) = idx;
+            st->src.mode |= CALL_STATE_NEXT_ARG;
             break;
         case PARROT_ARG_STRING:
-            fetch_arg_str_op(interp, st);
+            if (constant)
+                UVal_str(st->val) = st->src.ctx->constants[idx]->u.string;
+            else
+                UVal_str(st->val) = CTX_REG_STR(st->src.ctx, idx);
+            st->src.mode |= CALL_STATE_NEXT_ARG;
             break;
         case PARROT_ARG_FLOATVAL:
-            fetch_arg_num_op(interp, st);
+            if (constant)
+                UVal_num(st->val) = st->src.ctx->constants[idx]->u.number;
+            else
+                UVal_num(st->val) = CTX_REG_NUM(st->src.ctx, idx);
+            st->src.mode |= CALL_STATE_NEXT_ARG;
             break;
         case PARROT_ARG_PMC:
             fetch_arg_pmc_op(interp, st);
@@ -619,18 +572,18 @@
     /* 1) if we were slurpying positional args, we are done, turn it off
      * 2) set destination named args bit */
     st->dest.mode &= ~CALL_STATE_SLURP;
-    st->dest.mode |= CALL_STATE_x_NAMED;
     st->dest.slurp = NULL;
+    st->dest.mode |= CALL_STATE_x_NAMED;
+
     for (i = st->dest.i; i < st->dest.n; ++i) {
         sig = SIG_ITEM(st->dest.u.op.signature, i);
 
         /* skip the actual arg, only count the names of the named args */
         if (!(sig & PARROT_ARG_NAME))
             continue;
-        if (sig & PARROT_ARG_SLURPY_ARRAY) {
-            st->dest.slurp = pmc_new(interp,
-                Parrot_get_ctx_HLL_type(interp,
-                    enum_class_Hash));
+        /* slurpy named args, create slurpy hash */
+        else if (sig & PARROT_ARG_SLURPY_ARRAY) {
+            st->dest.slurp = pmc_new(interp, Parrot_get_ctx_HLL_type(interp, 
enum_class_Hash));
             /* pass the slurpy hash */
             idx = st->dest.u.op.pc[i];
             CTX_REG_PMC(st->dest.ctx, idx) = st->dest.slurp;
@@ -735,8 +688,35 @@
     }
 }
 
+static int
+store_current_arg(Interp *interp, struct call_state *st)
+{
+    INTVAL idx;
+    if (st->dest.i >= st->dest.n)
+        return 0;
+
+    assert(st->dest.mode & CALL_STATE_OP);
+    idx = st->dest.u.op.pc[st->dest.i];
+    assert(idx >= 0);
+    store_arg(st, idx);
+
+    return 1;
+}
+
+int
+Parrot_store_arg(Interp *interp, struct call_state *st)
+{
+    if (!store_current_arg(interp, st))
+        return 0;
+    if (!(st->dest.mode & CALL_STATE_x_NAMED))
+        st->dest.mode |= CALL_STATE_NEXT_ARG;
+    return 1;
+}
+
+
+
 static void
-create_slurpy_ar(Interp *interp, struct call_state *st, INTVAL idx)
+create_slurpy_array(Interp *interp, struct call_state *st, INTVAL idx)
 {
     st->dest.slurp =
         pmc_new(interp, Parrot_get_ctx_HLL_type(interp, 
enum_class_ResizablePMCArray));
@@ -859,7 +839,7 @@
                 /* create dest slurp array */
                 idx = st->dest.u.op.pc[st->dest.i];
                 assert(idx >= 0);
-                create_slurpy_ar(interp, st, idx);
+                create_slurpy_array(interp, st, idx);
                 state = CALL_STATE_POS_POS_SLURP;
             }
             /* positional src -> named src */
@@ -923,47 +903,55 @@
         switch (state) {
             case CALL_STATE_POS_POS:
                 st->dest.mode |= CALL_STATE_NEXT_ARG;
-                /* fall through */
+                Parrot_convert_arg(interp, st);
+                store_current_arg(interp, st);
+                break;
+
             case CALL_STATE_NAMED_NAMED:
             case CALL_STATE_POS_NAMED:
                 Parrot_convert_arg(interp, st);
-                idx = st->dest.u.op.pc[st->dest.i];
-                assert(idx >= 0);
-                store_arg(st, idx);
+                store_current_arg(interp, st);
                 break;
+
             case CALL_STATE_NAMED_NAMED_OPT:
             case CALL_STATE_POS_POS_OPT:
-                ++st->optionals;
-                Parrot_convert_arg(interp, st);
                 opt_flag = 1;
+
               store_opt:
-                idx = st->dest.u.op.pc[st->dest.i];
-                assert(idx >= 0);
-                store_arg(st, idx);
+                ++st->optionals;
+                Parrot_convert_arg(interp, st);
+                store_current_arg(interp, st);
+
                 /* :opt_flag is truely optional */
                 if (!next_arg(interp, &st->dest)) {
-                    if (!(state & CALL_STATE_x_NAMED))
-                        st->dest.mode |= CALL_STATE_x_END;
-                    break;
+                    /* do nothing */
                 }
-                if (!(st->dest.sig & PARROT_ARG_OPT_FLAG)) {
+                else if (!(st->dest.sig & PARROT_ARG_OPT_FLAG)) {
                     st->dest.i--;
-                    if (!(state & CALL_STATE_x_NAMED))
-                        st->dest.mode |= CALL_STATE_NEXT_ARG;
-                    break;
                 }
-                --st->params;
-                idx = st->dest.u.op.pc[st->dest.i];
-                assert(idx >= 0);
-                CTX_REG_INT(st->dest.ctx, idx) = opt_flag;
+                else
+                {
+                    int idx = st->dest.u.op.pc[st->dest.i];
+                    --st->params;
+                    assert(idx >= 0);
+                    CTX_REG_INT(st->dest.ctx, idx) = opt_flag;
+                }
                 if (!(state & CALL_STATE_x_NAMED))
                     st->dest.mode |= CALL_STATE_NEXT_ARG;
                 break;
             case CALL_STATE_END_POS_OPT:
-                ++st->optionals;
                 null_val(st->dest.sig, st);
                 opt_flag = 0;
                 goto store_opt;
+            case CALL_STATE_POS_POS_SLURP:
+                Parrot_convert_arg(interp, st);
+                VTABLE_push_pmc(interp, st->dest.slurp, UVal_pmc(st->val));
+                break;
+            case CALL_STATE_NAMED_NAMED_SLURP:
+                Parrot_convert_arg(interp, st);
+                VTABLE_set_pmc_keyed_str(interp, st->dest.slurp, st->name, 
UVal_pmc(st->val));
+                break;
+
             case CALL_STATE_END_NAMED_NAMED|CALL_STATE_OPT:
             case CALL_STATE_END_NAMED_NAMED:
             case CALL_STATE_END_POS_NAMED:
@@ -981,27 +969,13 @@
                     too_many(interp, st, action);
                 return;
             case CALL_STATE_END_x|CALL_STATE_SLURP:
-                /* this happens when flattening an empty array
-                 * into a slurpy
-                 */
+                /* this happens when flattening an empty array into a slurpy */
                 return;
-            case CALL_STATE_POS_POS_SLURP:
-                Parrot_convert_arg(interp, st);
-                VTABLE_push_pmc(interp, st->dest.slurp,
-                        UVal_pmc(st->val));
-                break;
             case CALL_STATE_NAMED_POS:
             case CALL_STATE_NAMED_POS_OPT:
             case CALL_STATE_NAMED_POS_SLURP:
-                real_exception(interp, NULL, E_ValueError,
-                        "too many named arguments");
-                break;
-            case CALL_STATE_NAMED_NAMED_SLURP:
-                Parrot_convert_arg(interp, st);
-                VTABLE_set_pmc_keyed_str(interp, st->dest.slurp,
-                        st->name, UVal_pmc(st->val));
+                real_exception(interp, NULL, E_ValueError, "too many named 
arguments");
                 break;
-
             case CALL_STATE_NAMED_x|CALL_STATE_x_NAMED|CALL_STATE_x_END:
                 /* XXX: this state doesn't properly reflect what's going on */
                 real_exception(interp, NULL, 0,
@@ -1017,18 +991,33 @@
 void
 Parrot_convert_arg(Interp *interp, struct call_state *st)
 {
+    /* if END OF SRC or DEST ARGS, no need to convert */
+    /*
     if (st->src.i >= st->src.n) {
         return;
     }
     if (st->dest.i >= st->dest.n) {
         return;
     }
+    */
+    /*
+    if ((st->src.i >= st->src.n) || (st->dest.i >= st->dest.n)) {
+        return;
+    }
+    */
+#define END_OF_ARGS(x) (x.i >= x.n )
+    if ((END_OF_ARGS(st->src) || END_OF_ARGS(st->dest)))
+        return;
+
     if ((st->src.sig & PARROT_ARG_TYPE_MASK) == PARROT_ARG_PMC) {
         clone_key_arg(interp, st);
     }
-    if ((st->dest.sig & PARROT_ARG_TYPE_MASK) ==
-        (st->src.sig & PARROT_ARG_TYPE_MASK))
+
+    /* if types are already equivalent, no need to convert */
+    if ((st->dest.sig & PARROT_ARG_TYPE_MASK) == (st->src.sig & 
PARROT_ARG_TYPE_MASK))
         return;
+
+    /* convert */
     switch (st->src.sig & PARROT_ARG_TYPE_MASK) {
         case PARROT_ARG_INTVAL:
             convert_arg_from_int(interp, st);
@@ -1046,35 +1035,6 @@
     }
 }
 
-int
-Parrot_store_arg(Interp *interp, struct call_state *st)
-{
-    INTVAL idx;
-
-    if (st->dest.i >= st->dest.n)
-        return 0;
-    assert(st->dest.mode & CALL_STATE_OP);
-    idx = st->dest.u.op.pc[st->dest.i];
-    assert(idx >= 0);
-    switch (st->dest.sig & PARROT_ARG_TYPE_MASK) {
-        case PARROT_ARG_INTVAL:
-            CTX_REG_INT(st->dest.ctx, idx) = UVal_int(st->val);
-            break;
-        case PARROT_ARG_FLOATVAL:
-            CTX_REG_NUM(st->dest.ctx, idx) = UVal_num(st->val);
-            break;
-        case PARROT_ARG_STRING:
-            CTX_REG_STR(st->dest.ctx, idx) = UVal_str(st->val);
-            break;
-        case PARROT_ARG_PMC:
-            CTX_REG_PMC(st->dest.ctx, idx) =  UVal_pmc(st->val);
-            break;
-    }
-    if (!(st->dest.mode & CALL_STATE_x_NAMED))
-        st->dest.mode |= CALL_STATE_NEXT_ARG;
-    return 1;
-}
-
 static void
 init_call_stats(struct call_state *st)
 {
@@ -1110,7 +1070,7 @@
 
 opcode_t *
 parrot_pass_args(Interp *interp,  parrot_context_t *src_ctx,
-        parrot_context_t *dest_ctx, int what)
+        parrot_context_t *dest_ctx, int mode)
 {
     const char *action;
     struct call_state st;
@@ -1119,37 +1079,49 @@
 
     st.dest.n = 0;      /* XXX */
 
-    if (what == PARROT_OP_get_params_pc) {
-        dst_pc = interp->current_params;
-        src_pc = interp->current_args;
-        /* the args and params are now 'used.' */
-        interp->current_args = NULL;
-        interp->current_params = NULL;
-        action = "params";
-    }
-    else {
-        dst_pc = dest_ctx->current_results;
-        if (what == PARROT_OP_get_results_pc) {
+    switch(mode)
+    {
+        case PARROT_OP_get_params_pc:
+            dst_pc = interp->current_params;
+            src_pc = interp->current_args;
+            /* the args and params are now 'used.' */
+            interp->current_args = NULL;
+            interp->current_params = NULL;
+            action = "params";
+            break;
+        case PARROT_OP_get_results_pc:
+            dst_pc = dest_ctx->current_results;
             src_pc = interp->current_returns;
             interp->current_returns = NULL;
+            interp->current_args = NULL;
             action = "results";
-        }
-        else {
-            assert(what == PARROT_OP_set_args_pc);
+            break;
+        case PARROT_OP_set_args_pc:
+            dst_pc = dest_ctx->current_results;
             src_pc = interp->current_args;
+            interp->current_args = NULL;
             action = "params";
-        }
-        interp->current_args = NULL;
+            break;
+        default:
+            assert(0);
+            break;
     }
+
+    interp->current_args = NULL;
+    interp->current_params = NULL;
+    interp->current_returns = NULL;
+
     if (!dst_pc) {
         /* XXX error checking */
         return NULL;
     }
+
     Parrot_init_arg_op(interp, dest_ctx, dst_pc, &st.dest);
     Parrot_init_arg_op(interp, src_ctx, src_pc, &st.src);
     init_call_stats(&st);
+
     err_check = 1;
-    if (what == PARROT_OP_get_results_pc) {
+    if (mode == PARROT_OP_get_results_pc) {
         if (!PARROT_ERRORS_test(interp, PARROT_ERRORS_RESULT_COUNT_FLAG))
             err_check = 0;
     }
@@ -1213,65 +1185,62 @@
     return dest + st.dest.n + 2;
 }
 
+int
+set_retval_util(Parrot_Interp interp, const char *sig, parrot_context_t *ctx, 
struct call_state *st)
+{
+    opcode_t *src_pc = interp->current_returns;
+    int todo = Parrot_init_arg_op(interp, ctx, src_pc, &st->src);
+
+    interp->current_returns = NULL;
+
+    if (todo) {
+        todo = Parrot_init_arg_sig(interp, CONTEXT(interp->ctx), sig, NULL, 
&st->dest);
+        if (todo) {
+            Parrot_fetch_arg(interp, st);
+            Parrot_convert_arg(interp, st);
+            return 1;
+        }
+    }
+    return 0;
+}
+
+
 /*
  * handle void, and pointer (PMC*, STRING*) return values
  */
 void*
 set_retval(Parrot_Interp interp, int sig_ret, parrot_context_t *ctx)
 {
-    opcode_t *src_pc;
-    int todo;
     struct call_state st;
-    char buf[2];
-    const char *sig = buf;
 
-    src_pc = interp->current_returns;
-    interp->current_returns = NULL;
     if (!sig_ret || sig_ret == 'v')
         return NULL;
 
-    todo = Parrot_init_arg_op(interp, ctx, src_pc, &st.src);
-    if (todo) {
-        buf[0] = sig_ret;
-        buf[1] = 0;
-        todo = Parrot_init_arg_sig(interp,
-                CONTEXT(interp->ctx), sig, NULL, &st.dest);
-    }
-    if (todo) {
-        Parrot_fetch_arg(interp, &st);
-        Parrot_convert_arg(interp, &st);
-        switch (sig_ret) {
-            case 'S':  return UVal_str(st.val);
-            case 'P':  return UVal_pmc(st.val);
-        }
+    switch (sig_ret) {
+        case 'S':
+            if (set_retval_util(interp, "S", ctx, &st))
+                return UVal_str(st.val);
+        case 'P':
+            if (set_retval_util(interp, "P", ctx, &st))
+                return UVal_pmc(st.val);
     }
     return NULL;
 }
+
 /*
  * handle INTVAL return value
  */
 INTVAL
 set_retval_i(Parrot_Interp interp, int sig_ret, parrot_context_t *ctx)
 {
-    opcode_t *src_pc;
-    int todo;
     struct call_state st;
-    const char *sig = "I";
 
-    if (sig_ret != 'I') {
-        real_exception(interp, NULL, E_ValueError,
-                "return signature not 'I'");
-    }
-    src_pc = interp->current_returns;
-    interp->current_returns = NULL;
-    Parrot_init_arg_op(interp, ctx, src_pc, &st.src);
-    todo = Parrot_init_arg_sig(interp,
-            CONTEXT(interp->ctx), sig, NULL, &st.dest);
-    if (todo) {
-        Parrot_fetch_arg(interp, &st);
-        Parrot_convert_arg(interp, &st);
+    if (sig_ret != 'I')
+        real_exception(interp, NULL, E_ValueError, "return signature not 'I'");
+
+    if (set_retval_util(interp, "I", ctx, &st))
         return UVal_int(st.val);
-    }
+
     return 0;
 }
 
@@ -1281,27 +1250,51 @@
 FLOATVAL
 set_retval_f(Parrot_Interp interp, int sig_ret, parrot_context_t *ctx)
 {
-    opcode_t *src_pc;
-    int todo;
     struct call_state st;
-    const char *sig = "N";
 
-    if (sig_ret != 'N') {
-        real_exception(interp, NULL, E_ValueError,
-                "return signature not 'I'");
-    }
-    src_pc = interp->current_returns;
-    interp->current_returns = NULL;
-    Parrot_init_arg_op(interp, ctx, src_pc, &st.src);
-    todo = Parrot_init_arg_sig(interp,
-            CONTEXT(interp->ctx), sig, NULL, &st.dest);
-    if (todo) {
-        Parrot_fetch_arg(interp, &st);
-        Parrot_convert_arg(interp, &st);
+    if (sig_ret != 'N')
+        real_exception(interp, NULL, E_ValueError, "return signature not 'N'");
+
+    if (set_retval_util(interp, "N", ctx, &st))
         return UVal_num(st.val);
-    }
+
     return 0.0;
 }
+
+/*
+ * handle STRING return value
+ */
+STRING*
+set_retval_s(Parrot_Interp interp, int sig_ret, parrot_context_t *ctx)
+{
+    struct call_state st;
+
+    if (sig_ret != 'S')
+        real_exception(interp, NULL, E_ValueError, "return signature not 'S'");
+
+    if (set_retval_util(interp, "S", ctx, &st))
+        return UVal_str(st.val);
+
+    return NULL;
+}
+
+/*
+ * handle PMC return value
+ */
+PMC*
+set_retval_p(Parrot_Interp interp, int sig_ret, parrot_context_t *ctx)
+{
+    struct call_state st;
+
+    if (sig_ret != 'P')
+        real_exception(interp, NULL, E_ValueError, "return signature not 'P'");
+
+    if (set_retval_util(interp, "P", ctx, &st))
+        return UVal_pmc(st.val);
+
+    return NULL;
+}
+
 /*
 
 =back

Reply via email to