… | |
… | |
1120 | /* always use the TRANSFER macro */ |
1120 | /* always use the TRANSFER macro */ |
1121 | static void NOINLINE |
1121 | static void NOINLINE |
1122 | transfer (pTHX_ struct coro *prev, struct coro *next) |
1122 | transfer (pTHX_ struct coro *prev, struct coro *next) |
1123 | { |
1123 | { |
1124 | dSTACKLEVEL; |
1124 | dSTACKLEVEL; |
|
|
1125 | static volatile int has_throw; |
1125 | |
1126 | |
1126 | /* sometimes transfer is only called to set idle_sp */ |
1127 | /* sometimes transfer is only called to set idle_sp */ |
1127 | if (expect_false (!next)) |
1128 | if (expect_false (!next)) |
1128 | { |
1129 | { |
1129 | ((coro_cctx *)prev)->idle_sp = STACKLEVEL; |
1130 | ((coro_cctx *)prev)->idle_sp = STACKLEVEL; |
… | |
… | |
1181 | ++next->usecount; |
1182 | ++next->usecount; |
1182 | |
1183 | |
1183 | if (expect_true (!next->cctx)) |
1184 | if (expect_true (!next->cctx)) |
1184 | next->cctx = cctx_get (aTHX); |
1185 | next->cctx = cctx_get (aTHX); |
1185 | |
1186 | |
|
|
1187 | has_throw = !!next->throw; |
|
|
1188 | |
1186 | if (expect_false (prev__cctx != next->cctx)) |
1189 | if (expect_false (prev__cctx != next->cctx)) |
1187 | { |
1190 | { |
1188 | prev__cctx->top_env = PL_top_env; |
1191 | prev__cctx->top_env = PL_top_env; |
1189 | PL_top_env = next->cctx->top_env; |
1192 | PL_top_env = next->cctx->top_env; |
1190 | coro_transfer (&prev__cctx->cctx, &next->cctx->cctx); |
1193 | coro_transfer (&prev__cctx->cctx, &next->cctx->cctx); |
1191 | } |
1194 | } |
1192 | |
1195 | |
1193 | free_coro_mortal (aTHX); |
1196 | free_coro_mortal (aTHX); |
1194 | UNLOCK; |
1197 | UNLOCK; |
1195 | |
1198 | |
1196 | if (expect_false (prev->throw || next->throw)) |
1199 | if (expect_false (has_throw)) |
1197 | { |
1200 | { |
1198 | struct coro *coro = SvSTATE (coro_current); |
1201 | struct coro *coro = SvSTATE (coro_current); |
1199 | |
1202 | |
1200 | if (coro->throw) |
1203 | if (coro->throw) |
1201 | { |
1204 | { |