… | |
… | |
184 | |
184 | |
185 | av_push ((AV *)*he, (SV *)CvPADLIST (cv)); |
185 | av_push ((AV *)*he, (SV *)CvPADLIST (cv)); |
186 | } |
186 | } |
187 | |
187 | |
188 | static void |
188 | static void |
189 | SAVE(pTHX_ Coro__State c) |
189 | save_state(pTHX_ Coro__State c) |
190 | { |
190 | { |
191 | { |
191 | { |
192 | dSP; |
192 | dSP; |
193 | I32 cxix = cxstack_ix; |
193 | I32 cxix = cxstack_ix; |
194 | PERL_SI *top_si = PL_curstackinfo; |
194 | PERL_SI *top_si = PL_curstackinfo; |
… | |
… | |
277 | c->retstack_ix = PL_retstack_ix; |
277 | c->retstack_ix = PL_retstack_ix; |
278 | c->retstack_max = PL_retstack_max; |
278 | c->retstack_max = PL_retstack_max; |
279 | c->curcop = PL_curcop; |
279 | c->curcop = PL_curcop; |
280 | } |
280 | } |
281 | |
281 | |
|
|
282 | #define LOAD(state) do { load_state(aTHX_ state); SPAGAIN; } while (0) |
|
|
283 | #define SAVE(state) do { PUTBACK; save_state(aTHX_ state); } while (0) |
|
|
284 | |
282 | static void |
285 | static void |
283 | LOAD(pTHX_ Coro__State c) |
286 | load_state(pTHX_ Coro__State c) |
284 | { |
287 | { |
285 | PL_dowarn = c->dowarn; |
288 | PL_dowarn = c->dowarn; |
286 | GvAV (PL_defgv) = c->defav; |
289 | GvAV (PL_defgv) = c->defav; |
287 | PL_curstackinfo = c->curstackinfo; |
290 | PL_curstackinfo = c->curstackinfo; |
288 | PL_curstack = c->curstack; |
291 | PL_curstack = c->curstack; |
… | |
… | |
336 | /* this is an EXACT copy of S_nuke_stacks in perl.c, which is unfortunately static */ |
339 | /* this is an EXACT copy of S_nuke_stacks in perl.c, which is unfortunately static */ |
337 | STATIC void |
340 | STATIC void |
338 | destroy_stacks(pTHX) |
341 | destroy_stacks(pTHX) |
339 | { |
342 | { |
340 | /* die does this while calling POPSTACK, but I just don't see why. */ |
343 | /* die does this while calling POPSTACK, but I just don't see why. */ |
|
|
344 | /* OTOH, die does not have a memleak, but we do... */ |
341 | dounwind(-1); |
345 | dounwind(-1); |
342 | |
346 | |
343 | /* is this ugly, I ask? */ |
347 | /* is this ugly, I ask? */ |
344 | while (PL_scopestack_ix) |
348 | while (PL_scopestack_ix) |
345 | LEAVE; |
349 | LEAVE; |
… | |
… | |
412 | Coro::State_or_hashref next |
416 | Coro::State_or_hashref next |
413 | CODE: |
417 | CODE: |
414 | |
418 | |
415 | if (prev != next) |
419 | if (prev != next) |
416 | { |
420 | { |
417 | PUTBACK; |
|
|
418 | SAVE (aTHX_ prev); |
|
|
419 | |
|
|
420 | /* |
421 | /* |
421 | * this could be done in newprocess which would lead to |
422 | * this could be done in newprocess which would lead to |
422 | * extremely elegant and fast (just PUTBACK/SAVE/LOAD/SPAGAIN) |
423 | * extremely elegant and fast (just SAVE/LOAD) |
423 | * code here, but lazy allocation of stacks has also |
424 | * code here, but lazy allocation of stacks has also |
424 | * some virtues and the overhead of the if() is nil. |
425 | * some virtues and the overhead of the if() is nil. |
425 | */ |
426 | */ |
426 | if (next->mainstack) |
427 | if (next->mainstack) |
427 | { |
428 | { |
|
|
429 | SAVE (prev); |
428 | LOAD (aTHX_ next); |
430 | LOAD (next); |
429 | next->mainstack = 0; /* unnecessary but much cleaner */ |
431 | /* mark this state as in-use */ |
430 | SPAGAIN; |
432 | next->mainstack = 0; |
|
|
433 | next->tmps_ix = -2; |
|
|
434 | } |
|
|
435 | else if (next->tmps_ix == -2) |
|
|
436 | { |
|
|
437 | croak ("tried to transfer to running coroutine"); |
431 | } |
438 | } |
432 | else |
439 | else |
433 | { |
440 | { |
|
|
441 | SAVE (prev); |
|
|
442 | |
434 | /* |
443 | /* |
435 | * emulate part of the perl startup here. |
444 | * emulate part of the perl startup here. |
436 | */ |
445 | */ |
437 | UNOP myop; |
446 | UNOP myop; |
438 | |
447 | |
… | |
… | |
469 | |
478 | |
470 | if (coro->mainstack) |
479 | if (coro->mainstack) |
471 | { |
480 | { |
472 | struct coro temp; |
481 | struct coro temp; |
473 | |
482 | |
474 | PUTBACK; |
|
|
475 | SAVE(aTHX_ (&temp)); |
483 | SAVE(aTHX_ (&temp)); |
476 | LOAD(aTHX_ coro); |
484 | LOAD(aTHX_ coro); |
477 | |
485 | |
478 | destroy_stacks (); |
486 | destroy_stacks (); |
479 | SvREFCNT_dec ((SV *)GvAV (PL_defgv)); |
487 | SvREFCNT_dec ((SV *)GvAV (PL_defgv)); |
480 | |
488 | |
481 | LOAD((&temp)); |
489 | LOAD((&temp)); |
482 | SPAGAIN; |
|
|
483 | } |
490 | } |
484 | |
491 | |
485 | SvREFCNT_dec (coro->args); |
492 | SvREFCNT_dec (coro->args); |
486 | Safefree (coro); |
493 | Safefree (coro); |
487 | |
494 | |