X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/2892acdbbc776bf121eaec9d93ea404f7afc54b8..94fcd414575e04d8b809003ba7bca1216090abff:/sv.h diff --git a/sv.h b/sv.h index b4926c0..f12780f 100644 --- a/sv.h +++ b/sv.h @@ -1,7 +1,7 @@ /* sv.h * * Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - * 2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others + * 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 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. @@ -45,14 +45,15 @@ Type flag for code refs. See C. typedef enum { SVt_NULL, /* 0 */ - SVt_IV, /* 1 */ - SVt_NV, /* 2 */ - SVt_RV, /* 3 */ - SVt_PV, /* 4 */ - SVt_PVIV, /* 5 */ - SVt_PVNV, /* 6 */ - SVt_PVMG, /* 7 */ - SVt_PVBM, /* 8 */ + SVt_BIND, /* 1 */ + SVt_IV, /* 2 */ + SVt_NV, /* 3 */ + SVt_RV, /* 4 */ + SVt_PV, /* 5 */ + SVt_PVIV, /* 6 */ + SVt_PVNV, /* 7 */ + SVt_PVMG, /* 8 */ + /* PVBM was here, before BIND replaced it. */ SVt_PVGV, /* 9 */ SVt_PVLV, /* 10 */ SVt_PVAV, /* 11 */ @@ -63,6 +64,13 @@ typedef enum { SVt_LAST /* keep last in enum. used to size arrays */ } svtype; +#ifndef PERL_CORE +/* Although Fast Boyer Moore tables are now being stored in PVGVs, for most + purposes eternal code wanting to consider PVBM probably needs to think of + PVMG instead. */ +# define SVt_PVBM SVt_PVMG +#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 @@ -97,6 +105,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 +158,43 @@ 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 +is not NULL. Since we don't have to check the NULLness, it's faster +and smaller. + +=for apidoc Am|void|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|void|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 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 expressions without side +effects. 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 +is not NULL. Since we don't have to check the NULLness, it's faster +and smaller. + +=for apidoc Am|void|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|void|SvREFCNT_inc_simple_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 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|void|SvREFCNT_dec|SV* sv Decrements the reference count of the given SV. @@ -174,11 +220,41 @@ perform the upgrade if necessary. See C. (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) 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))) + #if defined(__GNUC__) && !defined(__STRICT_ANSI__) && !defined(PERL_GCC_PEDANTIC) # define SvREFCNT_dec(sv) \ ({ \ @@ -197,7 +273,7 @@ perform the upgrade if necessary. See C. #endif #define SVTYPEMASK 0xff -#define SvTYPE(sv) ((sv)->sv_flags & SVTYPEMASK) +#define SvTYPE(sv) ((svtype)((sv)->sv_flags & SVTYPEMASK)) /* Sadly there are some parts of the core that have pointers to already-freed SV heads, and rely on being able to tell that they are now free. So mark @@ -206,50 +282,56 @@ perform the upgrade if necessary. See C. #define SvUPGRADE(sv, mt) (SvTYPE(sv) >= (mt) || (sv_upgrade(sv, mt), 1)) -#define SVf_IOK 0x00000100 /* has valid public integer value */ -#define SVf_NOK 0x00000200 /* has valid public numeric value */ -#define SVf_POK 0x00000400 /* has valid public pointer value */ -#define SVf_ROK 0x00000800 /* has a valid reference pointer */ - -#define SVp_IOK 0x00001000 /* has valid non-public integer value */ -#define SVp_NOK 0x00002000 /* has valid non-public numeric value */ -#define SVp_POK 0x00004000 /* has valid non-public pointer value */ -#define SVp_SCREAM 0x00008000 /* has been studied? */ -#define SVphv_CLONEABLE 0x00008000 /* PVHV (stashes) clone its objects */ - -#define SVs_PADSTALE 0x00010000 /* lexical has gone out of scope */ -#define SVs_PADTMP 0x00020000 /* in use as tmp */ -#define SVpad_TYPED 0x00020000 /* pad name is a Typed Lexical */ -#define SVs_PADMY 0x00040000 /* in use a "my" variable */ -#define SVpad_OUR 0x00040000 /* pad name is "our" instead of "my" */ -#define SVs_TEMP 0x00080000 /* string is stealable? */ -#define SVs_OBJECT 0x00100000 /* is "blessed" */ -#define SVs_GMG 0x00200000 /* has magical get method */ -#define SVs_SMG 0x00400000 /* has magical set method */ -#define SVs_RMG 0x00800000 /* has random magical methods */ - -#define SVf_FAKE 0x01000000 /* 0: glob or lexical is just a copy - 1: SV head arena wasn't malloc()ed - 2: in conjunction with SVf_READONLY - marks a shared hash key scalar - (SvLEN == 0) or a copy on write - string (SvLEN != 0) [SvIsCOW(sv)] - 3: For PVCV, whether CvUNIQUE(cv) - refers to an eval or once only - [CvEVAL(cv), CvSPECIAL(cv)] - 4: Whether the regexp pointer is in - 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". - */ -#define SVf_OOK 0x02000000 /* has valid offset value - For a PVHV this means that a - hv_aux struct is present after the - main array */ -#define SVf_BREAK 0x04000000 /* refcnt is artificially low - used - * by SV's in final arena cleanup */ -#define SVf_READONLY 0x08000000 /* may not be modified */ +#define SVf_IOK 0x00000100 /* has valid public integer value */ +#define SVf_NOK 0x00000200 /* has valid public numeric value */ +#define SVf_POK 0x00000400 /* has valid public pointer value */ +#define SVf_ROK 0x00000800 /* has a valid reference pointer */ + +#define SVp_IOK 0x00001000 /* has valid non-public integer value */ +#define SVp_NOK 0x00002000 /* has valid non-public numeric value */ +#define SVp_POK 0x00004000 /* has valid non-public pointer value */ +#define SVp_SCREAM 0x00008000 /* has been studied? */ +#define SVphv_CLONEABLE SVp_SCREAM /* PVHV (stashes) clone its objects */ +#define SVpgv_GP SVp_SCREAM /* GV has a valid GP */ +#define SVprv_PCS_IMPORTED SVp_SCREAM /* RV is a proxy for a constant + subroutine in another package. Set the + CvIMPORTED_CV_ON() if it needs to be + expanded to a real GV */ + +#define SVs_PADSTALE 0x00010000 /* lexical has gone out of scope */ +#define SVpad_STATE 0x00010000 /* pad name is a "state" var */ +#define SVs_PADTMP 0x00020000 /* in use as tmp */ +#define SVpad_TYPED 0x00020000 /* pad name is a Typed Lexical */ +#define SVs_PADMY 0x00040000 /* in use a "my" variable */ +#define SVpad_OUR 0x00040000 /* pad name is "our" instead of "my" */ +#define SVs_TEMP 0x00080000 /* string is stealable? */ +#define SVs_OBJECT 0x00100000 /* is "blessed" */ +#define SVs_GMG 0x00200000 /* has magical get method */ +#define SVs_SMG 0x00400000 /* has magical set method */ +#define SVs_RMG 0x00800000 /* has random magical methods */ + +#define SVf_FAKE 0x01000000 /* 0: glob or lexical is just a copy + 1: SV head arena wasn't malloc()ed + 2: in conjunction with SVf_READONLY + marks a shared hash key scalar + (SvLEN == 0) or a copy on write + string (SvLEN != 0) [SvIsCOW(sv)] + 3: For PVCV, whether CvUNIQUE(cv) + refers to an eval or once only + [CvEVAL(cv), CvSPECIAL(cv)] + 4: Whether the regexp pointer is in + 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". */ +#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 main array */ +#define SVf_BREAK 0x04000000 /* refcnt is artificially low - used by + SV's in final arena cleanup */ +#define SVf_READONLY 0x08000000 /* may not be modified */ @@ -257,65 +339,93 @@ perform the upgrade if necessary. See C. #define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE) #define SVf_OK (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \ - SVp_IOK|SVp_NOK|SVp_POK|SVp_SCREAM) + SVp_IOK|SVp_NOK|SVp_POK|SVpgv_GP) #define PRIVSHIFT 4 /* (SVp_?OK >> PRIVSHIFT) == SVf_?OK */ -#define SVf_AMAGIC 0x10000000 /* has magical overloaded methods */ -#define SVf_UTF8 0x20000000 /* SvPV is UTF-8 encoded */ -/* Ensure this value does not clash with the GV_ADD* flags in gv.h */ +#define SVf_AMAGIC 0x10000000 /* has magical overloaded methods */ + +/* Ensure this value does not clash with the GV_ADD* flags in gv.h: */ +#define SVf_UTF8 0x20000000 /* SvPV is UTF-8 encoded + This is also set on RVs whose overloaded + stringification is UTF-8. This might + only happen as a side effect of SvPV() */ + /* Some private flags. */ +/* PVAV could probably use 0x2000000 without conflict. I assume that PVFM can + be UTF-8 encoded, and PVCVs could well have UTF-8 prototypes. PVIOs haven't + been restructured, so sometimes get used as string buffers. */ + /* 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 */ -#define SVpad_NAME 0x40000000 /* This SV is a name in the PAD, so - SVpad_TYPED and SVpad_OUR apply */ +#define SVphv_SHAREKEYS 0x20000000 /* PVHV keys live on shared string table */ +/* PVNV, PVMG, presumably only inside pads */ +#define SVpad_NAME 0x40000000 /* This SV is a name in the PAD, so + SVpad_TYPED, SVpad_OUR and SVpad_STATE + apply */ /* PVAV */ -#define SVpav_REAL 0x40000000 /* free old entries */ +#define SVpav_REAL 0x40000000 /* free old entries */ /* PVHV */ -#define SVphv_LAZYDEL 0x40000000 /* entry in xhv_eiter must be deleted */ -/* PVBM */ -#define SVpbm_TAIL 0x40000000 +#define SVphv_LAZYDEL 0x40000000 /* entry in xhv_eiter must be deleted */ +/* This is only set true on a PVGV when it's playing "PVBM", but is tested for + on any regular scalar (anything <= PVLV) */ +#define SVpbm_VALID 0x40000000 /* ??? */ -#define SVrepl_EVAL 0x40000000 /* Replacement part of s///e */ +#define SVrepl_EVAL 0x40000000 /* Replacement part of s///e */ /* IV, PVIV, PVNV, PVMG, PVGV and (I assume) PVLV */ /* Presumably IVs aren't stored in pads */ -#define SVf_IVisUV 0x80000000 /* use XPVUV instead of XPVIV */ +#define SVf_IVisUV 0x80000000 /* use XPVUV instead of XPVIV */ /* PVAV */ -#define SVpav_REIFY 0x80000000 /* can become real */ +#define SVpav_REIFY 0x80000000 /* can become real */ /* PVHV */ -#define SVphv_HASKFLAGS 0x80000000 /* keys have flag byte after hash */ +#define SVphv_HASKFLAGS 0x80000000 /* keys have flag byte after hash */ /* PVFM */ -#define SVpfm_COMPILED 0x80000000 /* FORMLINE is compiled */ -/* PVBM */ -#define SVpbm_VALID 0x80000000 +#define SVpfm_COMPILED 0x80000000 /* FORMLINE is compiled */ +/* PVGV when SVpbm_VALID is true */ +#define SVpbm_TAIL 0x80000000 /* RV upwards. However, SVf_ROK and SVp_IOK are exclusive */ -#define SVprv_WEAKREF 0x80000000 /* Weak reference */ +#define SVprv_WEAKREF 0x80000000 /* Weak reference */ struct xpv { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + struct { + U32 xlow; + U32 xhigh; + } xpad_cop_seq; /* used by pad.c for cop_sequence */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ }; -#if 0 -typedef struct xpv xpv_allocated; -#else typedef struct { STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ } xpv_allocated; -#endif struct xpviv { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + struct { + U32 xlow; + U32 xhigh; + } xpad_cop_seq; /* used by pad.c for cop_sequence */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -323,12 +433,10 @@ struct xpviv { UV xivu_uv; void * xivu_p1; I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; }; -#if 0 -typedef struct xpviv xpviv_allocated; -#else typedef struct { STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ @@ -337,27 +445,52 @@ typedef struct { 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; + struct { + U32 xlow; + U32 xhigh; + } xpad_cop_seq; /* used by pad.c for cop_sequence */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ + } 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; + struct { + U32 xlow; + U32 xhigh; + } xpad_cop_seq; /* used by pad.c for cop_sequence */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -365,12 +498,25 @@ 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; + struct { + U32 xlow; + U32 xhigh; + } xpad_cop_seq; /* used by pad.c for cop_sequence */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -378,6 +524,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 +534,19 @@ struct xpvmg { }; struct xpvlv { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + struct { + U32 xlow; + U32 xhigh; + } xpad_cop_seq; /* used by pad.c for cop_sequence */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -395,6 +554,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 +562,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; @@ -416,38 +569,30 @@ struct xpvlv { * y=alem/helem/iter t=tie T=tied HE */ }; +/* This structure works in 3 ways - regular scalar, GV with GP, or fast + Boyer-Moore. */ 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 */ - UV xivu_uv; - void * xivu_p1; - I32 xivu_i32; - } xiv_u; 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 */ - STRLEN xpv_cur; /* length of svu_pv as a C string */ - STRLEN xpv_len; /* allocated size */ + NV xnv_nv; + HV * xgv_stash; /* The stash of this GV */ + struct { + U32 xlow; + U32 xhigh; + } xpad_cop_seq; /* used by pad.c for cop_sequence */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ + } xnv_u; + STRLEN xpv_cur; /* xgv_flags */ + STRLEN xpv_len; /* 0 */ union { - IV xivu_iv; /* integer value or pv offset */ + IV xivu_iv; UV xivu_uv; void * xivu_p1; - I32 xivu_i32; + I32 xivu_i32; /* is this constant pattern being useful? */ + HEK * xivu_namehek; /* GvNAME */ } xiv_u; union { MAGIC* xmg_magic; /* linked list of magicalness */ @@ -455,9 +600,6 @@ struct xpvbm { } xmg_u; HV* xmg_stash; /* class package */ - I32 xbm_useful; /* is this constant pattern being useful? */ - U16 xbm_previous; /* how many characters in string before rare? */ - U8 xbm_rare; /* rarest character in string */ }; /* This structure must match XPVCV in cv.h */ @@ -465,7 +607,19 @@ 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; + struct { + U32 xlow; + U32 xhigh; + } xpad_cop_seq; /* used by pad.c for cop_sequence */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -473,6 +627,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 +663,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 +692,19 @@ typedef struct { } xpvfm_allocated; struct xpvio { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + struct { + U32 xlow; + U32 xhigh; + } xpad_cop_seq; /* used by pad.c for cop_sequence */ + struct { + U32 xbm_previous; /* how many characters in string before rare? */ + U8 xbm_flags; + U8 xbm_rare; /* rarest character in string */ + } xbm_s; /* fields from PVBM */ + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -544,6 +712,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 */ @@ -576,9 +745,8 @@ struct xpvio { GV * xio_fmt_gv; /* $~ */ char * xio_bottom_name;/* $^B */ GV * xio_bottom_gv; /* $^B */ - short xio_subprocess; /* -| or |- */ char xio_type; - char xio_flags; + U8 xio_flags; }; #define xio_dirp xio_dirpu.xiou_dirp #define xio_any xio_dirpu.xiou_any @@ -594,35 +762,35 @@ struct xpvio { /* The following macros define implementation-independent predicates on SVs. */ /* -=for apidoc Am|bool|SvNIOK|SV* sv -Returns a boolean indicating whether the SV contains a number, integer or +=for apidoc Am|U32|SvNIOK|SV* sv +Returns a U32 value indicating whether the SV contains a number, integer or double. -=for apidoc Am|bool|SvNIOKp|SV* sv -Returns a boolean indicating whether the SV contains a number, integer or +=for apidoc Am|U32|SvNIOKp|SV* sv +Returns a U32 value indicating whether the SV contains a number, integer or double. Checks the B setting. Use C. =for apidoc Am|void|SvNIOK_off|SV* sv Unsets the NV/IV status of an SV. -=for apidoc Am|bool|SvOK|SV* sv -Returns a boolean indicating whether the value is an SV. It also tells +=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. -=for apidoc Am|bool|SvIOKp|SV* sv -Returns a boolean indicating whether the SV contains an integer. Checks +=for apidoc Am|U32|SvIOKp|SV* sv +Returns a U32 value indicating whether the SV contains an integer. Checks the B setting. Use C. -=for apidoc Am|bool|SvNOKp|SV* sv -Returns a boolean indicating whether the SV contains a double. Checks the +=for apidoc Am|U32|SvNOKp|SV* sv +Returns a U32 value indicating whether the SV contains a double. Checks the B setting. Use C. -=for apidoc Am|bool|SvPOKp|SV* sv -Returns a boolean indicating whether the SV contains a character string. +=for apidoc Am|U32|SvPOKp|SV* sv +Returns a U32 value indicating whether the SV contains a character string. Checks the B setting. Use C. -=for apidoc Am|bool|SvIOK|SV* sv -Returns a boolean indicating whether the SV contains an integer. +=for apidoc Am|U32|SvIOK|SV* sv +Returns a U32 value indicating whether the SV contains an integer. =for apidoc Am|void|SvIOK_on|SV* sv Tells an SV that it is an integer. @@ -639,14 +807,14 @@ Tells and SV that it is an unsigned integer and disables all other OK bits. =for apidoc Am|bool|SvIOK_UV|SV* sv Returns a boolean indicating whether the SV contains an unsigned integer. -=for apidoc Am|void|SvUOK|SV* sv +=for apidoc Am|bool|SvUOK|SV* sv Returns a boolean indicating whether the SV contains an unsigned integer. =for apidoc Am|bool|SvIOK_notUV|SV* sv Returns a boolean indicating whether the SV contains a signed integer. -=for apidoc Am|bool|SvNOK|SV* sv -Returns a boolean indicating whether the SV contains a double. +=for apidoc Am|U32|SvNOK|SV* sv +Returns a U32 value indicating whether the SV contains a double. =for apidoc Am|void|SvNOK_on|SV* sv Tells an SV that it is a double. @@ -657,8 +825,8 @@ Unsets the NV status of an SV. =for apidoc Am|void|SvNOK_only|SV* sv Tells an SV that it is a double and disables all other OK bits. -=for apidoc Am|bool|SvPOK|SV* sv -Returns a boolean indicating whether the SV contains a character +=for apidoc Am|U32|SvPOK|SV* sv +Returns a U32 value indicating whether the SV contains a character string. =for apidoc Am|void|SvPOK_on|SV* sv @@ -674,13 +842,13 @@ Will also turn off the UTF-8 status. =for apidoc Am|bool|SvVOK|SV* sv Returns a boolean indicating whether the SV contains a v-string. -=for apidoc Am|bool|SvOOK|SV* sv -Returns a boolean indicating whether the SvIVX is a valid offset value for +=for apidoc Am|U32|SvOOK|SV* sv +Returns a U32 indicating whether the SvIVX is a valid offset value for the SvPVX. This hack is used internally to speed up removal of characters from the beginning of a SvPV. When SvOOK is true, then the start of the allocated string buffer is really (SvPVX - SvIVX). -=for apidoc Am|bool|SvROK|SV* sv +=for apidoc Am|U32|SvROK|SV* sv Tests if the SV is an RV. =for apidoc Am|void|SvROK_on|SV* sv @@ -743,7 +911,7 @@ Set the value of the RV pointer in sv to val. See C. =for apidoc Am|void|SvMAGIC_set|SV* sv|MAGIC* val Set the value of the MAGIC pointer in sv to val. See C. -=for apidoc Am|void|SvSTASH_set|SV* sv|STASH* val +=for apidoc Am|void|SvSTASH_set|SV* sv|HV* val Set the value of the STASH pointer in sv to val. See C. =for apidoc Am|void|SvCUR_set|SV* sv|STRLEN len @@ -763,37 +931,41 @@ Set the actual length of the string which is in the SV. See C. #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(sv) ((SvTYPE(sv) == SVt_BIND) \ + ? (SvFLAGS(SvRV(sv)) & SVf_OK) \ + : (SvFLAGS(sv) & SVf_OK)) +#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)) \ @@ -807,14 +979,17 @@ Set the actual length of the string which is in the SV. See C. #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)) /* -=for apidoc Am|bool|SvUTF8|SV* sv -Returns a boolean indicating whether the SV contains UTF-8 encoded data. +=for apidoc Am|U32|SvUTF8|SV* sv +Returns a U32 value indicating whether the SV contains UTF-8 encoded data. +Call this after SvPV() in case any call to string overloading updates the +internal flag. =for apidoc Am|void|SvUTF8_on|SV *sv Turn on the UTF-8 status of an SV (the data is not changed, just the flag). @@ -837,20 +1012,24 @@ 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) \ - 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 SvVOK(sv) (SvMAGICAL(sv) \ + && mg_find(sv,PERL_MAGIC_vstring)) +/* returns the vstring magic, if any */ +#define SvVSTRING_mg(sv) (SvMAGICAL(sv) \ ? mg_find(sv,PERL_MAGIC_vstring) : NULL) + #define SvOOK(sv) (SvFLAGS(sv) & SVf_OOK) #define SvOOK_on(sv) ((void)SvIOK_off(sv), SvFLAGS(sv) |= SVf_OOK) #define SvOOK_off(sv) ((void)(SvOOK(sv) && sv_backoff(sv))) @@ -861,7 +1040,7 @@ in gv.h: */ #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)) @@ -879,17 +1058,36 @@ in gv.h: */ #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 SvGAMAGIC(sv) (SvFLAGS(sv) & (SVs_GMG|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 Gv_AMG(stash) \ - (HV_AMAGICmb(stash) && \ - ((!HV_AMAGICbad(stash) && HV_AMAGIC(stash)) || Gv_AMupdate(stash))) +=for apidoc Am|char*|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 +time it is accessed. Hence you must be careful to only read it once per user +logical operation and work with that returned value. If neither is true then +the scalar's value cannot change unless written to. + +=cut */ + +#define SvGAMAGIC(sv) (SvGMAGICAL(sv) || SvAMAGIC(sv)) + #define Gv_AMG(stash) (PL_amagic_generation && Gv_AMupdate(stash)) #define SvWEAKREF(sv) ((SvFLAGS(sv) & (SVf_ROK|SVprv_WEAKREF)) \ @@ -897,6 +1095,11 @@ in gv.h: */ #define SvWEAKREF_on(sv) (SvFLAGS(sv) |= (SVf_ROK|SVprv_WEAKREF)) #define SvWEAKREF_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVprv_WEAKREF)) +#define SvPCS_IMPORTED(sv) ((SvFLAGS(sv) & (SVf_ROK|SVprv_PCS_IMPORTED)) \ + == (SVf_ROK|SVprv_PCS_IMPORTED)) +#define SvPCS_IMPORTED_on(sv) (SvFLAGS(sv) |= (SVf_ROK|SVprv_PCS_IMPORTED)) +#define SvPCS_IMPORTED_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVprv_PCS_IMPORTED)) + #define SvTHINKFIRST(sv) (SvFLAGS(sv) & SVf_THINKFIRST) #define SvPADSTALE(sv) (SvFLAGS(sv) & SVs_PADSTALE) @@ -934,13 +1137,38 @@ in gv.h: */ #define SvEVALED_on(sv) (SvFLAGS(sv) |= SVrepl_EVAL) #define SvEVALED_off(sv) (SvFLAGS(sv) &= ~SVrepl_EVAL) -#define SvTAIL(sv) (SvFLAGS(sv) & SVpbm_TAIL) +#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_on(sv) ({ SV *const thwacke = (SV *) (sv); \ + assert(!isGV_with_GP(thwacke)); \ + (SvFLAGS(thwacke) |= SVpbm_VALID); \ + }) +# define SvVALID_off(sv) ({ SV *const thwacke = (SV *) (sv); \ + assert(!isGV_with_GP(thwacke)); \ + (SvFLAGS(thwacke) &= ~SVpbm_VALID); \ + }) + +# define SvTAIL(sv) ({ SV *const _svi = (SV *) (sv); \ + assert(SvTYPE(_svi) != SVt_PVAV); \ + assert(SvTYPE(_svi) != SVt_PVHV); \ + (SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID)) \ + == (SVpbm_TAIL|SVpbm_VALID); \ + }) +#else +# define SvVALID(sv) (SvFLAGS(sv) & SVpbm_VALID) +# define SvVALID_on(sv) (SvFLAGS(sv) |= SVpbm_VALID) +# define SvVALID_off(sv) (SvFLAGS(sv) &= ~SVpbm_VALID) +# define SvTAIL(sv) ((SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID)) \ + == (SVpbm_TAIL|SVpbm_VALID)) + +#endif #define SvTAIL_on(sv) (SvFLAGS(sv) |= SVpbm_TAIL) #define SvTAIL_off(sv) (SvFLAGS(sv) &= ~SVpbm_TAIL) -#define SvVALID(sv) (SvFLAGS(sv) & SVpbm_VALID) -#define SvVALID_on(sv) (SvFLAGS(sv) |= SVpbm_VALID) -#define SvVALID_off(sv) (SvFLAGS(sv) &= ~SVpbm_VALID) #ifdef USE_ITHREADS /* The following uses the FAKE flag to show that a regex pointer is infact @@ -952,24 +1180,45 @@ in gv.h: */ #define SvPAD_TYPED(sv) \ ((SvFLAGS(sv) & (SVpad_NAME|SVpad_TYPED)) == (SVpad_NAME|SVpad_TYPED)) -#define SvPAD_TYPED_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED) #define SvPAD_OUR(sv) \ ((SvFLAGS(sv) & (SVpad_NAME|SVpad_OUR)) == (SVpad_NAME|SVpad_OUR)) -#define SvPAD_OUR_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR) -#define OURSTASH(sv) \ +#define SvPAD_STATE(sv) \ + ((SvFLAGS(sv) & (SVpad_NAME|SVpad_STATE)) == (SVpad_NAME|SVpad_STATE)) + +#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); \ + }) +#define SvPAD_OUR_on(sv) ({ \ + SV *const whap = (SV *) (sv); \ + assert(SvTYPE(whap) == SVt_PVMG); \ + (SvFLAGS(whap) |= 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); \ + }) +#else +# define SvPAD_TYPED_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED) +# define SvPAD_OUR_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR) +# define SvPAD_STATE_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_STATE) +#endif + +#define SvOURSTASH(sv) \ (SvPAD_OUR(sv) ? ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash : NULL) -#define OURSTASH_set(sv, st) \ +#define SvOURSTASH_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 -#define SvRV(sv) ((sv)->sv_u.svu_rv) #endif #define SvRVx(sv) SvRV(sv) @@ -978,7 +1227,8 @@ 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) +# define SvRV(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)) @@ -990,67 +1240,91 @@ in gv.h: */ # 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_u.xmg_magic)) -# else -# define SvMAGIC(sv) (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*) SvANY(sv))->xmg_u.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_u.xmg_magic -# else -# define SvMAGIC(sv) (0 + ((XPVMG*) SvANY(sv))->xmg_u.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; \ + (*({ 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) \ - (*({ SV *const _svi = (SV *) 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); \ })) # define SvNVX(sv) \ - (*({ SV *const _svi = (SV *) 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); \ - &(((XPVNV*) SvANY(_svi))->xnv_nv); \ + assert(!isGV_with_GP(_svi)); \ + &(((XPVNV*) SvANY(_svi))->xnv_u.xnv_nv); \ + })) +# define SvRV(sv) \ + (*({ SV *const _svi = (SV *) (sv); \ + assert(SvTYPE(_svi) >= SVt_RV); \ + 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); \ })) # define SvMAGIC(sv) \ - (*({ SV *const _svi = (SV *) 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); \ })) # define SvSTASH(sv) \ - (*({ SV *const _svi = (SV *) sv; \ + (*({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) >= SVt_PVMG); \ &(((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 SvRV(sv) ((sv)->sv_u.svu_rv) # define SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_u.xmg_magic # define SvSTASH(sv) ((XPVMG*) SvANY(sv))->xmg_stash # endif @@ -1084,19 +1358,37 @@ 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(SvTYPE(sv) != SVt_PVAV); \ + assert(SvTYPE(sv) != SVt_PVHV); \ + assert(SvTYPE(sv) != SVt_PVCV); \ + 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(SvTYPE(sv) != SVt_PVCV); assert(SvTYPE(sv) != SVt_PVFM); \ + 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(SvTYPE(sv) != SVt_PVAV); \ + assert(SvTYPE(sv) != SVt_PVHV); \ + 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(SvTYPE(sv) != SVt_PVAV); \ + assert(SvTYPE(sv) != SVt_PVHV); \ + assert(SvTYPE(sv) != SVt_PVCV); \ + 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(SvTYPE(sv) != SVt_PVAV); \ + assert(SvTYPE(sv) != SVt_PVHV); \ + assert(SvTYPE(sv) != SVt_PVCV); \ + assert(SvTYPE(sv) != SVt_PVFM); \ + 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); \ @@ -1106,9 +1398,15 @@ in gv.h: */ (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END #define SvCUR_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ + assert(SvTYPE(sv) != SVt_PVAV); \ + assert(SvTYPE(sv) != SVt_PVHV); \ + 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(SvTYPE(sv) != SVt_PVAV); \ + assert(SvTYPE(sv) != SVt_PVHV); \ + 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); \ @@ -1138,9 +1436,45 @@ in gv.h: */ } \ } STMT_END -#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 PERL_FBM_TABLE_OFFSET 1 /* Number of bytes between EOS and table */ + +/* SvPOKp not SvPOK in the assertion because the string can be tainted! eg + perl -T -e '/$^X/' +*/ +#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); \ + })) +# 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); \ + })) +# 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); \ + })) +# 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); \ + })) +#else +# define BmFLAGS(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_flags +# define BmRARE(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_rare +# define BmUSEFUL(sv) ((XPVGV*) SvANY(sv))->xiv_u.xivu_i32 +# define BmPREVIOUS(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_previous + +#endif #define FmLINES(sv) ((XPVFM*) SvANY(sv))->xfm_lines @@ -1163,7 +1497,6 @@ in gv.h: */ #define IoFMT_GV(sv) ((XPVIO*) SvANY(sv))->xio_fmt_gv #define IoBOTTOM_NAME(sv)((XPVIO*) SvANY(sv))->xio_bottom_name #define IoBOTTOM_GV(sv) ((XPVIO*) SvANY(sv))->xio_bottom_gv -#define IoSUBPROCESS(sv)((XPVIO*) SvANY(sv))->xio_subprocess #define IoTYPE(sv) ((XPVIO*) SvANY(sv))->xio_type #define IoFLAGS(sv) ((XPVIO*) SvANY(sv))->xio_flags @@ -1233,7 +1566,9 @@ stringified version becoming C. Handles 'get' magic. See also C for a version which guarantees to evaluate sv only once. =for apidoc Am|char*|SvPVx|SV* sv|STRLEN len -A version of C which guarantees to evaluate sv only once. +A version of C which guarantees to evaluate C only once. +Only use this if C is an expression with side effects, otherwise use the +more efficient C. =for apidoc Am|char*|SvPV_nomg|SV* sv|STRLEN len Like C but doesn't process magic. @@ -1244,7 +1579,7 @@ the SV if the SV does not contain a string. The SV may cache the stringified form becoming C. Handles 'get' magic. =for apidoc Am|IV|SvIV|SV* sv -Coerces the given SV to an integer and returns it. See C for a +Coerces the given SV to an integer and returns it. See C for a version which guarantees to evaluate sv only once. =for apidoc Am|IV|SvIV_nomg|SV* sv @@ -1252,15 +1587,17 @@ Like C but doesn't process magic. =for apidoc Am|IV|SvIVx|SV* sv Coerces the given SV to an integer and returns it. Guarantees to evaluate -sv only once. Use the more efficient C otherwise. +C only once. Only use this if C is an expression with side effects, +otherwise use the more efficient C. =for apidoc Am|NV|SvNV|SV* sv -Coerce the given SV to a double and return it. See C for a version +Coerce the given SV to a double and return it. See C for a version which guarantees to evaluate sv only once. =for apidoc Am|NV|SvNVx|SV* sv Coerces the given SV to a double and returns it. Guarantees to evaluate -sv only once. Use the more efficient C otherwise. +C only once. Only use this if C is an expression with side effects, +otherwise use the more efficient C. =for apidoc Am|UV|SvUV|SV* sv Coerces the given SV to an unsigned integer and returns it. See C @@ -1271,7 +1608,8 @@ Like C but doesn't process magic. =for apidoc Am|UV|SvUVx|SV* sv Coerces the given SV to an unsigned integer and returns it. Guarantees to -evaluate sv only once. Use the more efficient C otherwise. +C only once. Only use this if C is an expression with side effects, +otherwise use the more efficient C. =for apidoc Am|bool|SvTRUE|SV* sv Returns a boolean indicating whether Perl would evaluate the SV as true or @@ -1516,9 +1854,29 @@ Like C but doesn't process magic. #define SV_CONST_RETURN 32 #define SV_MUTABLE_RETURN 64 #define SV_SMAGIC 128 +#define SV_HAS_TRAILING_NUL 256 +#define SV_COW_SHARED_HASH_KEYS 512 +/* This one is only enabled for PERL_OLD_COPY_ON_WRITE */ +#define SV_COW_OTHER_PVS 1024 + +/* 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. + */ +#ifdef PERL_CORE +# ifndef SV_DO_COW_SVSETSV +# define SV_DO_COW_SVSETSV SV_COW_SHARED_HASH_KEYS|SV_COW_OTHER_PVS +# endif +#endif + +#ifndef SV_DO_COW_SVSETSV +# define SV_DO_COW_SVSETSV 0 +#endif + #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 @@ -1530,8 +1888,8 @@ Like C but doesn't process magic. sv_force_normal_flags(sv, SV_COW_DROP_PV) #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 SvRELEASE_IVX(sv) \ + ((SvIsCOW(sv) ? sv_force_normal_flags(sv, 0) : (void) 0), SvOOK_off(sv)) # define SvIsCOW_normal(sv) (SvIsCOW(sv) && SvLEN(sv)) #else # define SvRELEASE_IVX(sv) SvOOK_off(sv) @@ -1539,7 +1897,7 @@ Like C but doesn't process magic. #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)) \ @@ -1555,8 +1913,9 @@ Like C but doesn't process magic. #define sv_pvn_force_nomg(sv, lp) sv_pvn_force_flags(sv, lp, 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) sv_setsv_flags(dsv, ssv, SV_GMAGIC) -#define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, 0) +#define sv_setsv(dsv, ssv) \ + sv_setsv_flags(dsv, ssv, SV_GMAGIC|SV_DO_COW_SVSETSV) +#define sv_setsv_nomg(dsv, ssv) sv_setsv_flags(dsv, ssv, SV_DO_COW_SVSETSV) #define sv_catsv(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC) #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) @@ -1663,7 +2022,7 @@ Returns a pointer to the character buffer. #define SvSetSV_nosteal_and(dst,src,finally) \ STMT_START { \ if ((dst) != (src)) { \ - sv_setsv_flags(dst, src, SV_GMAGIC | SV_NOSTEAL); \ + sv_setsv_flags(dst, src, SV_GMAGIC | SV_NOSTEAL | SV_DO_COW_SVSETSV); \ finally; \ } \ } STMT_END @@ -1690,6 +2049,24 @@ 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|SVpgv_GP)) == SVpgv_GP) \ + && (SvTYPE(pwadak) == SVt_PVGV || SvTYPE(pwadak) == SVt_PVLV)) +#define isGV_with_GP_on(sv) STMT_START { \ + assert (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV); \ + assert (!SvPOKp(sv)); \ + assert (!SvIOKp(sv)); \ + (SvFLAGS(sv) |= SVpgv_GP); \ + } STMT_END +#define isGV_with_GP_off(sv) STMT_START { \ + assert (SvTYPE(sv) == SVt_PVGV || SvTYPE(sv) == SVt_PVLV); \ + assert (!SvPOKp(sv)); \ + assert (!SvIOKp(sv)); \ + (SvFLAGS(sv) &= ~SVpgv_GP); \ + } STMT_END + #define SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv)) #define SvGROW_mutable(sv,len) \