X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=hv.h;h=efba2b98bdf67eaac8113c8266a6d452a467f63e;hb=943795c2b00ef89ec677d4af7a0a6bfabab5c916;hp=3115dba91ca450377dc7b9bccdbeefea20810827;hpb=97ddebaf393a19fb80bf52b8fdb8330e1c4a591b;p=p5sagit%2Fp5-mst-13.2.git diff --git a/hv.h b/hv.h index 3115dba..efba2b9 100644 --- a/hv.h +++ b/hv.h @@ -8,15 +8,17 @@ * */ -/* typedefs to eliminate some typing */ -typedef struct he HE; -typedef struct hek HEK; - /* entry in hash value chain */ struct he { + /* Keep hent_next first in this structure, because sv_free_arenas take + advantage of this to share code between the he arenas and the SV + body arenas */ HE *hent_next; /* next entry in chain */ HEK *hent_hek; /* hash key */ - SV *hent_val; /* scalar value that was hashed */ + union { + SV *hent_val; /* scalar value that was hashed */ + Size_t hent_refcount; /* references for this shared hash key */ + } he_valu; }; /* hash key -- defined separately for use as shared pointer */ @@ -29,12 +31,17 @@ struct hek { is UTF-8 */ }; +struct shared_he { + struct he shared_he_he; + struct hek shared_he_hek; +}; /* Subject to change. Don't access this directly. */ struct xpvhv_aux { HEK *xhv_name; /* name, if a symbol table */ + AV *xhv_backreferences; /* back references for weak references */ HE *xhv_eiter; /* current entry of iterator */ I32 xhv_riter; /* current root of iterator */ }; @@ -42,15 +49,23 @@ struct xpvhv_aux { /* hash structure: */ /* This structure must match the beginning of struct xpvmg in sv.h. */ struct xpvhv { - NV xnv_nv; /* numeric value, if any */ + union { + NV xnv_nv; /* numeric value, if any */ + HV * xgv_stash; + } xnv_u; STRLEN xhv_fill; /* how full xhv_array currently is */ STRLEN xhv_max; /* subscript of last element of xhv_array */ union { IV xivu_iv; /* integer value or pv offset */ UV xivu_uv; void * xivu_p1; + I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; - MAGIC* xmg_magic; /* magic for scalar array */ + 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 */ }; @@ -66,8 +81,13 @@ typedef struct { IV xivu_iv; /* integer value or pv offset */ UV xivu_uv; void * xivu_p1; + I32 xivu_i32; + HEK * xivu_namehek; } xiv_u; - MAGIC* xmg_magic; /* magic for scalar array */ + 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 */ } xpvhv_allocated; #endif @@ -79,7 +99,7 @@ typedef struct { /* The use of a temporary pointer and the casting games * is needed to serve the dual purposes of * (a) the hashed data being interpreted as "unsigned char" (new since 5.8, - * a "char" can be either signed or signed, depending on the compiler) + * a "char" can be either signed or unsigned, depending on the compiler) * (b) catering for old code that uses a "char" * * The "hash seed" feature was added in Perl 5.8.1 to perturb the results @@ -100,7 +120,7 @@ typedef struct { #endif #define PERL_HASH(hash,str,len) \ STMT_START { \ - register const char *s_PeRlHaSh_tmp = str; \ + register const char * const s_PeRlHaSh_tmp = str; \ register const unsigned char *s_PeRlHaSh = (const unsigned char *)s_PeRlHaSh_tmp; \ register I32 i_PeRlHaSh = len; \ register U32 hash_PeRlHaSh = PERL_HASH_SEED; \ @@ -118,7 +138,7 @@ typedef struct { #ifdef PERL_HASH_INTERNAL_ACCESS #define PERL_HASH_INTERNAL(hash,str,len) \ STMT_START { \ - register const char *s_PeRlHaSh_tmp = str; \ + register const char * const s_PeRlHaSh_tmp = str; \ register const unsigned char *s_PeRlHaSh = (const unsigned char *)s_PeRlHaSh_tmp; \ register I32 i_PeRlHaSh = len; \ register U32 hash_PeRlHaSh = PL_rehash_seed; \ @@ -149,7 +169,8 @@ Null HV pointer. =head1 Hash Manipulation Functions =for apidoc Am|char*|HvNAME|HV* stash -Returns the package name of a stash. See C, C. +Returns the package name of a stash, or NULL if C isn't a stash. +See C, C. =for apidoc Am|void*|HeKEY|HE* he Returns the actual pointer stored in the key slot of the hash entry. The @@ -181,7 +202,7 @@ the length of hash keys. This is very similar to the C macro described elsewhere in this document. =for apidoc Am|SV*|HeSVKEY|HE* he -Returns the key as an C, or C if the hash entry does not +Returns the key as an C, or C if the hash entry does not contain an C key. =for apidoc Am|SV*|HeSVKEY_force|HE* he @@ -201,7 +222,7 @@ C. #define Nullhv Null(HV*) -#define HvARRAY(hv) (*(HE***)&((hv)->sv_u.svu_array)) +#define HvARRAY(hv) ((hv)->sv_u.svu_hash) #define HvFILL(hv) ((XPVHV*) SvANY(hv))->xhv_fill #define HvMAX(hv) ((XPVHV*) SvANY(hv))->xhv_max /* This quite intentionally does no flag checking first. That's your @@ -262,19 +283,6 @@ C. #define HvREHASH_on(hv) (SvFLAGS(hv) |= SVphv_REHASH) #define HvREHASH_off(hv) (SvFLAGS(hv) &= ~SVphv_REHASH) -/* Maybe amagical: */ -/* #define HV_AMAGICmb(hv) (SvFLAGS(hv) & (SVpgv_badAM | SVpgv_AM)) */ - -#define HV_AMAGIC(hv) (SvFLAGS(hv) & SVpgv_AM) -#define HV_AMAGIC_on(hv) (SvFLAGS(hv) |= SVpgv_AM) -#define HV_AMAGIC_off(hv) (SvFLAGS(hv) &= ~SVpgv_AM) - -/* -#define HV_AMAGICbad(hv) (SvFLAGS(hv) & SVpgv_badAM) -#define HV_badAMAGIC_on(hv) (SvFLAGS(hv) |= SVpgv_badAM) -#define HV_badAMAGIC_off(hv) (SvFLAGS(hv) &= ~SVpgv_badAM) -*/ - #define Nullhe Null(HE*) #define HeNEXT(he) (he)->hent_next #define HeKEY_hek(he) (he)->hent_hek @@ -286,16 +294,16 @@ C. #define HeKREHASH(he) HEK_REHASH(HeKEY_hek(he)) #define HeKLEN_UTF8(he) (HeKUTF8(he) ? -HeKLEN(he) : HeKLEN(he)) #define HeKFLAGS(he) HEK_FLAGS(HeKEY_hek(he)) -#define HeVAL(he) (he)->hent_val +#define HeVAL(he) (he)->he_valu.hent_val #define HeHASH(he) HEK_HASH(HeKEY_hek(he)) #define HePV(he,lp) ((HeKLEN(he) == HEf_SVKEY) ? \ SvPV(HeKEY_sv(he),lp) : \ (((lp = HeKLEN(he)) >= 0) ? \ - HeKEY(he) : Nullch)) + HeKEY(he) : NULL)) #define HeSVKEY(he) ((HeKEY(he) && \ HeKLEN(he) == HEf_SVKEY) ? \ - HeKEY_sv(he) : Nullsv) + HeKEY_sv(he) : NULL) #define HeSVKEY_force(he) (HeKEY(he) ? \ ((HeKLEN(he) == HEf_SVKEY) ? \ @@ -356,10 +364,20 @@ C. /* Flags for hv_iternext_flags. */ #define HV_ITERNEXT_WANTPLACEHOLDERS 0x01 /* Don't skip placeholders. */ +#define hv_iternext(hv) hv_iternext_flags(hv, 0) +#define hv_magic(hv, gv, how) sv_magic((SV*)(hv), (SV*)(gv), how, NULL, 0) + /* available as a function in hv.c */ #define Perl_sharepvn(sv, len, hash) HEK_KEY(share_hek(sv, len, hash)) #define sharepvn(sv, len, hash) Perl_sharepvn(sv, len, hash) +#define share_hek_hek(hek) \ + (++(((struct shared_he *)(((char *)hek) \ + - STRUCT_OFFSET(struct shared_he, \ + shared_he_hek))) \ + ->shared_he_he.he_valu.hent_refcount), \ + hek) + /* * Local variables: * c-indentation-style: bsd