This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Document isGV_with_GP
[perl5.git] / sv.h
diff --git a/sv.h b/sv.h
index ad7046a..abe93ec 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -13,9 +13,9 @@
 #endif
 
 /*
-=head1 SV Flags
+=for apidoc_section $SV_flags
 
-=for apidoc AmU||svtype
+=for apidoc Ay||svtype
 An enum of flags for Perl types.  These are found in the file F<sv.h>
 in the C<svtype> enum.  Test these flags with the C<SvTYPE> macro.
 
@@ -72,52 +72,52 @@ hold C<undef> or a string.  C<SVt_PVIV> is a superset of C<SVt_PV> and C<SVt_IV>
 C<SVt_PVNV> is similar.  C<SVt_PVMG> can hold anything C<SVt_PVNV> can hold, but it
 can, but does not have to, be blessed or magical.
 
-=for apidoc AmU||SVt_NULL
+=for apidoc AmnU||SVt_NULL
 Type flag for scalars.  See L</svtype>.
 
-=for apidoc AmU||SVt_IV
+=for apidoc AmnU||SVt_IV
 Type flag for scalars.  See L</svtype>.
 
-=for apidoc AmU||SVt_NV
+=for apidoc AmnU||SVt_NV
 Type flag for scalars.  See L</svtype>.
 
-=for apidoc AmU||SVt_PV
+=for apidoc AmnU||SVt_PV
 Type flag for scalars.  See L</svtype>.
 
-=for apidoc AmU||SVt_PVIV
+=for apidoc AmnU||SVt_PVIV
 Type flag for scalars.  See L</svtype>.
 
-=for apidoc AmU||SVt_PVNV
+=for apidoc AmnU||SVt_PVNV
 Type flag for scalars.  See L</svtype>.
 
-=for apidoc AmU||SVt_PVMG
+=for apidoc AmnU||SVt_PVMG
 Type flag for scalars.  See L</svtype>.
 
-=for apidoc AmU||SVt_INVLIST
-Type flag for scalars.  See L</svtype>.
+=for apidoc CmnU||SVt_INVLIST
+Type flag for scalars.  See L<perlapi/svtype>.
 
-=for apidoc AmU||SVt_REGEXP
+=for apidoc AmnU||SVt_REGEXP
 Type flag for regular expressions.  See L</svtype>.
 
-=for apidoc AmU||SVt_PVGV
+=for apidoc AmnU||SVt_PVGV
 Type flag for typeglobs.  See L</svtype>.
 
-=for apidoc AmU||SVt_PVLV
+=for apidoc AmnU||SVt_PVLV
 Type flag for scalars.  See L</svtype>.
 
-=for apidoc AmU||SVt_PVAV
+=for apidoc AmnU||SVt_PVAV
 Type flag for arrays.  See L</svtype>.
 
-=for apidoc AmU||SVt_PVHV
+=for apidoc AmnU||SVt_PVHV
 Type flag for hashes.  See L</svtype>.
 
-=for apidoc AmU||SVt_PVCV
+=for apidoc AmnU||SVt_PVCV
 Type flag for subroutines.  See L</svtype>.
 
-=for apidoc AmU||SVt_PVFM
+=for apidoc AmnU||SVt_PVFM
 Type flag for formats.  See L</svtype>.
 
-=for apidoc AmU||SVt_PVIO
+=for apidoc AmnU||SVt_PVIO
 Type flag for I/O objects.  See L</svtype>.
 
 =cut
@@ -149,6 +149,9 @@ typedef enum {
        SVt_PVCV,       /* 13 */
        SVt_PVFM,       /* 14 */
        SVt_PVIO,       /* 15 */
+                        /* 16-31: Unused, though one should be reserved for a
+                         * freed sv, if the other 3 bits below the flags ones
+                         * get allocated */
        SVt_LAST        /* keep last in enum. used to size arrays */
 } svtype;
 
