summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-10-17 12:56:15 +0100
committerDavid Mitchell <davem@iabyn.com>2016-02-03 09:18:30 +0000
commit1bef65a2c897ceb4139a39df14a8514b260493bd (patch)
tree84844d6a1097fd8fee39e093df06f2bc043955c8 /pp_ctl.c
parent8a1f10dd1e1964fa64cd0dff7196cf3f1f503ae1 (diff)
downloadperl-1bef65a2c897ceb4139a39df14a8514b260493bd.tar.gz
Eliminate cx->blk_loop.resetsp
Of all the loop types, only CXt_LOOP_LIST, i.e. for (1,2,3) {}, needs to keep anything on the stack, i.e. for all the others, cx->blk_loop.resetsp can always equal cx->blk_oldsp. For CXt_LOOP_LIST, the same value as resetsp is stored as blk_loop.state_u.stack.basesp. So we can eliminate the resetsp field. This is good as the loop substruct is the largest (ITHREADS) or joint largest with eval (non-threaded). Also, we now don't have to store that value for non-CXt_LOOP_LIST loops. The downside is we now have to choose between basesp and oldsp in pp_leaveloop and pp_last, based on CX type.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 16891abad5..b73c95cbbc 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2186,8 +2186,8 @@ PP(pp_enteriter)
if (PL_op->op_private & OPpITER_DEF)
cxflags |= CXp_FOR_DEF;
- PUSHBLOCK(cx, cxflags, SP);
- PUSHLOOP_FOR(cx, itervarp, itersave, MARK);
+ PUSHBLOCK(cx, cxflags, MARK);
+ PUSHLOOP_FOR(cx, itervarp, itersave);
if (PL_op->op_flags & OPf_STACKED) {
SV *maybe_ary = POPs;
if (SvTYPE(maybe_ary) != SVt_PVAV) {
@@ -2204,10 +2204,6 @@ PP(pp_enteriter)
DIE(aTHX_ "Range iterator outside integer range");
cx->blk_loop.state_u.lazyiv.cur = SvIV_nomg(sv);
cx->blk_loop.state_u.lazyiv.end = SvIV_nomg(right);
-#ifdef DEBUGGING
- /* for correct -Dstv display */
- cx->blk_oldsp = sp - PL_stack_base;
-#endif
}
else {
cx->cx_type |= CXt_LOOP_LAZYSV;
@@ -2239,6 +2235,7 @@ PP(pp_enteriter)
}
else { /* iterating over items on the stack */
cx->cx_type |= CXt_LOOP_LIST;
+ cx->blk_oldsp = SP - PL_stack_base;
cx->blk_loop.state_u.stack.basesp = MARK - PL_stack_base;
cx->blk_loop.state_u.stack.ix =
(PL_op->op_private & OPpITER_REVERSED)
@@ -2259,7 +2256,7 @@ PP(pp_enterloop)
const I32 gimme = GIMME_V;
PUSHBLOCK(cx, CXt_LOOP_PLAIN, SP);
- PUSHLOOP_PLAIN(cx, SP);
+ PUSHLOOP_PLAIN(cx);
RETURN;
}
@@ -2274,7 +2271,9 @@ PP(pp_leaveloop)
cx = &cxstack[cxstack_ix];
assert(CxTYPE_is_LOOP(cx));
mark = PL_stack_base + cx->blk_oldsp;
- newsp = PL_stack_base + cx->blk_loop.resetsp;
+ newsp = CxTYPE(cx) == CXt_LOOP_LIST
+ ? PL_stack_base + cx->blk_loop.state_u.stack.basesp
+ : mark;
gimme = cx->blk_gimme;
if (gimme == G_VOID)
@@ -2579,7 +2578,11 @@ PP(pp_last)
cx = &cxstack[cxstack_ix];
assert(CxTYPE_is_LOOP(cx));
- PL_stack_sp = PL_stack_base + cx->blk_loop.resetsp;
+ PL_stack_sp = PL_stack_base
+ + (CxTYPE(cx) == CXt_LOOP_LIST
+ ? cx->blk_loop.state_u.stack.basesp
+ : cx->blk_oldsp
+ );
TAINT_NOT;