summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-12-17 23:01:07 -0800
committerFather Chrysostomos <sprout@cpan.org>2011-12-17 23:19:04 -0800
commit8dc99089b7dd2506e907c4344ed28a3206866f37 (patch)
tree2b28cabfeba32d6a8fc290e622a14e7e0a99cc9b /ext
parent8cd0c082aacc4c22b60ef4afdb96e244a082d4c1 (diff)
downloadperl-8dc99089b7dd2506e907c4344ed28a3206866f37.tar.gz
Stop tell($glob_copy) from clearing PL_last_in_gv
This bug is a side effect of rv2gv’s starting to return an incoercible mortal copy of a coercible glob in 5.14: $ perl5.12.4 -le 'open FH, "t/test.pl"; $fh=*FH; tell $fh; print tell' 0 $ perl5.14.0 -le 'open FH, "t/test.pl"; $fh=*FH; tell $fh; print tell' -1 In the first case, tell without arguments is returning the position of the filehandle. In the second case, tell with an explicit argument that happens to be a coercible glob (tell has an implicit rv2gv, so tell $fh is actu- ally tell *$fh) sets PL_last_in_gv to a mortal copy thereof, which is freed at the end of the statement, setting PL_last_in_gv to null. So there is no ‘last used’ handle by the time we get to the tell without arguments. This commit adds a new rv2gv flag that tells it not to copy the glob. By doing it unconditionally on the kidop, this allows tell(*$fh) to work the same way. Let’s hope nobody does tell(*{*$fh}), which will unset PL_last_in_gv because the inner * returns a mortal copy. This whole area is really icky. PL_last_in_gv should be refcounted, but that would cause handles to leak out of scope, breaking programs that rely on the auto-closing ‘feature’.
Diffstat (limited to 'ext')
-rw-r--r--ext/B/B/Concise.pm2
1 files changed, 1 insertions, 1 deletions
diff --git a/ext/B/B/Concise.pm b/ext/B/B/Concise.pm
index cc2c87debb..f3b517ac78 100644
--- a/ext/B/B/Concise.pm
+++ b/ext/B/B/Concise.pm
@@ -612,7 +612,7 @@ $priv{$_}{4} = "DREFed" for (qw(rv2sv rv2av rv2hv));
@{$priv{$_}}{32,64,96} = ("DREFAV", "DREFHV", "DREFSV")
for (qw(rv2gv rv2sv padsv aelem helem));
$priv{$_}{16} = "STATE" for ("padav", "padhv", "padsv");
-$priv{rv2gv}{4} = "NOINIT";
+@{$priv{rv2gv}}{4,16} = qw "NOINIT FAKE";
@{$priv{"entersub"}}{1,4,16,32,64} = qw( INARGS TARG DBG DEREF );
@{$priv{rv2cv}}{1,8,128} = ("CONST","AMPER","NO()");
$priv{"gv"}{32} = "EARLYCV";