@@ -157,10 +160,10 @@ typedef enum {
  * tables are in perl.h.  There are also two affected names tables in dump.c,
  * one in B.xs, and 'bodies_by_type[]' in sv.c.
  *
- * The bits that match 0xf0 are CURRENTLY UNUSED, except that 0xFF means a
- * freed SV.  The bits above that are for flags, like SVf_IOK */
+ * The bits that match 0xe0 are CURRENTLY UNUSED
+ * The bits above that are for flags, like SVf_IOK */
 
-#define SVt_MASK 0x  /* smallest bitmask that covers all types */
+#define SVt_MASK 0x1f  /* smallest bitmask that covers all types */
 
 #ifndef PERL_CORE
 /* Fast Boyer Moore tables are now stored in magic attached to PVMGs */
@@ -262,28 +265,33 @@ struct p5rx {
     _SV_HEAD_UNION;
 };
 
+struct invlist {
+    _SV_HEAD(XINVLIST*);       /* pointer to xpvinvlist body */
+    _SV_HEAD_UNION;
+};
+
 #undef _SV_HEAD
 #undef _SV_HEAD_UNION          /* ensure no pollution */
 
 /*
-=head1 SV Manipulation Functions
+=for apidoc_section $SV
 
 =for apidoc Am|U32|SvREFCNT|SV* sv
 Returns the value of the object's reference count. Exposed
 to perl code via Internals::SvREFCNT().
 
-=for apidoc Am|SV*|SvREFCNT_inc|SV* sv
+=for apidoc SvREFCNT_inc
 Increments the reference count of the given SV, returning the SV.
 
-All of the following C<SvREFCNT_inc>* macros are optimized versions of
+All of the following C<SvREFCNT_inc>* are optimized versions of
 C<SvREFCNT_inc>, and can be replaced with C<SvREFCNT_inc>.
 
-=for apidoc Am|SV*|SvREFCNT_inc_NN|SV* sv
+=for apidoc SvREFCNT_inc_NN
 Same as C<SvREFCNT_inc>, but can only be used if you know C<sv>
 is not C<NULL>.  Since we don't have to check the NULLness, it's faster
 and smaller.
 
-=for apidoc Am|void|SvREFCNT_inc_void|SV* sv
+=for apidoc SvREFCNT_inc_void
 Same as C<SvREFCNT_inc>, but can only be used if you don't need the
 return value.  The macro doesn't need to return a meaningful value.
 
@@ -312,10 +320,10 @@ value, and you know that C<sv> is not C<NULL>.  The macro doesn't need
 to return a meaningful value, or check for NULLness, so it's smaller
 and faster.
 
-=for apidoc Am|void|SvREFCNT_dec|SV* sv
+=for apidoc SvREFCNT_dec
 Decrements the reference count of the given SV.  C<sv> may be C<NULL>.
 
-=for apidoc Am|void|SvREFCNT_dec_NN|SV* sv
+=for apidoc SvREFCNT_dec_NN
 Same as C<SvREFCNT_dec>, but can only be used if you know C<sv>
 is not C<NULL>.  Since we don't have to check the NULLness, it's faster
 and smaller.
@@ -334,10 +342,10 @@ perform the upgrade if necessary.  See C<L</svtype>>.
 #define SvFLAGS(sv)    (sv)->sv_flags
 #define SvREFCNT(sv)   (sv)->sv_refcnt
 
-#define SvREFCNT_inc(sv)               S_SvREFCNT_inc(MUTABLE_SV(sv))
+#define SvREFCNT_inc(sv)               Perl_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))
+#define SvREFCNT_inc_NN(sv)            Perl_SvREFCNT_inc_NN(MUTABLE_SV(sv))
+#define SvREFCNT_inc_void(sv)          Perl_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
@@ -345,8 +353,8 @@ perform the upgrade if necessary.  See C<L</svtype>>.
 #define SvREFCNT_inc_void_NN(sv)       (void)(++SvREFCNT(MUTABLE_SV(sv)))
 #define SvREFCNT_inc_simple_void_NN(sv)        (void)(++SvREFCNT(MUTABLE_SV(sv)))
 
-#define SvREFCNT_dec(sv)       S_SvREFCNT_dec(aTHX_ MUTABLE_SV(sv))
-#define SvREFCNT_dec_NN(sv)    S_SvREFCNT_dec_NN(aTHX_ MUTABLE_SV(sv))
+#define SvREFCNT_dec(sv)       Perl_SvREFCNT_dec(aTHX_ MUTABLE_SV(sv))
+#define SvREFCNT_dec_NN(sv)    Perl_SvREFCNT_dec_NN(aTHX_ MUTABLE_SV(sv))
 
 #define SVTYPEMASK     0xff
 #define SvTYPE(sv)     ((svtype)((sv)->sv_flags & SVTYPEMASK))
@@ -429,7 +437,7 @@ perform the upgrade if necessary.  See C<L</svtype>>.
 
 #define PRIVSHIFT 4    /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */
 
-/* SVf_AMAGIC means that the stash *may* have have overload methods. It's
+/* SVf_AMAGIC means that the stash *may* have overload methods. It's
  * set each time a function is compiled into a stash, and is reset by the
  * overload code when called for the first time and finds that there are
  * no overload methods. Note that this used to be set on the object; but
@@ -699,12 +707,12 @@ Tells an SV that it is an unsigned integer and disables all other C<OK> bits.
 =for apidoc Am|bool|SvIOK_UV|SV* sv
 Returns a boolean indicating whether the SV contains an integer that must be
 interpreted as unsigned.  A non-negative integer whose value is within the
-range of both an IV and a UV may be be flagged as either C<SvUOK> or C<SVIOK>.
+range of both an IV and a UV may be flagged as either C<SvUOK> or C<SvIOK>.
 
 =for apidoc Am|bool|SvUOK|SV* sv
 Returns a boolean indicating whether the SV contains an integer that must be
 interpreted as unsigned.  A non-negative integer whose value is within the
-range of both an IV and a UV may be be flagged as either C<SvUOK> or C<SVIOK>.
+range of both an IV and a UV may be flagged as either C<SvUOK> or C<SvIOK>.
 
 =for apidoc Am|bool|SvIOK_notUV|SV* sv
 Returns a boolean indicating whether the SV contains a signed integer.
@@ -766,6 +774,9 @@ Only use when you are sure C<SvIOK> is true.  See also C<L</SvIV>>.
 Returns the raw value in the SV's UV slot, without checks or conversions.
 Only use when you are sure C<SvIOK> is true.  See also C<L</SvUV>>.
 
+=for apidoc AmD|UV|SvUVXx|SV* sv
+This is an unnecessary synonym for L</SvUVX>
+
 =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 C<SvNOK> is true.  See also C<L</SvNV>>.
@@ -818,8 +829,8 @@ Remember to free the previous PV buffer. There are many things to check.
 Beware that the existing pointer may be involved in copy-on-write or other
 mischief, so do C<SvOOK_off(sv)> and use C<sv_force_normal> or
 C<SvPV_force> (or check the C<SvIsCOW> flag) first to make sure this
-modification is safe. Then finally, if it is not a COW, call C<SvPV_free> to
-free the previous PV buffer.
+modification is safe. Then finally, if it is not a COW, call
+C<L</SvPV_free>> to free the previous PV buffer.
 
 =for apidoc Am|void|SvUV_set|SV* sv|UV val
 Set the value of the UV pointer in C<sv> to val.  See C<L</SvIV_set>>.
@@ -943,12 +954,28 @@ in gv.h: */
 
 #define SvVOK(sv)              (SvMAGICAL(sv)                          \
                                 && mg_find(sv,PERL_MAGIC_vstring))
