This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
utf16_to_utf8() should croak on encountering a bare low surrogate.
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index fc67ed9..0146de4 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -1,7 +1,7 @@
 /*    sv.h
  *
- *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- *    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, by Larry Wall and others
+ *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ *    2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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.
@@ -121,6 +121,7 @@ struct STRUCT_SV {          /* struct sv { */
     PERL_BITFIELD32 sv_debug_inpad:1;  /* was allocated in a pad for an OP */
     PERL_BITFIELD32 sv_debug_cloned:1; /* was cloned for an ithread */
     PERL_BITFIELD32 sv_debug_line:16;  /* the line where we were allocated */
+    U32                    sv_debug_serial;    /* serial number of sv allocation   */
     char *     sv_debug_file;          /* the file where we were allocated */
 #endif
 };
@@ -224,7 +225,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 #  define SvREFCNT_inc(sv)             \
     ({                                 \
-       SV * const _sv = (SV*)(sv);     \
+       SV * const _sv = MUTABLE_SV(sv);        \
        if (_sv)                        \
             (SvREFCNT(_sv))++;         \
        _sv;                            \
@@ -233,41 +234,41 @@ perform the upgrade if necessary.  See C<svtype>.
     ({                                 \
        if (sv)                         \
             (SvREFCNT(sv))++;          \
-       (SV *)(sv);                             \
+       MUTABLE_SV(sv);                         \
     })
 #  define SvREFCNT_inc_NN(sv)          \
     ({                                 \
-       SV * const _sv = (SV*)(sv);     \
+       SV * const _sv = MUTABLE_SV(sv);        \
        SvREFCNT(_sv)++;                \
        _sv;                            \
     })
 #  define SvREFCNT_inc_void(sv)                \
     ({                                 \
-       SV * const _sv = (SV*)(sv);     \
+       SV * const _sv = MUTABLE_SV(sv);        \
        if (_sv)                        \
            (void)(SvREFCNT(_sv)++);    \
     })
 #else
 #  define SvREFCNT_inc(sv)     \
-       ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL)
+       ((PL_Sv=MUTABLE_SV(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL)
 #  define SvREFCNT_inc_simple(sv) \
-       ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL)
+       ((sv) ? (SvREFCNT(sv)++,MUTABLE_SV(sv)) : NULL)
 #  define SvREFCNT_inc_NN(sv) \
-       (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv)
+       (PL_Sv=MUTABLE_SV(sv),++(SvREFCNT(PL_Sv)),PL_Sv)
 #  define SvREFCNT_inc_void(sv) \
-       (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0)
+       (void)((PL_Sv=MUTABLE_SV(sv)) ? ++(SvREFCNT(PL_Sv)) : 0)
 #endif
 
 /* These guys don't need the curly blocks */
 #define SvREFCNT_inc_simple_void(sv)   STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END
-#define SvREFCNT_inc_simple_NN(sv)     (++(SvREFCNT(sv)),(SV*)(sv))
-#define SvREFCNT_inc_void_NN(sv)       (void)(++SvREFCNT((SV*)(sv)))
-#define SvREFCNT_inc_simple_void_NN(sv)        (void)(++SvREFCNT((SV*)(sv)))
+#define SvREFCNT_inc_simple_NN(sv)     (++(SvREFCNT(sv)),MUTABLE_SV(sv))
+#define SvREFCNT_inc_void_NN(sv)       (void)(++SvREFCNT(MUTABLE_SV(sv)))
+#define SvREFCNT_inc_simple_void_NN(sv)        (void)(++SvREFCNT(MUTABLE_SV(sv)))
 
 #if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 #  define SvREFCNT_dec(sv)             \
     ({                                 \
-       SV * const _sv = (SV*)(sv);     \
+       SV * const _sv = MUTABLE_SV(sv);        \
        if (_sv) {                      \
            if (SvREFCNT(_sv)) {        \
                if (--(SvREFCNT(_sv)) == 0) \
@@ -278,7 +279,7 @@ perform the upgrade if necessary.  See C<svtype>.
        }                               \
     })
 #else
-#define SvREFCNT_dec(sv)       sv_free((SV*)(sv))
+#define SvREFCNT_dec(sv)       sv_free(MUTABLE_SV(sv))
 #endif
 
 #define SVTYPEMASK     0xff
@@ -397,13 +398,10 @@ perform the upgrade if necessary.  See C<svtype>.
 /* RV upwards. However, SVf_ROK and SVp_IOK are exclusive  */
 #define SVprv_WEAKREF   0x80000000  /* Weak reference */
 
-#define _XPV_ALLOCATED_HEAD                                            \
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */    \
-    STRLEN     xpv_len         /* allocated size */
-
 #define _XPV_HEAD      \
     union _xnvu xnv_u; \
-    _XPV_ALLOCATED_HEAD
+    STRLEN     xpv_cur;        /* length of svu_pv as a C string */    \
+    STRLEN     xpv_len         /* allocated size */
 
 union _xnvu {
     NV     xnv_nv;             /* numeric value, if any */
@@ -421,7 +419,7 @@ union _xnvu {
 
 union _xivu {
     IV     xivu_iv;            /* integer value */
-                               /* xpvfm: pv offset */
+                               /* xpvfm: lines */
     UV     xivu_uv;
     void *  xivu_p1;
     I32            xivu_i32;
@@ -438,20 +436,11 @@ struct xpv {
     _XPV_HEAD;
 };
 
-typedef struct {
-    _XPV_ALLOCATED_HEAD;
-} xpv_allocated;
-
 struct xpviv {
     _XPV_HEAD;
     union _xivu xiv_u;
 };
 
-typedef struct {
-    _XPV_ALLOCATED_HEAD;
-    union _xivu xiv_u;
-} xpviv_allocated;
-
 #define xiv_iv xiv_u.xivu_iv
 
 struct xpvuv {
@@ -471,7 +460,7 @@ struct xpvnv {
     union _xmgu        xmg_u;                              \
     HV*                xmg_stash       /* class package */
 
-/* These structure must match the beginning of struct xpvhv in hv.h. */
+/* This structure must match the beginning of struct xpvhv in hv.h. */
 struct xpvmg {
     _XPV_HEAD;
     _XPVMG_HEAD;
@@ -522,16 +511,8 @@ struct xpvfm {
     _XPV_HEAD;
     _XPVMG_HEAD;
     _XPVCV_COMMON;
-    IV         xfm_lines;
 };
 
-typedef struct {
-    _XPV_ALLOCATED_HEAD;
-    _XPVMG_HEAD;
-    _XPVCV_COMMON;
-    IV         xfm_lines;
-} xpvfm_allocated;
-
 #define _XPVIO_TAIL                                                    \
     PerlIO *   xio_ifp;        /* ifp and ofp are normally the same */ \
     PerlIO *   xio_ofp;        /* but sockets need separate streams */ \
@@ -568,12 +549,6 @@ struct xpvio {
     _XPVIO_TAIL;
 };
 
-typedef struct {
-    _XPV_ALLOCATED_HEAD;
-    _XPVMG_HEAD;
-    _XPVIO_TAIL;
-} xpvio_allocated;
-
 #define xio_dirp       xio_dirpu.xiou_dirp
 #define xio_any                xio_dirpu.xiou_any
 
@@ -594,26 +569,26 @@ double.
 
 =for apidoc Am|U32|SvNIOKp|SV* sv
 Returns a U32 value indicating whether the SV contains a number, integer or
-double.  Checks the B<private> setting.  Use C<SvNIOK>.
+double.  Checks the B<private> setting.  Use C<SvNIOK> instead.
 
 =for apidoc Am|void|SvNIOK_off|SV* sv
 Unsets the NV/IV status of an SV.
 
 =for apidoc Am|U32|SvOK|SV* sv
-Returns a U32 value indicating whether the value is an SV. It also tells
-whether the value is defined or not.
+Returns a U32 value indicating whether the value is defined. This is
+only meaningful for scalars.
 
 =for apidoc Am|U32|SvIOKp|SV* sv
 Returns a U32 value indicating whether the SV contains an integer.  Checks
-the B<private> setting.  Use C<SvIOK>.
+the B<private> setting.  Use C<SvIOK> instead.
 
 =for apidoc Am|U32|SvNOKp|SV* sv
 Returns a U32 value indicating whether the SV contains a double.  Checks the
-B<private> setting.  Use C<SvNOK>.
+B<private> setting.  Use C<SvNOK> instead.
 
 =for apidoc Am|U32|SvPOKp|SV* sv
 Returns a U32 value indicating whether the SV contains a character string.
-Checks the B<private> setting.  Use C<SvPOK>.
+Checks the B<private> setting.  Use C<SvPOK> instead.
 
 =for apidoc Am|U32|SvIOK|SV* sv
 Returns a U32 value indicating whether the SV contains an integer.
@@ -903,7 +878,7 @@ in gv.h: */
 #endif
 
 /*
-=for apidoc Am|char*|SvGAMAGIC|SV* sv
+=for apidoc Am|U32|SvGAMAGIC|SV* sv
 
 Returns true if the SV has get magic or overloading. If either is true then
 the scalar is active data, and has the potential to return a new value every
@@ -916,7 +891,7 @@ the scalar's value cannot change unless written to.
 
 #define SvGAMAGIC(sv)           (SvGMAGICAL(sv) || SvAMAGIC(sv))
 
-#define Gv_AMG(stash)           (PL_amagic_generation && Gv_AMupdate(stash))
+#define Gv_AMG(stash)           (PL_amagic_generation && Gv_AMupdate(stash, FALSE))
 
 #define SvWEAKREF(sv)          ((SvFLAGS(sv) & (SVf_ROK|SVprv_WEAKREF)) \
                                  == (SVf_ROK|SVprv_WEAKREF))
@@ -966,23 +941,23 @@ the scalar's value cannot change unless written to.
 #define SvEVALED_off(sv)       (SvFLAGS(sv) &= ~SVrepl_EVAL)
 
 #if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
-#  define SvVALID(sv)          ({ SV *const thwacke = (SV *) (sv);     \
-                                  if (SvFLAGS(thwacke) & SVpbm_VALID)  \
-                                      assert(!isGV_with_GP(thwacke));  \
-                                  (SvFLAGS(thwacke) & SVpbm_VALID);    \
+#  define SvVALID(sv)          ({ const SV *const _svvalid = (const SV*)(sv); \
+                                  if (SvFLAGS(_svvalid) & SVpbm_VALID) \
+                                      assert(!isGV_with_GP(_svvalid)); \
+                                  (SvFLAGS(_svvalid) & SVpbm_VALID);   \
                                })
-#  define SvVALID_on(sv)       ({ SV *const thwacke = (SV *) (sv);     \
-                                  assert(!isGV_with_GP(thwacke));      \
-                                  (SvFLAGS(thwacke) |= SVpbm_VALID);   \
+#  define SvVALID_on(sv)       ({ SV *const _svvalid = MUTABLE_SV(sv); \
+                                  assert(!isGV_with_GP(_svvalid));     \
+                                  (SvFLAGS(_svvalid) |= SVpbm_VALID);  \
                                })
-#  define SvVALID_off(sv)      ({ SV *const thwacke = (SV *) (sv);     \
-                                  assert(!isGV_with_GP(thwacke));      \
-                                  (SvFLAGS(thwacke) &= ~SVpbm_VALID);  \
+#  define SvVALID_off(sv)      ({ SV *const _svvalid = MUTABLE_SV(sv); \
+                                  assert(!isGV_with_GP(_svvalid));     \
+                                  (SvFLAGS(_svvalid) &= ~SVpbm_VALID); \
                                })
 
-#  define SvTAIL(sv)   ({ SV *const _svi = (SV *) (sv);                \
-                           assert(SvTYPE(_svi) != SVt_PVAV);           \
-                           assert(SvTYPE(_svi) != SVt_PVHV);           \
+#  define SvTAIL(sv)   ({ const SV *const _svtail = (const SV *)(sv);  \
+                           assert(SvTYPE(_svtail) != SVt_PVAV);                \
+                           assert(SvTYPE(_svtail) != SVt_PVHV);                \
                            (SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID))    \
                                == (SVpbm_TAIL|SVpbm_VALID);            \
                        })
@@ -1009,19 +984,19 @@ the scalar's value cannot change unless written to.
 
 #if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 #  define SvPAD_TYPED_on(sv)   ({                                      \
-           SV *const whap = (SV *) (sv);                               \
-           assert(SvTYPE(whap) == SVt_PVMG);                           \
-           (SvFLAGS(whap) |= SVpad_NAME|SVpad_TYPED);                  \
+           SV *const _svpad = MUTABLE_SV(sv);                          \
+           assert(SvTYPE(_svpad) == SVt_PVMG);                         \
+           (SvFLAGS(_svpad) |= SVpad_NAME|SVpad_TYPED);                \
        })
 #define SvPAD_OUR_on(sv)       ({                                      \
-           SV *const whap = (SV *) (sv);                               \
-           assert(SvTYPE(whap) == SVt_PVMG);                           \
-           (SvFLAGS(whap) |= SVpad_NAME|SVpad_OUR);                    \
+           SV *const _svpad = MUTABLE_SV(sv);                          \
+           assert(SvTYPE(_svpad) == SVt_PVMG);                         \
+           (SvFLAGS(_svpad) |= SVpad_NAME|SVpad_OUR);                  \
        })
 #define SvPAD_STATE_on(sv)     ({                                      \
-           SV *const whap = (SV *) (sv);                               \
-           assert(SvTYPE(whap) == SVt_PVNV || SvTYPE(whap) == SVt_PVMG); \
-           (SvFLAGS(whap) |= SVpad_NAME|SVpad_STATE);                  \
+           SV *const _svpad = MUTABLE_SV(sv);                          \
+           assert(SvTYPE(_svpad) == SVt_PVNV || SvTYPE(_svpad) == SVt_PVMG); \
+           (SvFLAGS(_svpad) |= SVpad_NAME|SVpad_STATE);                \
        })
 #else
 #  define SvPAD_TYPED_on(sv)   (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED)
@@ -1049,6 +1024,7 @@ the scalar's value cannot change unless written to.
 #  define SvUVX(sv) (0 + ((XPVUV*) SvANY(sv))->xuv_uv)
 #  define SvNVX(sv) (-0.0 + ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv)
 #  define SvRV(sv) (0 + (sv)->sv_u.svu_rv)
+#  define SvRV_const(sv) (0 + (sv)->sv_u.svu_rv)
 /* Don't test the core XS code yet.  */
 #  if defined (PERL_CORE) && PERL_DEBUG_COW > 1
 #    define SvPVX(sv) (0 + (assert(!SvREADONLY(sv)), (sv)->sv_u.svu_pv))
@@ -1073,71 +1049,83 @@ the scalar's value cannot change unless written to.
 #  if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 /* These get expanded inside other macros that already use a variable _sv  */
 #    define SvPVX(sv)                                                  \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) >= SVt_PV);                             \
-           assert(SvTYPE(_svi) != SVt_PVAV);                           \
-           assert(SvTYPE(_svi) != SVt_PVHV);                           \
-           assert(!isGV_with_GP(_svi));                                \
-           &((_svi)->sv_u.svu_pv);                                     \
+       (*({ SV *const _svpvx = MUTABLE_SV(sv);                         \
+           assert(SvTYPE(_svpvx) >= SVt_PV);                           \
+           assert(SvTYPE(_svpvx) != SVt_PVAV);                         \
+           assert(SvTYPE(_svpvx) != SVt_PVHV);                         \
+           assert(!isGV_with_GP(_svpvx));                              \
+           &((_svpvx)->sv_u.svu_pv);                                   \
         }))
 #    define SvCUR(sv)                                                  \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) >= SVt_PV);                             \
-           assert(SvTYPE(_svi) != SVt_PVAV);                           \
-           assert(SvTYPE(_svi) != SVt_PVHV);                           \
-           assert(!isGV_with_GP(_svi));                                \
-           &(((XPV*) SvANY(_svi))->xpv_cur);                           \
+       (*({ const SV *const _svcur = (const SV *)(sv);                 \
+           assert(SvTYPE(_svcur) >= SVt_PV);                           \
+           assert(SvTYPE(_svcur) != SVt_PVAV);                         \
+           assert(SvTYPE(_svcur) != SVt_PVHV);                         \
+           assert(!isGV_with_GP(_svcur));                              \
+           &(((XPV*) MUTABLE_PTR(SvANY(_svcur)))->xpv_cur);            \
         }))
 #    define SvIVX(sv)                                                  \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \
-           assert(SvTYPE(_svi) != SVt_PVAV);                           \
-           assert(SvTYPE(_svi) != SVt_PVHV);                           \
-           assert(SvTYPE(_svi) != SVt_PVCV);                           \
-           assert(!isGV_with_GP(_svi));                                \
-           &(((XPVIV*) SvANY(_svi))->xiv_iv);                          \
+       (*({ const SV *const _svivx = (const SV *)(sv);                 \
+           assert(SvTYPE(_svivx) == SVt_IV || SvTYPE(_svivx) >= SVt_PVIV); \
+           assert(SvTYPE(_svivx) != SVt_PVAV);                         \
+           assert(SvTYPE(_svivx) != SVt_PVHV);                         \
+           assert(SvTYPE(_svivx) != SVt_PVCV);                         \
+           assert(SvTYPE(_svivx) != SVt_PVFM);                         \
+           assert(!isGV_with_GP(_svivx));                              \
+           &(((XPVIV*) MUTABLE_PTR(SvANY(_svivx)))->xiv_iv);           \
         }))
 #    define SvUVX(sv)                                                  \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \
-           assert(SvTYPE(_svi) != SVt_PVAV);                           \
-           assert(SvTYPE(_svi) != SVt_PVHV);                           \
-           assert(SvTYPE(_svi) != SVt_PVCV);                           \
-           assert(!isGV_with_GP(_svi));                                \
-           &(((XPVUV*) SvANY(_svi))->xuv_uv);                          \
+       (*({ const SV *const _svuvx = (const SV *)(sv);                 \
+           assert(SvTYPE(_svuvx) == SVt_IV || SvTYPE(_svuvx) >= SVt_PVIV); \
+           assert(SvTYPE(_svuvx) != SVt_PVAV);                         \
+           assert(SvTYPE(_svuvx) != SVt_PVHV);                         \
+           assert(SvTYPE(_svuvx) != SVt_PVCV);                         \
+           assert(SvTYPE(_svuvx) != SVt_PVFM);                         \
+           assert(!isGV_with_GP(_svuvx));                              \
+           &(((XPVUV*) MUTABLE_PTR(SvANY(_svuvx)))->xuv_uv);           \
         }))
 #    define SvNVX(sv)                                                  \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) == SVt_NV || SvTYPE(_svi) >= SVt_PVNV); \
-           assert(SvTYPE(_svi) != SVt_PVAV);                           \
-           assert(SvTYPE(_svi) != SVt_PVHV);                           \
-           assert(SvTYPE(_svi) != SVt_PVCV);                           \
-           assert(SvTYPE(_svi) != SVt_PVFM);                           \
-           assert(SvTYPE(_svi) != SVt_PVIO);                           \
-           assert(!isGV_with_GP(_svi));                                \
-          &(((XPVNV*) SvANY(_svi))->xnv_u.xnv_nv);                     \
+       (*({ const SV *const _svnvx = (const SV *)(sv);                 \
+           assert(SvTYPE(_svnvx) == SVt_NV || SvTYPE(_svnvx) >= SVt_PVNV); \
+           assert(SvTYPE(_svnvx) != SVt_PVAV);                         \
+           assert(SvTYPE(_svnvx) != SVt_PVHV);                         \
+           assert(SvTYPE(_svnvx) != SVt_PVCV);                         \
+           assert(SvTYPE(_svnvx) != SVt_PVFM);                         \
+           assert(SvTYPE(_svnvx) != SVt_PVIO);                         \
+           assert(!isGV_with_GP(_svnvx));                              \
+           &(((XPVNV*) MUTABLE_PTR(SvANY(_svnvx)))->xnv_u.xnv_nv);     \
         }))
 #    define SvRV(sv)                                                   \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) >= SVt_PV || SvTYPE(_svi) == SVt_IV);   \
-           assert(SvTYPE(_svi) != SVt_PVAV);                           \
-           assert(SvTYPE(_svi) != SVt_PVHV);                           \
-           assert(SvTYPE(_svi) != SVt_PVCV);                           \
-           assert(SvTYPE(_svi) != SVt_PVFM);                           \
-           assert(!isGV_with_GP(_svi));                                \
-           &((_svi)->sv_u.svu_rv);                                     \
+       (*({ SV *const _svrv = MUTABLE_SV(sv);                          \
+           assert(SvTYPE(_svrv) >= SVt_PV || SvTYPE(_svrv) == SVt_IV); \
+           assert(SvTYPE(_svrv) != SVt_PVAV);                          \
+           assert(SvTYPE(_svrv) != SVt_PVHV);                          \
+           assert(SvTYPE(_svrv) != SVt_PVCV);                          \
+           assert(SvTYPE(_svrv) != SVt_PVFM);                          \
+           assert(!isGV_with_GP(_svrv));                               \
+           &((_svrv)->sv_u.svu_rv);                                    \
         }))
+#    define SvRV_const(sv)                                             \
+       ({ const SV *const _svrv = (const SV *)(sv);                    \
+           assert(SvTYPE(_svrv) >= SVt_PV || SvTYPE(_svrv) == SVt_IV); \
+           assert(SvTYPE(_svrv) != SVt_PVAV);                          \
+           assert(SvTYPE(_svrv) != SVt_PVHV);                          \
+           assert(SvTYPE(_svrv) != SVt_PVCV);                          \
+           assert(SvTYPE(_svrv) != SVt_PVFM);                          \
+           assert(!isGV_with_GP(_svrv));                               \
+           (_svrv)->sv_u.svu_rv;                                       \
+        })
 #    define SvMAGIC(sv)                                                        \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) >= SVt_PVMG);                           \
-           if(SvTYPE(_svi) == SVt_PVMG)                                \
-               assert(!SvPAD_OUR(_svi));                               \
-           &(((XPVMG*) SvANY(_svi))->xmg_u.xmg_magic);                 \
+       (*({ const SV *const _svmagic = (const SV *)(sv);               \
+           assert(SvTYPE(_svmagic) >= SVt_PVMG);                       \
+           if(SvTYPE(_svmagic) == SVt_PVMG)                            \
+               assert(!SvPAD_OUR(_svmagic));                           \
+           &(((XPVMG*) MUTABLE_PTR(SvANY(_svmagic)))->xmg_u.xmg_magic); \
          }))
 #    define SvSTASH(sv)                                                        \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) >= SVt_PVMG);                           \
-           &(((XPVMG*) SvANY(_svi))->xmg_stash);                       \
+       (*({ const SV *const _svstash = (const SV *)(sv);               \
+           assert(SvTYPE(_svstash) >= SVt_PVMG);                       \
+           &(((XPVMG*) MUTABLE_PTR(SvANY(_svstash)))->xmg_stash);      \
          }))
 #  else
 #    define SvPVX(sv) ((sv)->sv_u.svu_pv)
@@ -1146,6 +1134,7 @@ the scalar's value cannot change unless written to.
 #    define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
 #    define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv
 #    define SvRV(sv) ((sv)->sv_u.svu_rv)
+#    define SvRV_const(sv) (0 + (sv)->sv_u.svu_rv)
 #    define SvMAGIC(sv)        ((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic
 #    define SvSTASH(sv)        ((XPVMG*)  SvANY(sv))->xmg_stash
 #  endif
@@ -1232,7 +1221,7 @@ the scalar's value cannot change unless written to.
                (((XPV*)  SvANY(sv))->xpv_len = (val)); } STMT_END
 #define SvEND_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
-               (SvCUR(sv) = (val) - SvPVX(sv)); } STMT_END
+               SvCUR_set(sv, (val) - SvPVX(sv)); } STMT_END
 
 #define SvPV_renew(sv,n) \
        STMT_START { SvLEN_set(sv, n); \
@@ -1283,29 +1272,29 @@ the scalar's value cannot change unless written to.
 */
 #if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 #  define BmFLAGS(sv)                                                  \
-       (*({ SV *const uggh = (SV *) (sv);                              \
-               assert(SvTYPE(uggh) == SVt_PVGV);                       \
-               assert(SvVALID(uggh));                                  \
-           &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_flags);           \
+       (*({ SV *const _bmflags = MUTABLE_SV(sv);                       \
+               assert(SvTYPE(_bmflags) == SVt_PVGV);                   \
+               assert(SvVALID(_bmflags));                              \
+           &(((XPVGV*) SvANY(_bmflags))->xnv_u.xbm_s.xbm_flags);       \
         }))
 #  define BmRARE(sv)                                                   \
-       (*({ SV *const uggh = (SV *) (sv);                              \
-               assert(SvTYPE(uggh) == SVt_PVGV);                       \
-               assert(SvVALID(uggh));                                  \
-           &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_rare);            \
+       (*({ SV *const _bmrare = MUTABLE_SV(sv);                        \
+               assert(SvTYPE(_bmrare) == SVt_PVGV);                    \
+               assert(SvVALID(_bmrare));                               \
+           &(((XPVGV*) SvANY(_bmrare))->xnv_u.xbm_s.xbm_rare);         \
         }))
 #  define BmUSEFUL(sv)                                                 \
-       (*({ SV *const uggh = (SV *) (sv);                              \
-           assert(SvTYPE(uggh) == SVt_PVGV);                           \
-           assert(SvVALID(uggh));                                      \
-           assert(!SvIOK(uggh));                                       \
-           &(((XPVGV*) SvANY(uggh))->xiv_u.xivu_i32);                  \
+       (*({ SV *const _bmuseful = MUTABLE_SV(sv);                      \
+           assert(SvTYPE(_bmuseful) == SVt_PVGV);                      \
+           assert(SvVALID(_bmuseful));                                 \
+           assert(!SvIOK(_bmuseful));                                  \
+           &(((XPVGV*) SvANY(_bmuseful))->xiv_u.xivu_i32);             \
         }))
 #  define BmPREVIOUS(sv)                                               \
-       (*({ SV *const uggh = (SV *) (sv);                              \
-               assert(SvTYPE(uggh) == SVt_PVGV);                       \
-               assert(SvVALID(uggh));                                  \
-           &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_previous);        \
+    (*({ SV *const _bmprevious = MUTABLE_SV(sv);                       \
+               assert(SvTYPE(_bmprevious) == SVt_PVGV);                \
+               assert(SvVALID(_bmprevious));                           \
+           &(((XPVGV*) SvANY(_bmprevious))->xnv_u.xbm_s.xbm_previous); \
         }))
 #else
 #  define BmFLAGS(sv)          ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_flags
@@ -1315,7 +1304,7 @@ the scalar's value cannot change unless written to.
 
 #endif
 
-#define FmLINES(sv)    ((XPVFM*)  SvANY(sv))->xfm_lines
+#define FmLINES(sv)    ((XPVFM*)  SvANY(sv))->xiv_u.xivu_iv
 
 #define LvTYPE(sv)     ((XPVLV*)  SvANY(sv))->xlv_type
 #define LvTARG(sv)     ((XPVLV*)  SvANY(sv))->xlv_targ
@@ -1452,7 +1441,7 @@ otherwise use the more efficient C<SvUV>.
 
 =for apidoc Am|bool|SvTRUE|SV* sv
 Returns a boolean indicating whether Perl would evaluate the SV as true or
-false, defined or undefined.  Does not handle 'get' magic.
+false.  See SvOK() for a defined/undefined test.  Does not handle 'get' magic.
 
 =for apidoc Am|char*|SvPVutf8_force|SV* sv|STRLEN len
 Like C<SvPV_force>, but converts sv to utf8 first if necessary.
@@ -1510,6 +1499,10 @@ Like C<sv_setsv> but doesn't process magic.
 =for apidoc Am|void|sv_catsv_nomg|SV* dsv|SV* ssv
 Like C<sv_catsv> but doesn't process magic.
 
+=for apidoc Amdb|STRLEN|sv_utf8_upgrade_nomg|NN SV *sv
+
+Like sv_utf8_upgrade, but doesn't do magic on C<sv>
+
 =cut
 */
 
@@ -1615,9 +1608,9 @@ Like C<sv_catsv> but doesn't process magic.
 
 #if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 
-#  define SvIVx(sv) ({SV *_sv = (SV*)(sv); SvIV(_sv); })
-#  define SvUVx(sv) ({SV *_sv = (SV*)(sv); SvUV(_sv); })
-#  define SvNVx(sv) ({SV *_sv = (SV*)(sv); SvNV(_sv); })
+#  define SvIVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvIV(_sv); })
+#  define SvUVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvUV(_sv); })
+#  define SvNVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvNV(_sv); })
 #  define SvPVx(sv, lp) ({SV *_sv = (sv); SvPV(_sv, lp); })
 #  define SvPVx_const(sv, lp) ({SV *_sv = (sv); SvPV_const(_sv, lp); })
 #  define SvPVx_nolen(sv) ({SV *_sv = (sv); SvPV_nolen(_sv); })
@@ -1699,6 +1692,10 @@ Like C<sv_catsv> but doesn't process magic.
 #define SV_COW_OTHER_PVS       1024
 /* Make sv_2pv_flags return NULL if something is undefined.  */
 #define SV_UNDEF_RETURNS_NULL  2048
+/* Tell sv_utf8_upgrade() to not check to see if an upgrade is really needed.
+ * This is used when the caller has already determined it is, and avoids
+ * redundant work */
+#define SV_FORCE_UTF8_UPGRADE  4096
 
 /* The core is safe for this COW optimisation. XS code on CPAN may not be.
    So only default to doing the COW setup if we're in the core.
@@ -1758,6 +1755,7 @@ mg.c:1024: warning: left-hand operand of comma expression has no effect
 #define sv_pvbyte(sv) SvPVbyte_nolen(sv)
 
 #define sv_pvn_force_nomg(sv, lp) sv_pvn_force_flags(sv, lp, 0)
+#define sv_utf8_upgrade_flags(sv, flags) sv_utf8_upgrade_flags_grow(sv, flags, 0)
 #define sv_utf8_upgrade_nomg(sv) sv_utf8_upgrade_flags(sv, 0)
 #define sv_catpvn_nomg(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, 0)
 #define sv_setsv(dsv, ssv) \
@@ -1778,6 +1776,9 @@ mg.c:1024: warning: left-hand operand of comma expression has no effect
 #define sv_utf8_upgrade(sv) sv_utf8_upgrade_flags(sv, SV_GMAGIC)
 #define sv_2iv(sv) sv_2iv_flags(sv, SV_GMAGIC)
 #define sv_2uv(sv) sv_2uv_flags(sv, SV_GMAGIC)
+#define sv_insert(bigstr, offset, len, little, littlelen)              \
+       Perl_sv_insert_flags(aTHX_ (bigstr),(offset), (len), (little),  \
+                            (littlelen), SV_GMAGIC)
 
 /* Should be named SvCatPVN_utf8_upgrade? */
 #define sv_catpvn_utf8_upgrade(dsv, sstr, slen, nsv)   \
@@ -1997,6 +1998,9 @@ Evaluates I<sv> more than once. Sets I<len> to 0 if C<SvOOK(sv)> is false.
        }                                                               \
     } STMT_END
 #endif
+
+#define newIO()        MUTABLE_IO(newSV_type(SVt_PVIO))
+
 /*
  * Local variables:
  * c-indentation-style: bsd