This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make changes_between() in Module::CoreList API the same as the other functions
[perl5.git] / sv.c
diff --git a/sv.c b/sv.c
index d10e5a5..41f9d17 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -881,11 +881,6 @@ static const struct body_details bodies_by_type[] = {
     /* HEs use this offset for their arena.  */
     { 0, 0, 0, SVt_NULL, FALSE, NONV, NOARENA, 0 },
 
-    /* The bind placeholder pretends to be an RV for now.
-       Also it's marked as "can't upgrade" to stop anyone using it before it's
-       implemented.  */
-    { 0, 0, 0, SVt_DUMMY, TRUE, NONV, NOARENA, 0 },
-
     /* IVs are in the head, so the allocation size is 0.  */
     { 0,
       sizeof(IV), /* This is used to copy out the IV body.  */
@@ -903,6 +898,12 @@ static const struct body_details bodies_by_type[] = {
       SVt_PV, FALSE, NONV, HASARENA,
       FIT_ARENA(0, sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur)) },
 
+    { sizeof(XINVLIST) - STRUCT_OFFSET(XPV, xpv_cur),
+      copy_length(XINVLIST, is_offset) - STRUCT_OFFSET(XPV, xpv_cur),
+      + STRUCT_OFFSET(XPV, xpv_cur),
+      SVt_INVLIST, TRUE, NONV, HASARENA,
+      FIT_ARENA(0, sizeof(XINVLIST) - STRUCT_OFFSET(XPV, xpv_cur)) },
+
     { sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur),
       copy_length(XPVIV, xiv_u) - STRUCT_OFFSET(XPV, xpv_cur),
       + STRUCT_OFFSET(XPV, xpv_cur),
@@ -921,7 +922,7 @@ static const struct body_details bodies_by_type[] = {
     { sizeof(regexp),
       sizeof(regexp),
       0,
-      SVt_REGEXP, FALSE, NONV, HASARENA,
+      SVt_REGEXP, TRUE, NONV, HASARENA,
       FIT_ARENA(0, sizeof(regexp))
     },
 
@@ -1340,6 +1341,7 @@ Perl_sv_upgrade(pTHX_ SV *const sv, svtype new_type)
     case SVt_PVGV:
     case SVt_PVCV:
     case SVt_PVLV:
+    case SVt_INVLIST:
     case SVt_REGEXP:
     case SVt_PVMG:
     case SVt_PVNV:
@@ -1468,6 +1470,8 @@ Use the C<SvGROW> wrapper instead.
 =cut
 */
 
+static void S_sv_uncow(pTHX_ SV * const sv, const U32 flags);
+
 char *
 Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen)
 {
@@ -1500,7 +1504,7 @@ Perl_sv_grow(pTHX_ SV *const sv, STRLEN newlen)
     }
     else
     {
-       if (SvIsCOW(sv)) sv_force_normal(sv);
+       if (SvIsCOW(sv)) S_sv_uncow(aTHX_ sv, 0);
        s = SvPVX_mutable(sv);
     }
 
@@ -1720,26 +1724,24 @@ Perl_sv_setnv_mg(pTHX_ SV *const sv, const NV num)
     SvSETMAGIC(sv);
 }
 
-/* Print an "isn't numeric" warning, using a cleaned-up,
- * printable version of the offending string
+/* Return a cleaned-up, printable version of sv, for non-numeric, or
+ * not incrementable warning display.
+ * Originally part of S_not_a_number().
+ * The return value may be != tmpbuf.
  */
 
