… | |
… | |
184 | sv = (SV *) newAV (); |
184 | sv = (SV *) newAV (); |
185 | else if (*name == '%') |
185 | else if (*name == '%') |
186 | sv = (SV *) newHV (); |
186 | sv = (SV *) newHV (); |
187 | else |
187 | else |
188 | sv = NEWSV (0, 0); |
188 | sv = NEWSV (0, 0); |
|
|
189 | #ifdef SvPADBUSY |
189 | if (!SvPADBUSY (sv)) |
190 | if (!SvPADBUSY (sv)) |
|
|
191 | #endif |
190 | SvPADMY_on (sv); |
192 | SvPADMY_on (sv); |
191 | npad[ix] = sv; |
193 | npad[ix] = sv; |
192 | } |
194 | } |
193 | } |
195 | } |
194 | else if (IS_PADGV (ppad[ix]) || IS_PADCONST (ppad[ix])) |
196 | else if (IS_PADGV (ppad[ix]) || IS_PADCONST (ppad[ix])) |
… | |
… | |
303 | #define SE } while (0) |
305 | #define SE } while (0) |
304 | |
306 | |
305 | #define LOAD(state) load_state(aTHX_ (state)); |
307 | #define LOAD(state) load_state(aTHX_ (state)); |
306 | #define SAVE(state,flags) save_state(aTHX_ (state),(flags)); |
308 | #define SAVE(state,flags) save_state(aTHX_ (state),(flags)); |
307 | |
309 | |
308 | #define REPLACE_SV(sv,val) SB SvREFCNT_dec(sv); (sv) = (val); SE |
310 | #define REPLACE_SV(sv,val) SB SvREFCNT_dec(sv); (sv) = (val); (val) = 0; SE |
309 | |
311 | |
310 | static void |
312 | static void |
311 | load_state(pTHX_ Coro__State c) |
313 | load_state(pTHX_ Coro__State c) |
312 | { |
314 | { |
313 | PL_dowarn = c->dowarn; |
315 | PL_dowarn = c->dowarn; |
… | |
… | |
518 | PL_retstack_max = 8; |
520 | PL_retstack_max = 8; |
519 | } |
521 | } |
520 | |
522 | |
521 | /* |
523 | /* |
522 | * destroy the stacks, the callchain etc... |
524 | * destroy the stacks, the callchain etc... |
523 | * still there is a memleak of 128 bytes... |
|
|
524 | */ |
525 | */ |
525 | STATIC void |
526 | STATIC void |
526 | destroy_stacks(pTHX) |
527 | destroy_stacks(pTHX) |
527 | { |
528 | { |
528 | if (!IN_DESTRUCT) |
529 | if (!IN_DESTRUCT) |
… | |
… | |
609 | { |
610 | { |
610 | #ifdef HAVE_MMAP |
611 | #ifdef HAVE_MMAP |
611 | if (stack->ssize > 0 && stack->sptr) |
612 | if (stack->ssize > 0 && stack->sptr) |
612 | munmap (stack->sptr, stack->ssize); |
613 | munmap (stack->sptr, stack->ssize); |
613 | else |
614 | else |
614 | #else |
615 | #endif |
615 | Safefree (stack->sptr); |
616 | Safefree (stack->sptr); |
616 | #endif |
617 | |
617 | Safefree (stack); |
618 | Safefree (stack); |
618 | } |
619 | } |
619 | else if (ctx->gencnt == stack->gencnt) |
620 | else if (ctx->gencnt == stack->gencnt) |
620 | --stack->usecnt; |
621 | --stack->usecnt; |
621 | } |
622 | } |
… | |
… | |
633 | |
634 | |
634 | coro_init_stacks (aTHX); |
635 | coro_init_stacks (aTHX); |
635 | /*PL_curcop = 0;*/ |
636 | /*PL_curcop = 0;*/ |
636 | /*PL_in_eval = PL_in_eval;*/ /* inherit */ |
637 | /*PL_in_eval = PL_in_eval;*/ /* inherit */ |
637 | SvREFCNT_dec (GvAV (PL_defgv)); |
638 | SvREFCNT_dec (GvAV (PL_defgv)); |
638 | GvAV (PL_defgv) = ctx->args; |
639 | GvAV (PL_defgv) = ctx->args; ctx->args = 0; |
639 | |
640 | |
640 | SPAGAIN; |
641 | SPAGAIN; |
641 | |
642 | |
642 | if (ctx->stack) |
643 | if (ctx->stack) |
643 | { |
644 | { |
… | |
… | |
765 | next->stack = prev->stack; |
766 | next->stack = prev->stack; |
766 | next->gencnt = prev->gencnt; |
767 | next->gencnt = prev->gencnt; |
767 | } |
768 | } |
768 | else |
769 | else |
769 | { |
770 | { |
|
|
771 | assert (!next->stack); |
770 | allocate_stack (next, 1); |
772 | allocate_stack (next, 1); |
771 | coro_create (&(next->stack->cctx), |
773 | coro_create (&(next->stack->cctx), |
772 | setup_coro, (void *)next, |
774 | setup_coro, (void *)next, |
773 | next->stack->sptr, labs (next->stack->ssize)); |
775 | next->stack->sptr, labs (next->stack->ssize)); |
774 | coro_transfer (&(prev->stack->cctx), &(next->stack->cctx)); |
776 | coro_transfer (&(prev->stack->cctx), &(next->stack->cctx)); |
… | |
… | |
952 | Coro__State coro; |
954 | Coro__State coro; |
953 | |
955 | |
954 | if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV) |
956 | if (!SvROK (args) || SvTYPE (SvRV (args)) != SVt_PVAV) |
955 | croak ("Coro::State::_newprocess expects an arrayref"); |
957 | croak ("Coro::State::_newprocess expects an arrayref"); |
956 | |
958 | |
957 | New (0, coro, 1, struct coro); |
959 | Newz (0, coro, 1, struct coro); |
958 | |
960 | |
959 | coro->args = (AV *)SvREFCNT_inc (SvRV (args)); |
961 | coro->args = (AV *)SvREFCNT_inc (SvRV (args)); |
960 | coro->mainstack = 0; /* actual work is done inside transfer */ |
962 | coro->mainstack = 0; /* actual work is done inside transfer */ |
961 | coro->stack = 0; |
963 | coro->stack = 0; |
962 | |
964 | |
963 | /* same as JMPENV_BOOTSTRAP */ |
965 | /* same as JMPENV_BOOTSTRAP */ |
964 | /* we might be able to recycle start_env, but safe is safe */ |
966 | /* we might be able to recycle start_env, but safe is safe */ |
965 | Zero(&coro->start_env, 1, JMPENV); |
967 | //Zero(&coro->start_env, 1, JMPENV); |
966 | coro->start_env.je_ret = -1; |
968 | coro->start_env.je_ret = -1; |
967 | coro->start_env.je_mustcatch = TRUE; |
969 | coro->start_env.je_mustcatch = TRUE; |
968 | |
970 | |
969 | RETVAL = coro; |
971 | RETVAL = coro; |
970 | OUTPUT: |
972 | OUTPUT: |
… | |
… | |
1004 | |
1006 | |
1005 | coro->mainstack = 0; |
1007 | coro->mainstack = 0; |
1006 | } |
1008 | } |
1007 | |
1009 | |
1008 | deallocate_stack (coro); |
1010 | deallocate_stack (coro); |
1009 | |
1011 | SvREFCNT_dec (coro->args); |
1010 | Safefree (coro); |
1012 | Safefree (coro); |
1011 | |
1013 | |
1012 | void |
1014 | void |
1013 | flush() |
1015 | flush() |
1014 | CODE: |
1016 | CODE: |