char* svu_pv; /* pointer to malloced string */ \
SV** svu_array; \
HE** svu_hash; \
+ GP* svu_gp; \
} sv_u
=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.
(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) \
({ \
fact an offset [SvREPADTMP(sv)]
5: On a pad name SV, that slot in the
frame AV is a REFCNT'ed reference
- to a lexical from "outside".
- */
+ to a lexical from "outside". */
+#define SVphv_REHASH SVf_FAKE /* 6: On a PVHV, hash values are being
+ recalculated */
#define SVf_OOK 0x02000000 /* has valid offset value
For a PVHV this means that a
hv_aux struct is present after the
/* Some private flags. */
/* PVHV */
-#define SVphv_REHASH 0x10000000 /* PVHV is recalculating hash values */
-/* PVHV */
#define SVphv_SHAREKEYS 0x20000000 /* PVHV
keys live on shared string table */
/* PVNV, PVMG, PVGV, presumably only inside pads */
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 */
};
#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 {
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
};
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
} xpviv_allocated;
#endif
#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 {
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 {
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
- MAGIC* xmg_magic; /* linked list of magicalness */
+ union {
+ MAGIC* xmg_magic; /* linked list of magicalness */
+ HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */
+ } xmg_u;
HV* xmg_stash; /* class package */
};
struct xpvlv {
- 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 {
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek; /* GvNAME */
} xiv_u;
- MAGIC* xmg_magic; /* linked list of magicalness */
+ union {
+ MAGIC* xmg_magic; /* linked list of magicalness */
+ HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */
+ } xmg_u;
HV* xmg_stash; /* class package */
- /* a full glob fits into this */
- GP* xgv_gp;
- char* xgv_name;
- STRLEN xgv_namelen;
- HV* xgv_stash;
- U8 xgv_flags;
-
STRLEN xlv_targoff;
STRLEN xlv_targlen;
SV* xlv_targ;
};
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;
- MAGIC* xmg_magic; /* linked list of magicalness */
+ union {
+ MAGIC* xmg_magic; /* linked list of magicalness */
+ HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */
+ } xmg_u;
HV* xmg_stash; /* class package */
- GP* xgv_gp;
- 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 {
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
- MAGIC* xmg_magic; /* linked list of magicalness */
+ union {
+ MAGIC* xmg_magic; /* linked list of magicalness */
+ HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */
+ } xmg_u;
HV* xmg_stash; /* class package */
I32 xbm_useful; /* is this constant pattern being useful? */
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 {
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
- MAGIC* xmg_magic; /* linked list of magicalness */
+ union {
+ MAGIC* xmg_magic; /* linked list of magicalness */
+ HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */
+ } xmg_u;
HV* xmg_stash; /* class package */
HV * xcv_stash;
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
- MAGIC* xmg_magic; /* linked list of magicalness */
+ union {
+ MAGIC* xmg_magic; /* linked list of magicalness */
+ HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */
+ } xmg_u;
HV* xmg_stash; /* class package */
HV * xcv_stash;
} 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 {
UV xivu_uv;
void * xivu_p1;
I32 xivu_i32;
+ HEK * xivu_namehek;
} xiv_u;
- MAGIC* xmg_magic; /* linked list of magicalness */
+ union {
+ MAGIC* xmg_magic; /* linked list of magicalness */
+ HV* xmg_ourstash; /* Stash for our (when SvPAD_OUR is true) */
+ } xmg_u;
HV* xmg_stash; /* class package */
PerlIO * xio_ifp; /* ifp and ofp are normally the same */
#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) \
- SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+#define SvOK_off(sv) (assert_not_ROK(sv) assert_not_glob(sv) \
+ SvFLAGS(sv) &= ~(SVf_OK| \
SVf_IVisUV|SVf_UTF8), \
SvOOK_off(sv))
#define SvOK_off_exc_UV(sv) (assert_not_ROK(sv) \
- SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+ SvFLAGS(sv) &= ~(SVf_OK| \
SVf_UTF8), \
SvOOK_off(sv))
#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)) \
#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))
#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) \
- SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+#define SvPOK_only(sv) (assert_not_ROK(sv) assert_not_glob(sv) \
+ SvFLAGS(sv) &= ~(SVf_OK| \
SVf_IVisUV|SVf_UTF8), \
SvFLAGS(sv) |= (SVf_POK|SVp_POK))
-#define SvPOK_only_UTF8(sv) (assert_not_ROK(sv) \
- SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \
+#define SvPOK_only_UTF8(sv) (assert_not_ROK(sv) assert_not_glob(sv) \
+ SvFLAGS(sv) &= ~(SVf_OK| \
SVf_IVisUV), \
SvFLAGS(sv) |= (SVf_POK|SVp_POK))
#define SvROK(sv) (SvFLAGS(sv) & SVf_ROK)
#define SvROK_on(sv) (SvFLAGS(sv) |= SVf_ROK)
-#define SvROK_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVf_AMAGIC))
+#define SvROK_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK))
#define SvMAGICAL(sv) (SvFLAGS(sv) & (SVs_GMG|SVs_SMG|SVs_RMG))
#define SvMAGICAL_on(sv) (SvFLAGS(sv) |= (SVs_GMG|SVs_SMG|SVs_RMG))
#define SvRMAGICAL_on(sv) (SvFLAGS(sv) |= SVs_RMG)
#define SvRMAGICAL_off(sv) (SvFLAGS(sv) &= ~SVs_RMG)
-#define SvAMAGIC(sv) (SvFLAGS(sv) & SVf_AMAGIC)
-#define SvAMAGIC_on(sv) (SvFLAGS(sv) |= SVf_AMAGIC)
-#define SvAMAGIC_off(sv) (SvFLAGS(sv) &= ~SVf_AMAGIC)
+#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 SvGAMAGIC(sv) (SvFLAGS(sv) & (SVs_GMG|SVf_AMAGIC))
+#define SvGAMAGIC(sv) (SvGMAGICAL(sv) || SvAMAGIC(sv))
-/*
-#define Gv_AMG(stash) \
- (HV_AMAGICmb(stash) && \
- ((!HV_AMAGICbad(stash) && HV_AMAGIC(stash)) || Gv_AMupdate(stash)))
-*/
#define Gv_AMG(stash) (PL_amagic_generation && Gv_AMupdate(stash))
#define SvWEAKREF(sv) ((SvFLAGS(sv) & (SVf_ROK|SVprv_WEAKREF)) \
((SvFLAGS(sv) & (SVpad_NAME|SVpad_OUR)) == (SVpad_NAME|SVpad_OUR))
#define SvPAD_OUR_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR)
+#define OURSTASH(sv) \
+ (SvPAD_OUR(sv) ? ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash : NULL)
+#define OURSTASH_set(sv, st) \
+ STMT_START { \
+ assert(SvTYPE(sv) == SVt_PVMG); \
+ ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash = st; \
+ } STMT_END
+
#ifdef PERL_DEBUG_COW
#define SvRV(sv) (0 + (sv)->sv_u.svu_rv)
#else
+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))
# define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
# ifdef DEBUGGING
-# ifdef PERL_IN_SV_C
-/* Can't make this RVALUE because of Perl_sv_unmagic. */
-# define SvMAGIC(sv) (*(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*) SvANY(sv))->xmg_magic))
-# else
-# define SvMAGIC(sv) (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*) SvANY(sv))->xmg_magic))
-# endif
-# define SvSTASH(sv) (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*) SvANY(sv))->xmg_stash))
+# 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_IN_SV_C
-# define SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_magic
-# else
-# define SvMAGIC(sv) (0 + ((XPVMG*) SvANY(sv))->xmg_magic)
-# endif
-# define SvSTASH(sv) (0 + ((XPVMG*) SvANY(sv))->xmg_stash)
+# define SvMAGIC(sv) (0 + ((XPVMG*) SvANY(sv))->xmg_u.xmg_magic)
+# 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) \
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) \
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; \
assert(SvTYPE(_svi) >= SVt_PVMG); \
- &(((XPVMG*) SvANY(_svi))->xmg_magic); \
+ &(((XPVMG*) SvANY(_svi))->xmg_u.xmg_magic); \
}))
# define SvSTASH(sv) \
(*({ SV *const _svi = (SV *) sv; \
&(((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 SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_magic
+# 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
#endif
(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); \
- (((XPVMG*)SvANY(sv))->xmg_magic = (val)); } STMT_END
+ (((XPVMG*)SvANY(sv))->xmg_u.xmg_magic = (val)); } STMT_END
#define SvSTASH_set(sv, val) \
STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \
(((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END
#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); \
#define SV_CONST_RETURN 32
#define SV_MUTABLE_RETURN 64
#define SV_SMAGIC 128
+#define SV_HAS_TRAILING_NUL 256
#define sv_unref(sv) sv_unref_flags(sv, 0)
#define sv_force_normal(sv) sv_force_normal_flags(sv, 0)
+#define sv_usepvn(sv, p, l) sv_usepvn_flags(sv, p, l, 0)
+#define sv_usepvn_mg(sv, p, l) sv_usepvn_flags(sv, p, l, SV_SMAGIC)
/* We are about to replace the SV's current value. So if it's copy on write
we need to normalise it. Use the SV_COW_DROP_PV flag hint to say that
#define CAN_COW_MASK (SVs_OBJECT|SVs_GMG|SVs_SMG|SVs_RMG|SVf_IOK|SVf_NOK| \
SVf_POK|SVf_ROK|SVp_IOK|SVp_NOK|SVp_POK|SVf_FAKE| \
- SVf_OOK|SVf_BREAK|SVf_READONLY|SVf_AMAGIC)
+ SVf_OOK|SVf_BREAK|SVf_READONLY)
#define CAN_COW_FLAGS (SVp_POK|SVf_POK)
#define SV_CHECK_THINKFIRST(sv) if (SvTHINKFIRST(sv)) \
#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) \