-STATIC void
-S_not_a_number(pTHX_ SV *const sv)
-{
-     dVAR;
-     SV *dsv;
-     char tmpbuf[64];
-     const char *pv;
+STATIC const char *
+S_sv_display(pTHX_ SV *const sv, char *tmpbuf, STRLEN tmpbuf_size) {
+    const char *pv;
 
-     PERL_ARGS_ASSERT_NOT_A_NUMBER;
+     PERL_ARGS_ASSERT_SV_DISPLAY;
 
      if (DO_UTF8(sv)) {
-          dsv = newSVpvs_flags("", SVs_TEMP);
+          SV *dsv = newSVpvs_flags("", SVs_TEMP);
           pv = sv_uni_display(dsv, sv, 10, UNI_DISPLAY_ISPRINT);
      } else {
          char *d = tmpbuf;
-         const char * const limit = tmpbuf + sizeof(tmpbuf) - 8;
+         const char * const limit = tmpbuf + tmpbuf_size - 8;
          /* each *s can expand to 4 chars + "...\0",
             i.e. need room for 8 chars */
        
@@ -1747,10 +1749,12 @@ S_not_a_number(pTHX_ SV *const sv)
          const char * const end = s + SvCUR(sv);
          for ( ; s < end && d < limit; s++ ) {
               int ch = *s & 0xFF;
-              if (ch & 128 && !isPRINT_LC(ch)) {
+              if (! isASCII(ch) && !isPRINT_LC(ch)) {
                    *d++ = 'M';
                    *d++ = '-';
-                   ch &= 127;
+
+                    /* Map to ASCII "equivalent" of Latin1 */
+                   ch = LATIN1_TO_NATIVE(NATIVE_TO_LATIN1(ch) & 127);
               }
               if (ch == '\n') {
                    *d++ = '\\';
@@ -1788,6 +1792,24 @@ S_not_a_number(pTHX_ SV *const sv)
          pv = tmpbuf;
     }
 
+    return pv;
+}
+
+/* Print an "isn't numeric" warning, using a cleaned-up,
+ * printable version of the offending string
+ */
+
+STATIC void
+S_not_a_number(pTHX_ SV *const sv)
+{
+     dVAR;
+     char tmpbuf[64];
+     const char *pv;
+
+     PERL_ARGS_ASSERT_NOT_A_NUMBER;
+
+     pv = sv_display(sv, tmpbuf, sizeof(tmpbuf));
+
     if (PL_op)
        Perl_warner(aTHX_ packWARN(WARN_NUMERIC),
                    /* diag_listed_as: Argument "%s" isn't numeric%s */
@@ -1799,6 +1821,20 @@ S_not_a_number(pTHX_ SV *const sv)
                    "Argument \"%s\" isn't numeric", pv);
 }
 
+STATIC void
+S_not_incrementable(pTHX_ SV *const sv) {
+     dVAR;
+     char tmpbuf[64];
+     const char *pv;
+
+     PERL_ARGS_ASSERT_NOT_INCREMENTABLE;
+
+     pv = sv_display(sv, tmpbuf, sizeof(tmpbuf));
+
+     Perl_warner(aTHX_ packWARN(WARN_NUMERIC),
+                 "Argument \"%s\" treated as 0 in increment (++)", pv);
+}
+
 /*
 =for apidoc looks_like_number
 
@@ -2240,10 +2276,8 @@ S_sv_2iuv_common(pTHX_ SV *const sv)
        if (isGV_with_GP(sv))
            return glob_2number(MUTABLE_GV(sv));
 
-       if (!SvPADTMP(sv)) {
-           if (!PL_localizing && ckWARN(WARN_UNINITIALIZED))
+       if (!PL_localizing && ckWARN(WARN_UNINITIALIZED))
                report_uninit(sv);
-       }
        if (SvTYPE(sv) < SVt_IV)
            /* Typically the caller expects that sv_any is not NULL now.  */
            sv_upgrade(sv, SVt_IV);
@@ -2271,6 +2305,9 @@ Perl_sv_2iv_flags(pTHX_ SV *const sv, const I32 flags)
     if (!sv)
        return 0;
 
+    assert (SvTYPE(sv) != SVt_PVAV && SvTYPE(sv) != SVt_PVHV
+        && SvTYPE(sv) != SVt_PVFM);
+
     if (SvGMAGICAL(sv) && (flags & SV_GMAGIC))
        mg_get(sv);
 
@@ -2445,6 +2482,8 @@ Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags)
     dVAR;
     if (!sv)
        return 0.0;
+    assert (SvTYPE(sv) != SVt_PVAV && SvTYPE(sv) != SVt_PVHV
+        && SvTYPE(sv) != SVt_PVFM);
     if (SvGMAGICAL(sv) || SvVALID(sv) || isREGEXP(sv)) {
        /* FBMs use the space for SvIVX and SvNVX for other purposes, and use
           the same flag bit as SVf_IVisUV, so must not let them cache NVs.
@@ -2642,7 +2681,7 @@ Perl_sv_2nv_flags(pTHX_ SV *const sv, const I32 flags)
            return 0.0;
        }
 
-       if (!PL_localizing && !SvPADTMP(sv) && ckWARN(WARN_UNINITIALIZED))
+       if (!PL_localizing && ckWARN(WARN_UNINITIALIZED))
            report_uninit(sv);
        assert (SvTYPE(sv) >= SVt_NV);
        /* Typically the caller expects that sv_any is not NULL now.  */
@@ -2750,6 +2789,8 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
            *lp = 0;
        return (char *)"";
     }
+    assert (SvTYPE(sv) != SVt_PVAV && SvTYPE(sv) != SVt_PVHV
+        && SvTYPE(sv) != SVt_PVFM);
     if (SvGMAGICAL(sv) && (flags & SV_GMAGIC))
        mg_get(sv);
     if (SvROK(sv)) {
@@ -2903,6 +2944,7 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
        Move(ptr, s, len, char);
        s += len;
        *s = '\0';
+        SvPOK_on(sv);
     }
     else if (SvNOK(sv)) {
        if (SvTYPE(sv) < SVt_PVNV)
@@ -2916,7 +2958,43 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
            /* The +20 is pure guesswork.  Configure test needed. --jhi */
            s = SvGROW_mutable(sv, NV_DIG + 20);
            /* some Xenix systems wipe out errno here */
-           Gconvert(SvNVX(sv), NV_DIG, 0, s);
+
+#ifndef USE_LOCALE_NUMERIC
+            Gconvert(SvNVX(sv), NV_DIG, 0, s);
+            SvPOK_on(sv);
+#else
+            /* Gconvert always uses the current locale.  That's the right thing
+             * to do if we're supposed to be using locales.  But otherwise, we
+             * want the result to be based on the C locale, so we need to
+             * change to the C locale during the Gconvert and then change back.
+             * But if we're already in the C locale (PL_numeric_standard is
+             * TRUE in that case), no need to do any changing */
+            if (PL_numeric_standard || IN_SOME_LOCALE_FORM_RUNTIME) {
+                Gconvert(SvNVX(sv), NV_DIG, 0, s);
+
+                /* If the radix character is UTF-8, and actually is in the
+                 * output, turn on the UTF-8 flag for the scalar */
+                if (! PL_numeric_standard
+                    && PL_numeric_radix_sv && SvUTF8(PL_numeric_radix_sv)
+                    && instr(s, SvPVX_const(PL_numeric_radix_sv)))
+                {
+                    SvUTF8_on(sv);
+                }
+            }
+            else {
+                char *loc = savepv(setlocale(LC_NUMERIC, NULL));
+                setlocale(LC_NUMERIC, "C");
+                Gconvert(SvNVX(sv), NV_DIG, 0, s);
+                setlocale(LC_NUMERIC, loc);
+                Safefree(loc);
+
+            }
+
+            /* We don't call SvPOK_on(), because it may come to pass that the
+             * locale changes so that the stringification we just did is no
+             * longer correct.  We will have to re-stringify every time it is
+             * needed */
+#endif
            RESTORE_ERRNO;
            while (*s) s++;
        }
@@ -2947,7 +3025,7 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
            *lp = 0;
        if (flags & SV_UNDEF_RETURNS_NULL)
            return NULL;
-       if (!PL_localizing && !SvPADTMP(sv) && ckWARN(WARN_UNINITIALIZED))
+       if (!PL_localizing && ckWARN(WARN_UNINITIALIZED))
            report_uninit(sv);
        /* Typically the caller expects that sv_any is not NULL now.  */
        if (!SvREADONLY(sv) && SvTYPE(sv) < SVt_PV)
@@ -2961,7 +3039,6 @@ Perl_sv_2pv_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
            *lp = len;
        SvCUR_set(sv, len);
     }
-    SvPOK_on(sv);
     DEBUG_c(PerlIO_printf(Perl_debug_log, "0x%"UVxf" 2pv(%s)\n",
                          PTR2UV(sv),SvPVX_const(sv)));
     if (flags & SV_CONST_RETURN)
@@ -3037,13 +3114,13 @@ Perl_sv_2pvbyte(pTHX_ SV *sv, STRLEN *const lp)
 {
     PERL_ARGS_ASSERT_SV_2PVBYTE;
 
+    SvGETMAGIC(sv);
     if (((SvREADONLY(sv) || SvFAKE(sv)) && !SvIsCOW(sv))
      || isGV_with_GP(sv) || SvROK(sv)) {
        SV *sv2 = sv_newmortal();
-       sv_copypv(sv2,sv);
+       sv_copypv_nomg(sv2,sv);
        sv = sv2;
     }
-    else SvGETMAGIC(sv);
     sv_utf8_downgrade(sv,0);
     return lp ? SvPV_nomg(sv,*lp) : SvPV_nomg_nolen(sv);
 }
@@ -3110,6 +3187,9 @@ Perl_sv_2bool_flags(pTHX_ SV *const sv, const I32 flags)
        }
        return SvRV(sv) != 0;
     }
+    if (isREGEXP(sv))
+       return
+         RX_WRAPLEN(sv) > 1 || (RX_WRAPLEN(sv) && *RX_WRAPPED(sv) != '0');
     return SvTRUE_common(sv, isGV_with_GP(sv) ? 1 : 0);
 }
 
