This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Avoid special case SvMAGIC macros just to cope with Perl_sv_unmagic.
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index b5f1193..102c790 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 by Larry Wall and others
+ *    2000, 2001, 2002, 2003, 2004, 2005, 2006, 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.
@@ -59,22 +59,50 @@ typedef enum {
        SVt_PVHV,       /* 12 */
        SVt_PVCV,       /* 13 */
        SVt_PVFM,       /* 14 */
-       SVt_PVIO        /* 15 */
+       SVt_PVIO,       /* 15 */
+       SVt_LAST        /* keep last in enum. used to size arrays */
 } svtype;
 
+/* There is collusion here with sv_clear - sv_clear exits early for SVt_NULL
+   and SVt_IV, so never reaches the clause at the end that uses
+   sv_type_details->body_size to determine whether to call safefree(). Hence
+   body_size can be set no-zero to record the size of PTEs and HEs, without
+   fear of bogus frees.  */
+#ifdef PERL_IN_SV_C
+#define PTE_SVSLOT     SVt_IV
+#endif
+#if defined(PERL_IN_HV_C) || defined(PERL_IN_XS_APITEST)
+#define HE_SVSLOT      SVt_NULL
+#endif
+
+#define PERL_ARENA_ROOTS_SIZE  (SVt_LAST)
+
+/* typedefs to eliminate some typing */
+typedef struct he HE;
+typedef struct hek HEK;
+
 /* Using C's structural equivalence to help emulate C++ inheritance here... */
 
