In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/6dfba0aae8f42f8476fe450e6197024c9bd7a30e?hp=c263379c498269adb3a24d6d48aec4e822fde5c7>
- Log ----------------------------------------------------------------- commit 6dfba0aae8f42f8476fe450e6197024c9bd7a30e Author: Father Chrysostomos <[email protected]> Date: Sun Nov 16 18:31:09 2014 -0800 Manually revert âRemove SvREADONLY_on from op.c:op_const_svâ This effectively reverts d0a32af375ac806258a97cce0091ce4b3636f8dc. It was wrong. And I should know that, too. I was the one who implemented padtmp swiping and went around turning on the read-only flag to make it work correctly. This fails, because the second call to &$sub returns undef, its value having been stolen by the $y assignment. use Test::More tests=>1; my $sub = sub { my $x = "x"x2000; sub () {$x}; }->(); $y = &$sub; $z = &$sub; is $z, $y; M pad.c M t/op/const-optree.t commit 82e85a9ce986972c02dda51b9fa63d84843ec468 Author: Father Chrysostomos <[email protected]> Date: Sun Nov 16 18:23:34 2014 -0800 Fix assert fail with my $x; sub() {$x} If $x is not referenced or used in lvalue context elsewhere, then the constant sub can actually share the same scalar as the enclosing subâs pad. It doesnât need to copy. And we donât in that case, as of v5.21.5-421-g04472a8. But we need to make sure the PADTMP flag is turned off at scope exit if the pad has the only reference to the sub. (The PADTMP flag has been turned on as of v5.21.5-391-g5543332.) M scope.c M t/op/const-optree.t ----------------------------------------------------------------------- Summary of changes: pad.c | 1 + scope.c | 1 + t/op/const-optree.t | 17 ++++++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/pad.c b/pad.c index 1533ec5..c9e16e5 100644 --- a/pad.c +++ b/pad.c @@ -2239,6 +2239,7 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, bool newcv) /* If the lexical is not used elsewhere, it is safe to turn on SvPADTMP, since it is only when it is used in lvalue con- text that the difference is observable. */ + SvREADONLY_on(const_sv); SvPADTMP_on(const_sv); SvREFCNT_dec_NN(cv); cv = newCONSTSUB(CvSTASH(proto), NULL, const_sv); diff --git a/scope.c b/scope.c index 43e2e03..8e13071 100644 --- a/scope.c +++ b/scope.c @@ -1076,6 +1076,7 @@ Perl_leave_scope(pTHX_ I32 base) SvFLAGS(sv) &=~ (SVf_OK|SVf_IVisUV|SVf_UTF8); break; } + SvPADTMP_off(sv); SvPADSTALE_on(sv); /* mark as no longer live */ } else { /* Someone has a claim on this, so abandon it. */ diff --git a/t/op/const-optree.t b/t/op/const-optree.t index aa5bee6..bd47064 100644 --- a/t/op/const-optree.t +++ b/t/op/const-optree.t @@ -8,7 +8,7 @@ BEGIN { require './test.pl'; @INC = '../lib'; } -plan 166; +plan 168; # @tests is an array of hash refs, each of which can have various keys: # @@ -476,3 +476,18 @@ for \%_ (@tests) { &{$_{finally} or next} } + +# This used to fail an assertion in leave_scope. For some reason, it did +# not fail within the framework above. +sub { my $x = "x"; my $sub = sub () { $x }; undef $sub; } ->(); +pass("No assertion failure when turning on PADSTALE on lexical shared by" + ." erstwhile constant"); + +{ + my $sub = sub { + my $x = "x"x2000; sub () {$x}; + }->(); + $y = &$sub; + $z = &$sub; + is $z, $y, 'inlinable sub ret vals are not swipable'; +} -- Perl5 Master Repository
