summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2010-04-25 16:28:41 +0100
committerDavid Mitchell <davem@iabyn.com>2010-04-25 16:39:58 +0100
commit39cf747a86645fde6898cd6d09d351d50755c2fa (patch)
treeca3f0f3f8ba67fd92e04fd7ff7e8ed4dec137852 /pp_hot.c
parent529f008e1350d1b04e9f98427e8b2c8717a80712 (diff)
downloadperl-39cf747a86645fde6898cd6d09d351d50755c2fa.tar.gz
avoid multiple FETCHes
The fix 2d961f6deff7 for RT #5475 included a mechanism for the early calling of get magic on something like $tied[0]; so that even though the element is used in void context, we still call FETCH. Some people seem to rely on this. However, the call to mg_get() didn't distinguish between a tiedelem member retrieved from a tied array/hash, and a tiedscalar element retrieved from a plain array/hash. In the latter case, the S_GSKIP protection mechanism doesn't apply and a simple $foo = $h{tiedelem} generated two calls to FETCH. Fix this by only calling mg_get() on the element if it came from a *tied* array/hash. A side-effect of this fix is that the following no longer calls FETCH: my @plain_array; tie $plain_array[0], ....; # element 0 is now a tied scalar $plain_array[0]; # void context: no longer calls FETCH. This required one test in op/tie.t to be fixed up, but in general I think this is a reasonable compromise.
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/pp_hot.c b/pp_hot.c
index e1b1e8c1eb..aa038d3469 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -663,7 +663,7 @@ PP(pp_aelemfast)
SV** const svp = av_fetch(av, PL_op->op_private, lval);
SV *sv = (svp ? *svp : &PL_sv_undef);
EXTEND(SP, 1);
- if (!lval && SvGMAGICAL(sv)) /* see note in pp_helem() */
+ if (!lval && SvRMAGICAL(av) && SvGMAGICAL(sv)) /* see note in pp_helem() */
mg_get(sv);
PUSHs(sv);
RETURN;
@@ -1858,7 +1858,7 @@ PP(pp_helem)
* meant the original regex may be out of scope by now. So as a
* compromise, do the get magic here. (The MGf_GSKIP flag will stop it
* being called too many times). */
- if (!lval && SvGMAGICAL(sv))
+ if (!lval && SvRMAGICAL(hv) && SvGMAGICAL(sv))
mg_get(sv);
PUSHs(sv);
RETURN;
@@ -2996,7 +2996,7 @@ PP(pp_aelem)
vivify_ref(*svp, PL_op->op_private & OPpDEREF);
}
sv = (svp ? *svp : &PL_sv_undef);
- if (!lval && SvGMAGICAL(sv)) /* see note in pp_helem() */
+ if (!lval && SvRMAGICAL(av) && SvGMAGICAL(sv)) /* see note in pp_helem() */
mg_get(sv);
PUSHs(sv);
RETURN;