-/* returns the vstring magic, if any */
+/*
+=for apidoc Am|MAGIC*|SvVSTRING_mg|SV * sv
+
+Returns the vstring magic, or NULL if none
+
+=cut
+*/
 #define SvVSTRING_mg(sv)       (SvMAGICAL(sv) \
                                 ? mg_find(sv,PERL_MAGIC_vstring) : NULL)
 
 #define SvOOK(sv)              (SvFLAGS(sv) & SVf_OOK)
 #define SvOOK_on(sv)           (SvFLAGS(sv) |= SVf_OOK)
+
+
+/*
+=for apidoc Am|void|SvOOK_off|SV * sv
+
+Remove any string offset.
+
+=cut
+*/
+
 #define SvOOK_off(sv)          ((void)(SvOOK(sv) && (sv_backoff(sv),0)))
 
 #define SvFAKE(sv)             (SvFLAGS(sv) & SVf_FAKE)
@@ -1078,8 +1105,8 @@ C<sv_force_normal> does nothing.
 
 #define SvPADTMP_on(sv)                (SvFLAGS(sv) |= SVs_PADTMP)
 #define SvPADTMP_off(sv)       (SvFLAGS(sv) &= ~SVs_PADTMP)
-#define SvPADSTALE_on(sv)      S_SvPADSTALE_on(MUTABLE_SV(sv))
-#define SvPADSTALE_off(sv)     S_SvPADSTALE_off(MUTABLE_SV(sv))
+#define SvPADSTALE_on(sv)      Perl_SvPADSTALE_on(MUTABLE_SV(sv))
+#define SvPADSTALE_off(sv)     Perl_SvPADSTALE_off(MUTABLE_SV(sv))
 
 #define SvTEMP(sv)             (SvFLAGS(sv) & SVs_TEMP)
 #define SvTEMP_on(sv)          (SvFLAGS(sv) |= SVs_TEMP)
@@ -1092,7 +1119,7 @@ C<sv_force_normal> does nothing.
 /*
 =for apidoc Am|U32|SvREADONLY|SV* sv
 Returns true if the argument is readonly, otherwise returns false.
-Exposed to to perl code via Internals::SvREADONLY().
+Exposed to perl code via Internals::SvREADONLY().
 
 =for apidoc Am|U32|SvREADONLY_on|SV* sv
 Mark an object as readonly. Exactly what this means depends on the object
@@ -1125,7 +1152,7 @@ object type. Exposed to perl code via Internals::SvREADONLY().
 #endif
 
 
-#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#if defined (DEBUGGING) && defined(PERL_USE_GCC_BRACE_GROUPS)
 #  define SvTAIL(sv)   ({ const SV *const _svtail = (const SV *)(sv);  \
                            assert(SvTYPE(_svtail) != SVt_PVAV);        \
                            assert(SvTYPE(_svtail) != SVt_PVHV);        \
@@ -1170,10 +1197,14 @@ object type. Exposed to perl code via Internals::SvREADONLY().
 #  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
+# ifdef PERL_CORE
+#  define SvLEN(sv) (0 + ((XPV*) SvANY(sv))->xpv_len)
+# else
 #  define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len
+# endif
 #  define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
 
-#  if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#  if defined (DEBUGGING) && defined(PERL_USE_GCC_BRACE_GROUPS)
 /* These get expanded inside other macros that already use a variable _sv  */
 #    define SvPVX(sv)                                                  \
        (*({ SV *const _svpvx = MUTABLE_SV(sv);                         \
@@ -1183,6 +1214,16 @@ object type. Exposed to perl code via Internals::SvREADONLY().
                     && !(IoFLAGS(_svpvx) & IOf_FAKE_DIRP)));           \
            &((_svpvx)->sv_u.svu_pv);                                   \
         }))
+#   ifdef PERL_CORE
+#    define SvCUR(sv)                                                  \
+       ({ const SV *const _svcur = (const SV *)(sv);                   \
+           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);             \
+        })
+#   else
 #    define SvCUR(sv)                                                  \
        (*({ const SV *const _svcur = (const SV *)(sv);                 \
            assert(PL_valid_types_PVX[SvTYPE(_svcur) & SVt_MASK]);      \
@@ -1191,6 +1232,7 @@ object type. Exposed to perl code via Internals::SvREADONLY().
                     && !(IoFLAGS(_svcur) & IOf_FAKE_DIRP)));           \
            &(((XPV*) MUTABLE_PTR(SvANY(_svcur)))->xpv_cur);            \
         }))
