Remove the _ prototype, as Maintainers is used by makemeta, and in turn
[p5sagit/p5-mst-13.2.git] / pp_ctl.c
index 2419f27..b0ffcb5 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -1256,6 +1256,8 @@ S_dopoptolabel(pTHX_ const char *label)
            if (CxTYPE(cx) == CXt_NULL)
                return -1;
            break;
+       case CXt_LOOP_LAZYIV:
+       case CXt_LOOP_LAZYSV:
        case CXt_LOOP_FOR:
        case CXt_LOOP_PLAIN:
            if ( !CxLABEL(cx) || strNE(label, CxLABEL(cx)) ) {
@@ -1372,6 +1374,8 @@ S_dopoptoloop(pTHX_ I32 startingblock)
            if ((CxTYPE(cx)) == CXt_NULL)
                return -1;
            break;
+       case CXt_LOOP_LAZYIV:
+       case CXt_LOOP_LAZYSV:
        case CXt_LOOP_FOR:
        case CXt_LOOP_PLAIN:
            DEBUG_l( Perl_deb(aTHX_ "(Found loop #%ld)\n", (long)i));
@@ -1397,6 +1401,8 @@ S_dopoptogiven(pTHX_ I32 startingblock)
        case CXt_LOOP_PLAIN:
            assert(!CxFOREACHDEF(cx));
            break;
+       case CXt_LOOP_LAZYIV:
+       case CXt_LOOP_LAZYSV:
        case CXt_LOOP_FOR:
            if (CxFOREACHDEF(cx)) {
                DEBUG_l( Perl_deb(aTHX_ "(Found foreach #%ld)\n", (long)i));
@@ -1448,6 +1454,8 @@ Perl_dounwind(pTHX_ I32 cxix)
        case CXt_EVAL:
            POPEVAL(cx);
            break;
+       case CXt_LOOP_LAZYIV:
+       case CXt_LOOP_LAZYSV:
        case CXt_LOOP_FOR:
        case CXt_LOOP_PLAIN:
            POPLOOP(cx);
@@ -1827,9 +1835,9 @@ PP(pp_enteriter)
     register PERL_CONTEXT *cx;
     const I32 gimme = GIMME_V;
     SV **svp;
-    U16 cxtype = CXt_LOOP_FOR;
+    U8 cxtype = CXt_LOOP_FOR;
 #ifdef USE_ITHREADS
-    void *iterdata;
+    PAD *iterdata;
 #endif
 
     ENTER;
@@ -1841,13 +1849,11 @@ PP(pp_enteriter)
            SAVESETSVFLAGS(PAD_SVl(PL_op->op_targ),
                    SVs_PADSTALE, SVs_PADSTALE);
        }
+       SAVEPADSVANDMORTALIZE(PL_op->op_targ);
 #ifndef USE_ITHREADS
        svp = &PAD_SVl(PL_op->op_targ);         /* "my" variable */
-       SAVESPTR(*svp);
 #else
-       SAVEPADSV(PL_op->op_targ);
-       iterdata = INT2PTR(void*, PL_op->op_targ);
-       cxtype |= CXp_PADVAR;
+       iterdata = NULL;
 #endif
     }
     else {
@@ -1856,7 +1862,7 @@ PP(pp_enteriter)
        SAVEGENERICSV(*svp);
        *svp = newSV(0);
 #ifdef USE_ITHREADS
-       iterdata = (void*)gv;
+       iterdata = (PAD*)gv;
 #endif
     }
 
@@ -1867,18 +1873,23 @@ PP(pp_enteriter)
 
     PUSHBLOCK(cx, cxtype, SP);
 #ifdef USE_ITHREADS
-    PUSHLOOP_FOR(cx, iterdata, MARK);
+    PUSHLOOP_FOR(cx, iterdata, MARK, PL_op->op_targ);
 #else
-    PUSHLOOP_FOR(cx, svp, MARK);
+    PUSHLOOP_FOR(cx, svp, MARK, 0);
 #endif
     if (PL_op->op_flags & OPf_STACKED) {
-       cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs);
-       if (SvTYPE(cx->blk_loop.iterary) != SVt_PVAV) {
+       SV *maybe_ary = POPs;
+       if (SvTYPE(maybe_ary) != SVt_PVAV) {
            dPOPss;
-           SV * const right = (SV*)cx->blk_loop.iterary;
+           SV * const right = maybe_ary;
            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);
 #ifdef NV_PRESERVES_UV
                if ((SvOK(sv) && ((SvNV(sv) < (NV)IV_MIN) ||
                                  (SvNV(sv) > (NV)IV_MAX)))
@@ -1899,33 +1910,50 @@ PP(pp_enteriter)
                                         (SvNV(right) > (NV)UV_MAX))))))
 #endif
                    DIE(aTHX_ "Range iterator outside integer range");
