pad_free(): don't clear SVs_PADSTALE
authorDavid Mitchell <davem@iabyn.com>
Tue, 25 Sep 2012 11:47:51 +0000 (12:47 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sat, 10 Nov 2012 13:39:31 +0000 (13:39 +0000)
pad_free() clears the SVs_PADTMP bit. Since that bit is now shared
with SVs_PADSTALE, that gets cleared on state vars. It didn't matter up
till now, but the next commit will start optimising away pad ops, and
op_null() will call pad_free() which would clear the SVs_PADSTALE bit.

So only clear SVs_PADTMP/SVs_PADSTALE for non-lexical var ops.

pad.c

diff --git a/pad.c b/pad.c
index 258b39e..2292aaf 100644 (file)
--- a/pad.c
+++ b/pad.c
@@ -1810,6 +1810,7 @@ void
 Perl_pad_free(pTHX_ PADOFFSET po)
 {
     dVAR;
+    SV *sv;
     ASSERT_CURPAD_LEGAL("pad_free");
     if (!PL_curpad)
        return;
@@ -1824,9 +1825,11 @@ Perl_pad_free(pTHX_ PADOFFSET po)
            PTR2UV(PL_comppad), PTR2UV(PL_curpad), (long)po)
     );
 
-    if (PL_curpad[po] && PL_curpad[po] != &PL_sv_undef) {
-       SvFLAGS(PL_curpad[po]) &= ~SVs_PADTMP; /* also clears SVs_PADSTALE */
-    }
+
+    sv = PL_curpad[po];
+    if (sv && sv != &PL_sv_undef && !SvPADMY(sv))
+       SvFLAGS(sv) &= ~SVs_PADTMP;
+
     if ((I32)po < PL_padix)
        PL_padix = po - 1;
 }