This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
In struct regexp move the member paren_names to the IV union.
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index 4d7ad36..ea5e0ae 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, by Larry Wall and others
+ *    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 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.
@@ -45,14 +45,16 @@ Type flag for code refs.  See C<svtype>.
 
 typedef enum {
        SVt_NULL,       /* 0 */
-       SVt_IV,         /* 1 */
-       SVt_NV,         /* 2 */
-       SVt_RV,         /* 3 */
+       SVt_BIND,       /* 1 */
+       SVt_IV,         /* 2 */
+       SVt_NV,         /* 3 */
+       /* RV was here, before it was merged with IV.  */
        SVt_PV,         /* 4 */
        SVt_PVIV,       /* 5 */
        SVt_PVNV,       /* 6 */
        SVt_PVMG,       /* 7 */
-       SVt_PVBM,       /* 8 */
+       SVt_REGEXP,     /* 8 */
+       /* PVBM was here, before BIND replaced it.  */
        SVt_PVGV,       /* 9 */
        SVt_PVLV,       /* 10 */
        SVt_PVAV,       /* 11 */
@@ -63,6 +65,16 @@ typedef enum {
        SVt_LAST        /* keep last in enum. used to size arrays */
 } svtype;
 
+#ifndef PERL_CORE
+/* Although Fast Boyer Moore tables are now being stored in PVGVs, for most
+   purposes eternal code wanting to consider PVBM probably needs to think of
+   PVMG instead.  */
+#  define SVt_PVBM     SVt_PVMG
+/* Anything wanting to create a reference from clean should ensure that it has
+   a scalar of type SVt_IV now:  */
+#  define SVt_RV       SVt_IV
+#endif
+
 /* 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
@@ -169,9 +181,8 @@ to return a meaningful value, or check for NULLness, so it's smaller
 and faster.
 
 =for apidoc Am|SV*|SvREFCNT_inc_simple|SV* sv
-Same as SvREFCNT_inc, but can only be used with simple variables, not
-expressions or pointer dereferences.  Since we don't have to store a
-temporary value, it's faster.
+Same as SvREFCNT_inc, but can only be used with expressions without side
+effects.  Since we don't have to store a temporary value, it's faster.
 
 =for apidoc Am|SV*|SvREFCNT_inc_simple_NN|SV* sv
 Same as SvREFCNT_inc_simple, but can only be used if you know I<sv>
@@ -266,7 +277,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #endif
 
 #define SVTYPEMASK     0xff
-#define SvTYPE(sv)     (svtype)((sv)->sv_flags & SVTYPEMASK)
+#define SvTYPE(sv)     ((svtype)((sv)->sv_flags & SVTYPEMASK))
 
 /* 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
@@ -275,52 +286,56 @@ perform the upgrade if necessary.  See C<svtype>.
 
 #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 SVpad_STATE    0x00010000      /* pad name is a "state" var */
-#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 SVphv_REHASH   SVf_FAKE        /* 6: On a PVHV, hash values are being
-                                             recalculated */
-#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   0x08000000      /* may not be modified */
+#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        SVp_SCREAM  /* PVHV (stashes) clone its objects */
+#define SVpgv_GP       SVp_SCREAM  /* GV has a valid GP */
+#define SVprv_PCS_IMPORTED  SVp_SCREAM  /* RV is a proxy for a constant
+                                      subroutine in another package. Set the
+                                      CvIMPORTED_CV_ON() if it needs to be
+                                      expanded to a real GV */
+
+#define SVs_PADSTALE   0x00010000  /* lexical has gone out of scope */
+#define SVpad_STATE    0x00010000  /* pad name is a "state" var */
+#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 SVphv_REHASH   SVf_FAKE    /* 6: On a PVHV, hash values are being
+                                         recalculated */
+#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   0x08000000  /* may not be modified */
 
 
 
@@ -328,173 +343,138 @@ perform the upgrade if necessary.  See C<svtype>.
 #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_SCREAM)
+                        SVp_IOK|SVp_NOK|SVp_POK|SVpgv_GP)
 
 #define PRIVSHIFT 4    /* (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 */
+#define SVf_AMAGIC     0x10000000  /* has magical overloaded methods */
+
+/* Ensure this value does not clash with the GV_ADD* flags in gv.h: */
+#define SVf_UTF8        0x20000000  /* SvPV is UTF-8 encoded
+                                      This is also set on RVs whose overloaded
+                                      stringification is UTF-8. This might
+                                      only happen as a side effect of SvPV() */
+                                          
 
 /* Some private flags. */
 
+/* PVAV could probably use 0x2000000 without conflict. I assume that PVFM can
+   be UTF-8 encoded, and PVCVs could well have UTF-8 prototypes. PVIOs haven't
+   been restructured, so sometimes get used as string buffers.  */
+
 /* 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, SVpad_OUR and
-                                          SVpad_STATE apply */
+#define SVphv_SHAREKEYS 0x20000000  /* PVHV keys live on shared string table */
+/* PVNV, PVMG, presumably only inside pads */
+#define SVpad_NAME     0x40000000  /* This SV is a name in the PAD, so
+                                      SVpad_TYPED, SVpad_OUR and SVpad_STATE
+                                      apply */
 /* PVAV */
