This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Oops; fix threaded build
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index 7d3f1a6..b839a63 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -65,6 +65,11 @@ typedef enum {
        SVt_LAST        /* keep last in enum. used to size arrays */
 } svtype;
 
+/* *** any alterations to the SV types above need to be reflected in
+ * SVt_MASK and the various PL_valid_types_* tables */
+
+#define SVt_MASK 0xf   /* smallest bitmask that covers all types */
+
 #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
@@ -106,6 +111,7 @@ typedef struct hek HEK;
        SV**    svu_array;              \
        HE**    svu_hash;               \
        GP*     svu_gp;                 \
+       PerlIO *svu_fp;                 \
     }  sv_u
 
 
@@ -115,10 +121,10 @@ struct STRUCT_SV {                /* struct sv { */
 #ifdef DEBUG_LEAKING_SCALARS
     PERL_BITFIELD32 sv_debug_optype:9; /* the type of OP that allocated us */
     PERL_BITFIELD32 sv_debug_inpad:1;  /* was allocated in a pad for an OP */
-    PERL_BITFIELD32 sv_debug_cloned:1; /* was cloned for an ithread */
     PERL_BITFIELD32 sv_debug_line:16;  /* the line where we were allocated */
-    U32                    sv_debug_serial;    /* serial number of sv allocation   */
-    char *     sv_debug_file;          /* the file where we were allocated */
+    UV             sv_debug_serial;    /* serial number of sv allocation   */
+    char *         sv_debug_file;      /* the file where we were allocated */
+    SV *           sv_debug_parent;    /* what we were cloned from (ithreads)*/
 #endif
 };
 
@@ -218,42 +224,10 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SvFLAGS(sv)    (sv)->sv_flags
 #define SvREFCNT(sv)   (sv)->sv_refcnt
 
-#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
-#  define SvREFCNT_inc(sv)             \
-    ({                                 \
-       SV * const _sv = MUTABLE_SV(sv);        \
-       if (_sv)                        \
-            (SvREFCNT(_sv))++;         \
-       _sv;                            \
-    })
-#  define SvREFCNT_inc_simple(sv)      \
-    ({                                 \
-       if (sv)                         \
-            (SvREFCNT(sv))++;          \
-       MUTABLE_SV(sv);                         \
-    })
-#  define SvREFCNT_inc_NN(sv)          \
-    ({                                 \
-       SV * const _sv = MUTABLE_SV(sv);        \
-       SvREFCNT(_sv)++;                \
-       _sv;                            \
-    })
-#  define SvREFCNT_inc_void(sv)                \
-    ({                                 \
-       SV * const _sv = MUTABLE_SV(sv);        \
-       if (_sv)                        \
-           (void)(SvREFCNT(_sv)++);    \
-    })
-#else
-#  define SvREFCNT_inc(sv)     \
-       ((PL_Sv=MUTABLE_SV(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL)
-#  define SvREFCNT_inc_simple(sv) \
-       ((sv) ? (SvREFCNT(sv)++,MUTABLE_SV(sv)) : NULL)
-#  define SvREFCNT_inc_NN(sv) \
-       (PL_Sv=MUTABLE_SV(sv),++(SvREFCNT(PL_Sv)),PL_Sv)
-#  define SvREFCNT_inc_void(sv) \
-       (void)((PL_Sv=MUTABLE_SV(sv)) ? ++(SvREFCNT(PL_Sv)) : 0)
-#endif
+#define SvREFCNT_inc(sv)               S_SvREFCNT_inc(MUTABLE_SV(sv))
+#define SvREFCNT_inc_simple(sv)                SvREFCNT_inc(sv)
+#define SvREFCNT_inc_NN(sv)            S_SvREFCNT_inc_NN(MUTABLE_SV(sv))
+#define SvREFCNT_inc_void(sv)          S_SvREFCNT_inc_void(MUTABLE_SV(sv))
 
 /* These guys don't need the curly blocks */
 #define SvREFCNT_inc_simple_void(sv)   STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END
@@ -261,22 +235,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #define SvREFCNT_inc_void_NN(sv)       (void)(++SvREFCNT(MUTABLE_SV(sv)))
 #define SvREFCNT_inc_simple_void_NN(sv)        (void)(++SvREFCNT(MUTABLE_SV(sv)))
 
-#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
-#  define SvREFCNT_dec(sv)             \
-    ({                                 \
-       SV * const _sv = MUTABLE_SV(sv);        \
-       if (_sv) {                      \
-           if (SvREFCNT(_sv)) {        \
-               if (--(SvREFCNT(_sv)) == 0) \
-                   Perl_sv_free2(aTHX_ _sv);   \
-           } else {                    \
-               sv_free(_sv);           \
-           }                           \
-       }                               \
-    })
-#else
-#define SvREFCNT_dec(sv)       sv_free(MUTABLE_SV(sv))
-#endif
+#define SvREFCNT_dec(sv)       S_SvREFCNT_dec(aTHX_ MUTABLE_SV(sv))
 
 #define SVTYPEMASK     0xff
 #define SvTYPE(sv)     ((svtype)((sv)->sv_flags & SVTYPEMASK))
@@ -296,17 +255,17 @@ perform the upgrade if necessary.  See C<svtype>.
 #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 SVp_SCREAM     0x00008000  /* method name is DOES */
 #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
+                                      GvIMPORTED_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 */
+/*                      0x00010000  *** FREE SLOT */
+#define SVs_PADTMP     0x00020000  /* in use as tmp; only if ! SVs_PADMY */
+#define SVs_PADSTALE   0x00020000  /* lexical has gone out of scope;
+                                       only valid for SVs_PADMY */
 #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" */
@@ -316,7 +275,7 @@ perform the upgrade if necessary.  See C<svtype>.
 #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
+#define SVf_FAKE       0x01000000  /* 0: glob is just a copy
                                       1: SV head arena wasn't malloc()ed
                                       2: in conjunction with SVf_READONLY
                                          marks a shared hash key scalar
@@ -342,7 +301,7 @@ perform the upgrade if necessary.  See C<svtype>.
 
 
 
-#define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE)
+#define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE|SVs_RMG)
 
 #define SVf_OK         (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \
                         SVp_IOK|SVp_NOK|SVp_POK|SVpgv_GP)
@@ -366,8 +325,21 @@ perform the upgrade if necessary.  See C<svtype>.
 
 /* PVHV */
 #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
+
+/* PVNV, PVMG only, and only used in pads. Should be safe to test on any scalar
+   SV, as the core is careful to avoid setting both.
+
+   SVf_POK, SVp_POK also set:
+   0x00004400   Normal
+   0x0000C400   method name for DOES (SvSCREAM)
+   0x40004400   FBM compiled (SvVALID)
+   0x4000C400   pad name.
+
+   0x00008000   GV with GP
+   0x00008800   RV with PCS imported
+*/
+#define SVpad_NAME     (SVp_SCREAM|SVpbm_VALID)
+                                   /* This SV is a name in the PAD, so
                                       SVpad_TYPED, SVpad_OUR and SVpad_STATE
                                       apply */
 /* PVAV */
@@ -377,25 +349,25 @@ perform the upgrade if necessary.  See C<svtype>.
 /* 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
-/* ??? */
+/* Only used in toke.c on an SV stored in PL_lex_repl */
 #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 */
 /* 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 */
 /* 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 */
+/* pad name vars only */
+#define SVpad_STATE    0x80000000  /* pad name is a "state" var */
 
-#define _XPV_HEAD      \
-    union _xnvu xnv_u; \
+#define _XPV_HEAD                                                      \
+    HV*                xmg_stash;      /* class package */                     \
+    union _xmgu        xmg_u;                                                  \
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */    \
     STRLEN     xpv_len         /* allocated size */
 
@@ -407,25 +379,21 @@ union _xnvu {
        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;
+       I32 xbm_useful;
        U8  xbm_rare;           /* rarest character in string */
     }      xbm_s;              /* fields from PVBM */
 };
 
 union _xivu {
     IV     xivu_iv;            /* integer value */
-                               /* xpvfm: lines */
     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) */
