Remove the _ prototype, as Maintainers is used by makemeta, and in turn
[p5sagit/p5-mst-13.2.git] / pp_ctl.c
index 5cc002c..b0ffcb5 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -234,7 +234,7 @@ PP(pp_substcont)
        FREETMPS; /* Prevent excess tmp stack */
 
        /* Are we done */
-       if (cx->sb_once || !CALLREGEXEC(rx, s, cx->sb_strend, orig,
+       if (CxONCE(cx) || !CALLREGEXEC(rx, s, cx->sb_strend, orig,
                                     s == m, cx->sb_targ, NULL,
                                     ((cx->sb_rflags & REXEC_COPY_STR)
                                      ? (REXEC_IGNOREPOS|REXEC_NOT_FIRST)
@@ -1256,10 +1256,13 @@ S_dopoptolabel(pTHX_ const char *label)
            if (CxTYPE(cx) == CXt_NULL)
                return -1;
            break;
-       case CXt_LOOP:
-           if ( !cx->blk_loop.label || strNE(label, cx->blk_loop.label) ) {
+       case CXt_LOOP_LAZYIV:
+       case CXt_LOOP_LAZYSV:
+       case CXt_LOOP_FOR:
+       case CXt_LOOP_PLAIN:
+           if ( !CxLABEL(cx) || strNE(label, CxLABEL(cx)) ) {
                DEBUG_l(Perl_deb(aTHX_ "(Skipping label #%ld %s)\n",
-                       (long)i, cx->blk_loop.label));
+                       (long)i, CxLABEL(cx)));
                continue;
            }
            DEBUG_l( Perl_deb(aTHX_ "(Found label #%ld %s)\n", (long)i, label));
@@ -1308,8 +1311,8 @@ Perl_is_lvalue_sub(pTHX)
     const I32 cxix = dopoptosub(cxstack_ix);
     assert(cxix >= 0);  /* We should only be called from inside subs */
 
-    if (cxstack[cxix].blk_sub.lval && CvLVALUE(cxstack[cxix].blk_sub.cv))
-       return cxstack[cxix].blk_sub.lval;
+    if (CxLVAL(cxstack + cxix) && CvLVALUE(cxstack[cxix].blk_sub.cv))
+       return CxLVAL(cxstack + cxix);
     else
        return 0;
 }
@@ -1371,7 +1374,10 @@ S_dopoptoloop(pTHX_ I32 startingblock)
            if ((CxTYPE(cx)) == CXt_NULL)
                return -1;
            break;
-       case CXt_LOOP:
+       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));
            return i;
        }
@@ -1392,7 +1398,12 @@ S_dopoptogiven(pTHX_ I32 startingblock)
        case CXt_GIVEN:
            DEBUG_l( Perl_deb(aTHX_ "(Found given #%ld)\n", (long)i));
            return i;
-       case CXt_LOOP:
+       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));
                return i;
@@ -1443,7 +1454,10 @@ Perl_dounwind(pTHX_ I32 cxix)
        case CXt_EVAL:
            POPEVAL(cx);
            break;
-       case CXt_LOOP:
+       case CXt_LOOP_LAZYIV:
+       case CXt_LOOP_LAZYSV:
+       case CXt_LOOP_FOR:
+       case CXt_LOOP_PLAIN:
            POPLOOP(cx);
            break;
        case CXt_NULL:
@@ -1654,11 +1668,11 @@ PP(pp_caller)
            SV * const sv = newSV(0);
            gv_efullname3(sv, cvgv, NULL);
            mPUSHs(sv);