-#define SVpav_REAL     0x40000000      /* free old entries */
+#define SVpav_REAL     0x40000000  /* free old entries */
 /* PVHV */
-#define SVphv_LAZYDEL  0x40000000      /* entry in xhv_eiter must be deleted */
-/* Not just PVBM - basically anything that can be a regular scalar */
+#define SVphv_LAZYDEL  0x40000000  /* entry in xhv_eiter must be deleted */
+/* This is only set true on a PVGV when it's playing "PVBM", but is tested for
+   on any regular scalar (anything <= PVLV) */
 #define SVpbm_VALID    0x40000000
 /* ??? */
-#define SVrepl_EVAL    0x40000000      /* Replacement part of s///e */
+#define SVrepl_EVAL    0x40000000  /* Replacement part of s///e */
 
 /* 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 */
+#define SVf_IVisUV     0x80000000  /* use XPVUV instead of XPVIV */
 /* PVAV */
-#define SVpav_REIFY    0x80000000      /* can become real */
+#define SVpav_REIFY    0x80000000  /* can become real */
 /* PVHV */
-#define SVphv_HASKFLAGS        0x80000000      /* keys have flag byte after hash */
+#define SVphv_HASKFLAGS        0x80000000  /* keys have flag byte after hash */
 /* PVFM */
-#define SVpfm_COMPILED 0x80000000      /* FORMLINE is compiled */
-/* PVBM */
+#define SVpfm_COMPILED 0x80000000  /* FORMLINE is compiled */
+/* PVGV when SVpbm_VALID is true */
 #define SVpbm_TAIL     0x80000000
 /* RV upwards. However, SVf_ROK and SVp_IOK are exclusive  */
-#define SVprv_WEAKREF   0x80000000      /* Weak reference */
+#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
+
+union _xnvu {
+    NV     xnv_nv;             /* numeric value, if any */
+    HV *    xgv_stash;
+    struct {
+       U32 xlow;
+       U32 xhigh;
+    }      xpad_cop_seq;       /* used by pad.c for cop_sequence */
+    struct {
+       U32 xbm_previous;       /* how many characters in string before rare? */
+       U8  xbm_flags;
+       U8  xbm_rare;           /* rarest character in string */
+    }      xbm_s;              /* fields from PVBM */
+};
+
+union _xivu {
+    IV     xivu_iv;            /* integer value */
+                               /* xpvfm: pv offset */
+    UV     xivu_uv;
+    void *  xivu_p1;
+    I32            xivu_i32;
+    HEK *   xivu_namehek;      /* xpvlv, xpvgv: GvNAME */
+    HV *    xivu_hv;           /* regexp: paren_names */
+};
 
+union _xmgu {
+    MAGIC*  xmg_magic;         /* linked list of magicalness */
+    HV*            xmg_ourstash;       /* Stash for our (when SvPAD_OUR is true) */
+};
 
 struct xpv {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
+    _XPV_HEAD;
 };
 
-#if 0
-typedef struct xpv xpv_allocated;
-#else
 typedef struct {
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
+    _XPV_ALLOCATED_HEAD;
 } xpv_allocated;
-#endif
 
 struct xpviv {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-    }          xnv_u;
-    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;
-       HEK *   xivu_namehek;
-    }          xiv_u;
+    _XPV_HEAD;
+    union _xivu 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;
-       HEK *   xivu_namehek;
-    }          xiv_u;
+    _XPV_ALLOCATED_HEAD;
+    union _xivu xiv_u;
 } xpviv_allocated;
-#endif
 
 #define xiv_iv xiv_u.xivu_iv
 
 struct xpvuv {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-    }          xnv_u;
-    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;
-       HEK *   xivu_namehek;
-    }          xuv_u;
+    _XPV_HEAD;
+    union _xivu xuv_u;
 };
 
-#define xuv_uv xuv_u.xuvu_uv
+#define xuv_uv xuv_u.xivu_uv
 
 struct xpvnv {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-    }          xnv_u;
-    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;
-       HEK *   xivu_namehek;
-    }          xiv_u;
+    _XPV_HEAD;
+    union _xivu xiv_u;
 };
 
+#define _XPVMG_HEAD                                \
+    union _xivu xiv_u;                             \
+    union _xmgu        xmg_u;                              \
+    HV*                xmg_stash       /* class package */
+
 /* These structure must match the beginning of struct xpvhv in hv.h. */
 struct xpvmg {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-    }          xnv_u;
-    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;
-       HEK *   xivu_namehek;
-    }          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 */
+    _XPV_HEAD;
+    _XPVMG_HEAD;
 };
 
 struct xpvlv {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-    }          xnv_u;
-    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;
-       HEK *   xivu_namehek;   /* GvNAME */
-    }          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 */
+    _XPV_HEAD;
+    _XPVMG_HEAD;
 
     STRLEN     xlv_targoff;
     STRLEN     xlv_targlen;
@@ -503,151 +483,53 @@ struct xpvlv {
                                 * y=alem/helem/iter t=tie T=tied HE */
 };
 
