In perl.git, the branch sprout/padlist has been created
<http://perl5.git.perl.org/perl.git/commitdiff/0b0a3951d0f8534ed0dfdd60d324b4795047b930?hp=0000000000000000000000000000000000000000>
at 0b0a3951d0f8534ed0dfdd60d324b4795047b930 (commit)
- Log -----------------------------------------------------------------
commit 0b0a3951d0f8534ed0dfdd60d324b4795047b930
Author: Father Chrysostomos <[email protected]>
Date: Fri Aug 17 13:01:49 2012 -0700
Fix format closure bug with redefined outer sub
CVs close over their outer CVs. So, when you write:
my $x = 52;
sub foo {
sub bar {
sub baz {
$x
}
}
}
bazâs CvOUTSIDE pointer points to bar, barâs CvOUTSIDE points to foo,
and fooâs to the main cv.
When the inner reference to $x is looked up, the CvOUTSIDE chain is
followed, and each subâs pad is looked at to see if it has an $x.
(This happens at compile time.)
It can happen that bar is undefined and then redefined:
undef &bar;
eval 'sub bar { my $x = 34 }';
After this, baz will still refer to the main cvâs $x (52), but, if baz
had âeval '$x'â instead of just $x, it would see the new barâs $x.
(Itâs not really a new bar, as its refaddr is the same, but it has a
new body.)
This particular case is harmless, and is obscure enough that we could
define it any way we want, and it could still be considered correct.
The real problem happens when CVs are cloned.
When a CV is cloned, its name pad already contains the offsets into
the parent pad where the values are to be found. If the outer CV
has been undefined and redefined, those pad offsets can be com-
pletely bogus.
Normally, a CV cannot be cloned except when its outer CV is running.
And the outer CV cannot have been undefined without also throwing
away the op that would have cloned the prototype.
But formats can be cloned when the outer CV is not running. So it
is possible for cloned formats to close over bogus entries in a new
parent pad.
In this example, \$x gives us an array ref. It shows ARRAY(0xbaff1ed)
instead of SCALAR(0xdeafbee):
sub foo {
my $x;
format =
@
($x,warn \$x)[0]
.
}
undef &foo;
eval 'sub foo { my @x; write }';
foo
__END__
And if the offset that the formatâs pad closes over is beyond the end
of the parentâs new pad, we can even get a crash, as in this case:
eval
'sub foo {' .
'{my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p,$q,$r,$s,$t,$u)}'x999
. q|
my $x;
format =
@
($x,warn \$x)[0]
.
}
|;
undef &foo;
eval 'sub foo { my @x; my $x = 34; write }';
foo();
__END__
So now, instead of using CvROOT to identify clones of
CvOUTSIDE(format), we use the padlist ID instead. Padlists donât
actually have an ID, so we give them one. Any time a sub is cloned,
the new padlist gets the same ID as the old. The format needs to
remember what its outer subâs padlist ID was, so we put that in the
padlist struct, too.
M embed.fnc
M embedvar.h
M intrpvar.h
M pad.c
M pad.h
M pp.c
M pp.h
M pp_ctl.c
M proto.h
M t/comp/form_scope.t
M toke.c
commit 026ead2ab416ed171af6a4e11ea95b1f0558c42b
Author: Father Chrysostomos <[email protected]>
Date: Thu Aug 16 23:44:11 2012 -0700
pp_ctl.c:pp_dbstate: Donât adjust CvDEPTH for XSUBs
Commit c127bd3aaa5c5 made XS DB::DB subs work. Before that,
pp_dbstate assumed DB::DB was written it perl. It adjusts CvDEPTH
when calling the XSUB, which serves no purpose. It was presumably
just copied from the pure-Perl-calling code. pp_entersub does-
nât do this.
M pp_ctl.c
commit 38fb29afd227836458ecc7d3da787f7f8fa3223a
Author: Father Chrysostomos <[email protected]>
Date: Thu Aug 16 21:54:53 2012 -0700
[perl #113718] Add inline.h
We can put static inline functions here, and they can depend on
function prototypes and struct definitions from other header
files.
M MANIFEST
A inline.h
M perl.h
commit 364e9f5e6b42bf5993ee3733501c1e41964d5036
Author: Father Chrysostomos <[email protected]>
Date: Thu Aug 16 16:47:38 2012 -0700
Increase $B::Xref::VERSION from 1.03 to 1.04
M ext/B/B/Xref.pm
commit fbab59d2c812c71d4044e660a431cc29ddc9f817
Author: Father Chrysostomos <[email protected]>
Date: Thu Aug 16 16:46:20 2012 -0700
Stop padlists from being AVs
In order to fix a bug, I need to add new fields to padlists. But I
cannot easily do that as long as they are AVs.
So I have created a new padlist struct.
This not only allows me to extend the padlist struct with new members
as necessary, but also saves memory, as we now have a three-pointer
struct where before we had a whole SV head (3-4 pointers) + XPVAV (5
pointers).
This will unfortunately break half of CPAN, but the pad API docs
clearly say this:
NOTE: this function is experimental and may change or be
removed without notice.
This would have broken B::Debug, but a patch sent upstream has already
been integrated into blead with commit 9d2d23d981.
M av.c
M cpan/B-Debug/Debug.pm
M dump.c
M embed.fnc
M embed.h
M ext/B/B.xs
M ext/B/B/Xref.pm
M ext/B/typemap
M ext/XS-APItest/APItest.xs
M pad.c
M pad.h
M perl.h
M proto.h
M sv.c
commit 60bbc8d92b142bf2329b55c81191bb9b99af012b
Author: Father Chrysostomos <[email protected]>
Date: Wed Aug 15 22:27:54 2012 -0700
Use PADLIST in more places
Much code relies on the fact that PADLIST is typedeffed as AV.
PADLIST should be treated as a distinct type. (This also means cast-
ing PADLISTs to AV when passing them to av_fetch.)
M cop.h
M dump.c
M ext/XS-APItest/APItest.xs
M op.c
M pad.c
M pp_ctl.c
M pp_hot.c
M pp_sort.c
M sv.c
M sv.h
commit 2a5ae4c6c9537e61703d2da3e197870bdf55ca8a
Author: Father Chrysostomos <[email protected]>
Date: Wed Aug 15 22:11:46 2012 -0700
Move PAD(LIST) typedefs to perl.h
otherwise they can only be used in some header files.
M pad.h
M perl.h
-----------------------------------------------------------------------
--
Perl5 Master Repository