From: Nicholas Clark Date: Thu, 24 Jan 2008 12:50:32 +0000 (+0000) Subject: Change the context type of for ($a .. $b) to CXt_LOOP_LAZYIV, and X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=c6fdafd0fef3b735d3a7b9441840698d27fe4e6b;p=p5sagit%2Fp5-mst-13.2.git Change the context type of for ($a .. $b) to CXt_LOOP_LAZYIV, and assert that it isn't using cx->blk_loop.iterlval. Fix a casting bug when assigning a sentinal to cx->blk_loop.iterary. p4raw-id: //depot/perl@33061 --- diff --git a/cop.h b/cop.h index 9129002..fd8e9fa 100644 --- a/cop.h +++ b/cop.h @@ -518,6 +518,8 @@ struct block_loop { CX_ITERDATA_SET(cx,dat); #define POPLOOP(cx) \ + if (CxTYPE(cx) == CXt_LOOP_LAZYIV) \ + assert(!cx->blk_loop.iterlval); \ SvREFCNT_dec(cx->blk_loop.iterlval); \ if (CxITERVAR(cx)) { \ if (SvPADMY(cx->blk_loop.itersave)) { \ @@ -679,11 +681,12 @@ struct context { #define CXt_BLOCK 5 #define CXt_FORMAT 6 #define CXt_GIVEN 7 -#define CXt_LOOP_PLAIN 8 -#define CXt_LOOP_FOR 9 +/* This is first so that CXt_LOOP_FOR|CXt_LOOP_LAZYIV is CXt_LOOP_LAZYIV */ +#define CXt_LOOP_FOR 8 +#define CXt_LOOP_PLAIN 9 /* Foreach on a temporary list on the stack */ #define CXt_LOOP_STACK 10 -#define CXt_LOOP_RES2 11 +#define CXt_LOOP_LAZYIV 11 /* private flags for CXt_SUB and CXt_NULL However, this is checked in many places which do not check the type, so diff --git a/pp_ctl.c b/pp_ctl.c index c0f0724..7968eb9 100644 --- a/pp_ctl.c +++ b/pp_ctl.c @@ -1256,6 +1256,7 @@ S_dopoptolabel(pTHX_ const char *label) if (CxTYPE(cx) == CXt_NULL) return -1; break; + case CXt_LOOP_LAZYIV: case CXt_LOOP_STACK: case CXt_LOOP_FOR: case CXt_LOOP_PLAIN: @@ -1373,6 +1374,7 @@ S_dopoptoloop(pTHX_ I32 startingblock) if ((CxTYPE(cx)) == CXt_NULL) return -1; break; + case CXt_LOOP_LAZYIV: case CXt_LOOP_STACK: case CXt_LOOP_FOR: case CXt_LOOP_PLAIN: @@ -1399,6 +1401,7 @@ S_dopoptogiven(pTHX_ I32 startingblock) case CXt_LOOP_PLAIN: assert(!CxFOREACHDEF(cx)); break; + case CXt_LOOP_LAZYIV: case CXt_LOOP_STACK: case CXt_LOOP_FOR: if (CxFOREACHDEF(cx)) { @@ -1451,6 +1454,7 @@ Perl_dounwind(pTHX_ I32 cxix) case CXt_EVAL: POPEVAL(cx); break; + case CXt_LOOP_LAZYIV: case CXt_LOOP_STACK: case CXt_LOOP_FOR: case CXt_LOOP_PLAIN: @@ -1884,6 +1888,10 @@ PP(pp_enteriter) SvGETMAGIC(sv); SvGETMAGIC(right); if (RANGE_IS_NUMERIC(sv,right)) { + cx->cx_type |= CXt_LOOP_LAZYIV; + /* Make sure that no-one re-orders cop.h and breaks our + assumptions */ + assert(CxTYPE(cx) == CXt_LOOP_LAZYIV); #ifdef NV_PRESERVES_UV if ((SvOK(sv) && ((SvNV(sv) < (NV)IV_MIN) || (SvNV(sv) > (NV)IV_MAX))) @@ -1924,7 +1932,7 @@ PP(pp_enteriter) } } else { - cx->blk_loop.iterary = (SV*)0xDEADBEEF; + cx->blk_loop.iterary = (AV*)0xDEADBEEF; if (PL_op->op_private & OPpITER_REVERSED) { cx->blk_loop.itermax = MARK - PL_stack_base + 1; cx->blk_loop.iterix = cx->blk_oldsp + 1; @@ -2150,6 +2158,7 @@ PP(pp_last) cxstack_ix++; /* temporarily protect top context */ mark = newsp; switch (CxTYPE(cx)) { + case CXt_LOOP_LAZYIV: case CXt_LOOP_STACK: case CXt_LOOP_FOR: case CXt_LOOP_PLAIN: @@ -2195,6 +2204,7 @@ PP(pp_last) cxstack_ix--; /* Stack values are safe: */ switch (pop2) { + case CXt_LOOP_LAZYIV: case CXt_LOOP_PLAIN: case CXt_LOOP_STACK: case CXt_LOOP_FOR: @@ -2555,6 +2565,7 @@ PP(pp_goto) break; } /* else fall through */ + case CXt_LOOP_LAZYIV: case CXt_LOOP_STACK: case CXt_LOOP_FOR: case CXt_LOOP_PLAIN: diff --git a/pp_hot.c b/pp_hot.c index a7657f8..ca0b4ab 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -1914,7 +1914,7 @@ PP(pp_iter) av = CxTYPE(cx) == CXt_LOOP_STACK ? PL_curstack : cx->blk_loop.iterary; if (SvTYPE(av) != SVt_PVAV) { /* iterate ($min .. $max) */ - if (cx->blk_loop.iterlval) { + if (CxTYPE(cx) != CXt_LOOP_LAZYIV) { /* string increment */ register SV* cur = cx->blk_loop.iterlval; STRLEN maxlen = 0; @@ -1944,6 +1944,7 @@ PP(pp_iter) RETPUSHNO; } /* integer increment */ + assert(!cx->blk_loop.iterlval); if (cx->blk_loop.iterix > cx->blk_loop.itermax) RETPUSHNO; diff --git a/scope.c b/scope.c index 74a3be0..c8f190f 100644 --- a/scope.c +++ b/scope.c @@ -1083,6 +1083,8 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx) PTR2UV(cx->blk_eval.retop)); break; + case CXt_LOOP_LAZYIV: + case CXt_LOOP_STACK: case CXt_LOOP_FOR: case CXt_LOOP_PLAIN: PerlIO_printf(Perl_debug_log, "BLK_LOOP.LABEL = %s\n", CxLABEL(cx)); diff --git a/sv.c b/sv.c index 1feaa3e..33293a5 100644 --- a/sv.c +++ b/sv.c @@ -10542,6 +10542,7 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param) param); ncx->blk_eval.cur_text = sv_dup(ncx->blk_eval.cur_text, param); break; + case CXt_LOOP_LAZYIV: case CXt_LOOP_FOR: ncx->blk_loop.iterary = av_dup_inc(ncx->blk_loop.iterary, param);