+/* This structure works in 3 ways - regular scalar, GV with GP, or fast
+   Boyer-Moore.  */
 struct xpvgv {
-    union {
-       NV      xnv_nv;
-       HV *    xgv_stash;      /* The stash of this GV */
-    }          xnv_u;
-    STRLEN     xpv_cur;        /* xgv_flags */
-    STRLEN     xpv_len;        /* 0 */
-    union {
-       IV      xivu_iv;
-       UV      xivu_uv;
-       void *  xivu_p1;
-       I32     xivu_i32;
-       HEK *   xivu_namehek;   /* GvNAME */
-    }          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 xpvbm {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-    }          xnv_u;
-    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;       /* is this constant pattern being useful? */
-       HEK *   xivu_namehek;
-    }          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 */
-
-    U16                xbm_previous;   /* how many characters in string before rare? */
-    U8         xbm_rare;       /* rarest character in string */
+    _XPV_HEAD;
+    _XPVMG_HEAD;
 };
 
 /* This structure must match XPVCV in cv.h */
 
 typedef U16 cv_flags_t;
 
-struct xpvfm {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-    }          xnv_u;
-    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;
-       HEK *   xivu_namehek;
-    }          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 */
+#define _XPVCV_COMMON                                                          \
+    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
 
-    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;
+struct xpvfm {
+    _XPV_HEAD;
+    _XPVMG_HEAD;
+    _XPVCV_COMMON;
     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;
-       HEK *   xivu_namehek;
-    }          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;
+    _XPV_ALLOCATED_HEAD;
+    _XPVMG_HEAD;
+    _XPVCV_COMMON;
     IV         xfm_lines;
 } xpvfm_allocated;
 
 struct xpvio {
-    union {
-       NV      xnv_nv;         /* numeric value, if any */
-       HV *    xgv_stash;
-    }          xnv_u;
-    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;
-       HEK *   xivu_namehek;
-    }          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 */
+    _XPV_HEAD;
+    _XPVMG_HEAD;
 
     PerlIO *   xio_ifp;        /* ifp and ofp are normally the same */
     PerlIO *   xio_ofp;        /* but sockets need separate streams */
@@ -674,9 +556,8 @@ struct xpvio {
     GV *       xio_fmt_gv;     /* $~ */
     char *     xio_bottom_name;/* $^B */
     GV *       xio_bottom_gv;  /* $^B */
-    short      xio_subprocess; /* -| or |- */
     char       xio_type;
-    char       xio_flags;
+    U8         xio_flags;
 };
 #define xio_dirp       xio_dirpu.xiou_dirp
 #define xio_any                xio_dirpu.xiou_any
