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

Reply via email to