diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-09-04 10:24:57 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-09-15 22:45:07 -0700 |
commit | 9ccc915ef51db520896c2ca075446d61eaef1870 (patch) | |
tree | 0548a7d500e95a2d38466bc86a6c134bf1515850 /pad.c | |
parent | 1f122f9b83a0a767aa3a264b32482be38722715d (diff) | |
download | perl-9ccc915ef51db520896c2ca075446d61eaef1870.tar.gz |
In cv_clone, use pad ID to identify mysub outside
This code prints ARRAY(0x802e10), whereas it should print
SCALAR(0xfedbee):
undef &bar;
eval 'sub bar { my @x }';
{
my sub foo;
foo();
sub bar {
CORE::state $x;
sub foo { warn \$x }
}
}
The foo sub has a strong CvOUTSIDE pointer, but what it points to
can still be undefined and redefined. So we need to identify it
by its pad.
Diffstat (limited to 'pad.c')
-rw-r--r-- | pad.c | 12 |
1 files changed, 8 insertions, 4 deletions
@@ -1980,8 +1980,14 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside) if (SvTYPE(proto) == SVt_PVCV) { outside = find_runcv(NULL); - if (!CvANON(proto) && CvROOT(outside) != CvROOT(CvOUTSIDE(proto))) - outside = CvOUTSIDE(proto); + if (!CvANON(proto)) { + if (!CvPADLIST(outside) || + CvPADLIST(outside)->xpadl_id != protopadlist->xpadl_outid) + outside = CvOUTSIDE(proto); + if (!CvPADLIST(outside) || + CvPADLIST(outside)->xpadl_id != protopadlist->xpadl_outid) + outside = NULL; + } } else { outside = CvOUTSIDE(proto); @@ -1998,7 +2004,6 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside) depth = outside ? CvDEPTH(outside) : 0; if (!depth) depth = 1; - assert(SvTYPE(proto) == SVt_PVFM || CvPADLIST(outside)); ENTER; SAVESPTR(PL_compcv); @@ -2019,7 +2024,6 @@ S_cv_clone_pad(pTHX_ CV *proto, CV *cv, CV *outside) outpad = outside && CvPADLIST(outside) ? AvARRAY(PadlistARRAY(CvPADLIST(outside))[depth]) : NULL; - assert(outpad || SvTYPE(cv) == SVt_PVFM); if (outpad) CvPADLIST(cv)->xpadl_outid = CvPADLIST(outside)->xpadl_id; for (ix = fpad; ix > 0; ix--) { |