+/* start with 2 sv-head building blocks */
+#define _SV_HEAD(ptrtype) \
+    ptrtype    sv_any;         /* pointer to body */   \
+    U32                sv_refcnt;      /* how many references to us */ \
+    U32                sv_flags        /* what we are */
+
+#define _SV_HEAD_UNION \
+    union {                            \
+       IV      svu_iv;                 \
+       UV      svu_uv;                 \
+       SV*     svu_rv;         /* pointer to another SV */             \
+       char*   svu_pv;         /* pointer to malloced string */        \
+       SV**    svu_array;              \
+       HE**    svu_hash;               \
+    }  sv_u
+
+
 struct STRUCT_SV {             /* struct sv { */
-    void*      sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;         /* pointer to another SV */
-       char*   svu_pv;         /* pointer to malloced string */
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(void*);
+    _SV_HEAD_UNION;
 #ifdef DEBUG_LEAKING_SCALARS
     unsigned   sv_debug_optype:9;      /* the type of OP that allocated us */
     unsigned   sv_debug_inpad:1;       /* was allocated in a pad for an OP */
@@ -85,70 +113,33 @@ struct STRUCT_SV {         /* struct sv { */
 };
 
 struct gv {
-    XPVGV*     sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;
-       char*   svu_pv;
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(XPVGV*);          /* pointer to xpvgv body */
+    _SV_HEAD_UNION;
 };
 
 struct cv {
-    XPVCV*     sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;
-       char*   svu_pv;
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(XPVCV*);          /* pointer to xpvcv body */
+    _SV_HEAD_UNION;
 };
 
 struct av {
-    XPVAV*     sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;
-       char*   svu_pv;         /* pointer to first array element */
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(XPVAV*);          /* pointer to xpvav body */
+    _SV_HEAD_UNION;
 };
 
 struct hv {
-    XPVHV*     sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;
-       char*   svu_pv;
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(XPVHV*);          /* pointer to xpvhv body */
+    _SV_HEAD_UNION;
 };
 
 struct io {
-    XPVIO*     sv_any;         /* pointer to something */
-    U32                sv_refcnt;      /* how many references to us */
-    U32                sv_flags;       /* what we are */
-    union {
-       IV      svu_iv;
-       UV      svu_uv;
-       SV*     svu_rv;
-       char*   svu_pv;
-       SV**    svu_array;
-    }          sv_u;
+    _SV_HEAD(XPVIO*);          /* pointer to xpvio body */
+    _SV_HEAD_UNION;
 };
 
+#undef _SV_HEAD
+#undef _SV_HEAD_UNION          /* ensure no pollution */
+
 /*
 =head1 SV Manipulation Functions
 
@@ -185,7 +176,7 @@ perform the upgrade if necessary.  See C<svtype>.
     })
 #else
 #  define SvREFCNT_inc(sv)     \
-       ((PL_Sv=(SV*)(sv)), (PL_Sv && ++(SvREFCNT(PL_Sv))), (SV*)PL_Sv)
+       ((PL_Sv=(SV*)(sv)) ? ((++(SvREFCNT(PL_Sv))),(PL_Sv)) : NULL)
 #endif
 
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC)
@@ -208,74 +199,108 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SVTYPEMASK     0xff
 #define SvTYPE(sv)     ((sv)->sv_flags & SVTYPEMASK)
 
-#define SvUPGRADE(sv, mt) (SvTYPE(sv) >= mt || sv_upgrade(sv, mt))
-
-#define SVs_PADSTALE   0x00000100      /* lexical has gone out of scope */
-#define SVs_PADTMP     0x00000200      /* in use as tmp */
-#define SVs_PADMY      0x00000400      /* in use a "my" variable */
-#define SVs_TEMP       0x00000800      /* string is stealable? */
-#define SVs_OBJECT     0x00001000      /* is "blessed" */
-#define SVs_GMG                0x00002000      /* has magical get method */
-#define SVs_SMG                0x00004000      /* has magical set method */
-#define SVs_RMG                0x00008000      /* has random magical methods */
-
-#define SVf_IOK                0x00010000      /* has valid public integer value */
-#define SVf_NOK                0x00020000      /* has valid public numeric value */
-#define SVf_POK                0x00040000      /* has valid public pointer value */
-#define SVf_ROK                0x00080000      /* has a valid reference pointer */
-
-#define SVf_FAKE       0x00100000      /* glob or lexical is just a copy */
-#define SVf_OOK                0x00200000      /* has valid offset value */
-#define SVf_BREAK      0x00400000      /* refcnt is artificially low - used
+/* Sadly there are some parts of the core that have pointers to already-freed
+   SV heads, and rely on being able to tell that they are now free. So mark
+   them all by using a consistent macro.  */
+#define SvIS_FREED(sv) ((sv)->sv_flags == SVTYPEMASK)
+
+#define SvUPGRADE(sv, mt) (SvTYPE(sv) >= (mt) || (sv_upgrade(sv, mt), 1))
+
+#define SVf_IOK                0x00000100      /* has valid public integer value */
+#define SVf_NOK                0x00000200      /* has valid public numeric value */
+#define SVf_POK                0x00000400      /* has valid public pointer value */
+#define SVf_ROK                0x00000800      /* has a valid reference pointer */
+
+#define SVp_IOK                0x00001000      /* has valid non-public integer value */
+#define SVp_NOK                0x00002000      /* has valid non-public numeric value */
+#define SVp_POK                0x00004000      /* has valid non-public pointer value */
+#define SVp_SCREAM     0x00008000      /* has been studied? */
+#define SVphv_CLONEABLE        0x00008000      /* PVHV (stashes) clone its objects */
+
+#define SVs_PADSTALE   0x00010000      /* lexical has gone out of scope */
+#define SVs_PADTMP     0x00020000      /* in use as tmp */
+#define SVpad_TYPED    0x00020000      /* pad name is a Typed Lexical */
+#define SVs_PADMY      0x00040000      /* in use a "my" variable */
+#define SVpad_OUR      0x00040000      /* pad name is "our" instead of "my" */
+#define SVs_TEMP       0x00080000      /* string is stealable? */
+#define SVs_OBJECT     0x00100000      /* is "blessed" */
+#define SVs_GMG                0x00200000      /* has magical get method */
+#define SVs_SMG                0x00400000      /* has magical set method */
+#define SVs_RMG                0x00800000      /* has random magical methods */
+
+#define SVf_FAKE       0x01000000      /* 0: glob or lexical is just a copy
+                                          1: SV head arena wasn't malloc()ed
+                                          2: in conjunction with SVf_READONLY
+                                             marks a shared hash key scalar
+                                             (SvLEN == 0) or a copy on write
+                                             string (SvLEN != 0) [SvIsCOW(sv)]
+                                          3: For PVCV, whether CvUNIQUE(cv)
+                                             refers to an eval or once only
+                                             [CvEVAL(cv), CvSPECIAL(cv)]
+                                          4: Whether the regexp pointer is in
+                                             fact an offset [SvREPADTMP(sv)]
+                                          5: On a pad name SV, that slot in the
+                                             frame AV is a REFCNT'ed reference
+                                             to a lexical from "outside".
+                                       */
+#define SVf_OOK                0x02000000      /* has valid offset value
+                                          For a PVHV this means that a
+                                          hv_aux struct is present after the
+                                          main array  */
+#define SVf_BREAK      0x04000000      /* refcnt is artificially low - used
                                         * by SV's in final arena  cleanup */
-#define SVf_READONLY   0x00800000      /* may not be modified */
+#define SVf_READONLY   0x08000000      /* may not be modified */
 
 
-#define SVp_IOK                0x01000000      /* has valid non-public integer value */
-#define SVp_NOK                0x02000000      /* has valid non-public numeric value */
-#define SVp_POK                0x04000000      /* has valid non-public pointer value */
-#define SVp_SCREAM     0x08000000      /* has been studied? */
 
-#define SVf_UTF8        0x20000000      /* SvPV is UTF-8 encoded */
-/* Ensure this value does not clash with the GV_ADD* flags in gv.h */
 
 #define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE)
 
 #define SVf_OK         (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \
-                        SVp_IOK|SVp_NOK|SVp_POK)
+                        SVp_IOK|SVp_NOK|SVp_POK|SVp_SCREAM)
 
