diff options
author | Michael G. Schwern <schwern@pobox.com> | 2020-12-28 18:04:52 -0800 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2021-01-17 09:18:15 -0700 |
commit | 1604cfb0273418ed479719f39def5ee559bffda2 (patch) | |
tree | 166a5ab935a029ab86cf6295d6f3cb77da22e559 /hv.c | |
parent | 557ff1b2a4ecd18fe9229e7e0eb8fa123adc5670 (diff) | |
download | perl-1604cfb0273418ed479719f39def5ee559bffda2.tar.gz |
style: Detabify indentation of the C code maintained by the core.
This just detabifies to get rid of the mixed tab/space indentation.
Applying consistent indentation and dealing with other tabs are another issue.
Done with `expand -i`.
* vutil.* left alone, it's part of version.
* Left regen managed files alone for now.
Diffstat (limited to 'hv.c')
-rw-r--r-- | hv.c | 2602 |
1 files changed, 1301 insertions, 1301 deletions
@@ -57,7 +57,7 @@ S_new_he(pTHX) void ** const root = &PL_body_roots[HE_SVSLOT]; if (!*root) - Perl_more_bodies(aTHX_ HE_SVSLOT, sizeof(HE), PERL_ARENA_SIZE); + Perl_more_bodies(aTHX_ HE_SVSLOT, sizeof(HE), PERL_ARENA_SIZE); he = (HE*) *root; assert(he); *root = HeNEXT(he); @@ -67,8 +67,8 @@ S_new_he(pTHX) #define new_HE() new_he() #define del_HE(p) \ STMT_START { \ - HeNEXT(p) = (HE*)(PL_body_roots[HE_SVSLOT]); \ - PL_body_roots[HE_SVSLOT] = p; \ + HeNEXT(p) = (HE*)(PL_body_roots[HE_SVSLOT]); \ + PL_body_roots[HE_SVSLOT] = p; \ } STMT_END @@ -93,7 +93,7 @@ S_save_hek_flags(const char *str, I32 len, U32 hash, int flags) HEK_FLAGS(hek) = (unsigned char)flags_masked | HVhek_UNSHARED; if (flags & HVhek_FREEKEY) - Safefree(str); + Safefree(str); return hek; } @@ -105,10 +105,10 @@ Perl_free_tied_hv_pool(pTHX) { HE *he = PL_hv_fetch_ent_mh; while (he) { - HE * const ohe = he; - Safefree(HeKEY_hek(he)); - he = HeNEXT(he); - del_HE(ohe); + HE * const ohe = he; + Safefree(HeKEY_hek(he)); + he = HeNEXT(he); + del_HE(ohe); } PL_hv_fetch_ent_mh = NULL; } @@ -123,18 +123,18 @@ Perl_hek_dup(pTHX_ HEK *source, CLONE_PARAMS* param) PERL_UNUSED_ARG(param); if (!source) - return NULL; + return NULL; shared = (HEK*)ptr_table_fetch(PL_ptr_table, source); if (shared) { - /* We already shared this hash key. */ - (void)share_hek_hek(shared); + /* We already shared this hash key. */ + (void)share_hek_hek(shared); } else { - shared - = share_hek_flags(HEK_KEY(source), HEK_LEN(source), - HEK_HASH(source), HEK_FLAGS(source)); - ptr_table_store(PL_ptr_table, source, shared); + shared + = share_hek_flags(HEK_KEY(source), HEK_LEN(source), + HEK_HASH(source), HEK_FLAGS(source)); + ptr_table_store(PL_ptr_table, source, shared); } return shared; } @@ -147,11 +147,11 @@ Perl_he_dup(pTHX_ const HE *e, bool shared, CLONE_PARAMS* param) PERL_ARGS_ASSERT_HE_DUP; if (!e) - return NULL; + return NULL; /* look for it in the table first */ ret = (HE*)ptr_table_fetch(PL_ptr_table, e); if (ret) - return ret; + return ret; /* create anew and remember what it is */ ret = new_HE(); @@ -159,31 +159,31 @@ Perl_he_dup(pTHX_ const HE *e, bool shared, CLONE_PARAMS* param) HeNEXT(ret) = he_dup(HeNEXT(e),shared, param); if (HeKLEN(e) == HEf_SVKEY) { - char *k; - Newx(k, HEK_BASESIZE + sizeof(const SV *), char); - HeKEY_hek(ret) = (HEK*)k; - HeKEY_sv(ret) = sv_dup_inc(HeKEY_sv(e), param); + char *k; + Newx(k, HEK_BASESIZE + sizeof(const SV *), char); + HeKEY_hek(ret) = (HEK*)k; + HeKEY_sv(ret) = sv_dup_inc(HeKEY_sv(e), param); } else if (shared) { - /* This is hek_dup inlined, which seems to be important for speed - reasons. */ - HEK * const source = HeKEY_hek(e); - HEK *shared = (HEK*)ptr_table_fetch(PL_ptr_table, source); - - if (shared) { - /* We already shared this hash key. */ - (void)share_hek_hek(shared); - } - else { - shared - = share_hek_flags(HEK_KEY(source), HEK_LEN(source), - HEK_HASH(source), HEK_FLAGS(source)); - ptr_table_store(PL_ptr_table, source, shared); - } - HeKEY_hek(ret) = shared; + /* This is hek_dup inlined, which seems to be important for speed + reasons. */ + HEK * const source = HeKEY_hek(e); + HEK *shared = (HEK*)ptr_table_fetch(PL_ptr_table, source); + + if (shared) { + /* We already shared this hash key. */ + (void)share_hek_hek(shared); + } + else { + shared + = share_hek_flags(HEK_KEY(source), HEK_LEN(source), + HEK_HASH(source), HEK_FLAGS(source)); + ptr_table_store(PL_ptr_table, source, shared); + } + HeKEY_hek(ret) = shared; } else - HeKEY_hek(ret) = save_hek_flags(HeKEY(e), HeKLEN(e), HeHASH(e), + HeKEY_hek(ret) = save_hek_flags(HeKEY(e), HeKLEN(e), HeHASH(e), HeKFLAGS(e)); HeVAL(ret) = sv_dup_inc(HeVAL(e), param); return ret; @@ -192,22 +192,22 @@ Perl_he_dup(pTHX_ const HE *e, bool shared, CLONE_PARAMS* param) static void S_hv_notallowed(pTHX_ int flags, const char *key, I32 klen, - const char *msg) + const char *msg) { SV * const sv = sv_newmortal(); PERL_ARGS_ASSERT_HV_NOTALLOWED; if (!(flags & HVhek_FREEKEY)) { - sv_setpvn(sv, key, klen); + sv_setpvn(sv, key, klen); } else { - /* Need to free saved eventually assign to mortal SV */ - /* XXX is this line an error ???: SV *sv = sv_newmortal(); */ - sv_usepvn(sv, (char *) key, klen); + /* Need to free saved eventually assign to mortal SV */ + /* XXX is this line an error ???: SV *sv = sv_newmortal(); */ + sv_usepvn(sv, (char *) key, klen); } if (flags & HVhek_UTF8) { - SvUTF8_on(sv); + SvUTF8_on(sv); } Perl_croak(aTHX_ msg, SVfARG(sv)); } @@ -321,7 +321,7 @@ information on how to use this function on tied hashes. /* Common code for hv_delete()/hv_exists()/hv_fetch()/hv_store() */ void * Perl_hv_common_key_len(pTHX_ HV *hv, const char *key, I32 klen_i32, - const int action, SV *val, const U32 hash) + const int action, SV *val, const U32 hash) { STRLEN klen; int flags; @@ -329,18 +329,18 @@ Perl_hv_common_key_len(pTHX_ HV *hv, const char *key, I32 klen_i32, PERL_ARGS_ASSERT_HV_COMMON_KEY_LEN; if (klen_i32 < 0) { - klen = -klen_i32; - flags = HVhek_UTF8; + klen = -klen_i32; + flags = HVhek_UTF8; } else { - klen = klen_i32; - flags = 0; + klen = klen_i32; + flags = 0; } return hv_common(hv, NULL, key, klen, flags, action, val, hash); } void * Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, - int flags, int action, SV *val, U32 hash) + int flags, int action, SV *val, U32 hash) { XPVHV* xhv; HE *entry; @@ -353,276 +353,276 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, HEK *keysv_hek = NULL; if (!hv) - return NULL; + return NULL; if (SvTYPE(hv) == (svtype)SVTYPEMASK) - return NULL; + return NULL; assert(SvTYPE(hv) == SVt_PVHV); if (SvSMAGICAL(hv) && SvGMAGICAL(hv) && !(action & HV_DISABLE_UVAR_XKEY)) { - MAGIC* mg; - if ((mg = mg_find((const SV *)hv, PERL_MAGIC_uvar))) { - struct ufuncs * const uf = (struct ufuncs *)mg->mg_ptr; - if (uf->uf_set == NULL) { - SV* obj = mg->mg_obj; - - if (!keysv) { - keysv = newSVpvn_flags(key, klen, SVs_TEMP | - ((flags & HVhek_UTF8) - ? SVf_UTF8 : 0)); - } - - mg->mg_obj = keysv; /* pass key */ - uf->uf_index = action; /* pass action */ - magic_getuvar(MUTABLE_SV(hv), mg); - keysv = mg->mg_obj; /* may have changed */ - mg->mg_obj = obj; - - /* If the key may have changed, then we need to invalidate - any passed-in computed hash value. */ - hash = 0; - } - } + MAGIC* mg; + if ((mg = mg_find((const SV *)hv, PERL_MAGIC_uvar))) { + struct ufuncs * const uf = (struct ufuncs *)mg->mg_ptr; + if (uf->uf_set == NULL) { + SV* obj = mg->mg_obj; + + if (!keysv) { + keysv = newSVpvn_flags(key, klen, SVs_TEMP | + ((flags & HVhek_UTF8) + ? SVf_UTF8 : 0)); + } + + mg->mg_obj = keysv; /* pass key */ + uf->uf_index = action; /* pass action */ + magic_getuvar(MUTABLE_SV(hv), mg); + keysv = mg->mg_obj; /* may have changed */ + mg->mg_obj = obj; + + /* If the key may have changed, then we need to invalidate + any passed-in computed hash value. */ + hash = 0; + } + } } if (keysv) { - if (flags & HVhek_FREEKEY) - Safefree(key); - key = SvPV_const(keysv, klen); - is_utf8 = (SvUTF8(keysv) != 0); - if (SvIsCOW_shared_hash(keysv)) { - flags = HVhek_KEYCANONICAL | (is_utf8 ? HVhek_UTF8 : 0); - } else { - flags = 0; - } + if (flags & HVhek_FREEKEY) + Safefree(key); + key = SvPV_const(keysv, klen); + is_utf8 = (SvUTF8(keysv) != 0); + if (SvIsCOW_shared_hash(keysv)) { + flags = HVhek_KEYCANONICAL | (is_utf8 ? HVhek_UTF8 : 0); + } else { + flags = 0; + } } else { - is_utf8 = cBOOL(flags & HVhek_UTF8); + is_utf8 = cBOOL(flags & HVhek_UTF8); } if (action & HV_DELETE) { - return (void *) hv_delete_common(hv, keysv, key, klen, - flags | (is_utf8 ? HVhek_UTF8 : 0), - action, hash); + return (void *) hv_delete_common(hv, keysv, key, klen, + flags | (is_utf8 ? HVhek_UTF8 : 0), + action, hash); } xhv = (XPVHV*)SvANY(hv); if (SvMAGICAL(hv)) { - if (SvRMAGICAL(hv) && !(action & (HV_FETCH_ISSTORE|HV_FETCH_ISEXISTS))) { - if (mg_find((const SV *)hv, PERL_MAGIC_tied) - || SvGMAGICAL((const SV *)hv)) - { - /* FIXME should be able to skimp on the HE/HEK here when - HV_FETCH_JUST_SV is true. */ - if (!keysv) { - keysv = newSVpvn_utf8(key, klen, is_utf8); - } else { - keysv = newSVsv(keysv); - } + if (SvRMAGICAL(hv) && !(action & (HV_FETCH_ISSTORE|HV_FETCH_ISEXISTS))) { + if (mg_find((const SV *)hv, PERL_MAGIC_tied) + || SvGMAGICAL((const SV *)hv)) + { + /* FIXME should be able to skimp on the HE/HEK here when + HV_FETCH_JUST_SV is true. */ + if (!keysv) { + keysv = newSVpvn_utf8(key, klen, is_utf8); + } else { + keysv = newSVsv(keysv); + } sv = sv_newmortal(); mg_copy(MUTABLE_SV(hv), sv, (char *)keysv, HEf_SVKEY); - /* grab a fake HE/HEK pair from the pool or make a new one */ - entry = PL_hv_fetch_ent_mh; - if (entry) - PL_hv_fetch_ent_mh = HeNEXT(entry); - else { - char *k; - entry = new_HE(); - Newx(k, HEK_BASESIZE + sizeof(const SV *), char); - HeKEY_hek(entry) = (HEK*)k; - } - HeNEXT(entry) = NULL; - HeSVKEY_set(entry, keysv); - HeVAL(entry) = sv; - sv_upgrade(sv, SVt_PVLV); - LvTYPE(sv) = 'T'; - /* so we can free entry when freeing sv */ - LvTARG(sv) = MUTABLE_SV(entry); - - /* XXX remove at some point? */ - if (flags & HVhek_FREEKEY) - Safefree(key); - - if (return_svp) { - return entry ? (void *) &HeVAL(entry) : NULL; - } - return (void *) entry; - } + /* grab a fake HE/HEK pair from the pool or make a new one */ + entry = PL_hv_fetch_ent_mh; + if (entry) + PL_hv_fetch_ent_mh = HeNEXT(entry); + else { + char *k; + entry = new_HE(); + Newx(k, HEK_BASESIZE + sizeof(const SV *), char); + HeKEY_hek(entry) = (HEK*)k; + } + HeNEXT(entry) = NULL; + HeSVKEY_set(entry, keysv); + HeVAL(entry) = sv; + sv_upgrade(sv, SVt_PVLV); + LvTYPE(sv) = 'T'; + /* so we can free entry when freeing sv */ + LvTARG(sv) = MUTABLE_SV(entry); + + /* XXX remove at some point? */ + if (flags & HVhek_FREEKEY) + Safefree(key); + + if (return_svp) { + return entry ? (void *) &HeVAL(entry) : NULL; + } + return (void *) entry; + } #ifdef ENV_IS_CASELESS - else if (mg_find((const SV *)hv, PERL_MAGIC_env)) { - U32 i; - for (i = 0; i < klen; ++i) - if (isLOWER(key[i])) { - /* Would be nice if we had a routine to do the - copy and upercase in a single pass through. */ - const char * const nkey = strupr(savepvn(key,klen)); - /* Note that this fetch is for nkey (the uppercased - key) whereas the store is for key (the original) */ - void *result = hv_common(hv, NULL, nkey, klen, - HVhek_FREEKEY, /* free nkey */ - 0 /* non-LVAL fetch */ - | HV_DISABLE_UVAR_XKEY - | return_svp, - NULL /* no value */, - 0 /* compute hash */); - if (!result && (action & HV_FETCH_LVALUE)) { - /* This call will free key if necessary. - Do it this way to encourage compiler to tail - call optimise. */ - result = hv_common(hv, keysv, key, klen, flags, - HV_FETCH_ISSTORE - | HV_DISABLE_UVAR_XKEY - | return_svp, - newSV(0), hash); - } else { - if (flags & HVhek_FREEKEY) - Safefree(key); - } - return result; - } - } + else if (mg_find((const SV *)hv, PERL_MAGIC_env)) { + U32 i; + for (i = 0; i < klen; ++i) + if (isLOWER(key[i])) { + /* Would be nice if we had a routine to do the + copy and upercase in a single pass through. */ + const char * const nkey = strupr(savepvn(key,klen)); + /* Note that this fetch is for nkey (the uppercased + key) whereas the store is for key (the original) */ + void *result = hv_common(hv, NULL, nkey, klen, + HVhek_FREEKEY, /* free nkey */ + 0 /* non-LVAL fetch */ + | HV_DISABLE_UVAR_XKEY + | return_svp, + NULL /* no value */, + 0 /* compute hash */); + if (!result && (action & HV_FETCH_LVALUE)) { + /* This call will free key if necessary. + Do it this way to encourage compiler to tail + call optimise. */ + result = hv_common(hv, keysv, key, klen, flags, + HV_FETCH_ISSTORE + | HV_DISABLE_UVAR_XKEY + | return_svp, + newSV(0), hash); + } else { + if (flags & HVhek_FREEKEY) + Safefree(key); + } + return result; + } + } #endif - } /* ISFETCH */ - else if (SvRMAGICAL(hv) && (action & HV_FETCH_ISEXISTS)) { - if (mg_find((const SV *)hv, PERL_MAGIC_tied) - || SvGMAGICAL((const SV *)hv)) { - /* I don't understand why hv_exists_ent has svret and sv, - whereas hv_exists only had one. */ - SV * const svret = sv_newmortal(); - sv = sv_newmortal(); - - if (keysv || is_utf8) { - if (!keysv) { - keysv = newSVpvn_utf8(key, klen, TRUE); - } else { - keysv = newSVsv(keysv); - } - mg_copy(MUTABLE_SV(hv), sv, (char *)sv_2mortal(keysv), HEf_SVKEY); - } else { - mg_copy(MUTABLE_SV(hv), sv, key, klen); - } - if (flags & HVhek_FREEKEY) - Safefree(key); - { + } /* ISFETCH */ + else if (SvRMAGICAL(hv) && (action & HV_FETCH_ISEXISTS)) { + if (mg_find((const SV *)hv, PERL_MAGIC_tied) + || SvGMAGICAL((const SV *)hv)) { + /* I don't understand why hv_exists_ent has svret and sv, + whereas hv_exists only had one. */ + SV * const svret = sv_newmortal(); + sv = sv_newmortal(); + + if (keysv || is_utf8) { + if (!keysv) { + keysv = newSVpvn_utf8(key, klen, TRUE); + } else { + keysv = newSVsv(keysv); + } + mg_copy(MUTABLE_SV(hv), sv, (char *)sv_2mortal(keysv), HEf_SVKEY); + } else { + mg_copy(MUTABLE_SV(hv), sv, key, klen); + } + if (flags & HVhek_FREEKEY) + Safefree(key); + { MAGIC * const mg = mg_find(sv, PERL_MAGIC_tiedelem); if (mg) magic_existspack(svret, mg); - } - /* This cast somewhat evil, but I'm merely using NULL/ - not NULL to return the boolean exists. - And I know hv is not NULL. */ - return SvTRUE_NN(svret) ? (void *)hv : NULL; - } + } + /* This cast somewhat evil, but I'm merely using NULL/ + not NULL to return the boolean exists. + And I know hv is not NULL. */ + return SvTRUE_NN(svret) ? (void *)hv : NULL; + } #ifdef ENV_IS_CASELESS - else if (mg_find((const SV *)hv, PERL_MAGIC_env)) { - /* XXX This code isn't UTF8 clean. */ - char * const keysave = (char * const)key; - /* Will need to free this, so set FREEKEY flag. */ - key = savepvn(key,klen); - key = (const char*)strupr((char*)key); - is_utf8 = FALSE; - hash = 0; - keysv = 0; - - if (flags & HVhek_FREEKEY) { - Safefree(keysave); - } - flags |= HVhek_FREEKEY; - } + else if (mg_find((const SV *)hv, PERL_MAGIC_env)) { + /* XXX This code isn't UTF8 clean. */ + char * const keysave = (char * const)key; + /* Will need to free this, so set FREEKEY flag. */ + key = savepvn(key,klen); + key = (const char*)strupr((char*)key); + is_utf8 = FALSE; + hash = 0; + keysv = 0; + + if (flags & HVhek_FREEKEY) { + Safefree(keysave); + } + flags |= HVhek_FREEKEY; + } #endif - } /* ISEXISTS */ - else if (action & HV_FETCH_ISSTORE) { - bool needs_copy; - bool needs_store; - hv_magic_check (hv, &needs_copy, &needs_store); - if (needs_copy) { - const bool save_taint = TAINT_get; - if (keysv || is_utf8) { - if (!keysv) { - keysv = newSVpvn_utf8(key, klen, TRUE); - } - if (TAINTING_get) - TAINT_set(SvTAINTED(keysv)); - keysv = sv_2mortal(newSVsv(keysv)); - mg_copy(MUTABLE_SV(hv), val, (char*)keysv, HEf_SVKEY); - } else { - mg_copy(MUTABLE_SV(hv), val, key, klen); - } - - TAINT_IF(save_taint); + } /* ISEXISTS */ + else if (action & HV_FETCH_ISSTORE) { + bool needs_copy; + bool needs_store; + hv_magic_check (hv, &needs_copy, &needs_store); + if (needs_copy) { + const bool save_taint = TAINT_get; + if (keysv || is_utf8) { + if (!keysv) { + keysv = newSVpvn_utf8(key, klen, TRUE); + } + if (TAINTING_get) + TAINT_set(SvTAINTED(keysv)); + keysv = sv_2mortal(newSVsv(keysv)); + mg_copy(MUTABLE_SV(hv), val, (char*)keysv, HEf_SVKEY); + } else { + mg_copy(MUTABLE_SV(hv), val, key, klen); + } + + TAINT_IF(save_taint); #ifdef NO_TAINT_SUPPORT PERL_UNUSED_VAR(save_taint); #endif - if (!needs_store) { - if (flags & HVhek_FREEKEY) - Safefree(key); - return NULL; - } + if (!needs_store) { + if (flags & HVhek_FREEKEY) + Safefree(key); + return NULL; + } #ifdef ENV_IS_CASELESS - else if (mg_find((const SV *)hv, PERL_MAGIC_env)) { - /* XXX This code isn't UTF8 clean. */ - const char *keysave = key; - /* Will need to free this, so set FREEKEY flag. */ - key = savepvn(key,klen); - key = (const char*)strupr((char*)key); - is_utf8 = FALSE; - hash = 0; - keysv = 0; - - if (flags & HVhek_FREEKEY) { - Safefree(keysave); - } - flags |= HVhek_FREEKEY; - } + else if (mg_find((const SV *)hv, PERL_MAGIC_env)) { + /* XXX This code isn't UTF8 clean. */ + const char *keysave = key; + /* Will need to free this, so set FREEKEY flag. */ + key = savepvn(key,klen); + key = (const char*)strupr((char*)key); + is_utf8 = FALSE; + hash = 0; + keysv = 0; + + if (flags & HVhek_FREEKEY) { + Safefree(keysave); + } + flags |= HVhek_FREEKEY; + } #endif - } - } /* ISSTORE */ + } + } /* ISSTORE */ } /* SvMAGICAL */ if (!HvARRAY(hv)) { - if ((action & (HV_FETCH_LVALUE | HV_FETCH_ISSTORE)) + if ((action & (HV_FETCH_LVALUE | HV_FETCH_ISSTORE)) #ifdef DYNAMIC_ENV_FETCH /* if it's an %ENV lookup, we may get it on the fly */ - || (SvRMAGICAL((const SV *)hv) - && mg_find((const SV *)hv, PERL_MAGIC_env)) + || (SvRMAGICAL((const SV *)hv) + && mg_find((const SV *)hv, PERL_MAGIC_env)) #endif - ) { - char *array; - Newxz(array, - PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max+1 /* HvMAX(hv)+1 */), - char); - HvARRAY(hv) = (HE**)array; - } + ) { + char *array; + Newxz(array, + PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max+1 /* HvMAX(hv)+1 */), + char); + HvARRAY(hv) = (HE**)array; + } #ifdef DYNAMIC_ENV_FETCH - else if (action & HV_FETCH_ISEXISTS) { - /* for an %ENV exists, if we do an insert it's by a recursive - store call, so avoid creating HvARRAY(hv) right now. */ - } + else if (action & HV_FETCH_ISEXISTS) { + /* for an %ENV exists, if we do an insert it's by a recursive + store call, so avoid creating HvARRAY(hv) right now. */ + } #endif - else { - /* XXX remove at some point? */ + else { + /* XXX remove at some point? */ if (flags & HVhek_FREEKEY) Safefree(key); - return NULL; - } + return NULL; + } } if (is_utf8 && !(flags & HVhek_KEYCANONICAL)) { - char * const keysave = (char *)key; - key = (char*)bytes_from_utf8((U8*)key, &klen, &is_utf8); + char * const keysave = (char *)key; + key = (char*)bytes_from_utf8((U8*)key, &klen, &is_utf8); if (is_utf8) - flags |= HVhek_UTF8; - else - flags &= ~HVhek_UTF8; + flags |= HVhek_UTF8; + else + flags &= ~HVhek_UTF8; if (key != keysave) { - if (flags & HVhek_FREEKEY) - Safefree(keysave); + if (flags & HVhek_FREEKEY) + Safefree(keysave); flags |= HVhek_WASUTF8 | HVhek_FREEKEY; - /* If the caller calculated a hash, it was on the sequence of - octets that are the UTF-8 form. We've now changed the sequence - of octets stored to that of the equivalent byte representation, - so the hash we need is different. */ - hash = 0; - } + /* If the caller calculated a hash, it was on the sequence of + octets that are the UTF-8 form. We've now changed the sequence + of octets stored to that of the equivalent byte representation, + so the hash we need is different. */ + hash = 0; + } } if (keysv && (SvIsCOW_shared_hash(keysv))) { @@ -640,7 +640,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, else #endif { - entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)]; + entry = (HvARRAY(hv))[hash & (I32) HvMAX(hv)]; } if (!entry) @@ -674,146 +674,146 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, } for (; entry; entry = HeNEXT(entry)) { - if (HeHASH(entry) != hash) /* strings can't be equal */ - continue; - if (HeKLEN(entry) != (I32)klen) - continue; - if (memNE(HeKEY(entry),key,klen)) /* is this it? */ - continue; - if ((HeKFLAGS(entry) ^ masked_flags) & HVhek_UTF8) - continue; + if (HeHASH(entry) != hash) /* strings can't be equal */ + continue; + if (HeKLEN(entry) != (I32)klen) + continue; + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ + continue; + if ((HeKFLAGS(entry) ^ masked_flags) & HVhek_UTF8) + continue; found: if (action & (HV_FETCH_LVALUE|HV_FETCH_ISSTORE)) { - if (HeKFLAGS(entry) != masked_flags) { - /* We match if HVhek_UTF8 bit in our flags and hash key's - match. But if entry was set previously with HVhek_WASUTF8 - and key now doesn't (or vice versa) then we should change - the key's flag, as this is assignment. */ - if (HvSHAREKEYS(hv)) { - /* Need to swap the key we have for a key with the flags we - need. As keys are shared we can't just write to the - flag, so we share the new one, unshare the old one. */ - HEK * const new_hek = share_hek_flags(key, klen, hash, - masked_flags); - unshare_hek (HeKEY_hek(entry)); - HeKEY_hek(entry) = new_hek; - } - else if (hv == PL_strtab) { - /* PL_strtab is usually the only hash without HvSHAREKEYS, - so putting this test here is cheap */ - if (flags & HVhek_FREEKEY) - Safefree(key); - Perl_croak(aTHX_ S_strtab_error, - action & HV_FETCH_LVALUE ? "fetch" : "store"); - } - else - HeKFLAGS(entry) = masked_flags; - if (masked_flags & HVhek_ENABLEHVKFLAGS) - HvHASKFLAGS_on(hv); - } - if (HeVAL(entry) == &PL_sv_placeholder) { - /* yes, can store into placeholder slot */ - if (action & HV_FETCH_LVALUE) { - if (SvMAGICAL(hv)) { - /* This preserves behaviour with the old hv_fetch - implementation which at this point would bail out - with a break; (at "if we find a placeholder, we - pretend we haven't found anything") - - That break mean that if a placeholder were found, it - caused a call into hv_store, which in turn would - check magic, and if there is no magic end up pretty - much back at this point (in hv_store's code). */ - break; - } - /* LVAL fetch which actually needs a store. */ - val = newSV(0); - HvPLACEHOLDERS(hv)--; - } else { - /* store */ - if (val != &PL_sv_placeholder) - HvPLACEHOLDERS(hv)--; - } - HeVAL(entry) = val; - } else if (action & HV_FETCH_ISSTORE) { - SvREFCNT_dec(HeVAL(entry)); - HeVAL(entry) = val; - } - } else if (HeVAL(entry) == &PL_sv_placeholder) { - /* if we find a placeholder, we pretend we haven't found - anything */ - break; - } - if (flags & HVhek_FREEKEY) - Safefree(key); - if (return_svp) { + if (HeKFLAGS(entry) != masked_flags) { + /* We match if HVhek_UTF8 bit in our flags and hash key's + match. But if entry was set previously with HVhek_WASUTF8 + and key now doesn't (or vice versa) then we should change + the key's flag, as this is assignment. */ + if (HvSHAREKEYS(hv)) { + /* Need to swap the key we have for a key with the flags we + need. As keys are shared we can't just write to the + flag, so we share the new one, unshare the old one. */ + HEK * const new_hek = share_hek_flags(key, klen, hash, + masked_flags); + unshare_hek (HeKEY_hek(entry)); + HeKEY_hek(entry) = new_hek; + } + else if (hv == PL_strtab) { + /* PL_strtab is usually the only hash without HvSHAREKEYS, + so putting this test here is cheap */ + if (flags & HVhek_FREEKEY) + Safefree(key); + Perl_croak(aTHX_ S_strtab_error, + action & HV_FETCH_LVALUE ? "fetch" : "store"); + } + else + HeKFLAGS(entry) = masked_flags; + if (masked_flags & HVhek_ENABLEHVKFLAGS) + HvHASKFLAGS_on(hv); + } + if (HeVAL(entry) == &PL_sv_placeholder) { + /* yes, can store into placeholder slot */ + if (action & HV_FETCH_LVALUE) { + if (SvMAGICAL(hv)) { + /* This preserves behaviour with the old hv_fetch + implementation which at this point would bail out + with a break; (at "if we find a placeholder, we + pretend we haven't found anything") + + That break mean that if a placeholder were found, it + caused a call into hv_store, which in turn would + check magic, and if there is no magic end up pretty + much back at this point (in hv_store's code). */ + break; + } + /* LVAL fetch which actually needs a store. */ + val = newSV(0); + HvPLACEHOLDERS(hv)--; + } else { + /* store */ + if (val != &PL_sv_placeholder) + HvPLACEHOLDERS(hv)--; + } + HeVAL(entry) = val; + } else if (action & HV_FETCH_ISSTORE) { + SvREFCNT_dec(HeVAL(entry)); + HeVAL(entry) = val; + } + } else if (HeVAL(entry) == &PL_sv_placeholder) { + /* if we find a placeholder, we pretend we haven't found + anything */ + break; + } + if (flags & HVhek_FREEKEY) + Safefree(key); + if (return_svp) { return (void *) &HeVAL(entry); - } - return entry; + } + return entry; } not_found: #ifdef DYNAMIC_ENV_FETCH /* %ENV lookup? If so, try to fetch the value now */ if (!(action & HV_FETCH_ISSTORE) - && SvRMAGICAL((const SV *)hv) - && mg_find((const SV *)hv, PERL_MAGIC_env)) { - unsigned long len; - const char * const env = PerlEnv_ENVgetenv_len(key,&len); - if (env) { - sv = newSVpvn(env,len); - SvTAINTED_on(sv); - return hv_common(hv, keysv, key, klen, flags, - HV_FETCH_ISSTORE|HV_DISABLE_UVAR_XKEY|return_svp, - sv, hash); - } + && SvRMAGICAL((const SV *)hv) + && mg_find((const SV *)hv, PERL_MAGIC_env)) { + unsigned long len; + const char * const env = PerlEnv_ENVgetenv_len(key,&len); + if (env) { + sv = newSVpvn(env,len); + SvTAINTED_on(sv); + return hv_common(hv, keysv, key, klen, flags, + HV_FETCH_ISSTORE|HV_DISABLE_UVAR_XKEY|return_svp, + sv, hash); + } } #endif if (!entry && SvREADONLY(hv) && !(action & HV_FETCH_ISEXISTS)) { - hv_notallowed(flags, key, klen, - "Attempt to access disallowed key '%" SVf "' in" - " a restricted hash"); + hv_notallowed(flags, key, klen, + "Attempt to access disallowed key '%" SVf "' in" + " a restricted hash"); } if (!(action & (HV_FETCH_LVALUE|HV_FETCH_ISSTORE))) { - /* Not doing some form of store, so return failure. */ - if (flags & HVhek_FREEKEY) - Safefree(key); - return NULL; + /* Not doing some form of store, so return failure. */ + if (flags & HVhek_FREEKEY) + Safefree(key); + return NULL; } if (action & HV_FETCH_LVALUE) { - val = action & HV_FETCH_EMPTY_HE ? NULL : newSV(0); - if (SvMAGICAL(hv)) { - /* At this point the old hv_fetch code would call to hv_store, - which in turn might do some tied magic. So we need to make that - magic check happen. */ - /* gonna assign to this, so it better be there */ - /* If a fetch-as-store fails on the fetch, then the action is to - recurse once into "hv_store". If we didn't do this, then that - recursive call would call the key conversion routine again. - However, as we replace the original key with the converted - key, this would result in a double conversion, which would show - up as a bug if the conversion routine is not idempotent. - Hence the use of HV_DISABLE_UVAR_XKEY. */ - return hv_common(hv, keysv, key, klen, flags, - HV_FETCH_ISSTORE|HV_DISABLE_UVAR_XKEY|return_svp, - val, hash); - /* XXX Surely that could leak if the fetch-was-store fails? - Just like the hv_fetch. */ - } + val = action & HV_FETCH_EMPTY_HE ? NULL : newSV(0); + if (SvMAGICAL(hv)) { + /* At this point the old hv_fetch code would call to hv_store, + which in turn might do some tied magic. So we need to make that + magic check happen. */ + /* gonna assign to this, so it better be there */ + /* If a fetch-as-store fails on the fetch, then the action is to + recurse once into "hv_store". If we didn't do this, then that + recursive call would call the key conversion routine again. + However, as we replace the original key with the converted + key, this would result in a double conversion, which would show + up as a bug if the conversion routine is not idempotent. + Hence the use of HV_DISABLE_UVAR_XKEY. */ + return hv_common(hv, keysv, key, klen, flags, + HV_FETCH_ISSTORE|HV_DISABLE_UVAR_XKEY|return_svp, + val, hash); + /* XXX Surely that could leak if the fetch-was-store fails? + Just like the hv_fetch. */ + } } /* Welcome to hv_store... */ if (!HvARRAY(hv)) { - /* Not sure if we can get here. I think the only case of oentry being - NULL is for %ENV with dynamic env fetch. But that should disappear - with magic in the previous code. */ - char *array; - Newxz(array, - PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max+1 /* HvMAX(hv)+1 */), - char); - HvARRAY(hv) = (HE**)array; + /* Not sure if we can get here. I think the only case of oentry being + NULL is for %ENV with dynamic env fetch. But that should disappear + with magic in the previous code. */ + char *array; + Newxz(array, + PERL_HV_ARRAY_ALLOC_BYTES(xhv->xhv_max+1 /* HvMAX(hv)+1 */), + char); + HvARRAY(hv) = (HE**)array; } oentry = &(HvARRAY(hv))[hash & (I32) xhv->xhv_max]; @@ -822,17 +822,17 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, /* share_hek_flags will do the free for us. This might be considered bad API design. */ if (HvSHAREKEYS(hv)) - HeKEY_hek(entry) = share_hek_flags(key, klen, hash, flags); + HeKEY_hek(entry) = share_hek_flags(key, klen, hash, flags); else if (hv == PL_strtab) { - /* PL_strtab is usually the only hash without HvSHAREKEYS, so putting - this test here is cheap */ - if (flags & HVhek_FREEKEY) - Safefree(key); - Perl_croak(aTHX_ S_strtab_error, - action & HV_FETCH_LVALUE ? "fetch" : "store"); + /* PL_strtab is usually the only hash without HvSHAREKEYS, so putting + this test here is cheap */ + if (flags & HVhek_FREEKEY) + Safefree(key); + Perl_croak(aTHX_ S_strtab_error, + action & HV_FETCH_LVALUE ? "fetch" : "store"); } else /* gotta do the real thing */ - HeKEY_hek(entry) = save_hek_flags(key, klen, hash, flags); + HeKEY_hek(entry) = save_hek_flags(key, klen, hash, flags); HeVAL(entry) = val; #ifdef PERL_HASH_RANDOMIZE_KEYS @@ -879,9 +879,9 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, #endif if (val == &PL_sv_placeholder) - HvPLACEHOLDERS(hv)++; + HvPLACEHOLDERS(hv)++; if (masked_flags & HVhek_ENABLEHVKFLAGS) - HvHASKFLAGS_on(hv); + HvHASKFLAGS_on(hv); xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */ if ( in_collision && DO_HSPLIT(xhv) ) { @@ -908,7 +908,7 @@ Perl_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, } if (return_svp) { - return entry ? (void *) &HeVAL(entry) : NULL; + return entry ? (void *) &HeVAL(entry) : NULL; } return (void *) entry; } @@ -923,14 +923,14 @@ S_hv_magic_check(HV *hv, bool *needs_copy, bool *needs_store) *needs_copy = FALSE; *needs_store = TRUE; while (mg) { - if (isUPPER(mg->mg_type)) { - *needs_copy = TRUE; - if (mg->mg_type == PERL_MAGIC_tied) { - *needs_store = FALSE; - return; /* We've set all there is to set. */ - } - } - mg = mg->mg_moremagic; + if (isUPPER(mg->mg_type)) { + *needs_copy = TRUE; + if (mg->mg_type == PERL_MAGIC_tied) { + *needs_store = FALSE; + return; /* We've set all there is to set. */ + } + } + mg = mg->mg_moremagic; } } @@ -957,9 +957,9 @@ Perl_hv_scalar(pTHX_ HV *hv) PERL_ARGS_ASSERT_HV_SCALAR; if (SvRMAGICAL(hv)) { - MAGIC * const mg = mg_find((const SV *)hv, PERL_MAGIC_tied); - if (mg) - return magic_scalarpack(hv, mg); + MAGIC * const mg = mg_find((const SV *)hv, PERL_MAGIC_tied); + if (mg) + return magic_scalarpack(hv, mg); } sv = sv_newmortal(); @@ -1103,7 +1103,7 @@ value, or 0 to ask for it to be computed. STATIC SV * S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, - int k_flags, I32 d_flags, U32 hash) + int k_flags, I32 d_flags, U32 hash) { XPVHV* xhv; HE *entry; @@ -1118,65 +1118,65 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, HV *stash = NULL; if (SvRMAGICAL(hv)) { - bool needs_copy; - bool needs_store; - hv_magic_check (hv, &needs_copy, &needs_store); - - if (needs_copy) { - SV *sv; - entry = (HE *) hv_common(hv, keysv, key, klen, - k_flags & ~HVhek_FREEKEY, - HV_FETCH_LVALUE|HV_DISABLE_UVAR_XKEY, - NULL, hash); - sv = entry ? HeVAL(entry) : NULL; - if (sv) { - if (SvMAGICAL(sv)) { - mg_clear(sv); - } - if (!needs_store) { - if (mg_find(sv, PERL_MAGIC_tiedelem)) { - /* No longer an element */ - sv_unmagic(sv, PERL_MAGIC_tiedelem); - return sv; - } - return NULL; /* element cannot be deleted */ - } + bool needs_copy; + bool needs_store; + hv_magic_check (hv, &needs_copy, &needs_store); + + if (needs_copy) { + SV *sv; + entry = (HE *) hv_common(hv, keysv, key, klen, + k_flags & ~HVhek_FREEKEY, + HV_FETCH_LVALUE|HV_DISABLE_UVAR_XKEY, + NULL, hash); + sv = entry ? HeVAL(entry) : NULL; + if (sv) { + if (SvMAGICAL(sv)) { + mg_clear(sv); + } + if (!needs_store) { + if (mg_find(sv, PERL_MAGIC_tiedelem)) { + /* No longer an element */ + sv_unmagic(sv, PERL_MAGIC_tiedelem); + return sv; + } + return NULL; /* element cannot be deleted */ + } #ifdef ENV_IS_CASELESS - else if (mg_find((const SV *)hv, PERL_MAGIC_env)) { - /* XXX This code isn't UTF8 clean. */ - keysv = newSVpvn_flags(key, klen, SVs_TEMP); - if (k_flags & HVhek_FREEKEY) { - Safefree(key); - } - key = strupr(SvPVX(keysv)); - is_utf8 = 0; - k_flags = 0; - hash = 0; - } + else if (mg_find((const SV *)hv, PERL_MAGIC_env)) { + /* XXX This code isn't UTF8 clean. */ + keysv = newSVpvn_flags(key, klen, SVs_TEMP); + if (k_flags & HVhek_FREEKEY) { + Safefree(key); + } + key = strupr(SvPVX(keysv)); + is_utf8 = 0; + k_flags = 0; + hash = 0; + } #endif - } - } + } + } } xhv = (XPVHV*)SvANY(hv); if (!HvARRAY(hv)) - return NULL; + return NULL; if (is_utf8 && !(k_flags & HVhek_KEYCANONICAL)) { - const char * const keysave = key; - key = (char*)bytes_from_utf8((U8*)key, &klen, &is_utf8); + const char * const keysave = key; + key = (char*)bytes_from_utf8((U8*)key, &klen, &is_utf8); if (is_utf8) k_flags |= HVhek_UTF8; - else + else k_flags &= ~HVhek_UTF8; if (key != keysave) { - if (k_flags & HVhek_FREEKEY) { - /* This shouldn't happen if our caller does what we expect, - but strictly the API allows it. */ - Safefree(keysave); - } - k_flags |= HVhek_WASUTF8 | HVhek_FREEKEY; - } + if (k_flags & HVhek_FREEKEY) { + /* This shouldn't happen if our caller does what we expect, + but strictly the API allows it. */ + Safefree(keysave); + } + k_flags |= HVhek_WASUTF8 | HVhek_FREEKEY; + } HvHASKFLAGS_on(MUTABLE_SV(hv)); } @@ -1224,66 +1224,66 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, } for (; entry; oentry = &HeNEXT(entry), entry = *oentry) { - if (HeHASH(entry) != hash) /* strings can't be equal */ - continue; - if (HeKLEN(entry) != (I32)klen) - continue; - if (memNE(HeKEY(entry),key,klen)) /* is this it? */ - continue; - if ((HeKFLAGS(entry) ^ masked_flags) & HVhek_UTF8) - continue; + if (HeHASH(entry) != hash) /* strings can't be equal */ + continue; + if (HeKLEN(entry) != (I32)klen) + continue; + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ + continue; + if ((HeKFLAGS(entry) ^ masked_flags) & HVhek_UTF8) + continue; found: - if (hv == PL_strtab) { - if (k_flags & HVhek_FREEKEY) - Safefree(key); - Perl_croak(aTHX_ S_strtab_error, "delete"); - } - - /* if placeholder is here, it's already been deleted.... */ - if (HeVAL(entry) == &PL_sv_placeholder) { - if (k_flags & HVhek_FREEKEY) - Safefree(key); - return NULL; - } - if (SvREADONLY(hv) && HeVAL(entry) && SvREADONLY(HeVAL(entry))) { - hv_notallowed(k_flags, key, klen, - "Attempt to delete readonly key '%" SVf "' from" - " a restricted hash"); - } + if (hv == PL_strtab) { + if (k_flags & HVhek_FREEKEY) + Safefree(key); + Perl_croak(aTHX_ S_strtab_error, "delete"); + } + + /* if placeholder is here, it's already been deleted.... */ + if (HeVAL(entry) == &PL_sv_placeholder) { + if (k_flags & HVhek_FREEKEY) + Safefree(key); + return NULL; + } + if (SvREADONLY(hv) && HeVAL(entry) && SvREADONLY(HeVAL(entry))) { + hv_notallowed(k_flags, key, klen, + "Attempt to delete readonly key '%" SVf "' from" + " a restricted hash"); + } if (k_flags & HVhek_FREEKEY) Safefree(key); - /* If this is a stash and the key ends with ::, then someone is - * deleting a package. - */ - if (HeVAL(entry) && HvENAME_get(hv)) { - gv = (GV *)HeVAL(entry); - if (keysv) key = SvPV(keysv, klen); - if (( - (klen > 1 && key[klen-2] == ':' && key[klen-1] == ':') - || - (klen == 1 && key[0] == ':') - ) - && (klen != 6 || hv!=PL_defstash || memNE(key,"main::",6)) - && SvTYPE(gv) == SVt_PVGV && (stash = GvHV((GV *)gv)) - && HvENAME_get(stash)) { - /* A previous version of this code checked that the - * GV was still in the symbol table by fetching the - * GV with its name. That is not necessary (and - * sometimes incorrect), as HvENAME cannot be set - * on hv if it is not in the symtab. */ - mro_changes = 2; - /* Hang on to it for a bit. */ - SvREFCNT_inc_simple_void_NN( - sv_2mortal((SV *)gv) - ); - } - else if (memEQs(key, klen, "ISA") && GvAV(gv)) { + /* If this is a stash and the key ends with ::, then someone is + * deleting a package. + */ + if (HeVAL(entry) && HvENAME_get(hv)) { + gv = (GV *)HeVAL(entry); + if (keysv) key = SvPV(keysv, klen); + if (( + (klen > 1 && key[klen-2] == ':' && key[klen-1] == ':') + || + (klen == 1 && key[0] == ':') + ) + && (klen != 6 || hv!=PL_defstash || memNE(key,"main::",6)) + && SvTYPE(gv) == SVt_PVGV && (stash = GvHV((GV *)gv)) + && HvENAME_get(stash)) { + /* A previous version of this code checked that the + * GV was still in the symbol table by fetching the + * GV with its name. That is not necessary (and + * sometimes incorrect), as HvENAME cannot be set + * on hv if it is not in the symtab. */ + mro_changes = 2; + /* Hang on to it for a bit. */ + SvREFCNT_inc_simple_void_NN( + sv_2mortal((SV *)gv) + ); + } + else if (memEQs(key, klen, "ISA") && GvAV(gv)) { AV *isa = GvAV(gv); MAGIC *mg = mg_find((SV*)isa, PERL_MAGIC_isa); - mro_changes = 1; + mro_changes = 1; if (mg) { if (mg->mg_obj == (SV*)gv) { /* This is the only stash this ISA was used for. @@ -1346,63 +1346,63 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen, } } } - } - - sv = d_flags & G_DISCARD ? HeVAL(entry) : sv_2mortal(HeVAL(entry)); - HeVAL(entry) = &PL_sv_placeholder; - if (sv) { - /* deletion of method from stash */ - if (isGV(sv) && isGV_with_GP(sv) && GvCVu(sv) - && HvENAME_get(hv)) - mro_method_changed_in(hv); - } - - /* - * If a restricted hash, rather than really deleting the entry, put - * a placeholder there. This marks the key as being "approved", so - * we can still access via not-really-existing key without raising - * an error. - */ - if (SvREADONLY(hv)) - /* We'll be saving this slot, so the number of allocated keys - * doesn't go down, but the number placeholders goes up */ - HvPLACEHOLDERS(hv)++; - else { - *oentry = HeNEXT(entry); - if (SvOOK(hv) && entry == HvAUX(hv)->xhv_eiter /* HvEITER(hv) */) - HvLAZYDEL_on(hv); - else { - if (SvOOK(hv) && HvLAZYDEL(hv) && - entry == HeNEXT(HvAUX(hv)->xhv_eiter)) - HeNEXT(HvAUX(hv)->xhv_eiter) = HeNEXT(entry); - hv_free_ent(hv, entry); - } - xhv->xhv_keys--; /* HvTOTALKEYS(hv)-- */ - if (xhv->xhv_keys == 0) - HvHASKFLAGS_off(hv); - } - - if (d_flags & G_DISCARD) { - SvREFCNT_dec(sv); - sv = NULL; - } - - if (mro_changes == 1) mro_isa_changed_in(hv); - else if (mro_changes == 2) - mro_package_moved(NULL, stash, gv, 1); - - return sv; + } + + sv = d_flags & G_DISCARD ? HeVAL(entry) : sv_2mortal(HeVAL(entry)); + HeVAL(entry) = &PL_sv_placeholder; + if (sv) { + /* deletion of method from stash */ + if (isGV(sv) && isGV_with_GP(sv) && GvCVu(sv) + && HvENAME_get(hv)) + mro_method_changed_in(hv); + } + + /* + * If a restricted hash, rather than really deleting the entry, put + * a placeholder there. This marks the key as being "approved", so + * we can still access via not-really-existing key without raising + * an error. + */ + if (SvREADONLY(hv)) + /* We'll be saving this slot, so the number of allocated keys + * doesn't go down, but the number placeholders goes up */ + HvPLACEHOLDERS(hv)++; + else { + *oentry = HeNEXT(entry); + if (SvOOK(hv) && entry == HvAUX(hv)->xhv_eiter /* HvEITER(hv) */) + HvLAZYDEL_on(hv); + else { + if (SvOOK(hv) && HvLAZYDEL(hv) && + entry == HeNEXT(HvAUX(hv)->xhv_eiter)) + HeNEXT(HvAUX(hv)->xhv_eiter) = HeNEXT(entry); + hv_free_ent(hv, entry); + } + xhv->xhv_keys--; /* HvTOTALKEYS(hv)-- */ + if (xhv->xhv_keys == 0) + HvHASKFLAGS_off(hv); + } + + if (d_flags & G_DISCARD) { + SvREFCNT_dec(sv); + sv = NULL; + } + + if (mro_changes == 1) mro_isa_changed_in(hv); + else if (mro_changes == 2) + mro_package_moved(NULL, stash, gv, 1); + + return sv; } not_found: if (SvREADONLY(hv)) { - hv_notallowed(k_flags, key, klen, - "Attempt to delete disallowed key '%" SVf "' from" - " a restricted hash"); + hv_notallowed(k_flags, key, klen, + "Attempt to delete disallowed key '%" SVf "' from" + " a restricted hash"); } if (k_flags & HVhek_FREEKEY) - Safefree(key); + Safefree(key); return NULL; } @@ -1483,15 +1483,15 @@ S_hsplit(pTHX_ HV *hv, STRLEN const oldsize, STRLEN newsize) newsize--; aep = (HE**)a; do { - HE **oentry = aep + i; - HE *entry = aep[i]; + HE **oentry = aep + i; + HE *entry = aep[i]; - if (!entry) /* non-existent */ - continue; - do { + if (!entry) /* non-existent */ + continue; + do { U32 j = (HeHASH(entry) & newsize); - if (j != (U32)i) { - *oentry = HeNEXT(entry); + if (j != (U32)i) { + *oentry = HeNEXT(entry); #ifdef PERL_HASH_RANDOMIZE_KEYS /* if the target cell is empty or PL_HASH_RAND_BITS_ENABLED is false * insert to top, otherwise rotate the bucket rand 1 bit, @@ -1517,12 +1517,12 @@ S_hsplit(pTHX_ HV *hv, STRLEN const oldsize, STRLEN newsize) HeNEXT(entry) = aep[j]; aep[j] = entry; } - } - else { - oentry = &HeNEXT(entry); - } - entry = *oentry; - } while (entry); + } + else { + oentry = &HeNEXT(entry); + } + entry = *oentry; + } while (entry); } while (i++ < oldsize); } @@ -1540,7 +1540,7 @@ Perl_hv_ksplit(pTHX_ HV *hv, IV newmax) wantsize = (I32) newmax; /* possible truncation here */ if (wantsize != newmax) - return; + return; wantsize= wantsize + (wantsize >> 1); /* wantsize *= 1.5 */ if (wantsize < newmax) /* overflow detection */ @@ -1592,76 +1592,76 @@ Perl_newHVhv(pTHX_ HV *ohv) STRLEN hv_max; if (!ohv || (!HvTOTALKEYS(ohv) && !SvMAGICAL((const SV *)ohv))) - return hv; + return hv; hv_max = HvMAX(ohv); if (!SvMAGICAL((const SV *)ohv)) { - /* It's an ordinary hash, so copy it fast. AMS 20010804 */ - STRLEN i; - const bool shared = !!HvSHAREKEYS(ohv); - HE **ents, ** const oents = (HE **)HvARRAY(ohv); - char *a; - Newx(a, PERL_HV_ARRAY_ALLOC_BYTES(hv_max+1), char); - ents = (HE**)a; - - /* In each bucket... */ - for (i = 0; i <= hv_max; i++) { - HE *prev = NULL; - HE *oent = oents[i]; - - if (!oent) { - ents[i] = NULL; - continue; - } - - /* Copy the linked list of entries. */ - for (; oent; oent = HeNEXT(oent)) { - const U32 hash = HeHASH(oent); - const char * const key = HeKEY(oent); - const STRLEN len = HeKLEN(oent); - const int flags = HeKFLAGS(oent); - HE * const ent = new_HE(); - SV *const val = HeVAL(oent); - - HeVAL(ent) = SvIMMORTAL(val) ? val : newSVsv(val); - HeKEY_hek(ent) + /* It's an ordinary hash, so copy it fast. AMS 20010804 */ + STRLEN i; + const bool shared = !!HvSHAREKEYS(ohv); + HE **ents, ** const oents = (HE **)HvARRAY(ohv); + char *a; + Newx(a, PERL_HV_ARRAY_ALLOC_BYTES(hv_max+1), char); + ents = (HE**)a; + + /* In each bucket... */ + for (i = 0; i <= hv_max; i++) { + HE *prev = NULL; + HE *oent = oents[i]; + + if (!oent) { + ents[i] = NULL; + continue; + } + + /* Copy the linked list of entries. */ + for (; oent; oent = HeNEXT(oent)) { + const U32 hash = HeHASH(oent); + const char * const key = HeKEY(oent); + const STRLEN len = HeKLEN(oent); + const int flags = HeKFLAGS(oent); + HE * const ent = new_HE(); + SV *const val = HeVAL(oent); + + HeVAL(ent) = SvIMMORTAL(val) ? val : newSVsv(val); + HeKEY_hek(ent) = shared ? share_hek_flags(key, len, hash, flags) : save_hek_flags(key, len, hash, flags); - if (prev) - HeNEXT(prev) = ent; - else - ents[i] = ent; - prev = ent; - HeNEXT(ent) = NULL; - } - } - - HvMAX(hv) = hv_max; - HvTOTALKEYS(hv) = HvTOTALKEYS(ohv); - HvARRAY(hv) = ents; + if (prev) + HeNEXT(prev) = ent; + else + ents[i] = ent; + prev = ent; + HeNEXT(ent) = NULL; + } + } + + HvMAX(hv) = hv_max; + HvTOTALKEYS(hv) = HvTOTALKEYS(ohv); + HvARRAY(hv) = ents; } /* not magical */ else { - /* Iterate over ohv, copying keys and values one at a time. */ - HE *entry; - const I32 riter = HvRITER_get(ohv); - HE * const eiter = HvEITER_get(ohv); + /* Iterate over ohv, copying keys and values one at a time. */ + HE *entry; + const I32 riter = HvRITER_get(ohv); + HE * const eiter = HvEITER_get(ohv); STRLEN hv_keys = HvTOTALKEYS(ohv); HV_SET_MAX_ADJUSTED_FOR_KEYS(hv,hv_max,hv_keys); - hv_iterinit(ohv); - while ((entry = hv_iternext_flags(ohv, 0))) { - SV *val = hv_iterval(ohv,entry); - SV * const keysv = HeSVKEY(entry); - val = SvIMMORTAL(val) ? val : newSVsv(val); - if (keysv) - (void)hv_store_ent(hv, keysv, val, 0); - else - (void)hv_store_flags(hv, HeKEY(entry), HeKLEN(entry), val, - HeHASH(entry), HeKFLAGS(entry)); - } - HvRITER_set(ohv, riter); - HvEITER_set(ohv, eiter); + hv_iterinit(ohv); + while ((entry = hv_iternext_flags(ohv, 0))) { + SV *val = hv_iterval(ohv,entry); + SV * const keysv = HeSVKEY(entry); + val = SvIMMORTAL(val) ? val : newSVsv(val); + if (keysv) + (void)hv_store_ent(hv, keysv, val, 0); + else + (void)hv_store_flags(hv, HeKEY(entry), HeKLEN(entry), val, + HeHASH(entry), HeKFLAGS(entry)); + } + HvRITER_set(ohv, riter); + HvEITER_set(ohv, eiter); } return hv; @@ -1685,37 +1685,37 @@ Perl_hv_copy_hints_hv(pTHX_ HV *const ohv) HV * const hv = newHV(); if (ohv) { - STRLEN hv_max = HvMAX(ohv); + STRLEN hv_max = HvMAX(ohv); STRLEN hv_keys = HvTOTALKEYS(ohv); - HE *entry; - const I32 riter = HvRITER_get(ohv); - HE * const eiter = HvEITER_get(ohv); + HE *entry; + const I32 riter = HvRITER_get(ohv); + HE * const eiter = HvEITER_get(ohv); - ENTER; - SAVEFREESV(hv); + ENTER; + SAVEFREESV(hv); HV_SET_MAX_ADJUSTED_FOR_KEYS(hv,hv_max,hv_keys); - hv_iterinit(ohv); - while ((entry = hv_iternext_flags(ohv, 0))) { - SV *const sv = newSVsv(hv_iterval(ohv,entry)); - SV *heksv = HeSVKEY(entry); - if (!heksv && sv) heksv = newSVhek(HeKEY_hek(entry)); - if (sv) sv_magic(sv, NULL, PERL_MAGIC_hintselem, - (char *)heksv, HEf_SVKEY); - if (heksv == HeSVKEY(entry)) - (void)hv_store_ent(hv, heksv, sv, 0); - else { - (void)hv_common(hv, heksv, HeKEY(entry), HeKLEN(entry), - HeKFLAGS(entry), HV_FETCH_ISSTORE|HV_FETCH_JUST_SV, sv, HeHASH(entry)); - SvREFCNT_dec_NN(heksv); - } - } - HvRITER_set(ohv, riter); - HvEITER_set(ohv, eiter); - - SvREFCNT_inc_simple_void_NN(hv); - LEAVE; + hv_iterinit(ohv); + while ((entry = hv_iternext_flags(ohv, 0))) { + SV *const sv = newSVsv(hv_iterval(ohv,entry)); + SV *heksv = HeSVKEY(entry); + if (!heksv && sv) heksv = newSVhek(HeKEY_hek(entry)); + if (sv) sv_magic(sv, NULL, PERL_MAGIC_hintselem, + (char *)heksv, HEf_SVKEY); + if (heksv == HeSVKEY(entry)) + (void)hv_store_ent(hv, heksv, sv, 0); + else { + (void)hv_common(hv, heksv, HeKEY(entry), HeKLEN(entry), + HeKFLAGS(entry), HV_FETCH_ISSTORE|HV_FETCH_JUST_SV, sv, HeHASH(entry)); + SvREFCNT_dec_NN(heksv); + } + } + HvRITER_set(ohv, riter); + HvEITER_set(ohv, eiter); + + SvREFCNT_inc_simple_void_NN(hv); + LEAVE; } hv_magic(hv, NULL, PERL_MAGIC_hints); return hv; @@ -1732,13 +1732,13 @@ S_hv_free_ent_ret(pTHX_ HV *hv, HE *entry) val = HeVAL(entry); if (HeKLEN(entry) == HEf_SVKEY) { - SvREFCNT_dec(HeKEY_sv(entry)); - Safefree(HeKEY_hek(entry)); + SvREFCNT_dec(HeKEY_sv(entry)); + Safefree(HeKEY_hek(entry)); } else if (HvSHAREKEYS(hv)) - unshare_hek(HeKEY_hek(entry)); + unshare_hek(HeKEY_hek(entry)); else - Safefree(HeKEY_hek(entry)); + Safefree(HeKEY_hek(entry)); del_HE(entry); return val; } @@ -1752,7 +1752,7 @@ Perl_hv_free_ent(pTHX_ HV *hv, HE *entry) PERL_ARGS_ASSERT_HV_FREE_ENT; if (!entry) - return; + return; val = hv_free_ent_ret(hv, entry); SvREFCNT_dec(val); } @@ -1764,11 +1764,11 @@ Perl_hv_delayfree_ent(pTHX_ HV *hv, HE *entry) PERL_ARGS_ASSERT_HV_DELAYFREE_ENT; if (!entry) - return; + return; /* SvREFCNT_inc to counter the SvREFCNT_dec in hv_free_ent */ sv_2mortal(SvREFCNT_inc(HeVAL(entry))); /* free between statements */ if (HeKLEN(entry) == HEf_SVKEY) { - sv_2mortal(SvREFCNT_inc(HeKEY_sv(entry))); + sv_2mortal(SvREFCNT_inc(HeKEY_sv(entry))); } hv_free_ent(hv, entry); } @@ -1792,7 +1792,7 @@ Perl_hv_clear(pTHX_ HV *hv) XPVHV* xhv; if (!hv) - return; + return; DEBUG_A(Perl_hv_assert(aTHX_ hv)); @@ -1803,41 +1803,41 @@ Perl_hv_clear(pTHX_ HV *hv) PL_tmps_stack[++PL_tmps_ix] = SvREFCNT_inc_simple_NN(hv); orig_ix = PL_tmps_ix; if (SvREADONLY(hv) && HvARRAY(hv) != NULL) { - /* restricted hash: convert all keys to placeholders */ - STRLEN i; - for (i = 0; i <= xhv->xhv_max; i++) { - HE *entry = (HvARRAY(hv))[i]; - for (; entry; entry = HeNEXT(entry)) { - /* not already placeholder */ - if (HeVAL(entry) != &PL_sv_placeholder) { - if (HeVAL(entry)) { - if (SvREADONLY(HeVAL(entry))) { - SV* const keysv = hv_iterkeysv(entry); - Perl_croak_nocontext( - "Attempt to delete readonly key '%" SVf "' from a restricted hash", - (void*)keysv); - } - SvREFCNT_dec_NN(HeVAL(entry)); - } - HeVAL(entry) = &PL_sv_placeholder; - HvPLACEHOLDERS(hv)++; - } - } - } + /* restricted hash: convert all keys to placeholders */ + STRLEN i; + for (i = 0; i <= xhv->xhv_max; i++) { + HE *entry = (HvARRAY(hv))[i]; + for (; entry; entry = HeNEXT(entry)) { + /* not already placeholder */ + if (HeVAL(entry) != &PL_sv_placeholder) { + if (HeVAL(entry)) { + if (SvREADONLY(HeVAL(entry))) { + SV* const keysv = hv_iterkeysv(entry); + Perl_croak_nocontext( + "Attempt to delete readonly key '%" SVf "' from a restricted hash", + (void*)keysv); + } + SvREFCNT_dec_NN(HeVAL(entry)); + } + HeVAL(entry) = &PL_sv_placeholder; + HvPLACEHOLDERS(hv)++; + } + } + } } else { - hv_free_entries(hv); - HvPLACEHOLDERS_set(hv, 0); + hv_free_entries(hv); + HvPLACEHOLDERS_set(hv, 0); - if (SvRMAGICAL(hv)) - mg_clear(MUTABLE_SV(hv)); + if (SvRMAGICAL(hv)) + mg_clear(MUTABLE_SV(hv)); - HvHASKFLAGS_off(hv); + HvHASKFLAGS_off(hv); } if (SvOOK(hv)) { if(HvENAME_get(hv)) mro_isa_changed_in(hv); - HvEITER_set(hv, NULL); + HvEITER_set(hv, NULL); } /* disarm hv's premature free guard */ if (LIKELY(PL_tmps_ix == orig_ix)) @@ -1870,7 +1870,7 @@ Perl_hv_clear_placeholders(pTHX_ HV *hv) PERL_ARGS_ASSERT_HV_CLEAR_PLACEHOLDERS; if (items) - clear_placeholders(hv, items); + clear_placeholders(hv, items); } static void @@ -1881,40 +1881,40 @@ S_clear_placeholders(pTHX_ HV *hv, U32 items) PERL_ARGS_ASSERT_CLEAR_PLACEHOLDERS; if (items == 0) - return; + return; i = HvMAX(hv); do { - /* Loop down the linked list heads */ - HE **oentry = &(HvARRAY(hv))[i]; - HE *entry; - - while ((entry = *oentry)) { - if (HeVAL(entry) == &PL_sv_placeholder) { - *oentry = HeNEXT(entry); - if (entry == HvEITER_get(hv)) - HvLAZYDEL_on(hv); - else { - if (SvOOK(hv) && HvLAZYDEL(hv) && - entry == HeNEXT(HvAUX(hv)->xhv_eiter)) - HeNEXT(HvAUX(hv)->xhv_eiter) = HeNEXT(entry); - hv_free_ent(hv, entry); - } - - if (--items == 0) { - /* Finished. */ - I32 placeholders = HvPLACEHOLDERS_get(hv); - HvTOTALKEYS(hv) -= (IV)placeholders; - /* HvUSEDKEYS expanded */ - if ((HvTOTALKEYS(hv) - placeholders) == 0) - HvHASKFLAGS_off(hv); - HvPLACEHOLDERS_set(hv, 0); - return; - } - } else { - oentry = &HeNEXT(entry); - } - } + /* Loop down the linked list heads */ + HE **oentry = &(HvARRAY(hv))[i]; + HE *entry; + + while ((entry = *oentry)) { + if (HeVAL(entry) == &PL_sv_placeholder) { + *oentry = HeNEXT(entry); + if (entry == HvEITER_get(hv)) + HvLAZYDEL_on(hv); + else { + if (SvOOK(hv) && HvLAZYDEL(hv) && + entry == HeNEXT(HvAUX(hv)->xhv_eiter)) + HeNEXT(HvAUX(hv)->xhv_eiter) = HeNEXT(entry); + hv_free_ent(hv, entry); + } + + if (--items == 0) { + /* Finished. */ + I32 placeholders = HvPLACEHOLDERS_get(hv); + HvTOTALKEYS(hv) -= (IV)placeholders; + /* HvUSEDKEYS expanded */ + if ((HvTOTALKEYS(hv) - placeholders) == 0) + HvHASKFLAGS_off(hv); + HvPLACEHOLDERS_set(hv, 0); + return; + } + } else { + oentry = &HeNEXT(entry); + } + } } while (--i >= 0); /* You can't get here, hence assertion should always fail. */ assert (items == 0); @@ -1931,7 +1931,7 @@ S_hv_free_entries(pTHX_ HV *hv) PERL_ARGS_ASSERT_HV_FREE_ENTRIES; while ((sv = Perl_hfree_next_entry(aTHX_ hv, &index))||xhv->xhv_keys) { - SvREFCNT_dec(sv); + SvREFCNT_dec(sv); } } @@ -1958,7 +1958,7 @@ Perl_hfree_next_entry(pTHX_ HV *hv, STRLEN *indexp) PERL_ARGS_ASSERT_HFREE_NEXT_ENTRY; if (SvOOK(hv) && ((iter = HvAUX(hv)))) { - if ((entry = iter->xhv_eiter)) { + if ((entry = iter->xhv_eiter)) { /* the iterator may get resurrected after each * destructor call, so check each time */ if (entry && HvLAZYDEL(hv)) { /* was deleted earlier? */ @@ -1977,31 +1977,31 @@ Perl_hfree_next_entry(pTHX_ HV *hv, STRLEN *indexp) } if (!((XPVHV*)SvANY(hv))->xhv_keys) - return NULL; + return NULL; array = HvARRAY(hv); assert(array); while ( ! ((entry = array[*indexp])) ) { - if ((*indexp)++ >= HvMAX(hv)) - *indexp = 0; - assert(*indexp != orig_index); + if ((*indexp)++ >= HvMAX(hv)) + *indexp = 0; + assert(*indexp != orig_index); } array[*indexp] = HeNEXT(entry); ((XPVHV*) SvANY(hv))->xhv_keys--; if ( PL_phase != PERL_PHASE_DESTRUCT && HvENAME(hv) - && HeVAL(entry) && isGV(HeVAL(entry)) - && GvHV(HeVAL(entry)) && HvENAME(GvHV(HeVAL(entry))) + && HeVAL(entry) && isGV(HeVAL(entry)) + && GvHV(HeVAL(entry)) && HvENAME(GvHV(HeVAL(entry))) ) { - STRLEN klen; - const char * const key = HePV(entry,klen); - if ((klen > 1 && key[klen-1]==':' && key[klen-2]==':') - || (klen == 1 && key[0] == ':')) { - mro_package_moved( - NULL, GvHV(HeVAL(entry)), - (GV *)HeVAL(entry), 0 - ); - } + STRLEN klen; + const char * const key = HePV(entry,klen); + if ((klen > 1 && key[klen-1]==':' && key[klen-2]==':') + || (klen == 1 && key[0] == ':')) { + mro_package_moved( + NULL, GvHV(HeVAL(entry)), + (GV *)HeVAL(entry), 0 + ); + } } return hv_free_ent_ret(hv, entry); } @@ -2029,7 +2029,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) SSize_t orig_ix = PL_tmps_ix; /* silence compiler warning about unitialized vars */ if (!hv) - return; + return; save = cBOOL(SvREFCNT(hv)); DEBUG_A(Perl_hv_assert(aTHX_ hv)); xhv = (XPVHV*)SvANY(hv); @@ -2048,9 +2048,9 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) if (PL_stashcache) { DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for '%" HEKf "'\n", HEKfARG(HvNAME_HEK(hv)))); - (void)hv_deletehek(PL_stashcache, HvNAME_HEK(hv), G_DISCARD); + (void)hv_deletehek(PL_stashcache, HvNAME_HEK(hv), G_DISCARD); } - hv_name_set(hv, NULL, 0, 0); + hv_name_set(hv, NULL, 0, 0); } if (save) { /* avoid hv being freed when calling destructors below */ @@ -2064,12 +2064,12 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) const char *name; if (HvENAME_get(hv)) { - if (PL_phase != PERL_PHASE_DESTRUCT) - mro_isa_changed_in(hv); + if (PL_phase != PERL_PHASE_DESTRUCT) + mro_isa_changed_in(hv); if (PL_stashcache) { DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for effective name '%" HEKf "'\n", HEKfARG(HvENAME_HEK(hv)))); - (void)hv_deletehek(PL_stashcache, HvENAME_HEK(hv), G_DISCARD); + (void)hv_deletehek(PL_stashcache, HvENAME_HEK(hv), G_DISCARD); } } @@ -2080,41 +2080,41 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags) if (name && PL_stashcache) { DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for name '%" HEKf "'\n", HEKfARG(HvNAME_HEK(hv)))); - (void)hv_deletehek(PL_stashcache, HvNAME_HEK(hv), G_DISCARD); + (void)hv_deletehek(PL_stashcache, HvNAME_HEK(hv), G_DISCARD); } - hv_name_set(hv, NULL, 0, flags); + hv_name_set(hv, NULL, 0, flags); } if((meta = HvAUX(hv)->xhv_mro_meta)) { - if (meta->mro_linear_all) { - SvREFCNT_dec_NN(meta->mro_linear_all); - /* mro_linear_current is just acting as a shortcut pointer, - hence the else. */ - } - else - /* Only the current MRO is stored, so this owns the data. - */ - SvREFCNT_dec(meta->mro_linear_current); - SvREFCNT_dec(meta->mro_nextmethod); - SvREFCNT_dec(meta->isa); - SvREFCNT_dec(meta->super); - Safefree(meta); - HvAUX(hv)->xhv_mro_meta = NULL; + if (meta->mro_linear_all) { + SvREFCNT_dec_NN(meta->mro_linear_all); + /* mro_linear_current is just acting as a shortcut pointer, + hence the else. */ + } + else + /* Only the current MRO is stored, so this owns the data. + */ + SvREFCNT_dec(meta->mro_linear_current); + SvREFCNT_dec(meta->mro_nextmethod); + SvREFCNT_dec(meta->isa); + SvREFCNT_dec(meta->super); + Safefree(meta); + HvAUX(hv)->xhv_mro_meta = NULL; } if (!HvAUX(hv)->xhv_name_u.xhvnameu_name && ! HvAUX(hv)->xhv_backreferences) - SvFLAGS(hv) &= ~SVf_OOK; + SvFLAGS(hv) &= ~SVf_OOK; } if (!SvOOK(hv)) { - Safefree(HvARRAY(hv)); + Safefree(HvARRAY(hv)); xhv->xhv_max = PERL_HASH_DEFAULT_HvMAX; /* HvMAX(hv) = 7 (it's a normal hash) */ - HvARRAY(hv) = 0; + HvARRAY(hv) = 0; } /* if we're freeing the HV, the SvMAGIC field has been reused for * other purposes, and so there can't be any placeholder magic */ if (SvREFCNT(hv)) - HvPLACEHOLDERS_set(hv, 0); + HvPLACEHOLDERS_set(hv, 0); if (SvRMAGICAL(hv)) - mg_clear(MUTABLE_SV(hv)); + mg_clear(MUTABLE_SV(hv)); if (save) { /* disarm hv's premature free guard */ @@ -2162,13 +2162,13 @@ Perl_hv_fill(pTHX_ HV *const hv) * I would have thought counting up was better. * - Yves */ - HE *const *const last = ents + HvMAX(hv); - count = last + 1 - ents; + HE *const *const last = ents + HvMAX(hv); + count = last + 1 - ents; - do { - if (!*ents) - --count; - } while (++ents <= last); + do { + if (!*ents) + --count; + } while (++ents <= last); } return count; } @@ -2279,20 +2279,20 @@ Perl_hv_iterinit(pTHX_ HV *hv) PERL_ARGS_ASSERT_HV_ITERINIT; if (SvOOK(hv)) { - struct xpvhv_aux * iter = HvAUX(hv); - HE * const entry = iter->xhv_eiter; /* HvEITER(hv) */ - if (entry && HvLAZYDEL(hv)) { /* was deleted earlier? */ - HvLAZYDEL_off(hv); - hv_free_ent(hv, entry); - } - iter = HvAUX(hv); /* may have been reallocated */ - iter->xhv_riter = -1; /* HvRITER(hv) = -1 */ - iter->xhv_eiter = NULL; /* HvEITER(hv) = NULL */ + struct xpvhv_aux * iter = HvAUX(hv); + HE * const entry = iter->xhv_eiter; /* HvEITER(hv) */ + if (entry && HvLAZYDEL(hv)) { /* was deleted earlier? */ + HvLAZYDEL_off(hv); + hv_free_ent(hv, entry); + } + iter = HvAUX(hv); /* may have been reallocated */ + iter->xhv_riter = -1; /* HvRITER(hv) = -1 */ + iter->xhv_eiter = NULL; /* HvEITER(hv) = NULL */ #ifdef PERL_HASH_RANDOMIZE_KEYS iter->xhv_last_rand = iter->xhv_rand; #endif } else { - hv_auxinit(hv); + hv_auxinit(hv); } /* note this includes placeholders! */ @@ -2326,12 +2326,12 @@ Perl_hv_riter_set(pTHX_ HV *hv, I32 riter) { PERL_ARGS_ASSERT_HV_RITER_SET; if (SvOOK(hv)) { - iter = HvAUX(hv); + iter = HvAUX(hv); } else { - if (riter == -1) - return; + if (riter == -1) + return; - iter = hv_auxinit(hv); + iter = hv_auxinit(hv); } iter->xhv_riter = riter; } @@ -2361,14 +2361,14 @@ Perl_hv_eiter_set(pTHX_ HV *hv, HE *eiter) { PERL_ARGS_ASSERT_HV_EITER_SET; if (SvOOK(hv)) { - iter = HvAUX(hv); + iter = HvAUX(hv); } else { - /* 0 is the default so don't go malloc()ing a new structure just to - hold 0. */ - if (!eiter) - return; + /* 0 is the default so don't go malloc()ing a new structure just to + hold 0. */ + if (!eiter) + return; - iter = hv_auxinit(hv); + iter = hv_auxinit(hv); } iter->xhv_eiter = eiter; } @@ -2383,64 +2383,64 @@ Perl_hv_name_set(pTHX_ HV *hv, const char *name, U32 len, U32 flags) PERL_ARGS_ASSERT_HV_NAME_SET; if (len > I32_MAX) - Perl_croak(aTHX_ "panic: hv name too long (%" UVuf ")", (UV) len); + Perl_croak(aTHX_ "panic: hv name too long (%" UVuf ")", (UV) len); if (SvOOK(hv)) { - iter = HvAUX(hv); - if (iter->xhv_name_u.xhvnameu_name) { - if(iter->xhv_name_count) { - if(flags & HV_NAME_SETALL) { - HEK ** const this_name = HvAUX(hv)->xhv_name_u.xhvnameu_names; - HEK **hekp = this_name + ( - iter->xhv_name_count < 0 - ? -iter->xhv_name_count - : iter->xhv_name_count - ); - while(hekp-- > this_name+1) - unshare_hek_or_pvn(*hekp, 0, 0, 0); - /* The first elem may be null. */ - if(*this_name) unshare_hek_or_pvn(*this_name, 0, 0, 0); - Safefree(this_name); + iter = HvAUX(hv); + if (iter->xhv_name_u.xhvnameu_name) { + if(iter->xhv_name_count) { + if(flags & HV_NAME_SETALL) { + HEK ** const this_name = HvAUX(hv)->xhv_name_u.xhvnameu_names; + HEK **hekp = this_name + ( + iter->xhv_name_count < 0 + ? -iter->xhv_name_count + : iter->xhv_name_count + ); + while(hekp-- > this_name+1) + unshare_hek_or_pvn(*hekp, 0, 0, 0); + /* The first elem may be null. */ + if(*this_name) unshare_hek_or_pvn(*this_name, 0, 0, 0); + Safefree(this_name); iter = HvAUX(hv); /* may been realloced */ - spot = &iter->xhv_name_u.xhvnameu_name; - iter->xhv_name_count = 0; - } - else { - if(iter->xhv_name_count > 0) { - /* shift some things over */ - Renew( - iter->xhv_name_u.xhvnameu_names, iter->xhv_name_count + 1, HEK * - ); - spot = iter->xhv_name_u.xhvnameu_names; - spot[iter->xhv_name_count] = spot[1]; - spot[1] = spot[0]; - iter->xhv_name_count = -(iter->xhv_name_count + 1); - } - else if(*(spot = iter->xhv_name_u.xhvnameu_names)) { - unshare_hek_or_pvn(*spot, 0, 0, 0); - } - } - } - else if (flags & HV_NAME_SETALL) { - unshare_hek_or_pvn(iter->xhv_name_u.xhvnameu_name, 0, 0, 0); + spot = &iter->xhv_name_u.xhvnameu_name; + iter->xhv_name_count = 0; + } + else { + if(iter->xhv_name_count > 0) { + /* shift some things over */ + Renew( + iter->xhv_name_u.xhvnameu_names, iter->xhv_name_count + 1, HEK * + ); + spot = iter->xhv_name_u.xhvnameu_names; + spot[iter->xhv_name_count] = spot[1]; + spot[1] = spot[0]; + iter->xhv_name_count = -(iter->xhv_name_count + 1); + } + else if(*(spot = iter->xhv_name_u.xhvnameu_names)) { + unshare_hek_or_pvn(*spot, 0, 0, 0); + } + } + } + else if (flags & HV_NAME_SETALL) { + unshare_hek_or_pvn(iter->xhv_name_u.xhvnameu_name, 0, 0, 0); iter = HvAUX(hv); /* may been realloced */ - spot = &iter->xhv_name_u.xhvnameu_name; - } - else { - HEK * const existing_name = iter->xhv_name_u.xhvnameu_name; - Newx(iter->xhv_name_u.xhvnameu_names, 2, HEK *); - iter->xhv_name_count = -2; - spot = iter->xhv_name_u.xhvnameu_names; - spot[1] = existing_name; - } - } - else { spot = &iter->xhv_name_u.xhvnameu_name; iter->xhv_name_count = 0; } + spot = &iter->xhv_name_u.xhvnameu_name; + } + else { + HEK * const existing_name = iter->xhv_name_u.xhvnameu_name; + Newx(iter->xhv_name_u.xhvnameu_names, 2, HEK *); + iter->xhv_name_count = -2; + spot = iter->xhv_name_u.xhvnameu_names; + spot[1] = existing_name; + } + } + else { spot = &iter->xhv_name_u.xhvnameu_name; iter->xhv_name_count = 0; } } else { - if (name == 0) - return; + if (name == 0) + return; - iter = hv_auxinit(hv); - spot = &iter->xhv_name_u.xhvnameu_name; + iter = hv_auxinit(hv); + spot = &iter->xhv_name_u.xhvnameu_name; } PERL_HASH(hash, name, len); *spot = name ? share_hek(name, flags & SVf_UTF8 ? -(I32)len : (I32)len, hash) : NULL; @@ -2457,11 +2457,11 @@ hek_eq_pvn_flags(pTHX_ const HEK *hek, const char* pv, const I32 pvlen, const U3 if (flags & SVf_UTF8) return (bytes_cmp_utf8( (const U8*)HEK_KEY(hek), HEK_LEN(hek), - (const U8*)pv, pvlen) == 0); + (const U8*)pv, pvlen) == 0); else return (bytes_cmp_utf8( (const U8*)pv, pvlen, - (const U8*)HEK_KEY(hek), HEK_LEN(hek)) == 0); + (const U8*)HEK_KEY(hek), HEK_LEN(hek)) == 0); } else return HEK_LEN(hek) == pvlen && ((HEK_KEY(hek) == pv) @@ -2489,45 +2489,45 @@ Perl_hv_ename_add(pTHX_ HV *hv, const char *name, U32 len, U32 flags) PERL_ARGS_ASSERT_HV_ENAME_ADD; if (len > I32_MAX) - Perl_croak(aTHX_ "panic: hv name too long (%" UVuf ")", (UV) len); + Perl_croak(aTHX_ "panic: hv name too long (%" UVuf ")", (UV) len); PERL_HASH(hash, name, len); if (aux->xhv_name_count) { - I32 count = aux->xhv_name_count; - HEK ** const xhv_name = aux->xhv_name_u.xhvnameu_names + (count<0); - HEK **hekp = xhv_name + (count < 0 ? -count - 1 : count); - while (hekp-- > xhv_name) - { - assert(*hekp); - if ( + I32 count = aux->xhv_name_count; + HEK ** const xhv_name = aux->xhv_name_u.xhvnameu_names + (count<0); + HEK **hekp = xhv_name + (count < 0 ? -count - 1 : count); + while (hekp-- > xhv_name) + { + assert(*hekp); + if ( (HEK_UTF8(*hekp) || (flags & SVf_UTF8)) ? hek_eq_pvn_flags(aTHX_ *hekp, name, (I32)len, flags) - : (HEK_LEN(*hekp) == (I32)len && memEQ(HEK_KEY(*hekp), name, len)) + : (HEK_LEN(*hekp) == (I32)len && memEQ(HEK_KEY(*hekp), name, len)) ) { - if (hekp == xhv_name && count < 0) - aux->xhv_name_count = -count; - return; - } - } - if (count < 0) aux->xhv_name_count--, count = -count; - else aux->xhv_name_count++; - Renew(aux->xhv_name_u.xhvnameu_names, count + 1, HEK *); - (aux->xhv_name_u.xhvnameu_names)[count] = share_hek(name, (flags & SVf_UTF8 ? -(I32)len : (I32)len), hash); + if (hekp == xhv_name && count < 0) + aux->xhv_name_count = -count; + return; + } + } + if (count < 0) aux->xhv_name_count--, count = -count; + else aux->xhv_name_count++; + Renew(aux->xhv_name_u.xhvnameu_names, count + 1, HEK *); + (aux->xhv_name_u.xhvnameu_names)[count] = share_hek(name, (flags & SVf_UTF8 ? -(I32)len : (I32)len), hash); } else { - HEK *existing_name = aux->xhv_name_u.xhvnameu_name; - if ( - existing_name && ( + HEK *existing_name = aux->xhv_name_u.xhvnameu_name; + if ( + existing_name && ( (HEK_UTF8(existing_name) || (flags & SVf_UTF8)) ? hek_eq_pvn_flags(aTHX_ existing_name, name, (I32)len, flags) - : (HEK_LEN(existing_name) == (I32)len && memEQ(HEK_KEY(existing_name), name, len)) - ) - ) return; - Newx(aux->xhv_name_u.xhvnameu_names, 2, HEK *); - aux->xhv_name_count = existing_name ? 2 : -2; - *aux->xhv_name_u.xhvnameu_names = existing_name; - (aux->xhv_name_u.xhvnameu_names)[1] = share_hek(name, (flags & SVf_UTF8 ? -(I32)len : (I32)len), hash); + : (HEK_LEN(existing_name) == (I32)len && memEQ(HEK_KEY(existing_name), name, len)) + ) + ) return; + Newx(aux->xhv_name_u.xhvnameu_names, 2, HEK *); + aux->xhv_name_count = existing_name ? 2 : -2; + *aux->xhv_name_u.xhvnameu_names = existing_name; + (aux->xhv_name_u.xhvnameu_names)[1] = share_hek(name, (flags & SVf_UTF8 ? -(I32)len : (I32)len), hash); } } @@ -2551,7 +2551,7 @@ Perl_hv_ename_delete(pTHX_ HV *hv, const char *name, U32 len, U32 flags) PERL_ARGS_ASSERT_HV_ENAME_DELETE; if (len > I32_MAX) - Perl_croak(aTHX_ "panic: hv name too long (%" UVuf ")", (UV) len); + Perl_croak(aTHX_ "panic: hv name too long (%" UVuf ")", (UV) len); if (!SvOOK(hv)) return; @@ -2559,53 +2559,53 @@ Perl_hv_ename_delete(pTHX_ HV *hv, const char *name, U32 len, U32 flags) if (!aux->xhv_name_u.xhvnameu_name) return; if (aux->xhv_name_count) { - HEK ** const namep = aux->xhv_name_u.xhvnameu_names; - I32 const count = aux->xhv_name_count; - HEK **victim = namep + (count < 0 ? -count : count); - while (victim-- > namep + 1) - if ( + HEK ** const namep = aux->xhv_name_u.xhvnameu_names; + I32 const count = aux->xhv_name_count; + HEK **victim = namep + (count < 0 ? -count : count); + while (victim-- > namep + 1) + if ( (HEK_UTF8(*victim) || (flags & SVf_UTF8)) ? hek_eq_pvn_flags(aTHX_ *victim, name, (I32)len, flags) - : (HEK_LEN(*victim) == (I32)len && memEQ(HEK_KEY(*victim), name, len)) - ) { - unshare_hek_or_pvn(*victim, 0, 0, 0); + : (HEK_LEN(*victim) == (I32)len && memEQ(HEK_KEY(*victim), name, len)) + ) { + unshare_hek_or_pvn(*victim, 0, 0, 0); aux = HvAUX(hv); /* may been realloced */ - if (count < 0) ++aux->xhv_name_count; - else --aux->xhv_name_count; - if ( - (aux->xhv_name_count == 1 || aux->xhv_name_count == -1) - && !*namep - ) { /* if there are none left */ - Safefree(namep); - aux->xhv_name_u.xhvnameu_names = NULL; - aux->xhv_name_count = 0; - } - else { - /* Move the last one back to fill the empty slot. It - does not matter what order they are in. */ - *victim = *(namep + (count < 0 ? -count : count) - 1); - } - return; - } - if ( - count > 0 && ((HEK_UTF8(*namep) || (flags & SVf_UTF8)) + if (count < 0) ++aux->xhv_name_count; + else --aux->xhv_name_count; + if ( + (aux->xhv_name_count == 1 || aux->xhv_name_count == -1) + && !*namep + ) { /* if there are none left */ + Safefree(namep); + aux->xhv_name_u.xhvnameu_names = NULL; + aux->xhv_name_count = 0; + } + else { + /* Move the last one back to fill the empty slot. It + does not matter what order they are in. */ + *victim = *(namep + (count < 0 ? -count : count) - 1); + } + return; + } + if ( + count > 0 && ((HEK_UTF8(*namep) || (flags & SVf_UTF8)) ? hek_eq_pvn_flags(aTHX_ *namep, name, (I32)len, flags) - : (HEK_LEN(*namep) == (I32)len && memEQ(HEK_KEY(*namep), name, len)) + : (HEK_LEN(*namep) == (I32)len && memEQ(HEK_KEY(*namep), name, len)) ) - ) { - aux->xhv_name_count = -count; - } + ) { + aux->xhv_name_count = -count; + } } else if( (HEK_UTF8(aux->xhv_name_u.xhvnameu_name) || (flags & SVf_UTF8)) ? hek_eq_pvn_flags(aTHX_ aux->xhv_name_u.xhvnameu_name, name, (I32)len, flags) - : (HEK_LEN(aux->xhv_name_u.xhvnameu_name) == (I32)len && + : (HEK_LEN(aux->xhv_name_u.xhvnameu_name) == (I32)len && memEQ(HEK_KEY(aux->xhv_name_u.xhvnameu_name), name, len)) ) { - HEK * const namehek = aux->xhv_name_u.xhvnameu_name; - Newx(aux->xhv_name_u.xhvnameu_names, 1, HEK *); - *aux->xhv_name_u.xhvnameu_names = namehek; - aux->xhv_name_count = -1; + HEK * const namehek = aux->xhv_name_u.xhvnameu_name; + Newx(aux->xhv_name_u.xhvnameu_names, 1, HEK *); + *aux->xhv_name_u.xhvnameu_names = namehek; + aux->xhv_name_count = -1; } } @@ -2626,15 +2626,15 @@ Perl_hv_kill_backrefs(pTHX_ HV *hv) { PERL_ARGS_ASSERT_HV_KILL_BACKREFS; if (!SvOOK(hv)) - return; + return; av = HvAUX(hv)->xhv_backreferences; if (av) { - HvAUX(hv)->xhv_backreferences = 0; - Perl_sv_kill_backrefs(aTHX_ MUTABLE_SV(hv), av); - if (SvTYPE(av) == SVt_PVAV) - SvREFCNT_dec_NN(av); + HvAUX(hv)->xhv_backreferences = 0; + Perl_sv_kill_backrefs(aTHX_ MUTABLE_SV(hv), av); + if (SvTYPE(av) == SVt_PVAV) + SvREFCNT_dec_NN(av); } } @@ -2684,21 +2684,21 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) xhv = (XPVHV*)SvANY(hv); if (!SvOOK(hv)) { - /* Too many things (well, pp_each at least) merrily assume that you can - call hv_iternext without calling hv_iterinit, so we'll have to deal - with it. */ - hv_iterinit(hv); + /* Too many things (well, pp_each at least) merrily assume that you can + call hv_iternext without calling hv_iterinit, so we'll have to deal + with it. */ + hv_iterinit(hv); } iter = HvAUX(hv); oldentry = entry = iter->xhv_eiter; /* HvEITER(hv) */ if (SvMAGICAL(hv) && SvRMAGICAL(hv)) { - if ( ( mg = mg_find((const SV *)hv, PERL_MAGIC_tied) ) ) { + if ( ( mg = mg_find((const SV *)hv, PERL_MAGIC_tied) ) ) { SV * const key = sv_newmortal(); if (entry) { sv_setsv(key, HeSVKEY_force(entry)); SvREFCNT_dec(HeSVKEY(entry)); /* get rid of previous key */ - HeSVKEY_set(entry, NULL); + HeSVKEY_set(entry, NULL); } else { char *k; @@ -2706,7 +2706,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) /* one HE per MAGICAL hash */ iter->xhv_eiter = entry = new_HE(); /* HvEITER(hv) = new_HE() */ - HvLAZYDEL_on(hv); /* make sure entry gets freed */ + HvLAZYDEL_on(hv); /* make sure entry gets freed */ Zero(entry, 1, HE); Newxz(k, HEK_BASESIZE + sizeof(const SV *), char); hek = (HEK*)k; @@ -2724,21 +2724,21 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) del_HE(entry); iter = HvAUX(hv); /* may been realloced */ iter->xhv_eiter = NULL; /* HvEITER(hv) = NULL */ - HvLAZYDEL_off(hv); + HvLAZYDEL_off(hv); return NULL; } } #if defined(DYNAMIC_ENV_FETCH) && !defined(__riscos__) /* set up %ENV for iteration */ if (!entry && SvRMAGICAL((const SV *)hv) - && mg_find((const SV *)hv, PERL_MAGIC_env)) { - prime_env_iter(); + && mg_find((const SV *)hv, PERL_MAGIC_env)) { + prime_env_iter(); #ifdef VMS - /* The prime_env_iter() on VMS just loaded up new hash values - * so the iteration count needs to be reset back to the beginning - */ - hv_iterinit(hv); - iter = HvAUX(hv); - oldentry = entry = iter->xhv_eiter; /* HvEITER(hv) */ + /* The prime_env_iter() on VMS just loaded up new hash values + * so the iteration count needs to be reset back to the beginning + */ + hv_iterinit(hv); + iter = HvAUX(hv); + oldentry = entry = iter->xhv_eiter; /* HvEITER(hv) */ #endif } #endif @@ -2749,7 +2749,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) /* At start of hash, entry is NULL. */ if (entry) { - entry = HeNEXT(entry); + entry = HeNEXT(entry); if (!(flags & HV_ITERNEXT_WANTPLACEHOLDERS)) { /* * Skip past any placeholders -- don't want to include them in @@ -2758,7 +2758,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) while (entry && HeVAL(entry) == &PL_sv_placeholder) { entry = HeNEXT(entry); } - } + } } #ifdef PERL_HASH_RANDOMIZE_KEYS @@ -2776,31 +2776,31 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) /* Skip the entire loop if the hash is empty. */ if ((flags & HV_ITERNEXT_WANTPLACEHOLDERS) - ? HvTOTALKEYS(hv) : HvUSEDKEYS(hv)) { - while (!entry) { - /* OK. Come to the end of the current list. Grab the next one. */ - - iter->xhv_riter++; /* HvRITER(hv)++ */ - if (iter->xhv_riter > (I32)xhv->xhv_max /* HvRITER(hv) > HvMAX(hv) */) { - /* There is no next one. End of the hash. */ - iter->xhv_riter = -1; /* HvRITER(hv) = -1 */ + ? HvTOTALKEYS(hv) : HvUSEDKEYS(hv)) { + while (!entry) { + /* OK. Come to the end of the current list. Grab the next one. */ + + iter->xhv_riter++; /* HvRITER(hv)++ */ + if (iter->xhv_riter > (I32)xhv->xhv_max /* HvRITER(hv) > HvMAX(hv) */) { + /* There is no next one. End of the hash. */ + iter->xhv_riter = -1; /* HvRITER(hv) = -1 */ #ifdef PERL_HASH_RANDOMIZE_KEYS iter->xhv_last_rand = iter->xhv_rand; /* reset xhv_last_rand so we can detect inserts during traversal */ #endif - break; - } + break; + } entry = (HvARRAY(hv))[ PERL_HASH_ITER_BUCKET(iter) & xhv->xhv_max ]; - if (!(flags & HV_ITERNEXT_WANTPLACEHOLDERS)) { - /* If we have an entry, but it's a placeholder, don't count it. - Try the next. */ - while (entry && HeVAL(entry) == &PL_sv_placeholder) - entry = HeNEXT(entry); - } - /* Will loop again if this linked list starts NULL - (for HV_ITERNEXT_WANTPLACEHOLDERS) - or if we run through it and find only placeholders. */ - } + if (!(flags & HV_ITERNEXT_WANTPLACEHOLDERS)) { + /* If we have an entry, but it's a placeholder, don't count it. + Try the next. */ + while (entry && HeVAL(entry) == &PL_sv_placeholder) + entry = HeNEXT(entry); + } + /* Will loop again if this linked list starts NULL + (for HV_ITERNEXT_WANTPLACEHOLDERS) + or if we run through it and find only placeholders. */ + } } else { iter->xhv_riter = -1; @@ -2810,8 +2810,8 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags) } if (oldentry && HvLAZYDEL(hv)) { /* was deleted earlier? */ - HvLAZYDEL_off(hv); - hv_free_ent(hv, oldentry); + HvLAZYDEL_off(hv); + hv_free_ent(hv, oldentry); } iter = HvAUX(hv); /* may been realloced */ @@ -2834,14 +2834,14 @@ Perl_hv_iterkey(pTHX_ HE *entry, I32 *retlen) PERL_ARGS_ASSERT_HV_ITERKEY; if (HeKLEN(entry) == HEf_SVKEY) { - STRLEN len; - char * const p = SvPV(HeKEY_sv(entry), len); - *retlen = len; - return p; + STRLEN len; + char * const p = SvPV(HeKEY_sv(entry), len); + *retlen = len; + return p; } else { - *retlen = HeKLEN(entry); - return HeKEY(entry); + *retlen = HeKLEN(entry); + return HeKEY(entry); } } @@ -2879,14 +2879,14 @@ Perl_hv_iterval(pTHX_ HV *hv, HE *entry) PERL_ARGS_ASSERT_HV_ITERVAL; if (SvRMAGICAL(hv)) { - if (mg_find((const SV *)hv, PERL_MAGIC_tied)) { - SV* const sv = sv_newmortal(); - if (HeKLEN(entry) == HEf_SVKEY) - mg_copy(MUTABLE_SV(hv), sv, (char*)HeKEY_sv(entry), HEf_SVKEY); - else - mg_copy(MUTABLE_SV(hv), sv, HeKEY(entry), HeKLEN(entry)); - return sv; - } + if (mg_find((const SV *)hv, PERL_MAGIC_tied)) { + SV* const sv = sv_newmortal(); + if (HeKLEN(entry) == HEf_SVKEY) + mg_copy(MUTABLE_SV(hv), sv, (char*)HeKEY_sv(entry), HEf_SVKEY); + else + mg_copy(MUTABLE_SV(hv), sv, HeKEY(entry), HeKLEN(entry)); + return sv; + } } return HeVAL(entry); } @@ -2908,7 +2908,7 @@ Perl_hv_iternextsv(pTHX_ HV *hv, char **key, I32 *retlen) PERL_ARGS_ASSERT_HV_ITERNEXTSV; if (!he) - return NULL; + return NULL; *key = hv_iterkey(he, retlen); return hv_iterval(hv, he); } @@ -2957,19 +2957,19 @@ S_unshare_hek_or_pvn(pTHX_ const HEK *hek, const char *str, I32 len, U32 hash) struct shared_he *he = NULL; if (hek) { - /* Find the shared he which is just before us in memory. */ - he = (struct shared_he *)(((char *)hek) - - STRUCT_OFFSET(struct shared_he, - shared_he_hek)); + /* Find the shared he which is just before us in memory. */ + he = (struct shared_he *)(((char *)hek) + - STRUCT_OFFSET(struct shared_he, + shared_he_hek)); - /* Assert that the caller passed us a genuine (or at least consistent) - shared hek */ - assert (he->shared_he_he.hent_hek == hek); + /* Assert that the caller passed us a genuine (or at least consistent) + shared hek */ + assert (he->shared_he_he.hent_hek == hek); - if (he->shared_he_he.he_valu.hent_refcount - 1) { - --he->shared_he_he.he_valu.hent_refcount; - return; - } + if (he->shared_he_he.he_valu.hent_refcount - 1) { + --he->shared_he_he.he_valu.hent_refcount; + return; + } hash = HEK_HASH(hek); } else if (len < 0) { @@ -2986,14 +2986,14 @@ S_unshare_hek_or_pvn(pTHX_ const HEK *hek, const char *str, I32 len, U32 hash) /* what follows was the moral equivalent of: if ((Svp = hv_fetch(PL_strtab, tmpsv, FALSE, hash))) { - if (--*Svp == NULL) - hv_delete(PL_strtab, str, len, G_DISCARD, hash); + if (--*Svp == NULL) + hv_delete(PL_strtab, str, len, G_DISCARD, hash); } */ xhv = (XPVHV*)SvANY(PL_strtab); /* assert(xhv_array != 0) */ oentry = &(HvARRAY(PL_strtab))[hash & (I32) HvMAX(PL_strtab)]; if (he) { - const HE *const he_he = &(he->shared_he_he); + const HE *const he_he = &(he->shared_he_he); for (entry = *oentry; entry; oentry = &HeNEXT(entry), entry = *oentry) { if (entry == he_he) break; @@ -3022,13 +3022,13 @@ S_unshare_hek_or_pvn(pTHX_ const HEK *hek, const char *str, I32 len, U32 hash) } if (!entry) - Perl_ck_warner_d(aTHX_ packWARN(WARN_INTERNAL), - "Attempt to free nonexistent shared string '%s'%s" - pTHX__FORMAT, - hek ? HEK_KEY(hek) : str, - ((k_flags & HVhek_UTF8) ? " (utf8)" : "") pTHX__VALUE); + Perl_ck_warner_d(aTHX_ packWARN(WARN_INTERNAL), + "Attempt to free nonexistent shared string '%s'%s" + pTHX__FORMAT, + hek ? HEK_KEY(hek) : str, + ((k_flags & HVhek_UTF8) ? " (utf8)" : "") pTHX__VALUE); if (k_flags & HVhek_FREEKEY) - Safefree(str); + Safefree(str); } /* get a (constant) string ptr from the global string table @@ -3083,73 +3083,73 @@ S_share_hek_flags(pTHX_ const char *str, STRLEN len, U32 hash, int flags) /* what follows is the moral equivalent of: if (!(Svp = hv_fetch(PL_strtab, str, len, FALSE))) - hv_store(PL_strtab, str, len, NULL, hash); + hv_store(PL_strtab, str, len, NULL, hash); - Can't rehash the shared string table, so not sure if it's worth - counting the number of entries in the linked list + Can't rehash the shared string table, so not sure if it's worth + counting the number of entries in the linked list */ /* assert(xhv_array != 0) */ entry = (HvARRAY(PL_strtab))[hindex]; for (;entry; entry = HeNEXT(entry)) { - if (HeHASH(entry) != hash) /* strings can't be equal */ - continue; - if (HeKLEN(entry) != (SSize_t) len) - continue; - if (HeKEY(entry) != str && memNE(HeKEY(entry),str,len)) /* is this it? */ - continue; - if (HeKFLAGS(entry) != flags_masked) - continue; - break; + if (HeHASH(entry) != hash) /* strings can't be equal */ + continue; + if (HeKLEN(entry) != (SSize_t) len) + continue; + if (HeKEY(entry) != str && memNE(HeKEY(entry),str,len)) /* is this it? */ + continue; + if (HeKFLAGS(entry) != flags_masked) + continue; + break; } if (!entry) { - /* What used to be head of the list. - If this is NULL, then we're the first entry for this slot, which - means we need to increate fill. */ - struct shared_he *new_entry; - HEK *hek; - char *k; - HE **const head = &HvARRAY(PL_strtab)[hindex]; - HE *const next = *head; - - /* We don't actually store a HE from the arena and a regular HEK. - Instead we allocate one chunk of memory big enough for both, - and put the HEK straight after the HE. This way we can find the - HE directly from the HEK. - */ - - Newx(k, STRUCT_OFFSET(struct shared_he, - shared_he_hek.hek_key[0]) + len + 2, char); - new_entry = (struct shared_he *)k; - entry = &(new_entry->shared_he_he); - hek = &(new_entry->shared_he_hek); - - Copy(str, HEK_KEY(hek), len, char); - HEK_KEY(hek)[len] = 0; - HEK_LEN(hek) = len; - HEK_HASH(hek) = hash; - HEK_FLAGS(hek) = (unsigned char)flags_masked; - - /* Still "point" to the HEK, so that other code need not know what - we're up to. */ - HeKEY_hek(entry) = hek; - entry->he_valu.hent_refcount = 0; - HeNEXT(entry) = next; - *head = entry; - - xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */ - if (!next) { /* initial entry? */ - } else if ( DO_HSPLIT(xhv) ) { + /* What used to be head of the list. + If this is NULL, then we're the first entry for this slot, which + means we need to increate fill. */ + struct shared_he *new_entry; + HEK *hek; + char *k; + HE **const head = &HvARRAY(PL_strtab)[hindex]; + HE *const next = *head; + + /* We don't actually store a HE from the arena and a regular HEK. + Instead we allocate one chunk of memory big enough for both, + and put the HEK straight after the HE. This way we can find the + HE directly from the HEK. + */ + + Newx(k, STRUCT_OFFSET(struct shared_he, + shared_he_hek.hek_key[0]) + len + 2, char); + new_entry = (struct shared_he *)k; + entry = &(new_entry->shared_he_he); + hek = &(new_entry->shared_he_hek); + + Copy(str, HEK_KEY(hek), len, char); + HEK_KEY(hek)[len] = 0; + HEK_LEN(hek) = len; + HEK_HASH(hek) = hash; + HEK_FLAGS(hek) = (unsigned char)flags_masked; + + /* Still "point" to the HEK, so that other code need not know what + we're up to. */ + HeKEY_hek(entry) = hek; + entry->he_valu.hent_refcount = 0; + HeNEXT(entry) = next; + *head = entry; + + xhv->xhv_keys++; /* HvTOTALKEYS(hv)++ */ + if (!next) { /* initial entry? */ + } else if ( DO_HSPLIT(xhv) ) { const STRLEN oldsize = xhv->xhv_max + 1; hsplit(PL_strtab, oldsize, oldsize * 2); - } + } } ++entry->he_valu.hent_refcount; if (flags & HVhek_FREEKEY) - Safefree(str); + Safefree(str); return HeKEY_hek(entry); } @@ -3162,11 +3162,11 @@ Perl_hv_placeholders_p(pTHX_ HV *hv) PERL_ARGS_ASSERT_HV_PLACEHOLDERS_P; if (!mg) { - mg = sv_magicext(MUTABLE_SV(hv), 0, PERL_MAGIC_rhash, 0, 0, 0); + mg = sv_magicext(MUTABLE_SV(hv), 0, PERL_MAGIC_rhash, 0, 0, 0); - if (!mg) { - Perl_die(aTHX_ "panic: hv_placeholders_p"); - } + if (!mg) { + Perl_die(aTHX_ "panic: hv_placeholders_p"); + } } return &(mg->mg_len); } @@ -3191,10 +3191,10 @@ Perl_hv_placeholders_set(pTHX_ HV *hv, I32 ph) PERL_ARGS_ASSERT_HV_PLACEHOLDERS_SET; if (mg) { - mg->mg_len = ph; + mg->mg_len = ph; } else if (ph) { - if (!sv_magicext(MUTABLE_SV(hv), 0, PERL_MAGIC_rhash, 0, 0, ph)) - Perl_die(aTHX_ "panic: hv_placeholders_set"); + if (!sv_magicext(MUTABLE_SV(hv), 0, PERL_MAGIC_rhash, 0, 0, ph)) + Perl_die(aTHX_ "panic: hv_placeholders_set"); } /* else we don't need to add magic to record 0 placeholders. */ } @@ -3208,34 +3208,34 @@ S_refcounted_he_value(pTHX_ const struct refcounted_he *he) switch(he->refcounted_he_data[0] & HVrhek_typemask) { case HVrhek_undef: - value = newSV(0); - break; + value = newSV(0); + break; case HVrhek_delete: - value = &PL_sv_placeholder; - break; + value = &PL_sv_placeholder; + break; case HVrhek_IV: - value = newSViv(he->refcounted_he_val.refcounted_he_u_iv); - break; + value = newSViv(he->refcounted_he_val.refcounted_he_u_iv); + break; case HVrhek_UV: - value = newSVuv(he->refcounted_he_val.refcounted_he_u_uv); - break; + value = newSVuv(he->refcounted_he_val.refcounted_he_u_uv); + break; case HVrhek_PV: case HVrhek_PV_UTF8: - /* Create a string SV that directly points to the bytes in our - structure. */ - value = newSV_type(SVt_PV); - SvPV_set(value, (char *) he->refcounted_he_data + 1); - SvCUR_set(value, he->refcounted_he_val.refcounted_he_u_len); - /* This stops anything trying to free it */ - SvLEN_set(value, 0); - SvPOK_on(value); - SvREADONLY_on(value); - if ((he->refcounted_he_data[0] & HVrhek_typemask) == HVrhek_PV_UTF8) - SvUTF8_on(value); - break; + /* Create a string SV that directly points to the bytes in our + structure. */ + value = newSV_type(SVt_PV); + SvPV_set(value, (char *) he->refcounted_he_data + 1); + SvCUR_set(value, he->refcounted_he_val.refcounted_he_u_len); + /* This stops anything trying to free it */ + SvLEN_set(value, 0); + SvPOK_on(value); + SvREADONLY_on(value); + if ((he->refcounted_he_data[0] & HVrhek_typemask) == HVrhek_PV_UTF8) + SvUTF8_on(value); + break; default: - Perl_croak(aTHX_ "panic: refcounted_he_value bad flags %" UVxf, - (UV)he->refcounted_he_data[0]); + Perl_croak(aTHX_ "panic: refcounted_he_value bad flags %" UVxf, + (UV)he->refcounted_he_data[0]); } return value; } @@ -3256,8 +3256,8 @@ Perl_refcounted_he_chain_2hv(pTHX_ const struct refcounted_he *chain, U32 flags) U32 placeholders, max; if (flags) - Perl_croak(aTHX_ "panic: refcounted_he_chain_2hv bad flags %" UVxf, - (UV)flags); + Perl_croak(aTHX_ "panic: refcounted_he_chain_2hv bad flags %" UVxf, + (UV)flags); /* We could chase the chain once to get an idea of the number of keys, and call ksplit. But for now we'll make a potentially inefficient @@ -3265,77 +3265,77 @@ Perl_refcounted_he_chain_2hv(pTHX_ const struct refcounted_he *chain, U32 flags) hv = newHV(); max = HvMAX(hv); if (!HvARRAY(hv)) { - char *array; - Newxz(array, PERL_HV_ARRAY_ALLOC_BYTES(max + 1), char); - HvARRAY(hv) = (HE**)array; + char *array; + Newxz(array, PERL_HV_ARRAY_ALLOC_BYTES(max + 1), char); + HvARRAY(hv) = (HE**)array; } placeholders = 0; while (chain) { #ifdef USE_ITHREADS - U32 hash = chain->refcounted_he_hash; + U32 hash = chain->refcounted_he_hash; #else - U32 hash = HEK_HASH(chain->refcounted_he_hek); + U32 hash = HEK_HASH(chain->refcounted_he_hek); #endif - HE **oentry = &((HvARRAY(hv))[hash & max]); - HE *entry = *oentry; - SV *value; - - for (; entry; entry = HeNEXT(entry)) { - if (HeHASH(entry) == hash) { - /* We might have a duplicate key here. If so, entry is older - than the key we've already put in the hash, so if they are - the same, skip adding entry. */ + HE **oentry = &((HvARRAY(hv))[hash & max]); + HE *entry = *oentry; + SV *value; + + for (; entry; entry = HeNEXT(entry)) { + if (HeHASH(entry) == hash) { + /* We might have a duplicate key here. If so, entry is older + than the key we've already put in the hash, so if they are + the same, skip adding entry. */ #ifdef USE_ITHREADS - const STRLEN klen = HeKLEN(entry); - const char *const key = HeKEY(entry); - if (klen == chain->refcounted_he_keylen - && (!!HeKUTF8(entry) - == !!(chain->refcounted_he_data[0] & HVhek_UTF8)) - && memEQ(key, REF_HE_KEY(chain), klen)) - goto next_please; + const STRLEN klen = HeKLEN(entry); + const char *const key = HeKEY(entry); + if (klen == chain->refcounted_he_keylen + && (!!HeKUTF8(entry) + == !!(chain->refcounted_he_data[0] & HVhek_UTF8)) + && memEQ(key, REF_HE_KEY(chain), klen)) + goto next_please; #else - if (HeKEY_hek(entry) == chain->refcounted_he_hek) - goto next_please; - if (HeKLEN(entry) == HEK_LEN(chain->refcounted_he_hek) - && HeKUTF8(entry) == HEK_UTF8(chain->refcounted_he_hek) - && memEQ(HeKEY(entry), HEK_KEY(chain->refcounted_he_hek), - HeKLEN(entry))) - goto next_please; + if (HeKEY_hek(entry) == chain->refcounted_he_hek) + goto next_please; + if (HeKLEN(entry) == HEK_LEN(chain->refcounted_he_hek) + && HeKUTF8(entry) == HEK_UTF8(chain->refcounted_he_hek) + && memEQ(HeKEY(entry), HEK_KEY(chain->refcounted_he_hek), + HeKLEN(entry))) + goto next_please; #endif - } - } - assert (!entry); - entry = new_HE(); + } + } + assert (!entry); + entry = new_HE(); #ifdef USE_ITHREADS - HeKEY_hek(entry) - = share_hek_flags(REF_HE_KEY(chain), - chain->refcounted_he_keylen, - chain->refcounted_he_hash, - (chain->refcounted_he_data[0] - & (HVhek_UTF8|HVhek_WASUTF8))); + HeKEY_hek(entry) + = share_hek_flags(REF_HE_KEY(chain), + chain->refcounted_he_keylen, + chain->refcounted_he_hash, + (chain->refcounted_he_data[0] + & (HVhek_UTF8|HVhek_WASUTF8))); #else - HeKEY_hek(entry) = share_hek_hek(chain->refcounted_he_hek); + HeKEY_hek(entry) = share_hek_hek(chain->refcounted_he_hek); #endif - value = refcounted_he_value(chain); - if (value == &PL_sv_placeholder) - placeholders++; - HeVAL(entry) = value; + value = refcounted_he_value(chain); + if (value == &PL_sv_placeholder) + placeholders++; + HeVAL(entry) = value; - /* Link it into the chain. */ - HeNEXT(entry) = *oentry; - *oentry = entry; + /* Link it into the chain. */ + HeNEXT(entry) = *oentry; + *oentry = entry; - HvTOTALKEYS(hv)++; + HvTOTALKEYS(hv)++; next_please: - chain = chain->refcounted_he_next; + chain = chain->refcounted_he_next; } if (placeholders) { - clear_placeholders(hv, placeholders); - HvTOTALKEYS(hv) -= placeholders; + clear_placeholders(hv, placeholders); + HvTOTALKEYS(hv) -= placeholders; } /* We could check in the loop to see if we encounter any keys with key @@ -3363,38 +3363,38 @@ if there is no value associated with the key. SV * Perl_refcounted_he_fetch_pvn(pTHX_ const struct refcounted_he *chain, - const char *keypv, STRLEN keylen, U32 hash, U32 flags) + const char *keypv, STRLEN keylen, U32 hash, U32 flags) { U8 utf8_flag; PERL_ARGS_ASSERT_REFCOUNTED_HE_FETCH_PVN; if (flags & ~(REFCOUNTED_HE_KEY_UTF8|REFCOUNTED_HE_EXISTS)) - Perl_croak(aTHX_ "panic: refcounted_he_fetch_pvn bad flags %" UVxf, - (UV)flags); + Perl_croak(aTHX_ "panic: refcounted_he_fetch_pvn bad flags %" UVxf, + (UV)flags); if (!chain) - goto ret; + goto ret; if (flags & REFCOUNTED_HE_KEY_UTF8) { - /* For searching purposes, canonicalise to Latin-1 where possible. */ - const char *keyend = keypv + keylen, *p; - STRLEN nonascii_count = 0; - for (p = keypv; p != keyend; p++) { - if (! UTF8_IS_INVARIANT(*p)) { - if (! UTF8_IS_NEXT_CHAR_DOWNGRADEABLE(p, keyend)) { - goto canonicalised_key; + /* For searching purposes, canonicalise to Latin-1 where possible. */ + const char *keyend = keypv + keylen, *p; + STRLEN nonascii_count = 0; + for (p = keypv; p != keyend; p++) { + if (! UTF8_IS_INVARIANT(*p)) { + if (! UTF8_IS_NEXT_CHAR_DOWNGRADEABLE(p, keyend)) { + goto canonicalised_key; } - nonascii_count++; + nonascii_count++; p++; - } - } - if (nonascii_count) { - char *q; - const char *p = keypv, *keyend = keypv + keylen; - keylen -= nonascii_count; - Newx(q, keylen, char); - SAVEFREEPV(q); - keypv = q; - for (; p != keyend; p++, q++) { - U8 c = (U8)*p; + } + } + if (nonascii_count) { + char *q; + const char *p = keypv, *keyend = keypv + keylen; + keylen -= nonascii_count; + Newx(q, keylen, char); + SAVEFREEPV(q); + keypv = q; + for (; p != keyend; p++, q++) { + U8 c = (U8)*p; if (UTF8_IS_INVARIANT(c)) { *q = (char) c; } @@ -3402,35 +3402,35 @@ Perl_refcounted_he_fetch_pvn(pTHX_ const struct refcounted_he *chain, p++; *q = (char) EIGHT_BIT_UTF8_TO_NATIVE(c, *p); } - } - } - flags &= ~REFCOUNTED_HE_KEY_UTF8; - canonicalised_key: ; + } + } + flags &= ~REFCOUNTED_HE_KEY_UTF8; + canonicalised_key: ; } utf8_flag = (flags & REFCOUNTED_HE_KEY_UTF8) ? HVhek_UTF8 : 0; if (!hash) - PERL_HASH(hash, keypv, keylen); + PERL_HASH(hash, keypv, keylen); for (; chain; chain = chain->refcounted_he_next) { - if ( + if ( #ifdef USE_ITHREADS - hash == chain->refcounted_he_hash && - keylen == chain->refcounted_he_keylen && - memEQ(REF_HE_KEY(chain), keypv, keylen) && - utf8_flag == (chain->refcounted_he_data[0] & HVhek_UTF8) + hash == chain->refcounted_he_hash && + keylen == chain->refcounted_he_keylen && + memEQ(REF_HE_KEY(chain), keypv, keylen) && + utf8_flag == (chain->refcounted_he_data[0] & HVhek_UTF8) #else - hash == HEK_HASH(chain->refcounted_he_hek) && - keylen == (STRLEN)HEK_LEN(chain->refcounted_he_hek) && - memEQ(HEK_KEY(chain->refcounted_he_hek), keypv, keylen) && - utf8_flag == (HEK_FLAGS(chain->refcounted_he_hek) & HVhek_UTF8) + hash == HEK_HASH(chain->refcounted_he_hek) && + keylen == (STRLEN)HEK_LEN(chain->refcounted_he_hek) && + memEQ(HEK_KEY(chain->refcounted_he_hek), keypv, keylen) && + utf8_flag == (HEK_FLAGS(chain->refcounted_he_hek) & HVhek_UTF8) #endif - ) { - if (flags & REFCOUNTED_HE_EXISTS) - return (chain->refcounted_he_data[0] & HVrhek_typemask) - == HVrhek_delete - ? NULL : &PL_sv_yes; - return sv_2mortal(refcounted_he_value(chain)); - } + ) { + if (flags & REFCOUNTED_HE_EXISTS) + return (chain->refcounted_he_data[0] & HVrhek_typemask) + == HVrhek_delete + ? NULL : &PL_sv_yes; + return sv_2mortal(refcounted_he_value(chain)); + } } ret: return flags & REFCOUNTED_HE_EXISTS ? NULL : &PL_sv_placeholder; @@ -3447,7 +3447,7 @@ instead of a string/length pair. SV * Perl_refcounted_he_fetch_pv(pTHX_ const struct refcounted_he *chain, - const char *key, U32 hash, U32 flags) + const char *key, U32 hash, U32 flags) { PERL_ARGS_ASSERT_REFCOUNTED_HE_FETCH_PV; return refcounted_he_fetch_pvn(chain, key, strlen(key), hash, flags); @@ -3464,19 +3464,19 @@ string/length pair. SV * Perl_refcounted_he_fetch_sv(pTHX_ const struct refcounted_he *chain, - SV *key, U32 hash, U32 flags) + SV *key, U32 hash, U32 flags) { const char *keypv; STRLEN keylen; PERL_ARGS_ASSERT_REFCOUNTED_HE_FETCH_SV; if (flags & REFCOUNTED_HE_KEY_UTF8) - Perl_croak(aTHX_ "panic: refcounted_he_fetch_sv bad flags %" UVxf, - (UV)flags); + Perl_croak(aTHX_ "panic: refcounted_he_fetch_sv bad flags %" UVxf, + (UV)flags); keypv = SvPV_const(key, keylen); if (SvUTF8(key)) - flags |= REFCOUNTED_HE_KEY_UTF8; + flags |= REFCOUNTED_HE_KEY_UTF8; if (!hash && SvIsCOW_shared_hash(key)) - hash = SvSHARED_HASH(key); + hash = SvSHARED_HASH(key); return refcounted_he_fetch_pvn(chain, keypv, keylen, hash, flags); } @@ -3515,7 +3515,7 @@ C<refcounted_he>. struct refcounted_he * Perl_refcounted_he_new_pvn(pTHX_ struct refcounted_he *parent, - const char *keypv, STRLEN keylen, U32 hash, SV *value, U32 flags) + const char *keypv, STRLEN keylen, U32 hash, SV *value, U32 flags) { STRLEN value_len = 0; const char *value_p = NULL; @@ -3527,49 +3527,49 @@ Perl_refcounted_he_new_pvn(pTHX_ struct refcounted_he *parent, PERL_ARGS_ASSERT_REFCOUNTED_HE_NEW_PVN; if (!value || value == &PL_sv_placeholder) { - value_type = HVrhek_delete; + value_type = HVrhek_delete; } else if (SvPOK(value)) { - value_type = HVrhek_PV; + value_type = HVrhek_PV; } else if (SvIOK(value)) { - value_type = SvUOK((const SV *)value) ? HVrhek_UV : HVrhek_IV; + value_type = SvUOK((const SV *)value) ? HVrhek_UV : HVrhek_IV; } else if (!SvOK(value)) { - value_type = HVrhek_undef; + value_type = HVrhek_undef; } else { - value_type = HVrhek_PV; + value_type = HVrhek_PV; } is_pv = value_type == HVrhek_PV; if (is_pv) { - /* Do it this way so that the SvUTF8() test is after the SvPV, in case - the value is overloaded, and doesn't yet have the UTF-8flag set. */ - value_p = SvPV_const(value, value_len); - if (SvUTF8(value)) - value_type = HVrhek_PV_UTF8; - key_offset = value_len + 2; + /* Do it this way so that the SvUTF8() test is after the SvPV, in case + the value is overloaded, and doesn't yet have the UTF-8flag set. */ + value_p = SvPV_const(value, value_len); + if (SvUTF8(value)) + value_type = HVrhek_PV_UTF8; + key_offset = value_len + 2; } hekflags = value_type; if (flags & REFCOUNTED_HE_KEY_UTF8) { - /* Canonicalise to Latin-1 where possible. */ - const char *keyend = keypv + keylen, *p; - STRLEN nonascii_count = 0; - for (p = keypv; p != keyend; p++) { - if (! UTF8_IS_INVARIANT(*p)) { - if (! UTF8_IS_NEXT_CHAR_DOWNGRADEABLE(p, keyend)) { - goto canonicalised_key; + /* Canonicalise to Latin-1 where possible. */ + const char *keyend = keypv + keylen, *p; + STRLEN nonascii_count = 0; + for (p = keypv; p != keyend; p++) { + if (! UTF8_IS_INVARIANT(*p)) { + if (! UTF8_IS_NEXT_CHAR_DOWNGRADEABLE(p, keyend)) { + goto canonicalised_key; } - nonascii_count++; + nonascii_count++; p++; - } - } - if (nonascii_count) { - char *q; - const char *p = keypv, *keyend = keypv + keylen; - keylen -= nonascii_count; - Newx(q, keylen, char); - SAVEFREEPV(q); - keypv = q; - for (; p != keyend; p++, q++) { - U8 c = (U8)*p; + } + } + if (nonascii_count) { + char *q; + const char *p = keypv, *keyend = keypv + keylen; + keylen -= nonascii_count; + Newx(q, keylen, char); + SAVEFREEPV(q); + keypv = q; + for (; p != keyend; p++, q++) { + U8 c = (U8)*p; if (UTF8_IS_INVARIANT(c)) { *q = (char) c; } @@ -3577,36 +3577,36 @@ Perl_refcounted_he_new_pvn(pTHX_ struct refcounted_he *parent, p++; *q = (char) EIGHT_BIT_UTF8_TO_NATIVE(c, *p); } - } - } - flags &= ~REFCOUNTED_HE_KEY_UTF8; - canonicalised_key: ; + } + } + flags &= ~REFCOUNTED_HE_KEY_UTF8; + canonicalised_key: ; } if (flags & REFCOUNTED_HE_KEY_UTF8) - hekflags |= HVhek_UTF8; + hekflags |= HVhek_UTF8; if (!hash) - PERL_HASH(hash, keypv, keylen); + PERL_HASH(hash, keypv, keylen); #ifdef USE_ITHREADS he = (struct refcounted_he*) - PerlMemShared_malloc(sizeof(struct refcounted_he) - 1 - + keylen - + key_offset); + PerlMemShared_malloc(sizeof(struct refcounted_he) - 1 + + keylen + + key_offset); #else he = (struct refcounted_he*) - PerlMemShared_malloc(sizeof(struct refcounted_he) - 1 - + key_offset); + PerlMemShared_malloc(sizeof(struct refcounted_he) - 1 + + key_offset); #endif he->refcounted_he_next = parent; if (is_pv) { - Copy(value_p, he->refcounted_he_data + 1, value_len + 1, char); - he->refcounted_he_val.refcounted_he_u_len = value_len; + Copy(value_p, he->refcounted_he_data + 1, value_len + 1, char); + he->refcounted_he_val.refcounted_he_u_len = value_len; } else if (value_type == HVrhek_IV) { - he->refcounted_he_val.refcounted_he_u_iv = SvIVX(value); + he->refcounted_he_val.refcounted_he_u_iv = SvIVX(value); } else if (value_type == HVrhek_UV) { - he->refcounted_he_val.refcounted_he_u_uv = SvUVX(value); + he->refcounted_he_val.refcounted_he_u_uv = SvUVX(value); } #ifdef USE_ITHREADS @@ -3634,7 +3634,7 @@ of a string/length pair. struct refcounted_he * Perl_refcounted_he_new_pv(pTHX_ struct refcounted_he *parent, - const char *key, U32 hash, SV *value, U32 flags) + const char *key, U32 hash, SV *value, U32 flags) { PERL_ARGS_ASSERT_REFCOUNTED_HE_NEW_PV; return refcounted_he_new_pvn(parent, key, strlen(key), hash, value, flags); @@ -3651,19 +3651,19 @@ string/length pair. struct refcounted_he * Perl_refcounted_he_new_sv(pTHX_ struct refcounted_he *parent, - SV *key, U32 hash, SV *value, U32 flags) + SV *key, U32 hash, SV *value, U32 flags) { const char *keypv; STRLEN keylen; PERL_ARGS_ASSERT_REFCOUNTED_HE_NEW_SV; if (flags & REFCOUNTED_HE_KEY_UTF8) - Perl_croak(aTHX_ "panic: refcounted_he_new_sv bad flags %" UVxf, - (UV)flags); + Perl_croak(aTHX_ "panic: refcounted_he_new_sv bad flags %" UVxf, + (UV)flags); keypv = SvPV_const(key, keylen); if (SvUTF8(key)) - flags |= REFCOUNTED_HE_KEY_UTF8; + flags |= REFCOUNTED_HE_KEY_UTF8; if (!hash && SvIsCOW_shared_hash(key)) - hash = SvSHARED_HASH(key); + hash = SvSHARED_HASH(key); return refcounted_he_new_pvn(parent, keypv, keylen, hash, value, flags); } @@ -3684,23 +3684,23 @@ Perl_refcounted_he_free(pTHX_ struct refcounted_he *he) { PERL_UNUSED_CONTEXT; while (he) { - struct refcounted_he *copy; - U32 new_count; - - HINTS_REFCNT_LOCK; - new_count = --he->refcounted_he_refcnt; - HINTS_REFCNT_UNLOCK; - - if (new_count) { - return; - } + struct refcounted_he *copy; + U32 new_count; + + HINTS_REFCNT_LOCK; + new_count = --he->refcounted_he_refcnt; + HINTS_REFCNT_UNLOCK; + + if (new_count) { + return; + } #ifndef USE_ITHREADS - unshare_hek_or_pvn (he->refcounted_he_hek, 0, 0, 0); + unshare_hek_or_pvn (he->refcounted_he_hek, 0, 0, 0); #endif - copy = he; - he = he->refcounted_he_next; - PerlMemShared_free(copy); + copy = he; + he = he->refcounted_he_next; + PerlMemShared_free(copy); } } @@ -3719,9 +3719,9 @@ Perl_refcounted_he_inc(pTHX_ struct refcounted_he *he) { PERL_UNUSED_CONTEXT; if (he) { - HINTS_REFCNT_LOCK; - he->refcounted_he_refcnt++; - HINTS_REFCNT_UNLOCK; + HINTS_REFCNT_LOCK; + he->refcounted_he_refcnt++; + HINTS_REFCNT_UNLOCK; } return he; } @@ -3752,29 +3752,29 @@ Perl_cop_fetch_label(pTHX_ COP *const cop, STRLEN *len, U32 *flags) { PERL_UNUSED_CONTEXT; if (!chain) - return NULL; + return NULL; #ifdef USE_ITHREADS if (chain->refcounted_he_keylen != 1) - return NULL; + return NULL; if (*REF_HE_KEY(chain) != ':') - return NULL; + return NULL; #else if ((STRLEN)HEK_LEN(chain->refcounted_he_hek) != 1) - return NULL; + return NULL; if (*HEK_KEY(chain->refcounted_he_hek) != ':') - return NULL; + return NULL; #endif /* Stop anyone trying to really mess us up by adding their own value for ':' into %^H */ if ((chain->refcounted_he_data[0] & HVrhek_typemask) != HVrhek_PV - && (chain->refcounted_he_data[0] & HVrhek_typemask) != HVrhek_PV_UTF8) - return NULL; + && (chain->refcounted_he_data[0] & HVrhek_typemask) != HVrhek_PV_UTF8) + return NULL; if (len) - *len = chain->refcounted_he_val.refcounted_he_u_len; + *len = chain->refcounted_he_val.refcounted_he_u_len; if (flags) { - *flags = ((chain->refcounted_he_data[0] & HVrhek_typemask) - == HVrhek_PV_UTF8) ? SVf_UTF8 : 0; + *flags = ((chain->refcounted_he_data[0] & HVrhek_typemask) + == HVrhek_PV_UTF8) ? SVf_UTF8 : 0; } return chain->refcounted_he_data + 1; } @@ -3791,19 +3791,19 @@ for a UTF-8 label. Any other flag is ignored. void Perl_cop_store_label(pTHX_ COP *const cop, const char *label, STRLEN len, - U32 flags) + U32 flags) { SV *labelsv; PERL_ARGS_ASSERT_COP_STORE_LABEL; if (flags & ~(SVf_UTF8)) - Perl_croak(aTHX_ "panic: cop_store_label illegal flag bits 0x%" UVxf, - (UV)flags); + Perl_croak(aTHX_ "panic: cop_store_label illegal flag bits 0x%" UVxf, + (UV)flags); labelsv = newSVpvn_flags(label, len, SVs_TEMP); if (flags & SVf_UTF8) - SvUTF8_on(labelsv); + SvUTF8_on(labelsv); cop->cop_hints_hash - = refcounted_he_new_pvs(cop->cop_hints_hash, ":", labelsv, 0); + = refcounted_he_new_pvs(cop->cop_hints_hash, ":", labelsv, 0); } /* @@ -3833,47 +3833,47 @@ Perl_hv_assert(pTHX_ HV *hv) (void)hv_iterinit(hv); while ((entry = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS))) { - /* sanity check the values */ - if (HeVAL(entry) == &PL_sv_placeholder) - placeholders++; - else - real++; - /* sanity check the keys */ - if (HeSVKEY(entry)) { - NOOP; /* Don't know what to check on SV keys. */ - } else if (HeKUTF8(entry)) { - withflags++; - if (HeKWASUTF8(entry)) { - PerlIO_printf(Perl_debug_log, - "hash key has both WASUTF8 and UTF8: '%.*s'\n", - (int) HeKLEN(entry), HeKEY(entry)); - bad = 1; - } - } else if (HeKWASUTF8(entry)) - withflags++; + /* sanity check the values */ + if (HeVAL(entry) == &PL_sv_placeholder) + placeholders++; + else + real++; + /* sanity check the keys */ + if (HeSVKEY(entry)) { + NOOP; /* Don't know what to check on SV keys. */ + } else if (HeKUTF8(entry)) { + withflags++; + if (HeKWASUTF8(entry)) { + PerlIO_printf(Perl_debug_log, + "hash key has both WASUTF8 and UTF8: '%.*s'\n", + (int) HeKLEN(entry), HeKEY(entry)); + bad = 1; + } + } else if (HeKWASUTF8(entry)) + withflags++; } if (!SvTIED_mg((const SV *)hv, PERL_MAGIC_tied)) { - static const char bad_count[] = "Count %d %s(s), but hash reports %d\n"; - const int nhashkeys = HvUSEDKEYS(hv); - const int nhashplaceholders = HvPLACEHOLDERS_get(hv); - - if (nhashkeys != real) { - PerlIO_printf(Perl_debug_log, bad_count, real, "keys", nhashkeys ); - bad = 1; - } - if (nhashplaceholders != placeholders) { - PerlIO_printf(Perl_debug_log, bad_count, placeholders, "placeholder", nhashplaceholders ); - bad = 1; - } + static const char bad_count[] = "Count %d %s(s), but hash reports %d\n"; + const int nhashkeys = HvUSEDKEYS(hv); + const int nhashplaceholders = HvPLACEHOLDERS_get(hv); + + if (nhashkeys != real) { + PerlIO_printf(Perl_debug_log, bad_count, real, "keys", nhashkeys ); + bad = 1; + } + if (nhashplaceholders != placeholders) { + PerlIO_printf(Perl_debug_log, bad_count, placeholders, "placeholder", nhashplaceholders ); + bad = 1; + } } if (withflags && ! HvHASKFLAGS(hv)) { - PerlIO_printf(Perl_debug_log, - "Hash has HASKFLAGS off but I count %d key(s) with flags\n", - withflags); - bad = 1; + PerlIO_printf(Perl_debug_log, + "Hash has HASKFLAGS off but I count %d key(s) with flags\n", + withflags); + bad = 1; } if (bad) { - sv_dump(MUTABLE_SV(hv)); + sv_dump(MUTABLE_SV(hv)); } HvRITER_set(hv, riter); /* Restore hash iterator state */ HvEITER_set(hv, eiter); |