This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Deprecate Perl_ptr_table_clear(). Nothing outside sv.c uses it.
[perl5.git] / sv.c
diff --git a/sv.c b/sv.c
index 397de23..2e3ba69 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -607,7 +607,7 @@ Perl_sv_clean_all(pTHX)
 struct arena_desc {
     char       *arena;         /* the raw storage, allocated aligned */
     size_t      size;          /* its size ~4k typ */
-    U32                misc;           /* type, and in future other things. */
+    svtype     utype;          /* bodytype stored in arena */
 };
 
 struct arena_set;
@@ -689,7 +689,6 @@ Perl_sv_free_arenas(pTHX)
   2. regular body arenas
   3. arenas for reduced-size bodies
   4. Hash-Entry arenas
-  5. pte arenas (thread related)
 
   Arena types 2 & 3 are chained by body-type off an array of
   arena-root pointers, which is indexed by svtype.  Some of the
@@ -708,19 +707,13 @@ Perl_sv_free_arenas(pTHX)
 
   HE, HEK arenas are managed separately, with separate code, but may
   be merge-able later..
-
-  PTE arenas are not sv-bodies, but they share these mid-level
-  mechanics, so are considered here.  The new mid-level mechanics rely
-  on the sv_type of the body being allocated, so we just reserve one
-  of the unused body-slots for PTEs, then use it in those (2) PTE
-  contexts below (line ~10k)
 */
 
 /* get_arena(size): this creates custom-sized arenas
    TBD: export properly for hv.c: S_more_he().
 */
 void*
-Perl_get_arena(pTHX_ const size_t arena_size, const U32 misc)
+Perl_get_arena(pTHX_ const size_t arena_size, const svtype bodytype)
 {
     dVAR;
     struct arena_desc* adesc;
@@ -749,7 +742,7 @@ Perl_get_arena(pTHX_ const size_t arena_size, const U32 misc)
     
     Newx(adesc->arena, arena_size, char);
     adesc->size = arena_size;
-    adesc->misc = misc;
+    adesc->utype = bodytype;
     DEBUG_m(PerlIO_printf(Perl_debug_log, "arena %d added: %p size %"UVuf"\n", 
                          curr, (void*)adesc->arena, (UV)arena_size));
 
@@ -852,13 +845,6 @@ PL_body_roots[HE_SVSLOT=SVt_NULL] is filled by S_more_he, but the
 bodies_by_type[SVt_NULL] slot is not used, as the table is not
 available in hv.c.
 
-PTEs also use arenas, but are never seen in Perl_sv_upgrade. Nonetheless,
-they get their own slot in bodies_by_type[PTE_SVSLOT =SVt_IV], so they can
-just use the same allocation semantics.  At first, PTEs were also
-overloaded to a non-body sv-type, but this yielded hard-to-find malloc
-bugs, so was simplified by claiming a new slot.  This choice has no
-consequence at this time.
-
 */
 
 struct body_details {
@@ -921,14 +907,11 @@ static const struct body_details bodies_by_type[] = {
        implemented.  */
     { 0, 0, 0, SVt_BIND, TRUE, NONV, NOARENA, 0 },
 
-    /* IVs are in the head, so the allocation size is 0.
-       However, the slot is overloaded for PTEs.  */
-    { sizeof(struct ptr_tbl_ent), /* This is used for PTEs.  */
+    /* IVs are in the head, so the allocation size is 0.  */
+    { 0,
       sizeof(IV), /* This is used to copy out the IV body.  */
       STRUCT_OFFSET(XPVIV, xiv_iv), SVt_IV, FALSE, NONV,
-      NOARENA /* IVS don't need an arena  */,
-      /* But PTEs need to know the size of their arena  */
-      FIT_ARENA(0, sizeof(struct ptr_tbl_ent))
+      NOARENA /* IVS don't need an arena  */, 0
     },
 
     /* 8 bytes on most ILP32 with IEEE doubles */
@@ -1372,6 +1355,10 @@ Perl_sv_upgrade(pTHX_ register SV *const sv, svtype new_type)
        break;
 
 
+    case SVt_REGEXP:
+       /* This ensures that SvTHINKFIRST(sv) is true, and hence that
+          sv_force_normal_flags(sv) is called.  */
+       SvFAKE_on(sv);
     case SVt_PVIV:
        /* XXX Is this still needed?  Was it ever needed?   Surely as there is
           no route from NV to PVIV, NOK can never be true  */
@@ -1382,7 +1369,6 @@ Perl_sv_upgrade(pTHX_ register SV *const sv, svtype new_type)
     case SVt_PVGV:
     case SVt_PVCV:
     case SVt_PVLV:
-    case SVt_REGEXP:
     case SVt_PVMG:
     case SVt_PVNV:
     case SVt_PV:
@@ -1431,7 +1417,7 @@ Perl_sv_upgrade(pTHX_ register SV *const sv, svtype new_type)
 
        if (new_type == SVt_PVIO) {
            IO * const io = MUTABLE_IO(sv);
-           GV *iogv = gv_fetchpvs("IO::Handle::", GV_ADD, SVt_PVHV);
+           GV *iogv = gv_fetchpvs("IO::File::", GV_ADD, SVt_PVHV);
 
            SvOBJECT_on(io);
            /* Clear the stashcache because a new IO could overrule a package
@@ -1452,7 +1438,7 @@ Perl_sv_upgrade(pTHX_ register SV *const sv, svtype new_type)
                   (unsigned long)new_type);
     }
 
-    if (old_type > SVt_IV) { /* SVt_IVs are overloaded for PTEs */
+    if (old_type > SVt_IV) {
 #ifdef PURIFY
        my_safefree(old_body);
 #else
@@ -1714,7 +1700,7 @@ Perl_sv_setnv(pTHX_ register SV *const sv, const NV num)
     case SVt_PVFM:
     case SVt_PVIO:
        Perl_croak(aTHX_ "Can't coerce %s to number in %s", sv_reftype(sv,0),
-                  OP_NAME(PL_op));
+                  OP_DESC(PL_op));
     default: NOOP;
     }
     SvNV_set(sv, num);
@@ -2986,11 +2972,17 @@ Perl_sv_2pv_flags(pTHX_ register SV *const sv, STRLEN *const lp, const I32 flags
            gv_efullname3(buffer, gv, "*");
            SvFLAGS(gv) |= wasfake;
 
-           assert(SvPOK(buffer));
-           if (lp) {
-               *lp = SvCUR(buffer);
+           if (SvPOK(buffer)) {
+               if (lp) {
+                   *lp = SvCUR(buffer);
+               }
+               return SvPVX(buffer);
+           }
+           else {
+               if (lp)
+                   *lp = 0;
+               return (char *)"";
            }
-           return SvPVX(buffer);
        }
 
        if (lp)
@@ -3115,7 +3107,7 @@ Perl_sv_2bool(pTHX_ register SV *const sv)
        if (SvAMAGIC(sv)) {
            SV * const tmpsv = AMG_CALLun(sv,bool_);
            if (tmpsv && (!SvROK(tmpsv) || (SvRV(tmpsv) != SvRV(sv))))
-               return (bool)SvTRUE(tmpsv);
+               return cBOOL(SvTRUE(tmpsv));
        }
        return SvRV(sv) != 0;
     }
@@ -3676,7 +3668,6 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr)
     SV **location;
     U8 import_flag = 0;
     const U32 stype = SvTYPE(sref);
-    bool mro_changes = FALSE;
 
     PERL_ARGS_ASSERT_GLOB_ASSIGN_REF;
 
@@ -3697,8 +3688,6 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr)
        goto common;
     case SVt_PVAV:
        location = (SV **) &GvAV(dstr);
-        if (strEQ(GvNAME((GV*)dstr), "ISA"))
-           mro_changes = TRUE;
        import_flag = GVf_IMPORTED_AV;
        goto common;
     case SVt_PVIO:
@@ -3772,12 +3761,15 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr)
            && CopSTASH_ne(PL_curcop, GvSTASH(dstr))) {
            GvFLAGS(dstr) |= import_flag;
        }