-#define SVf_AMAGIC     0x10000000      /* has magical overloaded methods */
+#define PRIVSHIFT 4    /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */
 
-#define PRIVSHIFT 8    /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */
+#define SVf_AMAGIC     0x10000000      /* has magical overloaded methods */
+#define SVf_UTF8        0x20000000      /* SvPV is UTF-8 encoded */
+/* Ensure this value does not clash with the GV_ADD* flags in gv.h */
 
 /* Some private flags. */
 
-/* SVpad_OUR may be set on SVt_PV{NV,MG,GV} types */
-#define SVpad_OUR      0x80000000      /* pad name is "our" instead of "my" */
-#define SVpad_TYPED    0x40000000      /* Typed Lexical */
-
-#define SVf_IVisUV     0x80000000      /* use XPVUV instead of XPVIV */
-
-#define SVpfm_COMPILED 0x80000000      /* FORMLINE is compiled */
-
-#define SVpbm_VALID    0x80000000
+/* PVHV */
+#define SVphv_REHASH   0x10000000      /* PVHV is recalculating hash values */
+/* PVHV */
+#define SVphv_SHAREKEYS 0x20000000     /* PVHV
+                                          keys live on shared string table */
+/* PVNV, PVMG, PVGV, presumably only inside pads */
+#define SVpad_NAME     0x40000000      /* This SV is a name in the PAD, so
+                                          SVpad_TYPED and SVpad_OUR apply */
+/* PVAV */
+#define SVpav_REAL     0x40000000      /* free old entries */
+/* PVHV */
+#define SVphv_LAZYDEL  0x40000000      /* entry in xhv_eiter must be deleted */
+/* PVBM */
 #define SVpbm_TAIL     0x40000000
-
+/* ??? */
 #define SVrepl_EVAL    0x40000000      /* Replacement part of s///e */
 
-#define SVphv_CLONEABLE        0x08000000      /* for stashes: clone its objects */
-#define SVphv_REHASH   0x10000000      /* HV is recalculating hash values */
-#define SVphv_SHAREKEYS 0x20000000     /* keys live on shared string table */
-#define SVphv_LAZYDEL  0x40000000      /* entry in xhv_eiter must be deleted */
+/* IV, PVIV, PVNV, PVMG, PVGV and (I assume) PVLV  */
+/* Presumably IVs aren't stored in pads */
+#define SVf_IVisUV     0x80000000      /* use XPVUV instead of XPVIV */
+/* PVAV */
+#define SVpav_REIFY    0x80000000      /* can become real */
+/* PVHV */
 #define SVphv_HASKFLAGS        0x80000000      /* keys have flag byte after hash */
-
+/* PVFM */
+#define SVpfm_COMPILED 0x80000000      /* FORMLINE is compiled */
+/* PVBM */
+#define SVpbm_VALID    0x80000000
+/* RV upwards. However, SVf_ROK and SVp_IOK are exclusive  */
 #define SVprv_WEAKREF   0x80000000      /* Weak reference */
 
-#define SVpav_REAL     0x40000000      /* free old entries */
-#define SVpav_REIFY    0x80000000      /* can become real */
 
 struct xpv {
-    IV         xpv_dummy;      /* This isn't allocated. */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
 };
@@ -290,69 +315,91 @@ typedef struct {
 #endif
 
 struct xpviv {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
+    union {
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+       I32     xivu_i32;
+    }          xiv_u;
 };
 
+#if 0
+typedef struct xpviv xpviv_allocated;
+#else
+typedef struct {
+    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
+    STRLEN     xpv_len;        /* allocated size */
+    union {
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+       I32     xivu_i32;
+    }          xiv_u;
+} xpviv_allocated;
+#endif
+
+#define xiv_iv xiv_u.xivu_iv
+
 struct xpvuv {
-    UV         xuv_uv;         /* unsigned value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
+    union {
+       IV      xuvu_iv;
+       UV      xuvu_uv;        /* unsigned value or pv offset */
+       void *  xuvu_p1;
+    }          xuv_u;
 };
 
+#define xuv_uv xuv_u.xuvu_uv
+
 struct xpvnv {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+       I32     xivu_i32;
+    }          xiv_u;
 };
 
