X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.h;h=cf2f6562bb67ed692768ac29b828b30e7e1a8f5c;hb=a922f900a6916d70770b1348cbacd5ea3df02a9f;hp=7c098be80907592c8df2a539ef9a27c7027e8544;hpb=584307902de552f84517013f42d1db478f4102bd;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.h b/sv.h index 7c098be..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 */ @@ -330,6 +394,7 @@ struct xpviv { UV xivu_uv; void * xivu_p1; I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; }; @@ -344,6 +409,7 @@ typedef struct { UV xivu_uv; void * xivu_p1; I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; } xpviv_allocated; #endif @@ -361,6 +427,7 @@ struct xpvuv { IV xuvu_iv; UV xuvu_uv; /* unsigned value or pv offset */ void * xuvu_p1; + HEK * xivu_namehek; } xuv_u; }; @@ -378,6 +445,7 @@ struct xpvnv { UV xivu_uv; void * xivu_p1; I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; }; @@ -394,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 */ @@ -414,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 */ @@ -421,11 +491,6 @@ struct xpvlv { } xmg_u; HV* xmg_stash; /* class package */ - /* a full glob fits into this */ - char* xgv_name; - STRLEN xgv_namelen; - U8 xgv_flags; - STRLEN xlv_targoff; STRLEN xlv_targlen; SV* xlv_targ; @@ -438,13 +503,14 @@ struct xpvgv { NV xnv_nv; HV * xgv_stash; /* The stash of this GV */ } xnv_u; - STRLEN xpv_cur; /* length of svu_pv as a C string */ - STRLEN xpv_len; /* allocated size */ + 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; + HEK * xivu_namehek; /* GvNAME */ } xiv_u; union { MAGIC* xmg_magic; /* linked list of magicalness */ @@ -452,9 +518,6 @@ struct xpvgv { } xmg_u; HV* xmg_stash; /* class package */ - char* xgv_name; - STRLEN xgv_namelen; - U8 xgv_flags; }; struct xpvbm { @@ -469,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 */ @@ -497,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 */ @@ -532,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 */ @@ -571,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 */ @@ -798,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)) @@ -871,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)) @@ -891,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)) @@ -909,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)) \ @@ -1027,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) @@ -1041,6 +1114,14 @@ 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); \ @@ -1079,7 +1160,8 @@ 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_u.xnv_nv @@ -1116,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); \ + 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); \ @@ -1138,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); \ @@ -1572,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)) \