This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make pad_fixup_inner_anons cope with closed-over subs
authorFather Chrysostomos <sprout@cpan.org>
Sun, 8 Jul 2012 21:18:43 +0000 (14:18 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 16 Sep 2012 05:45:00 +0000 (22:45 -0700)
commit09a30bc412a109bcf4b748fa122483d380fcc8b6
treed413760840ad37b3cf7f937233dcb7c089e7611d
parent7d2057d821be137073b284c6ce586dfd519fd13b
Make pad_fixup_inner_anons cope with closed-over subs

When a sub starts being parsed, a new CV is created.  When it fin-
ishes, it is stored in its final location.  If there is a stub there
already, the pad is copied to the stub and the body attached thereto.

Since there may be closures inside the sub whose CvOUTSIDE
pointers point to the temporary CV used during compilation,
pad_fixup_inner_anons is called, to reassign all those
CvOUTSIDE pointers.

This happens in cases like this:

    sub f;
    sub f { sub { } }

When a sub closes over a lexical item in an outer sub, the inner sub
gets its own pad entry with the same value as the outer pad entry.

This means that, now that we have lexical subs (currently just state
subs), we can end up with a pad entry (&s) holding a sub whose
CvOUTSIDE does not point to the sub (f) that owns the pad:

    state sub s { }
    sub f { s() }

If the f sub has to reuse a stub, then pad_fixup_inner_anons gets to
see that, and complains bitterly:

$ ./perl -Ilib -E 'state sub s; sub f; sub f { s() }'
Assertion failed: (CvOUTSIDE(innercv) == old_cv), function Perl_pad_fixup_inner_anons, file pad.c, line 2095.
Abort trap
pad.c
t/cmd/lexsub.t