-#define xnv_nv xnv_u.xnvu_nv
-
 /* These structure must match the beginning of struct xpvhv in hv.h. */
 struct xpvmg {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+       I32     xivu_i32;
+    }          xiv_u;
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 };
 
 struct xpvlv {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+       I32     xivu_i32;
+    }          xiv_u;
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     /* a full glob fits into this */
@@ -370,20 +417,19 @@ struct xpvlv {
 };
 
 struct xpvgv {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+       I32     xivu_i32;
+    }          xiv_u;
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     GP*                xgv_gp;
@@ -394,20 +440,19 @@ struct xpvgv {
 };
 
 struct xpvbm {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+       I32     xivu_i32;
+    }          xiv_u;
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     I32                xbm_useful;     /* is this constant pattern being useful? */
@@ -420,54 +465,90 @@ struct xpvbm {
 typedef U16 cv_flags_t;
 
 struct xpvfm {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+       IV      xivu_iv;        /* PVFMs use the pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+       I32     xivu_i32;
+    }          xiv_u;
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     HV *       xcv_stash;
-    OP *       xcv_start;
-    OP *       xcv_root;
-    void      (*xcv_xsub)(pTHX_ CV*);
-    ANY                xcv_xsubany;
+    union {
+       OP *    xcv_start;
+       ANY     xcv_xsubany;
+    }          xcv_start_u;
+    union {
+       OP *    xcv_root;
+       void    (*xcv_xsub) (pTHX_ CV*);
+    }          xcv_root_u;
     GV *       xcv_gv;
     char *     xcv_file;
-    long       xcv_depth;      /* >= 2 indicates recursive call */
     AV *       xcv_padlist;
     CV *       xcv_outside;
-    cv_flags_t xcv_flags;
     U32                xcv_outside_seq; /* the COP sequence (at the point of our
                                  * compilation) in the lexically enclosing
                                  * sub */
+    cv_flags_t xcv_flags;
     IV         xfm_lines;
 };
 
+typedef struct {
+    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
+    STRLEN     xpv_len;        /* allocated size */
+    union {
+       IV      xivu_iv;        /* PVFMs use the pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+       I32     xivu_i32;
+    }          xiv_u;
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
+    HV*                xmg_stash;      /* class package */
+
+    HV *       xcv_stash;
+    union {
+       OP *    xcv_start;
+       ANY     xcv_xsubany;
+    }          xcv_start_u;
+    union {
+       OP *    xcv_root;
+       void    (*xcv_xsub) (pTHX_ CV*);
+    }          xcv_root_u;
+    GV *       xcv_gv;
+    char *     xcv_file;
+    AV *       xcv_padlist;
+    CV *       xcv_outside;
+    U32                xcv_outside_seq; /* the COP sequence (at the point of our
+                                 * compilation) in the lexically enclosing
+                                 * sub */
+    cv_flags_t xcv_flags;
+    IV         xfm_lines;
+} xpvfm_allocated;
+
 struct xpvio {
-    IV         xiv_iv;         /* integer value or pv offset */
+    NV         xnv_nv;         /* numeric value, if any */
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
-       struct {
-           void *xnv_p1;
-           union {
-               void *xnv_p2;
-               IV xnv_i2;
-           }   xnv_u2;
-       }       xnv_s;
-       NV      xnvu_nv;        /* numeric value, if any */
-    }          xnv_u;
-    MAGIC*     xmg_magic;      /* linked list of magicalness */
+       IV      xivu_iv;        /* integer value or pv offset */
+       UV      xivu_uv;
+       void *  xivu_p1;
+       I32     xivu_i32;
+    }          xiv_u;
+    union {
+       MAGIC*  xmg_magic;      /* linked list of magicalness */
+       HV*     xmg_ourstash;   /* Stash for our (when SvPAD_OUR is true) */
+    } xmg_u;
     HV*                xmg_stash;      /* class package */
 
     PerlIO *   xio_ifp;        /* ifp and ofp are normally the same */
@@ -768,7 +849,8 @@ in gv.h: */
                                                  SVf_IVisUV),          \
                                    SvFLAGS(sv) |= (SVf_POK|SVp_POK))
 
-#define SvVOK(sv)              (SvMAGICAL(sv) && mg_find(sv,'V'))
+#define SvVOK(sv)              (SvMAGICAL(sv)                          \
+                                ? mg_find(sv,PERL_MAGIC_vstring) : NULL)
 #define SvOOK(sv)              (SvFLAGS(sv) & SVf_OOK)
 #define SvOOK_on(sv)           ((void)SvIOK_off(sv), SvFLAGS(sv) |= SVf_OOK)
 #define SvOOK_off(sv)          ((void)(SvOOK(sv) && sv_backoff(sv)))
@@ -840,7 +922,7 @@ in gv.h: */
 #define SvREADONLY_on(sv)      (SvFLAGS(sv) |= SVf_READONLY)
 #define SvREADONLY_off(sv)     (SvFLAGS(sv) &= ~SVf_READONLY)
 
