📄 hv.h
字号:
/* hv.h * * Copyright (C) 1991, 1992, 1993, 1996, 1997, 1998, 1999, * 2000, 2001, 2002, 2003, 2005, 2006, 2007, 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. * *//* 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 */ 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 */struct hek { U32 hek_hash; /* hash of key */ I32 hek_len; /* length of hash key */ char hek_key[1]; /* variable-length hash key */ /* the hash-key is \0-terminated */ /* after the \0 there is a byte for flags, such as whether the key is UTF-8 */};struct shared_he { struct he shared_he_he; struct hek shared_he_hek;};/* 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? */};/* 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;};/* 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 */};#define xhv_keys xiv_u.xivu_ivtypedef 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;/* hash a key *//* FYI: This is the "One-at-a-Time" algorithm by Bob Jenkins * from requirements by Colin Plumb. * (http://burtleburtle.net/bob/hash/doobs.html) *//* 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 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 * to avoid "algorithmic complexity attacks". * * If USE_HASH_SEED is defined, hash randomisation is done by default * If USE_HASH_SEED_EXPLICIT is defined, hash randomisation is done * only if the environment variable PERL_HASH_SEED is set. * For maximal control, one can define PERL_HASH_SEED. * (see also perl.c:perl_parse()). */#ifndef PERL_HASH_SEED# if defined(USE_HASH_SEED) || defined(USE_HASH_SEED_EXPLICIT)# define PERL_HASH_SEED PL_hash_seed# else# define PERL_HASH_SEED 0# endif#endif#define PERL_HASH(hash,str,len) \ STMT_START { \ 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; \ while (i_PeRlHaSh--) { \ hash_PeRlHaSh += *s_PeRlHaSh++; \ hash_PeRlHaSh += (hash_PeRlHaSh << 10); \ hash_PeRlHaSh ^= (hash_PeRlHaSh >> 6); \ } \ hash_PeRlHaSh += (hash_PeRlHaSh << 3); \ hash_PeRlHaSh ^= (hash_PeRlHaSh >> 11); \ (hash) = (hash_PeRlHaSh + (hash_PeRlHaSh << 15)); \ } STMT_END/* Only hv.c and mod_perl should be doing this. */#ifdef PERL_HASH_INTERNAL_ACCESS#define PERL_HASH_INTERNAL(hash,str,len) \ STMT_START { \ 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; \ while (i_PeRlHaSh--) { \ hash_PeRlHaSh += *s_PeRlHaSh++; \ hash_PeRlHaSh += (hash_PeRlHaSh << 10); \ hash_PeRlHaSh ^= (hash_PeRlHaSh >> 6); \ } \ hash_PeRlHaSh += (hash_PeRlHaSh << 3); \ hash_PeRlHaSh ^= (hash_PeRlHaSh >> 11); \ (hash) = (hash_PeRlHaSh + (hash_PeRlHaSh << 15)); \ } STMT_END#endif/*=head1 Hash Manipulation Functions=for apidoc AmU||HEf_SVKEYThis flag, used in the length slot of hash entries and magic structures,specifies the structure contains an C<SV*> pointer where a C<char*> pointeris to be expected. (For information only--not to be used).=head1 Handy Values=for apidoc AmU||NullhvNull HV pointer.=head1 Hash Manipulation Functions=for apidoc Am|char*|HvNAME|HV* stashReturns the package name of a stash, or NULL if C<stash> isn't a stash.See C<SvSTASH>, C<CvSTASH>.=for apidoc Am|void*|HeKEY|HE* heReturns the actual pointer stored in the key slot of the hash entry. Thepointer may be either C<char*> or C<SV*>, depending on the value ofC<HeKLEN()>. Can be assigned to. The C<HePV()> or C<HeSVKEY()> macros areusually preferable for finding the value of a key.=for apidoc Am|STRLEN|HeKLEN|HE* heIf this is negative, and amounts to C<HEf_SVKEY>, it indicates the entryholds an C<SV*> key. Otherwise, holds the actual length of the key. Canbe assigned to. The C<HePV()> macro is usually preferable for finding keylengths.=for apidoc Am|SV*|HeVAL|HE* heReturns the value slot (type C<SV*>) stored in the hash entry.=for apidoc Am|U32|HeHASH|HE* heReturns the computed hash stored in the hash entry.=for apidoc Am|char*|HePV|HE* he|STRLEN lenReturns the key slot of the hash entry as a C<char*> value, doing anynecessary dereferencing of possibly C<SV*> keys. The length of the stringis placed in C<len> (this is a macro, so do I<not> use C<&len>). If you donot care about what the length of the key is, you may use the globalvariable C<PL_na>, though this is rather less efficient than using a localvariable. Remember though, that hash keys in perl are free to containembedded nulls, so using C<strlen()> or similar is not a good way to findthe length of hash keys. This is very similar to the C<SvPV()> macrodescribed elsewhere in this document.=for apidoc Am|SV*|HeSVKEY|HE* heReturns the key as an C<SV*>, or C<NULL> if the hash entry does notcontain an C<SV*> key.=for apidoc Am|SV*|HeSVKEY_force|HE* heReturns the key as an C<SV*>. Will create and return a temporary mortalC<SV*> if the hash entry contains only a C<char*> key.=for apidoc Am|SV*|HeSVKEY_set|HE* he|SV* svSets the key to a given C<SV*>, taking care to set the appropriate flags toindicate the presence of an C<SV*> key, and returns the sameC<SV*>.=cut*//* 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*)#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) (SvOOK(hv) ? HvAUX(hv)->xhv_riter : -1)#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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -