diff options
author | David Mitchell <davem@iabyn.com> | 2010-04-25 16:28:41 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2010-04-25 16:39:58 +0100 |
commit | 39cf747a86645fde6898cd6d09d351d50755c2fa (patch) | |
tree | ca3f0f3f8ba67fd92e04fd7ff7e8ed4dec137852 /pp_hot.c | |
parent | 529f008e1350d1b04e9f98427e8b2c8717a80712 (diff) | |
download | perl-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.c | 6 |
1 files changed, 3 insertions, 3 deletions
@@ -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; |