# define CopFILE_free(c) (SvREFCNT_dec(CopFILEGV(c)),(CopFILEGV(c) = NULL))
#endif /* USE_ITHREADS */
-#define CopLABEL(c) Perl_fetch_cop_label(aTHX_ (c)->cop_hints_hash, NULL, NULL)
+#define CopLABEL(c) Perl_fetch_cop_label(aTHX_ (c), NULL, NULL)
#define CopLABEL_alloc(pv) ((pv)?savepv(pv):NULL)
#define CopSTASH_ne(c,hv) (!CopSTASH_eq(c,hv))
struct block_loop {
I32 resetsp;
LOOP * my_op; /* My op, that contains redo, next and last ops. */
- /* (except for non_ithreads we need to modify next_op in pp_ctl.c, hence
- why next_op is conditionally defined below.) */
-#ifdef USE_ITHREADS
- PAD *oldcomppad; /* Also used for the GV, if targoffset is 0 */
- /* This is also accesible via cx->blk_loop.my_op->op_targ */
- PADOFFSET targoffset;
-#else
- OP * next_op;
- SV ** itervar;
-#endif
+ union { /* different ways of locating the iteration variable */
+ SV **svp;
+ GV *gv;
+ PAD *oldcomppad; /* only used in ITHREADS */
+ } itervar_u;
union {
struct { /* valid if type is LOOP_FOR or LOOP_PLAIN (but {NULL,0})*/
AV * ary; /* use the stack if this is NULL */
#ifdef USE_ITHREADS
# define CxITERVAR(c) \
- ((c)->blk_loop.oldcomppad \
+ ((c)->blk_loop.itervar_u.oldcomppad \
? (CxPADLOOP(c) \
- ? &CX_CURPAD_SV( (c)->blk_loop, (c)->blk_loop.targoffset ) \
- : &GvSV((GV*)(c)->blk_loop.oldcomppad)) \
+ ? &CX_CURPAD_SV( (c)->blk_loop.itervar_u, (c)->blk_loop.my_op->op_targ) \
+ : &GvSV((c)->blk_loop.itervar_u.gv)) \
: (SV**)NULL)
-# define CX_ITERDATA_SET(cx,idata,o) \
- if ((cx->blk_loop.targoffset = (o))) \
- CX_CURPAD_SAVE(cx->blk_loop); \
- else \
- cx->blk_loop.oldcomppad = (idata);
#else
-# define CxITERVAR(c) ((c)->blk_loop.itervar)
-# define CX_ITERDATA_SET(cx,ivar,o) \
- cx->blk_loop.itervar = (SV**)(ivar);
+# define CxITERVAR(c) ((c)->blk_loop.itervar_u.svp)
#endif
#define CxLABEL(c) (0 + CopLABEL((c)->blk_oldcop))
#define CxHASARGS(c) (((c)->cx_type & CXp_HASARGS) == CXp_HASARGS)
#define CxLVAL(c) (0 + (c)->blk_u16)
-#ifdef USE_ITHREADS
-# define PUSHLOOP_OP_NEXT /* No need to do anything. */
-# define CX_LOOP_NEXTOP_GET(cx) ((cx)->blk_loop.my_op->op_nextop + 0)
-#else
-# define PUSHLOOP_OP_NEXT cx->blk_loop.next_op = cLOOP->op_nextop
-# define CX_LOOP_NEXTOP_GET(cx) ((cx)->blk_loop.next_op + 0)
-#endif
-
#define PUSHLOOP_PLAIN(cx, s) \
cx->blk_loop.resetsp = s - PL_stack_base; \
cx->blk_loop.my_op = cLOOP; \
- PUSHLOOP_OP_NEXT; \
cx->blk_loop.state_u.ary.ary = NULL; \
cx->blk_loop.state_u.ary.ix = 0; \
- CX_ITERDATA_SET(cx, NULL, 0);
+ cx->blk_loop.itervar_u.svp = NULL;
-#define PUSHLOOP_FOR(cx, dat, s, offset) \
+#define PUSHLOOP_FOR(cx, ivar, s) \
cx->blk_loop.resetsp = s - PL_stack_base; \
cx->blk_loop.my_op = cLOOP; \
- PUSHLOOP_OP_NEXT; \
cx->blk_loop.state_u.ary.ary = NULL; \
cx->blk_loop.state_u.ary.ix = 0; \
- CX_ITERDATA_SET(cx, dat, offset);
+ cx->blk_loop.itervar_u.svp = (SV**)(ivar);
#define POPLOOP(cx) \
if (CxTYPE(cx) == CXt_LOOP_LAZYSV) { \
#define blk_givwhen cx_u.cx_blk.blk_u.blku_givwhen
#define DEBUG_CX(action) \
- DEBUG_l(WITH_THX( \
+ DEBUG_l( \
Perl_deb(aTHX_ "CX %ld %s %s (scope %ld,%ld) at %s:%d\n", \
(long)cxstack_ix, \
action, \
PL_block_type[CxTYPE(&cxstack[cxstack_ix])], \
(long)PL_scopestack_ix, \
(long)(cxstack[cxstack_ix].blk_oldscopesp), \
- __FILE__, __LINE__)));
+ __FILE__, __LINE__));
/* Enter a block. */
#define PUSHBLOCK(cx,t,sp) CXINC, cx = &cxstack[cxstack_ix], \
/* private flags for CXt_LOOP */
#define CXp_FOR_DEF 0x10 /* foreach using $_ */
#ifdef USE_ITHREADS
-# define CxPADLOOP(c) ((c)->blk_loop.targoffset)
+# define CxPADLOOP(c) ((c)->blk_loop.my_op->op_targ)
#endif
/* private flags for CXt_SUBST */
hash actions codes defined in hv.h */
#define G_EVAL 8 /* Assume eval {} around subroutine call. */
#define G_NOARGS 16 /* Don't construct a @_ array. */
-#define G_KEEPERR 32 /* Append errors to $@, don't overwrite it */
+#define G_KEEPERR 32 /* Warn for errors, don't overwrite $@ */
#define G_NODEBUG 64 /* Disable debugging at toplevel. */
#define G_METHOD 128 /* Calling method. */
#define G_FAKINGEVAL 256 /* Faking an eval context for call_sv or