diff options
author | Ævar Arnfjörð Bjarmason <avar@cpan.org> | 2014-05-07 12:09:40 +0000 |
---|---|---|
committer | Ricardo Signes <rjbs@cpan.org> | 2014-05-12 11:02:11 -0400 |
commit | d3f8a934ef964c0f488e9c692275435d8ea2e291 (patch) | |
tree | ed55053aa6f348e9bafa9b16832cacfd99e55f1a /pad.c | |
parent | fe39f0d59b87549f2e6cb1df1dfeaa25215b19ab (diff) | |
download | perl-d3f8a934ef964c0f488e9c692275435d8ea2e291.tar.gz |
Revert "[perl #79908] Stop sub inlining from breaking closures"
This reverts commit 137da2b05b4b7628115049f343163bdaf2c30dbb. See the
"How about having a recommended way to add constant subs dynamically?"
thread on perl5-porters, specifically while it sucks that we have this
bug, it's been documented to work this way since 5.003 in "Constant
Functions" in perlsub:
If the result after optimization and constant folding is either a
constant or a lexically-scoped scalar which has no other references,
then it will be used in place of function calls made without C<&>
-- http://perldoc.perl.org/perlsub.html#Constant-Functions
Since we've had this documented bug for a long time we should introduce
this fix in a deprecation cycle rather than silently slowing down code
that assumes it's going to be optimized by constant folding.
I didn't revert the tests it t/op/sub.t, but turned them into TODO tests
instead.
Conflicts:
t/op/sub.t
Diffstat (limited to 'pad.c')
-rw-r--r-- | pad.c | 19 |
1 files changed, 19 insertions, 0 deletions
@@ -2197,6 +2197,25 @@ S_cv_clone(pTHX_ CV *proto, CV *cv, CV *outside) cv_dump(cv, "To"); ); + if (CvCONST(cv)) { + /* Constant sub () { $x } closing over $x - see lib/constant.pm: + * The prototype was marked as a candiate for const-ization, + * so try to grab the current const value, and if successful, + * turn into a const sub: + */ + SV* const const_sv = op_const_sv(CvSTART(cv), cv); + if (const_sv) { + SvREFCNT_dec_NN(cv); + /* For this calling case, op_const_sv returns a *copy*, which we + donate to newCONSTSUB. Yes, this is ugly, and should be killed. + Need to fix how lib/constant.pm works to eliminate this. */ + cv = newCONSTSUB(CvSTASH(proto), NULL, const_sv); + } + else { + CvCONST_off(cv); + } + } + return cv; } |