Add the Perl 5 to Perl 5 convertor scripts.
[p5sagit/p5-mst-13.2.git] / sv.h
diff --git a/sv.h b/sv.h
index 102c790..d91957c 100644 (file)
--- a/sv.h
+++ b/sv.h
@@ -97,6 +97,7 @@ typedef struct hek HEK;
        char*   svu_pv;         /* pointer to malloced string */        \
        SV**    svu_array;              \
        HE**    svu_hash;               \
+       GP*     svu_gp;                 \
     }  sv_u
 
 
@@ -149,6 +150,41 @@ Returns the value of the object's reference count.
 =for apidoc Am|SV*|SvREFCNT_inc|SV* sv
 Increments the reference count of the given SV.
 
+All of the following SvREFCNT_inc* macros are optimized versions of
+SvREFCNT_inc, and can be replaced with SvREFCNT_inc.
+
+=for apidoc Am|SV*|SvREFCNT_inc_NN|SV* sv
+Same as SvREFCNT_inc, but can only be used if you know I<sv>
+is not NULL.  Since we don't have to check the NULLness, it's faster
+and smaller.
+
+=for apidoc Am|SV*|SvREFCNT_inc_void|SV* sv
+Same as 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.
+
+=for apidoc Am|SV*|SvREFCNT_inc_void_NN|SV* sv
+Same as SvREFCNT_inc, but can only be used if you don't need the return
+value, and you know that I<sv> is not NULL.  The macro doesn't need
+to return a meaningful value, or check for NULLness, so it's smaller
+and faster.
+
+=for apidoc Am|SV*|SvREFCNT_inc_simple|SV* sv
+Same as SvREFCNT_inc, but can only be used with simple variables, not
+expressions or pointer dereferences.  Since we don't have to store a
+temporary value, it's faster.
+
+=for apidoc Am|SV*|SvREFCNT_inc_simple_NN|SV* sv
+Same as SvREFCNT_inc_simple, but can only be used if you know I<sv>
+is not NULL.  Since we don't have to check the NULLness, it's faster
+and smaller.
+
+=for apidoc Am|SV*|SvREFCNT_inc_simple_void|SV* sv
+Same as SvREFCNT_inc_simple, but can only be used if you don't need the
+return value.  The macro doesn't need to return a meaningful value.
+
+=for apidoc Am|SV*|SvREFCNT_inc|SV* sv
+Increments the reference count of the given SV.
+
 =for apidoc Am|void|SvREFCNT_dec|SV* sv
 Decrements the reference count of the given SV.
 
@@ -174,11 +210,41 @@ perform the upgrade if necessary.  See C<svtype>.
             (SvREFCNT(_sv))++;         \
        _sv;                            \
     })
+#  define SvREFCNT_inc_simple(sv)      \
+    ({                                 \
+       if (sv)                         \
+            (SvREFCNT(sv))++;          \
+       (SV *)(sv);                             \
+    })
+#  define SvREFCNT_inc_NN(sv)          \
+    ({                                 \
+       SV * const _sv = (SV*)(sv);     \
+       SvREFCNT(_sv)++;                \
+       _sv;                            \
+    })
+#  define SvREFCNT_inc_void(sv)                \
+    ({                                 \
+       SV * const _sv = (SV*)(sv);     \
+       if (_sv)                        \
+           (void)(SvREFCNT(_sv)++);    \
+    })
 #else
 #  define SvREFCNT_inc(sv)     \
-       ((PL_Sv=(SV*)(sv)) ? ((++(SvREFCNT(PL_Sv))),(PL_Sv)) : NULL)
+       ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL)
+#  define SvREFCNT_inc_simple(sv) \
+       ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL)
+#  define SvREFCNT_inc_NN(sv) \
+       (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv)
+#  define SvREFCNT_inc_void(sv) \
+       (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0)
 #endif
 
