This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
CvOUTSIDE should be strong for lexsub declared in inner pack sub
authorFather Chrysostomos <sprout@cpan.org>
Tue, 4 Sep 2012 04:26:37 +0000 (21:26 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 16 Sep 2012 05:45:07 +0000 (22:45 -0700)
commit1f122f9b83a0a767aa3a264b32482be38722715d
tree66e91e46cb294c3d0b7b8f7311c43fcb28e09d12
parent8d88fe29d7f8e580970ac5a994ba499606884c4c
CvOUTSIDE should be strong for lexsub declared in inner pack sub

PadnameOUTER (SvFAKE) entries in pads of clonable subs contain the
offset in the parent pad where the closed-over entry is to be found.
The pad itself does not reference the outer lexical until the sub is
cloned at run time.

newMYSUB had to account for that by following CvOUTSIDE for
PadnameOUTER entries, to account for cases like this:

    my sub foo;
    my sub bar { sub foo {} }

The sub foo{} definition would have to find the my sub foo declaration
from outside and store the sub there.

That code was not accounting for named package subs, which close over
variables at compile time, so they don’t need (and don’t) store a par-
ent offset.

So outcv would point to bar in this case:

    my sub foo;
    sub bar { sub foo {} }

If outcv matched CvOUTSIDE(foo), then CvOUTSIDE was made weak.

That does not help in cases like this:

    undef *bar;
    {
        my sub foo;
        sub bar { sub foo {} }
    }

If foo has a weak CvOUTSIDE pointer, then it will still point to bar
after bar is freed, which does not help when the sub is cloned and
tries to look at CvROOT(CvOUTSIDE).

If the pad name is marked PadnameOUTER, even if it has no parent pad
index, newMYSUB needs to leave the CvOUTSIDE pointer strongc.

Also, pad_fixup_inner_anons did not account for subs with strong
CvOUTSIDE pointers whose CvOUTSIDE point to the sub whose pad is being
iterated through.
op.c
pad.c
t/cmd/lexsub.t