[svn:parrot] r41754 - branches/pcc_reapply/src/call

allison at svn.parrot.org allison at svn.parrot.org
Wed Oct 7 22:03:11 UTC 2009


Author: allison
Date: Wed Oct  7 22:03:06 2009
New Revision: 41754
URL: https://trac.parrot.org/parrot/changeset/41754

Log:
[pcc] Keep the old code in place for testing development, while we finalize the
new return handling.

Modified:
   branches/pcc_reapply/src/call/args.c

Modified: branches/pcc_reapply/src/call/args.c
==============================================================================
--- branches/pcc_reapply/src/call/args.c	Wed Oct  7 19:59:25 2009	(r41753)
+++ branches/pcc_reapply/src/call/args.c	Wed Oct  7 22:03:06 2009	(r41754)
@@ -23,6 +23,8 @@
 #include "args.str"
 #include "../pmc/pmc_key.h"
 
+/* #define DEVELOPING_NEW_RETURNS */
+
 /* HEADERIZER HFILE: include/parrot/call.h */
 
 /*
@@ -1812,6 +1814,7 @@
         ARGIN(PMC *raw_sig), ARGIN(opcode_t *raw_returns))
 {
     ASSERT_ARGS(Parrot_pcc_fill_returns_from_op)
+#ifdef DEVELOPING_NEW_RETURNS
     INTVAL return_list_elements;
     PMC *ctx = CURRENT_CONTEXT(interp);
     PMC *return_list;
@@ -1852,6 +1855,111 @@
     fill_results(interp, call_object, raw_sig, raw_returns, &function_pointers);
 
     return;
+#else
+    INTVAL return_list_elements;
+    PMC *ctx = CURRENT_CONTEXT(interp);
+    PMC *return_list;
+    PMC *caller_return_flags;
+    INTVAL raw_return_count     = VTABLE_elements(interp, raw_sig);
+    INTVAL return_index = 0;
+    INTVAL return_list_index = 0;
+    INTVAL err_check      = 0;
+
+    /* Check if we should be throwing errors. This is configured separately
+     * for parameters and return values. */
+    if (PARROT_ERRORS_test(interp, PARROT_ERRORS_RESULT_COUNT_FLAG))
+            err_check = 1;
+
+    /* A null call object is fine if there are no arguments and no returns. */
+    if (PMC_IS_NULL(call_object)) {
+        if (raw_return_count > 0) {
+            if (err_check)
+                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                        "too many return values: %d passed, 0 expected",
+                        raw_return_count);
+        }
+        return;
+    }
+
+    return_list = VTABLE_get_attr_str(interp, call_object, CONST_STRING(interp, "returns"));
+    if (PMC_IS_NULL(return_list)) {
+        if (raw_return_count > 0) {
+            if (err_check)
+                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                        "too many return values: %d passed, 0 expected",
+                        raw_return_count);
+        }
+        return;
+    }
+    else
+        return_list_elements = VTABLE_elements(interp, return_list);
+
+    caller_return_flags = VTABLE_get_attr_str(interp, call_object, CONST_STRING(interp, "return_flags"));
+
+
+    if (raw_return_count > return_list_elements) {
+        if (err_check)
+            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+                    "too many return values: %d passed, %d expected",
+                    raw_return_count, return_list_elements);
+    }
+
+    for (return_index = 0; return_index < raw_return_count; return_index++) {
+        INTVAL return_flags = VTABLE_get_integer_keyed_int(interp,
+                    raw_sig, return_index);
+        INTVAL result_flags;
+
+        const INTVAL constant  = PARROT_ARG_CONSTANT_ISSET(return_flags);
+        const INTVAL raw_index = raw_returns[return_index + 2];
+        PMC *result_item = VTABLE_get_pmc_keyed_int(interp, return_list, return_list_index);
+        STRING *item_sig;
+
+        /* Gracefully ignore extra returns when error checking is off. */
+        if (PMC_IS_NULL(result_item))
+            continue; /* Go on to next return arg. */
+
+        result_flags = VTABLE_get_integer_keyed_int(interp, caller_return_flags, return_list_index);
+        item_sig = VTABLE_get_string_keyed_str(interp, result_item, CONST_STRING(interp, ''));
+
+        switch (PARROT_ARG_TYPE_MASK_MASK(return_flags)) {
+            case PARROT_ARG_INTVAL:
+                if (constant)
+                    VTABLE_set_integer_native(interp, result_item, raw_index);
+                else
+                    VTABLE_set_integer_native(interp, result_item, CTX_REG_INT(ctx, raw_index));
+                return_list_index++;
+                break;
+            case PARROT_ARG_FLOATVAL:
+                if (constant)
+                    VTABLE_set_number_native(interp, result_item,
+                            Parrot_pcc_get_num_constant(interp, ctx, raw_index));
+                else
+                    VTABLE_set_number_native(interp, result_item, CTX_REG_NUM(ctx, raw_index));
+                return_list_index++;
+                break;
+            case PARROT_ARG_STRING:
+                if (constant)
+                    VTABLE_set_string_native(interp, result_item, Parrot_str_new_COW(interp,
+                            Parrot_pcc_get_string_constant(interp, ctx, raw_index)));
+                else
+                    VTABLE_set_string_native(interp, result_item, CTX_REG_STR(ctx, raw_index));
+                return_list_index++;
+                break;
+            case PARROT_ARG_PMC:
+                if (constant)
+                    VTABLE_set_pmc(interp, result_item,
+                            Parrot_pcc_get_pmc_constant(interp, ctx, raw_index));
+                else
+                    VTABLE_set_pmc(interp, result_item, CTX_REG_PMC(ctx, raw_index));
+                return_list_index++;
+                break;
+            default:
+                Parrot_ex_throw_from_c_args(interp, NULL,
+                        EXCEPTION_INVALID_OPERATION, "invalid parameter type");
+                break;
+        }
+    }
+#endif
 }
 
 /*


More information about the parrot-commits mailing list