-#define SvSCREAM(sv)           (SvFLAGS(sv) & SVp_SCREAM)
+#define SvSCREAM(sv) ((SvFLAGS(sv) & (SVp_SCREAM|SVp_POK)) == (SVp_SCREAM|SVp_POK))
 #define SvSCREAM_on(sv)                (SvFLAGS(sv) |= SVp_SCREAM)
 #define SvSCREAM_off(sv)       (SvFLAGS(sv) &= ~SVp_SCREAM)
 
@@ -868,6 +950,22 @@ in gv.h: */
 #define SvREPADTMP_off(sv)     (SvFLAGS(sv) &= ~SVf_FAKE)
 #endif
 
+#define SvPAD_TYPED(sv) \
+       ((SvFLAGS(sv) & (SVpad_NAME|SVpad_TYPED)) == (SVpad_NAME|SVpad_TYPED))
+#define SvPAD_TYPED_on(sv)     (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED)
+
+#define SvPAD_OUR(sv)  \
+       ((SvFLAGS(sv) & (SVpad_NAME|SVpad_OUR)) == (SVpad_NAME|SVpad_OUR))
+#define SvPAD_OUR_on(sv)       (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR)
+
+#define OURSTASH(sv)   \
+       (SvPAD_OUR(sv) ? ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash : NULL)
+#define OURSTASH_set(sv, st)                                   \
+        STMT_START {                                           \
+           assert(SvTYPE(sv) == SVt_PVMG);                     \
+           ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash = st;      \
+       } STMT_END
+
 #ifdef PERL_DEBUG_COW
 #define SvRV(sv) (0 + (sv)->sv_u.svu_rv)
 #else
@@ -876,47 +974,89 @@ in gv.h: */
 #define SvRVx(sv) SvRV(sv)
 
 #ifdef PERL_DEBUG_COW
-#define SvIVX(sv) (0 + ((XPVIV*) SvANY(sv))->xiv_iv)
-#define SvUVX(sv) (0 + ((XPVUV*) SvANY(sv))->xuv_uv)
-#define SvNVX(sv) (0 + ((XPVNV*) SvANY(sv))->xnv_nv)
-#define SvPVX(sv) (0 + (sv)->sv_u.svu_pv)
-#define SvCUR(sv) (0 + ((XPV*) SvANY(sv))->xpv_cur)
-#define SvLEN(sv) (0 + ((XPV*) SvANY(sv))->xpv_len)
-#define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
-
-#ifdef DEBUGGING
-#  ifdef PERL_IN_SV_C
-/* Can't make this RVALUE because of Perl_sv_unmagic.  */
-#    define SvMAGIC(sv)        (*(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_magic))
+/* Need -0.0 for SvNVX to preserve IEEE FP "negative zero" because
+   +0.0 + -0.0 => +0.0 but -0.0 + -0.0 => -0.0 */
+#  define SvIVX(sv) (0 + ((XPVIV*) SvANY(sv))->xiv_iv)
+#  define SvUVX(sv) (0 + ((XPVUV*) SvANY(sv))->xuv_uv)
+#  define SvNVX(sv) (-0.0 + ((XPVNV*) SvANY(sv))->xnv_nv)
+/* 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))
 #  else
-#    define SvMAGIC(sv)        (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_magic))
+#  define SvPVX(sv) SvPVX_mutable(sv)
 #  endif
-#define SvSTASH(sv)    (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_stash))
-#else
-#  ifdef PERL_IN_SV_C
-#    define SvMAGIC(sv) ((XPVMG*)  SvANY(sv))->xmg_magic
+#  define SvCUR(sv) (0 + ((XPV*) SvANY(sv))->xpv_cur)
+#  define SvLEN(sv) (0 + ((XPV*) SvANY(sv))->xpv_len)
+#  define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
+
+#  ifdef DEBUGGING
+#    define SvMAGIC(sv)        (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic))
+#    define SvSTASH(sv)        (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_stash))
 #  else
-#    define SvMAGIC(sv) (0 + ((XPVMG*)  SvANY(sv))->xmg_magic)
+#    define SvMAGIC(sv)        (0 + ((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic)
+#    define SvSTASH(sv)        (0 + ((XPVMG*)  SvANY(sv))->xmg_stash)
 #  endif
-#define SvSTASH(sv)     (0 + ((XPVMG*)  SvANY(sv))->xmg_stash)
-#endif
-#else
-#define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv
-#define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
-#define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_nv
-#define SvPVX(sv) ((sv)->sv_u.svu_pv)
-#define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur
-#define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len
-#define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
-
-#ifdef DEBUGGING
-#define SvMAGIC(sv)    (*(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_magic))
-#define SvSTASH(sv)    (*(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*)  SvANY(sv))->xmg_stash))
 #else
-#define SvMAGIC(sv)    ((XPVMG*)  SvANY(sv))->xmg_magic
-#define SvSTASH(sv)    ((XPVMG*)  SvANY(sv))->xmg_stash
+#  define SvPVX(sv) ((sv)->sv_u.svu_pv)
+#  define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur
+#  define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len
+#  define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
+
+#  if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+/* These get expanded inside other macros that already use a variable _sv  */
+#    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);                           \
+           &(((XPVIV*) SvANY(_svi))->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);                           \
+           &(((XPVUV*) SvANY(_svi))->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_PVFM);                           \
+          &(((XPVNV*) SvANY(_svi))->xnv_nv);                           \
+        }))
+#    define SvMAGIC(sv)                                                        \
+       (*({ SV *const _svi = (SV *) sv;                                \
+           assert(SvTYPE(_svi) >= SVt_PVMG);                           \
+           &(((XPVMG*) SvANY(_svi))->xmg_u.xmg_magic);                 \
+         }))
+#    define SvSTASH(sv)                                                        \
+       (*({ SV *const _svi = (SV *) sv;                                \
+           assert(SvTYPE(_svi) >= SVt_PVMG);                           \
+           &(((XPVMG*) SvANY(_svi))->xmg_stash);                       \
+         }))
+#  else
+#    define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv
+#    define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
+#    define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_nv
+#    define SvMAGIC(sv)        ((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic
+#    define SvSTASH(sv)        ((XPVMG*)  SvANY(sv))->xmg_stash
+#  endif
 #endif
 