+       if (stype == SVt_PVAV && strEQ(GvNAME((GV*)dstr), "ISA")) {
+           sv_magic(sref, dstr, PERL_MAGIC_isa, NULL, 0);
+           mro_isa_changed_in(GvSTASH(dstr));
+       }
        break;
     }
     SvREFCNT_dec(dref);
     if (SvTAINTED(sstr))
        SvTAINT(dstr);
-    if (mro_changes) mro_isa_changed_in(GvSTASH(dstr));
     return;
 }
 
@@ -3905,7 +3897,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags)
        {
        const char * const type = sv_reftype(sstr,0);
        if (PL_op)
-           Perl_croak(aTHX_ "Bizarre copy of %s in %s", type, OP_NAME(PL_op));
+           Perl_croak(aTHX_ "Bizarre copy of %s in %s", type, OP_DESC(PL_op));
        else
            Perl_croak(aTHX_ "Bizarre copy of %s", type);
        }
@@ -3965,7 +3957,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags)
     } else if (dtype == SVt_PVAV || dtype == SVt_PVHV) {
        const char * const type = sv_reftype(dstr,0);
        if (PL_op)
-           Perl_croak(aTHX_ "Cannot copy to %s in %s", type, OP_NAME(PL_op));
+           Perl_croak(aTHX_ "Cannot copy to %s in %s", type, OP_DESC(PL_op));
        else
            Perl_croak(aTHX_ "Cannot copy to %s", type);
     } else if (sflags & SVf_ROK) {
@@ -4609,6 +4601,45 @@ Perl_sv_force_normal_flags(pTHX_ register SV *const sv, const U32 flags)
        sv_unref_flags(sv, flags);
     else if (SvFAKE(sv) && SvTYPE(sv) == SVt_PVGV)
        sv_unglob(sv);
+    else if (SvFAKE(sv) && SvTYPE(sv) == SVt_REGEXP) {
+       /* Need to downgrade the REGEXP to a simple(r) scalar. This is analagous
+          to sv_unglob. We only need it here, so inline it.  */
+       const svtype new_type = SvMAGIC(sv) || SvSTASH(sv) ? SVt_PVMG : SVt_PV;
+       SV *const temp = newSV_type(new_type);
+       void *const temp_p = SvANY(sv);
+
+       if (new_type == SVt_PVMG) {
+           SvMAGIC_set(temp, SvMAGIC(sv));
+           SvMAGIC_set(sv, NULL);
+           SvSTASH_set(temp, SvSTASH(sv));
+           SvSTASH_set(sv, NULL);
+       }
+       SvCUR_set(temp, SvCUR(sv));
+       /* Remember that SvPVX is in the head, not the body. */
+       if (SvLEN(temp)) {
+           SvLEN_set(temp, SvLEN(sv));
+           /* This signals "buffer is owned by someone else" in sv_clear,
+              which is the least effort way to stop it freeing the buffer.
+           */
+           SvLEN_set(sv, SvLEN(sv)+1);
+       } else {
+           /* Their buffer is already owned by someone else. */
+           SvPVX(sv) = savepvn(SvPVX(sv), SvCUR(sv));
+           SvLEN_set(temp, SvCUR(sv)+1);
+       }
+
+       /* Now swap the rest of the bodies. */
+
+       SvFLAGS(sv) &= ~(SVf_FAKE|SVTYPEMASK);
+       SvFLAGS(sv) |= new_type;
+       SvANY(sv) = SvANY(temp);
+
+       SvFLAGS(temp) &= ~(SVTYPEMASK);
+       SvFLAGS(temp) |= SVt_REGEXP|SVf_FAKE;
+       SvANY(temp) = temp_p;
+
+       SvREFCNT_dec(temp);
+    }
 }
 
 /*
@@ -5209,12 +5240,14 @@ Perl_sv_unmagic(pTHX_ SV *const sv, const int type)
        else
            mgp = &mg->mg_moremagic;
     }
-    if (!SvMAGIC(sv)) {
+    if (SvMAGIC(sv)) {
+       if (SvMAGICAL(sv))      /* if we're under save_magic, wait for restore_magic; */
+           mg_magical(sv);     /*    else fix the flags now */
+    }
+    else {
        SvMAGICAL_off(sv);
        SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
-       SvMAGIC_set(sv, NULL);
     }