@@ -3206,7 +3286,7 @@ Perl_sv_utf8_upgrade_flags_grow(pTHX_ SV *const sv, const I32 flags, STRLEN extr
     }
 
     if (SvIsCOW(sv)) {
-        sv_force_normal_flags(sv, 0);
+        S_sv_uncow(aTHX_ sv, 0);
     }
 
     if (PL_encoding && !(flags & SV_UTF8_NO_ENCODING)) {
@@ -3236,7 +3316,7 @@ Perl_sv_utf8_upgrade_flags_grow(pTHX_ SV *const sv, const I32 flags, STRLEN extr
 
        while (t < e) {
            const U8 ch = *t++;
-           if (NATIVE_IS_INVARIANT(ch)) continue;
+           if (NATIVE_BYTE_IS_INVARIANT(ch)) continue;
 
            t--;    /* t already incremented; re-point to first variant */
            two_byte_count = 1;
@@ -3344,13 +3424,8 @@ must_be_utf8:
                }
 
                while (t < e) {
-                   const UV uv = NATIVE8_TO_UNI(*t++);
-                   if (UNI_IS_INVARIANT(uv))
-                       *d++ = (U8)UNI_TO_NATIVE(uv);
-                   else {
-                       *d++ = (U8)UTF8_EIGHT_BIT_HI(uv);
-                       *d++ = (U8)UTF8_EIGHT_BIT_LO(uv);
-                   }
+                    append_utf8_from_native_byte(*t, &d);
+                    t++;
                }
                *d = '\0';
                SvPV_free(sv); /* No longer using pre-existing string */
@@ -3376,7 +3451,7 @@ must_be_utf8:
 
                while (d < e) {
                    const U8 chr = *d++;
-                   if (! NATIVE_IS_INVARIANT(chr)) two_byte_count++;
+                   if (! NATIVE_BYTE_IS_INVARIANT(chr)) two_byte_count++;
                }
 
                /* The string will expand by just the number of bytes that
@@ -3396,34 +3471,26 @@ must_be_utf8:
 
                e--;
                while (e >= t) {
-                   const U8 ch = NATIVE8_TO_UNI(*e--);
-                   if (UNI_IS_INVARIANT(ch)) {
-                       *d-- = UNI_TO_NATIVE(ch);
+                   if (NATIVE_BYTE_IS_INVARIANT(*e)) {
+                       *d-- = *e;
                    } else {
-                       *d-- = (U8)UTF8_EIGHT_BIT_LO(ch);
-                       *d-- = (U8)UTF8_EIGHT_BIT_HI(ch);
+                       *d-- = UTF8_EIGHT_BIT_LO(*e);
+                       *d-- = UTF8_EIGHT_BIT_HI(*e);
                    }
+                    e--;
                }
            }
 
            if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
                /* Update pos. We do it at the end rather than during
                 * the upgrade, to avoid slowing down the common case
-                * (upgrade without pos) */
+                * (upgrade without pos).
+                * pos can be stored as either bytes or characters.  Since
+                * this was previously a byte string we can just turn off
+                * the bytes flag. */
                MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global);
                if (mg) {
-                   I32 pos = mg->mg_len;
-                   if (pos > 0 && (U32)pos > invariant_head) {
-                       U8 *d = (U8*) SvPVX(sv) + invariant_head;
-                       STRLEN n = (U32)pos - invariant_head;
-                       while (n > 0) {
-                           if (UTF8_IS_START(*d))
-                               d++;
-                           d++;
-                           n--;
-                       }
-                       mg->mg_len  = d - (U8*)SvPVX(sv);
-                   }
+                   mg->mg_flags &= ~MGf_BYTES;
                }
                if ((mg = mg_find(sv, PERL_MAGIC_utf8)))
                    magic_setutf8(sv,mg); /* clear UTF8 cache */
@@ -3465,18 +3532,15 @@ Perl_sv_utf8_downgrade(pTHX_ SV *const sv, const bool fail_ok)
            int mg_flags = SV_GMAGIC;
 
             if (SvIsCOW(sv)) {
-                sv_force_normal_flags(sv, 0);
+                S_sv_uncow(aTHX_ sv, 0);
             }
            if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
                /* update pos */
                MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global);