+    STRLEN  xmg_hash_index;    /* used while freeing hash entries */
 };
 
 struct xpv {
@@ -449,39 +417,36 @@ struct xpvuv {
 struct xpvnv {
     _XPV_HEAD;
     union _xivu xiv_u;
+    union _xnvu xnv_u;
 };
 
-#define _XPVMG_HEAD                                \
-    union _xivu xiv_u;                             \
-    union _xmgu        xmg_u;                              \
-    HV*                xmg_stash       /* class package */
-
 /* This structure must match the beginning of struct xpvhv in hv.h. */
 struct xpvmg {
     _XPV_HEAD;
-    _XPVMG_HEAD;
+    union _xivu xiv_u;
+    union _xnvu xnv_u;
 };
 
 struct xpvlv {
     _XPV_HEAD;
-    _XPVMG_HEAD;
-
+    union _xivu xiv_u;
+    union _xnvu xnv_u;
     STRLEN     xlv_targoff;
     STRLEN     xlv_targlen;
     SV*                xlv_targ;
     char       xlv_type;       /* k=keys .=pos x=substr v=vec /=join/re
                                 * y=alem/helem/iter t=tie T=tied HE */
+    char       xlv_flags;      /* 1 = negative offset  2 = negative len */
 };
 
 /* This structure works in 3 ways - regular scalar, GV with GP, or fast
    Boyer-Moore.  */
 struct xpvgv {
     _XPV_HEAD;
-    _XPVMG_HEAD;
+    union _xivu xiv_u;
+    union _xnvu xnv_u;
 };
 
-/* This structure must match XPVCV in cv.h */
-
 typedef U16 cv_flags_t;
 
 #define _XPVCV_COMMON                                                          \
@@ -494,55 +459,57 @@ typedef U16 cv_flags_t;
        OP *    xcv_root;                                                       \
        void    (*xcv_xsub) (pTHX_ CV*);                                        \
     }          xcv_root_u;                                                     \
-    GV *       xcv_gv;                                                         \
+    union {                                                            \
+       GV *    xcv_gv;                                                 \
+       HEK *   xcv_hek;                                                \
+    }          xcv_gv_u;                                               \
     char *     xcv_file;                                                       \
-    AV *       xcv_padlist;                                                    \
+    PADLIST *  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
+    cv_flags_t xcv_flags;                                              \
+    I32        xcv_depth       /* >= 2 indicates recursive call */
+
+/* This structure must match XPVCV in cv.h */
 
 struct xpvfm {
     _XPV_HEAD;
-    _XPVMG_HEAD;
     _XPVCV_COMMON;
 };
 
-#define _XPVIO_TAIL                                                    \
-    PerlIO *   xio_ifp;        /* ifp and ofp are normally the same */ \
-    PerlIO *   xio_ofp;        /* but sockets need separate streams */ \
-    /* Cray addresses everything by word boundaries (64 bits) and      \
-     * code and data pointers cannot be mixed (which is exactly what   \
-     * Perl_filter_add() tries to do with the dirp), hence the         \
-     *  following union trick (as suggested by Gurusamy Sarathy).      \
-     * For further information see Geir Johansen's problem report      \
-     * titled [ID 20000612.002] Perl problem on Cray system            \
-     * The any pointer (known as IoANY()) will also be a good place    \
-     * to hang any IO disciplines to.                                  \
-     */                                                                        \
-    union {                                                            \
-       DIR *   xiou_dirp;      /* for opendir, readdir, etc */         \
-       void *  xiou_any;       /* for alignment */                     \
-    } xio_dirpu;                                                       \
-    /* IV xio_lines is now in IVX  $. */                               \
-    IV         xio_page;       /* $% */                                \
-    IV         xio_page_len;   /* $= */                                \
-    IV         xio_lines_left; /* $- */                                \
-    char *     xio_top_name;   /* $^ */                                \
-    GV *       xio_top_gv;     /* $^ */                                \
-    char *     xio_fmt_name;   /* $~ */                                \
-    GV *       xio_fmt_gv;     /* $~ */                                \
-    char *     xio_bottom_name;/* $^B */                               \
-    GV *       xio_bottom_gv;  /* $^B */                               \
-    char       xio_type;                                               \
-    U8         xio_flags
-
 
 struct xpvio {
     _XPV_HEAD;
-    _XPVMG_HEAD;
-    _XPVIO_TAIL;
+    union _xivu xiv_u;
+    /* ifp and ofp are normally the same, but sockets need separate streams */
+    PerlIO *   xio_ofp;
+    /* Cray addresses everything by word boundaries (64 bits) and
+     * code and data pointers cannot be mixed (which is exactly what
+     * Perl_filter_add() tries to do with the dirp), hence the
+     *  following union trick (as suggested by Gurusamy Sarathy).
+     * For further information see Geir Johansen's problem report
+     * titled [ID 20000612.002] Perl problem on Cray system
+     * The any pointer (known as IoANY()) will also be a good place
+     * to hang any IO disciplines to.
+     */
+    union {
+       DIR *   xiou_dirp;      /* for opendir, readdir, etc */
+       void *  xiou_any;       /* for alignment */
+    } xio_dirpu;
+    /* IV xio_lines is now in IVX  $. */
+    IV         xio_page;       /* $% */
+    IV         xio_page_len;   /* $= */
+    IV         xio_lines_left; /* $- */
+    char *     xio_top_name;   /* $^ */
+    GV *       xio_top_gv;     /* $^ */
+    char *     xio_fmt_name;   /* $~ */
+    GV *       xio_fmt_gv;     /* $~ */
+    char *     xio_bottom_name;/* $^B */
+    GV *       xio_bottom_gv;  /* $^B */
+    char       xio_type;
+    U8         xio_flags;
 };
 
 #define xio_dirp       xio_dirpu.xiou_dirp
@@ -554,7 +521,8 @@ struct xpvio {
 #define IOf_DIDTOP     8       /* just did top of form */
 #define IOf_UNTAINT    16      /* consider this fp (and its data) "safe" */
 #define IOf_NOLINE     32      /* slurped a pseudo-line from empty file */
-#define IOf_FAKE_DIRP  64      /* xio_dirp is fake (source filters kludge) */
+#define IOf_FAKE_DIRP  64      /* xio_dirp is fake (source filters kludge)
+                                  Also, when this is set, SvPVX() is valid */
 
 /* The following macros define implementation-independent predicates on SVs. */
 
@@ -661,20 +629,23 @@ Dereferences an RV to return the SV.
 
 =for apidoc Am|IV|SvIVX|SV* sv
 Returns the raw value in the SV's IV slot, without checks or conversions.
-Only use when you are sure SvIOK is true. See also C<SvIV()>.
+Only use when you are sure SvIOK is true.  See also C<SvIV()>.
 
 =for apidoc Am|UV|SvUVX|SV* sv
 Returns the raw value in the SV's UV slot, without checks or conversions.
-Only use when you are sure SvIOK is true. See also C<SvUV()>.
+Only use when you are sure SvIOK is true.  See also C<SvUV()>.
 
 =for apidoc Am|NV|SvNVX|SV* sv
 Returns the raw value in the SV's NV slot, without checks or conversions.
-Only use when you are sure SvNOK is true. See also C<SvNV()>.
+Only use when you are sure SvNOK is true.  See also C<SvNV()>.
 
 =for apidoc Am|char*|SvPVX|SV* sv
 Returns a pointer to the physical string in the SV.  The SV must contain a
 string.
 
+This is also used to store the name of an autoloaded subroutine in an XS
+AUTOLOAD routine.  See L<perlguts/Autoloading with XSUBs>.
+
 =for apidoc Am|STRLEN|SvCUR|SV* sv
 Returns the length of the string which is in the SV.  See C<SvLEN>.
 
@@ -683,9 +654,14 @@ Returns the size of the string buffer in the SV, not including any part
 attributable to C<SvOOK>.  See C<SvCUR>.
 
 =for apidoc Am|char*|SvEND|SV* sv
-Returns a pointer to the last character in the string which is in the SV.
+Returns a pointer to the spot just after the last character in
+the string which is in the SV, where there is usually a trailing
+null (even though Perl scalars do not strictly require it).
 See C<SvCUR>.  Access the character as *(SvEND(sv)).
 
+Warning: If C<SvCUR> is equal to C<SvLEN>, then C<SvEND> points to
+unallocated memory.
+
 =for apidoc Am|HV*|SvSTASH|SV* sv
 Returns the stash of the SV.
 
@@ -728,13 +704,8 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
 #define SvNIOK_off(sv)         (SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK| \
                                                  SVp_IOK|SVp_NOK|SVf_IVisUV))
 
-#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
-#define assert_not_ROK(sv)     ({assert(!SvROK(sv) || !SvRV(sv));}),
-#define assert_not_glob(sv)    ({assert(!isGV_with_GP(sv));}),
-#else
-#define assert_not_ROK(sv)     
-#define assert_not_glob(sv)    
-#endif
+#define assert_not_ROK(sv)     assert_(!SvROK(sv) || !SvRV(sv))
+#define assert_not_glob(sv)    assert_(!isGV_with_GP(sv))
 
 #define SvOK(sv)               ((SvTYPE(sv) == SVt_BIND)               \
                                 ? (SvFLAGS(SvRV(sv)) & SVf_OK)         \
