[svn:parrot] r45567 - in branches/block_exit_handlers/src: . call ops pmc

whiteknight at svn.parrot.org whiteknight at svn.parrot.org
Sun Apr 11 14:12:36 UTC 2010


Author: whiteknight
Date: Sun Apr 11 14:12:35 2010
New Revision: 45567
URL: https://trac.parrot.org/parrot/changeset/45567

Log:
initial test work

Modified:
   branches/block_exit_handlers/src/call/context_accessors.c
   branches/block_exit_handlers/src/ops/core.ops
   branches/block_exit_handlers/src/pmc/callcontext.pmc
   branches/block_exit_handlers/src/pmc/coroutine.pmc
   branches/block_exit_handlers/src/sub.c

Modified: branches/block_exit_handlers/src/call/context_accessors.c
==============================================================================
--- branches/block_exit_handlers/src/call/context_accessors.c	Sun Apr 11 14:10:54 2010	(r45566)
+++ branches/block_exit_handlers/src/call/context_accessors.c	Sun Apr 11 14:12:35 2010	(r45567)
@@ -750,6 +750,23 @@
     return c->constants[idx]->u.key;
 }
 
+/*
+
+=item C<Parrot_pcc_get_exit_handlers(PARROT_INTERP, ARGIN(PMC *ctx))
+
+=cut
+
+*/
+
+PARROT_EXPORT
+PARROT_CAN_RETURN_NULL
+PMC*
+Parrot_pcc_get_pmc_constant_func(PARROT_INTERP, ARGIN(PMC *ctx), INTVAL idx)
+{
+    ASSERT_ARGS(Parrot_pcc_get_exit_handlers)
+    Parrot_Context const * c = get_context_struct_fast(interp
+    return c->exit_handler;
+}
 
 
 /*
@@ -779,6 +796,7 @@
     return PMC_data_typed(ctx, Parrot_Context *);
 }
 
+
 /*
 
 =back

Modified: branches/block_exit_handlers/src/ops/core.ops
==============================================================================
--- branches/block_exit_handlers/src/ops/core.ops	Sun Apr 11 14:10:54 2010	(r45566)
+++ branches/block_exit_handlers/src/ops/core.ops	Sun Apr 11 14:12:35 2010	(r45567)
@@ -428,7 +428,10 @@
 }
 
 inline op returncc() :flow {
-    PMC * const p = Parrot_pcc_get_continuation(interp, CURRENT_CONTEXT(interp));
+    PMC * const curr_ctx = CURRENT_CONTEXT(interp);
+    PMC * const p = Parrot_pcc_get_continuation(interp, curr_ctx);
+    opcode_t * dest;
+    Parrot_sub_exe_exit_handlers(INTERP, curr_ctx);
     opcode_t * const dest = VTABLE_invoke(interp, p, expr NEXT());
     goto ADDRESS(dest);
 }

Modified: branches/block_exit_handlers/src/pmc/callcontext.pmc
==============================================================================
--- branches/block_exit_handlers/src/pmc/callcontext.pmc	Sun Apr 11 14:10:54 2010	(r45566)
+++ branches/block_exit_handlers/src/pmc/callcontext.pmc	Sun Apr 11 14:12:35 2010	(r45567)
@@ -448,6 +448,7 @@
     ATTR PMC    *arg_flags;            /* Integer array of argument flags */
     ATTR PMC    *return_flags;         /* Integer array of return flags */
     ATTR Hash   *hash;                 /* Hash of named arguments */
+    ATTR PMC *   exit_handler;         /* Handlers to execute on block exit */
 
 /*
 
@@ -535,6 +536,9 @@
         GET_ATTR_current_sig(INTERP, SELF, tmp);
         Parrot_gc_mark_PMC_alive(INTERP, tmp);
 
+        GET_ATTR_exit_handler(INTERP, SELF, tmp);
+        Parrot_gc_mark_PMC_alive(INTERP, tmp);
+
         GET_ATTR_n_regs_used(INTERP, SELF, n_regs_used);
         if (!n_regs_used)
             return;
@@ -565,6 +569,7 @@
 =cut
 
 */
+
     VTABLE void morph(PMC *type) {
         Hash     *hash;
 
@@ -1505,6 +1510,34 @@
 
         RETURN(PMC *result);
     }
+
+    METHOD add_exit_handler(PMC * handler) {
+        PMC * existing;
+        GET_ATTR_exit_handler(INTERP, SELF, existing);
+        if (PMC_IS_NULL(existing)) {
+            SET_ATTR_exit_hander(INTERP, SELF, handler);
+            RETURN();
+        }
+        else if (existing->vtable->base_type == enum_class_Sub) {
+            PMC * const array = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+            VTABLE_set_pmc_keyed_int(INTERP, array, 0, existing);
+            VTABLE_set_pmc_keyed_int(INTERP, array, 1, handler);
+            RETURN();
+        }
+        else
+            VTABLE_push_pmc(INTERP, existing, handler);
+    }
+
+    METHOD clear_exit_handlers() {
+        SET_ATTR_exit_handler(INTERP, SELF, PMCNULL);
+    }
+
+    METHOD get_exit_handlers() {
+        PMC * existing;
+        GET_ATTR_exit_handler(INTERP, SELF, existing);
+        RETURN(PMC *existing);
+    }
+
 /*
 
 =back

Modified: branches/block_exit_handlers/src/pmc/coroutine.pmc
==============================================================================
--- branches/block_exit_handlers/src/pmc/coroutine.pmc	Sun Apr 11 14:10:54 2010	(r45566)
+++ branches/block_exit_handlers/src/pmc/coroutine.pmc	Sun Apr 11 14:12:35 2010	(r45567)
@@ -163,6 +163,8 @@
 
         GET_ATTR_ctx(INTERP, SELF, ctx);
 
+        /* On first execution, the ctx is null. Setup the coroutine here for
+           first execution. */
         if (PMC_IS_NULL(ctx)) {
             PackFile_ByteCode *seg;
             size_t             start_offs;

Modified: branches/block_exit_handlers/src/sub.c
==============================================================================
--- branches/block_exit_handlers/src/sub.c	Sun Apr 11 14:10:54 2010	(r45566)
+++ branches/block_exit_handlers/src/sub.c	Sun Apr 11 14:12:35 2010	(r45567)
@@ -569,8 +569,9 @@
 {
     ASSERT_ARGS(Parrot_continuation_rewind_environment)
 
-    PMC * const to_ctx = PARROT_CONTINUATION(pmc)->to_ctx;
-    PMC * const sig    = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
+    PMC * const to_ctx       = PARROT_CONTINUATION(pmc)->to_ctx;
+    PMC * const cur_ctx      = CURRENT_CONTEXT(interp);
+    PMC * const sig          = Parrot_pcc_get_signature(interp, cur_ctx);
 
     /* debug print before context is switched */
     if (Interp_trace_TEST(interp, PARROT_TRACE_SUB_CALL_FLAG)) {
@@ -581,11 +582,43 @@
                     interp->dynamic_env);
     }
 
+    Parrot_sub_exe_exit_handlers(interp, cur_ctx);
+
     /* set context */
     CURRENT_CONTEXT(interp) = to_ctx;
     Parrot_pcc_set_signature(interp, to_ctx, sig);
 }
 
+/*
+
+=item C<void Parrot_sub_exe_exit_handlers(PARROT_INTERP, ARGIN(PMC *ctx),
+ARGIN(PMC * handlers))>
+
+=cut
+
+*/
+
+void
+Parrot_sub_exe_exit_handlers(PARROT_INTERP, ARGIN(PMC *ctx), ARGIN(PMC * handlers))
+{
+    ASSERT_ARGS(Parrot_sub_exe_exit_handlers)
+    PMC * const exit_handler = Parrot_pcc_get_exit_handler(interp, ctx);
+    if (PMC_IS_NULL(exit_handler))
+        return;
+    else {
+        const INTVAL base_type = handlers->vtable->base_type;
+        if (base_type == enum_class_Sub)
+            Parrot_pcc_invoke_method_from_c_args(interp, ctx, handlers, "->");
+        else {
+            PMC * const iter = VTABLE_get_iter(interp, handlers);
+            while(VTABLE_get_bool(interp, iter)) {
+                PMC * const sub = VTABLE_shift_pmc(interp, iter);
+                Parrot_pcc_invoke_method_from_c_args(interp, ctx, sub, "->");
+            }
+        }
+    }
+}
+
 
 /*
 


More information about the parrot-commits mailing list