-               if (mg) {
-                   I32 pos = mg->mg_len;
-                   if (pos > 0) {
-                       sv_pos_b2u(sv, &pos);
+               if (mg && mg->mg_len > 0 && mg->mg_flags & MGf_BYTES) {
+                       mg->mg_len = sv_pos_b2u_flags(sv, mg->mg_len,
+                                               SV_GMAGIC|SV_CONST_RETURN);
                        mg_flags = 0; /* sv_pos_b2u does get magic */
-                       mg->mg_len  = pos;
-                   }
                }
                if ((mg = mg_find(sv, PERL_MAGIC_utf8)))
                    magic_setutf8(sv,mg); /* clear UTF8 cache */
@@ -3565,6 +3629,9 @@ Perl_sv_utf8_decode(pTHX_ SV *const sv)
            }
         }
        if (SvTYPE(sv) >= SVt_PVMG && SvMAGIC(sv)) {
+           /* XXX Is this dead code?  XS_utf8_decode calls SvSETMAGIC
+                  after this, clearing pos.  Does anything on CPAN
+                  need this? */
            /* adjust pos to the start of a UTF8 char sequence */
            MAGIC * mg = mg_find(sv, PERL_MAGIC_regex_global);
            if (mg) {
@@ -4091,7 +4158,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
        }
        break;
 
-       /* case SVt_DUMMY: */
+       case SVt_INVLIST:
     case SVt_PVLV:
     case SVt_PVGV:
     case SVt_PVMG:
@@ -4293,7 +4360,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags)
                ? (!((sflags & CAN_COW_MASK) == CAN_COW_FLAGS
 # ifdef PERL_OLD_COPY_ON_WRITE
                     && (SvFLAGS(dstr) & CAN_COW_MASK) == CAN_COW_FLAGS
-                    && SvTYPE(sstr) >= SVt_PVIV
+                    && SvTYPE(sstr) >= SVt_PVIV && len
 # else
                     && !(SvFLAGS(dstr) & SVf_BREAK)
                     && !(sflags & SVf_IsCOW)
@@ -4671,7 +4738,7 @@ Perl_sv_sethek(pTHX_ SV *const sv, const HEK *const hek)
         {
            SV_CHECK_THINKFIRST_COW_DROP(sv);
            SvUPGRADE(sv, SVt_PV);
-           Safefree(SvPVX(sv));
+           SvPV_free(sv);
            SvPV_set(sv,(char *)HEK_KEY(share_hek_hek(hek)));
            SvCUR_set(sv, HEK_LEN(hek));
            SvLEN_set(sv, 0);
@@ -4826,19 +4893,14 @@ with flags set to 0.
 =cut
 */
 
-void
-Perl_sv_force_normal_flags(pTHX_ SV *const sv, const U32 flags)
+static void
+S_sv_uncow(pTHX_ SV * const sv, const U32 flags)
 {
     dVAR;
 
-    PERL_ARGS_ASSERT_SV_FORCE_NORMAL_FLAGS;
-
+    assert(SvIsCOW(sv));
+    {
 #ifdef PERL_ANY_COW
-    if (SvREADONLY(sv)) {
-       if (IN_PERL_RUNTIME)
-           Perl_croak_no_modify();
-    }
-    else if (SvIsCOW(sv)) {
        const char * const pvx = SvPVX_const(sv);
        const STRLEN len = SvLEN(sv);
        const STRLEN cur = SvCUR(sv);
@@ -4891,14 +4953,7 @@ Perl_sv_force_normal_flags(pTHX_ SV *const sv, const U32 flags)
                 sv_dump(sv);
             }
        }
-    }
 #else
-    if (SvREADONLY(sv)) {
-       if (IN_PERL_RUNTIME)
-           Perl_croak_no_modify();
-    }
-    else
-       if (SvIsCOW(sv)) {
            const char * const pvx = SvPVX_const(sv);
            const STRLEN len = SvCUR(sv);
            SvIsCOW_off(sv);
@@ -4913,8 +4968,19 @@ Perl_sv_force_normal_flags(pTHX_ SV *const sv, const U32 flags)
                *SvEND(sv) = '\0';
            }
            unshare_hek(SvSHARED_HEK_FROM_PV(pvx));
-       }
 #endif
+    }
+}
+
+void
+Perl_sv_force_normal_flags(pTHX_ SV *const sv, const U32 flags)
+{
+    PERL_ARGS_ASSERT_SV_FORCE_NORMAL_FLAGS;
+
+    if (SvREADONLY(sv))
+       Perl_croak_no_modify();
+    else if (SvIsCOW(sv))
+       S_sv_uncow(aTHX_ sv, flags);
     if (SvROK(sv))
        sv_unref_flags(sv, flags);
     else if (SvFAKE(sv) && isGV_with_GP(sv))
@@ -5049,8 +5115,14 @@ Perl_sv_chop(pTHX_ SV *const sv, const char *const ptr)
     evacp = p - evacn;
 #endif
 
+    /* This sets 'delta' to the accumulated value of all deltas so far */
     delta += old_delta;
     assert(delta);
+
+    /* If 'delta' fits in a byte, store it just prior to the new beginning of
+     * the string; otherwise store a 0 byte there and store 'delta' just prior
+     * to that, using as many bytes as a STRLEN occupies.  Thus it overwrites a
+     * portion of the chopped part of the string */
     if (delta < 0x100) {
        *--p = (U8) delta;
     } else {
@@ -5125,13 +5197,8 @@ Perl_sv_catpvn_flags(pTHX_ SV *const dsv, const char *sstr, const STRLEN slen, c
        d = (U8 *)SvPVX(dsv) + dlen;
 
        while (sstr < send) {
-           const UV uv = NATIVE_TO_ASCII((U8)*sstr++);
-           if (UNI_IS_INVARIANT(uv))
-               *d++ = (U8)UTF_TO_NATIVE(uv);
-           else {
-               *d++ = (U8)UTF8_EIGHT_BIT_HI(uv);
-               *d++ = (U8)UTF8_EIGHT_BIT_LO(uv);
-           }
+            append_utf8_from_native_byte(*sstr, &d);
+           sstr++;
        }
        SvCUR_set(dsv, d-(const U8 *)SvPVX(dsv));
     }
@@ -5307,6 +5374,8 @@ Perl_sv_magicext(pTHX_ SV *const sv, SV *const obj, const int how,
 
     PERL_ARGS_ASSERT_SV_MAGICEXT;
 
+    if (SvTYPE(sv)==SVt_PVAV) { assert (!AvPAD_NAMELIST(sv)); }
+
     SvUPGRADE(sv, SVt_PVMG);
     Newxz(mg, 1, MAGIC);
     mg->mg_moremagic = SvMAGIC(sv);
@@ -5370,6 +5439,24 @@ Perl_sv_magicext(pTHX_ SV *const sv, SV *const obj, const int how,
     return mg;
 }
 
+MAGIC *
+Perl_sv_magicext_mglob(pTHX_ SV *sv)
+{
+    PERL_ARGS_ASSERT_SV_MAGICEXT_MGLOB;
+    if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y') {
+       /* This sv is only a delegate.  //g magic must be attached to
+          its target. */
+       vivify_defelem(sv);
+       sv = LvTARG(sv);
+    }
+#ifdef PERL_OLD_COPY_ON_WRITE
+    if (SvIsCOW(sv))
+       sv_force_normal_flags(sv, 0);
+#endif
+    return sv_magicext(sv, NULL, PERL_MAGIC_regex_global,
+                      &PL_vtbl_mglob, 0, 0);
+}
+
 /*
 =for apidoc sv_magic
 
@@ -5412,17 +5499,13 @@ Perl_sv_magic(pTHX_ SV *const sv, SV *const obj, const int how,
     vtable = (vtable_index == magic_vtable_max)
        ? NULL : PL_magic_vtables + vtable_index;
 
-#ifdef PERL_ANY_COW
+#ifdef PERL_OLD_COPY_ON_WRITE
     if (SvIsCOW(sv))
         sv_force_normal_flags(sv, 0);
 #endif
     if (SvREADONLY(sv)) {
        if (
-           /* its okay to attach magic to shared strings */
-           !SvIsCOW(sv)
-
-           && IN_PERL_RUNTIME
-           && !PERL_MAGIC_TYPE_READONLY_ACCEPTABLE(how)
+           !PERL_MAGIC_TYPE_READONLY_ACCEPTABLE(how)
           )
        {
            Perl_croak_no_modify();
@@ -5439,6 +5522,16 @@ Perl_sv_magic(pTHX_ SV *const sv, SV *const obj, const int how,
        }
     }
 
+    /* Force pos to be stored as characters, not bytes. */
+    if (SvMAGICAL(sv) && DO_UTF8(sv)
+      && (mg = mg_find(sv, PERL_MAGIC_regex_global))
+      && mg->mg_len != -1
+      && mg->mg_flags & MGf_BYTES) {
+       mg->mg_len = (SSize_t)sv_pos_b2u_flags(sv, (STRLEN)mg->mg_len,
+                                              SV_CONST_RETURN);
+       mg->mg_flags &= ~MGf_BYTES;
+    }
+
     /* Rest of work is done else where */
     mg = sv_magicext(sv,obj,how,vtable,name,namlen);
 
@@ -6144,6 +6237,9 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
            }
            else if (type == SVt_PVMG && SvPAD_OUR(sv)) {
                SvREFCNT_dec(SvOURSTASH(sv));
+           }
+           else if (type == SVt_PVAV && AvPAD_NAMELIST(sv)) {
+               assert(!SvMAGICAL(sv));
            } else if (SvMAGIC(sv)) {
                /* Free back-references before other types of magic. */
                sv_unmagic(sv, PERL_MAGIC_backref);
@@ -6154,7 +6250,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
                SvREFCNT_dec(SvSTASH(sv));
        }
        switch (type) {
-           /* case SVt_DUMMY: */
+           /* case SVt_INVLIST: */
        case SVt_PVIO:
            if (IoIFP(sv) &&
                IoIFP(sv) != PerlIO_stdin() &&
@@ -6280,6 +6376,7 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
        case SVt_PVMG:
        case SVt_PVNV:
        case SVt_PVIV:
+       case SVt_INVLIST:
        case SVt_PV:
          freescalar:
            /* Don't bother with SvOOK_off(sv); as we're only going to
@@ -6460,14 +6557,21 @@ S_curse(pTHX_ SV * const sv, const bool check_refcnt) {
          assert(SvTYPE(stash) == SVt_PVHV);
          if (HvNAME(stash)) {
            CV* destructor = NULL;
+           assert (SvOOK(stash));
            if (!SvOBJECT(stash)) destructor = (CV *)SvSTASH(stash);
-           if (!destructor) {
+           if (!destructor || HvMROMETA(stash)->destroy_gen
+                               != PL_sub_generation)
+           {
                GV * const gv =
                    gv_fetchmeth_autoload(stash, "DESTROY", 7, 0);
                if (gv) destructor = GvCV(gv);
                if (!SvOBJECT(stash))
+               {
                    SvSTASH(stash) =
                        destructor ? (HV *)destructor : ((HV *)0)+1;
+                   HvAUX(stash)->xhv_mro_meta->destroy_gen =
+                       PL_sub_generation;
+               }
            }
            assert(!destructor || destructor == ((CV *)0)+1
                || SvTYPE(destructor) == SVt_PVCV);
@@ -6581,7 +6685,7 @@ Perl_sv_free2(pTHX_ SV *const sv, const U32 rc)
 
     PERL_ARGS_ASSERT_SV_FREE2;
 
-    if (rc == 1) {
+    if (LIKELY( rc == 1 )) {
         /* normal case */
         SvREFCNT(sv) = 0;
 
@@ -6916,7 +7020,7 @@ S_sv_pos_u2b_cached(pTHX_ SV *const sv, MAGIC **const mgp, const U8 *const start
 /*
 =for apidoc sv_pos_u2b_flags
 
-Converts the value pointed to by offsetp from a count of UTF-8 chars from
+Converts the offset 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
@@ -7025,9 +7129,6 @@ S_utf8_mg_len_cache_update(pTHX_ SV *const sv, MAGIC **const mgp,
     assert(*mgp);
 
     (*mgp)->mg_len = ulen;
-    /* For now, treat "overflowed" as "still unknown". See RT #72924.  */
-    if (ulen != (STRLEN) (*mgp)->mg_len)
-       (*mgp)->mg_len = -1;
 }
 
 /* Create and update the UTF8 magic offset cache, with the proffered utf8/
@@ -7205,44 +7306,41 @@ S_sv_pos_b2u_midway(pTHX_ const U8 *const s, const U8 *const target,
 }
 
 /*
-=for apidoc sv_pos_b2u
+=for apidoc sv_pos_b2u_flags
 
-Converts the value pointed to by offsetp from a count of bytes from the
-start of the string, to a count of the equivalent number of UTF-8 chars.
-Handles magic and type coercion.
+Converts the offset from a count of bytes from the start of the string, to
+a count of the equivalent number of UTF-8 chars.  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_b2u() uses, like sv_pos_u2b(), the mg_ptr of the potential
- * PERL_MAGIC_utf8 of the sv to store the mapping between UTF-8 and
- * byte offsets.
+ * sv_pos_b2u_flags() uses, like sv_pos_u2b_flags(), the mg_ptr of the
+ * potential PERL_MAGIC_utf8 of the sv to store the mapping between UTF-8
+ * and byte offsets.
  *
  */
-void
-Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp)
+STRLEN
+Perl_sv_pos_b2u_flags(pTHX_ SV *const sv, STRLEN const offset, U32 flags)
 {
     const U8* s;
-    const STRLEN byte = *offsetp;
     STRLEN len = 0; /* Actually always set, but let's keep gcc happy.  */
     STRLEN blen;
     MAGIC* mg = NULL;
     const U8* send;
     bool found = FALSE;
 
-    PERL_ARGS_ASSERT_SV_POS_B2U;
+    PERL_ARGS_ASSERT_SV_POS_B2U_FLAGS;
 
-    if (!sv)
-       return;
+    s = (const U8*)SvPV_flags(sv, blen, flags);
 
-    s = (const U8*)SvPV_const(sv, blen);
-
-    if (blen < byte)
+    if (blen < offset)
        Perl_croak(aTHX_ "panic: sv_pos_b2u: bad byte offset, blen=%"UVuf
-                  ", byte=%"UVuf, (UV)blen, (UV)byte);
+                  ", byte=%"UVuf, (UV)blen, (UV)offset);
 
-    send = s + byte;
+    send = s + offset;
 
     if (!SvREADONLY(sv)
        && PL_utf8cache
@@ -7251,18 +7349,16 @@ Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp)
     {
        if (mg->mg_ptr) {
            STRLEN * const cache = (STRLEN *) mg->mg_ptr;
-           if (cache[1] == byte) {
+           if (cache[1] == offset) {
                /* An exact match. */
-               *offsetp = cache[0];
-               return;
+               return cache[0];
            }
-           if (cache[3] == byte) {
+           if (cache[3] == offset) {
                /* An exact match. */
-               *offsetp = cache[2];
-               return;
+               return cache[2];
            }
 
-           if (cache[1] < byte) {
+           if (cache[1] < offset) {
                /* We already know part of the way. */
                if (mg->mg_len != -1) {
                    /* Actually, we know the end too.  */
@@ -7273,7 +7369,7 @@ Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp)
                    len = cache[0] + utf8_length(s + cache[1], send);
                }
            }
-           else if (cache[3] < byte) {
+           else if (cache[3] < offset) {
                /* We're between the two cached pairs, so we do the calculation
                   offset by the byte/utf-8 positions for the earlier pair,
                   then add the utf-8 characters from the string start to
@@ -7283,7 +7379,7 @@ Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp)
                    + cache[2];
 
            }
-           else { /* cache[3] > byte */
+           else { /* cache[3] > offset */
                len = S_sv_pos_b2u_midway(aTHX_ s, send, s + cache[3],
                                          cache[2]);
 
@@ -7302,14 +7398,46 @@ Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp)
            assert_uft8_cache_coherent("sv_pos_b2u", len, real_len, sv);
        len = real_len;
     }
-    *offsetp = len;
 
     if (PL_utf8cache) {
-       if (blen == byte)
+       if (blen == offset)
            utf8_mg_len_cache_update(sv, &mg, len);
        else
-           utf8_mg_pos_cache_update(sv, &mg, byte, len, blen);
+           utf8_mg_pos_cache_update(sv, &mg, offset, len, blen);
     }
+
+    return len;
+}
+
+/*
+=for apidoc sv_pos_b2u
+
+Converts the value pointed to by offsetp from a count of bytes from the
+start of the string, to a count of the equivalent number of UTF-8 chars.
+Handles magic and type coercion.
+
+Use C<sv_pos_b2u_flags> in preference, which correctly handles strings
+longer than 2Gb.
+
+=cut
+*/
+
+/*
+ * sv_pos_b2u() uses, like sv_pos_u2b(), the mg_ptr of the potential
+ * PERL_MAGIC_utf8 of the sv to store the mapping between UTF-8 and
+ * byte offsets.
+ *
+ */
+void
+Perl_sv_pos_b2u(pTHX_ SV *const sv, I32 *const offsetp)
+{
+    PERL_ARGS_ASSERT_SV_POS_B2U;
+
+    if (!sv)
+       return;
+
+    *offsetp = (I32)sv_pos_b2u_flags(sv, (STRLEN)*offsetp,
+                                    SV_GMAGIC|SV_CONST_RETURN);
 }
 
 static void
@@ -7816,9 +7944,9 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
     STRLEN rslen;
     STDCHAR rslast;
     STDCHAR *bp;
-    I32 cnt;
-    I32 i = 0;
-    I32 rspara = 0;
+    SSize_t cnt;
+    int i = 0;
+    int rspara = 0;
 
     PERL_ARGS_ASSERT_SV_GETS;
 
@@ -7963,8 +8091,9 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
     DEBUG_P(PerlIO_printf(Perl_debug_log,
        "Screamer: entering, ptr=%"UVuf", cnt=%ld\n",PTR2UV(ptr),(long)cnt));
     DEBUG_P(PerlIO_printf(Perl_debug_log,
-       "Screamer: entering: PerlIO * thinks ptr=%"UVuf", cnt=%ld, base=%"UVuf"\n",
-              PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp),
+       "Screamer: entering: PerlIO * thinks ptr=%"UVuf", cnt=%zd, base=%"
+        UVuf"\n",
+              PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
               PTR2UV(PerlIO_has_base(fp) ? PerlIO_get_base(fp) : 0)));
     for (;;) {
       screamer:
@@ -7998,13 +8127,13 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
 
     cannot_be_shortbuffered:
        DEBUG_P(PerlIO_printf(Perl_debug_log,
-                             "Screamer: going to getc, ptr=%"UVuf", cnt=%ld\n",
-                             PTR2UV(ptr),(long)cnt));
+                            "Screamer: going to getc, ptr=%"UVuf", cnt=%zd\n",
+                             PTR2UV(ptr),cnt));
        PerlIO_set_ptrcnt(fp, (STDCHAR*)ptr, cnt); /* deregisterize cnt and ptr */
 
        DEBUG_Pv(PerlIO_printf(Perl_debug_log,
-           "Screamer: pre: FILE * thinks ptr=%"UVuf", cnt=%ld, base=%"UVuf"\n",
-           PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp),
+          "Screamer: pre: FILE * thinks ptr=%"UVuf", cnt=%zd, base=%"UVuf"\n",
+           PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
            PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0)));
 
        /* This used to call 'filbuf' in stdio form, but as that behaves like
@@ -8013,14 +8142,15 @@ Perl_sv_gets(pTHX_ SV *const sv, PerlIO *const fp, I32 append)
        i   = PerlIO_getc(fp);          /* get more characters */
 
        DEBUG_Pv(PerlIO_printf(Perl_debug_log,
-           "Screamer: post: FILE * thinks ptr=%"UVuf", cnt=%ld, base=%"UVuf"\n",
-           PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp),
+          "Screamer: post: FILE * thinks ptr=%"UVuf", cnt=%zd, base=%"UVuf"\n",
+           PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
            PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0)));
 
        cnt = PerlIO_get_cnt(fp);
        ptr = (STDCHAR*)PerlIO_get_ptr(fp);     /* reregisterize cnt and ptr */
        DEBUG_P(PerlIO_printf(Perl_debug_log,
-           "Screamer: after getc, ptr=%"UVuf", cnt=%ld\n",PTR2UV(ptr),(long)cnt));
+           "Screamer: after getc, ptr=%"UVuf", cnt=%zd\n",
+            PTR2UV(ptr),cnt));
 
        if (i == EOF)                   /* all done for ever? */
            goto thats_really_all_folks;
