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
-};
+