diff options
-rw-r--r-- | op.c | 6 | ||||
-rw-r--r-- | op.h | 3 | ||||
-rw-r--r-- | pp_ctl.c | 17 | ||||
-rwxr-xr-x | t/cmd/while.t | 19 |
4 files changed, 33 insertions, 12 deletions
@@ -3764,6 +3764,7 @@ Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP *loop, I32 whileline, OP * OP *listop; OP *o; OP *condop; + U8 loopflags = 0; if (expr && (expr->op_type == OP_READLINE || expr->op_type == OP_GLOB || (expr->op_type == OP_NULL && expr->op_targ == OP_GLOB))) { @@ -3796,8 +3797,10 @@ Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP *loop, I32 whileline, OP * block = scope(block); } - if (cont) + if (cont) { next = LINKLIST(cont); + loopflags |= OPpLOOP_CONTINUE; + } if (expr) { cont = append_elem(OP_LINESEQ, cont, newOP(OP_UNSTACK, 0)); if ((line_t)whileline != NOLINE) { @@ -3840,6 +3843,7 @@ Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP *loop, I32 whileline, OP * loop->op_redoop = redo; loop->op_lastop = o; + o->op_private |= loopflags; if (next) loop->op_nextop = next; @@ -139,6 +139,9 @@ Deprecated. Use C<GIMME_V> instead. /* Private for OP_REPEAT */ #define OPpREPEAT_DOLIST 64 /* List replication. */ +/* Private for OP_LEAVELOOP */ +#define OPpLOOP_CONTINUE 64 /* a continue block is present */ + /* Private for OP_RV2?V, OP_?ELEM */ #define OPpDEREF (32|64) /* Want ref to something: */ #define OPpDEREF_AV 32 /* Want ref to AV. */ @@ -1983,17 +1983,14 @@ PP(pp_next) if (cxix < cxstack_ix) dounwind(cxix); - cx = &cxstack[cxstack_ix]; - { - OP *nextop = cx->blk_loop.next_op; - /* clean scope, but only if there's no continue block */ - if (nextop == cUNOPx(cx->blk_loop.last_op)->op_first->op_next) { - TOPBLOCK(cx); - oldsave = PL_scopestack[PL_scopestack_ix - 1]; - LEAVE_SCOPE(oldsave); - } - return nextop; + 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); } + return cx->blk_loop.next_op; } PP(pp_redo) diff --git a/t/cmd/while.t b/t/cmd/while.t index 46bbdea15a..ecc15eda53 100755 --- a/t/cmd/while.t +++ b/t/cmd/while.t @@ -1,6 +1,6 @@ #!./perl -print "1..19\n"; +print "1..22\n"; open (tmp,'>Cmd_while.tmp') || die "Can't create Cmd_while.tmp."; print tmp "tvi925\n"; @@ -160,3 +160,20 @@ print "ok $i\n"; print "ok $l\n" } } + +$i = 20; +{ + while (1) { + my $x; + print $x if defined $x; + $x = "not "; + print "ok $i\n"; ++$i; + if ($i == 21) { + next; + } + last; + } + continue { + print "ok $i\n"; ++$i; + } +} |