Skip to content

Commit

Permalink
Have use VERSION and perl -E import a corresponding use builtin
Browse files Browse the repository at this point in the history
… bundle
  • Loading branch information
leonerd committed Jan 23, 2024
1 parent 39cdd68 commit e5a00b6
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 17 deletions.
13 changes: 7 additions & 6 deletions builtin.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
*/

#include "EXTERN.h"
#define PERL_IN_BUILTIN_C
#include "perl.h"

#include "XSUB.h"
Expand Down Expand Up @@ -39,8 +40,8 @@ static void S_warn_experimental_builtin(pTHX_ const char *name)
/* These three utilities might want to live elsewhere to be reused from other
* code sometime
*/
#define prepare_export_lexical() S_prepare_export_lexical(aTHX)
static void S_prepare_export_lexical(pTHX)
void
Perl_prepare_export_lexical(pTHX)
{
assert(PL_compcv);

Expand All @@ -59,8 +60,8 @@ static void S_export_lexical(pTHX_ SV *name, SV *sv)
PL_curpad[off] = SvREFCNT_inc(sv);
}

#define finish_export_lexical() S_finish_export_lexical(aTHX)
static void S_finish_export_lexical(pTHX)
void
Perl_finish_export_lexical(pTHX)
{
intro_my();

Expand Down Expand Up @@ -603,8 +604,8 @@ static bool S_cv_is_builtin(pTHX_ CV *cv)
return file && strEQ(file, __FILE__);
}

#define import_builtin_bundle(ver, do_unimport) S_import_builtin_bundle(aTHX_ ver, do_unimport)
static void S_import_builtin_bundle(pTHX_ U16 ver, bool do_unimport)
void
Perl_import_builtin_bundle(pTHX_ U16 ver, bool do_unimport)
{
SV *ampname = sv_newmortal();

Expand Down
7 changes: 7 additions & 0 deletions embed.fnc
Original file line number Diff line number Diff line change
Expand Up @@ -4076,6 +4076,13 @@ i |bool |PerlEnv_putenv |NN char *str
#if defined(PERL_IN_AV_C)
S |MAGIC *|get_aux_mg |NN AV *av
#endif
#if defined(PERL_IN_BUILTIN_C) || defined(PERL_IN_OP_C)
p |void |finish_export_lexical
p |void |import_builtin_bundle \
|U16 ver \
|bool do_unimport
p |void |prepare_export_lexical
#endif
#if defined(PERL_IN_CLASS_C) || defined(PERL_IN_OP_C) || \
defined(PERL_IN_PAD_C) || defined(PERL_IN_PERLY_C) || \
defined(PERL_IN_TOKE_C)
Expand Down
5 changes: 5 additions & 0 deletions embed.h
Original file line number Diff line number Diff line change
Expand Up @@ -1199,6 +1199,11 @@
# if defined(PERL_IN_AV_C)
# define get_aux_mg(a) S_get_aux_mg(aTHX_ a)
# endif
# if defined(PERL_IN_BUILTIN_C) || defined(PERL_IN_OP_C)
# define finish_export_lexical() Perl_finish_export_lexical(aTHX)
# define import_builtin_bundle(a,b) Perl_import_builtin_bundle(aTHX_ a,b)
# define prepare_export_lexical() Perl_prepare_export_lexical(aTHX)
# endif
# if defined(PERL_IN_CLASS_C) || defined(PERL_IN_GLOBALS_C) || \
defined(PERL_IN_OP_C) || defined(PERL_IN_PEEP_C)
# define ck_anoncode(a) Perl_ck_anoncode(aTHX_ a)
Expand Down
10 changes: 10 additions & 0 deletions op.c
Original file line number Diff line number Diff line change
Expand Up @@ -8046,6 +8046,16 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
PL_hints &= ~HINT_STRICT_VARS;
}

/* As an optimisation, there's no point scanning for changes of
* visible builtin functions when switching between versions earlier
* than v5.39, when any became visible at all
*/
if ((shortver >= SHORTVER(5, 39)) || (PL_prevailing_version >= SHORTVER(5, 39))) {
prepare_export_lexical();
import_builtin_bundle(shortver, true);
finish_export_lexical();
}

PL_prevailing_version = shortver;
}

