X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=hv.c;h=1ae7ad952d8cdd6b265a5cfd5330aee815a24e7c;hb=2f9daededa74ef1264bd2c46743008f84bff0cfc;hp=b25c2e29560d241f1d967b00b76dd620a0100d39;hpb=ff68c7194e176ca1907544a3a65684b76834d0fe;p=p5sagit%2Fp5-mst-13.2.git diff --git a/hv.c b/hv.c index b25c2e2..1ae7ad9 100644 --- a/hv.c +++ b/hv.c @@ -127,7 +127,7 @@ I32 lval; continue; if (HeKLEN(entry) != klen) continue; - if (memcmp(HeKEY(entry),key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; return &HeVAL(entry); } @@ -135,7 +135,7 @@ I32 lval; if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) { char *gotenv; - gotenv = my_getenv(key); + gotenv = ENV_getenv(key); if (gotenv != NULL) { sv = newSVpv(gotenv,strlen(gotenv)); return hv_store(hv,key,klen,sv,hash); @@ -168,20 +168,20 @@ register U32 hash; return 0; if (SvRMAGICAL(hv) && mg_find((SV*)hv,'P')) { - char *k; - HEK *hek; + static HE mh; - New(54, k, HEK_BASESIZE + sizeof(SV*), char); - hek = (HEK*)k; sv = sv_newmortal(); keysv = sv_2mortal(newSVsv(keysv)); mg_copy((SV*)hv, sv, (char*)keysv, HEf_SVKEY); - entry = &He; - HeVAL(entry) = sv; - HeKEY_hek(entry) = hek; - HeSVKEY_set(entry, keysv); - HeKLEN(entry) = HEf_SVKEY; /* hent_key is holding an SV* */ - return entry; + if (!HeKEY_hek(&mh)) { + char *k; + New(54, k, HEK_BASESIZE + sizeof(SV*), char); + HeKEY_hek(&mh) = (HEK*)k; + HeKLEN(&mh) = HEf_SVKEY; /* key will always hold an SV* */ + } + HeSVKEY_set(&mh, keysv); + HeVAL(&mh) = sv; + return &mh; } xhv = (XPVHV*)SvANY(hv); @@ -207,7 +207,7 @@ register U32 hash; continue; if (HeKLEN(entry) != klen) continue; - if (memcmp(HeKEY(entry),key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; return entry; } @@ -215,7 +215,7 @@ register U32 hash; if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) { char *gotenv; - gotenv = my_getenv(key); + gotenv = ENV_getenv(key); if (gotenv != NULL) { sv = newSVpv(gotenv,strlen(gotenv)); return hv_store_ent(hv,keysv,sv,hash); @@ -248,14 +248,14 @@ register U32 hash; xhv = (XPVHV*)SvANY(hv); if (SvMAGICAL(hv)) { mg_copy((SV*)hv, val, key, klen); -#ifndef OVERLOAD - if (!xhv->xhv_array) - return 0; -#else - if (!xhv->xhv_array && (SvMAGIC(hv)->mg_type != 'A' - || SvMAGIC(hv)->mg_moremagic)) - return 0; + if (!xhv->xhv_array + && (SvMAGIC(hv)->mg_moremagic + || (SvMAGIC(hv)->mg_type != 'E' +#ifdef OVERLOAD + && SvMAGIC(hv)->mg_type != 'A' #endif /* OVERLOAD */ + ))) + return 0; } if (!hash) PERL_HASH(hash, key, klen); @@ -271,7 +271,7 @@ register U32 hash; continue; if (HeKLEN(entry) != klen) continue; - if (memcmp(HeKEY(entry),key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; SvREFCNT_dec(HeVAL(entry)); HeVAL(entry) = val; @@ -318,14 +318,14 @@ register U32 hash; if (SvMAGICAL(hv)) { keysv = sv_2mortal(newSVsv(keysv)); mg_copy((SV*)hv, val, (char*)keysv, HEf_SVKEY); -#ifndef OVERLOAD - if (!xhv->xhv_array) - return Nullhe; -#else - if (!xhv->xhv_array && (SvMAGIC(hv)->mg_type != 'A' - || SvMAGIC(hv)->mg_moremagic)) - return Nullhe; + if (!xhv->xhv_array + && (SvMAGIC(hv)->mg_moremagic + || (SvMAGIC(hv)->mg_type != 'E' +#ifdef OVERLOAD + && SvMAGIC(hv)->mg_type != 'A' #endif /* OVERLOAD */ + ))) + return Nullhe; } key = SvPV(keysv, klen); @@ -344,7 +344,7 @@ register U32 hash; continue; if (HeKLEN(entry) != klen) continue; - if (memcmp(HeKEY(entry),key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; SvREFCNT_dec(HeVAL(entry)); HeVAL(entry) = val; @@ -411,7 +411,7 @@ I32 flags; continue; if (HeKLEN(entry) != klen) continue; - if (memcmp(HeKEY(entry),key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; *oentry = HeNEXT(entry); if (i && !*oentry) @@ -423,7 +423,7 @@ I32 flags; if (entry == xhv->xhv_eiter) HvLAZYDEL_on(hv); else - he_free(entry, HvSHAREKEYS(hv)); + he_free(hv, entry); --xhv->xhv_keys; return sv; } @@ -473,7 +473,7 @@ U32 hash; continue; if (HeKLEN(entry) != klen) continue; - if (memcmp(HeKEY(entry),key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; *oentry = HeNEXT(entry); if (i && !*oentry) @@ -485,7 +485,7 @@ U32 hash; if (entry == xhv->xhv_eiter) HvLAZYDEL_on(hv); else - he_free(entry, HvSHAREKEYS(hv)); + he_free(hv, entry); --xhv->xhv_keys; return sv; } @@ -527,7 +527,7 @@ U32 klen; continue; if (HeKLEN(entry) != klen) continue; - if (memcmp(HeKEY(entry),key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; return TRUE; } @@ -574,7 +574,7 @@ U32 hash; continue; if (HeKLEN(entry) != klen) continue; - if (memcmp(HeKEY(entry),key,klen)) /* is this it? */ + if (memNE(HeKEY(entry),key,klen)) /* is this it? */ continue; return TRUE; } @@ -746,17 +746,20 @@ newHV() } void -he_free(hent, shared) +he_free(hv, hent) +HV *hv; register HE *hent; -I32 shared; { if (!hent) return; + if (isGV(HeVAL(hent)) && GvCVu(HeVAL(hent)) && HvNAME(hv)) + sub_generation++; /* may be deletion of method from stash */ SvREFCNT_dec(HeVAL(hent)); if (HeKLEN(hent) == HEf_SVKEY) { SvREFCNT_dec(HeKEY_sv(hent)); Safefree(HeKEY_hek(hent)); - } else if (shared) + } + else if (HvSHAREKEYS(hv)) unshare_hek(HeKEY_hek(hent)); else Safefree(HeKEY_hek(hent)); @@ -764,17 +767,20 @@ I32 shared; } void -he_delayfree(hent, shared) +he_delayfree(hv, hent) +HV *hv; register HE *hent; -I32 shared; { if (!hent) return; + if (isGV(HeVAL(hent)) && GvCVu(HeVAL(hent)) && HvNAME(hv)) + sub_generation++; /* may be deletion of method from stash */ sv_2mortal(HeVAL(hent)); /* free between statements */ if (HeKLEN(hent) == HEf_SVKEY) { sv_2mortal(HeKEY_sv(hent)); Safefree(HeKEY_hek(hent)); - } else if (shared) + } + else if (HvSHAREKEYS(hv)) unshare_hek(HeKEY_hek(hent)); else Safefree(HeKEY_hek(hent)); @@ -808,7 +814,6 @@ HV *hv; register HE *ohent = Null(HE*); I32 riter; I32 max; - I32 shared; if (!hv) return; @@ -819,12 +824,11 @@ HV *hv; max = HvMAX(hv); array = HvARRAY(hv); hent = array[0]; - shared = HvSHAREKEYS(hv); for (;;) { if (hent) { ohent = hent; hent = HeNEXT(hent); - he_free(ohent, shared); + he_free(hv, ohent); } if (!hent) { if (++riter > max) @@ -850,7 +854,7 @@ HV *hv; HvNAME(hv) = 0; } xhv->xhv_array = 0; - xhv->xhv_max = 7; /* it's a normal associative array */ + xhv->xhv_max = 7; /* it's a normal hash */ xhv->xhv_fill = 0; xhv->xhv_keys = 0; @@ -862,14 +866,20 @@ I32 hv_iterinit(hv) HV *hv; { - register XPVHV* xhv = (XPVHV*)SvANY(hv); - HE *entry = xhv->xhv_eiter; + register XPVHV* xhv; + HE *entry; + + if (!hv) + croak("Bad hash"); + xhv = (XPVHV*)SvANY(hv); + entry = xhv->xhv_eiter; #ifdef DYNAMIC_ENV_FETCH /* set up %ENV for iteration */ - if (HvNAME(hv) && strEQ(HvNAME(hv),ENV_HV_NAME)) prime_env_iter(); + if (HvNAME(hv) && strEQ(HvNAME(hv), ENV_HV_NAME)) + prime_env_iter(); #endif if (entry && HvLAZYDEL(hv)) { /* was deleted earlier? */ HvLAZYDEL_off(hv); - he_free(entry, HvSHAREKEYS(hv)); + he_free(hv, entry); } xhv->xhv_riter = -1; xhv->xhv_eiter = Null(HE*); @@ -886,7 +896,7 @@ HV *hv; MAGIC* mg; if (!hv) - croak("Bad associative array"); + croak("Bad hash"); xhv = (XPVHV*)SvANY(hv); oldentry = entry = xhv->xhv_eiter; @@ -936,7 +946,7 @@ HV *hv; if (oldentry && HvLAZYDEL(hv)) { /* was deleted earlier? */ HvLAZYDEL_off(hv); - he_free(oldentry, HvSHAREKEYS(hv)); + he_free(hv, oldentry); } xhv->xhv_eiter = entry; @@ -1045,7 +1055,7 @@ U32 hash; continue; if (HeKLEN(entry) != len) continue; - if (memcmp(HeKEY(entry),str,len)) /* is this it? */ + if (memNE(HeKEY(entry),str,len)) /* is this it? */ continue; found = 1; if (--HeVAL(entry) == Nullsv) { @@ -1092,7 +1102,7 @@ register U32 hash; continue; if (HeKLEN(entry) != len) continue; - if (memcmp(HeKEY(entry),str,len)) /* is this it? */ + if (memNE(HeKEY(entry),str,len)) /* is this it? */ continue; found = 1; break;