diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-09-14 22:08:19 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-09-14 22:29:47 -0700 |
commit | cbacc9aa064469dbad90cdce51a3e7abbdf202be (patch) | |
tree | 0d7b9b54a5835f238c8439e291501b8ff77b30ff /pad.c | |
parent | 37b0b3b2e3fecf62fbb5a9c784ad24707e8d3581 (diff) | |
download | perl-cbacc9aa064469dbad90cdce51a3e7abbdf202be.tar.gz |
[perl #114888] Localise PL_comppad_name in cv_clone
In 9ef8d56 I made closures share their pad name lists, and not just
the names themselves, for speed (no need to SvREFCNT_inc each name and
copy the list).
To make that work, I had to set PL_comppad_name in cv_clone, before
the pad_new call. But I failed to move the PL_comppad_name localisa-
tion from pad_new to cv_clone.
So cv_clone would merrily clobber the previous value of
PL_comppad_name *before* localising it.
This only manifested itself in source filters. Most of the time,
pp_anoncode is called at run time when either no code is being com-
piled (PL_comppad_name is only used at compile time) or inside a
BEGIN block which itself localises PL_comppad_name. But inside a
Filter::Util::Call source filter there was no buffer like that to
protect it.
This meant that pad name creation (my $x) would create the name in the
PL_comppad_name belonging to the last-cloned sub. A subsequent name
lookup ($x) would look in the correct place, as it uses the moral
equivalent of PadlistNAMES(CvPADLIST(PL_compcv)), not PL_comppad_name.
So it would not find it, resulting in a global variable or a stricture
violation.
Diffstat (limited to 'pad.c')
-rw-r--r-- | pad.c | 3 |
1 files changed, 2 insertions, 1 deletions
@@ -247,8 +247,8 @@ Perl_pad_new(pTHX_ int flags) if (flags & padnew_SAVE) { SAVECOMPPAD(); - SAVESPTR(PL_comppad_name); if (! (flags & padnew_CLONE)) { + SAVESPTR(PL_comppad_name); SAVEI32(PL_padix); SAVEI32(PL_comppad_name_fill); SAVEI32(PL_min_intro_pending); @@ -2004,6 +2004,7 @@ Perl_cv_clone(pTHX_ CV *proto) if (SvMAGIC(proto)) mg_copy((SV *)proto, (SV *)cv, 0, 0); + SAVESPTR(PL_comppad_name); PL_comppad_name = protopad_name; CvPADLIST(cv) = pad_new(padnew_CLONE|padnew_SAVE); CvPADLIST(cv)->xpadl_id = protopadlist->xpadl_id; |