This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Refactoring to Sv*_set() macros - patch #5
[perl5.git] / sv.c
diff --git a/sv.c b/sv.c
index aec9802..d87da9c 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -1,7 +1,7 @@
 /*    sv.c
  *
  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- *    2000, 2001, 2002, 2003, 2004, by Larry Wall and others
+ *    2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -49,7 +49,7 @@
 
 #ifdef PERL_COPY_ON_WRITE
 #define SV_COW_NEXT_SV(sv)     INT2PTR(SV *,SvUVX(sv))
-#define SV_COW_NEXT_SV_SET(current,next)       SvUVX(current) = PTR2UV(next)
+#define SV_COW_NEXT_SV_SET(current,next)       SvUV_set(current, PTR2UV(next))
 /* This is a pessimistic view. Scalar must be purely a read-write PV to copy-
    on-write.  */
 #endif
@@ -165,8 +165,19 @@ Public API:
  * "A time to plant, and a time to uproot what was planted..."
  */
 
+#ifdef DEBUG_LEAKING_SCALARS
+#  ifdef NETWARE
+#    define FREE_SV_DEBUG_FILE(sv) PerlMemfree((sv)->sv_debug_file)
+#  else
+#    define FREE_SV_DEBUG_FILE(sv) PerlMemShared_free((sv)->sv_debug_file)
+#  endif
+#else
+#  define FREE_SV_DEBUG_FILE(sv)
+#endif
+
 #define plant_SV(p) \
     STMT_START {                                       \
+       FREE_SV_DEBUG_FILE(p);                          \
        SvANY(p) = (void *)PL_sv_root;                  \
        SvFLAGS(p) = SVTYPEMASK;                        \
        PL_sv_root = (p);                               \
@@ -200,6 +211,17 @@ S_new_SV(pTHX)
     SvANY(sv) = 0;
     SvREFCNT(sv) = 1;
     SvFLAGS(sv) = 0;
+    sv->sv_debug_optype = PL_op ? PL_op->op_type : 0;
+    sv->sv_debug_line = (U16) ((PL_copline == NOLINE) ?
+        (PL_curcop ? CopLINE(PL_curcop) : 0) : PL_copline);
+    sv->sv_debug_inpad = 0;
+    sv->sv_debug_cloned = 0;
+#  ifdef NETWARE
+    sv->sv_debug_file = PL_curcop ? savepv(CopFILE(PL_curcop)): NULL;
+#  else
+    sv->sv_debug_file = PL_curcop ? savesharedpv(CopFILE(PL_curcop)): NULL;
+#  endif
+    
     return sv;
 }
 #  define new_SV(p) (p)=S_new_SV(aTHX)
@@ -394,10 +416,10 @@ do_clean_objs(pTHX_ SV *sv)
        if (SvWEAKREF(sv)) {
            sv_del_backref(sv);
            SvWEAKREF_off(sv);
-           SvRV(sv) = 0;
+           SvRV_set(sv, NULL);
        } else {
            SvROK_off(sv);
-           SvRV(sv) = 0;
+           SvRV_set(sv, NULL);
            SvREFCNT_dec(rv);
        }
     }
@@ -682,7 +704,7 @@ S_find_array_subscript(pTHX_ AV *av, SV* val)
 #define FUV_SUBSCRIPT_WITHIN   4       /* "within @foo"   */
 
 STATIC SV*
-S_varname(pTHX_ GV *gv, char *gvtype, PADOFFSET targ,
+S_varname(pTHX_ GV *gv, const char *gvtype, PADOFFSET targ,
        SV* keyname, I32 aindex, int subscript_type)
 {
     AV *av;
@@ -696,15 +718,13 @@ S_varname(pTHX_ GV *gv, char *gvtype, PADOFFSET targ,
         * XXX get rid of all this if gv_fullnameX() ever supports this
         * directly */
 
-       char *p;
+       const char *p;
        HV *hv = GvSTASH(gv);
        sv_setpv(name, gvtype);
        if (!hv)
            p = "???";
-       else if (!HvNAME(hv))
+       else if (!(p=HvNAME(hv)))
            p = "__ANON__";
-       else
-           p = HvNAME(hv);
        if (strNE(p, "main")) {
            sv_catpv(name,p);
            sv_catpvn(name,"::", 2);
@@ -1878,59 +1898,59 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
        Perl_croak(aTHX_ "Can't upgrade to undef");
     case SVt_IV:
        SvANY(sv) = new_XIV();
-       SvIVX(sv)       = iv;
+       SvIV_set(sv, iv);
        break;
     case SVt_NV:
        SvANY(sv) = new_XNV();
-       SvNVX(sv)       = nv;
+       SvNV_set(sv, nv);
        break;
     case SVt_RV:
        SvANY(sv) = new_XRV();
-       SvRV(sv) = (SV*)pv;
+       SvRV_set(sv, (SV*)pv);
        break;
     case SVt_PV:
        SvANY(sv) = new_XPV();
-       SvPVX(sv)       = pv;
-       SvCUR(sv)       = cur;
-       SvLEN(sv)       = len;
+       SvPV_set(sv, pv);
+       SvCUR_set(sv, cur);
+       SvLEN_set(sv, len);
        break;
     case SVt_PVIV:
        SvANY(sv) = new_XPVIV();
-       SvPVX(sv)       = pv;
-       SvCUR(sv)       = cur;
-       SvLEN(sv)       = len;
-       SvIVX(sv)       = iv;
+       SvPV_set(sv, pv);
+       SvCUR_set(sv, cur);
+       SvLEN_set(sv, len);
+       SvIV_set(sv, iv);
        if (SvNIOK(sv))
            (void)SvIOK_on(sv);
        SvNOK_off(sv);
        break;
     case SVt_PVNV:
        SvANY(sv) = new_XPVNV();
-       SvPVX(sv)       = pv;
-       SvCUR(sv)       = cur;
-       SvLEN(sv)       = len;
-       SvIVX(sv)       = iv;
-       SvNVX(sv)       = nv;
+       SvPV_set(sv, pv);
+       SvCUR_set(sv, cur);
+       SvLEN_set(sv, len);
+       SvIV_set(sv, iv);
+       SvNV_set(sv, nv);
        break;
     case SVt_PVMG:
        SvANY(sv) = new_XPVMG();
-       SvPVX(sv)       = pv;
-       SvCUR(sv)       = cur;
-       SvLEN(sv)       = len;
-       SvIVX(sv)       = iv;
-       SvNVX(sv)       = nv;
-       SvMAGIC(sv)     = magic;
-       SvSTASH(sv)     = stash;
+       SvPV_set(sv, pv);
+       SvCUR_set(sv, cur);
+       SvLEN_set(sv, len);
+       SvIV_set(sv, iv);
+       SvNV_set(sv, nv);
+       SvMAGIC_set(sv, magic);
+       SvSTASH_set(sv, stash);
        break;
     case SVt_PVLV:
        SvANY(sv) = new_XPVLV();
-       SvPVX(sv)       = pv;
-       SvCUR(sv)       = cur;
-       SvLEN(sv)       = len;
-       SvIVX(sv)       = iv;
-       SvNVX(sv)       = nv;
-       SvMAGIC(sv)     = magic;
-       SvSTASH(sv)     = stash;
+       SvPV_set(sv, pv);
+       SvCUR_set(sv, cur);
+       SvLEN_set(sv, len);
+       SvIV_set(sv, iv);
+       SvNV_set(sv, nv);
+       SvMAGIC_set(sv, magic);
+       SvSTASH_set(sv, stash);
        LvTARGOFF(sv)   = 0;
        LvTARGLEN(sv)   = 0;
        LvTARG(sv)      = 0;
@@ -1945,13 +1965,13 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
        SvANY(sv) = new_XPVAV();
        if (pv)
            Safefree(pv);
-       SvPVX(sv)       = 0;
+       SvPV_set(sv, (char*)0);
        AvMAX(sv)       = -1;
        AvFILLp(sv)     = -1;
-       SvIVX(sv)       = 0;
-       SvNVX(sv)       = 0.0;
-       SvMAGIC(sv)     = magic;
-       SvSTASH(sv)     = stash;
+       SvIV_set(sv, 0);
+       SvNV_set(sv, 0.0);
+       SvMAGIC_set(sv, magic);
+       SvSTASH_set(sv, stash);
        AvALLOC(sv)     = 0;
        AvARYLEN(sv)    = 0;
        AvFLAGS(sv)     = AVf_REAL;
@@ -1960,13 +1980,13 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
        SvANY(sv) = new_XPVHV();
        if (pv)
            Safefree(pv);
-       SvPVX(sv)       = 0;
+       SvPV_set(sv, (char*)0);
        HvFILL(sv)      = 0;
        HvMAX(sv)       = 0;
        HvTOTALKEYS(sv) = 0;
        HvPLACEHOLDERS(sv) = 0;
-       SvMAGIC(sv)     = magic;
-       SvSTASH(sv)     = stash;
+       SvMAGIC_set(sv, magic);
+       SvSTASH_set(sv, stash);
        HvRITER(sv)     = 0;
        HvEITER(sv)     = 0;
        HvPMROOT(sv)    = 0;
@@ -1975,23 +1995,23 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
     case SVt_PVCV:
        SvANY(sv) = new_XPVCV();
        Zero(SvANY(sv), 1, XPVCV);
-       SvPVX(sv)       = pv;
-       SvCUR(sv)       = cur;
-       SvLEN(sv)       = len;
-       SvIVX(sv)       = iv;
-       SvNVX(sv)       = nv;
-       SvMAGIC(sv)     = magic;
-       SvSTASH(sv)     = stash;
+       SvPV_set(sv, pv);
+       SvCUR_set(sv, cur);
+       SvLEN_set(sv, len);
+       SvIV_set(sv, iv);
+       SvNV_set(sv, nv);
+       SvMAGIC_set(sv, magic);
+       SvSTASH_set(sv, stash);
        break;
     case SVt_PVGV:
        SvANY(sv) = new_XPVGV();
-       SvPVX(sv)       = pv;
-       SvCUR(sv)       = cur;
-       SvLEN(sv)       = len;
-       SvIVX(sv)       = iv;
-       SvNVX(sv)       = nv;
-       SvMAGIC(sv)     = magic;
-       SvSTASH(sv)     = stash;
+       SvPV_set(sv, pv);
+       SvCUR_set(sv, cur);
+       SvLEN_set(sv, len);
+       SvIV_set(sv, iv);
+       SvNV_set(sv, nv);
+       SvMAGIC_set(sv, magic);
+       SvSTASH_set(sv, stash);
        GvGP(sv)        = 0;
        GvNAME(sv)      = 0;
        GvNAMELEN(sv)   = 0;
@@ -2000,13 +2020,13 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
        break;
     case SVt_PVBM:
        SvANY(sv) = new_XPVBM();
-       SvPVX(sv)       = pv;
-       SvCUR(sv)       = cur;
-       SvLEN(sv)       = len;
-       SvIVX(sv)       = iv;
-       SvNVX(sv)       = nv;
-       SvMAGIC(sv)     = magic;
-       SvSTASH(sv)     = stash;
+       SvPV_set(sv, pv);
+       SvCUR_set(sv, cur);
+       SvLEN_set(sv, len);
+       SvIV_set(sv, iv);
+       SvNV_set(sv, nv);
+       SvMAGIC_set(sv, magic);
+       SvSTASH_set(sv, stash);
        BmRARE(sv)      = 0;
        BmUSEFUL(sv)    = 0;
        BmPREVIOUS(sv)  = 0;
@@ -2014,24 +2034,24 @@ Perl_sv_upgrade(pTHX_ register SV *sv, U32 mt)
     case SVt_PVFM:
        SvANY(sv) = new_XPVFM();
        Zero(SvANY(sv), 1, XPVFM);
-       SvPVX(sv)       = pv;
-       SvCUR(sv)       = cur;
-       SvLEN(sv)       = len;
-       SvIVX(sv)       = iv;
-       SvNVX(sv)       = nv;
-       SvMAGIC(sv)     = magic;
-       SvSTASH(sv)     = stash;
+       SvPV_set(sv, pv);
+       SvCUR_set(sv, cur);
+       SvLEN_set(sv, len);
+       SvIV_set(sv, iv);
+       SvNV_set(sv, nv);
+       SvMAGIC_set(sv, magic);
+       SvSTASH_set(sv, stash);
        break;
     case SVt_PVIO:
        SvANY(sv) = new_XPVIO();
        Zero(SvANY(sv), 1, XPVIO);
-       SvPVX(sv)       = pv;
-       SvCUR(sv)       = cur;
-       SvLEN(sv)       = len;
-       SvIVX(sv)       = iv;
-       SvNVX(sv)       = nv;
-       SvMAGIC(sv)     = magic;
-       SvSTASH(sv)     = stash;
+       SvPV_set(sv, pv);
+       SvCUR_set(sv, cur);
+       SvLEN_set(sv, len);
+       SvIV_set(sv, iv);
+       SvNV_set(sv, nv);
+       SvMAGIC_set(sv, magic);
+       SvSTASH_set(sv, stash);
        IoPAGE_LEN(sv)  = 60;
        break;
     }
@@ -2053,8 +2073,8 @@ Perl_sv_backoff(pTHX_ register SV *sv)
     assert(SvOOK(sv));
     if (SvIVX(sv)) {
        char *s = SvPVX(sv);
-       SvLEN(sv) += SvIVX(sv);
-       SvPVX(sv) -= SvIVX(sv);
+       SvLEN_set(sv, SvLEN(sv) + SvIVX(sv));
+       SvPV_set(sv, SvPVX(sv) - SvIVX(sv));
        SvIV_set(sv, 0);
        Move(s, SvPVX(sv), SvCUR(sv)+1, char);
     }
@@ -2114,7 +2134,7 @@ Perl_sv_grow(pTHX_ register SV *sv, register STRLEN newlen)
 #endif
            Renew(s,newlen,char);
        }
-        else {
+       else {
            New(703, s, newlen, char);
            if (SvPVX(sv) && SvCUR(sv)) {
                Move(SvPVX(sv), s, (newlen < SvCUR(sv)) ? newlen : SvCUR(sv), char);
@@ -2161,7 +2181,7 @@ Perl_sv_setiv(pTHX_ register SV *sv, IV i)
                   OP_DESC(PL_op));
     }
     (void)SvIOK_only(sv);                      /* validate number */
-    SvIVX(sv) = i;
+    SvIV_set(sv, i);
     SvTAINT(sv);
 }
 
@@ -2206,7 +2226,7 @@ Perl_sv_setuv(pTHX_ register SV *sv, UV u)
     }
     sv_setiv(sv, 0);
     SvIsUV_on(sv);
-    SvUVX(sv) = u;
+    SvUV_set(sv, u);
 }
 
 /*
@@ -2271,7 +2291,7 @@ Perl_sv_setnv(pTHX_ register SV *sv, NV num)
        Perl_croak(aTHX_ "Can't coerce %s to number in %s", sv_reftype(sv,0),
                   OP_NAME(PL_op));
     }
-    SvNVX(sv) = num;
+    SvNV_set(sv, num);
     (void)SvNOK_only(sv);                      /* validate number */
     SvTAINT(sv);
 }