+/* These guys don't need the curly blocks */
+#define SvREFCNT_inc_simple_void(sv)   if (sv) (SvREFCNT(sv)++);
+#define SvREFCNT_inc_simple_NN(sv)     (++(SvREFCNT(sv)),(SV*)(sv))
+#define SvREFCNT_inc_void_NN(sv)       (void)(++SvREFCNT((SV*)(sv)))
+#define SvREFCNT_inc_simple_void_NN(sv)        (void)(++SvREFCNT((SV*)(sv)))
+
 #if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC)
 #  define SvREFCNT_dec(sv)             \
     ({                                 \
@@ -300,7 +366,10 @@ perform the upgrade if necessary.  See C<svtype>.
 
 
 struct xpv {
-    NV         xnv_nv;         /* numeric value, if any */
+    union {
+       NV      xnv_nv;         /* numeric value, if any */
+       HV *    xgv_stash;
+    }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
 };
@@ -315,7 +384,10 @@ typedef struct {
 #endif
 
 struct xpviv {
-    NV         xnv_nv;         /* numeric value, if any */
+    union {
+       NV      xnv_nv;         /* numeric value, if any */
+       HV *    xgv_stash;
+    }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
@@ -323,6 +395,7 @@ struct xpviv {
        UV      xivu_uv;
        void *  xivu_p1;
        I32     xivu_i32;
+       HEK *   xivu_namehek;
     }          xiv_u;
 };
 
@@ -337,6 +410,7 @@ typedef struct {
        UV      xivu_uv;
        void *  xivu_p1;
        I32     xivu_i32;
+       HEK *   xivu_namehek;
     }          xiv_u;
 } xpviv_allocated;
 #endif
@@ -344,20 +418,27 @@ typedef struct {
 #define xiv_iv xiv_u.xivu_iv
 
 struct xpvuv {
-    NV         xnv_nv;         /* numeric value, if any */
+    union {
+       NV      xnv_nv;         /* numeric value, if any */
+       HV *    xgv_stash;
+    }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
        IV      xuvu_iv;
        UV      xuvu_uv;        /* unsigned value or pv offset */
        void *  xuvu_p1;
+       HEK *   xivu_namehek;
     }          xuv_u;
 };
 
 #define xuv_uv xuv_u.xuvu_uv
 
 struct xpvnv {
-    NV         xnv_nv;         /* numeric value, if any */
+    union {
+       NV      xnv_nv;         /* numeric value, if any */
+       HV *    xgv_stash;
+    }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
@@ -365,12 +446,16 @@ struct xpvnv {
        UV      xivu_uv;
        void *  xivu_p1;
        I32     xivu_i32;
+       HEK *   xivu_namehek;
     }          xiv_u;
 };
 
 /* These structure must match the beginning of struct xpvhv in hv.h. */
 struct xpvmg {
-    NV         xnv_nv;         /* numeric value, if any */
+    union {
+       NV      xnv_nv;         /* numeric value, if any */
+       HV *    xgv_stash;
+    }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
@@ -378,6 +463,7 @@ struct xpvmg {
        UV      xivu_uv;
        void *  xivu_p1;
        I32     xivu_i32;
+       HEK *   xivu_namehek;
     }          xiv_u;
     union {
        MAGIC*  xmg_magic;      /* linked list of magicalness */
@@ -387,7 +473,10 @@ struct xpvmg {
 };
 
 struct xpvlv {
-    NV         xnv_nv;         /* numeric value, if any */
+    union {
+       NV      xnv_nv;         /* numeric value, if any */
+       HV *    xgv_stash;
+    }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
@@ -395,6 +484,7 @@ struct xpvlv {
        UV      xivu_uv;
        void *  xivu_p1;
        I32     xivu_i32;
+       HEK *   xivu_namehek;   /* GvNAME */
     }          xiv_u;
     union {
        MAGIC*  xmg_magic;      /* linked list of magicalness */
@@ -402,13 +492,6 @@ struct xpvlv {
     } xmg_u;
     HV*                xmg_stash;      /* class package */
 
-    /* a full glob fits into this */
-    GP*                xgv_gp;
-    char*      xgv_name;
-    STRLEN     xgv_namelen;
-    HV*                xgv_stash;
-    U8         xgv_flags;
-
     STRLEN     xlv_targoff;
     STRLEN     xlv_targlen;
     SV*                xlv_targ;
@@ -417,14 +500,18 @@ struct xpvlv {
 };
 
 struct xpvgv {
-    NV         xnv_nv;         /* numeric value, if any */
-    STRLEN     xpv_cur;        /* length of svu_pv as a C string */
-    STRLEN     xpv_len;        /* allocated size */
     union {
-       IV      xivu_iv;        /* integer value or pv offset */
+       NV      xnv_nv;
+       HV *    xgv_stash;      /* The stash of this GV */
+    }          xnv_u;
+    STRLEN     xpv_cur;        /* xgv_flags */
+    STRLEN     xpv_len;        /* 0 */
+    union {
+       IV      xivu_iv;
        UV      xivu_uv;
        void *  xivu_p1;
        I32     xivu_i32;
+       HEK *   xivu_namehek;   /* GvNAME */
     }          xiv_u;
     union {
        MAGIC*  xmg_magic;      /* linked list of magicalness */
@@ -432,15 +519,13 @@ struct xpvgv {
     } xmg_u;
     HV*                xmg_stash;      /* class package */
 
-    GP*                xgv_gp;
-    char*      xgv_name;
-    STRLEN     xgv_namelen;
-    HV*                xgv_stash;
-    U8         xgv_flags;
 };
 
 struct xpvbm {
-    NV         xnv_nv;         /* numeric value, if any */
+    union {
+       NV      xnv_nv;         /* numeric value, if any */
+       HV *    xgv_stash;
+    }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
@@ -448,6 +533,7 @@ struct xpvbm {
        UV      xivu_uv;
        void *  xivu_p1;
        I32     xivu_i32;
+       HEK *   xivu_namehek;
     }          xiv_u;
     union {
        MAGIC*  xmg_magic;      /* linked list of magicalness */
@@ -465,7 +551,10 @@ struct xpvbm {
 typedef U16 cv_flags_t;
 
 struct xpvfm {
-    NV         xnv_nv;         /* numeric value, if any */
+    union {
+       NV      xnv_nv;         /* numeric value, if any */
+       HV *    xgv_stash;
+    }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
@@ -473,6 +562,7 @@ struct xpvfm {
        UV      xivu_uv;
        void *  xivu_p1;
        I32     xivu_i32;
+       HEK *   xivu_namehek;
     }          xiv_u;
     union {
        MAGIC*  xmg_magic;      /* linked list of magicalness */
@@ -508,6 +598,7 @@ typedef struct {
        UV      xivu_uv;
        void *  xivu_p1;
        I32     xivu_i32;
+       HEK *   xivu_namehek;
     }          xiv_u;
     union {
        MAGIC*  xmg_magic;      /* linked list of magicalness */
@@ -536,7 +627,10 @@ typedef struct {
 } xpvfm_allocated;
 
 struct xpvio {
-    NV         xnv_nv;         /* numeric value, if any */
+    union {
+       NV      xnv_nv;         /* numeric value, if any */
+       HV *    xgv_stash;
+    }          xnv_u;
     STRLEN     xpv_cur;        /* length of svu_pv as a C string */
     STRLEN     xpv_len;        /* allocated size */
     union {
@@ -544,6 +638,7 @@ struct xpvio {
        UV      xivu_uv;
        void *  xivu_p1;
        I32     xivu_i32;
+       HEK *   xivu_namehek;
     }          xiv_u;
     union {
        MAGIC*  xmg_magic;      /* linked list of magicalness */
@@ -763,12 +858,14 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
 
 #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 SvOK(sv)               (SvFLAGS(sv) & SVf_OK)
-#define SvOK_off(sv)           (assert_not_ROK(sv)                     \
+#define SvOK_off(sv)           (assert_not_ROK(sv) assert_not_glob(sv) \
                                 SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC|    \
                                                  SVf_IVisUV|SVf_UTF8), \
                                                        SvOOK_off(sv))
@@ -779,21 +876,21 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
 
 #define SvOKp(sv)              (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK))
 #define SvIOKp(sv)             (SvFLAGS(sv) & SVp_IOK)
-#define SvIOKp_on(sv)          (SvRELEASE_IVX(sv), \
+#define SvIOKp_on(sv)          (assert_not_glob(sv) SvRELEASE_IVX(sv), \
                                    SvFLAGS(sv) |= SVp_IOK)
 #define SvNOKp(sv)             (SvFLAGS(sv) & SVp_NOK)
-#define SvNOKp_on(sv)          (SvFLAGS(sv) |= SVp_NOK)
+#define SvNOKp_on(sv)          (assert_not_glob(sv) SvFLAGS(sv) |= SVp_NOK)
 #define SvPOKp(sv)             (SvFLAGS(sv) & SVp_POK)
-#define SvPOKp_on(sv)          (assert_not_ROK(sv)                     \
+#define SvPOKp_on(sv)          (assert_not_ROK(sv) assert_not_glob(sv) \
                                 SvFLAGS(sv) |= SVp_POK)
 
 #define SvIOK(sv)              (SvFLAGS(sv) & SVf_IOK)
-#define SvIOK_on(sv)           (SvRELEASE_IVX(sv), \
+#define SvIOK_on(sv)           (assert_not_glob(sv) SvRELEASE_IVX(sv), \
                                    SvFLAGS(sv) |= (SVf_IOK|SVp_IOK))
 #define SvIOK_off(sv)          (SvFLAGS(sv) &= ~(SVf_IOK|SVp_IOK|SVf_IVisUV))
 #define SvIOK_only(sv)         (SvOK_off(sv), \
                                    SvFLAGS(sv) |= (SVf_IOK|SVp_IOK))
-#define SvIOK_only_UV(sv)      (SvOK_off_exc_UV(sv), \
+#define SvIOK_only_UV(sv)      (assert_not_glob(sv) SvOK_off_exc_UV(sv), \
                                    SvFLAGS(sv) |= (SVf_IOK|SVp_IOK))
 
 #define SvIOK_UV(sv)           ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV))   \
@@ -807,7 +904,8 @@ Set the actual length of the string which is in the SV.  See C<SvIV_set>.
 #define SvIsUV_off(sv)         (SvFLAGS(sv) &= ~SVf_IVisUV)
 
 #define SvNOK(sv)              (SvFLAGS(sv) & SVf_NOK)
-#define SvNOK_on(sv)           (SvFLAGS(sv) |= (SVf_NOK|SVp_NOK))
+#define SvNOK_on(sv)           (assert_not_glob(sv) \
+                                SvFLAGS(sv) |= (SVf_NOK|SVp_NOK))
 #define SvNOK_off(sv)          (SvFLAGS(sv) &= ~(SVf_NOK|SVp_NOK))
 #define SvNOK_only(sv)         (SvOK_off(sv), \
                                    SvFLAGS(sv) |= (SVf_NOK|SVp_NOK))
@@ -837,14 +935,14 @@ in gv.h: */
 #define SvUTF8_off(sv)         (SvFLAGS(sv) &= ~(SVf_UTF8))
 
 #define SvPOK(sv)              (SvFLAGS(sv) & SVf_POK)
-#define SvPOK_on(sv)           (assert_not_ROK(sv)                     \
+#define SvPOK_on(sv)           (assert_not_ROK(sv) assert_not_glob(sv) \
                                 SvFLAGS(sv) |= (SVf_POK|SVp_POK))
 #define SvPOK_off(sv)          (SvFLAGS(sv) &= ~(SVf_POK|SVp_POK))
-#define SvPOK_only(sv)         (assert_not_ROK(sv)                     \
+#define SvPOK_only(sv)         (assert_not_ROK(sv) assert_not_glob(sv) \
                                 SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC|    \
                                                  SVf_IVisUV|SVf_UTF8), \
                                    SvFLAGS(sv) |= (SVf_POK|SVp_POK))
-#define SvPOK_only_UTF8(sv)    (assert_not_ROK(sv)                     \
+#define SvPOK_only_UTF8(sv)    (assert_not_ROK(sv) assert_not_glob(sv) \
                                 SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC|    \
                                                  SVf_IVisUV),          \
                                    SvFLAGS(sv) |= (SVf_POK|SVp_POK))
@@ -978,7 +1076,7 @@ in gv.h: */
    +0.0 + -0.0 => +0.0 but -0.0 + -0.0 => -0.0 */
 #  define SvIVX(sv) (0 + ((XPVIV*) SvANY(sv))->xiv_iv)
 #  define SvUVX(sv) (0 + ((XPVUV*) SvANY(sv))->xuv_uv)
-#  define SvNVX(sv) (-0.0 + ((XPVNV*) SvANY(sv))->xnv_nv)
+#  define SvNVX(sv) (-0.0 + ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv)
 /* Don't test the core XS code yet.  */
 #  if defined (PERL_CORE) && PERL_DEBUG_COW > 1
 #    define SvPVX(sv) (0 + (assert(!SvREADONLY(sv)), (sv)->sv_u.svu_pv))
@@ -997,19 +1095,34 @@ in gv.h: */
 #    define SvSTASH(sv)        (0 + ((XPVMG*)  SvANY(sv))->xmg_stash)
 #  endif
 #else
-#  define SvPVX(sv) ((sv)->sv_u.svu_pv)
-#  define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur
 #  define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len
 #  define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
 
 #  if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
 /* These get expanded inside other macros that already use a variable _sv  */
+#    define SvPVX(sv)                                                  \
+       (*({ SV *const _svi = (SV *) sv;                                \
+           assert(SvTYPE(_svi) >= SVt_PV);                             \
+           assert(SvTYPE(_svi) != SVt_PVAV);                           \
+           assert(SvTYPE(_svi) != SVt_PVHV);                           \
+           assert(!isGV_with_GP(_svi));                                \
+           &((_svi)->sv_u.svu_pv);                                     \
+        }))
+#    define SvCUR(sv)                                                  \
+       (*({ SV *const _svi = (SV *) sv;                                \
+           assert(SvTYPE(_svi) >= SVt_PV);                             \
+           assert(SvTYPE(_svi) != SVt_PVAV);                           \
+           assert(SvTYPE(_svi) != SVt_PVHV);                           \
+           assert(!isGV_with_GP(_svi));                                \
+           &(((XPV*) SvANY(_svi))->xpv_cur);                           \
+        }))
 #    define SvIVX(sv)                                                  \
        (*({ SV *const _svi = (SV *) sv;                                \
            assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
            assert(SvTYPE(_svi) != SVt_PVCV);                           \
+           assert(!isGV_with_GP(_svi));                                \
            &(((XPVIV*) SvANY(_svi))->xiv_iv);                          \
         }))
 #    define SvUVX(sv)                                                  \
@@ -1018,6 +1131,7 @@ in gv.h: */
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
            assert(SvTYPE(_svi) != SVt_PVCV);                           \
+           assert(!isGV_with_GP(_svi));                                \
            &(((XPVUV*) SvANY(_svi))->xuv_uv);                          \
         }))
 #    define SvNVX(sv)                                                  \