-           mPUSHi((I32)cx->blk_sub.hasargs);
+           PUSHs(boolSV(CxHASARGS(cx)));
        }
        else {
            PUSHs(newSVpvs_flags("(unknown)", SVs_TEMP));
-           mPUSHi((I32)cx->blk_sub.hasargs);
+           PUSHs(boolSV(CxHASARGS(cx)));
        }
     }
     else {
@@ -1669,10 +1683,10 @@ PP(pp_caller)
     if (gimme == G_VOID)
        PUSHs(&PL_sv_undef);
     else
-       mPUSHi(gimme & G_ARRAY);
+       PUSHs(boolSV((gimme & G_WANT) == G_ARRAY));
     if (CxTYPE(cx) == CXt_EVAL) {
        /* eval STRING */
-       if (cx->blk_eval.old_op_type == OP_ENTEREVAL) {
+       if (CxOLD_OP_TYPE(cx) == OP_ENTEREVAL) {
            PUSHs(cx->blk_eval.cur_text);
            PUSHs(&PL_sv_no);
        }
@@ -1691,7 +1705,7 @@ PP(pp_caller)
        PUSHs(&PL_sv_undef);
        PUSHs(&PL_sv_undef);
     }
-    if (CxTYPE(cx) == CXt_SUB && cx->blk_sub.hasargs
+    if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)
        && CopSTASH_eq(PL_curcop, PL_debstash))
     {
        AV * const ary = cx->blk_sub.argarray;
@@ -1821,9 +1835,9 @@ PP(pp_enteriter)
     register PERL_CONTEXT *cx;
     const I32 gimme = GIMME_V;
     SV **svp;
-    U16 cxtype = CXt_LOOP | CXp_FOREACH;
+    U8 cxtype = CXt_LOOP_FOR;
 #ifdef USE_ITHREADS
-    void *iterdata;
+    PAD *iterdata;
 #endif
 
     ENTER;
@@ -1835,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 {
@@ -1850,7 +1862,7 @@ PP(pp_enteriter)
        SAVEGENERICSV(*svp);
        *svp = newSV(0);
 #ifdef USE_ITHREADS
-       iterdata = (void*)gv;
+       iterdata = (PAD*)gv;
 #endif
     }
 
@@ -1861,49 +1873,87 @@ PP(pp_enteriter)
 
     PUSHBLOCK(cx, cxtype, SP);
 #ifdef USE_ITHREADS
-    PUSHLOOP(cx, iterdata, MARK);
+    PUSHLOOP_FOR(cx, iterdata, MARK, PL_op->op_targ);
 #else
-    PUSHLOOP(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)) {
-               if ((SvOK(sv) && SvNV(sv) < IV_MIN) ||
-                   (SvOK(right) && SvNV(right) >= IV_MAX))
+               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)))
+                       ||
+                   (SvOK(right) && ((SvNV(right) > (NV)IV_MAX) ||
+                                    (SvNV(right) < (NV)IV_MIN))))
+#else
+               if ((SvOK(sv) && ((SvNV(sv) <= (NV)IV_MIN)
+                                 ||
+                                 ((SvNV(sv) > 0) &&
+                                       ((SvUV(sv) > (UV)IV_MAX) ||
+                                        (SvNV(sv) > (NV)UV_MAX)))))
+                       ||
+                   (SvOK(right) && ((SvNV(right) <= (NV)IV_MIN)
+                                    ||
+                                    ((SvNV(right) > 0) &&
+                                       ((SvUV(right) > (UV)IV_MAX) ||
+                                        (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;
-       AvFILLp(PL_curstack) = SP - PL_stack_base;
+    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;
        }
     }
 
@@ -1920,8 +1970,8 @@ PP(pp_enterloop)
     SAVETMPS;
     ENTER;
 
-    PUSHBLOCK(cx, CXt_LOOP, SP);
-    PUSHLOOP(cx, 0, SP);
+    PUSHBLOCK(cx, CXt_LOOP_PLAIN, SP);
+    PUSHLOOP_PLAIN(cx, SP);
 
     RETURN;
 }
@@ -1936,7 +1986,7 @@ PP(pp_leaveloop)
     SV **mark;
 
     POPBLOCK(cx,newpm);
-    assert(CxTYPE(cx) == CXt_LOOP);
+    assert(CxTYPE_is_LOOP(cx));
     mark = newsp;
     newsp = PL_stack_base + cx->blk_loop.resetsp;
 
@@ -2123,8 +2173,11 @@ PP(pp_last)
     cxstack_ix++; /* temporarily protect top context */
     mark = newsp;
     switch (CxTYPE(cx)) {
-    case CXt_LOOP:
-       pop2 = CXt_LOOP;
+    case CXt_LOOP_LAZYIV:
+    case CXt_LOOP_LAZYSV:
+    case CXt_LOOP_FOR:
+    case CXt_LOOP_PLAIN:
+       pop2 = CxTYPE(cx);
        newsp = PL_stack_base + cx->blk_loop.resetsp;
        nextop = cx->blk_loop.my_op->op_lastop->op_next;
        break;
@@ -2166,7 +2219,10 @@ PP(pp_last)
     cxstack_ix--;
     /* Stack values are safe: */
     switch (pop2) {
-    case CXt_LOOP:
+    case CXt_LOOP_LAZYIV:
+    case CXt_LOOP_PLAIN:
+    case CXt_LOOP_LAZYSV:
+    case CXt_LOOP_FOR:
        POPLOOP(cx);    /* release loop vars ... */
        LEAVE;
        break;
@@ -2361,7 +2417,7 @@ PP(pp_goto)
            }
            else if (CxMULTICALL(cx))
                DIE(aTHX_ "Can't goto subroutine from a sort sub (or similar callback)");
-           if (CxTYPE(cx) == CXt_SUB && cx->blk_sub.hasargs) {
+           if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
                /* put @_ back onto stack */
                AV* av = cx->blk_sub.argarray;
 
@@ -2420,10 +2476,9 @@ PP(pp_goto)
            else {
                AV* const padlist = CvPADLIST(cv);
                if (CxTYPE(cx) == CXt_EVAL) {
-                   PL_in_eval = cx->blk_eval.old_in_eval;
+                   PL_in_eval = CxOLD_IN_EVAL(cx);
                    PL_eval_root = cx->blk_eval.old_eval_root;
                    cx->cx_type = CXt_SUB;
-                   cx->blk_sub.hasargs = 0;
                }
                cx->blk_sub.cv = cv;
                cx->blk_sub.olddepth = CvDEPTH(cv);
@@ -2438,7 +2493,7 @@ PP(pp_goto)
                }
                SAVECOMPPAD();
                PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv));
-               if (cx->blk_sub.hasargs)
+               if (CxHASARGS(cx))
                {
                    AV* const av = (AV*)PAD_SVl(0);
 
@@ -2525,7 +2580,10 @@ PP(pp_goto)
                    break;
                 }
                 /* else fall through */
-           case CXt_LOOP:
+           case CXt_LOOP_LAZYIV:
+           case CXt_LOOP_LAZYSV:
+           case CXt_LOOP_FOR:
+           case CXt_LOOP_PLAIN:
                gotoprobe = cx->blk_oldcop->op_sibling;
                break;
            case CXt_SUBST:
@@ -2791,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);
@@ -2983,9 +3041,9 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
            && cLISTOPx(cUNOPx(PL_eval_root)->op_first)->op_last->op_type
            == OP_REQUIRE)
        scalar(PL_eval_root);
-    else if (gimme & G_VOID)
+    else if ((gimme & G_WANT) == G_VOID)
        scalarvoid(PL_eval_root);
-    else if (gimme & G_ARRAY)
+    else if ((gimme & G_WANT) == G_ARRAY)
        list(PL_eval_root);
     else
        scalar(PL_eval_root);
@@ -3497,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);
@@ -3596,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 */
@@ -3713,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)