+#   endif
 #    define SvIVX(sv)                                                  \
        (*({ const SV *const _svivx = (const SV *)(sv);                 \
            assert(PL_valid_types_IVX[SvTYPE(_svivx) & SVt_MASK]);      \
@@ -1250,7 +1292,7 @@ object type. Exposed to perl code via Internals::SvREADONLY().
 
 #ifndef PERL_POISON
 /* Given that these two are new, there can't be any existing code using them
- *  as LVALUEs  */
+ *  as LVALUEs, so prevent that from happening  */
 #  define SvPVX_mutable(sv)    (0 + (sv)->sv_u.svu_pv)
 #  define SvPVX_const(sv)      ((const char*)(0 + (sv)->sv_u.svu_pv))
 #else
@@ -1343,6 +1385,14 @@ object type. Exposed to perl code via Internals::SvREADONLY().
                   SvPV_renew(sv, _lEnGtH); \
                 } STMT_END
 
+/*
+=for apidoc Am|void|SvPV_free|SV * sv
+
+Frees the PV buffer in C<sv>, leaving things in a precarious state, so should
+only be used as part of a larger operation
+
+=cut
+*/
 #define SvPV_free(sv)                                                  \
     STMT_START {                                                       \
                     assert(SvTYPE(sv) >= SVt_PV);                      \
@@ -1377,7 +1427,7 @@ object type. Exposed to perl code via Internals::SvREADONLY().
 #  define BmFLAGS(sv)          (SvTAIL(sv) ? FBMcf_TAIL : 0)
 #endif
 
-#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#if defined (DEBUGGING) && defined(PERL_USE_GCC_BRACE_GROUPS)
 #  define BmUSEFUL(sv)                                                 \
        (*({ SV *const _bmuseful = MUTABLE_SV(sv);                      \
            assert(SvTYPE(_bmuseful) >= SVt_PVIV);                      \
@@ -1586,27 +1636,57 @@ false.  See C<L</SvOK>> for a defined/undefined test.  Handles 'get' magic
 unless the scalar is already C<SvPOK>, C<SvIOK> or C<SvNOK> (the public, not the
 private flags).
 
+As of Perl 5.32, this is guaranteed to evaluate C<sv> only once.  Prior to that
+release, use C<L</SvTRUEx>> for single evaluation.
+
 =for apidoc Am|bool|SvTRUE_nomg|SV* sv
 Returns a boolean indicating whether Perl would evaluate the SV as true or
 false.  See C<L</SvOK>> for a defined/undefined test.  Does not handle 'get' magic.
 
+=for apidoc Am|bool|SvTRUEx|SV* sv
+Identical to C<L</SvTRUE>>.  Prior to 5.32, they differed in that only this one
+was guaranteed to evaluate C<sv> only once; in 5.32 they both evaluated it
+once, but C<SvTRUEx> was slightly slower on some platforms; now they are
+identical.
+
 =for apidoc Am|char*|SvPVutf8_force|SV* sv|STRLEN len
 Like C<SvPV_force>, but converts C<sv> to UTF-8 first if necessary.
 
 =for apidoc Am|char*|SvPVutf8|SV* sv|STRLEN len
 Like C<SvPV>, but converts C<sv> to UTF-8 first if necessary.
 
+=for apidoc Am|char*|SvPVutf8_nomg|SV* sv|STRLEN len
+Like C<SvPVutf8>, but does not process get magic.
+
+=for apidoc Am|char*|SvPVutf8_or_null|SV* sv|STRLEN len
+Like C<SvPVutf8>, but when C<sv> is undef, returns C<NULL>.
+
+=for apidoc Am|char*|SvPVutf8_or_null_nomg|SV* sv|STRLEN len
+Like C<SvPVutf8_or_null>, but does not process get magic.
+
 =for apidoc Am|char*|SvPVutf8_nolen|SV* sv
 Like C<SvPV_nolen>, but converts C<sv> to UTF-8 first if necessary.
 
 =for apidoc Am|char*|SvPVbyte_force|SV* sv|STRLEN len
-Like C<SvPV_force>, but converts C<sv> to byte representation first if necessary.
+Like C<SvPV_force>, but converts C<sv> to byte representation first if
+necessary.  If the SV cannot be downgraded from UTF-8, this croaks.
 
 =for apidoc Am|char*|SvPVbyte|SV* sv|STRLEN len
-Like C<SvPV>, but converts C<sv> to byte representation first if necessary.
+Like C<SvPV>, but converts C<sv> to byte representation first if necessary.  If
+the SV cannot be downgraded from UTF-8, this croaks.
+
+=for apidoc Am|char*|SvPVbyte_nomg|SV* sv|STRLEN len
+Like C<SvPVbyte>, but does not process get magic.
+
+=for apidoc Am|char*|SvPVbyte_or_null|SV* sv|STRLEN len
+Like C<SvPVbyte>, but when C<sv> is undef, returns C<NULL>.
+
+=for apidoc Am|char*|SvPVbyte_or_null_nomg|SV* sv|STRLEN len
+Like C<SvPVbyte_or_null>, but does not process get magic.
 
 =for apidoc Am|char*|SvPVbyte_nolen|SV* sv
-Like C<SvPV_nolen>, but converts C<sv> to byte representation first if necessary.
+Like C<SvPV_nolen>, but converts C<sv> to byte representation first if
+necessary.  If the SV cannot be downgraded from UTF-8, this croaks.
 
 =for apidoc Am|char*|SvPVutf8x_force|SV* sv|STRLEN len
 Like C<SvPV_force>, but converts C<sv> to UTF-8 first if necessary.
@@ -1621,12 +1701,12 @@ otherwise.
 =for apidoc Am|char*|SvPVbytex_force|SV* sv|STRLEN len
 Like C<SvPV_force>, but converts C<sv> to byte representation first if necessary.
 Guarantees to evaluate C<sv> only once; use the more efficient C<SvPVbyte_force>
-otherwise.
+otherwise.  If the SV cannot be downgraded from UTF-8, this croaks.
 
 =for apidoc Am|char*|SvPVbytex|SV* sv|STRLEN len
 Like C<SvPV>, but converts C<sv> to byte representation first if necessary.
 Guarantees to evaluate C<sv> only once; use the more efficient C<SvPVbyte>
-otherwise.
+otherwise.  If the SV cannot be downgraded from UTF-8, this croaks.
 
 =for apidoc Am|U32|SvIsCOW|SV* sv
 Returns a U32 value indicating whether the SV is Copy-On-Write (either shared
@@ -1637,22 +1717,9 @@ COW).
 Returns a boolean indicating whether the SV is Copy-On-Write shared hash key
 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.
-
-=for apidoc Am|void|sv_catsv_nomg|SV* dsv|SV* ssv
-Like C<sv_catsv> but doesn't process magic.
-
-=for apidoc Amdb|STRLEN|sv_utf8_upgrade_nomg|NN SV *sv
-
-Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
-
 =cut
 */
 
@@ -1662,50 +1729,50 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<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 SvUV_nomg(sv) (SvUOK(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_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC)
+#define SvPV(sv, len)         SvPV_flags(sv, len, SV_GMAGIC)
+#define SvPV_const(sv, len)   SvPV_flags_const(sv, len, SV_GMAGIC)
+#define SvPV_mutable(sv, len) SvPV_flags_mutable(sv, len, SV_GMAGIC)
 
-#define SvPV_flags(sv, lp, flags) \
+#define SvPV_flags(sv, len, flags) \
     (SvPOK_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags))
-#define SvPV_flags_const(sv, lp, flags) \
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &len, flags))
+#define SvPV_flags_const(sv, len, flags) \
     (SvPOK_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \
-     (const char*) sv_2pv_flags(sv, &lp, (flags|SV_CONST_RETURN)))
+     ? ((len = SvCUR(sv)), SvPVX_const(sv)) : \
+     (const char*) sv_2pv_flags(sv, &len, (flags|SV_CONST_RETURN)))
 #define SvPV_flags_const_nolen(sv, flags) \
     (SvPOK_nog(sv) \
      ? SvPVX_const(sv) : \
      (const char*) sv_2pv_flags(sv, 0, (flags|SV_CONST_RETURN)))
-#define SvPV_flags_mutable(sv, lp, flags) \
+#define SvPV_flags_mutable(sv, len, flags) \
     (SvPOK_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \
-     sv_2pv_flags(sv, &lp, (flags|SV_MUTABLE_RETURN)))
+     ? ((len = SvCUR(sv)), SvPVX_mutable(sv)) : \
+     sv_2pv_flags(sv, &len, (flags|SV_MUTABLE_RETURN)))
 
-#define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, SV_GMAGIC)
+#define SvPV_force(sv, len) SvPV_force_flags(sv, len, SV_GMAGIC)
 #define SvPV_force_nolen(sv) SvPV_force_flags_nolen(sv, SV_GMAGIC)
-#define SvPV_force_mutable(sv, lp) SvPV_force_flags_mutable(sv, lp, SV_GMAGIC)
+#define SvPV_force_mutable(sv, len) SvPV_force_flags_mutable(sv, len, SV_GMAGIC)
 
-#define SvPV_force_nomg(sv, lp) SvPV_force_flags(sv, lp, 0)
+#define SvPV_force_nomg(sv, len) SvPV_force_flags(sv, len, 0)
 #define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0)
 
-#define SvPV_force_flags(sv, lp, flags) \
+#define SvPV_force_flags(sv, len, flags) \
     (SvPOK_pure_nogthink(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &len, flags))
 
 #define SvPV_force_flags_nolen(sv, flags) \
     (SvPOK_pure_nogthink(sv) \
      ? SvPVX(sv) : sv_pvn_force_flags(sv, 0, flags))
 
-#define SvPV_force_flags_mutable(sv, lp, flags) \
+#define SvPV_force_flags_mutable(sv, len, flags) \
     (SvPOK_pure_nogthink(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \
-     : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
+     ? ((len = SvCUR(sv)), SvPVX_mutable(sv)) \
+     : sv_pvn_force_flags(sv, &len, flags|SV_MUTABLE_RETURN))
 
 #define SvPV_nolen(sv) \
     (SvPOK_nog(sv) \
@@ -1720,19 +1787,33 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
     (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)
-#define SvPV_nomg_const(sv, lp) SvPV_flags_const(sv, lp, 0)
+#define SvPV_nomg(sv, len) SvPV_flags(sv, len, 0)
+#define SvPV_nomg_const(sv, len) SvPV_flags_const(sv, len, 0)
 #define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0)
 
 /* ----*/
 
-#define SvPVutf8(sv, lp) \
+#define SvPVutf8(sv, len) \
     (SvPOK_utf8_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &len))
 
-#define SvPVutf8_force(sv, lp) \
+#define SvPVutf8_or_null(sv, len) \
+    (SvPOK_utf8_nog(sv) \
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : (SvGETMAGIC(sv), SvOK(sv)) \
+     ? sv_2pvutf8_flags(sv, &len, 0) : ((len = 0), NULL))
+
+#define SvPVutf8_nomg(sv, len) \
+    (SvPOK_utf8_nog(sv) \
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8_flags(sv, &len, 0))
+
+#define SvPVutf8_or_null_nomg(sv, len) \
+    (SvPOK_utf8_nog(sv) \
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : SvOK(sv) \
+     ? sv_2pvutf8_flags(sv, &len, 0) : ((len = 0), NULL))
+
+#define SvPVutf8_force(sv, len) \
     (SvPOK_utf8_pure_nogthink(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &len))
 
 #define SvPVutf8_nolen(sv) \
     (SvPOK_utf8_nog(sv) \
@@ -1740,13 +1821,27 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
 
 /* ----*/
 
-#define SvPVbyte(sv, lp) \
+#define SvPVbyte(sv, len) \
+    (SvPOK_byte_nog(sv) \
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &len))
+
+#define SvPVbyte_or_null(sv, len) \
+    (SvPOK_byte_nog(sv) \
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : (SvGETMAGIC(sv), SvOK(sv)) \
+     ? sv_2pvbyte_flags(sv, &len, 0) : ((len = 0), NULL))
+
+#define SvPVbyte_nomg(sv, len) \
     (SvPOK_byte_nog(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte_flags(sv, &len, 0))
+
+#define SvPVbyte_or_null_nomg(sv, len) \
+    (SvPOK_utf8_nog(sv) \
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : SvOK(sv) \
+     ? sv_2pvbyte_flags(sv, &len, 0) : ((len = 0), NULL))
 
-#define SvPVbyte_force(sv, lp) \
+#define SvPVbyte_force(sv, len) \
     (SvPOK_byte_pure_nogthink(sv) \
-     ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvbyten_force(sv, &lp))
+     ? ((len = SvCUR(sv)), SvPVX(sv)) : sv_pvbyten_force(sv, &len))
 
 #define SvPVbyte_nolen(sv) \
     (SvPOK_byte_nog(sv) \
@@ -1758,11 +1853,12 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
  * failing that, call a function to do the work
  */
 
-#define SvPVx_force(sv, lp) sv_pvn_force(sv, &lp)
-#define SvPVutf8x_force(sv, lp) sv_pvutf8n_force(sv, &lp)
-#define SvPVbytex_force(sv, lp) sv_pvbyten_force(sv, &lp)
+#define SvPVx_force(sv, len) sv_pvn_force(sv, &len)
+#define SvPVutf8x_force(sv, len) sv_pvutf8n_force(sv, &len)
+#define SvPVbytex_force(sv, len) sv_pvbyten_force(sv, &len)
 
-#define SvTRUE(sv)         (LIKELY(sv) && SvTRUE_NN(sv))
+#define SvTRUE(sv)         Perl_SvTRUE(aTHX_ sv)
+#define SvTRUEx(sv)        SvTRUE(sv)
 #define SvTRUE_nomg(sv)    (LIKELY(sv) && SvTRUE_nomg_NN(sv))
 #define SvTRUE_NN(sv)      (SvGETMAGIC(sv), SvTRUE_nomg_NN(sv))
 #define SvTRUE_nomg_NN(sv) (SvTRUE_common(sv, sv_2bool_nomg(sv)))
@@ -1775,25 +1871,24 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
     : SvPOK(sv)                                                \
        ? SvPVXtrue(sv)                                 \
     : SvIOK(sv)                                                \
-        ? SvIVX(sv)                                     \
+        ? (SvIVX(sv) != 0 /* cast to bool */)           \
     : (SvROK(sv) && !(   SvOBJECT(SvRV(sv))             \
                       && HvAMAGIC(SvSTASH(SvRV(sv)))))  \
         ? TRUE                                          \
     : (fallback))
 
-#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
+#if defined(PERL_USE_GCC_BRACE_GROUPS)
 
 #  define SvIVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvIV(_sv); })
 #  define SvUVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvUV(_sv); })
 #  define SvNVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvNV(_sv); })
-#  define SvPVx(sv, lp) ({SV *_sv = (sv); SvPV(_sv, lp); })
-#  define SvPVx_const(sv, lp) ({SV *_sv = (sv); SvPV_const(_sv, lp); })
+#  define SvPVx(sv, len) ({SV *_sv = (sv); SvPV(_sv, len); })
+#  define SvPVx_const(sv, len) ({SV *_sv = (sv); SvPV_const(_sv, len); })
 #  define SvPVx_nolen(sv) ({SV *_sv = (sv); SvPV_nolen(_sv); })
 #  define SvPVx_nolen_const(sv) ({SV *_sv = (sv); SvPV_nolen_const(_sv); })
-#  define SvPVutf8x(sv, lp) ({SV *_sv = (sv); SvPVutf8(_sv, lp); })
-#  define SvPVbytex(sv, lp) ({SV *_sv = (sv); SvPVbyte(_sv, lp); })
+#  define SvPVutf8x(sv, len) ({SV *_sv = (sv); SvPVutf8(_sv, len); })
+#  define SvPVbytex(sv, len) ({SV *_sv = (sv); SvPVbyte(_sv, len); })
 #  define SvPVbytex_nolen(sv) ({SV *_sv = (sv); SvPVbyte_nolen(_sv); })
-#  define SvTRUEx(sv)      ({SV *_sv = (sv); SvTRUE(_sv); })
 #  define SvTRUEx_nomg(sv) ({SV *_sv = (sv); SvTRUE_nomg(_sv); })
 
 #else /* __GNUC__ */
@@ -1804,14 +1899,13 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
 #  define SvIVx(sv) ((PL_Sv = (sv)), SvIV(PL_Sv))
 #  define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv))
 #  define SvNVx(sv) ((PL_Sv = (sv)), SvNV(PL_Sv))
-#  define SvPVx(sv, lp) ((PL_Sv = (sv)), SvPV(PL_Sv, lp))
-#  define SvPVx_const(sv, lp) ((PL_Sv = (sv)), SvPV_const(PL_Sv, lp))
+#  define SvPVx(sv, len) ((PL_Sv = (sv)), SvPV(PL_Sv, len))
+#  define SvPVx_const(sv, len) ((PL_Sv = (sv)), SvPV_const(PL_Sv, len))
 #  define SvPVx_nolen(sv) ((PL_Sv = (sv)), SvPV_nolen(PL_Sv))
 #  define SvPVx_nolen_const(sv) ((PL_Sv = (sv)), SvPV_nolen_const(PL_Sv))
-#  define SvPVutf8x(sv, lp) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, lp))
-#  define SvPVbytex(sv, lp) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, lp))
+#  define SvPVutf8x(sv, len) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, len))
+#  define SvPVbytex(sv, len) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, len))
 #  define SvPVbytex_nolen(sv) ((PL_Sv = (sv)), SvPVbyte_nolen(PL_Sv))
-#  define SvTRUEx(sv)      ((PL_Sv = (sv)), SvTRUE(PL_Sv))
 #  define SvTRUEx_nomg(sv) ((PL_Sv = (sv)), SvTRUE_nomg(PL_Sv))
 #endif /* __GNU__ */
 
@@ -1837,6 +1931,13 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
 
 /* flag values for sv_*_flags functions */
 #define SV_UTF8_NO_ENCODING    0       /* No longer used */
+
+/*
+=for apidoc AmnhD||SV_UTF8_NO_ENCODING
+
+=cut
+*/
+
 #define SV_IMMEDIATE_UNREF     1
 #define SV_GMAGIC              2
 #define SV_COW_DROP_PV         4
@@ -1899,7 +2000,7 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
                            && SvCUR(sv)+1 < SvLEN(sv))
    /* Note: To allow 256 COW "copies", a refcnt of 0 means 1. */
 #   define CowREFCNT(sv)       (*(U8 *)(SvPVX(sv)+SvLEN(sv)-1))
-#   define SV_COW_REFCNT_MAX   ((1 << sizeof(U8)*8) - 1)
+#   define SV_COW_REFCNT_MAX   nBIT_UMAX(sizeof(U8) * CHARBITS)
 #   define CAN_COW_MASK        (SVf_POK|SVf_ROK|SVp_POK|SVf_FAKE| \
                         SVf_OOK|SVf_BREAK|SVf_READONLY|SVf_PROTECT)
 #endif
@@ -1919,6 +2020,8 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
 #define sv_pvn_force_nomg(sv, lp) sv_pvn_force_flags(sv, lp, 0)
 #define sv_utf8_upgrade_flags(sv, flags) sv_utf8_upgrade_flags_grow(sv, flags, 0)
 #define sv_utf8_upgrade_nomg(sv) sv_utf8_upgrade_flags(sv, 0)
+#define sv_utf8_downgrade(sv, fail_ok) sv_utf8_downgrade_flags(sv, fail_ok, SV_GMAGIC)
+#define sv_utf8_downgrade_nomg(sv, fail_ok) sv_utf8_downgrade_flags(sv, fail_ok, 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) \
@@ -1928,12 +2031,14 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
 #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(dsv, sstr, slen) sv_catpvn_flags(dsv, 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(sv, lp) sv_2pvbyte_flags(sv, lp, SV_GMAGIC)
 #define sv_2pvbyte_nolen(sv) sv_2pvbyte(sv, 0)
+#define sv_2pvutf8(sv, lp) sv_2pvutf8_flags(sv, lp, SV_GMAGIC)
 #define sv_2pvutf8_nolen(sv) sv_2pvutf8(sv, 0)
 #define sv_2pv_nomg(sv, lp) sv_2pv_flags(sv, lp, 0)
 #define sv_pvn_force(sv, lp) sv_pvn_force_flags(sv, lp, SV_GMAGIC)
@@ -1944,7 +2049,7 @@ Like C<sv_utf8_upgrade>, but doesn't do magic on C<sv>.
 #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_collxfrm(sv, nxp) sv_collxfrm_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)              \
@@ -1994,15 +2099,15 @@ incremented.
 /* the following macros update any magic values this C<sv> is associated with */
 
 /*
-=head1 Magical Functions
+=for apidoc_section $magic
 
 =for apidoc Am|void|SvGETMAGIC|SV* sv
-Invokes C<mg_get> on an SV if it has 'get' magic.  For example, this
+Invokes C<L</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 is necessary
+Invokes C<L</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.
@@ -2033,7 +2138,7 @@ has been loaded.
 Releases a mutual exclusion lock on C<sv> if a suitable module
 has been loaded.
 
-=head1 SV Manipulation Functions
+=for apidoc_section $SV
 
 =for apidoc Am|char *|SvGROW|SV* sv|STRLEN len
 Expands the character buffer in the SV so that it has room for the
@@ -2131,6 +2236,13 @@ See also C<L</PL_sv_yes>> and C<L</PL_sv_no>>.
 #define isGV(sv) (SvTYPE(sv) == SVt_PVGV)
 /* If I give every macro argument a different name, then there won't be bugs
    where nested macros get confused. Been there, done that.  */
+/*
+=for apidoc Am|bool|isGV_with_GP|SV * sv
+Returns a boolean as to whether or not C<sv> is a GV with a pointer to a GP
+(glob pointer).
+
+=cut
+*/
 #define isGV_with_GP(pwadak) \
        (((SvFLAGS(pwadak) & (SVp_POK|SVpgv_GP)) == SVpgv_GP)   \
        && (SvTYPE(pwadak) == SVt_PVGV || SvTYPE(pwadak) == SVt_PVLV))
@@ -2146,6 +2258,10 @@ See also C<L</PL_sv_yes>> and C<L</PL_sv_no>>.
        assert (!SvIOKp(sv));                                          \
        (SvFLAGS(sv) &= ~SVpgv_GP);                                    \
     } STMT_END