@@ -1026,7 +1140,8 @@ in gv.h: */
            assert(SvTYPE(_svi) != SVt_PVAV);                           \
            assert(SvTYPE(_svi) != SVt_PVHV);                           \
            assert(SvTYPE(_svi) != SVt_PVFM);                           \
-          &(((XPVNV*) SvANY(_svi))->xnv_nv);                           \
+           assert(!isGV_with_GP(_svi));                                \
+          &(((XPVNV*) SvANY(_svi))->xnv_u.xnv_nv);                     \
         }))
 #    define SvMAGIC(sv)                                                        \
        (*({ SV *const _svi = (SV *) sv;                                \
@@ -1039,9 +1154,11 @@ in gv.h: */
            &(((XPVMG*) SvANY(_svi))->xmg_stash);                       \
          }))
 #  else
+#    define SvPVX(sv) ((sv)->sv_u.svu_pv)
+#    define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur
 #    define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv
 #    define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
-#    define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_nv
+#    define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv
 #    define SvMAGIC(sv)        ((XPVMG*)  SvANY(sv))->xmg_u.xmg_magic
 #    define SvSTASH(sv)        ((XPVMG*)  SvANY(sv))->xmg_stash
 #  endif
@@ -1075,19 +1192,24 @@ in gv.h: */
                (void) SvIV(sv); } STMT_END
 #define SvIV_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
