summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2008-01-24 12:50:32 +0000
committerNicholas Clark <nick@ccl4.org>2008-01-24 12:50:32 +0000
commitc6fdafd0fef3b735d3a7b9441840698d27fe4e6b (patch)
tree908c7569373a36970a0c8fe3311798a60b514fe4
parent8b73ab1881b775e12ace39efe757716ab526e9db (diff)
downloadperl-c6fdafd0fef3b735d3a7b9441840698d27fe4e6b.tar.gz
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
-rw-r--r--cop.h9
-rw-r--r--pp_ctl.c13
-rw-r--r--pp_hot.c3
-rw-r--r--scope.c2
-rw-r--r--sv.c1
5 files changed, 23 insertions, 5 deletions
diff --git a/cop.h b/cop.h
index 91290024cd..fd8e9fa04d 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 c0f0724a39..7968eb971e 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 a7657f8648..ca0b4abc43 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 74a3be0d97..c8f190fc1c 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 1feaa3e9dc..33293a5eeb 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);