ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Coro/Coro/State.xs
(Generate patch)

Comparing Coro/Coro/State.xs (file contents):
Revision 1.293 by root, Tue Nov 18 06:10:03 2008 UTC vs.
Revision 1.294 by root, Tue Nov 18 08:31:03 2008 UTC

120#endif 120#endif
121 121
122/* The next macros try to return the current stack pointer, in an as 122/* The next macros try to return the current stack pointer, in an as
123 * portable way as possible. */ 123 * portable way as possible. */
124#if __GNUC__ >= 4 124#if __GNUC__ >= 4
125# define dSTACKLEVEL int stacklevel_dummy
125# define dSTACKLEVEL void *stacklevel = __builtin_frame_address (0) 126# define STACKLEVEL __builtin_frame_address (0)
126#else 127#else
127# define dSTACKLEVEL volatile void *stacklevel = (volatile void *)&stacklevel 128# define dSTACKLEVEL volatile void *stacklevel
129# define STACKLEVEL ((void *)&stacklevel)
128#endif 130#endif
129 131
130#define IN_DESTRUCT (PL_main_cv == Nullcv) 132#define IN_DESTRUCT (PL_main_cv == Nullcv)
131 133
132#if __GNUC__ >= 3 134#if __GNUC__ >= 3
857 { 859 {
858 dSP; 860 dSP;
859 UNOP myop; 861 UNOP myop;
860 862
861 Zero (&myop, 1, UNOP); 863 Zero (&myop, 1, UNOP);
862 myop.op_next = Nullop; 864 myop.op_next = Nullop;
863 myop.op_flags = OPf_WANT_VOID; 865 myop.op_flags = OPf_WANT_VOID;
864 866
865 PUSHMARK (SP); 867 PUSHMARK (SP);
866 XPUSHs (sv_2mortal (av_shift (GvAV (PL_defgv)))); 868 XPUSHs (sv_2mortal (av_shift (GvAV (PL_defgv))));
867 PUTBACK; 869 PUTBACK;
875 */ 877 */
876 slf_frame.prepare = prepare_nop; /* provide a nop function for an eventual pp_slf */ 878 slf_frame.prepare = prepare_nop; /* provide a nop function for an eventual pp_slf */
877 slf_frame.check = slf_check_nop; /* signal pp_slf to not repeat */ 879 slf_frame.check = slf_check_nop; /* signal pp_slf to not repeat */
878 880
879 /* and we have to provide the pp_slf op in any case, so pp_slf can skip it */ 881 /* and we have to provide the pp_slf op in any case, so pp_slf can skip it */
882 coro_setup_op.op_next = PL_op;
880 coro_setup_op.op_type = OP_CUSTOM; 883 coro_setup_op.op_type = OP_CUSTOM;
881 coro_setup_op.op_ppaddr = pp_slf; 884 coro_setup_op.op_ppaddr = pp_slf;
882 coro_setup_op.op_next = PL_op; 885 /* no flags required, as an init function won't be called */
883 886
884 PL_op = (OP *)&coro_setup_op; 887 PL_op = (OP *)&coro_setup_op;
885 888
886 /* copy throw, in case it was set before coro_setup */ 889 /* copy throw, in case it was set before coro_setup */
887 coro_throw = coro->throw; 890 coro_throw = coro->throw;
1070static int 1073static int
1071slf_check_set_stacklevel (pTHX_ struct CoroSLF *frame) 1074slf_check_set_stacklevel (pTHX_ struct CoroSLF *frame)
1072{ 1075{
1073 *frame = cctx_ssl_frame; 1076 *frame = cctx_ssl_frame;
1074 1077
1075 return 1; /* execute the restored frame - there must be one */ 1078 return frame->check (aTHX_ frame); /* execute the restored frame - there must be one */
1076} 1079}
1077 1080
1078/* initialises PL_top_env and injects a pseudo-slf-call to sett he stacklevel */ 1081/* initialises PL_top_env and injects a pseudo-slf-call to set the stacklevel */
1079static void NOINLINE 1082static void NOINLINE
1080cctx_prepare (pTHX_ coro_cctx *cctx) 1083cctx_prepare (pTHX_ coro_cctx *cctx)
1081{ 1084{
1082 PL_top_env = &PL_start_env; 1085 PL_top_env = &PL_start_env;
1083 1086
1087 /* we already must be executing an SLF op, there is no other valid way 1090 /* we already must be executing an SLF op, there is no other valid way
1088 * that can lead to creation of a new cctx */ 1091 * that can lead to creation of a new cctx */
1089 assert (("FATAL: can't prepare slf-less cctx in Coro module (please report)", 1092 assert (("FATAL: can't prepare slf-less cctx in Coro module (please report)",
1090 slf_frame.prepare && PL_op->op_ppaddr == pp_slf)); 1093 slf_frame.prepare && PL_op->op_ppaddr == pp_slf));
1091 1094
1095 /* we must emulate leaving pp_slf, which is done inside slf_check_set_stacklevel */
1092 cctx_ssl_cctx = cctx; 1096 cctx_ssl_cctx = cctx;
1093 cctx_ssl_frame = slf_frame; 1097 cctx_ssl_frame = slf_frame;
1094 1098
1095 slf_frame.prepare = slf_prepare_set_stacklevel; 1099 slf_frame.prepare = slf_prepare_set_stacklevel;
1096 slf_frame.check = slf_check_set_stacklevel; 1100 slf_frame.check = slf_check_set_stacklevel;
1317 dSTACKLEVEL; 1321 dSTACKLEVEL;
1318 1322
1319 /* sometimes transfer is only called to set idle_sp */ 1323 /* sometimes transfer is only called to set idle_sp */
1320 if (expect_false (!next)) 1324 if (expect_false (!next))
1321 { 1325 {
1322 ((coro_cctx *)prev)->idle_sp = (void *)stacklevel; 1326 ((coro_cctx *)prev)->idle_sp = STACKLEVEL;
1323 assert (((coro_cctx *)prev)->idle_te = PL_top_env); /* just for the side-effect when asserts are enabled */ 1327 assert (((coro_cctx *)prev)->idle_te = PL_top_env); /* just for the side-effect when asserts are enabled */
1324 } 1328 }
1325 else if (expect_true (prev != next)) 1329 else if (expect_true (prev != next))
1326 { 1330 {
1327 coro_cctx *prev__cctx; 1331 coro_cctx *prev__cctx;
1352 1356
1353 prev__cctx = prev->cctx; 1357 prev__cctx = prev->cctx;
1354 1358
1355 /* possibly untie and reuse the cctx */ 1359 /* possibly untie and reuse the cctx */
1356 if (expect_true ( 1360 if (expect_true (
1357 prev__cctx->idle_sp == (void *)stacklevel 1361 prev__cctx->idle_sp == STACKLEVEL
1358 && !(prev__cctx->flags & CC_TRACE) 1362 && !(prev__cctx->flags & CC_TRACE)
1359 && !force_cctx 1363 && !force_cctx
1360 )) 1364 ))
1361 { 1365 {
1362 /* I assume that stacklevel is a stronger indicator than PL_top_env changes */ 1366 /* I assume that stacklevel is a stronger indicator than PL_top_env changes */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines