summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cop.h17
-rw-r--r--pp_ctl.c51
-rw-r--r--pp_hot.c14
3 files changed, 35 insertions, 47 deletions
diff --git a/cop.h b/cop.h
index d455478396..afaea1a077 100644
--- a/cop.h
+++ b/cop.h
@@ -796,6 +796,8 @@ struct block_loop {
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->blk_loop.itervar_u.svp = NULL; \
cx->blk_loop.itersave = NULL;
@@ -812,6 +814,8 @@ struct block_loop {
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->blk_loop.itersave = isave; \
PUSHLOOP_FOR_setpad(cx);
@@ -831,7 +835,8 @@ struct block_loop {
cursv = *svp; \
*svp = cx->blk_loop.itersave; \
SvREFCNT_dec(cursv); \
- }
+ } \
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
/* given/when context */
struct block_givwhen {
@@ -840,6 +845,9 @@ struct block_givwhen {
};
#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->blk_givwhen.leave_op = cLOGOP->op_other;
#define PUSHGIVEN(cx, orig_var) \
@@ -847,11 +855,14 @@ struct block_givwhen {
cx->blk_givwhen.defsv_save = orig_var;
#define POPWHEN(cx) \
- NOOP;
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix); \
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
#define POPGIVEN(cx) \
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix); \
SvREFCNT_dec(GvSV(PL_defgv)); \
- GvSV(PL_defgv) = cx->blk_givwhen.defsv_save;
+ GvSV(PL_defgv) = cx->blk_givwhen.defsv_save; \
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
/* context common to subroutines, evals and loops */
diff --git a/pp_ctl.c b/pp_ctl.c
index e400c5786d..518b7558f2 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1519,6 +1519,8 @@ Perl_dounwind(pTHX_ I32 cxix)
break;
case CXt_EVAL:
POPEVAL(cx);
+ /* FALLTHROUGH */
+ case CXt_BLOCK:
LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
break;
@@ -2060,10 +2062,10 @@ PP(pp_enter)
PERL_CONTEXT *cx;
I32 gimme = GIMME_V;
- ENTER_with_name("block");
-
- SAVETMPS;
PUSHBLOCK(cx, CXt_BLOCK, SP);
+ 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;
RETURN;
}
@@ -2090,9 +2092,10 @@ PP(pp_leave)
: leave_common(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP,
PL_op->op_private & OPpLVALUE);
- PL_curpm = newpm; /* Don't pop $1 et al till now */
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
+ PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
- LEAVE_with_name("block");
+ PL_curpm = newpm; /* Don't pop $1 et al till now */
RETURN;
}
@@ -2128,9 +2131,6 @@ PP(pp_enteriter)
SV *itersave; /* the old var in the iterator var slot */
U8 cxtype = CXt_LOOP_FOR;
- ENTER_with_name("loop1");
- SAVETMPS;
-
if (PL_op->op_targ) { /* "my" variable */
itervarp = &PAD_SVl(PL_op->op_targ);
itersave = *(SV**)itervarp;
@@ -2168,8 +2168,6 @@ PP(pp_enteriter)
if (PL_op->op_private & OPpITER_DEF)
cxtype |= CXp_FOR_DEF;
- ENTER_with_name("loop2");
-
PUSHBLOCK(cx, cxtype, SP);
PUSHLOOP_FOR(cx, itervarp, itersave, MARK);
if (PL_op->op_flags & OPf_STACKED) {
@@ -2246,10 +2244,6 @@ PP(pp_enterloop)
PERL_CONTEXT *cx;
const I32 gimme = GIMME_V;
- ENTER_with_name("loop1");
- SAVETMPS;
- ENTER_with_name("loop2");
-
PUSHBLOCK(cx, CXt_LOOP_PLAIN, SP);
PUSHLOOP_PLAIN(cx, SP);
@@ -2279,9 +2273,6 @@ PP(pp_leaveloop)
POPLOOP(cx); /* Stack values are safe: release loop vars ... */
PL_curpm = newpm; /* ... and pop $1 et al */
- LEAVE_with_name("loop2");
- LEAVE_with_name("loop1");
-
return NORMAL;
}
@@ -2578,11 +2569,9 @@ PP(pp_last)
TAINT_NOT;
PL_stack_sp = newsp;
- LEAVE_with_name("loop2");
cxstack_ix--;
/* Stack values are safe: */
POPLOOP(cx); /* release loop vars ... */
- LEAVE_with_name("loop1");
PL_curpm = newpm; /* ... and pop $1 et al */
PERL_UNUSED_VAR(gimme);
@@ -2592,15 +2581,10 @@ PP(pp_last)
PP(pp_next)
{
PERL_CONTEXT *cx;
- const I32 inner = PL_scopestack_ix;
S_unwind_loop(aTHX_ "next");
- /* clear off anything above the scope we're re-entering, but
- * save the rest until after a possible continue block */
TOPBLOCK(cx);
- if (PL_scopestack_ix < inner)
- leave_scope(PL_scopestack[PL_scopestack_ix]);
PL_curcop = cx->blk_oldcop;
PERL_ASYNC_CHECK();
return (cx)->blk_loop.my_op->op_nextop;
@@ -2610,7 +2594,6 @@ PP(pp_redo)
{
const I32 cxix = S_unwind_loop(aTHX_ "redo");
PERL_CONTEXT *cx;
- I32 oldsave;
OP* redo_op = cxstack[cxix].blk_loop.my_op->op_redoop;
if (redo_op->op_type == OP_ENTER) {
@@ -2621,8 +2604,7 @@ PP(pp_redo)
}
TOPBLOCK(cx);
- oldsave = PL_scopestack[PL_scopestack_ix - 1];
- LEAVE_SCOPE(oldsave);
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
FREETMPS;
PL_curcop = cx->blk_oldcop;
PERL_ASYNC_CHECK();
@@ -3051,14 +3033,10 @@ PP(pp_goto)
/* pop unwanted frames */
if (ix < cxstack_ix) {
- I32 oldsave;
-
if (ix < 0)
DIE(aTHX_ "panic: docatch: illegal ix=%ld", (long)ix);
dounwind(ix);
TOPBLOCK(cx);
- oldsave = PL_scopestack[PL_scopestack_ix];
- LEAVE_SCOPE(oldsave);
}
/* push wanted frames */
@@ -4419,9 +4397,6 @@ PP(pp_entergiven)
SV *origsv = DEFSV;
SV *newsv = POPs;
- ENTER_with_name("given");
- SAVETMPS;
-
assert(!PL_op->op_targ); /* used to be set for lexical $_ */
GvSV(PL_defgv) = SvREFCNT_inc(newsv);
@@ -4450,7 +4425,6 @@ PP(pp_leavegiven)
PL_curpm = newpm; /* Don't pop $1 et al till now */
- LEAVE_with_name("given");
RETURN;
}
@@ -5003,9 +4977,6 @@ PP(pp_enterwhen)
if ((0 == (PL_op->op_flags & OPf_SPECIAL)) && !SvTRUEx(POPs))
RETURNOP(cLOGOP->op_other->op_next);
- ENTER_with_name("when");
- SAVETMPS;
-
PUSHBLOCK(cx, CXt_WHEN, SP);
PUSHWHEN(cx);
@@ -5037,8 +5008,6 @@ PP(pp_leavewhen)
PL_curpm = newpm; /* pop $1 et al */
- LEAVE_with_name("when");
-
if (cxix < cxstack_ix)
dounwind(cxix);
@@ -5082,11 +5051,11 @@ PP(pp_continue)
POPBLOCK(cx,newpm);
assert(CxTYPE(cx) == CXt_WHEN);
+ POPWHEN(cx);
SP = newsp;
PL_curpm = newpm; /* pop $1 et al */
- LEAVE_with_name("when");
RETURNOP(cx->blk_givwhen.leave_op->op_next);
}
diff --git a/pp_hot.c b/pp_hot.c
index 6568ca1a17..fce942bd53 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -240,13 +240,21 @@ PP(pp_cond_expr)
PP(pp_unstack)
{
+ PERL_CONTEXT *cx;
PERL_ASYNC_CHECK();
TAINT_NOT; /* Each statement is presumed innocent */
- PL_stack_sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;
+ cx = &cxstack[cxstack_ix];
+ PL_stack_sp = PL_stack_base + cx->blk_oldsp;
FREETMPS;
if (!(PL_op->op_flags & OPf_SPECIAL)) {
- I32 oldsave = PL_scopestack[PL_scopestack_ix - 1];
- LEAVE_SCOPE(oldsave);
+ assert(
+ CxTYPE(cx) == CXt_BLOCK
+ || CxTYPE(cx) == CXt_LOOP_FOR
+ || CxTYPE(cx) == CXt_LOOP_PLAIN
+ || CxTYPE(cx) == CXt_LOOP_LAZYSV
+ || CxTYPE(cx) == CXt_LOOP_LAZYIV
+ );
+ LEAVE_SCOPE(cx->cx_u.cx_blk.blku_old_savestack_ix);
}
return NORMAL;
}