… | |
… | |
116 | # define CORO_PREFER_PERL_FUNCTIONS 0 |
116 | # define CORO_PREFER_PERL_FUNCTIONS 0 |
117 | #endif |
117 | #endif |
118 | |
118 | |
119 | /* The next macros try to return the current stack pointer, in an as |
119 | /* The next macros try to return the current stack pointer, in an as |
120 | * portable way as possible. */ |
120 | * portable way as possible. */ |
121 | #define dSTACKLEVEL volatile char stacklevel |
121 | #if __GNUC__ >= 4 |
122 | #define STACKLEVEL ((void *)&stacklevel) |
122 | # define dSTACKLEVEL void *stacklevel = __builtin_frame_address (0) |
|
|
123 | #else |
|
|
124 | # define dSTACKLEVEL volatile void *stacklevel = (volatile void *)&stacklevel |
|
|
125 | #endif |
123 | |
126 | |
124 | #define IN_DESTRUCT (PL_main_cv == Nullcv) |
127 | #define IN_DESTRUCT (PL_main_cv == Nullcv) |
125 | |
128 | |
126 | #if __GNUC__ >= 3 |
129 | #if __GNUC__ >= 3 |
127 | # define attribute(x) __attribute__(x) |
130 | # define attribute(x) __attribute__(x) |
… | |
… | |
1329 | dSTACKLEVEL; |
1332 | dSTACKLEVEL; |
1330 | |
1333 | |
1331 | /* sometimes transfer is only called to set idle_sp */ |
1334 | /* sometimes transfer is only called to set idle_sp */ |
1332 | if (expect_false (!next)) |
1335 | if (expect_false (!next)) |
1333 | { |
1336 | { |
1334 | ((coro_cctx *)prev)->idle_sp = STACKLEVEL; |
1337 | ((coro_cctx *)prev)->idle_sp = stacklevel; |
1335 | assert (((coro_cctx *)prev)->idle_te = PL_top_env); /* just for the side-effect when asserts are enabled */ |
1338 | assert (((coro_cctx *)prev)->idle_te = PL_top_env); /* just for the side-effect when asserts are enabled */ |
1336 | } |
1339 | } |
1337 | else if (expect_true (prev != next)) |
1340 | else if (expect_true (prev != next)) |
1338 | { |
1341 | { |
1339 | coro_cctx *prev__cctx; |
1342 | coro_cctx *prev__cctx; |
… | |
… | |
1366 | |
1369 | |
1367 | prev__cctx = prev->cctx; |
1370 | prev__cctx = prev->cctx; |
1368 | |
1371 | |
1369 | /* possibly untie and reuse the cctx */ |
1372 | /* possibly untie and reuse the cctx */ |
1370 | if (expect_true ( |
1373 | if (expect_true ( |
1371 | prev__cctx->idle_sp == STACKLEVEL |
1374 | prev__cctx->idle_sp == stacklevel |
1372 | && !(prev__cctx->flags & CC_TRACE) |
1375 | && !(prev__cctx->flags & CC_TRACE) |
1373 | && !force_cctx |
1376 | && !force_cctx |
1374 | )) |
1377 | )) |
1375 | { |
1378 | { |
1376 | /* I assume that STACKLEVEL is a stronger indicator than PL_top_env changes */ |
1379 | /* I assume that stacklevel is a stronger indicator than PL_top_env changes */ |
1377 | assert (("FATAL: current top_env must equal previous top_env in Coro (please report)", PL_top_env == prev__cctx->idle_te)); |
1380 | assert (("FATAL: current top_env must equal previous top_env in Coro (please report)", PL_top_env == prev__cctx->idle_te)); |
1378 | |
1381 | |
1379 | prev->cctx = 0; |
1382 | prev->cctx = 0; |
1380 | |
1383 | |
1381 | /* if the cctx is about to be destroyed we need to make sure we won't see it in cctx_get */ |
1384 | /* if the cctx is about to be destroyed we need to make sure we won't see it in cctx_get */ |