summaryrefslogtreecommitdiff
path: root/hv.c
diff options
context:
space:
mode:
Diffstat (limited to 'hv.c')
-rw-r--r--hv.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/hv.c b/hv.c
index 634d0e63d5..8394a0e5b1 100644
--- a/hv.c
+++ b/hv.c
@@ -426,7 +426,7 @@ S_hv_fetch_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
if (keysv) {
if (SvSMAGICAL(hv) && SvGMAGICAL(hv)
&& !(action & HV_DISABLE_UVAR_XKEY)) {
- keysv = hv_magic_uvar_xkey(hv, keysv, action);
+ keysv = hv_magic_uvar_xkey(hv, keysv, 0, 0, 0, action);
/* 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.
@@ -966,10 +966,10 @@ S_hv_delete_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
if (!hv)
return NULL;
+ if (SvSMAGICAL(hv) && SvGMAGICAL(hv)
+ && !(d_flags & HV_DISABLE_UVAR_XKEY))
+ keysv = hv_magic_uvar_xkey(hv, keysv, key, klen, k_flags, HV_DELETE);
if (keysv) {
- if (SvSMAGICAL(hv) && SvGMAGICAL(hv)
- && !(d_flags & HV_DISABLE_UVAR_XKEY))
- keysv = hv_magic_uvar_xkey(hv, keysv, HV_DELETE);
if (k_flags & HVhek_FREEKEY)
Safefree(key);
key = SvPV_const(keysv, klen);
@@ -2533,13 +2533,21 @@ S_share_hek_flags(pTHX_ const char *str, I32 len, register U32 hash, int flags)
}
STATIC SV *
-S_hv_magic_uvar_xkey(pTHX_ HV* hv, SV* keysv, int action)
+S_hv_magic_uvar_xkey(pTHX_ HV* hv, SV* keysv, const char *const key,
+ const STRLEN klen, const int k_flags, int action)
{
MAGIC* mg;
if ((mg = mg_find((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 = sv_2mortal(newSVpvn(key, klen));
+ if (k_flags & HVhek_UTF8)
+ SvUTF8_on(keysv);
+ }
+
mg->mg_obj = keysv; /* pass key */
uf->uf_index = action; /* pass action */
magic_getuvar((SV*)hv, mg);