@@ -692,35 +573,35 @@ struct xpvio {
 /* The following macros define implementation-independent predicates on SVs. */
 
 /*
-=for apidoc Am|bool|SvNIOK|SV* sv
-Returns a boolean indicating whether the SV contains a number, integer or
+=for apidoc Am|U32|SvNIOK|SV* sv
+Returns a U32 value indicating whether the SV contains a number, integer or
 double.
 
-=for apidoc Am|bool|SvNIOKp|SV* sv
-Returns a boolean indicating whether the SV contains a number, integer or
+=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>.
 
 =for apidoc Am|void|SvNIOK_off|SV* sv
 Unsets the NV/IV status of an SV.
 
-=for apidoc Am|bool|SvOK|SV* sv
-Returns a boolean indicating whether the value is an SV. It also tells
+=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.
 
-=for apidoc Am|bool|SvIOKp|SV* sv
-Returns a boolean indicating whether the SV contains an integer.  Checks
+=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>.
 
-=for apidoc Am|bool|SvNOKp|SV* sv
-Returns a boolean indicating whether the SV contains a double.  Checks the
+=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>.
 
-=for apidoc Am|bool|SvPOKp|SV* sv
-Returns a boolean indicating whether the SV contains a character string.
+=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>.
 
-=for apidoc Am|bool|SvIOK|SV* sv
-Returns a boolean indicating whether the SV contains an integer.
+=for apidoc Am|U32|SvIOK|SV* sv
+Returns a U32 value indicating whether the SV contains an integer.
 
 =for apidoc Am|void|SvIOK_on|SV* sv
 Tells an SV that it is an integer.
@@ -737,14 +618,14 @@ Tells and SV that it is an unsigned integer and disables all other OK bits.
 =for apidoc Am|bool|SvIOK_UV|SV* sv
 Returns a boolean indicating whether the SV contains an unsigned integer.
 
-=for apidoc Am|void|SvUOK|SV* sv
+=for apidoc Am|bool|SvUOK|SV* sv
 Returns a boolean indicating whether the SV contains an unsigned integer.
 
 =for apidoc Am|bool|SvIOK_notUV|SV* sv
 Returns a boolean indicating whether the SV contains a signed integer.
 
-=for apidoc Am|bool|SvNOK|SV* sv
-Returns a boolean indicating whether the SV contains a double.
+=for apidoc Am|U32|SvNOK|SV* sv
+Returns a U32 value indicating whether the SV contains a double.
 
 =for apidoc Am|void|SvNOK_on|SV* sv
 Tells an SV that it is a double.
@@ -755,8 +636,8 @@ Unsets the NV status of an SV.
 =for apidoc Am|void|SvNOK_only|SV* sv
 Tells an SV that it is a double and disables all other OK bits.
 
-=for apidoc Am|bool|SvPOK|SV* sv
-Returns a boolean indicating whether the SV contains a character
+=for apidoc Am|U32|SvPOK|SV* sv
+Returns a U32 value indicating whether the SV contains a character
 string.
 
 =for apidoc Am|void|SvPOK_on|SV* sv
@@ -772,13 +653,15 @@ Will also turn off the UTF-8 status.
 =for apidoc Am|bool|SvVOK|SV* sv
 Returns a boolean indicating whether the SV contains a v-string.
 
-=for apidoc Am|bool|SvOOK|SV* sv
-Returns a boolean indicating whether the SvIVX is a valid offset value for
-the SvPVX.  This hack is used internally to speed up removal of characters
-from the beginning of a SvPV.  When SvOOK is true, then the start of the
-allocated string buffer is really (SvPVX - SvIVX).
+=for apidoc Am|U32|SvOOK|SV* sv
+Returns a U32 indicating whether the pointer to the string buffer is offset.
+This hack is used internally to speed up removal of characters from the
+beginning of a SvPV.  When SvOOK is true, then the start of the
+allocated string buffer is actually C<SvOOK_offset()> bytes before SvPVX.
+This offset used to be stored in SvIVX, but is now stored within the spare
+part of the buffer.
 
-=for apidoc Am|bool|SvROK|SV* sv
+=for apidoc Am|U32|SvROK|SV* sv
 Tests if the SV is an RV.
 
 =for apidoc Am|void|SvROK_on|SV* sv
@@ -867,7 +750,9 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
 #define assert_not_glob(sv)    
 #endif
 
-#define SvOK(sv)               (SvFLAGS(sv) & SVf_OK)
+#define SvOK(sv)               ((SvTYPE(sv) == SVt_BIND)               \
+                                ? (SvFLAGS(SvRV(sv)) & SVf_OK)         \
+                                : (SvFLAGS(sv) & SVf_OK))
 #define SvOK_off(sv)           (assert_not_ROK(sv) assert_not_glob(sv) \
                                 SvFLAGS(sv) &= ~(SVf_OK|               \
                                                  SVf_IVisUV|SVf_UTF8), \
@@ -879,7 +764,7 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
 
 #define SvOKp(sv)              (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK))
 #define SvIOKp(sv)             (SvFLAGS(sv) & SVp_IOK)
-#define SvIOKp_on(sv)          (assert_not_glob(sv) SvRELEASE_IVX(sv), \
+#define SvIOKp_on(sv)          (assert_not_glob(sv) SvRELEASE_IVX_(sv) \
                                    SvFLAGS(sv) |= SVp_IOK)
 #define SvNOKp(sv)             (SvFLAGS(sv) & SVp_NOK)
 #define SvNOKp_on(sv)          (assert_not_glob(sv) SvFLAGS(sv) |= SVp_NOK)
@@ -888,7 +773,7 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
                                 SvFLAGS(sv) |= SVp_POK)
 
 #define SvIOK(sv)              (SvFLAGS(sv) & SVf_IOK)
-#define SvIOK_on(sv)           (assert_not_glob(sv) SvRELEASE_IVX(sv), \
+#define SvIOK_on(sv)           (assert_not_glob(sv) SvRELEASE_IVX_(sv) \
                                    SvFLAGS(sv) |= (SVf_IOK|SVp_IOK))
 #define SvIOK_off(sv)          (SvFLAGS(sv) &= ~(SVf_IOK|SVp_IOK|SVf_IVisUV))
 #define SvIOK_only(sv)         (SvOK_off(sv), \
@@ -914,8 +799,10 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
                                    SvFLAGS(sv) |= (SVf_NOK|SVp_NOK))
 
 /*
-=for apidoc Am|bool|SvUTF8|SV* sv
-Returns a boolean indicating whether the SV contains UTF-8 encoded data.
+=for apidoc Am|U32|SvUTF8|SV* sv
+Returns a U32 value indicating whether the SV contains UTF-8 encoded data.
+Call this after SvPV() in case any call to string overloading updates the
+internal flag.
 
 =for apidoc Am|void|SvUTF8_on|SV *sv
 Turn on the UTF-8 status of an SV (the data is not changed, just the flag).
@@ -1021,6 +908,11 @@ the scalar's value cannot change unless written to.
 #define SvWEAKREF_on(sv)       (SvFLAGS(sv) |=  (SVf_ROK|SVprv_WEAKREF))
 #define SvWEAKREF_off(sv)      (SvFLAGS(sv) &= ~(SVf_ROK|SVprv_WEAKREF))
 
+#define SvPCS_IMPORTED(sv)     ((SvFLAGS(sv) & (SVf_ROK|SVprv_PCS_IMPORTED)) \
+                                == (SVf_ROK|SVprv_PCS_IMPORTED))
+#define SvPCS_IMPORTED_on(sv)  (SvFLAGS(sv) |=  (SVf_ROK|SVprv_PCS_IMPORTED))
+#define SvPCS_IMPORTED_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVprv_PCS_IMPORTED))
+
 #define SvTHINKFIRST(sv)       (SvFLAGS(sv) & SVf_THINKFIRST)
 
 #define SvPADSTALE(sv)         (SvFLAGS(sv) & SVs_PADSTALE)
@@ -1059,6 +951,20 @@ 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_on(sv)       ({ SV *const thwacke = (SV *) (sv);     \
+                                  assert(!isGV_with_GP(thwacke));      \
+                                  (SvFLAGS(thwacke) |= SVpbm_VALID);   \
+                               })
+#  define SvVALID_off(sv)      ({ SV *const thwacke = (SV *) (sv);     \
+                                  assert(!isGV_with_GP(thwacke));      \
+                                  (SvFLAGS(thwacke) &= ~SVpbm_VALID);  \
+                               })
+
 #  define SvTAIL(sv)   ({ SV *const _svi = (SV *) (sv);                \
                            assert(SvTYPE(_svi) != SVt_PVAV);           \
                            assert(SvTYPE(_svi) != SVt_PVHV);           \
@@ -1066,6 +972,9 @@ the scalar's value cannot change unless written to.
                                == (SVpbm_TAIL|SVpbm_VALID);            \
                        })
 #else
+#  define SvVALID(sv)          (SvFLAGS(sv) & SVpbm_VALID)
+#  define SvVALID_on(sv)       (SvFLAGS(sv) |= SVpbm_VALID)
+#  define SvVALID_off(sv)      (SvFLAGS(sv) &= ~SVpbm_VALID)
 #  define SvTAIL(sv)       ((SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID))   \
                             == (SVpbm_TAIL|SVpbm_VALID))
 
@@ -1073,9 +982,6 @@ the scalar's value cannot change unless written to.
 #define SvTAIL_on(sv)          (SvFLAGS(sv) |= SVpbm_TAIL)
 #define SvTAIL_off(sv)         (SvFLAGS(sv) &= ~SVpbm_TAIL)
 
-#define SvVALID(sv)            (SvFLAGS(sv) & SVpbm_VALID)
-#define SvVALID_on(sv)         (SvFLAGS(sv) |= SVpbm_VALID)
-#define SvVALID_off(sv)                (SvFLAGS(sv) &= ~SVpbm_VALID)
 
 #ifdef USE_ITHREADS
 /* The following uses the FAKE flag to show that a regex pointer is infact
@@ -1087,28 +993,45 @@ the scalar's value cannot change unless written to.
 
 #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 SvPAD_STATE(sv)        \
        ((SvFLAGS(sv) & (SVpad_NAME|SVpad_STATE)) == (SVpad_NAME|SVpad_STATE))
-#define SvPAD_STATE_on(sv)     (SvFLAGS(sv) |= SVpad_NAME|SVpad_STATE)
 
-#define OURSTASH(sv)   \
+#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);                  \
+       })
+#define SvPAD_OUR_on(sv)       ({                                      \
+           SV *const whap = (SV *) (sv);                               \
+           assert(SvTYPE(whap) == SVt_PVMG);                           \
+           (SvFLAGS(whap) |= 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);                  \
+       })
+#else
+#  define SvPAD_TYPED_on(sv)   (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED)
+#  define SvPAD_OUR_on(sv)     (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR)
+#  define SvPAD_STATE_on(sv)   (SvFLAGS(sv) |= SVpad_NAME|SVpad_STATE)
+#endif
+
+#define SvOURSTASH(sv) \
        (SvPAD_OUR(sv) ? ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash : NULL)
-#define OURSTASH_set(sv, st)                                   \
+#define SvOURSTASH_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
-#define SvRV(sv) ((sv)->sv_u.svu_rv)
 #endif
 #define SvRVx(sv) SvRV(sv)
 
@@ -1118,6 +1041,7 @@ the scalar's value cannot change unless written to.
 #  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_u.xnv_nv)
+#  define SvRV(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))
@@ -1185,6 +1109,16 @@ the scalar's value cannot change unless written to.
            assert(!isGV_with_GP(_svi));                                \
           &(((XPVNV*) SvANY(_svi))->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);                                     \
+        }))
 #    define SvMAGIC(sv)                                                        \
        (*({ SV *const _svi = (SV *) (sv);                              \
            assert(SvTYPE(_svi) >= SVt_PVMG);                           \
@@ -1203,6 +1137,7 @@ the scalar's value cannot change unless written to.
 #    define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv
 #    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 SvMAGIC(sv)        ((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic
 #    define SvSTASH(sv)        ((XPVMG*)  SvANY(sv))->xmg_stash
 #  endif
@@ -1261,7 +1196,11 @@ the scalar's value cannot change unless written to.
                assert(!isGV_with_GP(sv));              \
                (((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END
 #define SvRV_set(sv, val) \
-        STMT_START { assert(SvTYPE(sv) >=  SVt_RV); \
+        STMT_START { assert(SvTYPE(sv) >=  SVt_PV || SvTYPE(sv) ==  SVt_IV); \
+               assert(SvTYPE(sv) != SVt_PVAV);         \
+               assert(SvTYPE(sv) != SVt_PVHV);         \
+               assert(SvTYPE(sv) != SVt_PVCV);         \
+               assert(SvTYPE(sv) != SVt_PVFM);         \
                assert(!isGV_with_GP(sv));              \
                 ((sv)->sv_u.svu_rv = (val)); } STMT_END
 #define SvMAGIC_set(sv, val) \
@@ -1302,38 +1241,69 @@ the scalar's value cannot change unless written to.
     STMT_START {                                                       \
                     assert(SvTYPE(sv) >= SVt_PV);                      \
                     if (SvLEN(sv)) {                                   \
+                        assert(!SvROK(sv));                            \
                         if(SvOOK(sv)) {                                \
-                            SvPV_set(sv, SvPVX_mutable(sv) - SvIVX(sv)); \
+                            STRLEN zok;                                \
+                            SvOOK_offset(sv, zok);                     \
+                            SvPV_set(sv, SvPVX_mutable(sv) - zok);     \
                             SvFLAGS(sv) &= ~SVf_OOK;                   \
                         }                                              \
                         Safefree(SvPVX(sv));                           \
                     }                                                  \
                 } STMT_END
 
+#ifdef PERL_CORE
+/* Code that crops up in three places to take a scalar and ready it to hold
+   a reference */
+#  define prepare_SV_for_RV(sv)                                                \
+    STMT_START {                                                       \
+                   if (SvTYPE(sv) < SVt_PV && SvTYPE(sv) != SVt_IV)    \
+                       sv_upgrade(sv, SVt_IV);                         \
+                   else if (SvTYPE(sv) >= SVt_PV) {                    \
+                       SvPV_free(sv);                                  \
+                       SvLEN_set(sv, 0);                               \
+                        SvCUR_set(sv, 0);                              \
+                   }                                                   \
+                } STMT_END
+#endif
+
+#define PERL_FBM_TABLE_OFFSET 1        /* Number of bytes between EOS and table */
+
+/* SvPOKp not SvPOK in the assertion because the string can be tainted! eg
+   perl -T -e '/$^X/'
+*/
 #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);           \
+        }))
 #  define BmRARE(sv)                                                   \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) == SVt_PVBM);                           \
