This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
start cleaning up perldelta for 5.17.6
[perl5.git] / pp_ctl.c
index 1fc855d..24eac16 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -116,7 +116,7 @@ PP(pp_regcomp)
                pm->op_pmflags |
                    (PL_op->op_flags & OPf_SPECIAL ? PMf_USE_RE_EVAL : 0));
     if (pm->op_pmflags & PMf_HAS_CV)
-       ((struct regexp *)SvANY(new_re))->qr_anoncv
+       ReANY(new_re)->qr_anoncv
                        = (CV*) SvREFCNT_inc(PAD_SV(PL_op->op_targ));
 
     if (is_bare_re) {
@@ -129,7 +129,7 @@ PP(pp_regcomp)
           some day. */
        if (pm->op_type == OP_MATCH) {
            SV *lhs;
-           const bool was_tainted = PL_tainted;
+           const bool was_tainted = TAINT_get;
            if (pm->op_flags & OPf_STACKED)
                lhs = args[-1];
            else if (pm->op_private & OPpTARGET_MY)
@@ -138,8 +138,8 @@ PP(pp_regcomp)
            SvGETMAGIC(lhs);
            /* Restore the previous value of PL_tainted (which may have been
               modified by get-magic), to avoid incorrectly setting the
-              RXf_TAINTED flag further down. */
-           PL_tainted = was_tainted;
+              RXf_TAINTED flag with RX_TAINT_on further down. */
+           TAINT_set(was_tainted);
        }
        tmp = reg_temp_copy(NULL, new_re);
        ReREFCNT_dec(new_re);
@@ -151,9 +151,9 @@ PP(pp_regcomp)
     }
 
 #ifndef INCOMPLETE_TAINTS