@@ -8044,11 +8174,12 @@ thats_really_all_folks:
     if (shortbuffered)
        cnt += shortbuffered;
        DEBUG_P(PerlIO_printf(Perl_debug_log,
-           "Screamer: quitting, ptr=%"UVuf", cnt=%ld\n",PTR2UV(ptr),(long)cnt));
+           "Screamer: quitting, ptr=%"UVuf", cnt=%zd\n",PTR2UV(ptr),cnt));
     PerlIO_set_ptrcnt(fp, (STDCHAR*)ptr, cnt); /* put these back or we're in trouble */
     DEBUG_P(PerlIO_printf(Perl_debug_log,
-       "Screamer: end: FILE * thinks ptr=%"UVuf", cnt=%ld, base=%"UVuf"\n",
-       PTR2UV(PerlIO_get_ptr(fp)), (long)PerlIO_get_cnt(fp),
+       "Screamer: end: FILE * thinks ptr=%"UVuf", cnt=%zd, base=%"UVuf
+       "\n",
+       PTR2UV(PerlIO_get_ptr(fp)), PerlIO_get_cnt(fp),
        PTR2UV(PerlIO_has_base (fp) ? PerlIO_get_base(fp) : 0)));
     *bp = '\0';
     SvCUR_set(sv, bp - (STDCHAR*)SvPVX_const(sv));     /* set length */