+#ifndef PERL_POISON
+/* Given that these two are new, there can't be any existing code using them
+ *  as LVALUEs  */
+#  define SvPVX_mutable(sv)    (0 + (sv)->sv_u.svu_pv)
+#  define SvPVX_const(sv)      ((const char*)(0 + (sv)->sv_u.svu_pv))
+#else
+/* Except for the poison code, which uses & to scribble over the pointer after
+   free() is called.  */
+#  define SvPVX_mutable(sv)    ((sv)->sv_u.svu_pv)
+#  define SvPVX_const(sv)      ((const char*)((sv)->sv_u.svu_pv))
 #endif
 
 #define SvIVXx(sv) SvIVX(sv)
@@ -938,6 +1078,7 @@ in gv.h: */
                (((XPVIV*)  SvANY(sv))->xiv_iv = (val)); } STMT_END
 #define SvNV_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) == SVt_NV || SvTYPE(sv) >= SVt_PVNV); \
+           assert(SvTYPE(sv) != SVt_PVAV); assert(SvTYPE(sv) != SVt_PVHV); \
                (((XPVNV*)SvANY(sv))->xnv_nv = (val)); } STMT_END
 #define SvPV_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
@@ -950,7 +1091,7 @@ in gv.h: */
                 ((sv)->sv_u.svu_rv = (val)); } STMT_END
 #define SvMAGIC_set(sv, val) \
         STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
-                (((XPVMG*)SvANY(sv))->xmg_magic = (val)); } STMT_END
+                (((XPVMG*)SvANY(sv))->xmg_u.xmg_magic = (val)); } STMT_END
 #define SvSTASH_set(sv, val) \
         STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
                 (((XPVMG*)  SvANY(sv))->xmg_stash = (val)); } STMT_END
@@ -976,19 +1117,17 @@ in gv.h: */
                   SvPV_renew(sv, _lEnGtH); \
                 } STMT_END
 
-#define SvPV_free(sv) \
-       STMT_START { assert(SvTYPE(sv) >= SVt_PV);      \
-               if (SvLEN(sv)) {                        \
-                   if(SvOOK(sv)) {                     \
-                     Safefree(SvPVX(sv) - SvIVX(sv));  \
-                     SvFLAGS(sv) &= ~SVf_OOK;          \
-                   } else {                            \
-                     Safefree(SvPVX(sv));              \
-                   }                                   \
-               }                                       \
-       } STMT_END
-
-#define SvPVX_const(sv)        ((const char*)SvPVX(sv))
+#define SvPV_free(sv)                                                  \
+    STMT_START {                                                       \
+                    assert(SvTYPE(sv) >= SVt_PV);                      \
+                    if (SvLEN(sv)) {                                   \
+                        if(SvOOK(sv)) {                                \
+                            SvPV_set(sv, SvPVX_mutable(sv) - SvIVX(sv)); \
+                            SvFLAGS(sv) &= ~SVf_OOK;                   \
+                        }                                              \
+                        Safefree(SvPVX(sv));                           \
+                    }                                                  \
+                } STMT_END
 
 #define BmRARE(sv)     ((XPVBM*)  SvANY(sv))->xbm_rare
 #define BmUSEFUL(sv)   ((XPVBM*)  SvANY(sv))->xbm_useful
