… | |
… | |
726 | #endif |
726 | #endif |
727 | } |
727 | } |
728 | |
728 | |
729 | /* swap sv heads, at least logically */ |
729 | /* swap sv heads, at least logically */ |
730 | static void |
730 | static void |
731 | swap_svs (pTHX_ Coro__State c) |
731 | swap_svs_enter (pTHX_ Coro__State c) |
732 | { |
732 | { |
733 | int i; |
733 | int i; |
734 | |
734 | |
735 | for (i = 0; i <= AvFILLp (c->swap_sv); i += 2) |
735 | for (i = 0; i <= AvFILLp (c->swap_sv); i += 2) |
736 | swap_sv (AvARRAY (c->swap_sv)[i], AvARRAY (c->swap_sv)[i + 1]); |
736 | swap_sv (AvARRAY (c->swap_sv)[i], AvARRAY (c->swap_sv)[i + 1]); |
737 | } |
737 | } |
738 | |
738 | |
|
|
739 | static void |
|
|
740 | swap_svs_leave (pTHX_ Coro__State c) |
|
|
741 | { |
|
|
742 | int i; |
|
|
743 | |
|
|
744 | for (i = AvFILLp (c->swap_sv) - 1; i >= 0; i -= 2) |
|
|
745 | swap_sv (AvARRAY (c->swap_sv)[i], AvARRAY (c->swap_sv)[i + 1]); |
|
|
746 | } |
|
|
747 | |
739 | #define SWAP_SVS(coro) \ |
748 | #define SWAP_SVS_ENTER(coro) \ |
740 | if (ecb_expect_false ((coro)->swap_sv)) \ |
749 | if (ecb_expect_false ((coro)->swap_sv)) \ |
741 | swap_svs (aTHX_ (coro)) |
750 | swap_svs_enter (aTHX_ (coro)) |
|
|
751 | |
|
|
752 | #define SWAP_SVS_LEAVE(coro) \ |
|
|
753 | if (ecb_expect_false ((coro)->swap_sv)) \ |
|
|
754 | swap_svs_leave (aTHX_ (coro)) |
742 | |
755 | |
743 | static void |
756 | static void |
744 | on_enterleave_call (pTHX_ SV *cb); |
757 | on_enterleave_call (pTHX_ SV *cb); |
745 | |
758 | |
746 | static void |
759 | static void |
… | |
… | |
799 | |
812 | |
800 | for (i = 0; i <= AvFILLp (c->on_enter_xs); i += 2) |
813 | for (i = 0; i <= AvFILLp (c->on_enter_xs); i += 2) |
801 | ((coro_enterleave_hook)AvARRAY (c->on_enter_xs)[i]) (aTHX_ AvARRAY (c->on_enter_xs)[i + 1]); |
814 | ((coro_enterleave_hook)AvARRAY (c->on_enter_xs)[i]) (aTHX_ AvARRAY (c->on_enter_xs)[i + 1]); |
802 | } |
815 | } |
803 | |
816 | |
804 | SWAP_SVS (c); |
817 | SWAP_SVS_ENTER (c); |
805 | } |
818 | } |
806 | |
819 | |
807 | static void |
820 | static void |
808 | save_perl (pTHX_ Coro__State c) |
821 | save_perl (pTHX_ Coro__State c) |
809 | { |
822 | { |
810 | SWAP_SVS (c); |
823 | SWAP_SVS_LEAVE (c); |
811 | |
824 | |
812 | if (ecb_expect_false (c->on_leave_xs)) |
825 | if (ecb_expect_false (c->on_leave_xs)) |
813 | { |
826 | { |
814 | int i; |
827 | int i; |
815 | |
828 | |
… | |
… | |
950 | #endif |
963 | #endif |
951 | |
964 | |
952 | New(54,PL_savestack,24,ANY); |
965 | New(54,PL_savestack,24,ANY); |
953 | PL_savestack_ix = 0; |
966 | PL_savestack_ix = 0; |
954 | PL_savestack_max = 24; |
967 | PL_savestack_max = 24; |
|
|
968 | #if !PERL_VERSION_ATLEAST (5,24,0) |
|
|
969 | /* perl 5.24 moves SS_MAXPUSH optimisation from */ |
|
|
970 | /* the header macros to PL_savestack_max */ |
|
|
971 | PL_savestack_max -= SS_MAXPUSH; |
|
|
972 | #endif |
955 | |
973 | |
956 | #if !PERL_VERSION_ATLEAST (5,10,0) |
974 | #if !PERL_VERSION_ATLEAST (5,10,0) |
957 | New(54,PL_retstack,4,OP*); |
975 | New(54,PL_retstack,4,OP*); |
958 | PL_retstack_ix = 0; |
976 | PL_retstack_ix = 0; |
959 | PL_retstack_max = 4; |
977 | PL_retstack_max = 4; |
… | |
… | |
1217 | PL_op = (OP *)&init_perl_op; |
1235 | PL_op = (OP *)&init_perl_op; |
1218 | |
1236 | |
1219 | /* copy throw, in case it was set before init_perl */ |
1237 | /* copy throw, in case it was set before init_perl */ |
1220 | CORO_THROW = coro->except; |
1238 | CORO_THROW = coro->except; |
1221 | |
1239 | |
1222 | SWAP_SVS (coro); |
1240 | SWAP_SVS_ENTER (coro); |
1223 | |
1241 | |
1224 | if (ecb_expect_false (enable_times)) |
1242 | if (ecb_expect_false (enable_times)) |
1225 | { |
1243 | { |
1226 | coro_times_update (); |
1244 | coro_times_update (); |
1227 | coro_times_sub (coro); |
1245 | coro_times_sub (coro); |
… | |
… | |
1265 | /* this will cause transfer_check to croak on block*/ |
1283 | /* this will cause transfer_check to croak on block*/ |
1266 | SvRV_set (coro_current, (SV *)coro->hv); |
1284 | SvRV_set (coro_current, (SV *)coro->hv); |
1267 | |
1285 | |
1268 | load_perl (aTHX_ coro); |
1286 | load_perl (aTHX_ coro); |
1269 | |
1287 | |
|
|
1288 | /* restore swapped sv's */ |
|
|
1289 | SWAP_SVS_LEAVE (coro); |
|
|
1290 | |
1270 | coro_unwind_stacks (aTHX); |
1291 | coro_unwind_stacks (aTHX); |
1271 | |
|
|
1272 | /* restore swapped sv's */ |
|
|
1273 | SWAP_SVS (coro); |
|
|
1274 | |
1292 | |
1275 | coro_destruct_stacks (aTHX); |
1293 | coro_destruct_stacks (aTHX); |
1276 | |
1294 | |
1277 | /* now save some sv's to be free'd later */ |
1295 | /* now save some sv's to be free'd later */ |
1278 | svf [0] = GvSV (PL_defgv); |
1296 | svf [0] = GvSV (PL_defgv); |
… | |
… | |
1525 | * coro body here, as perl_run destroys these. Likewise, we cannot catch |
1543 | * coro body here, as perl_run destroys these. Likewise, we cannot catch |
1526 | * runtime errors here, as this is just a random interpreter, not a thread. |
1544 | * runtime errors here, as this is just a random interpreter, not a thread. |
1527 | */ |
1545 | */ |
1528 | |
1546 | |
1529 | /* |
1547 | /* |
|
|
1548 | * pp_entersub in 5.24 no longer ENTERs, but perl_destruct |
|
|
1549 | * requires PL_scopestack_ix, so do it here if required. |
|
|
1550 | */ |
|
|
1551 | if (!PL_scopestack_ix) |
|
|
1552 | ENTER; |
|
|
1553 | |
|
|
1554 | /* |
1530 | * If perl-run returns we assume exit() was being called or the coro |
1555 | * If perl-run returns we assume exit() was being called or the coro |
1531 | * fell off the end, which seems to be the only valid (non-bug) |
1556 | * fell off the end, which seems to be the only valid (non-bug) |
1532 | * reason for perl_run to return. We try to mimic whatever perl is normally |
1557 | * reason for perl_run to return. We try to mimic whatever perl is normally |
1533 | * doing in that case. YMMV. |
1558 | * doing in that case. YMMV. |
1534 | */ |
1559 | */ |
… | |
… | |
2413 | else |
2438 | else |
2414 | { |
2439 | { |
2415 | av_clear (GvAV (PL_defgv)); |
2440 | av_clear (GvAV (PL_defgv)); |
2416 | hv_store (hv, "desc", sizeof ("desc") - 1, SvREFCNT_inc_NN (sv_async_pool_idle), 0); |
2441 | hv_store (hv, "desc", sizeof ("desc") - 1, SvREFCNT_inc_NN (sv_async_pool_idle), 0); |
2417 | |
2442 | |
|
|
2443 | if (ecb_expect_false (coro->swap_sv)) |
|
|
2444 | { |
|
|
2445 | swap_svs_leave (coro); |
|
|
2446 | SvREFCNT_dec_NN (coro->swap_sv); |
|
|
2447 | coro->swap_sv = 0; |
|
|
2448 | } |
|
|
2449 | |
2418 | coro->prio = 0; |
2450 | coro->prio = 0; |
2419 | |
2451 | |
2420 | if (coro->cctx && (coro->cctx->flags & CC_TRACE)) |
2452 | if (ecb_expect_false (coro->cctx) && ecb_expect_false (coro->cctx->flags & CC_TRACE)) |
2421 | api_trace (aTHX_ coro_current, 0); |
2453 | api_trace (aTHX_ coro_current, 0); |
2422 | |
2454 | |
2423 | frame->prepare = prepare_schedule; |
2455 | frame->prepare = prepare_schedule; |
2424 | av_push (av_async_pool, SvREFCNT_inc (hv)); |
2456 | av_push (av_async_pool, SvREFCNT_inc (hv)); |
2425 | } |
2457 | } |
… | |
… | |
3918 | if (ecb_expect_false (current == self)) |
3950 | if (ecb_expect_false (current == self)) |
3919 | coro_times_sub (SvSTATE (coro_current)); |
3951 | coro_times_sub (SvSTATE (coro_current)); |
3920 | } |
3952 | } |
3921 | |
3953 | |
3922 | void |
3954 | void |
3923 | swap_sv (Coro::State coro, SV *sv, SV *swapsv) |
3955 | swap_sv (Coro::State coro, SV *sva, SV *svb) |
3924 | CODE: |
3956 | CODE: |
3925 | { |
3957 | { |
3926 | struct coro *current = SvSTATE_current; |
3958 | struct coro *current = SvSTATE_current; |
|
|
3959 | AV *swap_sv; |
|
|
3960 | int i; |
|
|
3961 | |
|
|
3962 | sva = SvRV (sva); |
|
|
3963 | svb = SvRV (svb); |
3927 | |
3964 | |
3928 | if (current == coro) |
3965 | if (current == coro) |
3929 | SWAP_SVS (current); |
3966 | SWAP_SVS_LEAVE (current); |
3930 | |
3967 | |
3931 | if (!coro->swap_sv) |
3968 | if (!coro->swap_sv) |
3932 | coro->swap_sv = newAV (); |
3969 | coro->swap_sv = newAV (); |
3933 | |
3970 | |
|
|
3971 | swap_sv = coro->swap_sv; |
|
|
3972 | |
|
|
3973 | for (i = AvFILLp (swap_sv) - 1; i >= 0; i -= 2) |
|
|
3974 | { |
|
|
3975 | SV *a = AvARRAY (swap_sv)[i ]; |
|
|
3976 | SV *b = AvARRAY (swap_sv)[i + 1]; |
|
|
3977 | |
|
|
3978 | if (a == sva && b == svb) |
|
|
3979 | { |
|
|
3980 | SvREFCNT_dec_NN (a); |
|
|
3981 | SvREFCNT_dec_NN (b); |
|
|
3982 | |
|
|
3983 | for (; i <= AvFILLp (swap_sv) - 2; i++) |
|
|
3984 | AvARRAY (swap_sv)[i] = AvARRAY (swap_sv)[i + 2]; |
|
|
3985 | |
|
|
3986 | AvFILLp (swap_sv) -= 2; |
|
|
3987 | |
|
|
3988 | goto removed; |
|
|
3989 | } |
|
|
3990 | } |
|
|
3991 | |
3934 | av_push (coro->swap_sv, SvREFCNT_inc_NN (SvRV (sv ))); |
3992 | av_push (swap_sv, SvREFCNT_inc_NN (sva)); |
3935 | av_push (coro->swap_sv, SvREFCNT_inc_NN (SvRV (swapsv))); |
3993 | av_push (swap_sv, SvREFCNT_inc_NN (svb)); |
|
|
3994 | |
|
|
3995 | removed: |
3936 | |
3996 | |
3937 | if (current == coro) |
3997 | if (current == coro) |
3938 | SWAP_SVS (current); |
3998 | SWAP_SVS_ENTER (current); |
3939 | } |
3999 | } |
3940 | |
4000 | |
3941 | |
4001 | |
3942 | MODULE = Coro::State PACKAGE = Coro |
4002 | MODULE = Coro::State PACKAGE = Coro |
3943 | |
4003 | |