@@ -786,7 +757,8 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
 
 /*
 =for apidoc Am|U32|SvUTF8|SV* sv
-Returns a U32 value indicating whether the SV contains UTF-8 encoded data.
+Returns a U32 value indicating the UTF-8 status of an SV.  If things are set-up
+properly, this indicates whether or not the SV contains UTF-8 encoded data.
 Call this after SvPV() in case any call to string overloading updates the
 internal flag.
 
@@ -795,7 +767,8 @@ Turn on the UTF-8 status of an SV (the data is not changed, just the flag).
 Do not use frivolously.
 
 =for apidoc Am|void|SvUTF8_off|SV *sv
-Unsets the UTF-8 status of an SV.
+Unsets the UTF-8 status of an SV (the data is not changed, just the flag).
+Do not use frivolously.
 
 =for apidoc Am|void|SvPOK_only_UTF8|SV* sv
 Tells an SV that it is a string and disables all other OK bits,
@@ -830,7 +803,7 @@ in gv.h: */
                                 ? 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_on(sv)           (SvFLAGS(sv) |= SVf_OOK)
 #define SvOOK_off(sv)          ((void)(SvOOK(sv) && sv_backoff(sv)))
 
 #define SvFAKE(sv)             (SvFLAGS(sv) & SVf_FAKE)
@@ -857,29 +830,49 @@ in gv.h: */
 #define SvRMAGICAL_on(sv)      (SvFLAGS(sv) |= SVs_RMG)
 #define SvRMAGICAL_off(sv)     (SvFLAGS(sv) &= ~SVs_RMG)
 
-#define SvAMAGIC(sv)           (SvROK(sv) && (SvFLAGS(SvRV(sv)) & SVf_AMAGIC))
-#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
-#  define SvAMAGIC_on(sv)      ({ SV * const kloink = sv;              \
-                                  assert(SvROK(kloink));               \
-                                  SvFLAGS(SvRV(kloink)) |= SVf_AMAGIC; \
-                               })
-#  define SvAMAGIC_off(sv)     ({ SV * const kloink = sv;              \
-                                  if(SvROK(kloink))                    \
-                                       SvFLAGS(SvRV(kloink)) &= ~SVf_AMAGIC;\
-                               })
-#else
-#  define SvAMAGIC_on(sv)      (SvFLAGS(SvRV(sv)) |= SVf_AMAGIC)
-#  define SvAMAGIC_off(sv) \
-       (SvROK(sv) && (SvFLAGS(SvRV(sv)) &= ~SVf_AMAGIC))
-#endif
+#define SvAMAGIC(sv)           (SvROK(sv) && SvOBJECT(SvRV(sv)) &&     \
+                                HvAMAGIC(SvSTASH(SvRV(sv))))
+
+/* To be used on the stashes themselves: */
+#define HvAMAGIC(hv)           (SvFLAGS(hv) & SVf_AMAGIC)
+#define HvAMAGIC_on(hv)                (SvFLAGS(hv) |= SVf_AMAGIC)
+#define HvAMAGIC_off(hv)       (SvFLAGS(hv) &=~ SVf_AMAGIC)
+
+
+#define SvPOK_nog(sv)          ((SvFLAGS(sv) & (SVf_POK|SVs_GMG)) == SVf_POK)
+#define SvIOK_nog(sv)          ((SvFLAGS(sv) & (SVf_IOK|SVs_GMG)) == SVf_IOK)
+#define SvUOK_nog(sv)          ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV|SVs_GMG)) == (SVf_IOK|SVf_IVisUV))
+#define SvNOK_nog(sv)          ((SvFLAGS(sv) & (SVf_NOK|SVs_GMG)) == SVf_NOK)
+#define SvNIOK_nog(sv)         (SvNIOK(sv) && !(SvFLAGS(sv) & SVs_GMG))
+
+#define SvPOK_nogthink(sv)     ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST|SVs_GMG)) == SVf_POK)
+#define SvIOK_nogthink(sv)     ((SvFLAGS(sv) & (SVf_IOK|SVf_THINKFIRST|SVs_GMG)) == SVf_IOK)
+#define SvUOK_nogthink(sv)     ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV|SVf_THINKFIRST|SVs_GMG)) == (SVf_IOK|SVf_IVisUV))
+#define SvNOK_nogthink(sv)     ((SvFLAGS(sv) & (SVf_NOK|SVf_THINKFIRST|SVs_GMG)) == SVf_NOK)
+#define SvNIOK_nogthink(sv)    (SvNIOK(sv) && !(SvFLAGS(sv) & (SVf_THINKFIRST|SVs_GMG)))
+
+#define SvPOK_utf8_nog(sv)     ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVs_GMG)) == (SVf_POK|SVf_UTF8))
+#define SvPOK_utf8_nogthink(sv)        ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST|SVs_GMG)) == (SVf_POK|SVf_UTF8))
+
+#define SvPOK_byte_nog(sv)     ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVs_GMG)) == SVf_POK)
+#define SvPOK_byte_nogthink(sv)        ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST|SVs_GMG)) == SVf_POK)
+
+#define SvPOK_pure_nogthink(sv) \
+    ((SvFLAGS(sv) & (SVf_POK|SVf_IOK|SVf_NOK|SVf_ROK|SVpgv_GP|SVf_THINKFIRST|SVs_GMG)) == SVf_POK)
+#define SvPOK_utf8_pure_nogthink(sv) \
+    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_IOK|SVf_NOK|SVf_ROK|SVpgv_GP|SVf_THINKFIRST|SVs_GMG)) == (SVf_POK|SVf_UTF8))
+#define SvPOK_byte_pure_nogthink(sv) \
+    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_IOK|SVf_NOK|SVf_ROK|SVpgv_GP|SVf_THINKFIRST|SVs_GMG)) == SVf_POK)
 
 /*
 =for apidoc Am|U32|SvGAMAGIC|SV* sv
 
-Returns true if the SV has get magic or overloading. If either is true then
+Returns true if the SV has get magic or
+overloading.  If either is true then
 the scalar is active data, and has the potential to return a new value every
-time it is accessed. Hence you must be careful to only read it once per user
-logical operation and work with that returned value. If neither is true then
+time it is accessed.  Hence you must be careful to
+only read it once per user logical operation and work
+with that returned value.  If neither is true then
 the scalar's value cannot change unless written to.
 
 =cut
@@ -887,7 +880,10 @@ the scalar's value cannot change unless written to.
 
 #define SvGAMAGIC(sv)           (SvGMAGICAL(sv) || SvAMAGIC(sv))
 
-#define Gv_AMG(stash)           (PL_amagic_generation && Gv_AMupdate(stash, FALSE))
+#define Gv_AMG(stash) \
+       (HvNAME(stash) && Gv_AMupdate(stash,FALSE) \
+           ? 1                                     \
+           : (HvAMAGIC_off(stash), 0))
 
 #define SvWEAKREF(sv)          ((SvFLAGS(sv) & (SVf_ROK|SVprv_WEAKREF)) \
                                  == (SVf_ROK|SVprv_WEAKREF))
@@ -899,19 +895,46 @@ the scalar's value cannot change unless written to.
 #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)
+/*
+=for apidoc m|U32|SvTHINKFIRST|SV *sv
+
+A quick flag check to see whether an sv should be passed to sv_force_normal
+to be "downgraded" before SvIVX or SvPVX can be modified directly.
+
+For example, if your scalar is a reference and you want to modify the SvIVX
+slot, you can't just do SvROK_off, as that will leak the referent.
+
+This is used internally by various sv-modifying functions, such as
+sv_setsv, sv_setiv and sv_pvn_force.
+
+One case that this does not handle is a gv without SvFAKE set.  After
+
+    if (SvTHINKFIRST(gv)) sv_force_normal(gv);
 
-#define SvPADSTALE(sv)         (SvFLAGS(sv) & SVs_PADSTALE)
-#define SvPADSTALE_on(sv)      (SvFLAGS(sv) |= SVs_PADSTALE)
-#define SvPADSTALE_off(sv)     (SvFLAGS(sv) &= ~SVs_PADSTALE)
+it will still be a gv.
 
-#define SvPADTMP(sv)           (SvFLAGS(sv) & SVs_PADTMP)
-#define SvPADTMP_on(sv)                (SvFLAGS(sv) |= SVs_PADTMP)
-#define SvPADTMP_off(sv)       (SvFLAGS(sv) &= ~SVs_PADTMP)
+SvTHINKFIRST sometimes produces false positives.  In those cases
+sv_force_normal does nothing.
+
+=cut
+*/
+
+#define SvTHINKFIRST(sv)       (SvFLAGS(sv) & SVf_THINKFIRST)
 
 #define SvPADMY(sv)            (SvFLAGS(sv) & SVs_PADMY)
 #define SvPADMY_on(sv)         (SvFLAGS(sv) |= SVs_PADMY)
 
