X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/3441fb63c8a89050ee7151eb55228fe165595be1..1bae32dbd424ceb6a38c45cad34e4ad65c83b682:/hv.h diff --git a/hv.h b/hv.h index dee534d..7f96a13 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, 2005, 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. @@ -38,63 +38,59 @@ struct shared_he { /* Subject to change. Don't access this directly. + Use the funcs in mro.c */ + + +/* structure may change, so not public yet */ +struct mro_alg; + +struct mro_meta { + AV *mro_linear_dfs; /* cached dfs @ISA linearization */ + AV *mro_linear_c3; /* cached c3 @ISA linearization */ + HV *mro_nextmethod; /* next::method caching */ + U32 cache_gen; /* Bumping this invalidates our method cache */ + U32 pkg_gen; /* Bumps when local methods/@ISA change */ + const struct mro_alg *mro_which; /* which mro alg is in use? */ + HV *isa; /* Everything this class @ISA */ +}; + +/* 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 */ + 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 */ - } 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 -#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 { - 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; -#endif + +#undef _XPVHV_ALLOCATED_HEAD +#undef _XPVHV_HEAD /* hash a key */ /* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins @@ -170,6 +166,8 @@ is to be expected. (For information only--not to be used). =for apidoc AmU||Nullhv Null HV pointer. +(deprecated - use C<(HV *)NULL> instead) + =head1 Hash Manipulation Functions =for apidoc Am|char*|HvNAME|HV* stash @@ -203,7 +201,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 @@ -224,8 +233,9 @@ C. /* these hash entry flags ride on hent_klen (for use only in magic/tied HVs) */ #define HEf_SVKEY -2 /* hent_key is an SV* */ - -#define Nullhv Null(HV*) +#ifndef PERL_CORE +# define Nullhv Null(HV*) +#endif #define HvARRAY(hv) ((hv)->sv_u.svu_hash) #define HvFILL(hv) ((XPVHV*) SvANY(hv))->xhv_fill #define HvMAX(hv) ((XPVHV*) SvANY(hv))->xhv_max @@ -237,14 +247,21 @@ C. #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) (SvOOK(hv) ? HvAUX(hv)->xhv_riter : -1) -#define HvEITER_get(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_eiter : 0) +#define HvEITER_get(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_eiter : NULL) #define HvNAME(hv) HvNAME_get(hv) + +/* Checking that hv is a valid package stash is the + caller's responsibility */ +#define HvMROMETA(hv) (HvAUX(hv)->xhv_mro_meta \ + ? HvAUX(hv)->xhv_mro_meta \ + : mro_meta_init(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) (SvOOK(hv) ? HvAUX(hv)->xhv_name : 0) +#define HvNAME_HEK(hv) (SvOOK(hv) ? HvAUX(hv)->xhv_name : NULL) #define HvNAME_get(hv) ((SvOOK(hv) && (HvAUX(hv)->xhv_name)) \ - ? HEK_KEY(HvAUX(hv)->xhv_name) : 0) + ? HEK_KEY(HvAUX(hv)->xhv_name) : NULL) #define HvNAMELEN_get(hv) ((SvOOK(hv) && (HvAUX(hv)->xhv_name)) \ ? HEK_LEN(HvAUX(hv)->xhv_name) : 0) @@ -287,7 +304,9 @@ C. #define HvREHASH_on(hv) (SvFLAGS(hv) |= SVphv_REHASH) #define HvREHASH_off(hv) (SvFLAGS(hv) &= ~SVphv_REHASH) -#define Nullhe Null(HE*) +#ifndef PERL_CORE +# define Nullhe Null(HE*) +#endif #define HeNEXT(he) (he)->hent_next #define HeKEY_hek(he) (he)->hent_hek #define HeKEY(he) HEK_KEY(HeKEY_hek(he)) @@ -302,8 +321,10 @@ C. #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) : NULL)) + ((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) ? \ @@ -312,12 +333,14 @@ 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)) -#define Nullhek Null(HEK*) +#ifndef PERL_CORE +# define Nullhek Null(HEK*) +#endif #define HEK_BASESIZE STRUCT_OFFSET(HEK, hek_key[0]) #define HEK_HASH(hek) (hek)->hek_hash #define HEK_LEN(hek) (hek)->hek_len @@ -384,12 +407,51 @@ C. ->shared_he_he.he_valu.hent_refcount), \ hek) +#define hv_store_ent(hv, keysv, val, hash) \ + ((HE *) hv_common((hv), (keysv), NULL, 0, 0, HV_FETCH_ISSTORE, \ + (val), (hash))) + +#define hv_exists_ent(hv, keysv, hash) \ + (hv_common((hv), (keysv), NULL, 0, 0, HV_FETCH_ISEXISTS, 0, (hash)) \ + ? TRUE : FALSE) +#define hv_fetch_ent(hv, keysv, lval, hash) \ + ((HE *) hv_common((hv), (keysv), NULL, 0, 0, \ + ((lval) ? HV_FETCH_LVALUE : 0), NULL, (hash))) +#define hv_delete_ent(hv, key, flags, hash) \ + ((SV *) hv_common((hv), (key), NULL, 0, 0, (flags) | HV_DELETE, \ + NULL, (hash))) + +#define hv_store_flags(hv, key, klen, val, hash, flags) \ + ((SV**) hv_common((hv), NULL, (key), (klen), (flags), \ + (HV_FETCH_ISSTORE|HV_FETCH_JUST_SV), (val), \ + (hash))) + +#define hv_store(hv, key, klen, val, hash) \ + ((SV**) hv_common_key_len((hv), (key), (klen), \ + (HV_FETCH_ISSTORE|HV_FETCH_JUST_SV), \ + (val), (hash))) + +#define hv_exists(hv, key, klen) \ + (hv_common_key_len((hv), (key), (klen), HV_FETCH_ISEXISTS, NULL, 0) \ + ? TRUE : FALSE) + +#define hv_fetch(hv, key, klen, lval) \ + ((SV**) hv_common_key_len((hv), (key), (klen), (lval) \ + ? (HV_FETCH_JUST_SV | HV_FETCH_LVALUE) \ + : HV_FETCH_JUST_SV, NULL, 0)) + +#define hv_delete(hv, key, klen, flags) \ + ((SV*) hv_common_key_len((hv), (key), (klen), \ + (flags) | 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 between threads (because it hangs from OPs, which are shared), hence the alternate definition and mutex. */ +struct refcounted_he; + #ifdef PERL_CORE /* Gosh. This really isn't a good name any longer. */ @@ -401,12 +463,13 @@ struct refcounted_he { #else HEK *refcounted_he_hek; /* hint key */ #endif - U32 refcounted_he_refcnt; /* reference count */ union { IV refcounted_he_u_iv; UV refcounted_he_u_uv; STRLEN refcounted_he_u_len; + void *refcounted_he_u_ptr; /* Might be useful in future */ } refcounted_he_val; + U32 refcounted_he_refcnt; /* reference count */ /* First byte is flags. Then NUL-terminated value. Then for ithreads, non-NUL terminated key. */ char refcounted_he_data[1]; @@ -414,12 +477,22 @@ struct refcounted_he { /* Flag bits are HVhek_UTF8, HVhek_WASUTF8, then */ #define HVrhek_undef 0x00 /* Value is undef. */ -#define HVrhek_PV 0x10 /* Value is a string. */ -#define HVrhek_IV 0x20 /* Value is IV/UV. */ -#define HVrhek_delete 0x30 /* Value is placeholder - signifies delete. */ -#define HVrhek_typemask 0x30 -#define HVrhek_UTF8 0x40 /* string value is utf8. */ -#define HVrhek_UV 0x40 /* integer value is UV. */ +#define HVrhek_delete 0x10 /* Value is placeholder - signifies delete. */ +#define HVrhek_IV 0x20 /* Value is IV. */ +#define HVrhek_UV 0x30 /* Value is UV. */ +#define HVrhek_PV 0x40 /* Value is a (byte) string. */ +#define HVrhek_PV_UTF8 0x50 /* Value is a (utf8) string. */ +/* Two spare. As these have to live in the optree, you can't store anything + interpreter specific, such as SVs. :-( */ +#define HVrhek_typemask 0x70 + +#ifdef USE_ITHREADS +/* A big expression to find the key offset */ +#define REF_HE_KEY(chain) \ + ((((chain->refcounted_he_data[0] & 0x60) == 0x40) \ + ? chain->refcounted_he_val.refcounted_he_u_len + 1 : 0) \ + + 1 + chain->refcounted_he_data) +#endif # ifdef USE_ITHREADS # define HINTS_REFCNT_LOCK MUTEX_LOCK(&PL_hints_mutex) @@ -438,6 +511,28 @@ struct refcounted_he { # define HINTS_REFCNT_TERM NOOP #endif +/* Hash actions + * Passed in PERL_MAGIC_uvar calls + */ +#define HV_DISABLE_UVAR_XKEY 0x01 +/* We need to ensure that these don't clash with G_DISCARD, which is 2, as it + is documented as being passed to hv_delete(). */ +#define HV_FETCH_ISSTORE 0x04 +#define HV_FETCH_ISEXISTS 0x08 +#define HV_FETCH_LVALUE 0x10 +#define HV_FETCH_JUST_SV 0x20 +#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