@@ -1053,6 +1192,8 @@ Taints an SV if tainting is enabled.
 =cut
 */
 
+#define sv_taint(sv)     sv_magic((sv), NULL, PERL_MAGIC_taint, NULL, 0)
+
 #define SvTAINTED(sv)    (SvMAGICAL(sv) && sv_tainted(sv))
 #define SvTAINTED_on(sv)  STMT_START{ if(PL_tainting){sv_taint(sv);}   }STMT_END
 #define SvTAINTED_off(sv) STMT_START{ if(PL_tainting){sv_untaint(sv);} }STMT_END
@@ -1197,24 +1338,54 @@ Like C<sv_catsv> but doesn't process magic.
 /* ----*/
 
 #define SvPV(sv, lp) SvPV_flags(sv, lp, SV_GMAGIC)
+#define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC)
+#define SvPV_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC)
 
 #define SvPV_flags(sv, lp, flags) \
     ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags))
+#define SvPV_flags_const(sv, lp, flags) \
+    ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+     ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \
+     (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN))
+#define SvPV_flags_const_nolen(sv, flags) \
+    ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+     ? SvPVX_const(sv) : \
+     (const char*) sv_2pv_flags(sv, 0, flags|SV_CONST_RETURN))
+#define SvPV_flags_mutable(sv, lp, flags) \
+    ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+     ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \
+     sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
 
 #define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC)
+#define SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC)
+#define SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC)
 
 #define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0)
+#define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0)
 
 #define SvPV_force_flags(sv, lp, flags) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags))
+#define SvPV_force_flags_nolen(sv, flags) \
+    ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
+    ? SvPVX(sv) : sv_pvn_force_flags(sv, 0, flags))
+#define SvPV_force_flags_mutable(sv, lp, flags) \
+    ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
+    ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \
+     : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
 
 #define SvPV_nolen(sv) \
     ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
-     ? SvPVX(sv) : sv_2pv_nolen(sv))
+     ? SvPVX(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC))
+
+#define SvPV_nolen_const(sv) \
+    ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+     ? SvPVX_const(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC|SV_CONST_RETURN))
 
 #define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0)
+#define SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0)
+#define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0)
 
 /* ----*/
 
@@ -1229,7 +1400,7 @@ Like C<sv_catsv> but doesn't process magic.
 
 #define SvPVutf8_nolen(sv) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8)\
-     ? SvPVX(sv) : sv_2pvutf8_nolen(sv))
+     ? SvPVX(sv) : sv_2pvutf8(sv, 0))
 
 /* ----*/
 
@@ -1243,7 +1414,7 @@ Like C<sv_catsv> but doesn't process magic.
 
 #define SvPVbyte_nolen(sv) \
     ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK)\
-     ? SvPVX(sv) : sv_2pvbyte_nolen(sv))
+     ? SvPVX(sv) : sv_2pvbyte(sv, 0))
 
 
     
@@ -1262,8 +1433,12 @@ Like C<sv_catsv> but doesn't process magic.
 #  define SvUVx(sv) ({SV *_sv = (SV*)(sv); SvUV(_sv); })
 #  define SvNVx(sv) ({SV *_sv = (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); })
+#  define SvPVx_nolen_const(sv) ({SV *_sv = (sv); SvPV_nolen_const(_sv); })
 #  define SvPVutf8x(sv, lp) ({SV *_sv = (sv); SvPVutf8(_sv, lp); })
 #  define SvPVbytex(sv, lp) ({SV *_sv = (sv); SvPVbyte(_sv, lp); })
+#  define SvPVbytex_nolen(sv) ({SV *_sv = (sv); SvPVbyte_nolen(_sv); })
 #  define SvTRUE(sv) (                                         \
     !sv                                                                \
     ? 0                                                                \
@@ -1291,8 +1466,12 @@ Like C<sv_catsv> but doesn't process magic.
 #  define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv))
 #  define SvNVx(sv) ((PL_Sv = (sv)), SvNV(PL_Sv))
 #  define SvPVx(sv, lp) ((PL_Sv = (sv)), SvPV(PL_Sv, lp))
+#  define SvPVx_const(sv, lp) ((PL_Sv = (sv)), SvPV_const(PL_Sv, lp))
+#  define SvPVx_nolen(sv) ((PL_Sv = (sv)), SvPV_nolen(PL_Sv))
+#  define SvPVx_nolen_const(sv) ((PL_Sv = (sv)), SvPV_nolen_const(PL_Sv))
 #  define SvPVutf8x(sv, lp) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, lp))
 #  define SvPVbytex(sv, lp) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, lp))
+#  define SvPVbytex_nolen(sv) ((PL_Sv = (sv)), SvPVbyte_nolen(PL_Sv))
 #  define SvTRUE(sv) (                                         \
     !sv                                                                \
     ? 0                                                                \