Expand Down
18 changes: 12 additions & 6 deletions pod/perlfunc.pod
Original file line number Diff line number Diff line change
Expand Up @@ -10161,12 +10161,18 @@ Compare with L<C<require>|/require VERSION>, which can do a similar check
at run time.

If the specified Perl version is 5.12 or higher, strictures are enabled
lexically as with L<C<use strict>|strict>. Similarly, if the specified
Perl version is 5.35.0 or higher, L<warnings> are enabled. Later use of
C<use VERSION> will override all behavior of a previous C<use VERSION>,
possibly removing the C<strict>, C<warnings>, and C<feature> added by it.
C<use VERSION> does not load the F<feature.pm>, F<strict.pm>, or
F<warnings.pm> files.
lexically as with L<C<use strict>|strict>.

If the specified Perl version is 5.35.0 or higher, L<warnings> are enabled.

If the specified Perl version is 5.39.0 or higher, builtin functions are
imported lexically as with L<C<use builtin>|builtin> with a corresponding
version bundle.

Later use of C<use VERSION> will override all behavior of a previous
C<use VERSION>, possibly removing the C<strict>, C<warnings>, C<feature> and
C<builtin> effects added by it. C<use VERSION> does not load the
F<feature.pm>, F<strict.pm>, F<warnings.pm> or F<builtin.pm> files.

In the current implementation, any explicit use of C<use strict> or
C<no strict> overrides C<use VERSION>, even if it comes before it.
Expand Down
4 changes: 2 additions & 2 deletions pod/perlrun.pod
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,8 @@ to use semicolons where you would in a normal program.
X<-E>

behaves just like L<-e|/-e commandline>, except that it implicitly
enables all optional features (in the main compilation unit). See
L<feature>.
enables all optional features and builtin functions (in the main
compilation unit). See L<feature> and L<builtin>.

=item B<-f>
X<-f> X<sitecustomize> X<sitecustomize.pl>
Expand Down
17 changes: 17 additions & 0 deletions proto.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion t/comp/use.t
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ BEGIN {
$INC{"feature.pm"} = 1; # so we don't attempt to load feature.pm
}

print "1..85\n";
print "1..88\n";

# Can't require test.pl, as we're testing the use/require mechanism here.

Expand Down Expand Up @@ -170,6 +170,18 @@ ok $@, 'no strict vars allows ver decl to enable refs';
eval 'no strict "vars"; use 5.012; ursine_word';
ok $@, 'no strict vars allows ver decl to enable subs';

# check that "use 5.39.0" and higher imports builtins
{
my $result;

$result = eval 'use 5.39.0; my $t = true; $t eq "1"';
is ($@, "", 'builtin funcs available after use 5.39.0');
ok ($result, 'imported true is eq "1"');

eval 'use 5.39.0; use 5.36.0; my $t = true;';
like ($@, qr/^Bareword "true" not allowed while "strict subs" in use at /,
'builtin funcs are removed by use 5.36.0');
}

{ use test_use } # check that subparse saves pending tokens

Expand Down
7 changes: 6 additions & 1 deletion t/run/switches.t
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,12 @@ $TODO = ''; # the -E tests work on VMS
$r = runperl(
switches => [ '-E', '"say q(Hello, world!)"']
);
is( $r, "Hello, world!\n", "-E say" );
is( $r, "Hello, world!\n", "-E enables 'say' feature" );

$r = runperl(
switches => [ '-E', '"say reftype []"']
);
is( $r, "ARRAY\n", "-E enables 'reftype' builtin" );

$r = runperl(
switches => [ '-nE', q("} END { say q/affe/") ],
Expand Down
3 changes: 2 additions & 1 deletion toke.c
Original file line number Diff line number Diff line change
Expand Up @@ -9240,7 +9240,8 @@ yyl_try(pTHX_ char *s)
}
if (PL_minus_E)
sv_catpvs(PL_linestr,
"use feature ':" STRINGIFY(PERL_REVISION) "." STRINGIFY(PERL_VERSION) "';");
"use feature ':" STRINGIFY(PERL_REVISION) "." STRINGIFY(PERL_VERSION) "'; "
"use builtin ':" STRINGIFY(PERL_REVISION) "." STRINGIFY(PERL_VERSION) "';");
if (PL_minus_n || PL_minus_p) {
sv_catpvs(PL_linestr, "LINE: while (<>) {"/*}*/);
if (PL_minus_l)
Expand Down

0 comments on commit e5a00b6

Please sign in to comment.