+/* SVs_PADTMP and SVs_PADSTALE share the same bit, mediated by SVs_PADMY */
+
+#define SvPADTMP(sv)   ((SvFLAGS(sv) & (SVs_PADMY|SVs_PADTMP)) == SVs_PADTMP)
+#define SvPADSTALE(sv) ((SvFLAGS(sv) & (SVs_PADMY|SVs_PADSTALE)) \
+                                   == (SVs_PADMY|SVs_PADSTALE))
+
+#define SvPADTMP_on(sv)                S_SvPADTMP_on(MUTABLE_SV(sv))
+#define SvPADTMP_off(sv)       S_SvPADTMP_off(MUTABLE_SV(sv))
+#define SvPADSTALE_on(sv)      S_SvPADSTALE_on(MUTABLE_SV(sv))
+#define SvPADSTALE_off(sv)     S_SvPADSTALE_off(MUTABLE_SV(sv))
+
 #define SvTEMP(sv)             (SvFLAGS(sv) & SVs_TEMP)
 #define SvTEMP_on(sv)          (SvFLAGS(sv) |= SVs_TEMP)
 #define SvTEMP_off(sv)         (SvFLAGS(sv) &= ~SVs_TEMP)
@@ -928,9 +951,11 @@ the scalar's value cannot change unless written to.
 #define SvSCREAM_on(sv)                (SvFLAGS(sv) |= SVp_SCREAM)
 #define SvSCREAM_off(sv)       (SvFLAGS(sv) &= ~SVp_SCREAM)
 
-#define SvCOMPILED(sv)         (SvFLAGS(sv) & SVpfm_COMPILED)
-#define SvCOMPILED_on(sv)      (SvFLAGS(sv) |= SVpfm_COMPILED)
-#define SvCOMPILED_off(sv)     (SvFLAGS(sv) &= ~SVpfm_COMPILED)
+#ifndef PERL_CORE
+#  define SvCOMPILED(sv)       0
+#  define SvCOMPILED_on(sv)
+#  define SvCOMPILED_off(sv)
+#endif
 
 #define SvEVALED(sv)           (SvFLAGS(sv) & SVrepl_EVAL)
 #define SvEVALED_on(sv)                (SvFLAGS(sv) |= SVrepl_EVAL)
@@ -1008,9 +1033,6 @@ the scalar's value cannot change unless written to.
            ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash = st;      \
        } STMT_END
 
-#ifdef PERL_DEBUG_COW
-#else
-#endif
 #define SvRVx(sv) SvRV(sv)
 
 #ifdef PERL_DEBUG_COW
@@ -1023,7 +1045,7 @@ the scalar's value cannot change unless written to.
 #  define SvRV_const(sv) (0 + (sv)->sv_u.svu_rv)
 /* Don't test the core XS code yet.  */
 #  if defined (PERL_CORE) && PERL_DEBUG_COW > 1
-#    define SvPVX(sv) (0 + (assert(!SvREADONLY(sv)), (sv)->sv_u.svu_pv))
+#    define SvPVX(sv) (0 + (assert_(!SvREADONLY(sv)) (sv)->sv_u.svu_pv))
 #  else
 #  define SvPVX(sv) SvPVX_mutable(sv)
 #  endif
@@ -1031,13 +1053,8 @@ the scalar's value cannot change unless written to.
 #  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_u.xmg_magic)
-#    define SvSTASH(sv)        (0 + ((XPVMG*)  SvANY(sv))->xmg_stash)
-#  endif
+#  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 SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len
 #  define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
@@ -1046,71 +1063,52 @@ the scalar's value cannot change unless written to.
 /* These get expanded inside other macros that already use a variable _sv  */
 #    define SvPVX(sv)                                                  \
        (*({ SV *const _svpvx = MUTABLE_SV(sv);                         \
-           assert(SvTYPE(_svpvx) >= SVt_PV);                           \
-           assert(SvTYPE(_svpvx) != SVt_PVAV);                         \
-           assert(SvTYPE(_svpvx) != SVt_PVHV);                         \
+           assert(PL_valid_types_PVX[SvTYPE(_svpvx) & SVt_MASK]);      \
            assert(!isGV_with_GP(_svpvx));                              \
+           assert(!(SvTYPE(_svpvx) == SVt_PVIO                         \
+                    && !(IoFLAGS(_svpvx) & IOf_FAKE_DIRP)));           \
            &((_svpvx)->sv_u.svu_pv);                                   \
         }))
 #    define SvCUR(sv)                                                  \
        (*({ const SV *const _svcur = (const SV *)(sv);                 \
-           assert(SvTYPE(_svcur) >= SVt_PV);                           \
-           assert(SvTYPE(_svcur) != SVt_PVAV);                         \
-           assert(SvTYPE(_svcur) != SVt_PVHV);                         \
+           assert(PL_valid_types_PVX[SvTYPE(_svcur) & SVt_MASK]);      \
            assert(!isGV_with_GP(_svcur));                              \
+           assert(!(SvTYPE(_svcur) == SVt_PVIO                         \
+                    && !(IoFLAGS(_svcur) & IOf_FAKE_DIRP)));           \
            &(((XPV*) MUTABLE_PTR(SvANY(_svcur)))->xpv_cur);            \
         }))
 #    define SvIVX(sv)                                                  \
        (*({ const SV *const _svivx = (const SV *)(sv);                 \
-           assert(SvTYPE(_svivx) == SVt_IV || SvTYPE(_svivx) >= SVt_PVIV); \
-           assert(SvTYPE(_svivx) != SVt_PVAV);                         \
-           assert(SvTYPE(_svivx) != SVt_PVHV);                         \
-           assert(SvTYPE(_svivx) != SVt_PVCV);                         \
-           assert(SvTYPE(_svivx) != SVt_PVFM);                         \
-           assert(SvTYPE(_svivx) != SVt_PVIO);                         \
+           assert(PL_valid_types_IVX[SvTYPE(_svivx) & SVt_MASK]);      \
            assert(!isGV_with_GP(_svivx));                              \
            &(((XPVIV*) MUTABLE_PTR(SvANY(_svivx)))->xiv_iv);           \
         }))
 #    define SvUVX(sv)                                                  \
        (*({ const SV *const _svuvx = (const SV *)(sv);                 \
-           assert(SvTYPE(_svuvx) == SVt_IV || SvTYPE(_svuvx) >= SVt_PVIV); \
-           assert(SvTYPE(_svuvx) != SVt_PVAV);                         \
-           assert(SvTYPE(_svuvx) != SVt_PVHV);                         \
-           assert(SvTYPE(_svuvx) != SVt_PVCV);                         \
-           assert(SvTYPE(_svuvx) != SVt_PVFM);                         \
-           assert(SvTYPE(_svuvx) != SVt_PVIO);                         \
+           assert(PL_valid_types_IVX[SvTYPE(_svuvx) & SVt_MASK]);      \
            assert(!isGV_with_GP(_svuvx));                              \
            &(((XPVUV*) MUTABLE_PTR(SvANY(_svuvx)))->xuv_uv);           \
         }))
 #    define SvNVX(sv)                                                  \
        (*({ const SV *const _svnvx = (const SV *)(sv);                 \
-           assert(SvTYPE(_svnvx) == SVt_NV || SvTYPE(_svnvx) >= SVt_PVNV); \
-           assert(SvTYPE(_svnvx) != SVt_PVAV);                         \
-           assert(SvTYPE(_svnvx) != SVt_PVHV);                         \
-           assert(SvTYPE(_svnvx) != SVt_PVCV);                         \
-           assert(SvTYPE(_svnvx) != SVt_PVFM);                         \
-           assert(SvTYPE(_svnvx) != SVt_PVIO);                         \
+           assert(PL_valid_types_NVX[SvTYPE(_svnvx) & SVt_MASK]);      \
            assert(!isGV_with_GP(_svnvx));                              \
            &(((XPVNV*) MUTABLE_PTR(SvANY(_svnvx)))->xnv_u.xnv_nv);     \
         }))
 #    define SvRV(sv)                                                   \
        (*({ SV *const _svrv = MUTABLE_SV(sv);                          \
-           assert(SvTYPE(_svrv) >= SVt_PV || SvTYPE(_svrv) == SVt_IV); \
-           assert(SvTYPE(_svrv) != SVt_PVAV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVHV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVCV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVFM);                          \
+           assert(PL_valid_types_RV[SvTYPE(_svrv) & SVt_MASK]);        \
            assert(!isGV_with_GP(_svrv));                               \
+           assert(!(SvTYPE(_svrv) == SVt_PVIO                          \
+                    && !(IoFLAGS(_svrv) & IOf_FAKE_DIRP)));            \
            &((_svrv)->sv_u.svu_rv);                                    \
         }))
 #    define SvRV_const(sv)                                             \
        ({ const SV *const _svrv = (const SV *)(sv);                    \
-           assert(SvTYPE(_svrv) >= SVt_PV || SvTYPE(_svrv) == SVt_IV); \
-           assert(SvTYPE(_svrv) != SVt_PVAV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVHV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVCV);                          \
-           assert(SvTYPE(_svrv) != SVt_PVFM);                          \
+           assert(PL_valid_types_RV[SvTYPE(_svrv) & SVt_MASK]);        \
            assert(!isGV_with_GP(_svrv));                               \
+           assert(!(SvTYPE(_svrv) == SVt_PVIO                          \
+                    && !(IoFLAGS(_svrv) & IOf_FAKE_DIRP)));            \
            (_svrv)->sv_u.svu_rv;                                       \
         })
 #    define SvMAGIC(sv)                                                        \