@@ -8169,10 +8300,7 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv)
     if (!sv)
        return;
     if (SvTHINKFIRST(sv)) {
-       if (SvIsCOW(sv) || isGV_with_GP(sv))
-           sv_force_normal_flags(sv, 0);
        if (SvREADONLY(sv)) {
-           if (IN_PERL_RUNTIME)
                Perl_croak_no_modify();
        }
        if (SvROK(sv)) {
@@ -8183,6 +8311,7 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv)
            sv_unref(sv);
            sv_setiv(sv, i);
        }
+       else sv_force_normal_flags(sv, 0);
     }
     flags = SvFLAGS(sv);
     if ((flags & (SVp_NOK|SVp_IOK)) == SVp_NOK) {
@@ -8237,11 +8366,11 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv)
     while (isALPHA(*d)) d++;
     while (isDIGIT(*d)) d++;
     if (d < SvEND(sv)) {
+       const int numtype = grok_number(SvPVX_const(sv), SvCUR(sv), NULL);
 #ifdef PERL_PRESERVE_IVUV
        /* Got to punt this as an integer if needs be, but we don't issue
           warnings. Probably ought to make the sv_iv_please() that does
           the conversion if possible, and silently.  */
-       const int numtype = grok_number(SvPVX_const(sv), SvCUR(sv), NULL);
        if (numtype && !(numtype & IS_NUMBER_INFINITY)) {
            /* Need to try really hard to see if it's an integer.
               9.22337203685478e+18 is an integer.
@@ -8272,6 +8401,8 @@ Perl_sv_inc_nomg(pTHX_ SV *const sv)
 #endif
        }
 #endif /* PERL_PRESERVE_IVUV */
+        if (!numtype && ckWARN(WARN_NUMERIC))
+            not_incrementable(sv);
        sv_setnv(sv,Atof(SvPVX_const(sv)) + 1.0);
        return;
     }
@@ -8351,10 +8482,7 @@ Perl_sv_dec_nomg(pTHX_ SV *const sv)
     if (!sv)
        return;
     if (SvTHINKFIRST(sv)) {
-       if (SvIsCOW(sv) || isGV_with_GP(sv))
-           sv_force_normal_flags(sv, 0);
        if (SvREADONLY(sv)) {
-           if (IN_PERL_RUNTIME)
                Perl_croak_no_modify();
        }
        if (SvROK(sv)) {
@@ -8365,6 +8493,7 @@ Perl_sv_dec_nomg(pTHX_ SV *const sv)
            sv_unref(sv);
            sv_setiv(sv, i);
        }
+       else sv_force_normal_flags(sv, 0);
     }
     /* Unlike sv_inc we don't have to worry about string-never-numbers
        and keeping them magic. But we mustn't warn on punting */
@@ -8552,13 +8681,13 @@ Perl_newSVpvn_flags(pTHX_ const char *const s, const STRLEN len, const U32 flags
     new_SV(sv);
     sv_setpvn(sv,s,len);
 
-    /* This code used to a sv_2mortal(), however we now unroll the call to sv_2mortal()
-     * and do what it does ourselves here.
-     * Since we have asserted that flags can only have the SVf_UTF8 and/or SVs_TEMP flags
-     * set above we can use it to enable the sv flags directly (bypassing SvTEMP_on), which
-     * in turn means we dont need to mask out the SVf_UTF8 flag below, which means that we
-     * eliminate quite a few steps than it looks - Yves (explaining patch by gfx)
-     */
+    /* This code used to do a sv_2mortal(), however we now unroll the call to
+     * sv_2mortal() and do what it does ourselves here.  Since we have asserted
+     * that flags can only have the SVf_UTF8 and/or SVs_TEMP flags set above we
+     * can use it to enable the sv flags directly (bypassing SvTEMP_on), which
+     * in turn means we dont need to mask out the SVf_UTF8 flag below, which
+     * means that we eliminate quite a few steps than it looks - Yves
+     * (explaining patch by gfx) */
 
     SvFLAGS(sv) |= flags;
 
@@ -9052,35 +9181,15 @@ Perl_sv_resetpvn(pTHX_ const char *s, STRLEN len, HV * const stash)
                    continue;
                gv = MUTABLE_GV(HeVAL(entry));
                sv = GvSV(gv);
-               if (sv) {
-                   if (SvTHINKFIRST(sv)) {
-                       if (!SvREADONLY(sv) && SvROK(sv))
-                           sv_unref(sv);
-                       /* XXX Is this continue a bug? Why should THINKFIRST
-                          exempt us from resetting arrays and hashes?  */
-                       continue;
-                   }
-                   SvOK_off(sv);
-                   if (SvTYPE(sv) >= SVt_PV) {
-                       SvCUR_set(sv, 0);
-                       if (SvPVX_const(sv) != NULL)
-                           *SvPVX(sv) = '\0';
-                       SvTAINT(sv);
-                   }
+               if (sv && !SvREADONLY(sv)) {
+                   SV_CHECK_THINKFIRST_COW_DROP(sv);
+                   if (!isGV(sv)) SvOK_off(sv);
                }
                if (GvAV(gv)) {
                    av_clear(GvAV(gv));
                }
                if (GvHV(gv) && !HvNAME_get(GvHV(gv))) {
-#if defined(VMS)
-                   Perl_die(aTHX_ "Can't reset %%ENV on this system");
-#else /* ! VMS */
                    hv_clear(GvHV(gv));
-#  if defined(USE_ENVIRON_ARRAY)
-                   if (gv == PL_envgv)
-                       my_clearenv();
-#  endif /* USE_ENVIRON_ARRAY */
-#endif /* VMS */
                }
            }
        }
@@ -9290,7 +9399,7 @@ Perl_sv_pvn_force_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
     PERL_ARGS_ASSERT_SV_PVN_FORCE_FLAGS;
 
     if (flags & SV_GMAGIC) SvGETMAGIC(sv);
-    if (SvTHINKFIRST(sv) && !SvROK(sv))
+    if (SvTHINKFIRST(sv) && (!SvROK(sv) || SvREADONLY(sv)))
         sv_force_normal_flags(sv, 0);
 
     if (SvPOK(sv)) {
@@ -9301,14 +9410,6 @@ Perl_sv_pvn_force_flags(pTHX_ SV *const sv, STRLEN *const lp, const I32 flags)
        char *s;
        STRLEN len;
  
-       if (SvREADONLY(sv) && !(flags & SV_MUTABLE_RETURN)) {
-           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_DESC(PL_op));
-           else
-               Perl_croak(aTHX_ "Can't coerce readonly %s to string", ref);
-       }
        if (SvTYPE(sv) > SVt_PVLV
            || isGV_with_GP(sv))
            /* diag_listed_as: Can't coerce %s to %s in %s */
@@ -9424,7 +9525,7 @@ Perl_sv_reftype(pTHX_ const SV *const sv, const int ob)
                                    ? "GLOB" : "SCALAR");
        case SVt_PVFM:          return "FORMAT";
        case SVt_PVIO:          return "IO";
