arrange for next() to resume at the unstack op rather than the
Gurusamy Sarathy [Mon, 24 Apr 2000 08:43:24 +0000 (08:43 +0000)]
loop conditional, so that scope cleanup happens correctly
(from Stephen McCamant)

p4raw-id: //depot/perl@5927

op.c
pp_ctl.c
t/op/misc.t

diff --git a/op.c b/op.c
index 1cfc6dd..64b8006 100644 (file)
--- 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;
index e77901d..d2e795f 100644 (file)
--- 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;
 }
 
index ac1a44f..1673b27 100755 (executable)
@@ -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