@@ -1315,12 +1494,22 @@ Like C<sv_catsv> but doesn't process magic.
                                    (SVf_FAKE | SVf_READONLY))
 #define SvIsCOW_shared_hash(sv)        (SvIsCOW(sv) && SvLEN(sv) == 0)
 
+#define SvSHARED_HEK_FROM_PV(pvx) \
+       ((struct hek*)(pvx - STRUCT_OFFSET(struct hek, hek_key)))
+#define SvSHARED_HASH(sv) (0 + SvSHARED_HEK_FROM_PV(SvPVX_const(sv))->hek_hash)
+
 /* flag values for sv_*_flags functions */
 #define SV_IMMEDIATE_UNREF     1
 #define SV_GMAGIC              2
 #define SV_COW_DROP_PV         4
 #define SV_UTF8_NO_ENCODING    8
 #define SV_NOSTEAL             16
+#define SV_CONST_RETURN                32
+#define SV_MUTABLE_RETURN      64
+#define SV_SMAGIC              128
+
+#define sv_unref(sv)           sv_unref_flags(sv, 0)
+#define sv_force_normal(sv)    sv_force_normal_flags(sv, 0)
 
 /* We are about to replace the SV's current value. So if it's copy on write
    we need to normalise it. Use the SV_COW_DROP_PV flag hint to say that
@@ -1331,20 +1520,19 @@ Like C<sv_catsv> but doesn't process magic.
 #define SV_CHECK_THINKFIRST_COW_DROP(sv) if (SvTHINKFIRST(sv)) \
                                    sv_force_normal_flags(sv, SV_COW_DROP_PV)
 
-#ifdef PERL_COPY_ON_WRITE
+#ifdef PERL_OLD_COPY_ON_WRITE
 #  define SvRELEASE_IVX(sv)   ((void)((SvFLAGS(sv) & (SVf_OOK|SVf_READONLY|SVf_FAKE)) \
                                && Perl_sv_release_IVX(aTHX_ sv)))
 #  define SvIsCOW_normal(sv)   (SvIsCOW(sv) && SvLEN(sv))
+#else
+#  define SvRELEASE_IVX(sv)   SvOOK_off(sv)
+#endif /* PERL_OLD_COPY_ON_WRITE */
 
 #define CAN_COW_MASK   (SVs_OBJECT|SVs_GMG|SVs_SMG|SVs_RMG|SVf_IOK|SVf_NOK| \
                         SVf_POK|SVf_ROK|SVp_IOK|SVp_NOK|SVp_POK|SVf_FAKE| \
                         SVf_OOK|SVf_BREAK|SVf_READONLY|SVf_AMAGIC)
 #define CAN_COW_FLAGS  (SVp_POK|SVf_POK)
 
-#else
-#  define SvRELEASE_IVX(sv)   SvOOK_off(sv)
-#endif /* PERL_COPY_ON_WRITE */
-
 #define SV_CHECK_THINKFIRST(sv) if (SvTHINKFIRST(sv)) \
                                    sv_force_normal_flags(sv, 0)
 
@@ -1362,8 +1550,14 @@ Like C<sv_catsv> but doesn't process magic.
 #define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, 0)
 #define sv_catsv(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC)
 #define sv_catsv_nomg(dsv, ssv) sv_catsv_flags(dsv, ssv, 0)
+#define sv_catsv_mg(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC|SV_SMAGIC)
 #define sv_catpvn(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, SV_GMAGIC)
+#define sv_catpvn_mg(sv, sstr, slen) \
+       sv_catpvn_flags(sv, sstr, slen, SV_GMAGIC|SV_SMAGIC);
 #define sv_2pv(sv, lp) sv_2pv_flags(sv, lp, SV_GMAGIC)
+#define sv_2pv_nolen(sv) sv_2pv(sv, 0)
+#define sv_2pvbyte_nolen(sv) sv_2pvbyte(sv, 0)
+#define sv_2pvutf8_nolen(sv) sv_2pvutf8(sv, 0)
 #define sv_2pv_nomg(sv, lp) sv_2pv_flags(sv, lp, 0)
 #define sv_pvn_force(sv, lp) sv_pvn_force_flags(sv, lp, SV_GMAGIC)
 #define sv_utf8_upgrade(sv) sv_utf8_upgrade_flags(sv, SV_GMAGIC)
@@ -1489,6 +1683,8 @@ Returns a pointer to the character buffer.
 #define isGV(sv) (SvTYPE(sv) == SVt_PVGV)
 
 #define SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv))
+#define SvGROW_mutable(sv,len) \
+    (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX_mutable(sv))
 #define Sv_Grow sv_grow
 
 #define CLONEf_COPY_STACKS 1