/* sv.h
*
- * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, by Larry Wall and others
+ * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ * 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
#endif
/* There is collusion here with sv_clear - sv_clear exits early for SVt_NULL
- and SVt_IV, so never reaches the clause at the end that uses
- sv_type_details->body_size to determine whether to call safefree(). Hence
- body_size can be set no-zero to record the size of PTEs and HEs, without
- fear of bogus frees. */
-#ifdef PERL_IN_SV_C
-#define PTE_SVSLOT SVt_IV
-#endif
+ so never reaches the clause at the end that uses sv_type_details->body_size
+ to determine whether to call safefree(). Hence body_size can be set
+ non-zero to record the size of HEs, without fear of bogus frees. */
#if defined(PERL_IN_HV_C) || defined(PERL_IN_XS_APITEST)
#define HE_SVSLOT SVt_NULL
#endif
#define _SV_HEAD_UNION \
union { \
+ char* svu_pv; /* pointer to malloced string */ \
IV svu_iv; \
UV svu_uv; \
SV* svu_rv; /* pointer to another SV */ \
- char* svu_pv; /* pointer to malloced string */ \
SV** svu_array; \
HE** svu_hash; \
GP* svu_gp; \
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 */
#endif
};
#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
# define SvREFCNT_inc(sv) \
({ \
- SV * const _sv = (SV*)(sv); \
+ SV * const _sv = MUTABLE_SV(sv); \
if (_sv) \
(SvREFCNT(_sv))++; \
_sv; \
({ \
if (sv) \
(SvREFCNT(sv))++; \
- (SV *)(sv); \
+ MUTABLE_SV(sv); \
})
# define SvREFCNT_inc_NN(sv) \
({ \
- SV * const _sv = (SV*)(sv); \
+ SV * const _sv = MUTABLE_SV(sv); \
SvREFCNT(_sv)++; \
_sv; \
})
# define SvREFCNT_inc_void(sv) \
({ \
- SV * const _sv = (SV*)(sv); \
+ SV * const _sv = MUTABLE_SV(sv); \
if (_sv) \
(void)(SvREFCNT(_sv)++); \
})
#else
# define SvREFCNT_inc(sv) \
- ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL)
+ ((PL_Sv=MUTABLE_SV(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL)
# define SvREFCNT_inc_simple(sv) \
- ((sv) ? (SvREFCNT(sv)++,(SV*)(sv)) : NULL)
+ ((sv) ? (SvREFCNT(sv)++,MUTABLE_SV(sv)) : NULL)
# define SvREFCNT_inc_NN(sv) \
- (PL_Sv=(SV*)(sv),++(SvREFCNT(PL_Sv)),PL_Sv)
+ (PL_Sv=MUTABLE_SV(sv),++(SvREFCNT(PL_Sv)),PL_Sv)
# define SvREFCNT_inc_void(sv) \
- (void)((PL_Sv=(SV*)(sv)) ? ++(SvREFCNT(PL_Sv)) : 0)
+ (void)((PL_Sv=MUTABLE_SV(sv)) ? ++(SvREFCNT(PL_Sv)) : 0)
#endif
/* These guys don't need the curly blocks */
#define SvREFCNT_inc_simple_void(sv) STMT_START { if (sv) SvREFCNT(sv)++; } STMT_END
-#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)))
+#define SvREFCNT_inc_simple_NN(sv) (++(SvREFCNT(sv)),MUTABLE_SV(sv))
+#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 = (SV*)(sv); \
+ SV * const _sv = MUTABLE_SV(sv); \
if (_sv) { \
if (SvREFCNT(_sv)) { \
if (--(SvREFCNT(_sv)) == 0) \
} \
})
#else
-#define SvREFCNT_dec(sv) sv_free((SV*)(sv))
+#define SvREFCNT_dec(sv) sv_free(MUTABLE_SV(sv))
#endif
#define SVTYPEMASK 0xff
/* RV upwards. However, SVf_ROK and SVp_IOK are exclusive */
#define SVprv_WEAKREF 0x80000000 /* Weak reference */
-#define _XPV_ALLOCATED_HEAD \
+#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 */
-#define _XPV_HEAD \
- union _xnvu xnv_u; \
- _XPV_ALLOCATED_HEAD
-
union _xnvu {
NV xnv_nv; /* numeric value, if any */
HV * xgv_stash;
union _xivu {
IV xivu_iv; /* integer value */
- /* xpvfm: pv offset */
UV xivu_uv;
- void * xivu_p1;
- I32 xivu_i32;
+ I32 xivu_i32; /* BmUSEFUL */
HEK * xivu_namehek; /* xpvlv, xpvgv: GvNAME */
- HV * xivu_hv; /* regexp: paren_names */
};
union _xmgu {
_XPV_HEAD;
};
-typedef struct {
- _XPV_ALLOCATED_HEAD;
-} xpv_allocated;
-
struct xpviv {
_XPV_HEAD;
union _xivu xiv_u;
};
-typedef struct {
- _XPV_ALLOCATED_HEAD;
- union _xivu xiv_u;
-} xpviv_allocated;
-
#define xiv_iv xiv_u.xivu_iv
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 */
-
-/* These structure must match the beginning of struct xpvhv in hv.h. */
+/* 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;
Boyer-Moore. */
struct xpvgv {
_XPV_HEAD;
- _XPVMG_HEAD;
+ union _xivu xiv_u;
+ union _xnvu xnv_u;
};
/* This structure must match XPVCV in cv.h */
struct xpvfm {
_XPV_HEAD;
- _XPVMG_HEAD;
_XPVCV_COMMON;
IV xfm_lines;
};
-typedef struct {
- _XPV_ALLOCATED_HEAD;
- _XPVMG_HEAD;
- _XPVCV_COMMON;
- IV xfm_lines;
-} xpvfm_allocated;
-
#define _XPVIO_TAIL \
PerlIO * xio_ifp; /* ifp and ofp are normally the same */ \
PerlIO * xio_ofp; /* but sockets need separate streams */ \
DIR * xiou_dirp; /* for opendir, readdir, etc */ \
void * xiou_any; /* for alignment */ \
} xio_dirpu; \
- IV xio_lines; /* $. */ \
+ /* IV xio_lines is now in IVX $. */ \
IV xio_page; /* $% */ \
IV xio_page_len; /* $= */ \
IV xio_lines_left; /* $- */ \
struct xpvio {
_XPV_HEAD;
- _XPVMG_HEAD;
+ union _xivu xiv_u;
_XPVIO_TAIL;
};
-typedef struct {
- _XPV_ALLOCATED_HEAD;
- _XPVMG_HEAD;
- _XPVIO_TAIL;
-} xpvio_allocated;
-
#define xio_dirp xio_dirpu.xiou_dirp
#define xio_any xio_dirpu.xiou_any
=for apidoc Am|U32|SvNIOKp|SV* sv
Returns a U32 value indicating whether the SV contains a number, integer or
-double. Checks the B<private> setting. Use C<SvNIOK>.
+double. Checks the B<private> setting. Use C<SvNIOK> instead.
=for apidoc Am|void|SvNIOK_off|SV* sv
Unsets the NV/IV status of an SV.
=for apidoc Am|U32|SvOK|SV* sv
-Returns a U32 value indicating whether the value is an SV. It also tells
-whether the value is defined or not.
+Returns a U32 value indicating whether the value is defined. This is
+only meaningful for scalars.
=for apidoc Am|U32|SvIOKp|SV* sv
Returns a U32 value indicating whether the SV contains an integer. Checks
-the B<private> setting. Use C<SvIOK>.
+the B<private> setting. Use C<SvIOK> instead.
=for apidoc Am|U32|SvNOKp|SV* sv
Returns a U32 value indicating whether the SV contains a double. Checks the
-B<private> setting. Use C<SvNOK>.
+B<private> setting. Use C<SvNOK> instead.
=for apidoc Am|U32|SvPOKp|SV* sv
Returns a U32 value indicating whether the SV contains a character string.
-Checks the B<private> setting. Use C<SvPOK>.
+Checks the B<private> setting. Use C<SvPOK> instead.
=for apidoc Am|U32|SvIOK|SV* sv
Returns a U32 value indicating whether the SV contains an integer.
#endif
/*
-=for apidoc Am|char*|SvGAMAGIC|SV* sv
+=for apidoc Am|U32|SvGAMAGIC|SV* sv
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
#define SvGAMAGIC(sv) (SvGMAGICAL(sv) || SvAMAGIC(sv))
-#define Gv_AMG(stash) (PL_amagic_generation && Gv_AMupdate(stash))
+#define Gv_AMG(stash) (PL_amagic_generation && Gv_AMupdate(stash, FALSE))
#define SvWEAKREF(sv) ((SvFLAGS(sv) & (SVf_ROK|SVprv_WEAKREF)) \
== (SVf_ROK|SVprv_WEAKREF))
#define SvEVALED_off(sv) (SvFLAGS(sv) &= ~SVrepl_EVAL)
#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
-# define SvVALID(sv) ({ SV *const thwacke = (SV *) (sv); \
- if (SvFLAGS(thwacke) & SVpbm_VALID) \
- assert(!isGV_with_GP(thwacke)); \
- (SvFLAGS(thwacke) & SVpbm_VALID); \
+# define SvVALID(sv) ({ const SV *const _svvalid = (const SV*)(sv); \
+ if (SvFLAGS(_svvalid) & SVpbm_VALID) \
+ assert(!isGV_with_GP(_svvalid)); \
+ (SvFLAGS(_svvalid) & SVpbm_VALID); \
})
-# define SvVALID_on(sv) ({ SV *const thwacke = (SV *) (sv); \
- assert(!isGV_with_GP(thwacke)); \
- (SvFLAGS(thwacke) |= SVpbm_VALID); \
+# define SvVALID_on(sv) ({ SV *const _svvalid = MUTABLE_SV(sv); \
+ assert(!isGV_with_GP(_svvalid)); \
+ (SvFLAGS(_svvalid) |= SVpbm_VALID); \
})
-# define SvVALID_off(sv) ({ SV *const thwacke = (SV *) (sv); \
- assert(!isGV_with_GP(thwacke)); \
- (SvFLAGS(thwacke) &= ~SVpbm_VALID); \
+# define SvVALID_off(sv) ({ SV *const _svvalid = MUTABLE_SV(sv); \
+ assert(!isGV_with_GP(_svvalid)); \
+ (SvFLAGS(_svvalid) &= ~SVpbm_VALID); \
})
-# define SvTAIL(sv) ({ SV *const _svi = (SV *) (sv); \
- assert(SvTYPE(_svi) != SVt_PVAV); \
- assert(SvTYPE(_svi) != SVt_PVHV); \
+# define SvTAIL(sv) ({ const SV *const _svtail = (const SV *)(sv); \
+ assert(SvTYPE(_svtail) != SVt_PVAV); \
+ assert(SvTYPE(_svtail) != SVt_PVHV); \
(SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID)) \
== (SVpbm_TAIL|SVpbm_VALID); \
})
#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
# define SvPAD_TYPED_on(sv) ({ \
- SV *const whap = (SV *) (sv); \
- assert(SvTYPE(whap) == SVt_PVMG); \
- (SvFLAGS(whap) |= SVpad_NAME|SVpad_TYPED); \
+ SV *const _svpad = MUTABLE_SV(sv); \
+ assert(SvTYPE(_svpad) == SVt_PVMG); \
+ (SvFLAGS(_svpad) |= SVpad_NAME|SVpad_TYPED); \
})
#define SvPAD_OUR_on(sv) ({ \
- SV *const whap = (SV *) (sv); \
- assert(SvTYPE(whap) == SVt_PVMG); \
- (SvFLAGS(whap) |= SVpad_NAME|SVpad_OUR); \
+ SV *const _svpad = MUTABLE_SV(sv); \
+ assert(SvTYPE(_svpad) == SVt_PVMG); \
+ (SvFLAGS(_svpad) |= SVpad_NAME|SVpad_OUR); \
})
#define SvPAD_STATE_on(sv) ({ \
- SV *const whap = (SV *) (sv); \
- assert(SvTYPE(whap) == SVt_PVNV || SvTYPE(whap) == SVt_PVMG); \
- (SvFLAGS(whap) |= SVpad_NAME|SVpad_STATE); \
+ SV *const _svpad = MUTABLE_SV(sv); \
+ assert(SvTYPE(_svpad) == SVt_PVNV || SvTYPE(_svpad) == SVt_PVMG); \
+ (SvFLAGS(_svpad) |= SVpad_NAME|SVpad_STATE); \
})
#else
# define SvPAD_TYPED_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED)
# define SvUVX(sv) (0 + ((XPVUV*) SvANY(sv))->xuv_uv)
# define SvNVX(sv) (-0.0 + ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv)
# define SvRV(sv) (0 + (sv)->sv_u.svu_rv)
+# 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))
# 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); \
+ (*({ SV *const _svpvx = MUTABLE_SV(sv); \
+ assert(SvTYPE(_svpvx) >= SVt_PV); \
+ assert(SvTYPE(_svpvx) != SVt_PVAV); \
+ assert(SvTYPE(_svpvx) != SVt_PVHV); \
+ assert(!isGV_with_GP(_svpvx)); \
+ &((_svpvx)->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); \
+ (*({ const SV *const _svcur = (const SV *)(sv); \
+ assert(SvTYPE(_svcur) >= SVt_PV); \
+ assert(SvTYPE(_svcur) != SVt_PVAV); \
+ assert(SvTYPE(_svcur) != SVt_PVHV); \
+ assert(!isGV_with_GP(_svcur)); \
+ &(((XPV*) MUTABLE_PTR(SvANY(_svcur)))->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); \
+ (*({ 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(SvTYPE(_svivx) != SVt_REGEXP); \
+ assert(!isGV_with_GP(_svivx)); \
+ &(((XPVIV*) MUTABLE_PTR(SvANY(_svivx)))->xiv_iv); \
}))
# define SvUVX(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)); \
- &(((XPVUV*) SvANY(_svi))->xuv_uv); \
+ (*({ 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(SvTYPE(_svuvx) != SVt_REGEXP); \
+ assert(!isGV_with_GP(_svuvx)); \
+ &(((XPVUV*) MUTABLE_PTR(SvANY(_svuvx)))->xuv_uv); \
}))
# define SvNVX(sv) \
- (*({ SV *const _svi = (SV *) (sv); \
- assert(SvTYPE(_svi) == SVt_NV || SvTYPE(_svi) >= SVt_PVNV); \
- assert(SvTYPE(_svi) != SVt_PVAV); \
- assert(SvTYPE(_svi) != SVt_PVHV); \
- assert(SvTYPE(_svi) != SVt_PVCV); \
- assert(SvTYPE(_svi) != SVt_PVFM); \
- assert(SvTYPE(_svi) != SVt_PVIO); \
- assert(!isGV_with_GP(_svi)); \
- &(((XPVNV*) SvANY(_svi))->xnv_u.xnv_nv); \
+ (*({ 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(SvTYPE(_svnvx) != SVt_REGEXP); \
+ assert(!isGV_with_GP(_svnvx)); \
+ &(((XPVNV*) MUTABLE_PTR(SvANY(_svnvx)))->xnv_u.xnv_nv); \
}))
# define SvRV(sv) \
- (*({ SV *const _svi = (SV *) (sv); \
- assert(SvTYPE(_svi) >= SVt_PV || SvTYPE(_svi) == SVt_IV); \
- assert(SvTYPE(_svi) != SVt_PVAV); \
- assert(SvTYPE(_svi) != SVt_PVHV); \
- assert(SvTYPE(_svi) != SVt_PVCV); \
- assert(SvTYPE(_svi) != SVt_PVFM); \
- assert(!isGV_with_GP(_svi)); \
- &((_svi)->sv_u.svu_rv); \
+ (*({ 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(!isGV_with_GP(_svrv)); \
+ &((_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(!isGV_with_GP(_svrv)); \
+ (_svrv)->sv_u.svu_rv; \
+ })
# define SvMAGIC(sv) \
- (*({ SV *const _svi = (SV *) (sv); \
- assert(SvTYPE(_svi) >= SVt_PVMG); \
- if(SvTYPE(_svi) == SVt_PVMG) \
- assert(!SvPAD_OUR(_svi)); \
- &(((XPVMG*) SvANY(_svi))->xmg_u.xmg_magic); \
+ (*({ const SV *const _svmagic = (const SV *)(sv); \
+ assert(SvTYPE(_svmagic) >= SVt_PVMG); \
+ if(SvTYPE(_svmagic) == SVt_PVMG) \
+ assert(!SvPAD_OUR(_svmagic)); \
+ &(((XPVMG*) MUTABLE_PTR(SvANY(_svmagic)))->xmg_u.xmg_magic); \
}))
# define SvSTASH(sv) \
- (*({ SV *const _svi = (SV *) (sv); \
- assert(SvTYPE(_svi) >= SVt_PVMG); \
- &(((XPVMG*) SvANY(_svi))->xmg_stash); \
+ (*({ const SV *const _svstash = (const SV *)(sv); \
+ assert(SvTYPE(_svstash) >= SVt_PVMG); \
+ &(((XPVMG*) MUTABLE_PTR(SvANY(_svstash)))->xmg_stash); \
}))
# else
# define SvPVX(sv) ((sv)->sv_u.svu_pv)
# define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv
# define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv
# define SvRV(sv) ((sv)->sv_u.svu_rv)
+# define SvRV_const(sv) (0 + (sv)->sv_u.svu_rv)
# define SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_u.xmg_magic
# define SvSTASH(sv) ((XPVMG*) SvANY(sv))->xmg_stash
# endif
#define SvIV_please(sv) \
STMT_START {if (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv))) \
(void) SvIV(sv); } STMT_END
+#define SvIV_please_nomg(sv) \
+ STMT_START {if (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv))) \
+ (void) SvIV_nomg(sv); } STMT_END
#define SvIV_set(sv, val) \
STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \
assert(SvTYPE(sv) != SVt_PVAV); \
(((XPV*) SvANY(sv))->xpv_len = (val)); } STMT_END
#define SvEND_set(sv, val) \
STMT_START { assert(SvTYPE(sv) >= SVt_PV); \
- (SvCUR(sv) = (val) - SvPVX(sv)); } STMT_END
+ SvCUR_set(sv, (val) - SvPVX(sv)); } STMT_END
#define SvPV_renew(sv,n) \
STMT_START { SvLEN_set(sv, n); \
*/
#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
# define BmFLAGS(sv) \
- (*({ SV *const uggh = (SV *) (sv); \
- assert(SvTYPE(uggh) == SVt_PVGV); \
- assert(SvVALID(uggh)); \
- &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_flags); \
+ (*({ 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 uggh = (SV *) (sv); \
- assert(SvTYPE(uggh) == SVt_PVGV); \
- assert(SvVALID(uggh)); \
- &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_rare); \
+ (*({ SV *const _bmrare = MUTABLE_SV(sv); \
+ assert(SvTYPE(_bmrare) == SVt_PVGV); \
+ assert(SvVALID(_bmrare)); \
+ &(((XPVGV*) SvANY(_bmrare))->xnv_u.xbm_s.xbm_rare); \
}))
# define BmUSEFUL(sv) \
- (*({ SV *const uggh = (SV *) (sv); \
- assert(SvTYPE(uggh) == SVt_PVGV); \
- assert(SvVALID(uggh)); \
- assert(!SvIOK(uggh)); \
- &(((XPVGV*) SvANY(uggh))->xiv_u.xivu_i32); \
+ (*({ SV *const _bmuseful = MUTABLE_SV(sv); \
+ assert(SvTYPE(_bmuseful) == SVt_PVGV); \
+ assert(SvVALID(_bmuseful)); \
+ assert(!SvIOK(_bmuseful)); \
+ &(((XPVGV*) SvANY(_bmuseful))->xiv_u.xivu_i32); \
}))
# define BmPREVIOUS(sv) \
- (*({ SV *const uggh = (SV *) (sv); \
- assert(SvTYPE(uggh) == SVt_PVGV); \
- assert(SvVALID(uggh)); \
- &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_previous); \
+ (*({ SV *const _bmprevious = MUTABLE_SV(sv); \
+ assert(SvTYPE(_bmprevious) == SVt_PVGV); \
+ assert(SvVALID(_bmprevious)); \
+ &(((XPVGV*) SvANY(_bmprevious))->xnv_u.xbm_s.xbm_previous); \
}))
#else
# define BmFLAGS(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_flags
#define IoOFP(sv) ((XPVIO*) SvANY(sv))->xio_ofp
#define IoDIRP(sv) ((XPVIO*) SvANY(sv))->xio_dirp
#define IoANY(sv) ((XPVIO*) SvANY(sv))->xio_any
-#define IoLINES(sv) ((XPVIO*) SvANY(sv))->xio_lines
+#define IoLINES(sv) ((XPVIO*) SvANY(sv))->xiv_u.xivu_iv
#define IoPAGE(sv) ((XPVIO*) SvANY(sv))->xio_page
#define IoPAGE_LEN(sv) ((XPVIO*) SvANY(sv))->xio_page_len
#define IoLINES_LEFT(sv)((XPVIO*) SvANY(sv))->xio_lines_left
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,
=for apidoc Am|bool|SvTRUE|SV* sv
Returns a boolean indicating whether Perl would evaluate the SV as true or
-false, defined or undefined. Does not handle 'get' magic.
+false. See SvOK() for a defined/undefined test. Does not handle 'get' magic.
=for apidoc Am|char*|SvPVutf8_force|SV* sv|STRLEN len
Like C<SvPV_force>, but converts sv to utf8 first if necessary.
=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 sv_utf8_upgrade, but doesn't do magic on C<sv>
+
=cut
*/
#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))
/* ----*/
#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
-# define SvIVx(sv) ({SV *_sv = (SV*)(sv); SvIV(_sv); })
-# define SvUVx(sv) ({SV *_sv = (SV*)(sv); SvUV(_sv); })
-# define SvNVx(sv) ({SV *_sv = (SV*)(sv); SvNV(_sv); })
+# 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_nolen(sv) ({SV *_sv = (sv); SvPV_nolen(_sv); })
#define SV_COW_OTHER_PVS 1024
/* Make sv_2pv_flags return NULL if something is undefined. */
#define SV_UNDEF_RETURNS_NULL 2048
+/* Tell sv_utf8_upgrade() to not check to see if an upgrade is really needed.
+ * This is used when the caller has already determined it is, and avoids
+ * redundant work */
+#define SV_FORCE_UTF8_UPGRADE 4096
+/* 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
/* 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.
#define sv_pvbyte(sv) SvPVbyte_nolen(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_catpvn_nomg(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, 0)
#define sv_setsv(dsv, ssv) \
#define sv_utf8_upgrade(sv) sv_utf8_upgrade_flags(sv, SV_GMAGIC)
#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_insert(bigstr, offset, len, little, littlelen) \
Perl_sv_insert_flags(aTHX_ (bigstr),(offset), (len), (little), \
(littlelen), SV_GMAGIC)
AV* stashes;
UV flags;
PerlInterpreter *proto_perl;
+ PerlInterpreter *new_perl;
+ AV *unreferenced;
};
/*
} \
} STMT_END
#endif
+
+#define newIO() MUTABLE_IO(newSV_type(SVt_PVIO))
+
/*
* Local variables:
* c-indentation-style: bsd