-
     return 0;
 }
 
@@ -5626,15 +5659,9 @@ Perl_sv_clear(pTHX_ register SV *const sv)
 
     if (type <= SVt_IV) {
        /* See the comment in sv.h about the collusion between this early
-          return and the overloading of the NULL and IV slots in the size
-          table.  */
-       if (SvROK(sv)) {
-           SV * const target = SvRV(sv);
-           if (SvWEAKREF(sv))
-               sv_del_backref(target, sv);
-           else
-               SvREFCNT_dec(target);
-       }
+          return and the overloading of the NULL slots in the size table.  */
+       if (SvROK(sv))
+           goto free_rv;
        SvFLAGS(sv) &= SVf_BREAK;
        SvFLAGS(sv) |= SVTYPEMASK;
        return;
@@ -5656,7 +5683,8 @@ Perl_sv_clear(pTHX_ register SV *const sv)
                        && !CvCONST(destructor)
                        /* Don't bother calling an empty destructor */
                        && (CvISXSUB(destructor)
-                       || CvSTART(destructor)->op_next->op_type != OP_LEAVESUB))
+                       || (CvSTART(destructor)
+                           && (CvSTART(destructor)->op_next->op_type != OP_LEAVESUB))))
                {
                    SV* const tmpref = newRV(sv);
                    SvREADONLY_on(tmpref);   /* DESTROY() could be naughty */
@@ -5785,11 +5813,14 @@ Perl_sv_clear(pTHX_ register SV *const sv)
            /* Don't even bother with turning off the OOK flag.  */
        }
        if (SvROK(sv)) {
-           SV * const target = SvRV(sv);
-           if (SvWEAKREF(sv))
-               sv_del_backref(target, sv);
-           else
-               SvREFCNT_dec(target);
+       free_rv:
+           {
+               SV * const target = SvRV(sv);
+               if (SvWEAKREF(sv))
+                   sv_del_backref(target, sv);
+               else
+                   SvREFCNT_dec(target);
+           }
        }
 #ifdef PERL_OLD_COPY_ON_WRITE
        else if (SvPVX_const(sv)) {
@@ -6014,12 +6045,17 @@ Perl_sv_len_utf8(pTHX_ register SV *const sv)
            else {
                ulen = Perl_utf8_length(aTHX_ s, s + len);
                if (!SvREADONLY(sv)) {
-                   if (!mg) {
+                   if (!mg && (SvTYPE(sv) < SVt_PVMG ||
+                               !(mg = mg_find(sv, PERL_MAGIC_utf8)))) {
                        mg = sv_magicext(sv, 0, PERL_MAGIC_utf8,
                                         &PL_vtbl_utf8, 0, 0);
                    }
                    assert(mg);
                    mg->mg_len = ulen;
+                   /* For now, treat "overflowed" as "still unknown".
+                      See RT #72924.  */
+                   if (ulen != (STRLEN) mg->mg_len)
+                       mg->mg_len = -1;
                }
            }
            return ulen;
@@ -6094,8 +6130,10 @@ S_sv_pos_u2b_cached(pTHX_ SV *const sv, MAGIC **const mgp, const U8 *const start
 
     assert (uoffset >= uoffset0);
 
-    if (SvMAGICAL(sv) && !SvREADONLY(sv) && PL_utf8cache
-       && (*mgp || (*mgp = mg_find(sv, PERL_MAGIC_utf8)))) {
+    if (!SvREADONLY(sv)
+       && PL_utf8cache
+       && (*mgp || (SvTYPE(sv) >= SVt_PVMG &&
+                    (*mgp = mg_find(sv, PERL_MAGIC_utf8))))) {
        if ((*mgp)->mg_ptr) {
            STRLEN *cache = (STRLEN *) (*mgp)->mg_ptr;
            if (cache[0] == uoffset) {
@@ -6186,62 +6224,97 @@ S_sv_pos_u2b_cached(pTHX_ SV *const sv, MAGIC **const mgp, const U8 *const start
 
 
 /*
-=for apidoc sv_pos_u2b
+=for apidoc sv_pos_u2b_flags
 
 Converts the value pointed to by offsetp from a count of UTF-8 chars from
 the start of the string, to a count of the equivalent number of bytes; if
 lenp is non-zero, it does the same to lenp, but this time starting from
-the offset, rather than from the start of the string. Handles magic and
-type coercion.
+the offset, rather than from the start of the string. Handles type coercion.
+I<flags> is passed to C<SvPV_flags>, and usually should be
+C<SV_GMAGIC|SV_CONST_RETURN> to handle magic.
 
 =cut
 */
 
 /*
- * sv_pos_u2b() uses, like sv_pos_b2u(), the mg_ptr of the potential
+ * sv_pos_u2b_flags() uses, like sv_pos_b2u(), the mg_ptr of the potential
  * PERL_MAGIC_utf8 of the sv to store the mapping between UTF-8 and
  * byte offsets.  See also the comments of S_utf8_mg_pos_cache_update().
  *
  */
 
-void
-Perl_sv_pos_u2b(pTHX_ register SV *const sv, I32 *const offsetp, I32 *const lenp)
+STRLEN
+Perl_sv_pos_u2b_flags(pTHX_ SV *const sv, STRLEN uoffset, STRLEN *const lenp,
+                     U32 flags)
 {
     const U8 *start;
     STRLEN len;
+    STRLEN boffset;
 
-    PERL_ARGS_ASSERT_SV_POS_U2B;
+    PERL_ARGS_ASSERT_SV_POS_U2B_FLAGS;
 
-    if (!sv)
-       return;
-
-    start = (U8*)SvPV_const(sv, len);
+    start = (U8*)SvPV_flags(sv, len, flags);
     if (len) {
-       STRLEN uoffset = (STRLEN) *offsetp;
        const U8 * const send = start + len;
        MAGIC *mg = NULL;
-       const STRLEN boffset = sv_pos_u2b_cached(sv, &mg, start, send,
-                                            uoffset, 0, 0);
-
-       *offsetp = (I32) boffset;
+       boffset = sv_pos_u2b_cached(sv, &mg, start, send, uoffset, 0, 0);
 
        if (lenp) {
            /* Convert the relative offset to absolute.  */
-           const STRLEN uoffset2 = uoffset + (STRLEN) *lenp;
+           const STRLEN uoffset2 = uoffset + *lenp;
            const STRLEN boffset2
                = sv_pos_u2b_cached(sv, &mg, start, send, uoffset2,
                                      uoffset, boffset) - boffset;
 
            *lenp = boffset2;
        }
-    }
-    else {
-        *offsetp = 0;
-        if (lenp)
-             *lenp = 0;
+    } else {
+       if (lenp)
+           *lenp = 0;
+       boffset = 0;
     }
 
-    return;
+    return boffset;
+}
+
+/*
+=for apidoc sv_pos_u2b
+
+Converts the value pointed to by offsetp from a count of UTF-8 chars from
+the start of the string, to a count of the equivalent number of bytes; if
+lenp is non-zero, it does the same to lenp, but this time starting from
+the offset, rather than from the start of the string. Handles magic and
+type coercion.
+
+Use C<sv_pos_u2b_flags> in preference, which correctly handles strings longer
+than 2Gb.
+
+=cut
+*/
+
+/*
+ * sv_pos_u2b() uses, like sv_pos_b2u(), the mg_ptr of the potential
+ * PERL_MAGIC_utf8 of the sv to store the mapping between UTF-8 and
+ * byte offsets.  See also the comments of S_utf8_mg_pos_cache_update().
+ *
+ */
+
+/* This function is subject to size and sign problems */
+
+void
+Perl_sv_pos_u2b(pTHX_ register SV *const sv, I32 *const offsetp, I32 *const lenp)
+{
+    PERL_ARGS_ASSERT_SV_POS_U2B;
+
+    if (lenp) {
+       STRLEN ulen = (STRLEN)*lenp;
+       *offsetp = (I32)sv_pos_u2b_flags(sv, (STRLEN)*offsetp, &ulen,
+                                        SV_GMAGIC|SV_CONST_RETURN);
+       *lenp = (I32)ulen;
+    } else {
+       *offsetp = (I32)sv_pos_u2b_flags(sv, (STRLEN)*offsetp, NULL,
+                                        SV_GMAGIC|SV_CONST_RETURN);
+    }
 }
 
 /* Create and update the UTF8 magic offset cache, with the proffered utf8/
@@ -6278,7 +6351,8 @@ S_utf8_mg_pos_cache_update(pTHX_ SV *const sv, MAGIC **const mgp, const STRLEN b
     if (SvREADONLY(sv))
        return;
 
-    if (!*mgp) {
+    if (!*mgp && (SvTYPE(sv) < SVt_PVMG ||
+                 !(*mgp = mg_find(sv, PERL_MAGIC_utf8)))) {
        *mgp = sv_magicext(sv, 0, PERL_MAGIC_utf8, (MGVTBL*)&PL_vtbl_utf8, 0,
                           0);
        (*mgp)->mg_len = -1;
@@ -6475,8 +6549,11 @@ Perl_sv_pos_b2u(pTHX_ register SV *const sv, I32 *const offsetp)
 
     send = s + byte;
 
-    if (SvMAGICAL(sv) && !SvREADONLY(sv) && PL_utf8cache
-       && (mg = mg_find(sv, PERL_MAGIC_utf8))) {
+    if (!SvREADONLY(sv)
+       && PL_utf8cache
+       && SvTYPE(sv) >= SVt_PVMG
+       && (mg = mg_find(sv, PERL_MAGIC_utf8)))
+    {
        if (mg->mg_ptr) {
            STRLEN * const cache = (STRLEN *) mg->mg_ptr;
            if (cache[1] == byte) {
@@ -7577,7 +7654,8 @@ string.  You are responsible for ensuring that the source string is at least
 C<len> bytes long.  If the C<s> argument is NULL the new SV will be undefined.
 Currently the only flag bits accepted are C<SVf_UTF8> and C<SVs_TEMP>.
 If C<SVs_TEMP> is set, then C<sv2mortal()> is called on the result before
-returning. If C<SVf_UTF8> is set, then it will be set on the new SV.
+returning. If C<SVf_UTF8> is set, C<s> is considered to be in UTF-8 and the
+C<SVf_UTF8> flag will be set on the new SV.
 C<newSVpvn_utf8()> is a convenience wrapper for this function, defined as
 
     #define newSVpvn_utf8(s, len, u)                   \
@@ -8337,14 +8415,14 @@ Perl_sv_pvn_force_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
            const char * const ref = sv_reftype(sv,0);
            if (PL_op)
                Perl_croak(aTHX_ "Can't coerce readonly %s to string in %s",
-                          ref, OP_NAME(PL_op));
+                          ref, OP_DESC(PL_op));
            else
                Perl_croak(aTHX_ "Can't coerce readonly %s to string", ref);
        }
        if ((SvTYPE(sv) > SVt_PVLV && SvTYPE(sv) != SVt_PVFM)
            || isGV_with_GP(sv))
            Perl_croak(aTHX_ "Can't coerce %s to string in %s", sv_reftype(sv,0),
-               OP_NAME(PL_op));
+               OP_DESC(PL_op));
        s = sv_2pv_flags(sv, &len, flags);
        if (lp)
            *lp = len;
@@ -9161,6 +9239,22 @@ Perl_sv_vsetpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen,
     sv_vcatpvfn(sv, pat, patlen, args, svargs, svmax, maybe_tainted);
 }
 
+
+/*
+ * Warn of missing argument to sprintf, and then return a defined value
+ * to avoid inappropriate "use of uninit" warnings [perl #71000].
+ */
+#define WARN_MISSING WARN_UNINITIALIZED /* Not sure we want a new category */
+STATIC SV*
+S_vcatpvfn_missing_argument(pTHX) {
+    if (ckWARN(WARN_MISSING)) {
+       Perl_warner(aTHX_ packWARN(WARN_MISSING), "Missing argument in %s",
+               PL_op ? OP_DESC(PL_op) : "sv_vcatpvfn()");
+    }
+    return &PL_sv_no;
+}
+
+
 STATIC I32
 S_expect_number(pTHX_ char **const pattern)
 {
@@ -9177,7 +9271,7 @@ S_expect_number(pTHX_ char **const pattern)
        while (isDIGIT(**pattern)) {
            const I32 tmp = var * 10 + (*(*pattern)++ - '0');
            if (tmp < var)
-               Perl_croak(aTHX_ "Integer overflow in format string for %s", (PL_op ? OP_NAME(PL_op) : "sv_vcatpvfn"));
+               Perl_croak(aTHX_ "Integer overflow in format string for %s", (PL_op ? OP_DESC(PL_op) : "sv_vcatpvfn"));
            var = tmp;
        }
     }
@@ -9526,9 +9620,10 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen,
                    vecsv = va_arg(*args, SV*);
                else if (evix) {
                    vecsv = (evix > 0 && evix <= svmax)
-                       ? svargs[evix-1] : &PL_sv_undef;
+                       ? svargs[evix-1] : S_vcatpvfn_missing_argument(aTHX);
                } else {
-                   vecsv = svix < svmax ? svargs[svix++] : &PL_sv_undef;
+                   vecsv = svix < svmax
+                       ? svargs[svix++] : S_vcatpvfn_missing_argument(aTHX);
                }
                dotstr = SvPV_const(vecsv, dotstrlen);
                /* Keep the DO_UTF8 test *after* the SvPV call, else things go
@@ -9675,10 +9770,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen,
        if (!vectorize && !args) {
            if (efix) {
                const I32 i = efix-1;
-               argsv = (i >= 0 && i < svmax) ? svargs[i] : &PL_sv_undef;
+               argsv = (i >= 0 && i < svmax)
+                   ? svargs[i] : S_vcatpvfn_missing_argument(aTHX);
            } else {
                argsv = (svix >= 0 && svix < svmax)
-                   ? svargs[svix++] : &PL_sv_undef;
+                   ? svargs[svix++] : S_vcatpvfn_missing_argument(aTHX);
            }
        }
 
@@ -10315,6 +10411,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen,
            goto vector;
        }
     }
+    SvTAINT(sv);
 }
 
 /* =========================================================================
@@ -10620,6 +10717,11 @@ Perl_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *const param)
 
 #endif /* USE_ITHREADS */
 
+struct ptr_tbl_arena {
+    struct ptr_tbl_arena *next;
+    struct ptr_tbl_ent array[1023/3]; /* as ptr_tbl_ent has 3 pointers.  */
+};
+
 /* create a new pointer-mapping table */
 
 PTR_TBL_t *
@@ -10631,6 +10733,9 @@ Perl_ptr_table_new(pTHX)
     Newx(tbl, 1, PTR_TBL_t);
     tbl->tbl_max       = 511;
     tbl->tbl_items     = 0;
+    tbl->tbl_arena     = NULL;
+    tbl->tbl_arena_next        = NULL;
+    tbl->tbl_arena_end = NULL;
     Newxz(tbl->tbl_ary, tbl->tbl_max + 1, PTR_TBL_ENT_t*);
     return tbl;
 }
@@ -10638,14 +10743,6 @@ Perl_ptr_table_new(pTHX)
 #define PTR_TABLE_HASH(ptr) \
   ((PTR2UV(ptr) >> 3) ^ (PTR2UV(ptr) >> (3 + 7)) ^ (PTR2UV(ptr) >> (3 + 17)))
 
-/* 
-   we use the PTE_SVSLOT 'reservation' made above, both here (in the
-   following define) and at call to new_body_inline made below in 
-   Perl_ptr_table_store()
- */
-
-#define del_pte(p)     del_body_type(p, PTE_SVSLOT)
-
 /* map an existing pointer using a table */
 
 STATIC PTR_TBL_ENT_t *
@@ -10690,7 +10787,18 @@ Perl_ptr_table_store(pTHX_ PTR_TBL_t *const tbl, const void *const oldsv, void *
     } else {
        const UV entry = PTR_TABLE_HASH(oldsv) & tbl->tbl_max;
 
-       new_body_inline(tblent, PTE_SVSLOT);
+       if (tbl->tbl_arena_next == tbl->tbl_arena_end) {
+           struct ptr_tbl_arena *new_arena;
+
+           Newx(new_arena, 1, struct ptr_tbl_arena);
+           new_arena->next = tbl->tbl_arena;
+           tbl->tbl_arena = new_arena;
+           tbl->tbl_arena_next = new_arena->array;
+           tbl->tbl_arena_end = new_arena->array
+               + sizeof(new_arena->array) / sizeof(new_arena->array[0]);
+       }
+
+       tblent = tbl->tbl_arena_next++;
 
        tblent->oldval = oldsv;
        tblent->newval = newsv;
@@ -10738,25 +10846,27 @@ Perl_ptr_table_split(pTHX_ PTR_TBL_t *const tbl)
 }
 
 /* remove all the entries from a ptr table */
+/* Deprecated - will be removed post 5.14 */
 
 void
 Perl_ptr_table_clear(pTHX_ PTR_TBL_t *const tbl)
 {
     if (tbl && tbl->tbl_items) {
-       register PTR_TBL_ENT_t * const * const array = tbl->tbl_ary;
-       UV riter = tbl->tbl_max;
+       struct ptr_tbl_arena *arena = tbl->tbl_arena;
 
-       do {
-           PTR_TBL_ENT_t *entry = array[riter];
+       Zero(tbl->tbl_ary, tbl->tbl_max + 1, struct ptr_tbl_ent **);
 
-           while (entry) {
-               PTR_TBL_ENT_t * const oentry = entry;
-               entry = entry->next;
-               del_pte(oentry);
-           }
-       } while (riter--);
+       while (arena) {
+           struct ptr_tbl_arena *next = arena->next;
+
+           Safefree(arena);
+           arena = next;
+       };
 
        tbl->tbl_items = 0;
+       tbl->tbl_arena = NULL;
+       tbl->tbl_arena_next = NULL;
+       tbl->tbl_arena_end = NULL;
     }
 }
 
@@ -10765,10 +10875,21 @@ Perl_ptr_table_clear(pTHX_ PTR_TBL_t *const tbl)
 void
 Perl_ptr_table_free(pTHX_ PTR_TBL_t *const tbl)
 {
+    struct ptr_tbl_arena *arena;
+
     if (!tbl) {
         return;
     }
-    ptr_table_clear(tbl);
+
+    arena = tbl->tbl_arena;
+
+    while (arena) {
+       struct ptr_tbl_arena *next = arena->next;
+
+       Safefree(arena);
+       arena = next;
+    }
+
     Safefree(tbl->tbl_ary);
     Safefree(tbl);
 }
@@ -11008,10 +11129,23 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
                    GvNAME_HEK(dstr) = hek_dup(GvNAME_HEK(dstr), param);
                    /* Don't call sv_add_backref here as it's going to be
                       created as part of the magic cloning of the symbol
-                      table.  */
+                      table--unless this is during a join and the stash
+                      is not actually being cloned.  */
                    /* Danger Will Robinson - GvGP(dstr) isn't initialised
                       at the point of this comment.  */
                    GvSTASH(dstr) = hv_dup(GvSTASH(dstr), param);
+                   if(param->flags & CLONEf_JOIN_IN) {
+                       const HEK * const hvname
+                        = HvNAME_HEK(GvSTASH(dstr));
+                       if( hvname
+                        && GvSTASH(dstr) == gv_stashpvn(
+                            HEK_KEY(hvname), HEK_LEN(hvname), 0
+                           )
+                         )
+                           Perl_sv_add_backref(
+                            aTHX_ MUTABLE_SV(GvSTASH(dstr)), dstr
+                           );
+                   }
                    GvGP(dstr)  = gp_dup(GvGP(sstr), param);
                    (void)GpREFCNT_inc(GvGP(dstr));
                } else
@@ -11064,6 +11198,11 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
                    else {
                        while (items-- > 0)
                            *dst_ary++ = sv_dup(*src_ary++, param);
+                       if (!(param->flags & CLONEf_COPY_STACKS)
+                            && AvREIFY(sstr))
+                       {
+                           av_reify(MUTABLE_AV(dstr)); /* #41138 */
+                       }
                    }
                    items = AvMAX((const AV *)sstr) - AvFILLp((const AV *)sstr);
                    while (items-- > 0) {
@@ -11108,7 +11247,7 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
                        daux->xhv_riter = saux->xhv_riter;
                        daux->xhv_eiter = saux->xhv_eiter
                            ? he_dup(saux->xhv_eiter,
-                                       (bool)!!HvSHAREKEYS(sstr), param) : 0;
+                                       cBOOL(HvSHAREKEYS(sstr)), param) : 0;
                        /* backref array needs refcnt=2; see sv_add_backref */
                        daux->xhv_backreferences =
                            saux->xhv_backreferences
@@ -11454,12 +11593,14 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            TOPPTR(nss,ix) = pv_dup(c);
            break;
        case SAVEt_GP:                          /* scalar reference */
+           gv = (const GV *)POPPTR(ss,ix);
+           TOPPTR(nss,ix) = gv_dup_inc(gv, param);
            gp = (GP*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = gp = gp_dup(gp, param);
            (void)GpREFCNT_inc(gp);
-           gv = (const GV *)POPPTR(ss,ix);
-           TOPPTR(nss,ix) = gv_dup_inc(gv, param);
-            break;
+           i = POPINT(ss,ix);
+           TOPINT(nss,ix) = i;
+           break;
        case SAVEt_FREEOP:
            ptr = POPPTR(ss,ix);
            if (ptr && (((OP*)ptr)->op_private & OPpREFCOUNTED)) {
@@ -11561,7 +11702,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
            longval = (long)POPBOOL(ss,ix);
-           TOPBOOL(nss,ix) = (bool)longval;
+           TOPBOOL(nss,ix) = cBOOL(longval);
            break;
        case SAVEt_SET_SVFLAGS:
            i = POPINT(ss,ix);
@@ -11770,12 +11911,20 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PerlInterpreter * const my_perl = (PerlInterpreter*)(*ipM->pMalloc)(ipM, sizeof(PerlInterpreter));
 
     PERL_ARGS_ASSERT_PERL_CLONE_USING;
+#else          /* !PERL_IMPLICIT_SYS */
+    IV i;
+    CLONE_PARAMS clone_params;
+    CLONE_PARAMS* param = &clone_params;
+    PerlInterpreter * const my_perl = (PerlInterpreter*)PerlMem_malloc(sizeof(PerlInterpreter));
+
+    PERL_ARGS_ASSERT_PERL_CLONE;
+#endif         /* PERL_IMPLICIT_SYS */
 
     /* for each stash, determine whether its objects should be cloned */
     S_visit(proto_perl, do_mark_cloneable_stash, SVt_PVHV, SVTYPEMASK);
     PERL_SET_THX(my_perl);
 
-#  ifdef DEBUGGING
+#ifdef DEBUGGING
     PoisonNew(my_perl, 1, PerlInterpreter);
     PL_op = NULL;
     PL_curcop = NULL;
@@ -11788,10 +11937,14 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_sig_pending = 0;
     PL_parser = NULL;
     Zero(&PL_debug_pad, 1, struct perl_debug_pad);
-#  else        /* !DEBUGGING */
+#  ifdef DEBUG_LEAKING_SCALARS
+    PL_sv_serial = (((U32)my_perl >> 2) & 0xfff) * 1000000;
+#  endif
+#else  /* !DEBUGGING */
     Zero(my_perl, 1, PerlInterpreter);
-#  endif       /* DEBUGGING */
+#endif /* DEBUGGING */
 
+#ifdef PERL_IMPLICIT_SYS
     /* host pointers */
     PL_Mem             = ipM;
     PL_MemShared       = ipMS;
@@ -11802,35 +11955,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_Dir             = ipD;
     PL_Sock            = ipS;
     PL_Proc            = ipP;
-#else          /* !PERL_IMPLICIT_SYS */
-    IV i;
-    CLONE_PARAMS clone_params;
-    CLONE_PARAMS* param = &clone_params;
-    PerlInterpreter * const my_perl = (PerlInterpreter*)PerlMem_malloc(sizeof(PerlInterpreter));
-
-    PERL_ARGS_ASSERT_PERL_CLONE;
-
-    /* for each stash, determine whether its objects should be cloned */
-    S_visit(proto_perl, do_mark_cloneable_stash, SVt_PVHV, SVTYPEMASK);
-    PERL_SET_THX(my_perl);
-
-#    ifdef DEBUGGING
-    PoisonNew(my_perl, 1, PerlInterpreter);
-    PL_op = NULL;
-    PL_curcop = NULL;
-    PL_markstack = 0;
-    PL_scopestack = 0;
-    PL_scopestack_name = 0;
-    PL_savestack = 0;
-    PL_savestack_ix = 0;
-    PL_savestack_max = -1;
-    PL_sig_pending = 0;
-    PL_parser = NULL;
-    Zero(&PL_debug_pad, 1, struct perl_debug_pad);
-#    else      /* !DEBUGGING */
-    Zero(my_perl, 1, PerlInterpreter);
-#    endif     /* DEBUGGING */
 #endif         /* PERL_IMPLICIT_SYS */
+
     param->flags = flags;
     param->proto_perl = proto_perl;
 
@@ -11890,6 +12016,9 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     SvNV_set(&PL_sv_yes, 1);
     ptr_table_store(PL_ptr_table, &proto_perl->Isv_yes, &PL_sv_yes);
 
+    /* dbargs array probably holds garbage */
+    PL_dbargs          = NULL;
+
     /* create (a non-shared!) shared string table */
     PL_strtab          = newHV();
     HvSHAREKEYS_off(PL_strtab);
@@ -12016,7 +12145,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_DBsingle                = sv_dup(proto_perl->IDBsingle, param);
     PL_DBtrace         = sv_dup(proto_perl->IDBtrace, param);
     PL_DBsignal                = sv_dup(proto_perl->IDBsignal, param);
-    PL_dbargs          = av_dup(proto_perl->Idbargs, param);
 
     /* symbol tables */
     PL_defstash                = hv_dup_inc(proto_perl->Idefstash, param);
@@ -12187,6 +12315,16 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_utf8_punct      = sv_dup_inc(proto_perl->Iutf8_punct, param);
     PL_utf8_xdigit     = sv_dup_inc(proto_perl->Iutf8_xdigit, param);
     PL_utf8_mark       = sv_dup_inc(proto_perl->Iutf8_mark, param);
+    PL_utf8_X_begin    = sv_dup_inc(proto_perl->Iutf8_X_begin, param);
+    PL_utf8_X_extend   = sv_dup_inc(proto_perl->Iutf8_X_extend, param);
+    PL_utf8_X_prepend  = sv_dup_inc(proto_perl->Iutf8_X_prepend, param);
+    PL_utf8_X_non_hangul       = sv_dup_inc(proto_perl->Iutf8_X_non_hangul, param);
+    PL_utf8_X_L        = sv_dup_inc(proto_perl->Iutf8_X_L, param);
+    PL_utf8_X_LV       = sv_dup_inc(proto_perl->Iutf8_X_LV, param);
+    PL_utf8_X_LVT      = sv_dup_inc(proto_perl->Iutf8_X_LVT, param);
+    PL_utf8_X_T        = sv_dup_inc(proto_perl->Iutf8_X_T, param);
+    PL_utf8_X_V        = sv_dup_inc(proto_perl->Iutf8_X_V, param);
+    PL_utf8_X_LV_LVT_V = sv_dup_inc(proto_perl->Iutf8_X_LV_LVT_V, param);
     PL_utf8_toupper    = sv_dup_inc(proto_perl->Iutf8_toupper, param);
     PL_utf8_totitle    = sv_dup_inc(proto_perl->Iutf8_totitle, param);
     PL_utf8_tolower    = sv_dup_inc(proto_perl->Iutf8_tolower, param);
@@ -12351,6 +12489,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_bodytarget      = sv_dup_inc(proto_perl->Ibodytarget, param);
     PL_formtarget      = sv_dup(proto_perl->Iformtarget, param);
 
+    PL_restartjmpenv   = proto_perl->Irestartjmpenv;
     PL_restartop       = proto_perl->Irestartop;
     PL_in_eval         = proto_perl->Iin_eval;
     PL_delaymagic      = proto_perl->Idelaymagic;