diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-09-10 21:59:51 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-09-15 22:45:09 -0700 |
commit | 81df9f6f95225e40ead5e853dadb0bb98be2531b (patch) | |
tree | 422e6242902659e264962b28b8417a89665a1451 /scope.c | |
parent | d2c8bf052f5a8bb99050f6d2418d77151eb4b468 (diff) | |
download | perl-81df9f6f95225e40ead5e853dadb0bb98be2531b.tar.gz |
Move my sub prototype CVs to the pad names
my subs are cloned on scope entry. To make closures work, a stub
stored in the pad (and closed over elsewhere) is cloned into.
But we need somewhere to store the prototype from which the clone is
made. I was attaching the prototype via magic to the stub in the pad,
since the pad is available at run time, but not the pad names.
That leads to lots of little games all over the place to make sure
the prototype isn’t lost when the pad is swiped on scope exit
(SAVEt_CLEARSV in scope.c). We also run the risk of losing it if an
XS module replaces the sub with another.
Instead, we should be storing it with the pad name. The previous com-
mit made the pad names available at run time, so we can move it there
(still stuffed inside a magic box) and delete much code.
This does mean that newMYSUB cannot rely on the behaviour of non-clon-
able subs that close over variables (or subs) immediately. Previ-
ously, we would dig through outer scopes to find the stub in cases
like this:
sub y {
my sub foo;
sub x {
sub {
sub foo { ... }
}
}
}
We would stop at x, which happens to have y’s stub in its pad, so
that’s no problem.
If we attach it to the pad name, we definitely have to dig past x to
get to the pad name in y’s pad.
Usually, immediate closures do not store the parent pad index, since
it will never be used. But now we do need to use it, so we modify the
code in pad.c:S_pad_findlex to set it always for my/state.
Diffstat (limited to 'scope.c')
-rw-r--r-- | scope.c | 14 |
1 files changed, 0 insertions, 14 deletions
@@ -955,8 +955,6 @@ Perl_leave_scope(pTHX_ I32 base) case SVt_PVCV: { SV ** const svp = (SV **)ptr; - MAGIC *mg = SvMAGIC(sv); - MAGIC **tomg = &SvMAGIC(sv); /* Create a stub */ *svp = newSV_type(SVt_PVCV); @@ -965,18 +963,6 @@ Perl_leave_scope(pTHX_ I32 base) assert(CvNAMED(sv)); CvNAME_HEK_set(*svp, share_hek_hek(CvNAME_HEK((CV *)sv))); - - /* Steal magic */ - while (mg) { - if (mg->mg_type == PERL_MAGIC_proto) break; - mg = *(tomg = &mg->mg_moremagic); - } - assert(mg); - *tomg = mg->mg_moremagic; - mg->mg_moremagic = SvMAGIC(*svp); - SvMAGIC(*svp) = mg; - mg_magical(*svp); - mg_magical(sv); break; } default: *(SV**)ptr = newSV(0); break; |