+#ifdef PERL_CORE
+# define isGV_or_RVCV(kadawp) \
+    (isGV(kadawp) || (SvROK(kadawp) && SvTYPE(SvRV(kadawp)) == SVt_PVCV))
+#endif
 #define isREGEXP(sv) \
     (SvTYPE(sv) == SVt_REGEXP                                \
      || (SvFLAGS(sv) & (SVTYPEMASK|SVpgv_GP|SVf_FAKE))        \
@@ -2175,8 +2291,13 @@ struct clone_params {
   AV *unreferenced;
 };
 
+/* SV_NOSTEAL prevents TEMP buffers being, well, stolen, and saves games
+   with SvTEMP_off and SvTEMP_on round a call to sv_setsv.  */
+#define newSVsv(sv) newSVsv_flags((sv), SV_GMAGIC|SV_NOSTEAL)
+#define newSVsv_nomg(sv) newSVsv_flags((sv), SV_NOSTEAL)
+
 /*
-=for apidoc Am|SV*|newSVpvn_utf8|NULLOK const char* s|STRLEN len|U32 utf8
+=for apidoc Am|SV*|newSVpvn_utf8|const char* s|STRLEN len|U32 utf8
 
 Creates a new SV and copies a string (which may contain C<NUL> (C<\0>)
 characters) into it.  If C<utf8> is true, calls
@@ -2198,7 +2319,7 @@ Creates a new SV containing the pad name.
 #define newSVpadname(pn) newSVpvn_utf8(PadnamePV(pn), PadnameLEN(pn), TRUE)
 
 /*
-=for apidoc Am|void|SvOOK_offset|NN SV*sv|STRLEN len
+=for apidoc Am|void|SvOOK_offset|SV*sv|STRLEN len
 
 Reads into C<len> the offset from C<SvPVX> back to the true start of the
 allocated buffer, which will be non-zero if C<sv_chop> has been used to
@@ -2215,7 +2336,7 @@ Evaluates C<sv> more than once.  Sets C<len> to 0 if C<SvOOK(sv)> is false.
 10:28 <+meta> Nicholas: crash
 */
 #  define SvOOK_offset(sv, offset) STMT_START {                                \
-       assert(sizeof(offset) == sizeof(STRLEN));                       \
+       STATIC_ASSERT_STMT(sizeof(offset) == sizeof(STRLEN));           \
        if (SvOOK(sv)) {                                                \
            const U8 *_crash = (U8*)SvPVX_const(sv);                    \
            (offset) = *--_crash;                                       \
@@ -2239,7 +2360,7 @@ Evaluates C<sv> more than once.  Sets C<len> to 0 if C<SvOOK(sv)> is false.
 #else
     /* This is the same code, but avoids using any temporary variables:  */
 #  define SvOOK_offset(sv, offset) STMT_START {                                \
-       assert(sizeof(offset) == sizeof(STRLEN));                       \
+       STATIC_ASSERT_STMT(sizeof(offset) == sizeof(STRLEN));           \
        if (SvOOK(sv)) {                                                \
            (offset) = ((U8*)SvPVX_const(sv))[-1];                      \
            if (!(offset)) {                                            \