#define SVTYPEMASK 0xff
#define SvTYPE(sv) ((sv)->sv_flags & SVTYPEMASK)
-#define SvUPGRADE(sv, mt) (SvTYPE(sv) >= mt || sv_upgrade(sv, mt))
+#define SvUPGRADE(sv, mt) (void)(SvTYPE(sv) >= mt || sv_upgrade(sv, mt))
#define SVs_PADSTALE 0x00000100 /* lexical has gone out of scope */
#define SVs_PADTMP 0x00000200 /* in use as tmp */
#define SvIVX(sv) (0 + ((XPVIV*) SvANY(sv))->xiv_iv)
#define SvUVX(sv) (0 + ((XPVUV*) SvANY(sv))->xuv_uv)
#define SvNVX(sv) (0 + ((XPVNV*) SvANY(sv))->xnv_nv)
-#define SvPVX(sv) (0 + (sv)->sv_u.svu_pv)
+/* 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))
+#else
+#define SvPVX(sv) SvPVX_mutable(sv)
+#endif
+#define SvPVX_mutable(sv) (0 + (sv)->sv_u.svu_pv)
+#define SvPVX_const(sv) ((const char*)(0 + (sv)->sv_u.svu_pv))
#define SvCUR(sv) (0 + ((XPV*) SvANY(sv))->xpv_cur)
#define SvLEN(sv) (0 + ((XPV*) SvANY(sv))->xpv_len)
#define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)
#define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
#define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_nv
#define SvPVX(sv) ((sv)->sv_u.svu_pv)
+#define SvPVX_mutable(sv) SvPVX(sv)
+#define SvPVX_const(sv) ((const char*)SvPVX(sv))
#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)
} \
} STMT_END
-#define SvPVX_const(sv) ((const char*)SvPVX(sv))
-
#define BmRARE(sv) ((XPVBM*) SvANY(sv))->xbm_rare
#define BmUSEFUL(sv) ((XPVBM*) SvANY(sv))->xbm_useful
#define BmPREVIOUS(sv) ((XPVBM*) SvANY(sv))->xbm_previous
/* ----*/
#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 \
? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags))
+#define SvPV_flags_const(sv, lp, flags) \
+ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+ ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \
+ (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN))
+#define SvPV_flags_mutable(sv, lp, flags) \
+ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+ ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \
+ sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
#define SvPV_force(sv, lp) SvPV_force_flags(sv, lp, 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_nomg(sv, lp) SvPV_force_flags(sv, lp, 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))
+#define SvPV_force_flags_nolen(sv, flags) \
+ ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \
+ ? 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)) \
+ : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN))
#define SvPV_nolen(sv) \
((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
- ? SvPVX(sv) : sv_2pv_nolen(sv))
+ ? SvPVX(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC))
+
+#define SvPV_nolen_const(sv) \
+ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
+ ? 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 SvPVutf8_nolen(sv) \
((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8)\
- ? SvPVX(sv) : sv_2pvutf8_nolen(sv))
+ ? SvPVX(sv) : sv_2pvutf8(sv, 0))
/* ----*/
#define SvPVbyte_nolen(sv) \
((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK)\
- ? SvPVX(sv) : sv_2pvbyte_nolen(sv))
+ ? SvPVX(sv) : sv_2pvbyte(sv, 0))
# define SvUVx(sv) ({SV *_sv = (SV*)(sv); SvUV(_sv); })
# define SvNVx(sv) ({SV *_sv = (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_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 SvPVbytex_nolen(sv) ({SV *_sv = (sv); SvPVbyte_nolen(_sv); })
# define SvTRUE(sv) ( \
!sv \
? 0 \
# 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_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 SvPVbytex_nolen(sv) ((PL_Sv = (sv)), SvPVbyte_nolen(PL_Sv))
# define SvTRUE(sv) ( \
!sv \
? 0 \
(SVf_FAKE | SVf_READONLY))
#define SvIsCOW_shared_hash(sv) (SvIsCOW(sv) && SvLEN(sv) == 0)
+#define SvSHARED_HASH(sv) SvUVX(sv)
+
/* flag values for sv_*_flags functions */
#define SV_IMMEDIATE_UNREF 1
#define SV_GMAGIC 2
#define SV_COW_DROP_PV 4
#define SV_UTF8_NO_ENCODING 8
#define SV_NOSTEAL 16
+#define SV_CONST_RETURN 32
+#define SV_MUTABLE_RETURN 64
/* 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 SV_CHECK_THINKFIRST_COW_DROP(sv) if (SvTHINKFIRST(sv)) \
sv_force_normal_flags(sv, SV_COW_DROP_PV)
-#ifdef PERL_COPY_ON_WRITE
+#ifdef PERL_OLD_COPY_ON_WRITE
# define SvRELEASE_IVX(sv) ((void)((SvFLAGS(sv) & (SVf_OOK|SVf_READONLY|SVf_FAKE)) \
&& Perl_sv_release_IVX(aTHX_ sv)))
# define SvIsCOW_normal(sv) (SvIsCOW(sv) && SvLEN(sv))
+#else
+# define SvRELEASE_IVX(sv) SvOOK_off(sv)
+#endif /* PERL_OLD_COPY_ON_WRITE */
#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)
#define CAN_COW_FLAGS (SVp_POK|SVf_POK)
-#else
-# define SvRELEASE_IVX(sv) SvOOK_off(sv)
-#endif /* PERL_COPY_ON_WRITE */
-
#define SV_CHECK_THINKFIRST(sv) if (SvTHINKFIRST(sv)) \
sv_force_normal_flags(sv, 0)