@@ -2482,14 +2502,14 @@ S_sv_2iuv_non_preserve(pTHX_ register SV *sv, I32 numtype)
     if (SvNVX(sv) < (NV)IV_MIN) {
        (void)SvIOKp_on(sv);
        (void)SvNOK_on(sv);
-       SvIVX(sv) = IV_MIN;
+       SvIV_set(sv, IV_MIN);
        return IS_NUMBER_UNDERFLOW_IV;
     }
     if (SvNVX(sv) > (NV)UV_MAX) {
        (void)SvIOKp_on(sv);
        (void)SvNOK_on(sv);
        SvIsUV_on(sv);
-       SvUVX(sv) = UV_MAX;
+       SvUV_set(sv, UV_MAX);
        return IS_NUMBER_OVERFLOW_UV;
     }
     (void)SvIOKp_on(sv);
@@ -2497,7 +2517,7 @@ S_sv_2iuv_non_preserve(pTHX_ register SV *sv, I32 numtype)
     /* Can't use strtol etc to convert this string.  (See truth table in
        sv_2iv  */
     if (SvNVX(sv) <= (UV)IV_MAX) {
-        SvIVX(sv) = I_V(SvNVX(sv));
+        SvIV_set(sv, I_V(SvNVX(sv)));
         if ((NV)(SvIVX(sv)) == SvNVX(sv)) {
             SvIOK_on(sv); /* Integer is precise. NOK, IOK */
         } else {
@@ -2506,7 +2526,7 @@ S_sv_2iuv_non_preserve(pTHX_ register SV *sv, I32 numtype)
         return SvNVX(sv) < 0 ? IS_NUMBER_UNDERFLOW_UV : IS_NUMBER_IV_AND_UV;
     }
     SvIsUV_on(sv);
-    SvUVX(sv) = U_V(SvNVX(sv));
+    SvUV_set(sv, U_V(SvNVX(sv)));
     if ((NV)(SvUVX(sv)) == SvNVX(sv)) {
         if (SvUVX(sv) == UV_MAX) {
             /* As we know that NVs don't preserve UVs, UV_MAX cannot
@@ -2605,7 +2625,7 @@ Perl_sv_2iv_flags(pTHX_ register SV *sv, I32 flags)
           answer is the UV IV_MAX +1. Hence < ensures that dodgy boundary
           cases go to UV */
        if (SvNVX(sv) < (NV)IV_MAX + 0.5) {
-           SvIVX(sv) = I_V(SvNVX(sv));
+           SvIV_set(sv, I_V(SvNVX(sv)));
            if (SvNVX(sv) == (NV) SvIVX(sv)
 #ifndef NV_PRESERVES_UV
                && (((UV)1 << NV_PRESERVES_UV_BITS) >
@@ -2643,7 +2663,7 @@ Perl_sv_2iv_flags(pTHX_ register SV *sv, I32 flags)
               0x8000000000000000 which will be exact. NWC */
        }
        else {
-           SvUVX(sv) = U_V(SvNVX(sv));
+           SvUV_set(sv, U_V(SvNVX(sv)));
            if (
                (SvNVX(sv) == (NV) SvUVX(sv))
 #ifndef  NV_PRESERVES_UV
@@ -2706,15 +2726,15 @@ Perl_sv_2iv_flags(pTHX_ register SV *sv, I32 flags)
            if (!(numtype & IS_NUMBER_NEG)) {
                /* positive */;
                if (value <= (UV)IV_MAX) {
-                   SvIVX(sv) = (IV)value;
+                   SvIV_set(sv, (IV)value);
                } else {
-                   SvUVX(sv) = value;
+                   SvUV_set(sv, value);
                    SvIsUV_on(sv);
                }
            } else {
                /* 2s complement assumption  */
                if (value <= (UV)IV_MIN) {
-                   SvIVX(sv) = -(IV)value;
+                   SvIV_set(sv, -(IV)value);
                } else {
                    /* Too negative for an IV.  This is a double upgrade, but
                       I'm assuming it will be rare.  */
@@ -2723,8 +2743,8 @@ Perl_sv_2iv_flags(pTHX_ register SV *sv, I32 flags)
                    SvNOK_on(sv);
                    SvIOK_off(sv);
                    SvIOKp_on(sv);
-                   SvNVX(sv) = -(NV)value;
-                   SvIVX(sv) = IV_MIN;
+                   SvNV_set(sv, -(NV)value);
+                   SvIV_set(sv, IV_MIN);
                }
            }
        }
@@ -2735,7 +2755,7 @@ Perl_sv_2iv_flags(pTHX_ register SV *sv, I32 flags)
        if ((numtype & (IS_NUMBER_IN_UV | IS_NUMBER_NOT_INT))
            != IS_NUMBER_IN_UV) {
            /* It wasn't an (integer that doesn't overflow the UV). */
-           SvNVX(sv) = Atof(SvPVX(sv));
+           SvNV_set(sv, Atof(SvPVX(sv)));
 
            if (! numtype && ckWARN(WARN_NUMERIC))
                not_a_number(sv);
@@ -2753,7 +2773,7 @@ Perl_sv_2iv_flags(pTHX_ register SV *sv, I32 flags)
            (void)SvIOKp_on(sv);
            (void)SvNOK_on(sv);
            if (SvNVX(sv) < (NV)IV_MAX + 0.5) {
-               SvIVX(sv) = I_V(SvNVX(sv));
+               SvIV_set(sv, I_V(SvNVX(sv)));
                if ((NV)(SvIVX(sv)) == SvNVX(sv)) {
                    SvIOK_on(sv);
                } else {
@@ -2764,10 +2784,10 @@ Perl_sv_2iv_flags(pTHX_ register SV *sv, I32 flags)
                if (SvNVX(sv) > (NV)UV_MAX) {
                    SvIsUV_on(sv);
                    /* Integer is inaccurate. NOK, IOKp, is UV */
-                   SvUVX(sv) = UV_MAX;
+                   SvUV_set(sv, UV_MAX);
                    SvIsUV_on(sv);
                } else {
-                   SvUVX(sv) = U_V(SvNVX(sv));
+                   SvUV_set(sv, U_V(SvNVX(sv)));
                    /* 0xFFFFFFFFFFFFFFFF not an issue in here */
                    if ((NV)(SvUVX(sv)) == SvNVX(sv)) {
                        SvIOK_on(sv);
@@ -2793,7 +2813,7 @@ Perl_sv_2iv_flags(pTHX_ register SV *sv, I32 flags)
                     /* Small enough to preserve all bits. */
                     (void)SvIOKp_on(sv);
                     SvNOK_on(sv);
-                    SvIVX(sv) = I_V(SvNVX(sv));
+                    SvIV_set(sv, I_V(SvNVX(sv)));
                     if ((NV)(SvIVX(sv)) == SvNVX(sv))
                         SvIOK_on(sv);
                     /* Assumption: first non-preserved integer is < IV_MAX,
@@ -2910,7 +2930,7 @@ Perl_sv_2uv_flags(pTHX_ register SV *sv, I32 flags)
 
        (void)SvIOKp_on(sv);    /* Must do this first, to clear any SvOOK */
        if (SvNVX(sv) < (NV)IV_MAX + 0.5) {
-           SvIVX(sv) = I_V(SvNVX(sv));
+           SvIV_set(sv, I_V(SvNVX(sv)));
            if (SvNVX(sv) == (NV) SvIVX(sv)
 #ifndef NV_PRESERVES_UV
                && (((UV)1 << NV_PRESERVES_UV_BITS) >
@@ -2948,7 +2968,7 @@ Perl_sv_2uv_flags(pTHX_ register SV *sv, I32 flags)
               0x8000000000000000 which will be exact. NWC */
        }
        else {
-           SvUVX(sv) = U_V(SvNVX(sv));
+           SvUV_set(sv, U_V(SvNVX(sv)));
            if (
                (SvNVX(sv) == (NV) SvUVX(sv))
 #ifndef  NV_PRESERVES_UV
@@ -3007,16 +3027,16 @@ Perl_sv_2uv_flags(pTHX_ register SV *sv, I32 flags)
            if (!(numtype & IS_NUMBER_NEG)) {
                /* positive */;
                if (value <= (UV)IV_MAX) {
-                   SvIVX(sv) = (IV)value;
+                   SvIV_set(sv, (IV)value);
                } else {
                    /* it didn't overflow, and it was positive. */
-                   SvUVX(sv) = value;
+                   SvUV_set(sv, value);
                    SvIsUV_on(sv);
                }
            } else {
                /* 2s complement assumption  */
                if (value <= (UV)IV_MIN) {
-                   SvIVX(sv) = -(IV)value;
+                   SvIV_set(sv, -(IV)value);
                } else {
                    /* Too negative for an IV.  This is a double upgrade, but
                       I'm assuming it will be rare.  */
@@ -3025,8 +3045,8 @@ Perl_sv_2uv_flags(pTHX_ register SV *sv, I32 flags)
                    SvNOK_on(sv);
                    SvIOK_off(sv);
                    SvIOKp_on(sv);
-                   SvNVX(sv) = -(NV)value;
-                   SvIVX(sv) = IV_MIN;
+                   SvNV_set(sv, -(NV)value);
+                   SvIV_set(sv, IV_MIN);
                }
            }
        }
@@ -3034,7 +3054,7 @@ Perl_sv_2uv_flags(pTHX_ register SV *sv, I32 flags)
        if ((numtype & (IS_NUMBER_IN_UV | IS_NUMBER_NOT_INT))
            != IS_NUMBER_IN_UV) {
            /* It wasn't an integer, or it overflowed the UV. */
-           SvNVX(sv) = Atof(SvPVX(sv));
+           SvNV_set(sv, Atof(SvPVX(sv)));
 
             if (! numtype && ckWARN(WARN_NUMERIC))
                    not_a_number(sv);
@@ -3051,7 +3071,7 @@ Perl_sv_2uv_flags(pTHX_ register SV *sv, I32 flags)
             (void)SvIOKp_on(sv);
             (void)SvNOK_on(sv);
             if (SvNVX(sv) < (NV)IV_MAX + 0.5) {
-                SvIVX(sv) = I_V(SvNVX(sv));
+                SvIV_set(sv, I_V(SvNVX(sv)));
                 if ((NV)(SvIVX(sv)) == SvNVX(sv)) {
                     SvIOK_on(sv);
                 } else {
@@ -3062,10 +3082,10 @@ Perl_sv_2uv_flags(pTHX_ register SV *sv, I32 flags)
                 if (SvNVX(sv) > (NV)UV_MAX) {
                     SvIsUV_on(sv);
                     /* Integer is inaccurate. NOK, IOKp, is UV */
-                    SvUVX(sv) = UV_MAX;
+                    SvUV_set(sv, UV_MAX);
                     SvIsUV_on(sv);
                 } else {
-                    SvUVX(sv) = U_V(SvNVX(sv));
+                    SvUV_set(sv, U_V(SvNVX(sv)));
                     /* 0xFFFFFFFFFFFFFFFF not an issue in here, NVs
                        NV preservse UV so can do correct comparison.  */
                     if ((NV)(SvUVX(sv)) == SvNVX(sv)) {
@@ -3091,7 +3111,7 @@ Perl_sv_2uv_flags(pTHX_ register SV *sv, I32 flags)
                     /* Small enough to preserve all bits. */
                     (void)SvIOKp_on(sv);
                     SvNOK_on(sv);
-                    SvIVX(sv) = I_V(SvNVX(sv));
+                    SvIV_set(sv, I_V(SvNVX(sv)));
                     if ((NV)(SvIVX(sv)) == SvNVX(sv))
                         SvIOK_on(sv);
                     /* Assumption: first non-preserved integer is < IV_MAX,
@@ -3206,7 +3226,7 @@ Perl_sv_2nv(pTHX_ register SV *sv)
         return SvNVX(sv);
     }
     if (SvIOKp(sv)) {
-       SvNVX(sv) = SvIsUV(sv) ? (NV)SvUVX(sv) : (NV)SvIVX(sv);
+       SvNV_set(sv, SvIsUV(sv) ? (NV)SvUVX(sv) : (NV)SvIVX(sv));
 #ifdef NV_PRESERVES_UV
        SvNOK_on(sv);
 #else
@@ -3228,12 +3248,12 @@ Perl_sv_2nv(pTHX_ register SV *sv)
        if ((numtype & (IS_NUMBER_IN_UV | IS_NUMBER_NOT_INT))
            == IS_NUMBER_IN_UV) {
            /* It's definitely an integer */
-           SvNVX(sv) = (numtype & IS_NUMBER_NEG) ? -(NV)value : (NV)value;
+           SvNV_set(sv, (numtype & IS_NUMBER_NEG) ? -(NV)value : (NV)value);
        } else
-           SvNVX(sv) = Atof(SvPVX(sv));
+           SvNV_set(sv, Atof(SvPVX(sv)));
        SvNOK_on(sv);
 #else
-       SvNVX(sv) = Atof(SvPVX(sv));
+       SvNV_set(sv, Atof(SvPVX(sv)));
        /* Only set the public NV OK flag if this NV preserves the value in
           the PV at least as well as an IV/UV would.
           Not sure how to do this 100% reliably. */
@@ -3257,11 +3277,11 @@ Perl_sv_2nv(pTHX_ register SV *sv)
                 SvIOKp_on(sv);
 
                 if (numtype & IS_NUMBER_NEG) {
-                    SvIVX(sv) = -(IV)value;
+                    SvIV_set(sv, -(IV)value);
                 } else if (value <= (UV)IV_MAX) {
-                   SvIVX(sv) = (IV)value;
+                   SvIV_set(sv, (IV)value);
                } else {
-                   SvUVX(sv) = value;
+                   SvUV_set(sv, value);
                    SvIsUV_on(sv);
                }
 
@@ -3460,7 +3480,7 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
 
     if (!sv) {
        *lp = 0;
-       return "";
+       return (char *)"";
     }
     if (SvGMAGICAL(sv)) {
        if (flags & SV_GMAGIC)
@@ -3488,12 +3508,13 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
                    report_uninit(sv);
            }
             *lp = 0;
-            return "";
+            return (char *)"";
         }
     }
     if (SvTHINKFIRST(sv)) {
        if (SvROK(sv)) {
            SV* tmpstr;
+            register const char *typestr;
             if (SvAMAGIC(sv) && (tmpstr=AMG_CALLun(sv,string)) &&
                 (!SvROK(tmpstr) || (SvRV(tmpstr) != SvRV(sv)))) {
                 char *pv = SvPV(tmpstr, *lp);
@@ -3506,7 +3527,7 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
            origsv = sv;
            sv = (SV*)SvRV(sv);
            if (!sv)
-               s = "NULLREF";
+               typestr = "NULLREF";
            else {
                MAGIC *mg;
                
@@ -3516,10 +3537,10 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
                           (SVs_OBJECT|SVf_OK|SVs_GMG|SVs_SMG|SVs_RMG))
                          == (SVs_OBJECT|SVs_SMG))
                         && (mg = mg_find(sv, PERL_MAGIC_qr))) {
-                       regexp *re = (regexp *)mg->mg_obj;
+                        const regexp *re = (regexp *)mg->mg_obj;
 
                        if (!mg->mg_ptr) {
-                           char *fptr = "msix";
+                            const char *fptr = "msix";
                            char reflags[6];
                            char ch;
                            int left = 0;
@@ -3559,10 +3580,10 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
                              */
                             if (PMf_EXTENDED & re->reganch)
                             {
-                                char *endptr = re->precomp + re->prelen;
+                                const char *endptr = re->precomp + re->prelen;
                                 while (endptr >= re->precomp)
                                 {
-                                    char c = *(endptr--);
+                                    const char c = *(endptr--);
                                     if (c == '\n')
                                         break; /* don't need another */
                                     if (c == '#') {
@@ -3602,49 +3623,45 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
                case SVt_PV:
                case SVt_PVIV:
                case SVt_PVNV:
-               case SVt_PVBM:  if (SvROK(sv))
-                                   s = "REF";
-                               else
-                                   s = "SCALAR";               break;
-               case SVt_PVLV:  s = SvROK(sv) ? "REF"
+               case SVt_PVBM:  typestr = SvROK(sv) ? "REF" : "SCALAR"; break;
+               case SVt_PVLV:  typestr = SvROK(sv) ? "REF"
                                /* tied lvalues should appear to be
                                 * scalars for backwards compatitbility */
                                : (LvTYPE(sv) == 't' || LvTYPE(sv) == 'T')
                                    ? "SCALAR" : "LVALUE";      break;
-               case SVt_PVAV:  s = "ARRAY";                    break;
-               case SVt_PVHV:  s = "HASH";                     break;
-               case SVt_PVCV:  s = "CODE";                     break;
-               case SVt_PVGV:  s = "GLOB";                     break;
-               case SVt_PVFM:  s = "FORMAT";                   break;
-               case SVt_PVIO:  s = "IO";                       break;
-               default:        s = "UNKNOWN";                  break;
+               case SVt_PVAV:  typestr = "ARRAY";      break;
+               case SVt_PVHV:  typestr = "HASH";       break;
+               case SVt_PVCV:  typestr = "CODE";       break;
+               case SVt_PVGV:  typestr = "GLOB";       break;
+               case SVt_PVFM:  typestr = "FORMAT";     break;
+               case SVt_PVIO:  typestr = "IO";         break;
+               default:        typestr = "UNKNOWN";    break;
                }
                tsv = NEWSV(0,0);
-               if (SvOBJECT(sv))
-                   if (HvNAME(SvSTASH(sv)))
-                       Perl_sv_setpvf(aTHX_ tsv, "%s=%s", HvNAME(SvSTASH(sv)), s);
-                   else
-                       Perl_sv_setpvf(aTHX_ tsv, "__ANON__=%s", s);
+               if (SvOBJECT(sv)) {
+                   const char *name = HvNAME(SvSTASH(sv));
+                   Perl_sv_setpvf(aTHX_ tsv, "%s=%s(0x%"UVxf")",
+                                  name ? name : "__ANON__" , typestr, PTR2UV(sv));
+               }
                else
-                   sv_setpv(tsv, s);
-               Perl_sv_catpvf(aTHX_ tsv, "(0x%"UVxf")", PTR2UV(sv));
+                   Perl_sv_setpvf(aTHX_ tsv, "%s(0x%"UVxf")", typestr, PTR2UV(sv));
                goto tokensaveref;
            }
-           *lp = strlen(s);
-           return s;
+           *lp = strlen(typestr);
+           return (char *)typestr;
        }
        if (SvREADONLY(sv) && !SvOK(sv)) {
            if (ckWARN(WARN_UNINITIALIZED))
                report_uninit(sv);
            *lp = 0;
-           return "";
+           return (char *)"";
        }
     }
     if (SvIOK(sv) || ((SvIOKp(sv) && !SvNOKp(sv)))) {
        /* I'm assuming that if both IV and NV are equally valid then
           converting the IV is going to be more efficient */
-       U32 isIOK = SvIOK(sv);
-       U32 isUIOK = SvIsUV(sv);
+       const U32 isIOK = SvIOK(sv);
+       const U32 isUIOK = SvIsUV(sv);
        char buf[TYPE_CHARS(UV)];
        char *ebuf, *ptr;
 
@@ -3700,7 +3717,7 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
        if (SvTYPE(sv) < SVt_PV)
            /* Typically the caller expects that sv_any is not NULL now.  */
            sv_upgrade(sv, SVt_PV);
-       return "";
+       return (char *)"";
     }
     *lp = s - SvPVX(sv);
     SvCUR_set(sv, *lp);
@@ -3722,7 +3739,7 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
     }
     else {
        STRLEN len;
-       char *t;
+        const char *t;
 
        if (tsv) {
            sv_2mortal(tsv);
@@ -3978,11 +3995,11 @@ Perl_sv_utf8_upgrade_flags(pTHX_ register SV *sv, I32 flags)
              (void)SvOOK_off(sv);
              s = (U8*)SvPVX(sv);
              len = SvCUR(sv) + 1; /* Plus the \0 */
-             SvPVX(sv) = (char*)bytes_to_utf8((U8*)s, &len);
-             SvCUR(sv) = len - 1;
+             SvPV_set(sv, (char*)bytes_to_utf8((U8*)s, &len));
+             SvCUR_set(sv, len - 1);
              if (SvLEN(sv) != 0)
                   Safefree(s); /* No longer using what was there before. */
-             SvLEN(sv) = len; /* No longer know the real size. */
+             SvLEN_set(sv, len); /* No longer know the real size. */
         }
         /* Mark as UTF-8 even if no hibit - saves scanning loop */
         SvUTF8_on(sv);
@@ -4027,7 +4044,7 @@ Perl_sv_utf8_downgrade(pTHX_ register SV* sv, bool fail_ok)
                        Perl_croak(aTHX_ "Wide character");
                }
            }
-           SvCUR(sv) = len;
+           SvCUR_set(sv, len);
        }
     }
     SvUTF8_off(sv);
@@ -4192,7 +4209,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
                break;
            }
            (void)SvIOK_only(dstr);
-           SvIVX(dstr) = SvIVX(sstr);
+           SvIV_set(dstr,  SvIVX(sstr));
            if (SvIsUV(sstr))
                SvIsUV_on(dstr);
            if (SvTAINTED(sstr))
@@ -4214,7 +4231,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
                sv_upgrade(dstr, SVt_PVNV);
                break;
            }
-           SvNVX(dstr) = SvNVX(sstr);
+           SvNV_set(dstr, SvNVX(sstr));
            (void)SvNOK_only(dstr);
            if (SvTAINTED(sstr))
                SvTAINT(dstr);
@@ -4469,18 +4486,19 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
                (void)SvOOK_off(dstr);          /* backoff */
                if (SvLEN(dstr))
                    Safefree(SvPVX(dstr));
-               SvLEN(dstr)=SvCUR(dstr)=0;
+               SvLEN_set(dstr, 0);
+                SvCUR_set(dstr, 0);
            }
        }
        (void)SvOK_off(dstr);
-       SvRV(dstr) = SvREFCNT_inc(SvRV(sstr));
+       SvRV_set(dstr, SvREFCNT_inc(SvRV(sstr)));
        SvROK_on(dstr);
        if (sflags & SVp_NOK) {
            SvNOKp_on(dstr);
            /* Only set the public OK flag if the source has public OK.  */
            if (sflags & SVf_NOK)
                SvFLAGS(dstr) |= SVf_NOK;
-           SvNVX(dstr) = SvNVX(sstr);
+           SvNV_set(dstr, SvNVX(sstr));
        }
        if (sflags & SVp_IOK) {
            (void)SvIOKp_on(dstr);
@@ -4488,7 +4506,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
                SvFLAGS(dstr) |= SVf_IOK;
            if (sflags & SVf_IVisUV)
                SvIsUV_on(dstr);
-           SvIVX(dstr) = SvIVX(sstr);
+           SvIV_set(dstr, SvIVX(sstr));
        }
        if (SvAMAGIC(sstr)) {
            SvAMAGIC_on(dstr);
@@ -4593,7 +4611,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
                     SvPV_set(dstr,
                              sharepvn(SvPVX(sstr),
                                       (sflags & SVf_UTF8?-cur:cur), hash));
-                    SvUVX(dstr) = hash;
+                    SvUV_set(dstr, hash);
                 }
                 SvLEN(dstr) = len;
                 SvCUR(dstr) = cur;
@@ -4623,7 +4641,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
            SvNOKp_on(dstr);
            if (sflags & SVf_NOK)
                SvFLAGS(dstr) |= SVf_NOK;
-           SvNVX(dstr) = SvNVX(sstr);
+           SvNV_set(dstr, SvNVX(sstr));
        }
        if (sflags & SVp_IOK) {
            (void)SvIOKp_on(dstr);
@@ -4631,7 +4649,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
                SvFLAGS(dstr) |= SVf_IOK;
            if (sflags & SVf_IVisUV)
                SvIsUV_on(dstr);
-           SvIVX(dstr) = SvIVX(sstr);
+           SvIV_set(dstr, SvIVX(sstr));
        }
        if (SvVOK(sstr)) {
            MAGIC *smg = mg_find(sstr,PERL_MAGIC_vstring);
@@ -4650,13 +4668,13 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
        /* XXXX Do we want to set IsUV for IV(ROK)?  Be extra safe... */
        if (sflags & SVf_IVisUV)
            SvIsUV_on(dstr);
-       SvIVX(dstr) = SvIVX(sstr);
+       SvIV_set(dstr, SvIVX(sstr));
        if (sflags & SVp_NOK) {
            if (sflags & SVf_NOK)
                (void)SvNOK_on(dstr);
            else
                (void)SvNOKp_on(dstr);
-           SvNVX(dstr) = SvNVX(sstr);
+           SvNV_set(dstr, SvNVX(sstr));
        }
     }
     else if (sflags & SVp_NOK) {
@@ -4666,7 +4684,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV *sstr, I32 flags)
            (void)SvOK_off(dstr);
            SvNOKp_on(dstr);
        }
-       SvNVX(dstr) = SvNVX(sstr);
+       SvNV_set(dstr, SvNVX(sstr));
     }
     else {
        if (dtype == SVt_PVGV) {
@@ -4735,7 +4753,7 @@ Perl_sv_setsv_cow(pTHX_ SV *dstr, SV *sstr)
            UV hash = SvUVX(sstr);
            DEBUG_C(PerlIO_printf(Perl_debug_log,
                                  "Fast copy on write: Sharing hash\n"));
-           SvUVX(dstr) = hash;
+           SvUV_set(dstr, hash);
            new_pv = sharepvn(SvPVX(sstr), (SvUTF8(sstr)?-cur:cur), hash);
            goto common_exit;
        }
@@ -4889,7 +4907,7 @@ Perl_sv_usepvn(pTHX_ register SV *sv, register char *ptr, register STRLEN len)
     if (SvPVX(sv) && SvLEN(sv))
        Safefree(SvPVX(sv));
     Renew(ptr, len+1, char);
-    SvPVX(sv) = ptr;
+    SvPV_set(sv, ptr);
     SvCUR_set(sv, len);
     SvLEN_set(sv, len+1);
     *SvEND(sv) = '\0';
@@ -4997,7 +5015,7 @@ Perl_sv_force_normal_flags(pTHX_ register SV *sv, U32 flags)
             SvFAKE_off(sv);
             SvREADONLY_off(sv);
             /* This SV doesn't own the buffer, so need to New() a new one:  */
-            SvPVX(sv) = 0;
+            SvPV_set(sv, (char*)0);
             SvLEN(sv) = 0;
             if (flags & SV_COW_DROP_PV) {
                 /* OK, so we don't need to copy our buffer.  */
@@ -5026,8 +5044,8 @@ Perl_sv_force_normal_flags(pTHX_ register SV *sv, U32 flags)
             U32 hash   = SvUVX(sv);
            SvFAKE_off(sv);
            SvREADONLY_off(sv);
-            SvPVX(sv) = 0;
-            SvLEN(sv) = 0;
+            SvPV_set(sv, (char*)0);
+            SvLEN_set(sv, 0);
            SvGROW(sv, len + 1);
            Move(pvx,SvPVX(sv),len,char);
            *SvEND(sv) = '\0';
@@ -5091,17 +5109,17 @@ Perl_sv_chop(pTHX_ register SV *sv, register char *ptr)
            Move(pvx,SvPVX(sv),len,char);
            *SvEND(sv) = '\0';
        }
-       SvIVX(sv) = 0;
+       SvIV_set(sv, 0);
        /* Same SvOOK_on but SvOOK_on does a SvIOK_off
           and we do that anyway inside the SvNIOK_off
        */
        SvFLAGS(sv) |= SVf_OOK;
     }
     SvNIOK_off(sv);
-    SvLEN(sv) -= delta;
-    SvCUR(sv) -= delta;
-    SvPVX(sv) += delta;
-    SvIVX(sv) += delta;
+    SvLEN_set(sv, SvLEN(sv) - delta);
+    SvCUR_set(sv, SvCUR(sv) - delta);
+    SvPV_set(sv, SvPVX(sv) + delta);
+    SvIV_set(sv, SvIVX(sv) + delta);
 }
 
 /* sv_catpvn() is now a macro using Perl_sv_catpvn_flags();
@@ -5145,7 +5163,7 @@ Perl_sv_catpvn_flags(pTHX_ register SV *dsv, register const char *sstr, register
     if (sstr == dstr)
        sstr = SvPVX(dsv);
     Move(sstr, SvPVX(dsv) + dlen, slen, char);
-    SvCUR(dsv) += slen;
+    SvCUR_set(dsv, SvCUR(dsv) + slen);
     *SvEND(dsv) = '\0';
     (void)SvPOK_only_UTF8(dsv);                /* validate pointer */
     SvTAINT(dsv);
@@ -5268,7 +5286,7 @@ Perl_sv_catpv(pTHX_ register SV *sv, register const char *ptr)
     if (ptr == junk)
        ptr = SvPVX(sv);
     Move(ptr,SvPVX(sv)+tlen,len+1,char);
-    SvCUR(sv) += len;
+    SvCUR_set(sv, SvCUR(sv) + len);
     (void)SvPOK_only_UTF8(sv);         /* validate pointer */
     SvTAINT(sv);
 }
@@ -5314,23 +5332,23 @@ Perl_newSV(pTHX_ STRLEN len)
 =for apidoc sv_magicext
 
 Adds magic to an SV, upgrading it if necessary. Applies the
-supplied vtable and returns pointer to the magic added.
+supplied vtable and returns pointer to the magic added.
 
-Note that sv_magicext will allow things that sv_magic will not.
-In particular you can add magic to SvREADONLY SVs and and more than
-one instance of the same 'how'
+Note that C<sv_magicext> will allow things that C<sv_magic> will not.
+In particular, you can add magic to SvREADONLY SVs, and add more than
+one instance of the same 'how'.
 
-I C<namelen> is greater then zero then a savepvn() I<copy> of C<name> is stored,
-if C<namelen> is zero then C<name> is stored as-is and - as another special
-case - if C<(name && namelen == HEf_SVKEY)> then C<name> is assumed to contain
-an C<SV*> and has its REFCNT incremented
+If C<namlen> is greater than zero then a C<savepvn> I<copy> of C<name> is
+stored, if C<namlen> is zero then C<name> is stored as-is and - as another
+special case - if C<(name && namlen == HEf_SVKEY)> then C<name> is assumed
+to contain an C<SV*> and is stored as-is with its REFCNT incremented.
 
-(This is now used as a subroutine by sv_magic.)
+(This is now used as a subroutine by C<sv_magic>.)
 
 =cut
 */
 MAGIC *        
-Perl_sv_magicext(pTHX_ SV* sv, SV* obj, int how, MGVTBL *vtable,
+Perl_sv_magicext(pTHX_ SV* sv, SV* obj, int how, const MGVTBL *vtable,
                 const char* name, I32 namlen)
 {
     MAGIC* mg;
@@ -5340,12 +5358,12 @@ Perl_sv_magicext(pTHX_ SV* sv, SV* obj, int how, MGVTBL *vtable,
     }
     Newz(702,mg, 1, MAGIC);
     mg->mg_moremagic = SvMAGIC(sv);
-    SvMAGIC(sv) = mg;
+    SvMAGIC_set(sv, mg);
 
-    /* Some magic sontains a reference loop, where the sv and object refer to
-       each other.  To prevent a reference loop that would prevent such
-       objects being freed, we look for such loops and if we find one we
-       avoid incrementing the object refcount.
+    /* Sometimes a magic contains a reference loop, where the sv and
+       object refer to each other.  To prevent a reference loop that
+       would prevent such objects being freed, we look for such loops
+       and if we find one we avoid incrementing the object refcount.
 
        Note we cannot do this to avoid self-tie loops as intervening RV must
        have its REFCNT incremented to keep it in existence.
@@ -5404,14 +5422,20 @@ Perl_sv_magicext(pTHX_ SV* sv, SV* obj, int how, MGVTBL *vtable,
 Adds magic to an SV. First upgrades C<sv> to type C<SVt_PVMG> if necessary,
 then adds a new magic item of type C<how> to the head of the magic list.
 
+See C<sv_magicext> (which C<sv_magic> now calls) for a description of the
+handling of the C<name> and C<namlen> arguments.
+
+You need to use C<sv_magicext> to add magic to SvREADONLY SVs and also
+to add more than one instance of the same 'how'.
+
 =cut
 */
 
 void
 Perl_sv_magic(pTHX_ register SV *sv, SV *obj, int how, const char *name, I32 namlen)
 {
+    const MGVTBL *vtable = 0;
     MAGIC* mg;
-    MGVTBL *vtable = 0;
 
 #ifdef PERL_COPY_ON_WRITE
     if (SvIsCOW(sv))
@@ -5585,7 +5609,7 @@ Perl_sv_unmagic(pTHX_ SV *sv, int type)
     mgp = &SvMAGIC(sv);
     for (mg = *mgp; mg; mg = *mgp) {
        if (mg->mg_type == type) {
-           MGVTBL* vtbl = mg->mg_virtual;
+            const MGVTBL* const vtbl = mg->mg_virtual;
            *mgp = mg->mg_moremagic;
            if (vtbl && vtbl->svt_free)
                CALL_FPTR(vtbl->svt_free)(aTHX_ sv, mg);
@@ -5704,7 +5728,7 @@ the Perl substr() function.
 */
 
 void
-Perl_sv_insert(pTHX_ SV *bigstr, STRLEN offset, STRLEN len, char *little, STRLEN littlelen)
+Perl_sv_insert(pTHX_ SV *bigstr, STRLEN offset, STRLEN len, const char *little, STRLEN littlelen)
 {
     register char *big;
     register char *mid;
@@ -5735,7 +5759,7 @@ Perl_sv_insert(pTHX_ SV *bigstr, STRLEN offset, STRLEN len, char *little, STRLEN
        while (midend > mid)            /* shove everything down */
            *--bigend = *--midend;
        Move(little,big+offset,littlelen,char);
-       SvCUR(bigstr) += i;
+       SvCUR_set(bigstr, SvCUR(bigstr) + i);
        SvSETMAGIC(bigstr);
        return;
     }
@@ -5813,15 +5837,22 @@ Perl_sv_replace(pTHX_ register SV *sv, register SV *nsv)
            mg_free(nsv);
        else
            sv_upgrade(nsv, SVt_PVMG);
-       SvMAGIC(nsv) = SvMAGIC(sv);
+       SvMAGIC_set(nsv, SvMAGIC(sv));
        SvFLAGS(nsv) |= SvMAGICAL(sv);
        SvMAGICAL_off(sv);
-       SvMAGIC(sv) = 0;
+       SvMAGIC_set(sv, NULL);
     }
     SvREFCNT(sv) = 0;
     sv_clear(sv);
     assert(!SvREFCNT(sv));
+#ifdef DEBUG_LEAKING_SCALARS
+    sv->sv_flags  = nsv->sv_flags;
+    sv->sv_any    = nsv->sv_any;
+    sv->sv_refcnt = nsv->sv_refcnt;
+#else
     StructCopy(nsv,sv,SV);
+#endif
+
 #ifdef PERL_COPY_ON_WRITE
     if (SvIsCOW_normal(nsv)) {
        /* We need to follow the pointers around the loop to make the
@@ -5899,7 +5930,7 @@ Perl_sv_clear(pTHX_ register SV *sv)
                    if(SvREFCNT(tmpref) < 2) {
                        /* tmpref is not kept alive! */
                        SvREFCNT(sv)--;
-                       SvRV(tmpref) = 0;
+                       SvRV_set(tmpref, NULL);
                        SvROK_off(tmpref);
                    }
                    SvREFCNT_dec(tmpref);
@@ -6612,9 +6643,9 @@ coerce its args to strings if necessary.
 I32
 Perl_sv_eq(pTHX_ register SV *sv1, register SV *sv2)
 {
-    char *pv1;
+    const char *pv1;
     STRLEN cur1;
-    char *pv2;
+    const char *pv2;
     STRLEN cur2;
     I32  eq     = 0;
     char *tpv   = Nullch;
@@ -6660,7 +6691,7 @@ Perl_sv_eq(pTHX_ register SV *sv1, register SV *sv2)
              if (SvUTF8(sv1)) {
                   /* sv1 is the UTF-8 one,
                    * if is equal it must be downgrade-able */
-                  char *pv = (char*)bytes_from_utf8((U8*)pv1,
+                  char *pv = (char*)bytes_from_utf8((const U8*)pv1,
                                                     &cur1, &is_utf8);
                   if (pv != pv1)
                        pv1 = tpv = pv;
@@ -6668,7 +6699,7 @@ Perl_sv_eq(pTHX_ register SV *sv1, register SV *sv2)
              else {
                   /* sv2 is the UTF-8 one,
                    * if is equal it must be downgrade-able */
-                  char *pv = (char *)bytes_from_utf8((U8*)pv2,
+                  char *pv = (char *)bytes_from_utf8((const U8*)pv2,
                                                      &cur2, &is_utf8);
                   if (pv != pv2)
                        pv2 = tpv = pv;
@@ -6708,7 +6739,8 @@ I32
 Perl_sv_cmp(pTHX_ register SV *sv1, register SV *sv2)
 {
     STRLEN cur1, cur2;
-    char *pv1, *pv2, *tpv = Nullch;
+    const char *pv1, *pv2;
+    char *tpv = Nullch;
     I32  cmp;
     SV *svrecode = Nullsv;
 
@@ -6736,7 +6768,7 @@ Perl_sv_cmp(pTHX_ register SV *sv1, register SV *sv2)
                 pv2 = SvPV(svrecode, cur2);
            }
            else {
-                pv2 = tpv = (char*)bytes_to_utf8((U8*)pv2, &cur2);
+                pv2 = tpv = (char*)bytes_to_utf8((const U8*)pv2, &cur2);
            }
        }
        else {
@@ -6746,7 +6778,7 @@ Perl_sv_cmp(pTHX_ register SV *sv1, register SV *sv2)
                 pv1 = SvPV(svrecode, cur1);
            }
            else {
-                pv1 = tpv = (char*)bytes_to_utf8((U8*)pv1, &cur1);
+                pv1 = tpv = (char*)bytes_to_utf8((const U8*)pv1, &cur1);
            }
        }
     }
@@ -6756,7 +6788,7 @@ Perl_sv_cmp(pTHX_ register SV *sv1, register SV *sv2)
     } else if (!cur2) {
        cmp = 1;
     } else {
-       I32 retval = memcmp((void*)pv1, (void*)pv2, cur1 < cur2 ? cur1 : cur2);
+        const I32 retval = memcmp((const void*)pv1, (const void*)pv2, cur1 < cur2 ? cur1 : cur2);
 
        if (retval) {
            cmp = retval < 0 ? -1 : 1;
@@ -6908,7 +6940,7 @@ appending to the currently-stored string.
 char *
 Perl_sv_gets(pTHX_ register SV *sv, register PerlIO *fp, I32 append)
 {
-    char *rsptr;
+    const char *rsptr;
     STRLEN rslen;
     register STDCHAR rslast;
     register STDCHAR *bp;
@@ -7197,7 +7229,7 @@ thats_really_all_folks:
 
 screamer2:
        if (rslen) {
-           register STDCHAR *bpe = buf + sizeof(buf);
+            const register STDCHAR *bpe = buf + sizeof(buf);
            bp = buf;
            while ((i = PerlIO_getc(fp)) != EOF && (*bp++ = (STDCHAR)i) != rslast && bp < bpe)
                ; /* keep reading */
@@ -7313,20 +7345,20 @@ Perl_sv_inc(pTHX_ register SV *sv)
                sv_setnv(sv, UV_MAX_P1);
            else
                (void)SvIOK_only_UV(sv);
-               ++SvUVX(sv);
+               SvUV_set(sv, SvUVX(sv) + 1);
        } else {
            if (SvIVX(sv) == IV_MAX)
                sv_setuv(sv, (UV)IV_MAX + 1);
            else {
                (void)SvIOK_only(sv);
-               ++SvIVX(sv);
+               SvIV_set(sv, SvIVX(sv) + 1);
            }   
        }
        return;
     }
     if (flags & SVp_NOK) {
        (void)SvNOK_only(sv);
-       SvNVX(sv) += 1.0;
+        SvNV_set(sv, SvNVX(sv) + 1.0);
        return;
     }
 
@@ -7334,7 +7366,7 @@ Perl_sv_inc(pTHX_ register SV *sv)
        if ((flags & SVTYPEMASK) < SVt_PVIV)
            sv_upgrade(sv, SVt_IV);
        (void)SvIOK_only(sv);
-       SvIVX(sv) = 1;
+       SvIV_set(sv, 1);
        return;
     }
     d = SvPVX(sv);
@@ -7361,7 +7393,7 @@ Perl_sv_inc(pTHX_ register SV *sv)
            /* sv_2iv *should* have made this an NV */
            if (flags & SVp_NOK) {
                (void)SvNOK_only(sv);
-               SvNVX(sv) += 1.0;
+                SvNV_set(sv, SvNVX(sv) + 1.0);
                return;
            }
            /* I don't think we can get here. Maybe I should assert this
@@ -7409,7 +7441,7 @@ Perl_sv_inc(pTHX_ register SV *sv)
     }
     /* oh,oh, the number grew */
     SvGROW(sv, SvCUR(sv) + 2);
-    SvCUR(sv)++;
+    SvCUR_set(sv, SvCUR(sv) + 1);
     for (d = SvPVX(sv) + SvCUR(sv); d > SvPVX(sv); d--)
        *d = d[-1];
     if (isDIGIT(d[1]))
@@ -7463,31 +7495,31 @@ Perl_sv_dec(pTHX_ register SV *sv)
        if (SvIsUV(sv)) {
            if (SvUVX(sv) == 0) {
                (void)SvIOK_only(sv);
-               SvIVX(sv) = -1;
+               SvIV_set(sv, -1);
            }
            else {
                (void)SvIOK_only_UV(sv);
-               --SvUVX(sv);
+               SvUV_set(sv, SvUVX(sv) + 1);
            }   
        } else {
            if (SvIVX(sv) == IV_MIN)
                sv_setnv(sv, (NV)IV_MIN - 1.0);
            else {
                (void)SvIOK_only(sv);
-               --SvIVX(sv);
+               SvIV_set(sv, SvIVX(sv) - 1);
            }   
        }
        return;
     }
     if (flags & SVp_NOK) {
-       SvNVX(sv) -= 1.0;
+        SvNV_set(sv, SvNVX(sv) - 1.0);
        (void)SvNOK_only(sv);
        return;
     }
     if (!(flags & SVp_POK)) {
        if ((flags & SVTYPEMASK) < SVt_PVNV)
            sv_upgrade(sv, SVt_NV);
-       SvNVX(sv) = -1.0;
+       SvNV_set(sv, 1.0);
        (void)SvNOK_only(sv);
        return;
     }
@@ -7509,7 +7541,7 @@ Perl_sv_dec(pTHX_ register SV *sv)
            /* sv_2iv *should* have made this an NV */
            if (flags & SVp_NOK) {
                (void)SvNOK_only(sv);
-               SvNVX(sv) -= 1.0;
+                SvNV_set(sv, SvNVX(sv) - 1.0);
                return;
            }
            /* I don't think we can get here. Maybe I should assert this
@@ -7671,17 +7703,17 @@ Perl_newSVpvn_share(pTHX_ const char *src, I32 len, U32 hash)
        STRLEN tmplen = -len;
         is_utf8 = TRUE;
        /* See the note in hv.c:hv_fetch() --jhi */
-       src = (char*)bytes_from_utf8((U8*)src, &tmplen, &is_utf8);
+       src = (char*)bytes_from_utf8((const U8*)src, &tmplen, &is_utf8);
        len = tmplen;
     }
     if (!hash)
        PERL_HASH(hash, src, len);
     new_SV(sv);
     sv_upgrade(sv, SVt_PVIV);
-    SvPVX(sv) = sharepvn(src, is_utf8?-len:len, hash);
-    SvCUR(sv) = len;
-    SvUVX(sv) = hash;
-    SvLEN(sv) = 0;
+    SvPV_set(sv, sharepvn(src, is_utf8?-len:len, hash));
+    SvCUR_set(sv, len);
+    SvUV_set(sv, hash);
+    SvLEN_set(sv, 0);
     SvREADONLY_on(sv);
     SvFAKE_on(sv);
     SvPOK_on(sv);
@@ -7816,7 +7848,7 @@ Perl_newRV_noinc(pTHX_ SV *tmpRef)
     new_SV(sv);
     sv_upgrade(sv, SVt_RV);
     SvTEMP_off(tmpRef);
-    SvRV(sv) = tmpRef;
+    SvRV_set(sv, tmpRef);
     SvROK_on(sv);
     return sv;
 }
@@ -7853,13 +7885,10 @@ Perl_newSVsv(pTHX_ register SV *old)
        return Nullsv;
     }
     new_SV(sv);
-    if (SvTEMP(old)) {
-       SvTEMP_off(old);
-       sv_setsv(sv,old);
-       SvTEMP_on(old);
-    }
-    else
-       sv_setsv(sv,old);
+    /* SV_GMAGIC is the default for sv_setv()
+       SV_NOSTEAL prevents TEMP buffers being, well, stolen, and saves games
+       with SvTEMP_off and SvTEMP_on round a call to sv_setsv.  */
+    sv_setsv_flags(sv, old, SV_GMAGIC | SV_NOSTEAL);
     return sv;
 }
 
@@ -7873,7 +7902,7 @@ Note that the perl-level function is vaguely deprecated.
 */
 
 void
-Perl_sv_reset(pTHX_ register char *s, HV *stash)
+Perl_sv_reset(pTHX_ register const char *s, HV *stash)
 {
     register HE *entry;
     register GV *gv;
@@ -7967,7 +7996,6 @@ Perl_sv_2io(pTHX_ SV *sv)
 {
     IO* io;
     GV* gv;
-    STRLEN n_a;
 
     switch (SvTYPE(sv)) {
     case SVt_PVIO:
@@ -7984,7 +8012,7 @@ Perl_sv_2io(pTHX_ SV *sv)
            Perl_croak(aTHX_ PL_no_usym, "filehandle");
        if (SvROK(sv))
            return sv_2io(SvRV(sv));
-       gv = gv_fetchpv(SvPV(sv,n_a), FALSE, SVt_PVIO);
+       gv = gv_fetchsv(sv, FALSE, SVt_PVIO);
        if (gv)
            io = GvIO(gv);
        else
@@ -8010,7 +8038,6 @@ Perl_sv_2cv(pTHX_ SV *sv, HV **st, GV **gvp, I32 lref)
 {
     GV *gv = Nullgv;
     CV *cv = Nullcv;
-    STRLEN n_a;
 
     if (!sv)
        return *gvp = Nullgv, Nullcv;
@@ -8051,7 +8078,7 @@ Perl_sv_2cv(pTHX_ SV *sv, HV **st, GV **gvp, I32 lref)
        else if (isGV(sv))
            gv = (GV*)sv;
        else
-           gv = gv_fetchpv(SvPV(sv, n_a), lref, SVt_PVCV);
+           gv = gv_fetchsv(sv, lref, SVt_PVCV);
        *gvp = gv;
        if (!gv)
            return Nullcv;
@@ -8094,7 +8121,7 @@ Perl_sv_true(pTHX_ register SV *sv)
     if (!sv)
        return 0;
     if (SvPOK(sv)) {
-       register XPV* tXpv;
+       const register XPV* tXpv;
        if ((tXpv = (XPV*)SvANY(sv)) &&
                (tXpv->xpv_cur > 1 ||
                (tXpv->xpv_cur && *tXpv->xpv_pv != '0')))
@@ -8399,13 +8426,13 @@ Returns a string describing what the SV is a reference to.
 */
 
 char *
-Perl_sv_reftype(pTHX_ SV *sv, int ob)
+Perl_sv_reftype(pTHX_ const SV *sv, int ob)
 {
+    /* The fact that I don't need to downcast to char * everywhere, only in ?:
+       inside return suggests a const propagation bug in g++.  */
     if (ob && SvOBJECT(sv)) {
-       if (HvNAME(SvSTASH(sv)))
-           return HvNAME(SvSTASH(sv));
-       else
-           return "__ANON__";
+       char *name = HvNAME(SvSTASH(sv));
+       return name ? name : (char *) "__ANON__";
     }
     else {
        switch (SvTYPE(sv)) {
@@ -8418,18 +8445,18 @@ Perl_sv_reftype(pTHX_ SV *sv, int ob)
        case SVt_PVNV:
        case SVt_PVMG:
        case SVt_PVBM:
-                               if (SvVOK(sv))
+                               if (SvVOK(sv))
                                    return "VSTRING";
                                if (SvROK(sv))
                                    return "REF";
                                else
                                    return "SCALAR";
-                               
-       case SVt_PVLV:          return SvROK(sv) ? "REF"
+
+       case SVt_PVLV:          return (char *)  (SvROK(sv) ? "REF"
                                /* tied lvalues should appear to be
                                 * scalars for backwards compatitbility */
                                : (LvTYPE(sv) == 't' || LvTYPE(sv) == 'T')
-                                   ? "SCALAR" : "LVALUE";
+                                   ? "SCALAR" : "LVALUE");
        case SVt_PVAV:          return "ARRAY";
        case SVt_PVHV:          return "HASH";
        case SVt_PVCV:          return "CODE";
@@ -8534,7 +8561,7 @@ Perl_newSVrv(pTHX_ SV *rv, const char *classname)
     }
 
     SvOK_off(rv);
-    SvRV(rv) = sv;
+    SvRV_set(rv, sv);
     SvROK_on(rv);
 
     if (classname) {
@@ -8683,7 +8710,7 @@ Perl_sv_bless(pTHX_ SV *sv, HV *stash)
     if (SvTYPE(tmpRef) != SVt_PVIO)
        ++PL_sv_objcount;
     (void)SvUPGRADE(tmpRef, SVt_PVMG);
-    SvSTASH(tmpRef) = (HV*)SvREFCNT_inc(stash);
+    SvSTASH_set(tmpRef, (HV*)SvREFCNT_inc(stash));
 
     if (Gv_AMG(stash))
        SvAMAGIC_on(sv);
@@ -8751,10 +8778,10 @@ Perl_sv_unref_flags(pTHX_ SV *sv, U32 flags)
     if (SvWEAKREF(sv)) {
        sv_del_backref(sv);
        SvWEAKREF_off(sv);
-       SvRV(sv) = 0;
+       SvRV_set(sv, NULL);
        return;
     }
-    SvRV(sv) = 0;
+    SvRV_set(sv, NULL);
     SvROK_off(sv);
     /* You can't have a || SvREADONLY(rv) here, as $a = $$a, where $a was
        assigned to as BEGIN {$a = \"Foo"} will fail.  */
@@ -9010,7 +9037,8 @@ output to an SV.  If the appended data contains "wide" characters
 (including, but not limited to, SVs with a UTF-8 PV formatted with %s,
 and characters >255 formatted with %c), the original SV might get
 upgraded to UTF-8.  Handles 'get' magic, but not 'set' magic.  See
-C<sv_catpvf_mg>.
+C<sv_catpvf_mg>. If the original SV was UTF-8, the pattern should be
+valid UTF-8; if the original SV was bytes, the pattern should be too.
 
 =cut */
 
@@ -9150,6 +9178,8 @@ Usually used via one of its frontends C<sv_vcatpvf> and C<sv_vcatpvf_mg>.
 =cut
 */
 
+/* XXX maybe_tainted is never assigned to, so the doc above is lying. */
+
 void
 Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV **svargs, I32 svmax, bool *maybe_tainted)
 {
@@ -9182,7 +9212,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
        switch (pat[1]) {
        case 's':
            if (args) {
-               char *s = va_arg(*args, char*);
+                const char *s = va_arg(*args, char*);
                sv_catpv(sv, s ? s : nullstr);
            }
            else if (svix < svmax) {
@@ -9272,7 +9302,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
 #endif
 
        char esignbuf[4];
-       U8 utf8buf[UTF8_MAXLEN+1];
+       U8 utf8buf[UTF8_MAXBYTES+1];
        STRLEN esignlen = 0;
 
        char *eptr = Nullch;
@@ -9296,7 +9326,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
        STRLEN have;
        STRLEN need;
        STRLEN gap;
-       char *dotstr = ".";
+        const char *dotstr = ".";
        STRLEN dotstrlen = 1;
        I32 efix = 0; /* explicit format parameter index */
        I32 ewix = 0; /* explicit width index */
@@ -9582,6 +9612,9 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
            goto string;
 
        case '_':
+#ifdef CHECK_FORMAT
+       format_sv:
+#endif
            /*
             * The "%_" hack might have to be changed someday,
             * if ISO or ANSI decide to use '_' for something.
@@ -9603,6 +9636,17 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
            /* INTEGERS */
 
        case 'p':
+#ifdef CHECK_FORMAT
+           if (left) {
+               left = FALSE;
+               if (!width)
+                   goto format_sv;     /* %-p  -> %_   */
+               precis = width;
+               has_precis = TRUE;
+               width = 0;
+               goto format_sv;         /* %-Np -> %.N_ */      
+           }
+#endif
            if (alt || vectorize)
                goto unknown;
            uv = PTR2UV(args ? va_arg(*args, void*) : argsv);
@@ -9779,19 +9823,6 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
                }
                break;
            default:            /* it had better be ten or less */
-#if defined(PERL_Y2KWARN)
-               if (ckWARN(WARN_Y2K)) {
-                   STRLEN n;
-                   char *s = SvPV(sv,n);
-                   if (n >= 2 && s[n-2] == '1' && s[n-1] == '9'
-                       && (n == 2 || !isDIGIT(s[n-3])))
-                   {
-                       Perl_warner(aTHX_ packWARN(WARN_Y2K),
-                                   "Possible Y2K bug: %%%c %s",
-                                   c, "format string following '19'");
-                   }
-               }
-#endif
                do {
                    dig = uv % base;
                    *--eptr = '0' + dig;
@@ -10064,7 +10095,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
            Copy(eptr, p, elen, char);
            p += elen;
            *p = '\0';
-           SvCUR(sv) = p - SvPVX(sv);
+           SvCUR_set(sv, p - SvPVX(sv));
            svix = osvix;
            continue;   /* not "break" */
        }
@@ -10130,7 +10161,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
        if (has_utf8)
            SvUTF8_on(sv);
        *p = '\0';
-       SvCUR(sv) = p - SvPVX(sv);
+       SvCUR_set(sv, p - SvPVX(sv));
        if (vectorize) {
            esignlen = 0;
            goto vector;
@@ -10215,7 +10246,7 @@ Perl_re_dup(pTHX_ REGEXP *r, CLONE_PARAMS *param)
     ret->regstclass = NULL;
     if (r->data) {
        struct reg_data *d;
-       int count = r->data->count;
+        const int count = r->data->count;
 
        Newc(0, d, sizeof(struct reg_data) + count*sizeof(void *),
                char, struct reg_data);
@@ -10225,6 +10256,8 @@ Perl_re_dup(pTHX_ REGEXP *r, CLONE_PARAMS *param)
        for (i = 0; i < count; i++) {
            d->what[i] = r->data->what[i];
            switch (d->what[i]) {
+               /* legal options are one of: sfpont
+                  see also regcomp.h and pregfree() */
            case 's':
                d->data[i] = sv_dup_inc((SV *)r->data->data[i], param);
                break;
@@ -10241,11 +10274,21 @@ Perl_re_dup(pTHX_ REGEXP *r, CLONE_PARAMS *param)
            case 'o':
                /* Compiled op trees are readonly, and can thus be
                   shared without duplication. */
+               OP_REFCNT_LOCK;
                d->data[i] = (void*)OpREFCNT_inc((OP*)r->data->data[i]);
+               OP_REFCNT_UNLOCK;
                break;
            case 'n':
                d->data[i] = r->data->data[i];
                break;
+           case 't':
+               d->data[i] = r->data->data[i];
+               OP_REFCNT_LOCK;
+               ((reg_trie_data*)d->data[i])->refcount++;
+               OP_REFCNT_UNLOCK;
+               break;
+            default:
+               Perl_croak(aTHX_ "panic: re_dup unknown data code '%c'", r->data->what[i]);
            }
        }
 
@@ -10286,6 +10329,8 @@ PerlIO *
 Perl_fp_dup(pTHX_ PerlIO *fp, char type, CLONE_PARAMS *param)
 {
     PerlIO *ret;
+    (void)type;
+
     if (!fp)
        return (PerlIO*)NULL;
 
@@ -10373,10 +10418,10 @@ Perl_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS* param)
            nmg->mg_obj = (SV*)re_dup((REGEXP*)mg->mg_obj, param);
        }
        else if(mg->mg_type == PERL_MAGIC_backref) {
-           AV *av = (AV*) mg->mg_obj;
+           const AV * const av = (AV*) mg->mg_obj;
            SV **svp;
            I32 i;
-           SvREFCNT_inc(nmg->mg_obj = (SV*)newAV());
+           (void)SvREFCNT_inc(nmg->mg_obj = (SV*)newAV());
            svp = AvARRAY(av);
            for (i = AvFILLp(av); i >= 0; i--) {
                if (!svp[i]) continue;
@@ -10628,15 +10673,16 @@ void
 Perl_rvpv_dup(pTHX_ SV *dstr, SV *sstr, CLONE_PARAMS* param)
 {
     if (SvROK(sstr)) {
-       SvRV(dstr) = SvWEAKREF(sstr)
-                    ? sv_dup(SvRV(sstr), param)
-                    : sv_dup_inc(SvRV(sstr), param);
+       SvRV_set(dstr, SvWEAKREF(sstr)
+                      ? sv_dup(SvRV(sstr), param)
+                      : sv_dup_inc(SvRV(sstr), param));
+
     }
     else if (SvPVX(sstr)) {
        /* Has something there */
        if (SvLEN(sstr)) {
            /* Normal PV - clone whole allocated space */
-           SvPVX(dstr) = SAVEPVN(SvPVX(sstr), SvLEN(sstr)-1);
+           SvPV_set(dstr, SAVEPVN(SvPVX(sstr), SvLEN(sstr)-1));
            if (SvREADONLY(sstr) && SvFAKE(sstr)) {
                /* Not that normal - actually sstr is copy on write.
                   But we are a true, independant SV, so:  */
@@ -10653,25 +10699,28 @@ Perl_rvpv_dup(pTHX_ SV *dstr, SV *sstr, CLONE_PARAMS* param)
                        and they should not have these flags
                        turned off */
 
-                    SvPVX(dstr) = sharepvn(SvPVX(sstr), SvCUR(sstr),
-                                           SvUVX(sstr));
-                    SvUVX(dstr) = SvUVX(sstr);
+                    SvPV_set(dstr, sharepvn(SvPVX(sstr), SvCUR(sstr),
+                                           SvUVX(sstr)));
+                    SvUV_set(dstr, SvUVX(sstr));
                 } else {
 
-                    SvPVX(dstr) = SAVEPVN(SvPVX(sstr), SvCUR(sstr));
+                    SvPV_set(dstr, SAVEPVN(SvPVX(sstr), SvCUR(sstr)));
                     SvFAKE_off(dstr);
                     SvREADONLY_off(dstr);
                 }
            }
            else {
                /* Some other special case - random pointer */
-               SvPVX(dstr) = SvPVX(sstr);              
+               SvPV_set(dstr, SvPVX(sstr));            
            }
        }
     }
     else {
        /* Copy the Null */
-       SvPVX(dstr) = SvPVX(sstr);
+       if (SvTYPE(dstr) == SVt_RV)
+           SvRV_set(dstr, NULL);
+       else
+           SvPV_set(dstr, 0);
     }
 }
 
@@ -10701,6 +10750,19 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
 
     /* create anew and remember what it is */
     new_SV(dstr);
+
+#ifdef DEBUG_LEAKING_SCALARS
+    dstr->sv_debug_optype = sstr->sv_debug_optype;
+    dstr->sv_debug_line = sstr->sv_debug_line;
+    dstr->sv_debug_inpad = sstr->sv_debug_inpad;
+    dstr->sv_debug_cloned = 1;
+#  ifdef NETWARE
+    dstr->sv_debug_file = savepv(sstr->sv_debug_file);
+#  else
+    dstr->sv_debug_file = savesharedpv(sstr->sv_debug_file);
+#  endif
+#endif
+
     ptr_table_store(PL_ptr_table, sstr, dstr);
 
     /* clone */
@@ -10714,17 +10776,24 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
                      PL_watch_pvx, SvPVX(sstr));
 #endif
 
+    /* don't clone objects whose class has asked us not to */
+    if (SvOBJECT(sstr) && ! (SvFLAGS(SvSTASH(sstr)) & SVphv_CLONEABLE)) {
+       SvFLAGS(dstr) &= ~SVTYPEMASK;
+       SvOBJECT_off(dstr);
+       return dstr;
+    }
+
     switch (SvTYPE(sstr)) {
     case SVt_NULL:
        SvANY(dstr)     = NULL;
        break;
     case SVt_IV:
        SvANY(dstr)     = new_XIV();
-       SvIVX(dstr)     = SvIVX(sstr);
+       SvIV_set(dstr, SvIVX(sstr));
        break;
     case SVt_NV:
        SvANY(dstr)     = new_XNV();
-       SvNVX(dstr)     = SvNVX(sstr);
+       SvNV_set(dstr, SvNVX(sstr));
        break;
     case SVt_RV:
        SvANY(dstr)     = new_XRV();
@@ -10732,43 +10801,43 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
        break;
     case SVt_PV:
        SvANY(dstr)     = new_XPV();
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
        Perl_rvpv_dup(aTHX_ dstr, sstr, param);
        break;
     case SVt_PVIV:
        SvANY(dstr)     = new_XPVIV();
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
-       SvIVX(dstr)     = SvIVX(sstr);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
+       SvIV_set(dstr, SvIVX(sstr));
        Perl_rvpv_dup(aTHX_ dstr, sstr, param);
        break;
     case SVt_PVNV:
        SvANY(dstr)     = new_XPVNV();
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
-       SvIVX(dstr)     = SvIVX(sstr);
-       SvNVX(dstr)     = SvNVX(sstr);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
+       SvIV_set(dstr, SvIVX(sstr));
+       SvNV_set(dstr, SvNVX(sstr));
        Perl_rvpv_dup(aTHX_ dstr, sstr, param);
        break;
     case SVt_PVMG:
        SvANY(dstr)     = new_XPVMG();
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
-       SvIVX(dstr)     = SvIVX(sstr);
-       SvNVX(dstr)     = SvNVX(sstr);
-       SvMAGIC(dstr)   = mg_dup(SvMAGIC(sstr), param);
-       SvSTASH(dstr)   = hv_dup_inc(SvSTASH(sstr), param);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
+       SvIV_set(dstr, SvIVX(sstr));
+       SvNV_set(dstr, SvNVX(sstr));
+       SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
+       SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
        Perl_rvpv_dup(aTHX_ dstr, sstr, param);
        break;
     case SVt_PVBM:
        SvANY(dstr)     = new_XPVBM();
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
-       SvIVX(dstr)     = SvIVX(sstr);
-       SvNVX(dstr)     = SvNVX(sstr);
-       SvMAGIC(dstr)   = mg_dup(SvMAGIC(sstr), param);
-       SvSTASH(dstr)   = hv_dup_inc(SvSTASH(sstr), param);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
+       SvIV_set(dstr, SvIVX(sstr));
+       SvNV_set(dstr, SvNVX(sstr));
+       SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
+       SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
        Perl_rvpv_dup(aTHX_ dstr, sstr, param);
        BmRARE(dstr)    = BmRARE(sstr);
        BmUSEFUL(dstr)  = BmUSEFUL(sstr);
@@ -10776,12 +10845,12 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
        break;
     case SVt_PVLV:
        SvANY(dstr)     = new_XPVLV();
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
-       SvIVX(dstr)     = SvIVX(sstr);
-       SvNVX(dstr)     = SvNVX(sstr);
-       SvMAGIC(dstr)   = mg_dup(SvMAGIC(sstr), param);
-       SvSTASH(dstr)   = hv_dup_inc(SvSTASH(sstr), param);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
+       SvIV_set(dstr, SvIVX(sstr));
+       SvNV_set(dstr, SvNVX(sstr));
+       SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
+       SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
        Perl_rvpv_dup(aTHX_ dstr, sstr, param);
        LvTARGOFF(dstr) = LvTARGOFF(sstr);      /* XXX sometimes holds PMOP* when DEBUGGING */
        LvTARGLEN(dstr) = LvTARGLEN(sstr);
@@ -10808,12 +10877,12 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
             }
        }
        SvANY(dstr)     = new_XPVGV();
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
-       SvIVX(dstr)     = SvIVX(sstr);
-       SvNVX(dstr)     = SvNVX(sstr);
-       SvMAGIC(dstr)   = mg_dup(SvMAGIC(sstr), param);
-       SvSTASH(dstr)   = hv_dup_inc(SvSTASH(sstr), param);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
+       SvIV_set(dstr, SvIVX(sstr));
+       SvNV_set(dstr, SvNVX(sstr));
+       SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
+       SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
        Perl_rvpv_dup(aTHX_ dstr, sstr, param);
        GvNAMELEN(dstr) = GvNAMELEN(sstr);
        GvNAME(dstr)    = SAVEPVN(GvNAME(sstr), GvNAMELEN(sstr));
@@ -10824,12 +10893,12 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
        break;
     case SVt_PVIO:
        SvANY(dstr)     = new_XPVIO();
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
-       SvIVX(dstr)     = SvIVX(sstr);
-       SvNVX(dstr)     = SvNVX(sstr);
-       SvMAGIC(dstr)   = mg_dup(SvMAGIC(sstr), param);
-       SvSTASH(dstr)   = hv_dup_inc(SvSTASH(sstr), param);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
+       SvIV_set(dstr, SvIVX(sstr));
+       SvNV_set(dstr, SvNVX(sstr));
+       SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
+       SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
        Perl_rvpv_dup(aTHX_ dstr, sstr, param);
        IoIFP(dstr)     = fp_dup(IoIFP(sstr), IoTYPE(sstr), param);
        if (IoOFP(sstr) == IoIFP(sstr))
@@ -10866,12 +10935,12 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
        break;
     case SVt_PVAV:
        SvANY(dstr)     = new_XPVAV();
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
-       SvIVX(dstr)     = SvIVX(sstr);
-       SvNVX(dstr)     = SvNVX(sstr);
-       SvMAGIC(dstr)   = mg_dup(SvMAGIC(sstr), param);
-       SvSTASH(dstr)   = hv_dup_inc(SvSTASH(sstr), param);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
+       SvIV_set(dstr, SvIVX(sstr));
+       SvNV_set(dstr, SvNVX(sstr));
+       SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
+       SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
        AvARYLEN((AV*)dstr) = sv_dup_inc(AvARYLEN((AV*)sstr), param);
        AvFLAGS((AV*)dstr) = AvFLAGS((AV*)sstr);
        if (AvARRAY((AV*)sstr)) {
@@ -10881,7 +10950,7 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
            src_ary = AvARRAY((AV*)sstr);
            Newz(0, dst_ary, AvMAX((AV*)sstr)+1, SV*);
            ptr_table_store(PL_ptr_table, src_ary, dst_ary);
-           SvPVX(dstr) = (char*)dst_ary;
+           SvPV_set(dstr, (char*)dst_ary);
            AvALLOC((AV*)dstr) = dst_ary;
            if (AvREAL((AV*)sstr)) {
                while (items-- > 0)
@@ -10897,18 +10966,18 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
            }
        }
        else {
-           SvPVX(dstr)         = Nullch;
+           SvPV_set(dstr, Nullch);
            AvALLOC((AV*)dstr)  = (SV**)NULL;
        }
        break;
     case SVt_PVHV:
        SvANY(dstr)     = new_XPVHV();
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
-       SvIVX(dstr)     = SvIVX(sstr);
-       SvNVX(dstr)     = SvNVX(sstr);
-       SvMAGIC(dstr)   = mg_dup(SvMAGIC(sstr), param);
-       SvSTASH(dstr)   = hv_dup_inc(SvSTASH(sstr), param);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
+       SvIV_set(dstr, SvIVX(sstr));
+       SvNV_set(dstr, SvNVX(sstr));
+       SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
+       SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
        HvRITER((HV*)dstr)      = HvRITER((HV*)sstr);
        if (HvARRAY((HV*)sstr)) {
            STRLEN i = 0;
@@ -10926,7 +10995,7 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
                                     (bool)!!HvSHAREKEYS(sstr), param);
        }
        else {
-           SvPVX(dstr)         = Nullch;
+           SvPV_set(dstr, Nullch);
            HvEITER((HV*)dstr)  = (HE*)NULL;
        }
        HvPMROOT((HV*)dstr)     = HvPMROOT((HV*)sstr);          /* XXX */
@@ -10943,22 +11012,24 @@ Perl_sv_dup(pTHX_ SV *sstr, CLONE_PARAMS* param)
     case SVt_PVCV:
        SvANY(dstr)     = new_XPVCV();
         dup_pvcv:
-       SvCUR(dstr)     = SvCUR(sstr);
-       SvLEN(dstr)     = SvLEN(sstr);
-       SvIVX(dstr)     = SvIVX(sstr);
-       SvNVX(dstr)     = SvNVX(sstr);
-       SvMAGIC(dstr)   = mg_dup(SvMAGIC(sstr), param);
-       SvSTASH(dstr)   = hv_dup_inc(SvSTASH(sstr), param);
+       SvCUR_set(dstr, SvCUR(sstr));
+       SvLEN_set(dstr, SvLEN(sstr));
+       SvIV_set(dstr, SvIVX(sstr));
+       SvNV_set(dstr, SvNVX(sstr));
+       SvMAGIC_set(dstr, mg_dup(SvMAGIC(sstr), param));
+       SvSTASH_set(dstr, hv_dup_inc(SvSTASH(sstr), param));
        Perl_rvpv_dup(aTHX_ dstr, sstr, param);
        CvSTASH(dstr)   = hv_dup(CvSTASH(sstr), param); /* NOTE: not refcounted */
        CvSTART(dstr)   = CvSTART(sstr);
+       OP_REFCNT_LOCK;
        CvROOT(dstr)    = OpREFCNT_inc(CvROOT(sstr));
+       OP_REFCNT_UNLOCK;
        CvXSUB(dstr)    = CvXSUB(sstr);
        CvXSUBANY(dstr) = CvXSUBANY(sstr);
        if (CvCONST(sstr)) {
            CvXSUBANY(dstr).any_ptr = GvUNIQUE(CvGV(sstr)) ?
                 SvREFCNT_inc(CvXSUBANY(sstr).any_ptr) :
-                sv_dup_inc(CvXSUBANY(sstr).any_ptr, param);
+                sv_dup_inc((SV *)CvXSUBANY(sstr).any_ptr, param);
        }
        /* don't dup if copying back - CvGV isn't refcounted, so the
         * duped GV may never be freed. A bit of a hack! DAPM */
@@ -11427,6 +11498,40 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
     return nss;
 }
 
+
+/* if sv is a stash, call $class->CLONE_SKIP(), and set the SVphv_CLONEABLE
+ * flag to the result. This is done for each stash before cloning starts,
+ * so we know which stashes want their objects cloned */
+
+static void
+do_mark_cloneable_stash(pTHX_ SV *sv)
+{
+    if (HvNAME((HV*)sv)) {
+       GV* cloner = gv_fetchmethod_autoload((HV*)sv, "CLONE_SKIP", 0);
+       SvFLAGS(sv) |= SVphv_CLONEABLE; /* clone objects by default */
+       if (cloner && GvCV(cloner)) {
+           dSP;
+           UV status;
+
+           ENTER;
+           SAVETMPS;
+           PUSHMARK(SP);
+           XPUSHs(sv_2mortal(newSVpv(HvNAME((HV*)sv), 0)));
+           PUTBACK;
+           call_sv((SV*)GvCV(cloner), G_SCALAR);
+           SPAGAIN;
+           status = POPu;
+           PUTBACK;
+           FREETMPS;
+           LEAVE;
+           if (status)
+               SvFLAGS(sv) &= ~SVphv_CLONEABLE;
+       }
+    }
+}
+
+
+
 /*
 =for apidoc perl_clone
 
@@ -11508,10 +11613,14 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     CLONE_PARAMS* param = &clone_params;
 
     PerlInterpreter *my_perl = (PerlInterpreter*)(*ipM->pMalloc)(ipM, sizeof(PerlInterpreter));
+    /* 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
     Poison(my_perl, 1, PerlInterpreter);
+    PL_op = Nullop;
+    PL_curcop = (COP *)Nullop;
     PL_markstack = 0;
     PL_scopestack = 0;
     PL_savestack = 0;
@@ -11538,12 +11647,14 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     CLONE_PARAMS clone_params;
     CLONE_PARAMS* param = &clone_params;
     PerlInterpreter *my_perl = (PerlInterpreter*)PerlMem_malloc(sizeof(PerlInterpreter));
+    /* 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
     Poison(my_perl, 1, PerlInterpreter);
+    PL_op = Nullop;
+    PL_curcop = (COP *)Nullop;
     PL_markstack = 0;
     PL_scopestack = 0;
     PL_savestack = 0;
@@ -11613,20 +11724,24 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
 
     SvANY(&PL_sv_no)           = new_XPVNV();
     SvREFCNT(&PL_sv_no)                = (~(U32)0)/2;
-    SvFLAGS(&PL_sv_no)         = SVp_NOK|SVf_NOK|SVp_POK|SVf_POK|SVf_READONLY|SVt_PVNV;
-    SvPVX(&PL_sv_no)           = SAVEPVN(PL_No, 0);
-    SvCUR(&PL_sv_no)           = 0;
-    SvLEN(&PL_sv_no)           = 1;
-    SvNVX(&PL_sv_no)           = 0;
+    SvFLAGS(&PL_sv_no)         = SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK
+                                 |SVp_POK|SVf_POK|SVf_READONLY|SVt_PVNV;
+    SvPV_set(&PL_sv_no, SAVEPVN(PL_No, 0));
+    SvCUR_set(&PL_sv_no, 0);
+    SvLEN_set(&PL_sv_no, 1);
+    SvIV_set(&PL_sv_no, 0);
+    SvNV_set(&PL_sv_no, 0);
     ptr_table_store(PL_ptr_table, &proto_perl->Isv_no, &PL_sv_no);
 
     SvANY(&PL_sv_yes)          = new_XPVNV();
     SvREFCNT(&PL_sv_yes)       = (~(U32)0)/2;
-    SvFLAGS(&PL_sv_yes)                = SVp_NOK|SVf_NOK|SVp_POK|SVf_POK|SVf_READONLY|SVt_PVNV;
-    SvPVX(&PL_sv_yes)          = SAVEPVN(PL_Yes, 1);
-    SvCUR(&PL_sv_yes)          = 1;
-    SvLEN(&PL_sv_yes)          = 2;
-    SvNVX(&PL_sv_yes)          = 1;
+    SvFLAGS(&PL_sv_yes)                = SVp_IOK|SVf_IOK|SVp_NOK|SVf_NOK
+                                 |SVp_POK|SVf_POK|SVf_READONLY|SVt_PVNV;
+    SvPV_set(&PL_sv_yes, SAVEPVN(PL_Yes, 1));
+    SvCUR_set(&PL_sv_yes, 1);
+    SvLEN_set(&PL_sv_yes, 2);
+    SvIV_set(&PL_sv_yes, 1);
+    SvNV_set(&PL_sv_yes, 1);
     ptr_table_store(PL_ptr_table, &proto_perl->Isv_yes, &PL_sv_yes);
 
     /* create (a non-shared!) shared string table */
@@ -12145,9 +12260,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
     PL_dirty           = proto_perl->Tdirty;
     PL_localizing      = proto_perl->Tlocalizing;
 
-#ifdef PERL_FLEXIBLE_EXCEPTIONS
-    PL_protect         = proto_perl->Tprotect;
-#endif
     PL_errors          = sv_dup_inc(proto_perl->Terrors, param);
     PL_hv_fetch_ent_mh = Nullhe;
     PL_modcount                = proto_perl->Tmodcount;
@@ -12246,7 +12358,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
            ENTER;
            SAVETMPS;
            PUSHMARK(SP);
-           XPUSHs(sv_2mortal(newSVpv(HvNAME(stash), 0)));
+           XPUSHs(sv_2mortal(newSVpv(HvNAME(stash), 0)));
            PUTBACK;
            call_sv((SV*)GvCV(cloner), G_DISCARD);
            FREETMPS;
@@ -12371,3 +12483,12 @@ Perl_sv_cat_decode(pTHX_ SV *dsv, SV *encoding,
     return ret;
 }
 
+/*
+ * Local variables:
+ * c-indentation-style: bsd
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vim: shiftwidth=4:
+*/