@@ -1164,40 +1162,38 @@ the scalar's value cannot change unless written to.
 #define SvIV_please(sv) \
        STMT_START {if (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv))) \
                (void) SvIV(sv); } STMT_END
+#define SvIV_please_nomg(sv) \
+       (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv)) \
+           ? (SvIV_nomg(sv), SvIOK(sv))          \
+           : SvIOK(sv))
 #define SvIV_set(sv, val) \
-       STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
-               assert(SvTYPE(sv) != SVt_PVAV);         \
-               assert(SvTYPE(sv) != SVt_PVHV);         \
-               assert(SvTYPE(sv) != SVt_PVCV);         \
+       STMT_START { \
+               assert(PL_valid_types_IV_set[SvTYPE(sv) & SVt_MASK]);   \
                assert(!isGV_with_GP(sv));              \
                (((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); \
-           assert(SvTYPE(sv) != SVt_PVCV); assert(SvTYPE(sv) != SVt_PVFM); \
-               assert(SvTYPE(sv) != SVt_PVIO);         \
+       STMT_START { \
+               assert(PL_valid_types_NV_set[SvTYPE(sv) & SVt_MASK]);   \
                assert(!isGV_with_GP(sv));              \
                (((XPVNV*)SvANY(sv))->xnv_u.xnv_nv = (val)); } STMT_END
 #define SvPV_set(sv, val) \
-       STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
-               assert(SvTYPE(sv) != SVt_PVAV);         \
-               assert(SvTYPE(sv) != SVt_PVHV);         \
+       STMT_START { \
+               assert(PL_valid_types_PVX[SvTYPE(sv) & SVt_MASK]);      \
                assert(!isGV_with_GP(sv));              \
+               assert(!(SvTYPE(sv) == SVt_PVIO         \
+                    && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \
                ((sv)->sv_u.svu_pv = (val)); } STMT_END
 #define SvUV_set(sv, val) \
-       STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
-               assert(SvTYPE(sv) != SVt_PVAV);         \
-               assert(SvTYPE(sv) != SVt_PVHV);         \
-               assert(SvTYPE(sv) != SVt_PVCV);         \
+       STMT_START { \
+               assert(PL_valid_types_IV_set[SvTYPE(sv) & SVt_MASK]);   \
                assert(!isGV_with_GP(sv));              \
                (((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END
 #define SvRV_set(sv, val) \
-        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);         \
+        STMT_START { \
+               assert(PL_valid_types_RV[SvTYPE(sv) & SVt_MASK]);       \
                assert(!isGV_with_GP(sv));              \
+               assert(!(SvTYPE(sv) == SVt_PVIO         \
+                    && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \
                 ((sv)->sv_u.svu_rv = (val)); } STMT_END
 #define SvMAGIC_set(sv, val) \
         STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
@@ -1206,16 +1202,18 @@ the scalar's value cannot change unless written to.
         STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
                 (((XPVMG*)  SvANY(sv))->xmg_stash = (val)); } STMT_END
 #define SvCUR_set(sv, val) \
-       STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
-               assert(SvTYPE(sv) != SVt_PVAV);         \
-               assert(SvTYPE(sv) != SVt_PVHV);         \
+       STMT_START { \
+               assert(PL_valid_types_PVX[SvTYPE(sv) & SVt_MASK]);      \
                assert(!isGV_with_GP(sv));              \
+               assert(!(SvTYPE(sv) == SVt_PVIO         \
+                    && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \
                (((XPV*)  SvANY(sv))->xpv_cur = (val)); } STMT_END
 #define SvLEN_set(sv, val) \
-       STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
-               assert(SvTYPE(sv) != SVt_PVAV); \
-               assert(SvTYPE(sv) != SVt_PVHV); \
+       STMT_START { \
+               assert(PL_valid_types_PVX[SvTYPE(sv) & SVt_MASK]);      \
                assert(!isGV_with_GP(sv));      \
+               assert(!(SvTYPE(sv) == SVt_PVIO         \
+                    && !(IoFLAGS(sv) & IOf_FAKE_DIRP))); \
                (((XPV*)  SvANY(sv))->xpv_len = (val)); } STMT_END
 #define SvEND_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
@@ -1263,53 +1261,46 @@ the scalar's value cannot change unless written to.
                 } STMT_END
 #endif
 
-#define PERL_FBM_TABLE_OFFSET 1        /* Number of bytes between EOS and table */
+#ifndef PERL_CORE
+#  define BmFLAGS(sv)          (SvTAIL(sv) ? FBMcf_TAIL : 0)
+#endif
 
-/* 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 _bmflags = MUTABLE_SV(sv);                       \
-               assert(SvTYPE(_bmflags) == SVt_PVGV);                   \
-               assert(SvVALID(_bmflags));                              \
-           &(((XPVGV*) SvANY(_bmflags))->xnv_u.xbm_s.xbm_flags);       \
-        }))
 #  define BmRARE(sv)                                                   \
        (*({ SV *const _bmrare = MUTABLE_SV(sv);                        \
-               assert(SvTYPE(_bmrare) == SVt_PVGV);                    \
+               assert(SvTYPE(_bmrare) == SVt_PVMG);                    \
                assert(SvVALID(_bmrare));                               \
-           &(((XPVGV*) SvANY(_bmrare))->xnv_u.xbm_s.xbm_rare);         \
+           &(((XPVMG*) SvANY(_bmrare))->xnv_u.xbm_s.xbm_rare);         \
         }))
 #  define BmUSEFUL(sv)                                                 \
        (*({ SV *const _bmuseful = MUTABLE_SV(sv);                      \
-           assert(SvTYPE(_bmuseful) == SVt_PVGV);                      \
+           assert(SvTYPE(_bmuseful) == SVt_PVMG);                      \
            assert(SvVALID(_bmuseful));                                 \
            assert(!SvIOK(_bmuseful));                                  \
-           &(((XPVGV*) SvANY(_bmuseful))->xiv_u.xivu_i32);             \
+           &(((XPVMG*) SvANY(_bmuseful))->xnv_u.xbm_s.xbm_useful);     \
         }))
 #  define BmPREVIOUS(sv)                                               \
     (*({ SV *const _bmprevious = MUTABLE_SV(sv);                       \
-               assert(SvTYPE(_bmprevious) == SVt_PVGV);                \
+               assert(SvTYPE(_bmprevious) == SVt_PVMG);                \
                assert(SvVALID(_bmprevious));                           \
-           &(((XPVGV*) SvANY(_bmprevious))->xnv_u.xbm_s.xbm_previous); \
+           &(((XPVMG*) SvANY(_bmprevious))->xiv_u.xivu_uv);            \
         }))
 #else
-#  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
+#  define BmRARE(sv)           ((XPVMG*) SvANY(sv))->xnv_u.xbm_s.xbm_rare
+#  define BmUSEFUL(sv)         ((XPVMG*) SvANY(sv))->xnv_u.xbm_s.xbm_useful
+#  define BmPREVIOUS(sv)       ((XPVMG*) SvANY(sv))->xiv_u.xivu_uv
 
 #endif
 
-#define FmLINES(sv)    ((XPVFM*)  SvANY(sv))->xiv_u.xivu_iv
+#define FmLINES(sv)    ((XPVIV*)  SvANY(sv))->xiv_iv
 
 #define LvTYPE(sv)     ((XPVLV*)  SvANY(sv))->xlv_type
 #define LvTARG(sv)     ((XPVLV*)  SvANY(sv))->xlv_targ
 #define LvTARGOFF(sv)  ((XPVLV*)  SvANY(sv))->xlv_targoff
 #define LvTARGLEN(sv)  ((XPVLV*)  SvANY(sv))->xlv_targlen
+#define LvFLAGS(sv)    ((XPVLV*)  SvANY(sv))->xlv_flags
 
-#define IoIFP(sv)      ((XPVIO*)  SvANY(sv))->xio_ifp
+#define IoIFP(sv)      (sv)->sv_u.svu_fp
 #define IoOFP(sv)      ((XPVIO*)  SvANY(sv))->xio_ofp
 #define IoDIRP(sv)     ((XPVIO*)  SvANY(sv))->xio_dirp
 #define IoANY(sv)      ((XPVIO*)  SvANY(sv))->xio_any
@@ -1340,22 +1331,26 @@ the scalar's value cannot change unless written to.
 
 /*
 =for apidoc Am|bool|SvTAINTED|SV* sv
-Checks to see if an SV is tainted. Returns TRUE if it is, FALSE if
+Checks to see if an SV is tainted.  Returns TRUE if it is, FALSE if
 not.
 
 =for apidoc Am|void|SvTAINTED_on|SV* sv
 Marks an SV as tainted if tainting is enabled.
 
 =for apidoc Am|void|SvTAINTED_off|SV* sv
-Untaints an SV. Be I<very> careful with this routine, as it short-circuits
-some of Perl's fundamental security features. XS module authors should not
+Untaints an SV.  Be I<very> careful with this routine, as it short-circuits
+some of Perl's fundamental security features.  XS module authors should not
 use this function unless they fully understand all the implications of
 unconditionally untainting the value. Untainting should be done in the
 standard perl fashion, via a carefully crafted regexp, rather than directly
 untainting variables.
 
 =for apidoc Am|void|SvTAINT|SV* sv
-Taints an SV if tainting is enabled.
+Taints an SV if tainting is enabled, and if some input to the current
+expression is tainted--usually a variable, but possibly also implicit
+inputs such as locale settings.  C<SvTAINT> propagates that taintedness to
+the outputs of an expression in a pessimistic fashion; i.e., without paying
+attention to precisely which outputs are influenced by which inputs.
 
 =cut
 */
@@ -1376,25 +1371,25 @@ Taints an SV if tainting is enabled.
 
 /*
 =for apidoc Am|char*|SvPV_force|SV* sv|STRLEN len
-Like C<SvPV> but will force the SV into containing just a string
-(C<SvPOK_only>).  You want force if you are going to update the C<SvPVX>
-directly.
+Like C<SvPV> but will force the SV into containing a string (C<SvPOK>), and
+only a string (C<SvPOK_only>), by hook or by crook.  You want force if you are
+going to update the C<SvPVX> directly.  Processes get magic.
 
 =for apidoc Am|char*|SvPV_force_nomg|SV* sv|STRLEN len
-Like C<SvPV> but will force the SV into containing just a string
-(C<SvPOK_only>).  You want force if you are going to update the C<SvPVX>
-directly. Doesn't process magic.
+Like C<SvPV> but will force the SV into containing a string (C<SvPOK>), and
+only a string (C<SvPOK_only>), by hook or by crook.  You want force if you are
+going to update the C<SvPVX> directly.  Doesn't process get magic.
 
 =for apidoc Am|char*|SvPV|SV* sv|STRLEN len
 Returns a pointer to the string in the SV, or a stringified form of
 the SV if the SV does not contain a string.  The SV may cache the
-stringified version becoming C<SvPOK>.  Handles 'get' magic. See also
+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 C<sv> only once.
 Only use this if C<sv> is an expression with side effects, otherwise use the
-more efficient C<SvPVX>.
+more efficient C<SvPV>.
 
 =for apidoc Am|char*|SvPV_nomg|SV* sv|STRLEN len
 Like C<SvPV> but doesn't process magic.
@@ -1404,25 +1399,33 @@ Returns a pointer to the string in the SV, or a stringified form of
 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|char*|SvPV_nomg_nolen|SV* sv
+Like C<SvPV_nolen> but doesn't process 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
 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
-C<sv> only once. Only use this if C<sv> is an expression with side effects,
+Coerces the given SV to an integer and returns it.
+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<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|SvNV_nomg|SV* sv
+Like C<SvNV> but doesn't process magic.
+
 =for apidoc Am|NV|SvNVx|SV* sv
-Coerces the given SV to a double and returns it. Guarantees to evaluate
-C<sv> only once. Only use this if C<sv> is an expression with side effects,
+Coerces the given SV to a double and returns it.
+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<SvNV>.
 
 =for apidoc Am|UV|SvUV|SV* sv
@@ -1433,12 +1436,19 @@ for a version which guarantees to evaluate sv only once.
 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
-C<sv> only once. Only use this if C<sv> is an expression with side effects,
+Coerces the given SV to an unsigned integer and
+returns it.  Guarantees to 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
+false.  See SvOK() for a defined/undefined test.  Handles 'get' magic
+unless the scalar is already SvPOK, SvIOK or SvNOK (the public, not the
+private flags).
+
+=for apidoc Am|bool|SvTRUE_nomg|SV* sv
+Returns a boolean indicating whether Perl would evaluate the SV as true or
 false.  See SvOK() for a defined/undefined test.  Does not handle 'get' magic.
 
 =for apidoc Am|char*|SvPVutf8_force|SV* sv|STRLEN len
@@ -1480,9 +1490,9 @@ Guarantees to evaluate sv only once; use the more efficient C<SvPVbyte>
 otherwise.
 
 =for apidoc Am|bool|SvIsCOW|SV* sv
-Returns a boolean indicating whether the SV is Copy-On-Write. (either shared
+Returns a boolean indicating whether the SV is Copy-On-Write (either shared
 hash key scalars, or full Copy On Write scalars if 5.9.0 is configured for
-COW)
+COW).
 
 =for apidoc Am|bool|SvIsCOW_shared_hash|SV* sv
 Returns a boolean indicating whether the SV is Copy-On-Write shared hash key
@@ -1491,6 +1501,9 @@ scalar.
 =for apidoc Am|void|sv_catpvn_nomg|SV* sv|const char* ptr|STRLEN len
 Like C<sv_catpvn> but doesn't process magic.
 
+=for apidoc Am|void|sv_catpv_nomg|SV* sv|const char* ptr
+Like C<sv_catpv> but doesn't process magic.
+
 =for apidoc Am|void|sv_setsv_nomg|SV* dsv|SV* ssv
 Like C<sv_setsv> but doesn't process magic.
 
@@ -1499,38 +1512,39 @@ Like C<sv_catsv> but doesn't process magic.
 
 =for apidoc Amdb|STRLEN|sv_utf8_upgrade_nomg|NN SV *sv
 
-Like sv_utf8_upgrade, but doesn't do magic on C<sv>
+Like sv_utf8_upgrade, but doesn't do magic on C<sv>.
 
 =cut
 */
 
 /* Let us hope that bitmaps for UV and IV are the same */
-#define SvIV(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv))
-#define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv))
-#define SvNV(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv))
+#define SvIV(sv) (SvIOK_nog(sv) ? SvIVX(sv) : sv_2iv(sv))
+#define SvUV(sv) (SvUOK_nog(sv) ? SvUVX(sv) : sv_2uv(sv))
+#define SvNV(sv) (SvNOK_nog(sv) ? SvNVX(sv) : sv_2nv(sv))
 
 #define SvIV_nomg(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv_flags(sv, 0))
 #define SvUV_nomg(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv_flags(sv, 0))
+#define SvNV_nomg(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv_flags(sv, 0))
 
 /* ----*/
 
-#define SvPV(sv, lp) SvPV_flags(sv, lp, SV_GMAGIC)
-#define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC)
+#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 \
+    (SvPOK_nog(sv) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags))
 #define SvPV_flags_const(sv, lp, flags) \
-    ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+    (SvPOK_nog(sv) \
      ? ((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 \
+    (SvPOK_nog(sv) \
      ? 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 \
+    (SvPOK_nog(sv) \
      ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \
      sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
 
@@ -1542,22 +1556,28 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>
 #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))
+    (SvPOK_pure_nogthink(sv) \
+     ? ((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))
+    (SvPOK_pure_nogthink(sv) \
+     ? 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)) \
+    (SvPOK_pure_nogthink(sv) \
+     ? ((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 \
+    (SvPOK_nog(sv) \
      ? SvPVX(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC))
 
+#define SvPV_nomg_nolen(sv) \
+    (SvPOK_nog(sv) \
+     ? SvPVX(sv) : sv_2pv_flags(sv, 0, 0))
+
 #define SvPV_nolen_const(sv) \
-    ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+    (SvPOK_nog(sv) \
      ? SvPVX_const(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC|SV_CONST_RETURN))
 
 #define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0)
@@ -1567,33 +1587,31 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>
 /* ----*/
 
 #define SvPVutf8(sv, lp) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8) \
+    (SvPOK_utf8_nog(sv) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp))
 
 #define SvPVutf8_force(sv, lp) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST)) == (SVf_POK|SVf_UTF8) \
+    (SvPOK_utf8_pure_nogthink(sv) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp))
 
-
 #define SvPVutf8_nolen(sv) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8)\
+    (SvPOK_utf8_nog(sv) \
      ? SvPVX(sv) : sv_2pvutf8(sv, 0))
 
 /* ----*/
 
 #define SvPVbyte(sv, lp) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \
+    (SvPOK_byte_nog(sv) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp))
 
 #define SvPVbyte_force(sv, lp) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST)) == (SVf_POK) \
+    (SvPOK_byte_pure_nogthink(sv) \
      ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvbyten_force(sv, &lp))
 
 #define SvPVbyte_nolen(sv) \
-    ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK)\
+    (SvPOK_byte_nog(sv) \
      ? SvPVX(sv) : sv_2pvbyte(sv, 0))
 
-
     
 /* define FOOx(): idempotent versions of FOO(). If possible, use a local
  * var to evaluate the arg once; failing that, use a global if possible;
@@ -1604,6 +1622,17 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>
 #define SvPVutf8x_force(sv, lp) sv_pvutf8n_force(sv, &lp)
 #define SvPVbytex_force(sv, lp) sv_pvbyten_force(sv, &lp)
 
+#define SvTRUE(sv)        ((sv) && (SvGMAGICAL(sv) ? sv_2bool(sv) : SvTRUE_common(sv, sv_2bool_nomg(sv))))
+#define SvTRUE_nomg(sv)   ((sv) && (                                SvTRUE_common(sv, sv_2bool_nomg(sv))))
+#define SvTRUE_common(sv,fallback) (                   \
+      !SvOK(sv)                                                \
+       ? 0                                             \
+    : (SvFLAGS(sv) & (SVf_POK|SVf_IOK|SVf_NOK))                \
+       ? (   (SvPOK(sv) && SvPVXtrue(sv))              \
+          || (SvIOK(sv) && SvIVX(sv) != 0)             \
+          || (SvNOK(sv) && SvNVX(sv) != 0.0))          \
+    : (fallback))
+
 #if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 
 #  define SvIVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvIV(_sv); })
@@ -1616,23 +1645,13 @@ Like sv_utf8_upgrade, but doesn't do magic on C<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                                                                \
-    :    SvPOK(sv)                                             \
-       ?   (({XPV *nxpv = (XPV*)SvANY(sv);                     \
-            nxpv &&                                            \
-            (nxpv->xpv_cur > 1 ||                              \
-             (nxpv->xpv_cur && *(sv)->sv_u.svu_pv != '0')); }) \
-            ? 1                                                \
-            : 0)                                               \
-       :                                                       \
-           SvIOK(sv)                                           \
-           ? SvIVX(sv) != 0                                    \
-           :   SvNOK(sv)                                       \
-               ? SvNVX(sv) != 0.0                              \
-               : sv_2bool(sv) )
-#  define SvTRUEx(sv) ({SV *_sv = (sv); SvTRUE(_sv); })
+#  define SvTRUEx(sv)      ({SV *_sv = (sv); SvTRUE(_sv); })
+#  define SvTRUEx_nomg(sv) ({SV *_sv = (sv); SvTRUE_nomg(_sv); })
+#  define SvPVXtrue(sv)                                                \
+    ({XPV *nxpv;                                               \
+     (nxpv = (XPV*)SvANY(sv))                                  \
+      && (nxpv->xpv_cur > 1                                    \
+         || (nxpv->xpv_cur && *(sv)->sv_u.svu_pv != '0'));})
 
 #else /* __GNUC__ */
 
@@ -1649,26 +1668,17 @@ Like sv_utf8_upgrade, but doesn't do magic on C<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                                                                \
-    :    SvPOK(sv)                                             \
-       ?   ((PL_Xpv = (XPV*)SvANY(PL_Sv = (sv))) &&            \
-            (PL_Xpv->xpv_cur > 1 ||                            \
-             (PL_Xpv->xpv_cur && *PL_Sv->sv_u.svu_pv != '0'))  \
-            ? 1                                                \
-            : 0)                                               \
-       :                                                       \
-           SvIOK(sv)                                           \
-           ? SvIVX(sv) != 0                                    \
-           :   SvNOK(sv)                                       \
-               ? SvNVX(sv) != 0.0                              \
-               : sv_2bool(sv) )
-#  define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv))
+#  define SvTRUEx(sv)      ((PL_Sv = (sv)), SvTRUE(PL_Sv))
+#  define SvTRUEx_nomg(sv) ((PL_Sv = (sv)), SvTRUE_nomg(PL_Sv))
+#  define SvPVXtrue(sv)                                                \
+    ((PL_Xpv = (XPV*)SvANY(PL_Sv = (sv)))                      \
+     && (PL_Xpv->xpv_cur > 1                                   \
+        || (PL_Xpv->xpv_cur && *PL_Sv->sv_u.svu_pv != '0')))
 #endif /* __GNU__ */
 
-#define SvIsCOW(sv)            ((SvFLAGS(sv) & (SVf_FAKE | SVf_READONLY)) == \
-                                   (SVf_FAKE | SVf_READONLY))
+#define SvIsCOW(sv)    ((SvFLAGS(sv) & (SVf_FAKE | SVf_READONLY)) == \
+                          (SVf_FAKE | SVf_READONLY) && !isGV_with_GP(sv) \
+                          && SvTYPE(sv) != SVt_REGEXP)
 #define SvIsCOW_shared_hash(sv)        (SvIsCOW(sv) && SvLEN(sv) == 0)
 
 #define SvSHARED_HEK_FROM_PV(pvx) \
@@ -1697,6 +1707,12 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>
 /* if (after resolving magic etc), the SV is found to be overloaded,
  * don't call the overload magic, just return as-is */
 #define SV_SKIP_OVERLOAD       8192
+/* It is not yet clear whether we want this as an API, or what the
+ * constants should be named. */
+#ifdef PERL_CORE
+# define SV_CATBYTES           16384
+# define SV_CATUTF8            32768
+#endif
 
 /* 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.
@@ -1734,7 +1750,7 @@ Like sv_utf8_upgrade, but doesn't do magic on C<sv>
 #else
 #  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: In function 'Perl_magic_get':
 mg.c:1024: warning: left-hand operand of comma expression has no effect
 */
 #  define SvRELEASE_IVX_(sv)  /**/
@@ -1759,6 +1775,7 @@ mg.c:1024: warning: left-hand operand of comma expression has no effect
 #define sv_utf8_upgrade_flags(sv, flags) sv_utf8_upgrade_flags_grow(sv, flags, 0)
 #define sv_utf8_upgrade_nomg(sv) sv_utf8_upgrade_flags(sv, 0)
 #define sv_catpvn_nomg(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, 0)
+#define sv_catpv_nomg(dsv, sstr) sv_catpv_flags(dsv, sstr, 0)
 #define sv_setsv(dsv, ssv) \
        sv_setsv_flags(dsv, ssv, SV_GMAGIC|SV_DO_COW_SVSETSV)
 #define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, SV_DO_COW_SVSETSV)
@@ -1766,8 +1783,9 @@ mg.c:1024: warning: left-hand operand of comma expression has no effect
 #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_catpvn_mg(sv, sstr, slen) sv_catpvn_flags(sv, sstr, slen, SV_GMAGIC|SV_SMAGIC);
+#define sv_copypv(dsv, ssv) sv_copypv_flags(dsv, ssv, SV_GMAGIC)
+#define sv_copypv_nomg(dsv, ssv) sv_copypv_flags(dsv, ssv, 0)
 #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)
@@ -1778,12 +1796,18 @@ mg.c:1024: warning: left-hand operand of comma expression has no effect
 #define sv_2iv(sv) sv_2iv_flags(sv, SV_GMAGIC)
 #define sv_2uv(sv) sv_2uv_flags(sv, SV_GMAGIC)
 #define sv_2nv(sv) sv_2nv_flags(sv, SV_GMAGIC)
+#define sv_eq(sv1, sv2) sv_eq_flags(sv1, sv2, SV_GMAGIC)
+#define sv_cmp(sv1, sv2) sv_cmp_flags(sv1, sv2, SV_GMAGIC)
+#define sv_cmp_locale(sv1, sv2) sv_cmp_locale_flags(sv1, sv2, SV_GMAGIC)
+#define sv_collxfrm(sv, nxp) sv_cmp_flags(sv, nxp, SV_GMAGIC)
+#define sv_2bool(sv) sv_2bool_flags(sv, SV_GMAGIC)
+#define sv_2bool_nomg(sv) sv_2bool_flags(sv, 0)
 #define sv_insert(bigstr, offset, len, little, littlelen)              \
        Perl_sv_insert_flags(aTHX_ (bigstr),(offset), (len), (little),  \
                             (littlelen), SV_GMAGIC)
 
 /* Should be named SvCatPVN_utf8_upgrade? */
-#define sv_catpvn_utf8_upgrade(dsv, sstr, slen, nsv)   \
+#define sv_catpvn_nomg_utf8_upgrade(dsv, sstr, slen, nsv)      \
        STMT_START {                                    \
            if (!(nsv))                                 \
                nsv = newSVpvn_flags(sstr, slen, SVs_TEMP);     \
@@ -1791,9 +1815,17 @@ mg.c:1024: warning: left-hand operand of comma expression has no effect
                sv_setpvn(nsv, sstr, slen);             \
            SvUTF8_off(nsv);                            \
            sv_utf8_upgrade(nsv);                       \
-           sv_catsv(dsv, nsv); \
+           sv_catsv_nomg(dsv, nsv);                    \
        } STMT_END
 
+#ifdef PERL_CORE
+# define sv_or_pv_len_utf8(sv, pv, bytelen)          \
+    (SvGAMAGIC(sv)                                    \
+       ? utf8_length((U8 *)(pv), (U8 *)(pv)+(bytelen)) \
+       : sv_len_utf8(sv))
+# define sv_or_pv_pos_u2b(sv,s,p,lp) S_sv_or_pv_pos_u2b(aTHX_ sv,s,p,lp)
+#endif
+
 /*
 =for apidoc Am|SV*|newRV_inc|SV* sv
 
@@ -1811,11 +1843,14 @@ incremented.
 =head1 Magical Functions
 
 =for apidoc Am|void|SvGETMAGIC|SV* sv
-Invokes C<mg_get> on an SV if it has 'get' magic.  This macro evaluates its
+Invokes C<mg_get> on an SV if it has 'get' magic.  For example, this
+will call C<FETCH> on a tied variable.  This macro evaluates its
 argument more than once.
 
 =for apidoc Am|void|SvSETMAGIC|SV* sv
-Invokes C<mg_set> on an SV if it has 'set' magic.  This macro evaluates its
+Invokes C<mg_set> on an SV if it has 'set' magic.  This is necessary
+after modifying a scalar, in case it is a magical variable like C<$|>
+or a tied variable (it calls C<STORE>).  This macro evaluates its
 argument more than once.
 
 =for apidoc Am|void|SvSetSV|SV* dsb|SV* ssv
@@ -1824,7 +1859,7 @@ more than once.
 
 =for apidoc Am|void|SvSetSV_nosteal|SV* dsv|SV* ssv
 Calls a non-destructive version of C<sv_setsv> if dsv is not the same as
-ssv. May evaluate arguments more than once.
+ssv.  May evaluate arguments more than once.
 
 =for apidoc Am|void|SvSetMagicSV|SV* dsb|SV* ssv
 Like C<SvSetSV>, but does any set magic required afterwards.
@@ -1855,12 +1890,12 @@ Returns a pointer to the character buffer.
 =cut
 */
 
-#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 SvSHARE(sv) PL_sharehook(aTHX_ sv)
+#define SvLOCK(sv) PL_lockhook(aTHX_ sv)
+#define SvUNLOCK(sv) PL_unlockhook(aTHX_ sv)
+#define SvDESTROYABLE(sv) PL_destroyhook(aTHX_ sv)
 
-#define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
+#define SvGETMAGIC(x) ((void)(SvGMAGICAL(x) && mg_get(x)))
 #define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END
 
 #define SvSetSV_and(dst,src,finally) \
@@ -1897,6 +1932,16 @@ Returns a pointer to the character buffer.
 
 #define SvIMMORTAL(sv) ((sv)==&PL_sv_undef || (sv)==&PL_sv_yes || (sv)==&PL_sv_no || (sv)==&PL_sv_placeholder)
 
+/*
+=for apidoc Am|SV *|boolSV|bool b
+
+Returns a true SV if C<b> is a true value, or a false SV if C<b> is 0.
+
+See also C<PL_sv_yes> and C<PL_sv_no>.
+
+=cut
+*/
+
 #define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no)
 
 #define isGV(sv) (SvTYPE(sv) == SVt_PVGV)
@@ -1933,6 +1978,8 @@ struct clone_params {
   AV* stashes;
   UV  flags;
   PerlInterpreter *proto_perl;
+  PerlInterpreter *new_perl;
+  AV *unreferenced;
 };
 
 /*
@@ -1947,13 +1994,25 @@ C<SvUTF8_on> on the new SV.  Implemented as a wrapper around C<newSVpvn_flags>.
 #define newSVpvn_utf8(s, len, u) newSVpvn_flags((s), (len), (u) ? SVf_UTF8 : 0)
 
 /*
+=for apidoc Amx|SV*|newSVpadname|PADNAME *pn
+
+Creates a new SV containing the pad name.  This is currently identical
+to C<newSVsv>, but pad names may cease being SVs at some point, so
+C<newSVpadname> is preferable.
+
+=cut
+*/
+
+#define newSVpadname(pn) newSVsv(pn)
+
+/*
 =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
+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.
+Evaluates I<sv> more than once.  Sets I<len> to 0 if C<SvOOK(sv)> is false.
 
 =cut
 */
@@ -1966,23 +2025,23 @@ Evaluates I<sv> more than once. Sets I<len> to 0 if C<SvOOK(sv)> is false.
 #  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);         \
+           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));               \
+               const U8 *const _bonk = (U8*)SvPVX_const(sv) - (offset);\
+               while (_crash > _bonk) {                                \
+                   --_crash;                                           \
+                   assert (*_crash == (U8)PTR2UV(_crash));             \
                }                                                       \
            }                                                           \
        } else {                                                        \
-           offset = 0;                                                 \
+           (offset) = 0;                                               \
        }                                                               \
     } STMT_END
 #else
@@ -1990,13 +2049,13 @@ Evaluates I<sv> more than once. Sets I<len> to 0 if C<SvOOK(sv)> is false.
 #  define SvOOK_offset(sv, offset) STMT_START {                                \
        assert(sizeof(offset) == sizeof(STRLEN));                       \
        if (SvOOK(sv)) {                                                \
-           offset = ((U8*)SvPVX_const(sv))[-1];                        \
-           if (!offset) {                                              \
+           (offset) = ((U8*)SvPVX_const(sv))[-1];                      \
+           if (!(offset)) {                                            \
                Copy(SvPVX_const(sv) - 1 - sizeof(STRLEN),              \
-                    (U8 *)&offset, sizeof(STRLEN), U8);                \
+                    (U8*)&(offset), sizeof(STRLEN), U8);               \
            }                                                           \
        } else {                                                        \
-           offset = 0;                                                 \
+           (offset) = 0;                                               \
        }                                                               \
     } STMT_END
 #endif
@@ -2007,8 +2066,8 @@ Evaluates I<sv> more than once. Sets I<len> to 0 if C<SvOOK(sv)> is false.
  * Local variables:
  * c-indentation-style: bsd
  * c-basic-offset: 4
- * indent-tabs-mode: t
+ * indent-tabs-mode: nil
  * End:
  *
- * ex: set ts=8 sts=4 sw=4 noet:
+ * ex: set ts=8 sts=4 sw=4 et:
  */