X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=hv.h;h=f21307d0f6fbeec0e1576a870e42744e1b63ad58;hb=1515bec64143d124d61662e88e4dc5160e2ea6d7;hp=f91443dddc6cda1f574528cbc2f845f4f4037a4c;hpb=4c2df08ca7dcec8d9dadbf994c085e23d96957a3;p=p5sagit%2Fp5-mst-13.2.git diff --git a/hv.h b/hv.h index f91443d..f21307d 100644 --- a/hv.h +++ b/hv.h @@ -1,7 +1,7 @@ /* hv.h * * Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, - * 2000, 2001, 2002, 2003, 2005, 2006, 2007, by Larry Wall and others + * 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008, 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. @@ -41,10 +41,9 @@ struct shared_he { Use the funcs in mro.c */ -typedef enum { - MRO_DFS, /* 0 */ - MRO_C3 /* 1 */ -} mro_alg; + +/* structure may change, so not public yet */ +struct mro_alg; struct mro_meta { AV *mro_linear_dfs; /* cached dfs @ISA linearization */ @@ -52,7 +51,7 @@ struct mro_meta { HV *mro_nextmethod; /* next::method caching */ U32 cache_gen; /* Bumping this invalidates our method cache */ U32 pkg_gen; /* Bumps when local methods/@ISA change */ - mro_alg mro_which; /* which mro alg is in use? */ + const struct mro_alg *mro_which; /* which mro alg is in use? */ }; /* Subject to change. @@ -67,57 +66,31 @@ struct xpvhv_aux { struct mro_meta *xhv_mro_meta; }; +#define _XPVHV_ALLOCATED_HEAD \ + STRLEN xhv_fill; /* how full xhv_array currently is */ \ + STRLEN xhv_max /* subscript of last element of xhv_array */ + +#define _XPVHV_HEAD \ + union _xnvu xnv_u; \ + _XPVHV_ALLOCATED_HEAD + /* hash structure: */ /* This structure must match the beginning of struct xpvmg in sv.h. */ struct xpvhv { - 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 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; - 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_HEAD; + _XPVMG_HEAD; }; #define xhv_keys xiv_u.xivu_iv typedef struct { - 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; - 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_HEAD; + _XPVMG_HEAD; } xpvhv_allocated; +#undef _XPVHV_ALLOCATED_HEAD +#undef _XPVHV_HEAD + /* hash a key */ /* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins * from requirements by Colin Plumb. @@ -225,7 +198,18 @@ variable C, though this is rather less efficient than using a local variable. Remember though, that hash keys in perl are free to contain embedded nulls, so using C or similar is not a good way to find the length of hash keys. This is very similar to the C macro -described elsewhere in this document. +described elsewhere in this document. See also C. + +If you are using C to get values to pass to C to create a +new SV, you should consider using C as it is more +efficient. + +=for apidoc Am|char*|HeUTF8|HE* he|STRLEN len +Returns whether the C value returned by C is encoded in UTF-8, +doing any necessary dereferencing of possibly C keys. The value returned +will be 0 or non-0, not necessarily 1 (or even a value with any low bits set), +so B blindly assign this to a C variable, as C may be a +typedef for C. =for apidoc Am|SV*|HeSVKEY|HE* he Returns the key as an C, or C if the hash entry does not @@ -332,6 +316,9 @@ C. #define HePV(he,lp) ((HeKLEN(he) == HEf_SVKEY) ? \ SvPV(HeKEY_sv(he),lp) : \ ((lp = HeKLEN(he)), HeKEY(he))) +#define HeUTF8(he) ((HeKLEN(he) == HEf_SVKEY) ? \ + SvUTF8(HeKEY_sv(he)) : \ + (U32)HeKUTF8(he)) #define HeSVKEY(he) ((HeKEY(he) && \ HeKLEN(he) == HEf_SVKEY) ? \ @@ -340,8 +327,8 @@ C. #define HeSVKEY_force(he) (HeKEY(he) ? \ ((HeKLEN(he) == HEf_SVKEY) ? \ HeKEY_sv(he) : \ - sv_2mortal(newSVpvn(HeKEY(he), \ - HeKLEN(he)))) : \ + newSVpvn_flags(HeKEY(he), \ + HeKLEN(he), SVs_TEMP)) : \ &PL_sv_undef) #define HeSVKEY_set(he,sv) ((HeKLEN(he) = HEf_SVKEY), (HeKEY_sv(he) = sv)) @@ -413,18 +400,42 @@ C. hek) #define hv_store_ent(zlonk, awk, touche, zgruppp) \ - hv_common((zlonk), (awk), NULL, 0, 0, HV_FETCH_ISSTORE, (touche), (zgruppp)) + ((HE *) hv_common((zlonk), (awk), NULL, 0, 0, HV_FETCH_ISSTORE, \ + (touche), (zgruppp))) #define hv_exists_ent(zlonk, awk, zgruppp) \ (hv_common((zlonk), (awk), NULL, 0, 0, HV_FETCH_ISEXISTS, 0, (zgruppp))\ ? TRUE : FALSE) #define hv_fetch_ent(zlonk, awk, touche, zgruppp) \ - hv_common((zlonk), (awk), NULL, 0, 0, ((touche) ? HV_FETCH_LVALUE : 0), \ - NULL, (zgruppp)) + ((HE *) hv_common((zlonk), (awk), NULL, 0, 0, \ + ((touche) ? HV_FETCH_LVALUE : 0), NULL, (zgruppp))) #define hv_delete_ent(zlonk, awk, touche, zgruppp) \ ((SV *) hv_common((zlonk), (awk), NULL, 0, 0, (touche) | HV_DELETE, \ NULL, (zgruppp))) +#define hv_store_flags(urkk, zamm, clunk, thwape, sploosh, eee_yow) \ + ((SV**) hv_common((urkk), NULL, (zamm), (clunk), (eee_yow), \ + (HV_FETCH_ISSTORE|HV_FETCH_JUST_SV), (thwape), \ + (sploosh))) + +#define hv_store(urkk, zamm, clunk, thwape, sploosh) \ + ((SV**) hv_common_key_len((urkk), (zamm), (clunk), \ + (HV_FETCH_ISSTORE|HV_FETCH_JUST_SV), \ + (thwape), (sploosh))) + +#define hv_exists(urkk, zamm, clunk) \ + (hv_common_key_len((urkk), (zamm), (clunk), HV_FETCH_ISEXISTS, NULL, 0) \ + ? TRUE : FALSE) + +#define hv_fetch(urkk, zamm, clunk, pam) \ + ((SV**) hv_common_key_len((urkk), (zamm), (clunk), (pam) \ + ? (HV_FETCH_JUST_SV | HV_FETCH_LVALUE) \ + : HV_FETCH_JUST_SV, NULL, 0)) + +#define hv_delete(urkk, zamm, clunk, pam) \ + ((SV*) hv_common_key_len((urkk), (zamm), (clunk), \ + (pam) | HV_DELETE, NULL, 0)) + /* This refcounted he structure is used for storing the hints used for lexical pragmas. Without threads, it's basically struct he + refcount. With threads, life gets more complex as the structure needs to be shared @@ -505,6 +516,16 @@ struct refcounted_he { #define HV_DELETE 0x40 /* +=for apidoc newHV + +Creates a new HV. The reference count is set to 1. + +=cut +*/ + +#define newHV() ((HV*)newSV_type(SVt_PVHV)) + +/* * Local variables: * c-indentation-style: bsd * c-basic-offset: 4