-           assert(SvVALID(_svi));                                      \
-           &(((XPVBM*) SvANY(_svi))->xbm_rare);                        \
+       (*({ SV *const uggh = (SV *) (sv);                              \
+               assert(SvTYPE(uggh) == SVt_PVGV);                       \
+               assert(SvVALID(uggh));                                  \
+           &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_rare);            \
         }))
 #  define BmUSEFUL(sv)                                                 \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) == SVt_PVBM);                           \
-           assert(SvVALID(_svi));                                      \
-           assert(!SvIOK(_svi));                                       \
-           &(((XPVBM*) SvANY(_svi))->xiv_u.xivu_i32);                  \
+       (*({ SV *const uggh = (SV *) (sv);                              \
+           assert(SvTYPE(uggh) == SVt_PVGV);                           \
+           assert(SvVALID(uggh));                                      \
+           assert(!SvIOK(uggh));                                       \
+           &(((XPVGV*) SvANY(uggh))->xiv_u.xivu_i32);                  \
         }))
 #  define BmPREVIOUS(sv)                                               \
-       (*({ SV *const _svi = (SV *) (sv);                              \
-           assert(SvTYPE(_svi) == SVt_PVBM);                           \
-           assert(SvVALID(_svi));                                      \
-           &(((XPVBM*) SvANY(_svi))->xbm_previous);                    \
+       (*({ SV *const uggh = (SV *) (sv);                              \
+               assert(SvTYPE(uggh) == SVt_PVGV);                       \
+               assert(SvVALID(uggh));                                  \
+           &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_previous);        \
         }))
 #else
-#  define BmRARE(sv)   ((XPVBM*)  SvANY(sv))->xbm_rare
-#  define BmUSEFUL(sv) ((XPVBM*)  SvANY(sv))->xiv_u.xivu_i32
-#  define BmPREVIOUS(sv)       ((XPVBM*)  SvANY(sv))->xbm_previous
+#  define BmFLAGS(sv)          ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_flags
+#  define BmRARE(sv)           ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_rare
+#  define BmUSEFUL(sv)         ((XPVGV*) SvANY(sv))->xiv_u.xivu_i32
+#  define BmPREVIOUS(sv)       ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_previous
+
 #endif
 
 #define FmLINES(sv)    ((XPVFM*)  SvANY(sv))->xfm_lines
@@ -1357,7 +1327,6 @@ the scalar's value cannot change unless written to.
 #define IoFMT_GV(sv)   ((XPVIO*)  SvANY(sv))->xio_fmt_gv
 #define IoBOTTOM_NAME(sv)((XPVIO*) SvANY(sv))->xio_bottom_name
 #define IoBOTTOM_GV(sv)        ((XPVIO*)  SvANY(sv))->xio_bottom_gv
-#define IoSUBPROCESS(sv)((XPVIO*)  SvANY(sv))->xio_subprocess
 #define IoTYPE(sv)     ((XPVIO*)  SvANY(sv))->xio_type
 #define IoFLAGS(sv)    ((XPVIO*)  SvANY(sv))->xio_flags
 
@@ -1427,7 +1396,9 @@ stringified version becoming C<SvPOK>.  Handles 'get' magic. See also
 C<SvPVx> for a version which guarantees to evaluate sv only once.
 
 =for apidoc Am|char*|SvPVx|SV* sv|STRLEN len
-A version of C<SvPV> which guarantees to evaluate sv only once.
+A version of C<SvPV> which guarantees to evaluate C<sv> only once.
+Only use this if C<sv> is an expression with side effects, otherwise use the
+more efficient C<SvPVX>.
 
 =for apidoc Am|char*|SvPV_nomg|SV* sv|STRLEN len
 Like C<SvPV> but doesn't process magic.
@@ -1438,7 +1409,7 @@ the SV if the SV does not contain a string.  The SV may cache the
 stringified form becoming C<SvPOK>.  Handles 'get' magic.
 
 =for apidoc Am|IV|SvIV|SV* sv
-Coerces the given SV to an integer and returns it. See  C<SvIVx> for a
+Coerces the given SV to an integer and returns it. See C<SvIVx> for a
 version which guarantees to evaluate sv only once.
 
 =for apidoc Am|IV|SvIV_nomg|SV* sv
@@ -1446,15 +1417,17 @@ Like C<SvIV> but doesn't process magic.
 
 =for apidoc Am|IV|SvIVx|SV* sv
 Coerces the given SV to an integer and returns it. Guarantees to evaluate
-sv only once. Use the more efficient C<SvIV> otherwise.
+C<sv> only once. Only use this if C<sv> is an expression with side effects,
+otherwise use the more efficient C<SvIV>.
 
 =for apidoc Am|NV|SvNV|SV* sv
-Coerce the given SV to a double and return it. See  C<SvNVx> for a version
+Coerce the given SV to a double and return it. See C<SvNVx> for a version
 which guarantees to evaluate sv only once.
 
 =for apidoc Am|NV|SvNVx|SV* sv
 Coerces the given SV to a double and returns it. Guarantees to evaluate
-sv only once. Use the more efficient C<SvNV> otherwise.
+C<sv> only once. Only use this if C<sv> is an expression with side effects,
+otherwise use the more efficient C<SvNV>.
 
 =for apidoc Am|UV|SvUV|SV* sv
 Coerces the given SV to an unsigned integer and returns it.  See C<SvUVx>
@@ -1465,7 +1438,8 @@ Like C<SvUV> but doesn't process magic.
 
 =for apidoc Am|UV|SvUVx|SV* sv
 Coerces the given SV to an unsigned integer and returns it. Guarantees to
-evaluate sv only once. Use the more efficient C<SvUV> otherwise.
+C<sv> only once. Only use this if C<sv> is an expression with side effects,
+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
@@ -1597,7 +1571,7 @@ Like C<sv_catsv> but doesn't process magic.
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp))
 
 #define SvPVutf8_force(sv, lp) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == (SVf_POK|SVf_UTF8) \