-    if (PL_tainting && PL_tainted) {
+    if (TAINTING_get && TAINT_get) {
        SvTAINTED_on((SV*)new_re);
-       RX_EXTFLAGS(new_re) |= RXf_TAINTED;
+        RX_TAINT_on(new_re);
     }
 #endif
 
@@ -250,6 +250,7 @@ PP(pp_substcont)
                    SvUTF8_on(targ);
                SvPV_set(dstr, NULL);
 
+               PL_tainted = 0;
                mPUSHi(saviters - 1);
 
                (void)SvPOK_only_UTF8(targ);
@@ -258,7 +259,7 @@ PP(pp_substcont)
            /* update the taint state of various various variables in
             * preparation for final exit.
             * See "how taint works" above pp_subst() */
-           if (PL_tainting) {
+           if (TAINTING_get) {
                if ((cx->sb_rxtainted & SUBST_TAINT_PAT) ||
                    ((cx->sb_rxtainted & (SUBST_TAINT_STR|SUBST_TAINT_RETAINT))
                                    == (SUBST_TAINT_STR|SUBST_TAINT_RETAINT))
@@ -270,8 +271,10 @@ PP(pp_substcont)
                )
                    SvTAINTED_on(TOPs);  /* taint return value */
                /* needed for mg_set below */
-               PL_tainted = cBOOL(cx->sb_rxtainted &
-                           (SUBST_TAINT_STR|SUBST_TAINT_PAT|SUBST_TAINT_REPL));
+               TAINT_set(
+                    cBOOL(cx->sb_rxtainted &
+                         (SUBST_TAINT_STR|SUBST_TAINT_PAT|SUBST_TAINT_REPL))
+                );
                SvTAINT(TARG);
            }
            /* PL_tainted must be correctly set for this mg_set */
@@ -320,7 +323,7 @@ PP(pp_substcont)
     /* update the taint state of various various variables in preparation
      * for calling the code block.
      * See "how taint works" above pp_subst() */
-    if (PL_tainting) {
+    if (TAINTING_get) {
        if (RX_MATCH_TAINTED(rx)) /* run time pattern taint, eg locale */
            cx->sb_rxtainted |= SUBST_TAINT_PAT;
 
@@ -366,13 +369,13 @@ Perl_rxres_save(pTHX_ void **rsp, REGEXP *rx)
     /* what (if anything) to free on croak */
     *p++ = PTR2UV(RX_MATCH_COPIED(rx) ? RX_SUBBEG(rx) : NULL);
     RX_MATCH_COPIED_off(rx);
+    *p++ = RX_NPARENS(rx);
 
 #ifdef PERL_OLD_COPY_ON_WRITE
     *p++ = PTR2UV(RX_SAVED_COPY(rx));
     RX_SAVED_COPY(rx) = NULL;
 #endif
 
-    *p++ = RX_NPARENS(rx);
     *p++ = PTR2UV(RX_SUBBEG(rx));
     *p++ = (UV)RX_SUBLEN(rx);
     *p++ = (UV)RX_SUBOFFSET(rx);
@@ -395,6 +398,7 @@ S_rxres_restore(pTHX_ void **rsp, REGEXP *rx)
     RX_MATCH_COPY_FREE(rx);
     RX_MATCH_COPIED_set(rx, *p);
     *p++ = 0;
+    RX_NPARENS(rx) = *p++;
 
 #ifdef PERL_OLD_COPY_ON_WRITE
     if (RX_SAVED_COPY(rx))
@@ -403,7 +407,6 @@ S_rxres_restore(pTHX_ void **rsp, REGEXP *rx)
     *p++ = 0;
 #endif
 
-    RX_NPARENS(rx) = *p++;
     RX_SUBBEG(rx) = INT2PTR(char*,*p++);
     RX_SUBLEN(rx) = (I32)(*p++);
     RX_SUBOFFSET(rx) = (I32)*p++;
@@ -423,19 +426,23 @@ S_rxres_free(pTHX_ void **rsp)
     PERL_UNUSED_CONTEXT;
 
     if (p) {
-#ifdef PERL_POISON
        void *tmp = INT2PTR(char*,*p);
-       Safefree(tmp);
-       if (*p)
-           PoisonFree(*p, 1, sizeof(*p));
+#ifdef PERL_POISON
+#ifdef PERL_OLD_COPY_ON_WRITE
+       U32 i = 9 + p[1] * 2;
 #else
-       Safefree(INT2PTR(char*,*p));
+       U32 i = 8 + p[1] * 2;
+#endif
 #endif
+
 #ifdef PERL_OLD_COPY_ON_WRITE
-       if (p[1]) {
-           SvREFCNT_dec (INT2PTR(SV*,p[1]));
-       }
+        SvREFCNT_dec (INT2PTR(SV*,p[2]));
 #endif
+#ifdef PERL_POISON
+        PoisonFree(p, i, sizeof(UV));
+#endif
+
+       Safefree(tmp);
        Safefree(p);
        *rsp = NULL;
     }
@@ -1892,17 +1899,15 @@ PP(pp_caller)
        Copy(AvALLOC(ary), AvARRAY(PL_dbargs), AvFILLp(ary) + 1 + off, SV*);
        AvFILLp(PL_dbargs) = AvFILLp(ary) + off;
     }
-    /* XXX only hints propagated via op_private are currently
-     * visible (others are not easily accessible, since they
-     * use the global PL_hints) */
     mPUSHi(CopHINTS_get(cx->blk_oldcop));
     {
        SV * mask ;
        STRLEN * const old_warnings = cx->blk_oldcop->cop_warnings ;
 
-       if  (old_warnings == pWARN_NONE ||
-               (old_warnings == pWARN_STD && (PL_dowarn & G_WARN_ON) == 0))
+       if  (old_warnings == pWARN_NONE)
             mask = newSVpvn(WARN_NONEstring, WARNsize) ;
+       else if (old_warnings == pWARN_STD && (PL_dowarn & G_WARN_ON) == 0)
+            mask = &PL_sv_undef ;
         else if (old_warnings == pWARN_ALL ||
                  (old_warnings == pWARN_STD && PL_dowarn & G_WARN_ON)) {
            /* Get the bit mask for $warnings::Bits{all}, because
@@ -1931,9 +1936,13 @@ PP(pp_reset)
 {
     dVAR;
     dSP;
-    const char * const tmps =
-       (MAXARG < 1 || (!TOPs && !POPs)) ? (const char *)"" : POPpconstx;
-    sv_reset(tmps, CopSTASH(PL_curcop));
+    const char * tmps;
+    STRLEN len = 0;
+    if (MAXARG < 1 || (!TOPs && !POPs))
+       tmps = NULL, len = 0;
+    else
+       tmps = SvPVx_const(POPs, len);
+    sv_resetpvn(tmps, len, CopSTASH(PL_curcop));
     PUSHs(&PL_sv_yes);
     RETURN;
 }
@@ -1958,9 +1967,12 @@ PP(pp_dbstate)
        const I32 gimme = G_ARRAY;
        U8 hasargs;
        GV * const gv = PL_DBgv;
-       CV * const cv = GvCV(gv);
+       CV * cv = NULL;
 
-       if (!cv)
+        if (gv && isGV_with_GP(gv))
+            cv = GvCV(gv);
+
+       if (!cv || (!CvROOT(cv) && !CvXSUB(cv)))
            DIE(aTHX_ "No DB::DB routine defined");
 
        if (CvDEPTH(cv) >= 1 && !(PL_debug & DEBUG_DB_RECURSE_FLAG))
@@ -1988,8 +2000,12 @@ PP(pp_dbstate)
            PUSHSUB_DB(cx);
            cx->blk_sub.retop = PL_op->op_next;
            CvDEPTH(cv)++;
+           if (CvDEPTH(cv) >= 2) {
+               PERL_STACK_OVERFLOW_CHECK();
+               pad_push(CvPADLIST(cv), CvDEPTH(cv));
+           }
            SAVECOMPPAD();
-           PAD_SET_CUR_NOSAVE(CvPADLIST(cv), 1);
+           PAD_SET_CUR_NOSAVE(CvPADLIST(cv), CvDEPTH(cv));
            RETURNOP(CvSTART(cv));
        }
     }
@@ -2758,10 +2774,8 @@ PP(pp_goto)
            I32 cxix;
            PERL_CONTEXT *cx;
            CV *cv = MUTABLE_CV(SvRV(sv));
-           SV** mark;
-           I32 items = 0;
+           AV *arg = GvAV(PL_defgv);
            I32 oldsave;
-           bool reified = 0;
 
        retry:
            if (!CvROOT(cv) && !CvXSUB(cv)) {
@@ -2789,13 +2803,17 @@ PP(pp_goto)
            FREETMPS;
            cxix = dopoptosub(cxstack_ix);
            if (cxix < 0)
+           {
+               SvREFCNT_dec(cv);
                DIE(aTHX_ "Can't goto subroutine outside a subroutine");
+           }
            if (cxix < cxstack_ix)
                dounwind(cxix);
            TOPBLOCK(cx);
            SPAGAIN;
            /* ban goto in eval: see <20050521150056.GC20213@iabyn.com> */
            if (CxTYPE(cx) == CXt_EVAL) {
+               SvREFCNT_dec(cv);
                if (CxREALEVAL(cx))
                /* diag_listed_as: Can't goto subroutine from an eval-%s */
                    DIE(aTHX_ "Can't goto subroutine from an eval-string");
@@ -2804,35 +2822,25 @@ PP(pp_goto)
                    DIE(aTHX_ "Can't goto subroutine from an eval-block");
            }
            else if (CxMULTICALL(cx))
+           {
+               SvREFCNT_dec(cv);
                DIE(aTHX_ "Can't goto subroutine from a sort sub (or similar callback)");
+           }
            if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
-               /* put @_ back onto stack */
                AV* av = cx->blk_sub.argarray;
 
-               items = AvFILLp(av) + 1;
-               EXTEND(SP, items+1); /* @_ could have been extended. */
-               Copy(AvARRAY(av), SP + 1, items, SV*);
-               SvREFCNT_dec(GvAV(PL_defgv));
-               GvAV(PL_defgv) = cx->blk_sub.savearray;
-               CLEAR_ARGARRAY(av);
-               /* abandon @_ if it got reified */
-               if (AvREAL(av)) {
-                   reified = 1;
+               /* abandon the original @_ if it got reified or if it is
+                  the same as the current @_ */
+               if (AvREAL(av) || av == arg) {
                    SvREFCNT_dec(av);
                    av = newAV();
-                   av_extend(av, items-1);
                    AvREIFY_only(av);
                    PAD_SVl(0) = MUTABLE_SV(cx->blk_sub.argarray = av);
                }
+               else CLEAR_ARGARRAY(av);
            }
-           else if (CvISXSUB(cv)) {    /* put GvAV(defgv) back onto stack */
-               AV* const av = GvAV(PL_defgv);
-               items = AvFILLp(av) + 1;
-               EXTEND(SP, items+1); /* @_ could have been extended. */
-               Copy(AvARRAY(av), SP + 1, items, SV*);
-           }
-           mark = SP;
-           SP += items;
+           /* We donate this refcount later to the callee’s pad. */
+           SvREFCNT_inc_simple_void(arg);
            if (CxTYPE(cx) == CXt_SUB &&
                !(CvDEPTH(cx->blk_sub.cv) = cx->blk_sub.olddepth))
                SvREFCNT_dec(cx->blk_sub.cv);
@@ -2843,6 +2851,7 @@ PP(pp_goto)
             * our precious cv.  See bug #99850. */
            if (!CvROOT(cv) && !CvXSUB(cv)) {
                const GV * const gv = CvGV(cv);
+               SvREFCNT_dec(arg);
                if (gv) {
                    SV * const tmpstr = sv_newmortal();
                    gv_efullname3(tmpstr, gv, NULL);
@@ -2859,10 +2868,25 @@ PP(pp_goto)
                OP* const retop = cx->blk_sub.retop;
                SV **newsp PERL_UNUSED_DECL;
                I32 gimme PERL_UNUSED_DECL;
-               if (reified) {
+               const SSize_t items = AvFILLp(arg) + 1;
+               SV** mark;
+
+               /* put GvAV(defgv) back onto stack */
+               EXTEND(SP, items+1); /* @_ could have been extended. */
+               Copy(AvARRAY(arg), SP + 1, items, SV*);
+               mark = SP;
+               SP += items;
+               if (AvREAL(arg)) {
                    I32 index;
                    for (index=0; index<items; index++)
-                       sv_2mortal(SP[-index]);
+                       SvREFCNT_inc_void(sv_2mortal(SP[-index]));
+               }
+               SvREFCNT_dec(arg);
+               if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
+                   /* Restore old @_ */
+                   arg = GvAV(PL_defgv);
+                   GvAV(PL_defgv) = cx->blk_sub.savearray;
+                   SvREFCNT_dec(arg);
                }
 
                /* XS subs don't have a CxSUB, so pop it */
@@ -2876,11 +2900,6 @@ PP(pp_goto)
            }
            else {
                PADLIST * const padlist = CvPADLIST(cv);
-               if (CxTYPE(cx) == CXt_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.cv = cv;
                cx->blk_sub.olddepth = CvDEPTH(cv);
 
@@ -2897,41 +2916,26 @@ PP(pp_goto)
                PAD_SET_CUR_NOSAVE(padlist, CvDEPTH(cv));
                if (CxHASARGS(cx))
                {
-                   AV *const av = MUTABLE_AV(PAD_SVl(0));
-
-                   cx->blk_sub.savearray = GvAV(PL_defgv);
-                   GvAV(PL_defgv) = MUTABLE_AV(SvREFCNT_inc_simple(av));
                    CX_CURPAD_SAVE(cx->blk_sub);
-                   cx->blk_sub.argarray = av;
 
-                   if (items >= AvMAX(av) + 1) {
-                       SV **ary = AvALLOC(av);
-                       if (AvARRAY(av) != ary) {
-                           AvMAX(av) += AvARRAY(av) - AvALLOC(av);
-                           AvARRAY(av) = ary;
-                       }
-                       if (items >= AvMAX(av) + 1) {
-                           AvMAX(av) = items - 1;
-                           Renew(ary,items+1,SV*);
-                           AvALLOC(av) = ary;
-                           AvARRAY(av) = ary;
-                       }
-                   }
-                   ++mark;
-                   Copy(mark,AvARRAY(av),items,SV*);
-                   AvFILLp(av) = items - 1;
-                   assert(!AvREAL(av));
-                   if (reified) {
-                       /* transfer 'ownership' of refcnts to new @_ */
-                       AvREAL_on(av);
-                       AvREIFY_off(av);
-                   }
-                   while (items--) {
-                       if (*mark)
-                           SvTEMP_off(*mark);
-                       mark++;
+                   /* cx->blk_sub.argarray has no reference count, so we
+                      need something to hang on to our argument array so
+                      that cx->blk_sub.argarray does not end up pointing
+                      to freed memory as the result of undef *_.  So put
+                      it in the callee’s pad, donating our refer-
+                      ence count. */
+                   SvREFCNT_dec(PAD_SVl(0));
+                   PAD_SVl(0) = (SV *)(cx->blk_sub.argarray = arg);
+
+                   /* GvAV(PL_defgv) might have been modified on scope
+                      exit, so restore it. */
+                   if (arg != GvAV(PL_defgv)) {
+                       AV * const av = GvAV(PL_defgv);
+                       GvAV(PL_defgv) = (AV *)SvREFCNT_inc_simple(arg);
+                       SvREFCNT_dec(av);
                    }
                }
+               else SvREFCNT_dec(arg);
                if (PERLDB_SUB) {       /* Checking curstash breaks DProf. */
                    Perl_get_db_sub(aTHX_ NULL, cv);
                    if (PERLDB_GOTO) {
@@ -3263,7 +3267,8 @@ Perl_find_runcv_where(pTHX_ U8 cond, IV arg, U32 *db_seqp)
                switch (cond) {
                case FIND_RUNCV_padid_eq:
                    if (!CvPADLIST(cv)
-                    || CvPADLIST(cv)->xpadl_id != (U32)arg) continue;
+                    || PadlistNAMES(CvPADLIST(cv)) != INT2PTR(PADNAMELIST *, arg))
+                       continue;
                    return cv;
                case FIND_RUNCV_level_eq:
                    if (level++ != arg) continue;
@@ -3451,7 +3456,6 @@ S_doeval(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
        PL_op = saveop;
        if (yystatus != 3) {
            if (PL_eval_root) {
-               cv_forget_slab(evalcv);
                op_free(PL_eval_root);
                PL_eval_root = NULL;
            }
@@ -3603,7 +3607,7 @@ PP(pp_require)
     sv = POPs;
     if ( (SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE) {
        sv = sv_2mortal(new_version(sv));
-       if (!sv_derived_from(PL_patchlevel, "version"))
+       if (!Perl_sv_derived_from_pvn(aTHX_ PL_patchlevel, STR_WITH_LEN("version"), 0))
            upg_version(PL_patchlevel, TRUE);
        if (cUNOP->op_first->op_type == OP_CONST && cUNOP->op_first->op_private & OPpCONST_NOVER) {
            if ( vcmp(sv,PL_patchlevel) <= 0 )
@@ -3923,22 +3927,36 @@ PP(pp_require)
                if (namesv) {                   /* did we lookup @INC? */
                    AV * const ar = GvAVn(PL_incgv);
                    I32 i;
+                   SV *const msg = newSVpvs_flags("", SVs_TEMP);
                    SV *const inc = newSVpvs_flags("", SVs_TEMP);
                    for (i = 0; i <= AvFILL(ar); i++) {
                        sv_catpvs(inc, " ");
                        sv_catsv(inc, *av_fetch(ar, i, TRUE));
                    }
+                   if (len >= 4 && memEQ(name + len - 3, ".pm", 4)) {
+                       const char *c, *e = name + len - 3;
+                       sv_catpv(msg, " (you may need to install the ");
+                       for (c = name; c < e; c++) {
+                           if (*c == '/') {
+                               sv_catpvn(msg, "::", 2);
+                           }
+                           else {
+                               sv_catpvn(msg, c, 1);
+                           }
+                       }
+                       sv_catpv(msg, " module)");
+                   }
+                   else if (len >= 2 && memEQ(name + len - 2, ".h", 3)) {
+                       sv_catpv(msg, " (change .h to .ph maybe?) (did you run h2ph?)");
+                   }
+                   else if (len >= 3 && memEQ(name + len - 3, ".ph", 4)) {
+                       sv_catpv(msg, " (did you run h2ph?)");
+                   }
 
                    /* diag_listed_as: Can't locate %s */
                    DIE(aTHX_
-                       "Can't locate %s in @INC%s%s (@INC contains:%" SVf ")",
-                       name,
-                       (len >= 2 && memEQ(name + len - 2, ".h", 3)
-                        ? " (change .h to .ph maybe?) (did you run h2ph?)" : ""),
-                       (len >= 3 && memEQ(name + len - 3, ".ph", 4)
-                        ? " (did you run h2ph?)" : ""),
-                       inc
-                       );
+                       "Can't locate %s in @INC%" SVf " (@INC contains:%" SVf ")",
+                       name, msg, inc);
                }
            }
            DIE(aTHX_ "Can't locate %s", name);
@@ -5359,6 +5377,7 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
        LEAVE_with_name("call_filter_sub");
     }
 
+    if (SvIsCOW(upstream)) sv_force_normal(upstream);
     if(!err && SvOK(upstream)) {
        got_p = SvPV(upstream, got_len);
        if (umaxlen) {