X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.h;h=cf2f6562bb67ed692768ac29b828b30e7e1a8f5c;hb=a1bbeb14a7db6e20495fcc951bfd8664b8f99c58;hp=c509ac664966cf82ab953a9fc89f5ccde377a9e8;hpb=f7877b281b40407827939f44ea94226de573cdbc;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.h b/sv.h index c509ac6..cf2f656 100644 --- a/sv.h +++ b/sv.h @@ -150,6 +150,41 @@ Returns the value of the object's reference count. =for apidoc Am|SV*|SvREFCNT_inc|SV* sv Increments the reference count of the given SV. +All of the following SvREFCNT_inc* macros are optimized versions of +SvREFCNT_inc, and can be replaced with SvREFCNT_inc. + +=for apidoc Am|SV*|SvREFCNT_inc_NN|SV* sv +Same as SvREFCNT_inc, but can only be used if you know I +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 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 +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. @@ -175,11 +210,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) 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) \ ({ \ @@ -242,8 +307,9 @@ perform the upgrade if necessary. See C. 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 @@ -269,8 +335,6 @@ perform the upgrade if necessary. See C. /* 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 */ @@ -301,7 +365,10 @@ perform the upgrade if necessary. See C. 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 */ }; @@ -316,7 +383,10 @@ typedef struct { #endif struct xpviv { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -324,6 +394,7 @@ struct xpviv { UV xivu_uv; void * xivu_p1; I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; }; @@ -338,6 +409,7 @@ typedef struct { UV xivu_uv; void * xivu_p1; I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; } xpviv_allocated; #endif @@ -345,20 +417,27 @@ typedef struct { #define xiv_iv xiv_u.xivu_iv struct xpvuv { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { IV xuvu_iv; UV xuvu_uv; /* unsigned value or pv offset */ void * xuvu_p1; + HEK * xivu_namehek; } xuv_u; }; #define xuv_uv xuv_u.xuvu_uv struct xpvnv { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -366,12 +445,16 @@ struct xpvnv { UV xivu_uv; void * xivu_p1; I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; }; /* These structure must match the beginning of struct xpvhv in hv.h. */ struct xpvmg { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -379,6 +462,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 */ @@ -388,7 +472,10 @@ struct xpvmg { }; struct xpvlv { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -396,6 +483,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 */ @@ -403,12 +491,6 @@ struct xpvlv { } xmg_u; HV* xmg_stash; /* class package */ - /* a full glob fits into this */ - char* xgv_name; - STRLEN xgv_namelen; - HV* xgv_stash; - U8 xgv_flags; - STRLEN xlv_targoff; STRLEN xlv_targlen; SV* xlv_targ; @@ -417,14 +499,18 @@ struct xpvlv { }; struct xpvgv { - NV xnv_nv; /* numeric value, if any */ - STRLEN xpv_cur; /* length of svu_pv as a C string */ - STRLEN xpv_len; /* allocated size */ union { - IV xivu_iv; /* integer value or pv offset */ + NV xnv_nv; + HV * xgv_stash; /* The stash of this GV */ + } xnv_u; + STRLEN xpv_cur; /* xgv_flags */ + STRLEN xpv_len; /* 0 */ + union { + IV xivu_iv; UV xivu_uv; void * xivu_p1; I32 xivu_i32; + HEK * xivu_namehek; /* GvNAME */ } xiv_u; union { MAGIC* xmg_magic; /* linked list of magicalness */ @@ -432,14 +518,13 @@ struct xpvgv { } xmg_u; HV* xmg_stash; /* class package */ - 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 { @@ -447,6 +532,7 @@ struct xpvbm { UV xivu_uv; void * xivu_p1; I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; union { MAGIC* xmg_magic; /* linked list of magicalness */ @@ -464,7 +550,10 @@ struct xpvbm { typedef U16 cv_flags_t; struct xpvfm { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -472,6 +561,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 */ @@ -507,6 +597,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 */ @@ -535,7 +626,10 @@ typedef struct { } xpvfm_allocated; struct xpvio { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + } xnv_u; STRLEN xpv_cur; /* length of svu_pv as a C string */ STRLEN xpv_len; /* allocated size */ union { @@ -543,6 +637,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 */ @@ -770,11 +865,11 @@ Set the actual length of the string which is in the SV. See C. #define SvOK(sv) (SvFLAGS(sv) & SVf_OK) #define SvOK_off(sv) (assert_not_ROK(sv) assert_not_glob(sv) \ - SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ + 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)) @@ -843,11 +938,11 @@ in gv.h: */ SvFLAGS(sv) |= (SVf_POK|SVp_POK)) #define SvPOK_off(sv) (SvFLAGS(sv) &= ~(SVf_POK|SVp_POK)) #define SvPOK_only(sv) (assert_not_ROK(sv) assert_not_glob(sv) \ - SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ + SvFLAGS(sv) &= ~(SVf_OK| \ SVf_IVisUV|SVf_UTF8), \ SvFLAGS(sv) |= (SVf_POK|SVp_POK)) #define SvPOK_only_UTF8(sv) (assert_not_ROK(sv) assert_not_glob(sv) \ - SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ + SvFLAGS(sv) &= ~(SVf_OK| \ SVf_IVisUV), \ SvFLAGS(sv) |= (SVf_POK|SVp_POK)) @@ -863,7 +958,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)) @@ -881,17 +976,24 @@ 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 SvAMAGIC(sv) (SvROK(sv) && (SvFLAGS(SvRV(sv)) & SVf_AMAGIC)) +#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) +# define SvAMAGIC_on(sv) ({ SV *kloink = sv; \ + assert(SvROK(kloink)); \ + SvFLAGS(SvRV(kloink)) |= SVf_AMAGIC; \ + }) +# define SvAMAGIC_off(sv) ({ SV *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)) \ @@ -980,7 +1082,7 @@ in gv.h: */ +0.0 + -0.0 => +0.0 but -0.0 + -0.0 => -0.0 */ # define SvIVX(sv) (0 + ((XPVIV*) SvANY(sv))->xiv_iv) # define SvUVX(sv) (0 + ((XPVUV*) SvANY(sv))->xuv_uv) -# define SvNVX(sv) (-0.0 + ((XPVNV*) SvANY(sv))->xnv_nv) +# define SvNVX(sv) (-0.0 + ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv) /* Don't test the core XS code yet. */ # if defined (PERL_CORE) && PERL_DEBUG_COW > 1 # define SvPVX(sv) (0 + (assert(!SvREADONLY(sv)), (sv)->sv_u.svu_pv)) @@ -999,7 +1101,6 @@ in gv.h: */ # define SvSTASH(sv) (0 + ((XPVMG*) SvANY(sv))->xmg_stash) # endif #else -# 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) @@ -1013,12 +1114,21 @@ in gv.h: */ 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) \ @@ -1027,6 +1137,7 @@ in gv.h: */ assert(SvTYPE(_svi) != SVt_PVAV); \ assert(SvTYPE(_svi) != SVt_PVHV); \ assert(SvTYPE(_svi) != SVt_PVCV); \ + assert(!isGV_with_GP(_svi)); \ &(((XPVUV*) SvANY(_svi))->xuv_uv); \ })) # define SvNVX(sv) \ @@ -1035,7 +1146,8 @@ in gv.h: */ assert(SvTYPE(_svi) != SVt_PVAV); \ assert(SvTYPE(_svi) != SVt_PVHV); \ assert(SvTYPE(_svi) != SVt_PVFM); \ - &(((XPVNV*) SvANY(_svi))->xnv_nv); \ + assert(!isGV_with_GP(_svi)); \ + &(((XPVNV*) SvANY(_svi))->xnv_u.xnv_nv); \ })) # define SvMAGIC(sv) \ (*({ SV *const _svi = (SV *) sv; \ @@ -1048,10 +1160,11 @@ in gv.h: */ &(((XPVMG*) SvANY(_svi))->xmg_stash); \ })) # else -# define SvPVX(sv) ((sv)->sv_u.svu_pv) +# define SvPVX(sv) ((sv)->sv_u.svu_pv) +# define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur # define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv # define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv -# define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_nv +# define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv # define SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_u.xmg_magic # define SvSTASH(sv) ((XPVMG*) SvANY(sv))->xmg_stash # endif @@ -1085,19 +1198,24 @@ in gv.h: */ (void) SvIV(sv); } STMT_END #define SvIV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ + assert(!isGV_with_GP(sv)); \ (((XPVIV*) SvANY(sv))->xiv_iv = (val)); } STMT_END #define SvNV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) == SVt_NV || SvTYPE(sv) >= SVt_PVNV); \ assert(SvTYPE(sv) != SVt_PVAV); assert(SvTYPE(sv) != SVt_PVHV); \ - (((XPVNV*)SvANY(sv))->xnv_nv = (val)); } STMT_END + assert(!isGV_with_GP(sv)); \ + (((XPVNV*)SvANY(sv))->xnv_u.xnv_nv = (val)); } STMT_END #define SvPV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ + assert(!isGV_with_GP(sv)); \ ((sv)->sv_u.svu_pv = (val)); } STMT_END #define SvUV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ + assert(!isGV_with_GP(sv)); \ (((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END #define SvRV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ + assert(!isGV_with_GP(sv)); \ ((sv)->sv_u.svu_rv = (val)); } STMT_END #define SvMAGIC_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ @@ -1107,6 +1225,7 @@ in gv.h: */ (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END #define SvCUR_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ + assert(!isGV_with_GP(sv)); \ (((XPV*) SvANY(sv))->xpv_cur = (val)); } STMT_END #define SvLEN_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ @@ -1541,7 +1660,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)) \