+    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST)) == (SVf_POK|SVf_UTF8) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp))
 
 
@@ -1712,13 +1686,15 @@ Like C<sv_catsv> but doesn't process magic.
 #define SV_SMAGIC              128
 #define SV_HAS_TRAILING_NUL    256
 #define SV_COW_SHARED_HASH_KEYS        512
+/* This one is only enabled for PERL_OLD_COPY_ON_WRITE */
+#define SV_COW_OTHER_PVS       1024
 
 /* 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.
  */
 #ifdef PERL_CORE
 #  ifndef SV_DO_COW_SVSETSV
-#    define SV_DO_COW_SVSETSV  SV_COW_SHARED_HASH_KEYS
+#    define SV_DO_COW_SVSETSV  SV_COW_SHARED_HASH_KEYS|SV_COW_OTHER_PVS
 #  endif
 #endif
 
@@ -1742,11 +1718,17 @@ Like C<sv_catsv> but doesn't process magic.
                                    sv_force_normal_flags(sv, SV_COW_DROP_PV)
 
 #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 SvRELEASE_IVX(sv)   \
+    ((SvIsCOW(sv) ? sv_force_normal_flags(sv, 0) : (void) 0), 0)
 #  define SvIsCOW_normal(sv)   (SvIsCOW(sv) && SvLEN(sv))
