This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Clone my subs on scope entry
authorFather Chrysostomos <sprout@cpan.org>
Fri, 3 Aug 2012 16:23:15 +0000 (09:23 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 16 Sep 2012 05:45:05 +0000 (22:45 -0700)
commit6d5c21479838db78689e08afd075ef4e9100ef0d
tree44db00c7bbbae895f1e3208ffcd3a43b719373cb
parentfead5351141134064bc3069932e04930bd96eb0e
Clone my subs on scope entry

The pad slot for a my sub now holds a stub with a prototype CV
attached to it by proto magic.

The prototype is cloned on scope entry.  The stub in the pad is used
when cloning, so any code that references the sub before scope entry
will be able to see that stub become defined, making these behave
similarly:

    our $x;
    BEGIN { $x = \&foo }
    sub foo { }

    our $x;
    my sub foo { }
    BEGIN { $x = \&foo }

Constants are currently not cloned, but that may cause bugs in
pad_push.  I’ll have to look into that.

On scope exit, lexical CVs go through leave_scope’s SAVEt_CLEARSV sec-
tion, like lexical variables.  If the sub is referenced elsewhere, it
is abandoned, and its proto magic is stolen and attached to a new stub
stored in the pad.  If the sub is not referenced elsewhere, it is
undefined via cv_undef.

To clone my subs on scope entry, we create a sequence of introcv and
clonecv ops.  See the huge comment in block_end that explains why we
need two separate ops for each CV.

To allow my subs to be defined in inner subs (my sub foo; sub { sub
foo {} }), pad_add_name_pvn and S_pad_findlex now upgrade the entry
for a my sub to a CV to begin with, so that fake entries added to pads
(fake entries are those that reference outer pads) can share the same
CV.  Otherwise newMYSUB would have to add the CV to every pad that
closes over the ‘my sub’ declaration.  newMYSUB no longer throws away
the initial value replacing it with a new one.

Prototypes are not currently visible to sub calls at compile time,
because the lexer sees the empty stub.  A future commit will
solve that.

When I added name heks to CV’s I made mistakes in a few places, by not
turning on the CVf_NAMED flag, or by not clearing the field when free-
ing the hek.  Those code paths were not exercised enough by state
subs, so the problems did not show up till now.  So this commit fixes
those, too.

One of the tests in lexsub.t, involving foreach loops, was incorrect,
and has been fixed.  Another test has been added to the end for a par-
ticular case of state subs closing over my subs that I broke when ini-
tially trying to get sibling my subs to close over each other, before
I had separate introcv and clonecv ops.
12 files changed:
embed.fnc
embed.h
op.c
pad.c
perly.act
perly.h
perly.tab
perly.y
pp.c
proto.h
scope.c
t/cmd/lexsub.t