Author: leo
Date: Mon Oct 10 01:42:12 2005
New Revision: 9428

Modified:
   trunk/classes/coroutine.pmc
   trunk/t/pmc/coroutine.t
Log:
More versatile coroutines

* coroutines now remember caller's state (context, code) on each
  invocation, so that e.g. the initial call to the coroutine and
  further calls after yield can come from different code locations
* unTODO test (provided by pmichaud (r9423)


Modified: trunk/classes/coroutine.pmc
==============================================================================
--- trunk/classes/coroutine.pmc (original)
+++ trunk/classes/coroutine.pmc Mon Oct 10 01:42:12 2005
@@ -96,11 +96,12 @@ Swaps the "context".
         struct PackFile_ByteCode *wanted_seg;
         opcode_t * dest = co->address;
         parrot_context_t ctx;
+        PMC *ccont;
 
         ctx = INTERP->ctx;
 
         if (!co->ctx.bp) {
-            PMC *pad, *ccont;
+            PMC *pad;
 
             ccont = INTERP->current_cont;
             if (ccont == NEED_CONTINUATION) {
@@ -141,13 +142,19 @@ Swaps the "context".
             PObj_get_FLAGS(SELF) |= SUB_FLAG_CORO_FF;
             wanted_seg = co->seg;
             /* remember segment of caller */
+            co->caller_seg = INTERP->code;
+            /* and the recent call context */
+            ccont = CONTEXT(co->ctx)->current_cont;
+            PMC_cont(ccont)->to_ctx = INTERP->ctx;
+            /* set context to coro context */
             INTERP->ctx = co->ctx;
         }
         else {
             PObj_get_FLAGS(SELF) &= ~SUB_FLAG_CORO_FF;
+            /* switch back to last remembered code seg and context */
             wanted_seg = co->caller_seg;
-            ctx.rctx = CONTEXT(ctx)->prev;
-            INTERP->ctx = ctx;
+            ccont = CONTEXT(co->ctx)->current_cont;
+            INTERP->ctx = ctx = PMC_cont(ccont)->to_ctx;
             /* yield values */
             if (INTERP->current_returns && CONTEXT(ctx)->current_results)
                 parrot_pass_args(INTERP, wanted_seg,

Modified: trunk/t/pmc/coroutine.t
==============================================================================
--- trunk/t/pmc/coroutine.t     (original)
+++ trunk/t/pmc/coroutine.t     Mon Oct 10 01:42:12 2005
@@ -519,8 +519,6 @@ CODE
 0
 OUTPUT
 
-TODO: {
-  local $TODO  = "coroutines re-entered from another sub";
 pir_output_is(<<'CODE', <<'OUTPUT', "re-entering coro from another sub");
 
 .sub main @MAIN
@@ -531,7 +529,7 @@ pir_output_is(<<'CODE', <<'OUTPUT', "re-
     z = 0
   loop:
     unless z < 4 goto end
-    met(corou)                     # <-- replace with "corou()" and it works
+    met(corou)
     inc z
     goto loop
   end:
@@ -565,5 +563,5 @@ yield #3
 yield #4
 yield #5
 OUTPUT
-};
+
 

Reply via email to