+#  define SvRELEASE_IVX_(sv)   SvRELEASE_IVX(sv),
 #else
-#  define SvRELEASE_IVX(sv)   SvOOK_off(sv)
+#  define SvRELEASE_IVX(sv)   0
+/* This little game brought to you by the need to shut this warning up:
+mg.c: In function `Perl_magic_get':
+mg.c:1024: warning: left-hand operand of comma expression has no effect
+*/
+#  define SvRELEASE_IVX_(sv)  /**/
 #endif /* PERL_OLD_COPY_ON_WRITE */
 
 #define CAN_COW_MASK   (SVs_OBJECT|SVs_GMG|SVs_SMG|SVs_RMG|SVf_IOK|SVf_NOK| \
@@ -1790,7 +1772,7 @@ Like C<sv_catsv> but doesn't process magic.
 #define sv_catpvn_utf8_upgrade(dsv, sstr, slen, nsv)   \
        STMT_START {                                    \
            if (!(nsv))                                 \
-               nsv = sv_2mortal(newSVpvn(sstr, slen)); \
+               nsv = newSVpvn_flags(sstr, slen, SVs_TEMP);     \
            else                                        \
                sv_setpvn(nsv, sstr, slen);             \
            SvUTF8_off(nsv);                            \
@@ -1862,6 +1844,7 @@ Returns a pointer to the character buffer.
 #define SvSHARE(sv) CALL_FPTR(PL_sharehook)(aTHX_ sv)
 #define SvLOCK(sv) CALL_FPTR(PL_lockhook)(aTHX_ sv)
 #define SvUNLOCK(sv) CALL_FPTR(PL_unlockhook)(aTHX_ sv)
+#define SvDESTROYABLE(sv) CALL_FPTR(PL_destroyhook)(aTHX_ sv)
 
 #define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
 #define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END
@@ -1906,8 +1889,21 @@ Returns a pointer to the character buffer.
 /* If I give every macro argument a different name, then there won't be bugs
    where nested macros get confused. Been there, done that.  */
 #define isGV_with_GP(pwadak) \
-       (((SvFLAGS(pwadak) & (SVp_POK|SVp_SCREAM)) == SVp_SCREAM)       \
+       (((SvFLAGS(pwadak) & (SVp_POK|SVpgv_GP)) == SVpgv_GP)   \
        && (SvTYPE(pwadak) == SVt_PVGV || SvTYPE(pwadak) == SVt_PVLV))
+#define isGV_with_GP_on(sv)    STMT_START {                           \
+       assert (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV); \
+       assert (!SvPOKp(sv));                                          \
+       assert (!SvIOKp(sv));                                          \
+       (SvFLAGS(sv) |= SVpgv_GP);                                     \
+    } STMT_END
+#define isGV_with_GP_off(sv)   STMT_START {                           \
+       assert (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV); \
+       assert (!SvPOKp(sv));                                          \
+       assert (!SvIOKp(sv));                                          \
+       (SvFLAGS(sv) &= ~SVpgv_GP);                                    \
+    } STMT_END
+
 
 #define SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv))
 #define SvGROW_mutable(sv,len) \
