[svn:parrot] r41717 - branches/pcc_reapply/src/call
bacek at svn.parrot.org
bacek at svn.parrot.org
Sun Oct 4 23:03:59 UTC 2009
Author: bacek
Date: Sun Oct 4 23:03:56 2009
New Revision: 41717
URL: https://trac.parrot.org/parrot/changeset/41717
Log:
Clone Key args in fill_params. Stolen from old PCC.
Modified:
branches/pcc_reapply/src/call/args.c
Modified: branches/pcc_reapply/src/call/args.c
==============================================================================
--- branches/pcc_reapply/src/call/args.c Sun Oct 4 22:45:09 2009 (r41716)
+++ branches/pcc_reapply/src/call/args.c Sun Oct 4 23:03:56 2009 (r41717)
@@ -62,6 +62,10 @@
__attribute__nonnull__(4)
__attribute__nonnull__(5);
+static PMC* clone_key_arg(PARROT_INTERP, ARGIN(PMC *key))
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
PARROT_CANNOT_RETURN_NULL
static STRING * dissect_aggregate_arg(PARROT_INTERP,
ARGMOD(PMC *call_object),
@@ -191,6 +195,9 @@
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(arg_info) \
, PARROT_ASSERT_ARG(accessor))
+#define ASSERT_ARGS_clone_key_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
+ PARROT_ASSERT_ARG(interp) \
+ , PARROT_ASSERT_ARG(key))
#define ASSERT_ARGS_dissect_aggregate_arg __attribute__unused__ int _ASSERT_ARGS_CHECK = (\
PARROT_ASSERT_ARG(interp) \
, PARROT_ASSERT_ARG(call_object) \
@@ -851,8 +858,8 @@
VTABLE_get_string_keyed_int(interp, call_object, arg_index);
break;
case PARROT_ARG_PMC:
- *accessor->pmc(interp, arg_info, param_index) =
- VTABLE_get_pmc_keyed_int(interp, call_object, arg_index);
+ *accessor->pmc(interp, arg_info, param_index) = clone_key_arg(interp,
+ VTABLE_get_pmc_keyed_int(interp, call_object, arg_index));
break;
default:
Parrot_ex_throw_from_c_args(interp, NULL,
@@ -1008,8 +1015,8 @@
VTABLE_get_string_keyed_str(interp, call_object, param_name);
break;
case PARROT_ARG_PMC:
- *accessor->pmc(interp, arg_info, param_index) =
- VTABLE_get_pmc_keyed_str(interp, call_object, param_name);
+ *accessor->pmc(interp, arg_info, param_index) = clone_key_arg(interp,
+ VTABLE_get_pmc_keyed_int(interp, call_object, arg_index));
break;
default:
Parrot_ex_throw_from_c_args(interp, NULL,
@@ -1747,6 +1754,63 @@
/*
+=item C<static PMC* clone_key_arg(PARROT_INTERP, PMC *key)>
+
+Replaces any src registers by their values (done inside clone). This needs a
+test for tailcalls too, but I think there is no syntax to pass a key to a
+tailcalled function or method.
+
+=cut
+
+*/
+
+static PMC*
+clone_key_arg(PARROT_INTERP, ARGIN(PMC *key))
+{
+ ASSERT_ARGS(clone_key_arg)
+
+ if (PMC_IS_NULL(key))
+ return key;
+
+ if (key->vtable->base_type != enum_class_Key)
+ return key;
+
+ for (; key; key=key_next(interp, key)) {
+ /* register keys have to be cloned */
+ if (PObj_get_FLAGS(key) & KEY_register_FLAG) {
+ INTVAL n_regs_used[4];
+ Regs_ni bp;
+ Regs_ps bp_ps;
+ PMC *res;
+ PMC *caller_ctx = Parrot_pcc_get_caller_ctx(interp, CURRENT_CONTEXT(interp));
+
+ /* clone sets key values according to refered register items */
+ bp = *Parrot_pcc_get_regs_ni(interp, CURRENT_CONTEXT(interp));
+ bp_ps = *Parrot_pcc_get_regs_ps(interp, CURRENT_CONTEXT(interp));
+ memcpy(n_regs_used, CONTEXT(interp)->n_regs_used, 4 * sizeof (INTVAL));
+
+ Parrot_pcc_set_regs_ni(interp, CURRENT_CONTEXT(interp),
+ Parrot_pcc_get_regs_ni(interp, caller_ctx));
+ Parrot_pcc_set_regs_ps(interp, CURRENT_CONTEXT(interp),
+ Parrot_pcc_get_regs_ps(interp, caller_ctx));
+ memcpy(CONTEXT(interp)->n_regs_used,
+ Parrot_pcc_get_context_struct(interp, caller_ctx),
+ 4 * sizeof (INTVAL));
+
+ res = VTABLE_clone(interp, key);
+
+ Parrot_pcc_set_regs_ni(interp, CURRENT_CONTEXT(interp), &bp);
+ Parrot_pcc_set_regs_ps(interp, CURRENT_CONTEXT(interp), &bp_ps);
+ memcpy(CONTEXT(interp)->n_regs_used, n_regs_used, 4 * sizeof (INTVAL));
+ return res;
+ }
+ }
+
+ return key;
+}
+
+/*
+
=back
=head1 SEE ALSO
More information about the parrot-commits
mailing list