-       case SVt_DUMMY:         return "DUMMY";
+       case SVt_INVLIST:       return "INVLIST";
        case SVt_REGEXP:        return "REGEXP";
        default:                return "UNKNOWN";
        }
@@ -9563,6 +9664,19 @@ Perl_newSVrv(pTHX_ SV *const rv, const char *const classname)
     return sv;
 }
 
+SV *
+Perl_newSVavdefelem(pTHX_ AV *av, SSize_t ix, bool extendible)
+{
+    SV * const lv = newSV_type(SVt_PVLV);
+    PERL_ARGS_ASSERT_NEWSVAVDEFELEM;
+    LvTYPE(lv) = 'y';
+    sv_magic(lv, NULL, PERL_MAGIC_defelem, NULL, 0);
+    LvTARG(lv) = SvREFCNT_inc_simple_NN(av);
+    LvSTARGOFF(lv) = ix;
+    LvTARGLEN(lv) = extendible ? 1 : (STRLEN)UV_MAX;
+    return lv;
+}
+
 /*
 =for apidoc sv_setref_pv
 
@@ -9700,22 +9814,25 @@ Perl_sv_bless(pTHX_ SV *const sv, HV *const stash)
 {
     dVAR;
     SV *tmpRef;
+    HV *oldstash = NULL;
 
     PERL_ARGS_ASSERT_SV_BLESS;
 
+    SvGETMAGIC(sv);
     if (!SvROK(sv))
         Perl_croak(aTHX_ "Can't bless non-reference value");
     tmpRef = SvRV(sv);
     if (SvFLAGS(tmpRef) & (SVs_OBJECT|SVf_READONLY)) {
-       if (SvREADONLY(tmpRef) && !SvIsCOW(tmpRef))
+       if (SvREADONLY(tmpRef))
            Perl_croak_no_modify();
        if (SvOBJECT(tmpRef)) {
-           SvREFCNT_dec(SvSTASH(tmpRef));
+           oldstash = SvSTASH(tmpRef);
        }
     }
     SvOBJECT_on(tmpRef);
     SvUPGRADE(tmpRef, SVt_PVMG);
     SvSTASH_set(tmpRef, MUTABLE_HV(SvREFCNT_inc_simple(stash)));
+    SvREFCNT_dec(oldstash);
 
     if(SvSMAGICAL(tmpRef))
         if(mg_find(tmpRef, PERL_MAGIC_ext) || mg_find(tmpRef, PERL_MAGIC_uvar))
@@ -10283,6 +10400,9 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
     char ebuf[IV_DIG * 4 + NV_DIG + 32];
     /* large enough for "%#.#f" --chip */
     /* what about long double NVs? --jhi */
+#ifdef USE_LOCALE_NUMERIC
+    SV* oldlocale = NULL;
+#endif
 
     PERL_ARGS_ASSERT_SV_VCATPVFN_FLAGS;
     PERL_UNUSED_ARG(maybe_tainted);
@@ -10451,7 +10571,8 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                %-<num>p        include an SV with precision <num>      
                %2p             include a HEK
                %3p             include a HEK with precision of 256
-               %<num>p         (where num != 2 or 3) reserved for future
+               %4p             char* preceded by utf8 flag and length
+               %<num>p         (where num is 1 or > 4) reserved for future
                                extensions
 
        Robin Barker 2005-07-14 (but modified since)
@@ -10463,6 +10584,15 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
            STRLEN n = 0;
            if (*q == '-')
                sv = *q++;
