/* free all savestack items back to the watermark of the specified context */
-#define CX_LEAVE_SCOPE(cx) \
- LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix)
+#define CX_LEAVE_SCOPE(cx) LEAVE_SCOPE(cx->cx_old_savestack_ix)
/* base for the next two macros. Don't use directly.
* The context frame holds a reference to the CV so that it can't be
cx->blk_sub.prevcomppad = PL_comppad; \
cx->cx_type |= (hasargs) ? CXp_HASARGS : 0; \
cx->blk_sub.retop = NULL; \
- SvREFCNT_inc_simple_void_NN(cv); \
- cx->cx_u.cx_blk.blku_old_tmpsfloor = PL_tmps_floor; \
- PL_tmps_floor = PL_tmps_ix;
+ SvREFCNT_inc_simple_void_NN(cv);
#define PUSHSUB_GET_LVALUE_MASK(func) \
/* If the context is indeterminate, then only the lvalue */ \
cx->blk_format.dfoutgv = PL_defoutgv; \
cx->blk_format.prevcomppad = PL_comppad; \
cx->blk_u16 = 0; \
- cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix; \
- cx->cx_u.cx_blk.blku_old_tmpsfloor = PL_tmps_floor; \
- PL_tmps_floor = PL_tmps_ix; \
+ cx->cx_old_savestack_ix = PL_savestack_ix; \
SvREFCNT_inc_simple_void_NN(cv); \
CvDEPTH(cv)++; \
SvREFCNT_inc_void(cx->blk_format.dfoutgv)
#define POPSUB(cx) \
STMT_START { \
- CX_LEAVE_SCOPE(cx); \
if (!(cx->blk_u16 & CxPOPSUB_DONE)) { \
cx->blk_u16 |= CxPOPSUB_DONE; \
RETURN_PROBE(CvNAMED(cx->blk_sub.cv) \
#define POPFORMAT(cx) \
STMT_START { \
- CX_LEAVE_SCOPE(cx); \
if (!(cx->blk_u16 & CxPOPSUB_DONE)) { \
CV * const cv = cx->blk_format.cv; \
GV * const dfuot = cx->blk_format.dfoutgv; \
assert(!(PL_in_eval & ~0x7F)); \
assert(!(PL_op->op_type & ~0x1FF)); \
cx->blk_u16 = (PL_in_eval & 0x7F) | ((U16)PL_op->op_type << 7); \
- cx->cx_u.cx_blk.blku_old_tmpsfloor = PL_tmps_floor; \
- PL_tmps_floor = PL_tmps_ix; \
cx->blk_eval.old_namesv = (n ? newSVpv(n,0) : NULL); \
cx->blk_eval.old_eval_root = PL_eval_root; \
cx->blk_eval.cur_text = PL_parser ? PL_parser->linestr : NULL; \
#define POPEVAL(cx) \
STMT_START { \
- CX_LEAVE_SCOPE(cx); \
PL_in_eval = CxOLD_IN_EVAL(cx); \
optype = CxOLD_OP_TYPE(cx); \
PL_eval_root = cx->blk_eval.old_eval_root; \
cx->blk_loop.my_op = cLOOP; \
cx->blk_loop.state_u.ary.ary = NULL; \
cx->blk_loop.state_u.ary.ix = 0; \
- cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix; \
- cx->cx_u.cx_blk.blku_old_tmpsfloor = PL_tmps_floor; \
- PL_tmps_floor = PL_tmps_ix; \
+ cx->cx_old_savestack_ix = PL_savestack_ix; \
cx->blk_loop.itervar_u.svp = NULL; \
cx->blk_loop.itersave = NULL;
cx->blk_loop.state_u.ary.ary = NULL; \
cx->blk_loop.state_u.ary.ix = 0; \
cx->blk_loop.itervar_u.svp = (SV**)(ivar); \
- cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix; \
- cx->cx_u.cx_blk.blku_old_tmpsfloor = PL_tmps_floor; \
- PL_tmps_floor = PL_tmps_ix; \
+ cx->cx_old_savestack_ix = PL_savestack_ix; \
cx->blk_loop.itersave = isave; \
PUSHLOOP_FOR_setpad(cx);
#define POPLOOP(cx) \
- CX_LEAVE_SCOPE(cx); \
if (CxTYPE(cx) == CXt_LOOP_LAZYSV) { \
SvREFCNT_dec_NN(cx->blk_loop.state_u.lazysv.cur); \
SvREFCNT_dec_NN(cx->blk_loop.state_u.lazysv.end); \
};
#define PUSHWHEN(cx) \
- cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix; \
- cx->cx_u.cx_blk.blku_old_tmpsfloor = PL_tmps_floor; \
- PL_tmps_floor = PL_tmps_ix; \
+ cx->cx_old_savestack_ix = PL_savestack_ix; \
cx->blk_givwhen.leave_op = cLOGOP->op_other;
#define PUSHGIVEN(cx, orig_var) \
cx->blk_givwhen.defsv_save = orig_var;
#define POPWHEN(cx) \
- CX_LEAVE_SCOPE(cx);
+ NOOP;
#define POPGIVEN(cx) \
- CX_LEAVE_SCOPE(cx); \
SvREFCNT_dec(GvSV(PL_defgv)); \
GvSV(PL_defgv) = cx->blk_givwhen.defsv_save;
/* basic block, i.e. pp_enter/leave */
#define PUSHBASICBLK(cx) \
- cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix; \
- cx->cx_u.cx_blk.blku_old_tmpsfloor = PL_tmps_floor; \
- PL_tmps_floor = PL_tmps_ix;
+ cx->cx_old_savestack_ix = PL_savestack_ix;
#define POPBASICBLK(cx) \
- CX_LEAVE_SCOPE(cx);
+ NOOP;
/* context common to subroutines, evals and loops */
I32 blku_oldscopesp; /* scope stack index */
PMOP * blku_oldpm; /* values of pattern match vars */
SSize_t blku_old_tmpsfloor; /* saved PL_tmps_floor */
- I32 blku_old_savestack_ix; /* saved PL_savestack_ix */
union {
struct block_sub blku_sub;
(long)PL_scopestack_ix, \
(long)(cxstack[cxstack_ix].blk_oldscopesp), \
(long)PL_savestack_ix, \
- (long)(cxstack[cxstack_ix].cx_u.cx_blk.blku_old_savestack_ix),\
+ (long)(cxstack[cxstack_ix].cx_old_savestack_ix), \
__FILE__, __LINE__));
/* Enter a block. */
cx->blk_oldscopesp = PL_scopestack_ix, \
cx->blk_oldpm = PL_curpm, \
cx->blk_gimme = (U8)gimme; \
+ cx->cx_u.cx_blk.blku_old_tmpsfloor = PL_tmps_floor; \
+ PL_tmps_floor = PL_tmps_ix; \
DEBUG_CX("PUSH");
/* Exit a block (RETURN and LAST). */
/* LEAVE_SCOPE() should have made this true. /(?{})/ cheats
* and leaves a CX entry lying around for repeated use, so
* skip for multicall */ \
- assert((CxTYPE(cx) == CXt_SUB && CxMULTICALL(cx)) || \
- PL_savestack_ix == cx->cx_u.cx_blk.blku_old_savestack_ix); \
+ assert( (CxTYPE(cx) == CXt_SUB && CxMULTICALL(cx)) \
+ || PL_savestack_ix == cx->cx_old_savestack_ix); \
PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor; \
PL_curpm = cx->blk_oldpm;
U8 sbu_type; /* what kind of context this is */
U8 sbu_rflags;
U16 sbu_rxtainted; /* matches struct block */
- I32 sbu_oldsave;
SSize_t sbu_iters;
SSize_t sbu_maxiters;
char * sbu_orig;
#define sb_iters cx_u.cx_subst.sbu_iters
#define sb_maxiters cx_u.cx_subst.sbu_maxiters
#define sb_rflags cx_u.cx_subst.sbu_rflags
-#define sb_oldsave cx_u.cx_subst.sbu_oldsave
#define sb_rxtainted cx_u.cx_subst.sbu_rxtainted
#define sb_orig cx_u.cx_subst.sbu_orig
#define sb_dstr cx_u.cx_subst.sbu_dstr
#ifdef PERL_CORE
# define PUSHSUBST(cx) CXINC, cx = &cxstack[cxstack_ix], \
+ cx->cx_old_savestack_ix = oldsave, \
cx->sb_iters = iters, \
cx->sb_maxiters = maxiters, \
cx->sb_rflags = r_flags, \
- cx->sb_oldsave = oldsave, \
cx->sb_rxtainted = rxtainted, \
cx->sb_orig = orig, \
cx->sb_dstr = dstr, \
#define CxONCE(cx) ((cx)->cx_type & CXp_ONCE)
struct context {
+ I32 cx_old_savestack_ix; /* saved PL_savestack_ix */
union {
struct block cx_blk;
struct subst cx_subst;
PUSHSTACKi(PERLSI_MULTICALL); \
PUSHBLOCK(cx, (CXt_SUB|CXp_MULTICALL|flags), PL_stack_sp); \
PUSHSUB(cx); \
- cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix; \
+ cx->cx_old_savestack_ix = PL_savestack_ix; \
SAVEVPTR(PL_op); \
if (!(flags & CXp_SUB_RE_FAKE)) \
CvDEPTH(cv)++; \
STMT_START { \
cx = &cxstack[cxstack_ix]; \
CvDEPTH(multicall_cv) = cx->blk_sub.olddepth; \
- /* includes partial unrolled POPSUB(): */ \
CX_LEAVE_SCOPE(cx); \
+ /* includes partial unrolled POPSUB(): */ \
PL_comppad = cx->blk_sub.prevcomppad; \
PL_curpad = LIKELY(PL_comppad) ? AvARRAY(PL_comppad) : NULL; \
SvREFCNT_dec_NN(multicall_cv); \
{ \
/* save a few things that we don't want PUSHSUB to zap */ \
PAD * const prevcomppad = cx->blk_sub.prevcomppad; \
- SSize_t old_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor; \
- SSize_t floor = PL_tmps_floor; \
PUSHSUB(cx); \
/* undo the stuff that PUSHSUB zapped */ \
cx->blk_sub.prevcomppad = prevcomppad ; \
- cx->cx_u.cx_blk.blku_old_tmpsfloor = old_floor; \
- PL_tmps_floor = floor; \
} \
if (!(flags & CXp_SUB_RE_FAKE)) \
CvDEPTH(cv)++; \