X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=hv.h;h=f47a77b98b427f02bde2ce8badef1972fbd04c4f;hb=c067b4bea65bd7b97b0ae4f7b058dd94b44a4c48;hp=c99d4790f7d1c03add3fc9703065fd23a0fc87d7;hpb=9b9d0b15bd9c5c0115200324ab9b04803069c7ce;p=p5sagit%2Fp5-mst-13.2.git diff --git a/hv.h b/hv.h index c99d479..f47a77b 100644 --- a/hv.h +++ b/hv.h @@ -8,12 +8,11 @@ * */ -/* 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 */ @@ -29,6 +28,10 @@ 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. @@ -42,43 +45,31 @@ struct xpvhv_aux { /* hash structure: */ /* This structure must match the beginning of struct xpvmg in sv.h. */ struct xpvhv { - IV for_rent; + NV xnv_nv; /* numeric value, if any */ STRLEN xhv_fill; /* how full xhv_array currently is */ STRLEN xhv_max; /* subscript of last element of xhv_array */ union { - struct { - void *xnv_p1; - union { - void *xnv_p2; - IV xnv_i2; /* how many elements in the array */ - } xnv_u2; - } xnv_s; - NV xnvu_nv; /* numeric value, if any */ - } xnv_u; + IV xivu_iv; /* integer value or pv offset */ + UV xivu_uv; + void * xivu_p1; + } xiv_u; MAGIC* xmg_magic; /* magic for scalar array */ HV* xmg_stash; /* class package */ - /* list of pm's for this package is now stored in symtab magic. */ }; -#define xhv_aux xnv_u.xnv_s.xnv_p1 -#define xhv_keys xnv_u.xnv_s.xnv_u2.xnv_i2 +#define xhv_keys xiv_u.xivu_iv -#if !defined(PERL_EXPERIMENTAL_LAYOUT) +#if 0 typedef struct xpvhv xpvhv_allocated; #else typedef struct { STRLEN xhv_fill; /* how full xhv_array currently is */ STRLEN xhv_max; /* subscript of last element of xhv_array */ union { - NV xnvu_nv; /* numeric value, if any */ - struct { - void *xnv_p1; - union { - void *xnv_p2; - IV xnv_i2; /* how many elements in the array */ - } xnv_u2; - } xnv_s; - } xnv_u; + IV xivu_iv; /* integer value or pv offset */ + UV xivu_uv; + void * xivu_p1; + } xiv_u; MAGIC* xmg_magic; /* magic for scalar array */ HV* xmg_stash; /* class package */ } xpvhv_allocated; @@ -91,7 +82,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 @@ -161,7 +152,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 @@ -213,26 +205,27 @@ 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 + responsibility. */ +#define HvAUX(hv) ((struct xpvhv_aux*)&(HvARRAY(hv)[HvMAX(hv)+1])) #define HvRITER(hv) (*Perl_hv_riter_p(aTHX_ (HV*)(hv))) #define HvEITER(hv) (*Perl_hv_eiter_p(aTHX_ (HV*)(hv))) #define HvRITER_set(hv,r) Perl_hv_riter_set(aTHX_ (HV*)(hv), r) #define HvEITER_set(hv,e) Perl_hv_eiter_set(aTHX_ (HV*)(hv), e) -#define HvRITER_get(hv) (((XPVHV *)SvANY(hv))->xhv_aux ? \ - ((struct xpvhv_aux*)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_riter : -1) -#define HvEITER_get(hv) (((XPVHV *)SvANY(hv))->xhv_aux ? \ - ((struct xpvhv_aux *)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_eiter : 0) +#define HvRITER_get(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_riter : -1) +#define HvEITER_get(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_eiter : 0) #define HvNAME(hv) HvNAME_get(hv) /* FIXME - all of these should use a UTF8 aware API, which should also involve getting the length. */ /* This macro may go away without notice. */ -#define HvNAME_HEK(hv) (((XPVHV *)SvANY(hv))->xhv_aux && (((struct xpvhv_aux *)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_name) ? ((struct xpvhv_aux *)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_name: 0) -#define HvNAME_get(hv) (((XPVHV *)SvANY(hv))->xhv_aux ? \ - (((struct xpvhv_aux *)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_name) ? HEK_KEY(((struct xpvhv_aux *)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_name) : 0 : 0) -#define HvNAMELEN_get(hv) (((XPVHV *)SvANY(hv))->xhv_aux ? \ - (((struct xpvhv_aux *)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_name) ? HEK_LEN(((struct xpvhv_aux *)((XPVHV *)SvANY(hv))->xhv_aux)->xhv_name) : 0 : 0) +#define HvNAME_HEK(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_name : 0) +#define HvNAME_get(hv) ((SvOOK(hv) && (HvAUX(hv)->xhv_name)) \ + ? HEK_KEY(HvAUX(hv)->xhv_name) : 0) +#define HvNAMELEN_get(hv) ((SvOOK(hv) && (HvAUX(hv)->xhv_name)) \ + ? HEK_LEN(HvAUX(hv)->xhv_name) : 0) /* the number of keys (including any placeholers) */ #define XHvTOTALKEYS(xhv) ((xhv)->xhv_keys) @@ -371,6 +364,13 @@ 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.hent_val), \ + hek) + /* * Local variables: * c-indentation-style: bsd