summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGurusamy Sarathy <gsar@cpan.org>2000-04-24 08:43:24 +0000
committerGurusamy Sarathy <gsar@cpan.org>2000-04-24 08:43:24 +0000
commit855383171f82b0033b4163a01d30ba375967a9d0 (patch)
treea22da01cd6f1a18ac0b25aef643b0b5f678f618a
parent32b22042d2a54453bc0d4b6b7f1d2123903a49be (diff)
downloadperl-855383171f82b0033b4163a01d30ba375967a9d0.tar.gz
arrange for next() to resume at the unstack op rather than the
loop conditional, so that scope cleanup happens correctly (from Stephen McCamant) p4raw-id: //depot/perl@5927
-rw-r--r--op.c7
-rw-r--r--pp_ctl.c13
-rwxr-xr-xt/op/misc.t6
3 files changed, 16 insertions, 10 deletions
diff --git a/op.c b/op.c
index 1cfc6dde2a..64b80062b7 100644
--- a/op.c
+++ b/op.c
@@ -3848,7 +3848,10 @@ Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP *loop, I32 whileline, OP *
loopflags |= OPpLOOP_CONTINUE;
}
if (expr) {
- cont = append_elem(OP_LINESEQ, cont, newOP(OP_UNSTACK, 0));
+ OP *unstack = newOP(OP_UNSTACK, 0);
+ if (!next)
+ next = unstack;
+ cont = append_elem(OP_LINESEQ, cont, unstack);
if ((line_t)whileline != NOLINE) {
PL_copline = whileline;
cont = append_elem(OP_LINESEQ, cont,
@@ -3871,8 +3874,6 @@ Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP *loop, I32 whileline, OP *
if (listop)
((LISTOP*)listop)->op_last->op_next = condop =
(o == listop ? redo : LINKLIST(o));
- if (!next)
- next = condop;
}
else
o = listop;
diff --git a/pp_ctl.c b/pp_ctl.c
index e77901d502..d2e795f7ea 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1985,7 +1985,7 @@ PP(pp_next)
{
I32 cxix;
register PERL_CONTEXT *cx;
- I32 oldsave;
+ I32 inner;
if (PL_op->op_flags & OPf_SPECIAL) {
cxix = dopoptoloop(cxstack_ix);
@@ -2000,13 +2000,12 @@ PP(pp_next)
if (cxix < cxstack_ix)
dounwind(cxix);
+ /* clear off anything above the scope we're re-entering, but
+ * save the rest until after a possible continue block */
+ inner = PL_scopestack_ix;
TOPBLOCK(cx);
-
- /* clean scope, but only if there's no continue block */
- if (!(cx->blk_loop.last_op->op_private & OPpLOOP_CONTINUE)) {
- oldsave = PL_scopestack[PL_scopestack_ix - 1];
- LEAVE_SCOPE(oldsave);
- }
+ if (PL_scopestack_ix < inner)
+ leave_scope(PL_scopestack[PL_scopestack_ix]);
return cx->blk_loop.next_op;
}
diff --git a/t/op/misc.t b/t/op/misc.t
index ac1a44fadb..1673b273d7 100755
--- a/t/op/misc.t
+++ b/t/op/misc.t
@@ -545,3 +545,9 @@ ucfirst - World
lcfirst - world
uc - WORLD
lc - world
+########
+sub f { my $a = 1; my $b = 2; my $c = 3; my $d = 4; next }
+my $x = "foo";
+{ f } continue { print $x, "\n" }
+EXPECT
+foo