summaryrefslogtreecommitdiff
path: root/dist/constant
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-06-28 01:27:48 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-07-25 23:48:01 -0700
commit94d5c1748d4becd9d5dc21c90a0cae02d399076d (patch)
tree874cd8cb05cc13e86fd2f378cb856111b7bfed1e /dist/constant
parent82c2360886b2bdf906710e9ba6b5639cece80e9f (diff)
downloadperl-94d5c1748d4becd9d5dc21c90a0cae02d399076d.tar.gz
Stop constant.pm from (ab)using subs for scalars
under versions that support $::{foo} = \1. This changes no behaviour. Future commits will change the way sub(){42} and sub(){$forty_two} work. (The former will return a muta- ble value; the latter will not be inlined at all.)
Diffstat (limited to 'dist/constant')
-rw-r--r--dist/constant/lib/constant.pm34
1 files changed, 25 insertions, 9 deletions
diff --git a/dist/constant/lib/constant.pm b/dist/constant/lib/constant.pm
index 035bce2374..dbd1142200 100644
--- a/dist/constant/lib/constant.pm
+++ b/dist/constant/lib/constant.pm
@@ -25,12 +25,19 @@ BEGIN {
# We'd like to do use constant _CAN_PCS => $] > 5.009002
# but that's a bit tricky before we load the constant module :-)
# By doing this, we save 1 run time check for *every* call to import.
- no strict 'refs';
my $const = $] > 5.009002;
- *_CAN_PCS = sub () {$const};
-
my $downgrade = $] < 5.015004; # && $] >= 5.008
- *_DOWNGRADE = sub () { $downgrade };
+ if ($const) {
+ Internals::SvREADONLY($const, 1);
+ Internals::SvREADONLY($downgrade, 1);
+ $constant::{_CAN_PCS} = \$const;
+ $constant::{_DOWNGRADE} = \$downgrade;
+ }
+ else {
+ no strict 'refs';
+ *{"_CAN_PCS"} = sub () {$const};
+ *{"_DOWNGRADE"} = sub () { $downgrade };
+ }
}
#=======================================================================
@@ -128,14 +135,23 @@ sub import {
# The constant serves to optimise this entire block out on
# 5.8 and earlier.
- if (_CAN_PCS && $symtab && !exists $symtab->{$name}) {
- # No typeglob yet, so we can use a reference as space-
- # efficient proxy for a constant subroutine
+ if (_CAN_PCS) {
+ # Use a reference as a proxy for a constant subroutine.
+ # If this is not a glob yet, it saves space. If it is
+ # a glob, we must still create it this way to get the
+ # right internal flags set, as constants are distinct
+ # from subroutines created with sub(){...}.
# The check in Perl_ck_rvconst knows that inlinable
# constants from cv_const_sv are read only. So we have to:
Internals::SvREADONLY($scalar, 1);
- $symtab->{$name} = \$scalar;
- ++$flush_mro;
+ if ($symtab && !exists $symtab->{$name}) {
+ $symtab->{$name} = \$scalar;
+ ++$flush_mro;
+ }
+ else {
+ local $constant::{_dummy} = \$scalar;
+ *$full_name = \&{"_dummy"};
+ }
} else {
*$full_name = sub () { $scalar };
}