X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=hv.c;h=f92e31e4275e97882c51c5a06613c52bab0a74d8;hb=0ab125c1e00cef4eab6989366621d77be6d38567;hp=df6c2d1c02217314df215c5269774f358ae3c16c;hpb=9014280dc8264580f076d4325a59f22a11592058;p=p5sagit%2Fp5-mst-13.2.git diff --git a/hv.c b/hv.c index df6c2d1..f92e31e 100644 --- a/hv.c +++ b/hv.c @@ -133,7 +133,7 @@ Perl_he_dup(pTHX_ HE *e, bool shared, CLONE_PARAMS* param) static void Perl_hv_notallowed(pTHX_ bool is_utf8, const char *key, I32 klen, - const char *keysave) + const char *keysave, const char *msg) { SV *sv = sv_newmortal(); if (key == keysave) { @@ -147,7 +147,7 @@ Perl_hv_notallowed(pTHX_ bool is_utf8, const char *key, I32 klen, if (is_utf8) { SvUTF8_on(sv); } - Perl_croak(aTHX_ "Attempt to access key '%"SVf"' in fixed hash",sv); + Perl_croak(aTHX_ msg, sv); } /* (klen == HEf_SVKEY) is special for MAGICAL hv entries, meaning key slot @@ -266,7 +266,9 @@ Perl_hv_fetch(pTHX_ HV *hv, const char *key, I32 klen, I32 lval) } #endif if (!entry && SvREADONLY(hv)) { - Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave); + Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave, + "Attempt to access disallowed key '%"SVf"' in a fixed hash" + ); } if (lval) { /* gonna assign to this, so it better be there */ sv = NEWSV(61,0); @@ -400,7 +402,9 @@ Perl_hv_fetch_ent(pTHX_ HV *hv, SV *keysv, I32 lval, register U32 hash) } #endif if (!entry && SvREADONLY(hv)) { - Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave); + Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave, + "Attempt to access disallowed key '%"SVf"' in a fixed hash" + ); } if (key != keysave) Safefree(key); @@ -484,11 +488,13 @@ Perl_hv_store(pTHX_ HV *hv, const char *key, I32 klen, SV *val, register U32 has #endif } } + if (is_utf8) { STRLEN tmplen = klen; /* See the note in hv_fetch(). --jhi */ key = (char*)bytes_from_utf8((U8*)key, &tmplen, &is_utf8); klen = tmplen; + HvUTF8KEYS_on((SV*)hv); } if (!hash) @@ -523,7 +529,9 @@ Perl_hv_store(pTHX_ HV *hv, const char *key, I32 klen, SV *val, register U32 has } if (SvREADONLY(hv)) { - Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave); + Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave, + "Attempt to access disallowed key '%"SVf"' to a fixed hash" + ); } entry = new_HE(); @@ -609,8 +617,10 @@ Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash) keysave = key = SvPV(keysv, klen); is_utf8 = (SvUTF8(keysv) != 0); - if (is_utf8) + if (is_utf8) { key = (char*)bytes_from_utf8((U8*)key, &klen, &is_utf8); + HvUTF8KEYS_on((SV*)hv); + } if (!hash) PERL_HASH(hash, key, klen); @@ -644,7 +654,9 @@ Perl_hv_store_ent(pTHX_ HV *hv, SV *keysv, SV *val, register U32 hash) } if (SvREADONLY(hv)) { - Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave); + Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave, + "Attempt to access disallowed key '%"SVf"' to a fixed hash" + ); } entry = new_HE(); @@ -765,12 +777,16 @@ Perl_hv_delete(pTHX_ HV *hv, const char *key, I32 klen, I32 flags) else hv_free_ent(hv, entry); xhv->xhv_keys--; /* HvKEYS(hv)-- */ + if (xhv->xhv_keys == 0) + HvUTF8KEYS_off(hv); xhv->xhv_placeholders--; return Nullsv; } } else if (SvREADONLY(hv) && HeVAL(entry) && SvREADONLY(HeVAL(entry))) { - Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave); + Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave, + "Attempt to delete readonly key '%"SVf"' from a fixed hash" + ); } if (flags & G_DISCARD) @@ -800,11 +816,15 @@ Perl_hv_delete(pTHX_ HV *hv, const char *key, I32 klen, I32 flags) else hv_free_ent(hv, entry); xhv->xhv_keys--; /* HvKEYS(hv)-- */ + if (xhv->xhv_keys == 0) + HvUTF8KEYS_off(hv); } return sv; } if (SvREADONLY(hv)) { - Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave); + Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave, + "Attempt to access disallowed key '%"SVf"' from a fixed hash" + ); } if (key != keysave) @@ -908,11 +928,15 @@ Perl_hv_delete_ent(pTHX_ HV *hv, SV *keysv, I32 flags, U32 hash) else hv_free_ent(hv, entry); xhv->xhv_keys--; /* HvKEYS(hv)-- */ + if (xhv->xhv_keys == 0) + HvUTF8KEYS_off(hv); xhv->xhv_placeholders--; return Nullsv; } else if (SvREADONLY(hv) && HeVAL(entry) && SvREADONLY(HeVAL(entry))) { - Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave); + Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave, + "Attempt to delete readonly key '%"SVf"' from a fixed hash" + ); } if (flags & G_DISCARD) @@ -942,11 +966,15 @@ Perl_hv_delete_ent(pTHX_ HV *hv, SV *keysv, I32 flags, U32 hash) else hv_free_ent(hv, entry); xhv->xhv_keys--; /* HvKEYS(hv)-- */ + if (xhv->xhv_keys == 0) + HvUTF8KEYS_off(hv); } return sv; } if (SvREADONLY(hv)) { - Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave); + Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave, + "Attempt to delete disallowed key '%"SVf"' from a fixed hash" + ); } if (key != keysave) @@ -1446,6 +1474,11 @@ Perl_hv_clear(pTHX_ HV *hv) register XPVHV* xhv; if (!hv) return; + + if(SvREADONLY(hv)) { + Perl_croak(aTHX_ "Attempt to clear a fixed hash"); + } + xhv = (XPVHV*)SvANY(hv); hfreeentries(hv); xhv->xhv_fill = 0; /* HvFILL(hv) = 0 */ @@ -1457,6 +1490,8 @@ Perl_hv_clear(pTHX_ HV *hv) if (SvRMAGICAL(hv)) mg_clear((SV*)hv); + + HvUTF8KEYS_off(hv); } STATIC void