-               cx->blk_loop.iterix = SvIV(sv);
-               cx->blk_loop.itermax = SvIV(right);
+               cx->blk_loop.state_u.lazyiv.cur = SvIV(sv);
+               cx->blk_loop.state_u.lazyiv.end = SvIV(right);
 #ifdef DEBUGGING
                /* for correct -Dstv display */
                cx->blk_oldsp = sp - PL_stack_base;
 #endif
            }
            else {
-               cx->blk_loop.iterlval = newSVsv(sv);
-               (void) SvPV_force_nolen(cx->blk_loop.iterlval);
+               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);
+               (void) SvPV_force_nolen(cx->blk_loop.state_u.lazysv.cur);
+               /* This will do the upgrade to SVt_PV, and warn if the value
+                  is uninitialised.  */
                (void) SvPV_nolen_const(right);
+               /* Doing this avoids a check every time in pp_iter in pp_hot.c
+                  to replace !SvOK() with a pointer to "".  */
+               if (!SvOK(right)) {
+                   SvREFCNT_dec(right);
+                   cx->blk_loop.state_u.lazysv.end = &PL_sv_no;
+               }
            }
        }
-       else if (PL_op->op_private & OPpITER_REVERSED) {
-           cx->blk_loop.itermax = 0;
-           cx->blk_loop.iterix = AvFILL(cx->blk_loop.iterary) + 1;
-
+       else /* SvTYPE(maybe_ary) == SVt_PVAV */ {
+           cx->blk_loop.state_u.ary.ary = (AV*)maybe_ary;
+           SvREFCNT_inc(maybe_ary);
+           cx->blk_loop.state_u.ary.ix =
+               (PL_op->op_private & OPpITER_REVERSED) ?
+               AvFILL(cx->blk_loop.state_u.ary.ary) + 1 :
+               -1;
        }
     }
-    else {
-       cx->blk_loop.iterary = PL_curstack;
+    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.itermax = MARK - PL_stack_base + 1;
-           cx->blk_loop.iterix = cx->blk_oldsp + 1;
+           cx->blk_loop.state_u.ary.ix = cx->blk_oldsp + 1;
        }
        else {
-           cx->blk_loop.iterix = MARK - PL_stack_base;
+           cx->blk_loop.state_u.ary.ix = MARK - PL_stack_base;
        }
     }
 
@@ -2145,6 +2173,8 @@ PP(pp_last)
     cxstack_ix++; /* temporarily protect top context */
     mark = newsp;
     switch (CxTYPE(cx)) {
+    case CXt_LOOP_LAZYIV:
+    case CXt_LOOP_LAZYSV:
     case CXt_LOOP_FOR:
     case CXt_LOOP_PLAIN:
        pop2 = CxTYPE(cx);
@@ -2189,7 +2219,9 @@ PP(pp_last)
     cxstack_ix--;
     /* Stack values are safe: */
     switch (pop2) {
+    case CXt_LOOP_LAZYIV:
     case CXt_LOOP_PLAIN:
+    case CXt_LOOP_LAZYSV:
     case CXt_LOOP_FOR:
        POPLOOP(cx);    /* release loop vars ... */
        LEAVE;
@@ -2548,6 +2580,8 @@ PP(pp_goto)
                    break;
                 }
                 /* else fall through */
+           case CXt_LOOP_LAZYIV:
+           case CXt_LOOP_LAZYSV:
            case CXt_LOOP_FOR:
            case CXt_LOOP_PLAIN:
                gotoprobe = cx->blk_oldcop->op_sibling;
@@ -2815,7 +2849,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, const char *code, PAD** padp)
     PL_op->op_type = OP_ENTEREVAL;
     PL_op->op_flags = 0;                       /* Avoid uninit warning. */
     PUSHBLOCK(cx, CXt_EVAL|(IN_PERL_COMPILETIME ? 0 : CXp_REAL), SP);
-    PUSHEVAL(cx, 0, NULL);
+    PUSHEVAL(cx, 0);
 
     if (runtime)
        (void) doeval(G_SCALAR, startop, runcv, PL_curcop->cop_seq);
@@ -3521,7 +3555,7 @@ PP(pp_require)
 
     /* switch to eval mode */
     PUSHBLOCK(cx, CXt_EVAL, SP);
-    PUSHEVAL(cx, name, NULL);
+    PUSHEVAL(cx, name);
     cx->blk_eval.retop = PL_op->op_next;
 
     SAVECOPLINE(&PL_compiling);
@@ -3620,7 +3654,7 @@ PP(pp_entereval)
     runcv = find_runcv(&seq);
 
     PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP);
-    PUSHEVAL(cx, 0, NULL);
+    PUSHEVAL(cx, 0);
     cx->blk_eval.retop = PL_op->op_next;
 
     /* prepare to compile string */
@@ -3737,7 +3771,7 @@ Perl_create_eval_scope(pTHX_ U32 flags)
     SAVETMPS;
 
     PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
-    PUSHEVAL(cx, 0, 0);
+    PUSHEVAL(cx, 0);
 
     PL_in_eval = EVAL_INEVAL;
     if (flags & G_KEEPERR)