+               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); \
-               (((XPVNV*)SvANY(sv))->xnv_nv = (val)); } STMT_END
+               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(!isGV_with_GP(sv));              \
                ((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(!isGV_with_GP(sv));              \
                (((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END
 #define SvRV_set(sv, val) \
         STMT_START { assert(SvTYPE(sv) >=  SVt_RV); \
+               assert(!isGV_with_GP(sv));              \
                 ((sv)->sv_u.svu_rv = (val)); } STMT_END
 #define SvMAGIC_set(sv, val) \
         STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
@@ -1097,9 +1219,11 @@ in gv.h: */
                 (((XPVMG*)  SvANY(sv))->xmg_stash = (val)); } STMT_END
 #define SvCUR_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
+               assert(!isGV_with_GP(sv));              \
                (((XPV*)  SvANY(sv))->xpv_cur = (val)); } STMT_END
 #define SvLEN_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
+               assert(!isGV_with_GP(sv));      \
                (((XPV*)  SvANY(sv))->xpv_len = (val)); } STMT_END
 #define SvEND_set(sv, val) \
        STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
@@ -1681,6 +1805,11 @@ Returns a pointer to the character buffer.
 #define boolSV(b) ((b) ? &PL_sv_yes : &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.  */
+#define isGV_with_GP(pwadak) \
+       (((SvFLAGS(pwadak) & (SVp_POK|SVp_SCREAM)) == SVp_SCREAM)       \
+       && (SvTYPE(pwadak) == SVt_PVGV || SvTYPE(pwadak) == SVt_PVLV))
 
 #define SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv))
 #define SvGROW_mutable(sv,len) \