summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2002-05-08 00:13:10 +0100
committerJarkko Hietaniemi <jhi@iki.fi>2002-05-07 22:23:34 +0000
commit8d1f198fe997a3eac9dc901e973cdc46ac8bbdec (patch)
tree07e0eb8e581ea5a539f7a8fcf662bcac98581fbf /pp_hot.c
parent386c44e5c8a5d040bf976283d7be37c363673092 (diff)
downloadperl-8d1f198fe997a3eac9dc901e973cdc46ac8bbdec.tar.gz
correctly unlocalise exists on tied/%ENV
Message-ID: <20020507231310.B4118@fdgroup.com> p4raw-id: //depot/perl@16455
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/pp_hot.c b/pp_hot.c
index f2387b4ce0..98229a2303 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1643,13 +1643,25 @@ PP(pp_helem)
I32 preeminent = 0;
if (SvTYPE(hv) == SVt_PVHV) {
- if (PL_op->op_private & OPpLVAL_INTRO)
+ if (PL_op->op_private & OPpLVAL_INTRO) {
+ MAGIC *mg;
+ HV *stash;
+ /* does the element we're localizing already exist? */
preeminent =
- ( SvRMAGICAL(hv)
- && !mg_find((SV*)hv, PERL_MAGIC_tied)
- && !mg_find((SV*)hv, PERL_MAGIC_env)
- ) ? 1 : hv_exists_ent(hv, keysv, 0);
+ /* can we determine whether it exists? */
+ ( !SvRMAGICAL(hv)
+ || mg_find((SV*)hv, PERL_MAGIC_env)
+ || ( (mg = mg_find((SV*)hv, PERL_MAGIC_tied))
+ /* Try to preserve the existenceness of a tied hash
+ * element by using EXISTS and DELETE if possible.
+ * Fallback to FETCH and STORE otherwise */
+ && (stash = SvSTASH(SvRV(SvTIED_obj((SV*)hv, mg))))
+ && gv_fetchmethod_autoload(stash, "EXISTS", TRUE)
+ && gv_fetchmethod_autoload(stash, "DELETE", TRUE)
+ )
+ ) ? hv_exists_ent(hv, keysv, 0) : 1;
+ }
he = hv_fetch_ent(hv, keysv, lval && !defer, hash);
svp = he ? &HeVAL(he) : 0;
}