summaryrefslogtreecommitdiff
path: root/pad.c
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2010-02-26 09:18:44 +0000
committerNicholas Clark <nick@ccl4.org>2010-05-24 15:50:57 +0100
commitadf8f095c5881bcedf07b8e41072f8125e00b5a6 (patch)
tree60fefd15aa87c06d10518762c8a403c21c964155 /pad.c
parent05d04d9c74ee968bace5e063c9ded74f94b3df24 (diff)
downloadperl-adf8f095c5881bcedf07b8e41072f8125e00b5a6.tar.gz
Set PADSTALE on all lexicals at the end of sub creation.
The PADSTALEness of lexicals between the 0th and 1st call to a subroutine is now consistent with the state between the nth and (n + 1)th call. This permits a work around in Perl_padlist_dup() to avoid leaking active pad data into a new thread, whilst still correctly bodging the external references needed by the current ?{} implementation. Fix that, and this can be removed.
Diffstat (limited to 'pad.c')
-rw-r--r--pad.c27
1 files changed, 25 insertions, 2 deletions
diff --git a/pad.c b/pad.c
index cc2ade250e..8015154bf3 100644
--- a/pad.c
+++ b/pad.c
@@ -1305,12 +1305,32 @@ Perl_pad_tidy(pTHX_ padtidy_type type)
}
if (type == padtidy_SUB || type == padtidy_FORMAT) {
+ SV * const * const namep = AvARRAY(PL_comppad_name);
PADOFFSET ix;
for (ix = AvFILLp(PL_comppad); ix > 0; ix--) {
if (SvIMMORTAL(PL_curpad[ix]) || IS_PADGV(PL_curpad[ix]) || IS_PADCONST(PL_curpad[ix]))
continue;
- if (!SvPADMY(PL_curpad[ix]))
+ if (!SvPADMY(PL_curpad[ix])) {
SvPADTMP_on(PL_curpad[ix]);
+ } else if (!SvFAKE(namep[ix])) {
+ /* This is a work around for how the current implementation of
+ ?{ } blocks in regexps interacts with lexicals.
+
+ One of our lexicals.
+ Can't do this on all lexicals, otherwise sub baz() won't
+ compile in
+
+ my $foo;
+
+ sub bar { ++$foo; }
+
+ sub baz { ++$foo; }
+
+ because completion of compiling &bar calling pad_tidy()
+ would cause (top level) $foo to be marked as stale, and
+ "no longer available". */
+ SvPADSTALE_on(PL_curpad[ix]);
+ }
}
}
PL_curpad = AvARRAY(PL_comppad);
@@ -1816,7 +1836,10 @@ Perl_padlist_dup(pTHX_ AV *const srcpad, CLONE_PARAMS *const param)
pad1a[ix] = sv_dup_inc(oldpad[ix], param);
}
else { /* our own lexical */
- if(SvREFCNT(oldpad[ix]) > 1) {
+ if(SvPADSTALE(oldpad[ix]) && SvREFCNT(oldpad[ix]) > 1) {
+ /* This is a work around for how the current
+ implementation of ?{ } blocks in regexps
+ interacts with lexicals. */
pad1a[ix] = sv_dup_inc(oldpad[ix], param);
} else {
SV *sv;