summaryrefslogtreecommitdiff
path: root/pad.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-08-19 23:17:08 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-08-20 12:50:00 -0700
commit3a6ce63afe9bfc9bf645e0c127824d8426a7ee67 (patch)
tree6a994506662ea1964fea6cddf3afc61f994ca276 /pad.c
parent25451ceff7e8f05c501ecc72a1b3536005f391f7 (diff)
downloadperl-3a6ce63afe9bfc9bf645e0c127824d8426a7ee67.tar.gz
Fix skip logic in pad_tidy and cv_clone
Commit 325e1816dc changed the logic for determining whether a pad entry is to be treated like a constant; i.e., shared between recursion levels and sub clones. According the old logic, a pad entry must be shared if it is marked READONLY or is a shared hash key scalar. According to the new logic, the entry must be shared if the pad name has a zero-length PV (i.e., &PL_sv_no). Two pieces of code were still following the old logic. Changing them fixes this old bug: my $close_over_me; sub { () = $close_over_me; open my $fh, "/dev/null"; print "$$fh\n" }->(); __END__ Output: *main:: The name attached to the implicit rv2gv op in open() was not being copied by sub clones. The previous commit is also part of the fix. In the tests, I tested the combination of sub cloning and recursion, since it seemed like a good idea (and also as a result of copying and pasting :-). S_pmtrans was still relying on the old logic, so it gets changed, too.
Diffstat (limited to 'pad.c')
-rw-r--r--pad.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/pad.c b/pad.c
index d2b6c4fd81..d8d9322c60 100644
--- a/pad.c
+++ b/pad.c
@@ -1773,16 +1773,16 @@ Perl_pad_tidy(pTHX_ padtidy_type type)
for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
SV *namesv;
- if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]) || IS_PADCONST(PL_curpad[ix]))
- continue;
/*
* The only things that a clonable function needs in its
- * pad are anonymous subs.
+ * pad are anonymous subs, constants and GVs.
* The rest are created anew during cloning.
*/
+ if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]))
+ continue;
if (!((namesv = namep[ix]) != NULL &&
- namesv != &PL_sv_undef &&
- *SvPVX_const(namesv) == '&'))
+ PadnamePV(namesv) &&
+ (!PadnameLEN(namesv) || *SvPVX_const(namesv) == '&')))
{
SvREFCNT_dec(PL_curpad[ix]);
PL_curpad[ix] = NULL;
@@ -2120,7 +2120,7 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside, bool newcv)
SvPADSTALE_on(sv);
}
}
- else if (IS_PADGV(ppad[ix]) || IS_PADCONST(ppad[ix])) {
+ else if (IS_PADGV(ppad[ix]) || (namesv && PadnamePV(namesv))) {
sv = SvREFCNT_inc_NN(ppad[ix]);
}
else {