+           else if (strnEQ(q, UTF8f, sizeof(UTF8f)-1)) { /* UTF8f */
+               /* The argument has already gone through cBOOL, so the cast
+                  is safe. */
+               is_utf8 = (bool)va_arg(*args, int);
+               elen = va_arg(*args, UV);
+               eptr = va_arg(*args, char *);
+               q += sizeof(UTF8f)-1;
+               goto string;
+           }
            n = expect_number(&q);
            if (*q++ == 'p') {
                if (sv) {                       /* SVf */
@@ -10678,10 +10808,10 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
            q++;
            break;
 #endif
-#if defined(HAS_QUAD) || defined(HAS_LONG_DOUBLE)
+#if IVSIZE >= 8 || defined(HAS_LONG_DOUBLE)
        case 'L':                       /* Ld */
            /*FALLTHROUGH*/
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
        case 'q':                       /* qd */
 #endif
            intsize = 'q';
@@ -10690,7 +10820,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
 #endif
        case 'l':
            ++q;
-#if defined(HAS_QUAD) || defined(HAS_LONG_DOUBLE)
+#if IVSIZE >= 8 || defined(HAS_LONG_DOUBLE)
            if (*q == 'l') {    /* lld, llf */
                intsize = 'q';
                ++q;
@@ -10749,7 +10879,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                goto unknown;
            uv = (args) ? va_arg(*args, int) : SvIV(argsv);
            if ((uv > 255 ||
-                (!UNI_IS_INVARIANT(uv) && SvUTF8(sv)))
+                (!UVCHR_IS_INVARIANT(uv) && SvUTF8(sv)))
                && !IN_BYTES) {
                eptr = (char*)utf8buf;
                elen = uvchr_to_utf8((U8*)eptr, uv) - utf8buf;
@@ -10850,7 +10980,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                case 'j':       iv = va_arg(*args, intmax_t); break;
 #endif
                case 'q':
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
                                iv = va_arg(*args, Quad_t); break;
 #else
                                goto unknown;
@@ -10866,7 +10996,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                case 'V':
                default:        iv = tiv; break;
                case 'q':
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
                                iv = (Quad_t)tiv; break;
 #else
                                goto unknown;
@@ -10948,7 +11078,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
 #endif
                default:   uv = va_arg(*args, unsigned); break;
                case 'q':
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
                           uv = va_arg(*args, Uquad_t); break;
 #else
                           goto unknown;
@@ -10964,7 +11094,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                case 'V':
                default:        uv = tuv; break;
                case 'q':
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
                                uv = (Uquad_t)tuv; break;
 #else
                                goto unknown;
@@ -11233,6 +11363,21 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                /* No taint.  Otherwise we are in the strange situation
                 * where printf() taints but print($float) doesn't.
                 * --jhi */
+
+#ifdef USE_LOCALE_NUMERIC
+                if (! PL_numeric_standard && ! IN_SOME_LOCALE_FORM) {
+
+                    /* We use a mortal SV, so that any failures (such as if
+                     * warnings are made fatal) won't leak */
+                    char *oldlocale_string = setlocale(LC_NUMERIC, NULL);
+                    oldlocale = newSVpvn_flags(oldlocale_string,
+                                               strlen(oldlocale_string),
+                                               SVs_TEMP);
+                    PL_numeric_standard = TRUE;
+                    setlocale(LC_NUMERIC, "C");
+                }
+#endif
+
 #if defined(HAS_LONG_DOUBLE)
                elen = ((intsize == 'q')
                        ? my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, nv)
@@ -11243,6 +11388,15 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
            }
        float_converted:
            eptr = PL_efloatbuf;
+
+#ifdef USE_LOCALE_NUMERIC
+            if (PL_numeric_radix_sv && SvUTF8(PL_numeric_radix_sv)
+                && instr(eptr, SvPVX_const(PL_numeric_radix_sv)))
+            {
+                is_utf8 = TRUE;
+            }
+#endif
+
            break;
 
            /* SPECIAL */
@@ -11264,7 +11418,7 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
                case 'j':       *(va_arg(*args, intmax_t*)) = i; break;
 #endif
                case 'q':
-#ifdef HAS_QUAD
+#if IVSIZE >= 8
                                *(va_arg(*args, Quad_t*)) = i; break;
 #else
                                goto unknown;
@@ -11343,13 +11497,13 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
 
        have = esignlen + zeros + elen;
        if (have < zeros)
-           Perl_croak_memory_wrap();
+           croak_memory_wrap();
 
        need = (have > width ? have : width);
        gap = need - have;
 
        if (need >= (((STRLEN)~0) - SvCUR(sv) - dotstrlen - 1))
-           Perl_croak_memory_wrap();
+           croak_memory_wrap();
        SvGROW(sv, SvCUR(sv) + need + dotstrlen + 1);
        p = SvEND(sv);
        if (esignlen && fill == '0') {
@@ -11399,6 +11553,14 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
        }
     }
     SvTAINT(sv);
+
+#ifdef USE_LOCALE_NUMERIC   /* Done outside loop, so don't have to save/restore
+                               each iteration. */
+    if (oldlocale) {
+        setlocale(LC_NUMERIC, SvPVX(oldlocale));
+        PL_numeric_standard = FALSE;
+    }
+#endif
 }
 
 /* =========================================================================
@@ -12151,7 +12313,6 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
        SvANY(dstr)     = new_XNV();
        SvNV_set(dstr, SvNVX(sstr));
        break;
-       /* case SVt_DUMMY: */
     default:
        {
            /* These are all the types that need complex bodies allocating.  */
@@ -12176,6 +12337,7 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
            case SVt_PVMG:
            case SVt_PVNV:
            case SVt_PVIV:
+            case SVt_INVLIST:
            case SVt_PV:
                assert(sv_type_details->body_size);
                if (sv_type_details->arena) {
@@ -12213,6 +12375,8 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
            if (sv_type >= SVt_PVMG) {
                if ((sv_type == SVt_PVMG) && SvPAD_OUR(dstr)) {
                    SvOURSTASH_set(dstr, hv_dup_inc(SvOURSTASH(dstr), param));
+               } else if (sv_type == SVt_PVAV && AvPAD_NAMELIST(dstr)) {
+                   NOOP;
                } else if (SvMAGIC(dstr))
                    SvMAGIC_set(dstr, mg_dup(SvMAGIC(dstr), param));
                if (SvOBJECT(dstr) && SvSTASH(dstr))
@@ -12395,7 +12559,6 @@ S_sv_dup_common(pTHX_ const SV *const sstr, CLONE_PARAMS *const param)
                         daux->xhv_mro_meta = saux->xhv_mro_meta
                             ? mro_meta_dup(saux->xhv_mro_meta, param)
                             : 0;
-                       daux->xhv_super = NULL;
 
                        /* Record stashes for possible cloning in Perl_clone(). */
                        if (HvNAME(sstr))
@@ -12712,6 +12875,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            /* fall through */
        case SAVEt_FREESV:
        case SAVEt_MORTALIZESV:
+       case SAVEt_READONLY_OFF:
            sv = (const SV *)POPPTR(ss,ix);
            TOPPTR(nss,ix) = sv_dup_inc(sv, param);
            break;
@@ -12765,6 +12929,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            TOPINT(nss,ix) = i;
            break;
        case SAVEt_IV:                          /* IV reference */
+       case SAVEt_STRLEN:                      /* STRLEN/size_t ref */
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = any_dup(ptr, proto_perl);
            iv = POPIV(ss,ix);
@@ -12834,6 +12999,12 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
            ptr = POPPTR(ss,ix);
            TOPPTR(nss,ix) = cophh_copy((COPHH *)ptr);
            break;
+       case SAVEt_ADELETE:
+           av = (const AV *)POPPTR(ss,ix);
+           TOPPTR(nss,ix) = av_dup_inc(av, param);
+           i = POPINT(ss,ix);
+           TOPINT(nss,ix) = i;
+           break;
        case SAVEt_DELETE:
            hv = (const HV *)POPPTR(ss,ix);
            TOPPTR(nss,ix) = hv_dup_inc(hv, param);
@@ -13217,8 +13388,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_cryptseen       = proto_perl->Icryptseen;
 #endif
 
-    PL_hints           = proto_perl->Ihints;
-
 #ifdef USE_LOCALE_COLLATE
     PL_collation_ix    = proto_perl->Icollation_ix;
     PL_collation_standard      = proto_perl->Icollation_standard;
@@ -13270,6 +13439,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_last_swash_slen = 0;
 
     PL_srand_called    = proto_perl->Isrand_called;
+    Copy(&(proto_perl->Irandom_state), &PL_random_state, 1, PL_RANDOM_STATE_TYPE);
 
     if (flags & CLONEf_COPY_STACKS) {
        /* next allocation will be PL_tmps_stack[PL_tmps_ix+1] */
@@ -13362,6 +13532,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     hv_ksplit(PL_strtab, HvTOTALKEYS(proto_perl->Istrtab));
     ptr_table_store(PL_ptr_table, proto_perl->Istrtab, PL_strtab);
 
+    Zero(PL_sv_consts, SV_CONSTS_COUNT, SV*);
+
     /* This PV will be free'd special way so must set it same way op.c does */
     PL_compiling.cop_file    = savesharedpv(PL_compiling.cop_file);
     ptr_table_store(PL_ptr_table, proto_perl->Icompiling.cop_file, PL_compiling.cop_file);
@@ -13557,6 +13729,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     /* Unicode inversion lists */
     PL_ASCII           = sv_dup_inc(proto_perl->IASCII, param);
     PL_Latin1          = sv_dup_inc(proto_perl->ILatin1, param);
+    PL_AboveLatin1     = sv_dup_inc(proto_perl->IAboveLatin1, param);
 
     PL_NonL1NonFinalFold = sv_dup_inc(proto_perl->INonL1NonFinalFold, param);
     PL_HasMultiCharFold= sv_dup_inc(proto_perl->IHasMultiCharFold, param);
@@ -13586,9 +13759,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_utf8_foldable   = sv_dup_inc(proto_perl->Iutf8_foldable, param);
     PL_utf8_charname_begin = sv_dup_inc(proto_perl->Iutf8_charname_begin, param);
     PL_utf8_charname_continue = sv_dup_inc(proto_perl->Iutf8_charname_continue, param);
-    PL_ASCII           = sv_dup_inc(proto_perl->IASCII, param);
-    PL_AboveLatin1     = sv_dup_inc(proto_perl->IAboveLatin1, param);
-    PL_Latin1          = sv_dup_inc(proto_perl->ILatin1, param);
 
     if (proto_perl->Ipsig_pend) {
        Newxz(PL_psig_pend, SIG_SIZE, int);
@@ -14342,8 +14512,10 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv,
                        break;
                }
                else {
+                   SV * const  opsv = cSVOPx_sv(kid);
+                   const IV  opsviv = SvIV(opsv);
                    SV * const * const svp = av_fetch(MUTABLE_AV(sv),
-                       negate ? - SvIV(cSVOPx_sv(kid)) : SvIV(cSVOPx_sv(kid)),
+                       negate ? - opsviv : opsviv,
                        FALSE);
                    if (!svp || *svp != uninit_sv)
                        break;