avoid multiple FETCHes
authorDavid Mitchell <davem@iabyn.com>
Sun, 25 Apr 2010 15:28:41 +0000 (16:28 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sun, 25 Apr 2010 15:39:58 +0000 (16:39 +0100)
commit39cf747a86645fde6898cd6d09d351d50755c2fa
treeca3f0f3f8ba67fd92e04fd7ff7e8ed4dec137852
parent529f008e1350d1b04e9f98427e8b2c8717a80712
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.
pp_hot.c
t/op/tie.t