Call get-magic once for defined ${...}
authorFather Chrysostomos <sprout@cpan.org>
Wed, 24 Aug 2011 01:15:48 +0000 (18:15 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Wed, 24 Aug 2011 03:06:26 +0000 (20:06 -0700)
This example:

sub TIESCALAR { bless[]}
sub FETCH { warn "fetching"; "\cTAINT" }
tie my $a, "";
defined $$a;

prints ‘fetching’ three times in 5.8.8, five times (!) in 5.10-12,
four times in 5.14, and three times in blead as of ed996e63f6.  Now it
only happens once.

It was commit 7a5fd60d4c that increased the number of fetches in 5.10,
but I haven’t checked which commits reduced it in 5.14.

pp.c
t/op/tie_fetch_count.t

diff --git a/pp.c b/pp.c
index dbe2647..a5691ee 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -286,10 +286,16 @@ Perl_softref2xv(pTHX_ SV *const sv, const char *const what,
     if ((PL_op->op_flags & OPf_SPECIAL) &&
        !(PL_op->op_flags & OPf_MOD))
        {
-           gv = gv_fetchsv(sv, 0, type);
+           STRLEN len;
+           const char * const nambeg = SvPV_nomg_const(sv, len);
+           gv = gv_fetchpvn_flags(nambeg, len, SvUTF8(sv), type);
            if (!gv
                && (!is_gv_magical_sv(sv,0)
-                   || !(gv = gv_fetchsv(sv, GV_ADD, type))))
+                   || !(gv = gv_fetchpvn_flags(
+                         nambeg, len, GV_ADD|SvUTF8(sv), type
+                       ))
+                  )
+              )
                {
                    **spp = &PL_sv_undef;
                    return NULL;
index b6c4d6a..426addb 100644 (file)
@@ -7,7 +7,7 @@ BEGIN {
     chdir 't' if -d 't';
     @INC = '../lib';
     require './test.pl';
-    plan (tests => 216);
+    plan (tests => 217);
 }
 
 use strict;
@@ -195,6 +195,11 @@ $dummy  = &$var5        ; check_count '&{}';
     tie my $var6 => main => "\cOPEN";
     no warnings;
     readdir $var6           ; check_count 'symbolic readdir';
+    if (exists $::{973}) { # Need a different variable here
+       die "*973 already exists. Please adjust this test"
+    }
+    tie my $var7 => main => 973;
+    defined $$var7          ; check_count 'symbolic defined ${}';
 }
 
 ###############################################