summaryrefslogtreecommitdiff
path: root/pad.c
diff options
context:
space:
mode:
authorÆvar Arnfjörð Bjarmason <avar@cpan.org>2014-05-07 12:09:40 +0000
committerRicardo Signes <rjbs@cpan.org>2014-05-12 11:02:11 -0400
commitd3f8a934ef964c0f488e9c692275435d8ea2e291 (patch)
treeed55053aa6f348e9bafa9b16832cacfd99e55f1a /pad.c
parentfe39f0d59b87549f2e6cb1df1dfeaa25215b19ab (diff)
downloadperl-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.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/pad.c b/pad.c
index 419b40338d..31282d157d 100644
--- a/pad.c
+++ b/pad.c
@@ -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;
}