From: Gurusamy Sarathy Date: Fri, 25 Feb 2000 19:23:58 +0000 (+0000) Subject: change#4849 wasn't restoring savestack correctly; make loops that have X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=1ba6ee2b6ffb90b7d229bcee46bded6dda6b3bcc;p=p5sagit%2Fp5-mst-13.2.git change#4849 wasn't restoring savestack correctly; make loops that have continue blocks recognizable at run time p4raw-link: @4849 on //depot/perl: 872465582bf743a066e1240f2c3e941735674827 p4raw-id: //depot/perl@5255 --- diff --git a/op.c b/op.c index 04a84b8..6ed38e4 100644 --- a/op.c +++ b/op.c @@ -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; diff --git a/op.h b/op.h index 6019486..52b68cb 100644 --- a/op.h +++ b/op.h @@ -139,6 +139,9 @@ Deprecated. Use C 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. */ diff --git a/pp_ctl.c b/pp_ctl.c index 308c824..5523592 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -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 46bbdea..ecc15ed 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; + } +}