… | |
… | |
47 | void *sptr; |
47 | void *sptr; |
48 | long ssize; /* positive == mmap, otherwise malloc */ |
48 | long ssize; /* positive == mmap, otherwise malloc */ |
49 | } coro_stack; |
49 | } coro_stack; |
50 | |
50 | |
51 | struct coro { |
51 | struct coro { |
|
|
52 | /* the top-level JMPENV for each coroutine, needed to catch dies. */ |
|
|
53 | JMPENV start_env; |
|
|
54 | |
52 | /* the optional C context */ |
55 | /* the optional C context */ |
53 | coro_stack *stack; |
56 | coro_stack *stack; |
54 | void *cursp; |
57 | void *cursp; |
55 | int gencnt; |
58 | int gencnt; |
56 | |
59 | |
… | |
… | |
68 | AV *curstack; |
71 | AV *curstack; |
69 | AV *mainstack; |
72 | AV *mainstack; |
70 | SV **stack_sp; |
73 | SV **stack_sp; |
71 | OP *op; |
74 | OP *op; |
72 | SV **curpad; |
75 | SV **curpad; |
|
|
76 | AV *comppad; |
73 | SV **stack_base; |
77 | SV **stack_base; |
74 | SV **stack_max; |
78 | SV **stack_max; |
75 | SV **tmps_stack; |
79 | SV **tmps_stack; |
76 | I32 tmps_floor; |
80 | I32 tmps_floor; |
77 | I32 tmps_ix; |
81 | I32 tmps_ix; |
… | |
… | |
290 | PL_curstack = c->curstack; |
294 | PL_curstack = c->curstack; |
291 | PL_mainstack = c->mainstack; |
295 | PL_mainstack = c->mainstack; |
292 | PL_stack_sp = c->stack_sp; |
296 | PL_stack_sp = c->stack_sp; |
293 | PL_op = c->op; |
297 | PL_op = c->op; |
294 | PL_curpad = c->curpad; |
298 | PL_curpad = c->curpad; |
|
|
299 | PL_comppad = c->comppad; |
295 | PL_stack_base = c->stack_base; |
300 | PL_stack_base = c->stack_base; |
296 | PL_stack_max = c->stack_max; |
301 | PL_stack_max = c->stack_max; |
297 | PL_tmps_stack = c->tmps_stack; |
302 | PL_tmps_stack = c->tmps_stack; |
298 | PL_tmps_floor = c->tmps_floor; |
303 | PL_tmps_floor = c->tmps_floor; |
299 | PL_tmps_ix = c->tmps_ix; |
304 | PL_tmps_ix = c->tmps_ix; |
… | |
… | |
419 | c->curstack = PL_curstack; |
424 | c->curstack = PL_curstack; |
420 | c->mainstack = PL_mainstack; |
425 | c->mainstack = PL_mainstack; |
421 | c->stack_sp = PL_stack_sp; |
426 | c->stack_sp = PL_stack_sp; |
422 | c->op = PL_op; |
427 | c->op = PL_op; |
423 | c->curpad = PL_curpad; |
428 | c->curpad = PL_curpad; |
|
|
429 | c->comppad = PL_comppad; |
424 | c->stack_base = PL_stack_base; |
430 | c->stack_base = PL_stack_base; |
425 | c->stack_max = PL_stack_max; |
431 | c->stack_max = PL_stack_max; |
426 | c->tmps_stack = PL_tmps_stack; |
432 | c->tmps_stack = PL_tmps_stack; |
427 | c->tmps_floor = PL_tmps_floor; |
433 | c->tmps_floor = PL_tmps_floor; |
428 | c->tmps_ix = PL_tmps_ix; |
434 | c->tmps_ix = PL_tmps_ix; |
… | |
… | |
637 | * that doesn't matter, though, since it is only |
643 | * that doesn't matter, though, since it is only |
638 | * pp_nextstate and we never return... |
644 | * pp_nextstate and we never return... |
639 | * ah yes, and I don't care anyways ;) |
645 | * ah yes, and I don't care anyways ;) |
640 | */ |
646 | */ |
641 | PUTBACK; |
647 | PUTBACK; |
642 | PL_op = PL_ppaddr[OP_ENTERSUB](); |
648 | PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); |
643 | SPAGAIN; |
649 | SPAGAIN; |
644 | |
650 | |
645 | ENTER; /* necessary e.g. for dounwind */ |
651 | ENTER; /* necessary e.g. for dounwind */ |
646 | } |
652 | } |
647 | } |
653 | } |
… | |
… | |
653 | * this is a _very_ stripped down perl interpreter ;) |
659 | * this is a _very_ stripped down perl interpreter ;) |
654 | */ |
660 | */ |
655 | Coro__State ctx = (Coro__State)arg; |
661 | Coro__State ctx = (Coro__State)arg; |
656 | JMPENV coro_start_env; |
662 | JMPENV coro_start_env; |
657 | |
663 | |
658 | /* same as JMPENV_BOOTSTRAP */ |
|
|
659 | Zero(&coro_start_env, 1, JMPENV); |
|
|
660 | coro_start_env.je_ret = -1; |
|
|
661 | coro_start_env.je_mustcatch = TRUE; |
|
|
662 | PL_top_env = &coro_start_env; |
664 | PL_top_env = &ctx->start_env; |
663 | |
665 | |
664 | ctx->cursp = 0; |
666 | ctx->cursp = 0; |
665 | PL_op = PL_op->op_next; |
667 | PL_op = PL_op->op_next; |
666 | CALLRUNOPS(aTHX); |
668 | CALLRUNOPS(aTHX); |
667 | |
669 | |
… | |
… | |
725 | if (!prev->stack) |
727 | if (!prev->stack) |
726 | allocate_stack (prev, 0); |
728 | allocate_stack (prev, 0); |
727 | |
729 | |
728 | if (prev->stack->sptr && flags & TRANSFER_LAZY_STACK) |
730 | if (prev->stack->sptr && flags & TRANSFER_LAZY_STACK) |
729 | { |
731 | { |
|
|
732 | PL_top_env = &next->start_env; |
|
|
733 | |
730 | setup_coro (next); |
734 | setup_coro (next); |
731 | |
735 | |
732 | prev->stack->refcnt++; |
736 | prev->stack->refcnt++; |
733 | prev->stack->usecnt++; |
737 | prev->stack->usecnt++; |
734 | next->stack = prev->stack; |
738 | next->stack = prev->stack; |
… | |
… | |
927 | |
931 | |
928 | coro->args = (AV *)SvREFCNT_inc (SvRV (args)); |
932 | coro->args = (AV *)SvREFCNT_inc (SvRV (args)); |
929 | coro->mainstack = 0; /* actual work is done inside transfer */ |
933 | coro->mainstack = 0; /* actual work is done inside transfer */ |
930 | coro->stack = 0; |
934 | coro->stack = 0; |
931 | |
935 | |
|
|
936 | /* same as JMPENV_BOOTSTRAP */ |
|
|
937 | /* we might be able to recycle start_env, but safe is safe */ |
|
|
938 | Zero(&coro->start_env, 1, JMPENV); |
|
|
939 | coro->start_env.je_ret = -1; |
|
|
940 | coro->start_env.je_mustcatch = TRUE; |
|
|
941 | |
932 | RETVAL = coro; |
942 | RETVAL = coro; |
933 | OUTPUT: |
943 | OUTPUT: |
934 | RETVAL |
944 | RETVAL |
935 | |
945 | |
936 | void |
946 | void |