@@ -1926,6 +1922,71 @@ struct clone_params {
 };
 
 /*
+=for apidoc Am|SV*|newSVpvn_utf8|NULLOK const char* s|STRLEN len|U32 utf8
+
+Creates a new SV and copies a string into it.  If utf8 is true, calls
+C<SvUTF8_on> on the new SV.  Implemented as a wrapper around C<newSVpvn_flags>.
+
+=cut
+*/
+
+#define newSVpvn_utf8(s, len, u) newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0)
+
+/*
+=for apidoc Am|void|SvOOK_offset|NN SV*sv|STRLEN len
+
+Reads into I<len> the offset from SvPVX back to the true start of the
+allocated buffer, which will be non-zero if C<sv_chop> has been used to
+efficiently remove characters from start of the buffer. Implemented as a
+macro, which takes the address of I<len>, which must be of type C<STRLEN>.
+Evaluates I<sv> more than once. Sets I<len> to 0 if C<SvOOK(sv)> is false.
+
+=cut
+*/
+
+#ifdef DEBUGGING
+/* Does the bot know something I don't?
+10:28 <@Nicholas> metabatman
+10:28 <+meta> Nicholas: crash
+*/
+#  define SvOOK_offset(sv, offset) STMT_START {                                \
+       assert(sizeof(offset) == sizeof(STRLEN));                       \
+       if (SvOOK(sv)) {                                                \
+           const U8 *crash = (U8*)SvPVX_const(sv);                     \
+           offset = *--crash;                                          \
+           if (!offset) {                                              \
+               crash -= sizeof(STRLEN);                                \
+               Copy(crash, (U8 *)&offset, sizeof(STRLEN), U8);         \
+           }                                                           \
+           {                                                           \
+               /* Validate the preceding buffer's sentinels to         \
+                  verify that no-one is using it.  */                  \
+               const U8 *const bonk = (U8 *) SvPVX_const(sv) - offset; \
+               while (crash > bonk) {                                  \
+                   --crash;                                            \
+                   assert (*crash == (U8)PTR2UV(crash));               \
+               }                                                       \
+           }                                                           \
+       } else {                                                        \
+           offset = 0;                                                 \
+       }                                                               \
+    } STMT_END
+#else
+    /* This is the same code, but avoids using any temporary variables:  */
+#  define SvOOK_offset(sv, offset) STMT_START {                                \
+       assert(sizeof(offset) == sizeof(STRLEN));                       \
+       if (SvOOK(sv)) {                                                \
+           offset = ((U8*)SvPVX_const(sv))[-1];                        \
+           if (!offset) {                                              \
+               Copy(SvPVX_const(sv) - 1 - sizeof(STRLEN),              \
+                    (U8 *)&offset, sizeof(STRLEN), U8);                \
+           }                                                           \
+       } else {                                                        \
+           offset = 0;                                                 \
+       }                                                               \
+    } STMT_END
+#endif
+/*
  * Local variables:
  * c-indentation-style: bsd
  * c-basic-offset: 4