Change the context type of for ($a .. $b) to CXt_LOOP_LAZYIV, and
Nicholas Clark [Thu, 24 Jan 2008 12:50:32 +0000 (12:50 +0000)]
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

cop.h
pp_ctl.c
pp_hot.c
scope.c
sv.c

diff --git a/cop.h b/cop.h
index 9129002..fd8e9fa 100644 (file)
--- 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
index c0f0724..7968eb9 100644 (file)
--- 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:
index a7657f8..ca0b4ab 100644 (file)
--- 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 (file)
--- 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 (file)
--- 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);