This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
split CXt_LOOP_FOR into CXt_LOOP_LIST,CXt_LOOP_ARY
authorDavid Mitchell <davem@iabyn.com>
Fri, 16 Oct 2015 23:18:44 +0000 (00:18 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 3 Feb 2016 09:18:29 +0000 (09:18 +0000)
Create a new context type so that "for (1,2,3)" and "for (@ary)"
are now two separate types.

For the list type, we store the index of the base stack element in the
state union rather than having an array pointer. Currently this is just
the same as blk_resetsp, but this will shortly allow us to eliminate the
resetsp field from the struct block_loop - which is currently the largest
sub-struct within the block union.

Having two separate types also allows the two cases to be handled directly
in the main switch in the hot pp_iter code, rather than having extra
conditionals.

cop.h
lib/B/Op_private.pm
opcode.h
perl.h
pp_ctl.c
pp_hot.c
regen/op_private
scope.c
sv.c

diff --git a/cop.h b/cop.h
index ae86211..05458c5 100644 (file)
--- a/cop.h
+++ b/cop.h
@@ -770,15 +770,19 @@ struct block_loop {
     } itervar_u;
     SV          *itersave; /* the original iteration var */
     union {
-       struct { /* valid if type is LOOP_FOR or LOOP_PLAIN (but {NULL,0})*/
-           AV * ary; /* use the stack if this is NULL */
-           IV ix;
+       struct { /* CXt_LOOP_ARY, C<for (@ary)>  */
+           AV *ary; /* array being iterated over */
+           IV  ix;   /* index relative to base of array */
        } ary;
-       struct { /* valid if type is LOOP_LAZYIV */
+       struct { /* CXt_LOOP_LIST, C<for (list)> */
+           I32 basesp; /* first element of list on stack */
+           IV  ix;      /* index relative to basesp */
+       } stack;
+       struct { /* CXt_LOOP_LAZYIV, C<for (1..9)> */
            IV cur;
            IV end;
        } lazyiv;
-       struct { /* valid if type if LOOP_LAZYSV */
+       struct { /* CXt_LOOP_LAZYSV C<for ('a'..'z')> */
            SV * cur;
            SV * end; /* maxiumum value (or minimum in reverse) */
        } lazysv;
@@ -822,8 +826,6 @@ struct block_loop {
 #define PUSHLOOP_FOR(cx, ivar, isave, s)                               \
        cx->blk_loop.resetsp = s - PL_stack_base;                       \
        cx->blk_loop.my_op = cLOOP;                                     \
-       cx->blk_loop.state_u.ary.ary = NULL;                            \
-       cx->blk_loop.state_u.ary.ix = 0;                                \
        cx->blk_loop.itervar_u.svp = (SV**)(ivar);                      \
         cx->cx_old_savestack_ix = PL_savestack_ix;                      \
         cx->blk_loop.itersave = isave;                                  \
@@ -834,7 +836,7 @@ struct block_loop {
            SvREFCNT_dec_NN(cx->blk_loop.state_u.lazysv.cur);           \
            SvREFCNT_dec_NN(cx->blk_loop.state_u.lazysv.end);           \
        }                                                               \
-       else if (CxTYPE(cx) == CXt_LOOP_FOR)                            \
+       else if (CxTYPE(cx) == CXt_LOOP_ARY)                            \
            SvREFCNT_dec(cx->blk_loop.state_u.ary.ary);                 \
         if (cx->cx_type & (CXp_FOR_PAD|CXp_FOR_GV)) {                   \
             SV *cursv;                                                  \
@@ -1035,15 +1037,19 @@ struct context {
    The first 4 don't have a 'case' in at least one switch statement in pp_ctl.c
 */
 #define CXt_GIVEN      3
-/* This is first so that CXt_LOOP_FOR|CXt_LOOP_LAZYIV is CXt_LOOP_LAZYIV */
-#define CXt_LOOP_FOR   4
-#define CXt_LOOP_PLAIN 5
-#define CXt_LOOP_LAZYSV        6
-#define CXt_LOOP_LAZYIV        7
-#define CXt_SUB                8
-#define CXt_FORMAT      9
-#define CXt_EVAL       10
-#define CXt_SUBST      11
+
+/* be careful of the ordering of these five. Macros like CxTYPE_is_LOOP,
+ * CxFOREACH compare ranges */
+#define CXt_LOOP_PLAIN 4 /*                {} */
+#define CXt_LOOP_LAZYIV        5 /* for (1..9)     {} */
+#define CXt_LOOP_LAZYSV        6 /* for ('a'..'z') {} */
+#define CXt_LOOP_LIST  7 /* for (1,2,3)    {} */
+#define CXt_LOOP_ARY   8 /* for (@ary)     {} */
+
+#define CXt_SUB                9
+#define CXt_FORMAT     10
+#define CXt_EVAL       11
+#define CXt_SUBST      12
 /* SUBST doesn't feature in all switch statements.  */
 
 /* private flags for CXt_SUB and CXt_FORMAT */
@@ -1068,15 +1074,15 @@ struct context {
 #define CXp_ONCE       0x10    /* What was sbu_once in struct subst */
 
 #define CxTYPE(c)      ((c)->cx_type & CXTYPEMASK)
-#define CxTYPE_is_LOOP(c)      (((c)->cx_type & 0xC) == 0x4)
+#define CxTYPE_is_LOOP(c) (   CxTYPE(cx) >= CXt_LOOP_PLAIN              \
+                           && CxTYPE(cx) <= CXt_LOOP_ARY)
 #define CxMULTICALL(c) ((c)->cx_type & CXp_MULTICALL)
 #define CxREALEVAL(c)  (((c)->cx_type & (CXTYPEMASK|CXp_REAL))         \
                         == (CXt_EVAL|CXp_REAL))
 #define CxTRYBLOCK(c)  (((c)->cx_type & (CXTYPEMASK|CXp_TRYBLOCK))     \
                         == (CXt_EVAL|CXp_TRYBLOCK))
-#define CxFOREACH(c)   (CxTYPE_is_LOOP(c) && CxTYPE(c) != CXt_LOOP_PLAIN)
-#define CxFOREACHDEF(c)        ((CxTYPE_is_LOOP(c) && CxTYPE(c) != CXt_LOOP_PLAIN) \
-                        && ((c)->cx_type & CXp_FOR_DEF))
+#define CxFOREACH(c)   (   CxTYPE(cx) >= CXt_LOOP_LAZYSV               \
+                         && CxTYPE(cx) <= CXt_LOOP_ARY)
 
 #define CXINC (cxstack_ix < cxstack_max ? ++cxstack_ix : (cxstack_ix = cxinc()))
 
index 85076ee..7825f79 100644 (file)
@@ -130,7 +130,7 @@ $bits{$_}{2} = 'OPpFT_STACKED' for qw(ftatime ftbinary ftblk ftchr ftctime ftdir
 $bits{$_}{3} = 'OPpFT_STACKING' for qw(ftatime ftbinary ftblk ftchr ftctime ftdir fteexec fteowned fteread ftewrite ftfile ftis ftlink ftmtime ftpipe ftrexec ftrowned ftrread ftrwrite ftsgid ftsize ftsock ftsuid ftsvtx fttext fttty ftzero);
 $bits{$_}{1} = 'OPpHINT_STRICT_REFS' for qw(entersub multideref rv2av rv2cv rv2gv rv2hv rv2sv);
 $bits{$_}{5} = 'OPpHUSH_VMSISH' for qw(dbstate nextstate);
-$bits{$_}{2} = 'OPpITER_REVERSED' for qw(enteriter iter);
+$bits{$_}{1} = 'OPpITER_REVERSED' for qw(enteriter iter);
 $bits{$_}{7} = 'OPpLVALUE' for qw(leave leaveloop);
 $bits{$_}{6} = 'OPpLVAL_DEFER' for qw(aelem helem multideref);
 $bits{$_}{7} = 'OPpLVAL_INTRO' for qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multideref padav padhv padrange padsv pushmark refassign rv2av rv2gv rv2hv rv2sv);
@@ -604,7 +604,7 @@ our %defines = (
     OPpHINT_STRICT_REFS      =>   2,
     OPpHUSH_VMSISH           =>  32,
     OPpITER_DEF              =>   8,
-    OPpITER_REVERSED         =>   4,
+    OPpITER_REVERSED         =>   2,
     OPpLIST_GUESSED          =>  64,
     OPpLVALUE                => 128,
     OPpLVAL_DEFER            =>  64,
index e711e65..5ec8f58 100644 (file)
--- a/opcode.h
+++ b/opcode.h
@@ -2190,6 +2190,7 @@ END_EXTERN_C
 #define OPpEVAL_HAS_HH          0x02
 #define OPpFT_ACCESS            0x02
 #define OPpHINT_STRICT_REFS     0x02
+#define OPpITER_REVERSED        0x02
 #define OPpSORT_INTEGER         0x02
 #define OPpTRANS_TO_UTF         0x02
 #define OPpARG2_MASK            0x03
@@ -2198,7 +2199,6 @@ END_EXTERN_C
 #define OPpENTERSUB_HASTARG     0x04
 #define OPpEVAL_UNICODE         0x04
 #define OPpFT_STACKED           0x04
-#define OPpITER_REVERSED        0x04
 #define OPpLVREF_ELEM           0x04
 #define OPpSLICEWARNING         0x04
 #define OPpSORT_REVERSE         0x04
@@ -2873,8 +2873,8 @@ EXTCONST U16  PL_op_private_bitdefs[] = {
     0x00bc, 0x012f, /* caller */
     0x21f5, /* nextstate, dbstate */
     0x29fc, 0x33d9, /* leave */
-    0x2b5c, 0x3078, 0x0e8c, 0x36e9, /* enteriter */
-    0x36e9, /* iter */
+    0x2b5c, 0x3078, 0x0e8c, 0x36e5, /* enteriter */
+    0x36e5, /* iter */
     0x29fc, 0x0067, /* leaveloop */
     0x41dc, 0x0003, /* last, next, redo, dump, goto */
     0x325c, 0x3178, 0x2634, 0x2570, 0x012f, /* open */
diff --git a/perl.h b/perl.h
index 960a8a5..46906af 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -5110,10 +5110,11 @@ EXTCONST char* const PL_block_type[] = {
        "WHEN",
        "BLOCK",
        "GIVEN",
-       "LOOP_FOR",
        "LOOP_PLAIN",
-       "LOOP_LAZYSV",
        "LOOP_LAZYIV",
+       "LOOP_LAZYSV",
+       "LOOP_LIST",
+       "LOOP_ARY",
        "SUB",
        "FORMAT",
        "EVAL",
index c283c65..e453ad7 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1266,10 +1266,11 @@ static const char * const context_name[] = {
     NULL, /* CXt_WHEN never actually needs "block" */
     NULL, /* CXt_BLOCK never actually needs "block" */
     NULL, /* CXt_GIVEN never actually needs "block" */
-    NULL, /* CXt_LOOP_FOR never actually needs "loop" */
     NULL, /* CXt_LOOP_PLAIN never actually needs "loop" */
-    NULL, /* CXt_LOOP_LAZYSV never actually needs "loop" */
     NULL, /* CXt_LOOP_LAZYIV never actually needs "loop" */
+    NULL, /* CXt_LOOP_LAZYSV never actually needs "loop" */
+    NULL, /* CXt_LOOP_LIST never actually needs "loop" */
+    NULL, /* CXt_LOOP_ARY never actually needs "loop" */
     "subroutine",
     "format",
     "eval",
@@ -1297,10 +1298,11 @@ S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags)
            if (CxTYPE(cx) == CXt_NULL) /* sort BLOCK */
                return -1;
            break;
+       case CXt_LOOP_PLAIN:
        case CXt_LOOP_LAZYIV:
        case CXt_LOOP_LAZYSV:
-       case CXt_LOOP_FOR:
-       case CXt_LOOP_PLAIN:
+       case CXt_LOOP_LIST:
+       case CXt_LOOP_ARY:
          {
             STRLEN cx_label_len = 0;
             U32 cx_label_flags = 0;
@@ -1444,10 +1446,11 @@ S_dopoptoloop(pTHX_ I32 startingblock)
            if ((CxTYPE(cx)) == CXt_NULL) /* sort BLOCK */
                return -1;
            break;
+       case CXt_LOOP_PLAIN:
        case CXt_LOOP_LAZYIV:
        case CXt_LOOP_LAZYSV:
-       case CXt_LOOP_FOR:
-       case CXt_LOOP_PLAIN:
+       case CXt_LOOP_LIST:
+       case CXt_LOOP_ARY:
            DEBUG_l( Perl_deb(aTHX_ "(dopoptoloop(): found loop at cx=%ld)\n", (long)i));
            return i;
        }
@@ -1470,12 +1473,13 @@ S_dopoptogivenfor(pTHX_ I32 startingblock)
            DEBUG_l( Perl_deb(aTHX_ "(dopoptogivenfor(): found given at cx=%ld)\n", (long)i));
            return i;
        case CXt_LOOP_PLAIN:
-           assert(!CxFOREACHDEF(cx));
+            assert(!(cx->cx_type & CXp_FOR_DEF));
            break;
        case CXt_LOOP_LAZYIV:
        case CXt_LOOP_LAZYSV:
-       case CXt_LOOP_FOR:
-           if (CxFOREACHDEF(cx)) {
+       case CXt_LOOP_LIST:
+       case CXt_LOOP_ARY:
+            if (cx->cx_type & CXp_FOR_DEF) {
                DEBUG_l( Perl_deb(aTHX_ "(dopoptogivenfor(): found foreach at cx=%ld)\n", (long)i));
                return i;
            }
@@ -1527,10 +1531,11 @@ Perl_dounwind(pTHX_ I32 cxix)
        case CXt_BLOCK:
             POPBASICBLK(cx);
            break;
+       case CXt_LOOP_PLAIN:
        case CXt_LOOP_LAZYIV:
        case CXt_LOOP_LAZYSV:
-       case CXt_LOOP_FOR:
-       case CXt_LOOP_PLAIN:
+       case CXt_LOOP_LIST:
+       case CXt_LOOP_ARY:
            POPLOOP(cx);
            break;
        case CXt_WHEN:
@@ -2142,7 +2147,7 @@ PP(pp_enteriter)
     const I32 gimme = GIMME_V;
     void *itervarp; /* GV or pad slot of the iteration variable */
     SV   *itersave; /* the old var in the iterator var slot */
-    U8 cxtype = CXt_LOOP_FOR;
+    U8 cxflags = 0;
 
     if (PL_op->op_targ) {                       /* "my" variable */
        itervarp = &PAD_SVl(PL_op->op_targ);
@@ -2155,7 +2160,7 @@ PP(pp_enteriter)
            SvPADSTALE_on(itersave);
        }
         SvREFCNT_inc_simple_void_NN(itersave);
-       cxtype |= CXp_FOR_PAD;
+       cxflags = CXp_FOR_PAD;
     }
     else {
        SV * const sv = POPs;
@@ -2167,37 +2172,33 @@ PP(pp_enteriter)
                 SvREFCNT_inc_simple_void_NN(itersave);
             else
                 *svp = newSV(0);
-            cxtype |= CXp_FOR_GV;
+            cxflags = CXp_FOR_GV;
         }
         else {                          /* LV ref: for \$foo (...) */
             assert(SvTYPE(sv) == SVt_PVMG);
             assert(SvMAGIC(sv));
             assert(SvMAGIC(sv)->mg_type == PERL_MAGIC_lvref);
             itersave = NULL;
-            cxtype |= CXp_FOR_LVREF;
+            cxflags = CXp_FOR_LVREF;
         }
     }
 
     if (PL_op->op_private & OPpITER_DEF)
-       cxtype |= CXp_FOR_DEF;
+       cxflags |= CXp_FOR_DEF;
 
-    PUSHBLOCK(cx, cxtype, SP);
+    PUSHBLOCK(cx, cxflags, SP);
     PUSHLOOP_FOR(cx, itervarp, itersave, MARK);
     if (PL_op->op_flags & OPf_STACKED) {
        SV *maybe_ary = POPs;
        if (SvTYPE(maybe_ary) != SVt_PVAV) {
            dPOPss;
            SV * const right = maybe_ary;
-           if (UNLIKELY(cxtype & CXp_FOR_LVREF))
+           if (UNLIKELY(cxflags & CXp_FOR_LVREF))
                DIE(aTHX_ "Assigned value is not a reference");
            SvGETMAGIC(sv);
            SvGETMAGIC(right);
            if (RANGE_IS_NUMERIC(sv,right)) {
-               cx->cx_type &= ~CXTYPEMASK;
                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);
                if (S_outside_integer(aTHX_ sv) ||
                     S_outside_integer(aTHX_ right))
                    DIE(aTHX_ "Range iterator outside integer range");
@@ -2209,11 +2210,7 @@ PP(pp_enteriter)
 #endif
            }
            else {
-               cx->cx_type &= ~CXTYPEMASK;
                cx->cx_type |= CXt_LOOP_LAZYSV;
-               /* Make sure that no-one re-orders cop.h and breaks our
-                  assumptions */
-               assert(CxTYPE(cx) == CXt_LOOP_LAZYSV);
                cx->blk_loop.state_u.lazysv.cur = newSVsv(sv);
                cx->blk_loop.state_u.lazysv.end = right;
                SvREFCNT_inc(right);
@@ -2230,6 +2227,7 @@ PP(pp_enteriter)
            }
        }
        else /* SvTYPE(maybe_ary) == SVt_PVAV */ {
+            cx->cx_type |= CXt_LOOP_ARY;
            cx->blk_loop.state_u.ary.ary = MUTABLE_AV(maybe_ary);
            SvREFCNT_inc(maybe_ary);
            cx->blk_loop.state_u.ary.ix =
@@ -2239,13 +2237,12 @@ PP(pp_enteriter)
        }
     }
     else { /* iterating over items on the stack */
-       cx->blk_loop.state_u.ary.ary = NULL; /* means to use the stack */
-       if (PL_op->op_private & OPpITER_REVERSED) {
-           cx->blk_loop.state_u.ary.ix = cx->blk_oldsp + 1;
-       }
-       else {
-           cx->blk_loop.state_u.ary.ix = MARK - PL_stack_base;
-       }
+        cx->cx_type |= CXt_LOOP_LIST;
+       cx->blk_loop.state_u.stack.basesp = MARK - PL_stack_base;
+        cx->blk_loop.state_u.stack.ix =
+            (PL_op->op_private & OPpITER_REVERSED)
+                ? cx->blk_oldsp + 1
+                : cx->blk_loop.state_u.stack.basesp;
     }
 
     RETURN;
@@ -2577,12 +2574,7 @@ PP(pp_last)
 
     cx = &cxstack[cxstack_ix];
 
-    assert(
-           CxTYPE(cx) == CXt_LOOP_LAZYIV
-        || CxTYPE(cx) == CXt_LOOP_LAZYSV
-        || CxTYPE(cx) == CXt_LOOP_FOR
-        || CxTYPE(cx) == CXt_LOOP_PLAIN
-    );
+    assert(CxTYPE_is_LOOP(cx));
     PL_stack_sp = PL_stack_base + cx->blk_loop.resetsp;
 
     TAINT_NOT;
@@ -2969,10 +2961,11 @@ PP(pp_goto)
                    break;
                 }
                 /* else fall through */
-           case CXt_LOOP_LAZYIV:
-           case CXt_LOOP_LAZYSV:
-           case CXt_LOOP_FOR:
-           case CXt_LOOP_PLAIN:
+            case CXt_LOOP_PLAIN:
+            case CXt_LOOP_LAZYIV:
+            case CXt_LOOP_LAZYSV:
+            case CXt_LOOP_LIST:
+            case CXt_LOOP_ARY:
            case CXt_GIVEN:
            case CXt_WHEN:
                gotoprobe = OpSIBLING(cx->blk_oldcop);
index 013eb98..524adeb 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -247,13 +247,7 @@ PP(pp_unstack)
     PL_stack_sp = PL_stack_base + cx->blk_oldsp;
     FREETMPS;
     if (!(PL_op->op_flags & OPf_SPECIAL)) {
-        assert(
-               CxTYPE(cx) == CXt_BLOCK
-            || CxTYPE(cx) == CXt_LOOP_FOR
-            || CxTYPE(cx) == CXt_LOOP_PLAIN
-            || CxTYPE(cx) == CXt_LOOP_LAZYSV
-            || CxTYPE(cx) == CXt_LOOP_LAZYIV
-        );
+        assert(CxTYPE(cx) == CXt_BLOCK || CxTYPE_is_LOOP(cx));
        CX_LEAVE_SCOPE(cx);
     }
     return NORMAL;
@@ -2702,28 +2696,37 @@ PP(pp_iter)
         break;
     }
 
-    case CXt_LOOP_FOR: /* iterate array */
     {
-
-        AV *av = cx->blk_loop.state_u.ary.ary;
         SV *sv;
-        bool av_is_stack = FALSE;
+        AV *av;
         IV ix;
+        IV inc;
 
-        if (!av) {
-            av_is_stack = TRUE;
-            av = PL_curstack;
-        }
-        if (PL_op->op_private & OPpITER_REVERSED) {
-            ix = --cx->blk_loop.state_u.ary.ix;
-            if (UNLIKELY(ix <= (av_is_stack ? cx->blk_loop.resetsp : -1)))
-                RETPUSHNO;
-        }
-        else {
-            ix = ++cx->blk_loop.state_u.ary.ix;
-            if (UNLIKELY(ix > (av_is_stack ? cx->blk_oldsp : AvFILL(av))))
-                RETPUSHNO;
-        }
+    case CXt_LOOP_LIST: /* for (1,2,3) */
+
+        assert(OPpITER_REVERSED == 2); /* so inc becomes -1 or 1 */
+        inc = 1 - (PL_op->op_private & OPpITER_REVERSED);
+        ix = (cx->blk_loop.state_u.stack.ix += inc);
+        if (UNLIKELY(inc > 0
+                        ? ix > cx->blk_oldsp
+                        : ix <= cx->blk_loop.state_u.stack.basesp)
+        )
+            RETPUSHNO;
+
+        sv = PL_stack_base[ix];
+        av = NULL;
+        goto loop_ary_common;
+
+    case CXt_LOOP_ARY: /* for (@ary) */
+
+        av = cx->blk_loop.state_u.ary.ary;
+        inc = 1 - (PL_op->op_private & OPpITER_REVERSED);
+        ix = (cx->blk_loop.state_u.ary.ix += inc);
+        if (UNLIKELY(inc > 0
+                        ? ix > AvFILL(av)
+                        : ix < 0)
+        )
+            RETPUSHNO;
 
         if (UNLIKELY(SvMAGICAL(av) || AvREIFY(av))) {
             SV * const * const svp = av_fetch(av, ix, FALSE);
@@ -2733,6 +2736,8 @@ PP(pp_iter)
             sv = AvARRAY(av)[ix];
         }
 
+      loop_ary_common:
+
         if (UNLIKELY(cx->cx_type & CXp_FOR_LVREF)) {
             SvSetMagicSV(*itersvp, sv);
             break;
@@ -2751,7 +2756,7 @@ PP(pp_iter)
                 SvREFCNT_inc_simple_void_NN(sv);
             }
         }
-        else if (!av_is_stack) {
+        else if (av) {
             sv = newSVavdefelem(av, ix, 0);
         }
         else
index ab63e11..a7f569e 100644 (file)
@@ -619,12 +619,13 @@ addbits('rv2gv',
 );
 
 
+# NB OPpITER_REVERSED must always be bit 1: see pp_iter()
 
 addbits('enteriter',
-                    2 => qw(OPpITER_REVERSED REVERSED),# for (reverse ...)
+                    1 => qw(OPpITER_REVERSED REVERSED),# for (reverse ...)
                     3 => qw(OPpITER_DEF      DEF),     # 'for $_'
 );
-addbits('iter',     2 => qw(OPpITER_REVERSED REVERSED));
+addbits('iter',     1 => qw(OPpITER_REVERSED REVERSED));
 
 
 
diff --git a/scope.c b/scope.c
index 375240e..08456d4 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -1366,10 +1366,11 @@ Perl_cx_dump(pTHX_ PERL_CONTEXT *cx)
                PTR2UV(cx->blk_eval.retop));
        break;
 
+    case CXt_LOOP_PLAIN:
     case CXt_LOOP_LAZYIV:
     case CXt_LOOP_LAZYSV:
-    case CXt_LOOP_FOR:
-    case CXt_LOOP_PLAIN:
+    case CXt_LOOP_LIST:
+    case CXt_LOOP_ARY:
        PerlIO_printf(Perl_debug_log, "BLK_LOOP.LABEL = %s\n", CxLABEL(cx));
        PerlIO_printf(Perl_debug_log, "BLK_LOOP.RESETSP = %ld\n",
                (long)cx->blk_loop.resetsp);
diff --git a/sv.c b/sv.c
index 558ecd5..48457b6 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -13969,10 +13969,11 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param)
                assert ((void *) &ncx->blk_loop.state_u.ary.ary ==
                        (void *) &ncx->blk_loop.state_u.lazysv.cur);
                 /* FALLTHROUGH */
-           case CXt_LOOP_FOR:
+           case CXt_LOOP_ARY:
                ncx->blk_loop.state_u.ary.ary
                    = av_dup_inc(ncx->blk_loop.state_u.ary.ary, param);
                 /* FALLTHROUGH */
+           case CXt_LOOP_LIST:
            case CXt_LOOP_LAZYIV:
            case CXt_LOOP_PLAIN:
                 /* code common to all CXt_LOOP_* types */