… | |
… | |
129 | }; |
129 | }; |
130 | |
130 | |
131 | static size_t coro_stacksize = CORO_STACKSIZE; |
131 | static size_t coro_stacksize = CORO_STACKSIZE; |
132 | static struct CoroAPI coroapi; |
132 | static struct CoroAPI coroapi; |
133 | static AV *main_mainstack; /* used to differentiate between $main and others */ |
133 | static AV *main_mainstack; /* used to differentiate between $main and others */ |
|
|
134 | static JMPENV *main_top_env; |
134 | static HV *coro_state_stash, *coro_stash; |
135 | static HV *coro_state_stash, *coro_stash; |
135 | static SV *coro_mortal; /* will be freed after next transfer */ |
136 | static SV *coro_mortal; /* will be freed after next transfer */ |
136 | |
137 | |
137 | static struct coro_cctx *cctx_first; |
138 | static struct coro_cctx *cctx_first; |
138 | static int cctx_count, cctx_idle; |
139 | static int cctx_count, cctx_idle; |
… | |
… | |
587 | coro_mortal = 0; |
588 | coro_mortal = 0; |
588 | } |
589 | } |
589 | } |
590 | } |
590 | |
591 | |
591 | /* inject a fake call to Coro::State::_cctx_init into the execution */ |
592 | /* inject a fake call to Coro::State::_cctx_init into the execution */ |
|
|
593 | /* _cctx_init shoukld be careful, as it could be called at almost any time */ |
|
|
594 | /* during execution of a pelr program */ |
592 | static void NOINLINE |
595 | static void NOINLINE |
593 | prepare_cctx (pTHX_ coro_cctx *cctx) |
596 | prepare_cctx (pTHX_ coro_cctx *cctx) |
594 | { |
597 | { |
595 | dSP; |
598 | dSP; |
596 | LOGOP myop; |
599 | LOGOP myop; |
… | |
… | |
607 | PL_op = (OP *)&myop; |
610 | PL_op = (OP *)&myop; |
608 | PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); |
611 | PL_op = PL_ppaddr[OP_ENTERSUB](aTHX); |
609 | SPAGAIN; |
612 | SPAGAIN; |
610 | } |
613 | } |
611 | |
614 | |
|
|
615 | /* |
|
|
616 | * this is a _very_ stripped down perl interpreter ;) |
|
|
617 | */ |
612 | static void |
618 | static void |
613 | coro_run (void *arg) |
619 | coro_run (void *arg) |
614 | { |
620 | { |
615 | dTHX; |
621 | dTHX; |
616 | |
622 | |
617 | /* coro_run is the alternative tail of transfer(), so unlock here. */ |
623 | /* coro_run is the alternative tail of transfer(), so unlock here. */ |
618 | UNLOCK; |
624 | UNLOCK; |
619 | |
625 | |
620 | /* |
|
|
621 | * this is a _very_ stripped down perl interpreter ;) |
|
|
622 | */ |
|
|
623 | PL_top_env = &PL_start_env; |
626 | PL_top_env = &PL_start_env; |
624 | |
627 | |
625 | /* inject call to cctx_init */ |
628 | /* inject a fake subroutine call to cctx_init */ |
626 | prepare_cctx (aTHX_ (coro_cctx *)arg); |
629 | prepare_cctx (aTHX_ (coro_cctx *)arg); |
627 | |
630 | |
628 | /* somebody will hit me for both perl_run and PL_restartop */ |
631 | /* somebody or something will hit me for both perl_run and PL_restartop */ |
629 | PL_restartop = PL_op; |
632 | PL_restartop = PL_op; |
630 | perl_run (PL_curinterp); |
633 | perl_run (PL_curinterp); |
631 | |
634 | |
632 | fputs ("FATAL: C coroutine fell over the edge of the world, aborting. Did you call exit in a coroutine?\n", stderr); |
635 | /* If perl-run returns we assume exit() was being called, which */ |
633 | abort (); |
636 | /* seems to be the only valid (non-bug) reason for perl_run to return. */ |
|
|
637 | /* We try to exit by jumping to the bootstrap-time "top" top_env, as */ |
|
|
638 | /* we cannot restore the "main" coroutine as Coro has no such concept */ |
|
|
639 | PL_top_env = main_top_env; |
|
|
640 | JMPENV_JUMP (2); /* I do not feel well about the hardcoded 2 at all */ |
634 | } |
641 | } |
635 | |
642 | |
636 | static coro_cctx * |
643 | static coro_cctx * |
637 | cctx_new () |
644 | cctx_new () |
638 | { |
645 | { |
… | |
… | |
1175 | newCONSTSUB (coro_state_stash, "SAVE_DEFFH", newSViv (CORO_SAVE_DEFFH)); |
1182 | newCONSTSUB (coro_state_stash, "SAVE_DEFFH", newSViv (CORO_SAVE_DEFFH)); |
1176 | newCONSTSUB (coro_state_stash, "SAVE_DEF", newSViv (CORO_SAVE_DEF)); |
1183 | newCONSTSUB (coro_state_stash, "SAVE_DEF", newSViv (CORO_SAVE_DEF)); |
1177 | newCONSTSUB (coro_state_stash, "SAVE_ALL", newSViv (CORO_SAVE_ALL)); |
1184 | newCONSTSUB (coro_state_stash, "SAVE_ALL", newSViv (CORO_SAVE_ALL)); |
1178 | |
1185 | |
1179 | main_mainstack = PL_mainstack; |
1186 | main_mainstack = PL_mainstack; |
|
|
1187 | main_top_env = PL_top_env; |
|
|
1188 | |
|
|
1189 | while (main_top_env->je_prev) |
|
|
1190 | main_top_env = main_top_env->je_prev; |
1180 | |
1191 | |
1181 | coroapi.ver = CORO_API_VERSION; |
1192 | coroapi.ver = CORO_API_VERSION; |
1182 | coroapi.transfer = api_transfer; |
1193 | coroapi.transfer = api_transfer; |
1183 | |
1194 | |
1184 | assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL)); |
1195 | assert (("PRIO_NORMAL must be 0", !PRIO_NORMAL)); |