| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Just use B directly to look at the op tree, instead of checking that
deparsed op trees are identical.
Before:
real 0m4.021s
user 0m3.668s
sys 0m0.191s
After:
real 0m0.388s
user 0m0.251s
sys 0m0.080s
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Constant folding is not supposed to warn. If it would produce a warn-
ing, then it is skipped and the warning is deferred to run time.
This means the -w flag can affect constant folding:
$ ./perl -Ilib -MO=Concise -le 'use constant u=>undef; $a = u+1'
6 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 132 -e:1) v:{ ->3
5 <2> sassign vKS/2 ->6
3 <$> const[NV 1] s/FOLD ->4
- <1> ex-rv2sv sKRM*/1 ->5
4 <#> gvsv[*a] s ->5
-e syntax OK
$ ./perl -Ilib -MO=Concise -lwe 'use constant u=>undef; $a = u+1'
8 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 132 -e:1) v:{ ->3
7 <2> sassign vKS/2 ->8
5 <2> add[t2] sK/2 ->6
3 <$> const[NULL ] s*/FOLD ->4
4 <$> const[PVNV 1] s ->5
- <1> ex-rv2sv sKRM*/1 ->7
6 <#> gvsv[*a] s ->7
-e syntax OK
But the problem here is that the flag could be turned on at run time,
so if the folding happens because -w is off, then the behaviour
changes due to folding. It’s fine to do the folding here only when
warnings are lexically disabled, as that overrides any setting of -w.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
As of 4aaa475724fbbc4ab2427743fa4d07a12e6ce0d9, when Perl compiles code like
BEGIN { *entangle = \&CORE::tie }
entangle $foo, $package
the apparent call to "entangle" is replaced with an inlined invocation of
the "tie" builtin.
For unary ops, the OPf_SPECIAL flag was set on the generated inlined op iff
the op's argument was surrounded by parens. But that's incorrect for ops
which have their own interpretation of OPf_SPECIAL. In particular:
keys, values, each
OPf_SPECIAL is set for lvalue usage; this shows up when the compile-time
argument is a reference to be subjected to the autoderef feature, and
the run-time argument is an array ref. The existing tests didn't execute
the code (and didn't combine inlining with array autoderefs), so didn't
catch this case.
delete, exists
OPf_SPECIAL is set when the argument is an array element rather than a
hash element; this doesn't directly cause any obvious problems, because
pp_delete and pp_exists consider OPf_SPECIAL only when they've already
determined that their argument is an array element, but it did break
deparsing (because B::Deparse considers OPf_SPECIAL in all cases): the
hash element argument got deparsed as an array element. Further, the
inlining tests themselves rely on deparsing to ensure that the op was
inlined. The existing inlining tests happened to use array elements, so
didn't catch this problem.
This commit fixes those cases, by avoiding setting OPf_SPECIAL when inlining
an invocation of one of those ops. The list of op types is hard-coded; this
seems a little icky, but I don't see a better alternative.
I believe that no other ops are affected by this issue, but my confidence in
that statement isn't as high as it might be; it seems hard to work out
exactly which ops use OPf_SPECIAL.
|
|
|
|
|
| |
This routine will be used in the next commit. I believe that the behaviour
of the tests remains unchanged after this commit.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The original sample was:
BEGIN {
$^H |= 0x00000400; # strict vars
}
# Undeclared variable here
sub foo { return $anyvar; }
# Any CORE:: here
sub bar { \&CORE::lc }
simplified to:
BEGIN {
$^H |= 0x00000400; # strict vars
}
$anyvar;
&CORE::lc;
but it occurs for any compile-time error that doesn't abort compilation,
such as:
$foo/; \&CORE::lc
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In the error message, we can’t say ‘&CORE::undef operator’, so we
should be using the op name, rather than the op description.
Instead of using OP_NAME(PL_op->op_next), which would expand to
PL_op->op_next->op_type == OP_CUSTOM
? XopENTRY(Perl_custom_op_xop(aTHX_ PL_op->op_next), xop_name)
: PL_op_name[PL_op->op_next->op_type]
we can simply use PL_op_name[opnum], which should be quicker.
pp_undef can already handle nulls on the stack.
There is one remaining problem. If &CORE::undef(\*_) is called, *_
will be undefined while @_ is localised during the sub call, so it
won’t have the same effect as undef *_. I don’t know whether this
should be considered a bug or not, but I could solve it by making
pp_undef an XSUB.
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I added a special case for OP_GLOB to pp_coreargs, since glob does not
have the u flag in regen/opcodes; hence PL_opargs[opnum] & OA_DEFGV is
false, even though glob does imply $_.
Adding the flag to regen/opcodes is not so simple, as the code in
ck_fun that adds the DEFSV op does not account for list ops, but
leaves op_last unchanged.
Changing ck_fun to account requires adding more code than this special
case in pp_coreargs.
OPf_SPECIAL indicates that glob was called with the CORE:: prefix.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
Instead of skipping positive keywords (those that cannot be over-
ridden) because of their positivity, list them explicitly in the
skip list.
This will allow them to be removed one by one.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I was trying to write a JAPH, but did not get what I expected:
$ ./perl -Ilib -e '@UNIVERSAL::ISA = CORE; print "just another "->ucfirst, "perl hacker,\n"->ucfirst'
Perl hacker,
Perl hacker,
This happened because coresubs use leavesublv, to avoid copying the
return value wastefully.
But since this is exactly the same ucfirst op being called each time
(the one in &CORE::ucfirst’s op tree), and since ucfirst uses TARG, we
end up with the same scalar.
We have the same problem with lvalue subs:
$ ./perl -Ilib -e 'sub UNIVERSAL::ucfirst :lvalue { ucfirst $_[0] } print "just another "->ucfirst, "perl hacker,\n"->ucfirst'
Perl hacker,
Perl hacker,
(This is not a regression, as 5.14 gave ‘Can't modify ucfirst in
lvalue subroutine return’.)
So ‘fixing’ coresubs would not be a solution, but a workaround.
The solution therefore is for leavesublv to copy PADTMPs in
rvalue context.
Commit 80422e24c fixed this for potential lvalue list context (i.e.,
for(lvsub()) {...}), but it wasn’t sufficient.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
newATTRSUB requires the sub name to be passed to it wrapped up in
a const op.
Commit 8756617677dbd allowed it to accept a GV that way, since
S_maybe_add_coresub (in gv.c) needed to pass it an existing GV not in
the symbol table yet (to simplify code elsewhere).
This had the inadvertent side-effect of making the GV read-only, since
that’s what the check function for const ops does.
Even if we were to call this a feature, it wouldn’t make sense as
implemented, as GVs for non-ampable (&-able) subs like *CORE::chdir
were not being made read-only.
This commit adds a new flag to newATTRSUB, to allow a GV to be passed
as the o parameter, instead of an op. While this may look as though
it’s undoing the simplification in commit 8756617677dbd by adding
more code, the new code is still conceptually simpler and more
straightforward.
Since newATTRSUB is in the API, I had to add a new _flags variant.
(How did newATTRSUB get into the API to begin with?)
In adding a test, I also discovered that ‘used once’ warnings
were applying to these subs, which is obviously wrong. Commit
8756617677dbd caused that, too, as it was relying on the side-effect
of newATTRSUB doing a GV lookup.
This fixes that, too, by turning on the multi flag in
S_maybe_add_coresub.
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
This function evaluates its argument as a byte string, regardless of
the internal encoding. It croaks if the string contains characters
outside the byte range. Hence evalbytes(" use utf8; '\xc4\x80' ")
will return "\x{100}", even if the original string had the UTF8 flag
on, and evalbytes(" '\xc4\x80' ") will return "\xc4\x80".
This has the side effect of fixing the deparsing of CORE::break under
‘use feature’ when there is an override.
|
|
|
|
|
|
|
|
|
|
| |
This will probably not be used, but ought to be here for complete-
ness’ sake.
Method lookup needs to trigger the autovivification of coresubs.
Since it does not use gv_fetchpvn_flags, the coresub-autovification is
now in a separate static function, so that both standard gv lookup and
method lookup can share it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since goto &foo is supposed to replace the current sub call, as though
foo had been called instead, logically foo should see the same lexical
hints that would have been seen if it had been called to begin with.
Regular Perl subs begin with nextstate ops, so they have their own
lexical scopes, but CORE:: subs see the caller’s PL_curcop. They lack
a nextstate precisely so that they run in the caller’s scope, just as
though a built-in function had been called.
For Perl subs (as opposed to XSUBs), goto-&sub was not reset-
ting PL_curcop to the caller’s value, but leaving as it was, so
goto &CORE::sub would cause the CORE sub to run with the lexical hints
of the subroutine in replaced, instead of that sub’s caller.
This was never a problem until CORE subs came along, as they look like
Perl subs to the internals (they have an op tree and are flagged as
such), but comprise a sequence of ops that can never result from com-
piling Perl source code.
The simple one-line fix is to set PL_curcop in pp_goto for Perl subs
as well as XSUBs. (For XSUBs it is implied by POPBLOCK.)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Magical variables usually get autovivified, even in rvalue context,
because Perl is trying to pretend they have been there all along.
That means defined(${"."}) will autovivify $. and return true.
Until CORE subs were introduced, there were no subroutines that popped
into existence when looked at.
This commit makes rv_2cv use the GV_ADDMG flag added in commit
23496c6ea. When this flag is passed, gv_fetchpvn_flags creates a GV
but does not add it to the stash until it finds out that it is creat-
ing a magical one. The CORE sub code calls newATTRSUB, which expects
to add the CV to the stash itself. So the gv has to be added there
and then. So gv_fetchpvn_flags is also adjusted to add the gv to the
stash right before calling newATTRSUB, and to tell itself that the
GV_ADDMG flag is actually off.
It might be better to move the CV-creation code into op.c and inline
parts of newATTRSUB, to avoid fiddling with the addmg variable (and
avoid prototype checks on CORE subs), but that refactoring should
probably come in separate commits.
|
| |
|
|
|
|
|
|
|
|
| |
Originally, coresubs.t was going to be for generic tests and
coreinline.t was going to be for inlining. But the latter ended
up testing other things than inlining, the former testing just
&ersand() calls. So this commits renames coresubs.t to coreamp.t
and coreinline.t to coresubs.t.
|
|
|
|
|
|
|
|
| |
This commit allows &CORE::rand to be called through references and
via ampersand syntax. pp_rand is modified to take into account the
nulls pushed on to the stack in pp_coreargs, which happens because
pp_coreargs has no other way to tell rand how many arguments it’s
actually getting. See commit 0163043a for details.
|
|
|
|
|
|
| |
This commit allows &CORE::open to be called through references or with
ampersand syntax. It modifies pp_coreargs not to push nulls for ops
that require a pushmark.
|
|
|
|
|
|
|
|
| |
This commit allows &CORE::mkdir to be called through references and
via ampersand syntax. pp_mkdir is modified to take into account the
nulls pushed on to the stack in pp_coreargs, which happens because
pp_coreargs has no other way to tell mkdir how many arguments it’s
actually getting.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit allows &CORE::lock to be called through references and
via ampersand syntax. It adds code to pp_coreargs for handling the
OA_SCALARREF case, though what it adds is currently lock-specific.
(Subsequent commits will address that.) Since lock returns the scalar
passed to it, not a copy, &CORE::lock needs to use op_leavesublv,
rather than op_leavesub. But it can’t be an lvalue sub, as
&CORE::lock = 3 should be disallowed. So we use the sneaky trick of
turning on the lvalue flag before attaching the op tree to the sub
(which causes newATTRSUB to use op_leavesublv), and then turning it
off afterwards.
|
|
|
|
|
|
|
|
| |
This commit allows &CORE::index and &CORE::rindex to be called through
references and via ampersand syntax. pp_index is modified to take
into account the nulls pushed on to the stack in pp_coreargs, which
happens because pp_coreargs has no other way to tell pp_index how many
arguments it’s actually getting. See commit 0163043a for details.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit allows &CORE::gmtime and &CORE::localtime to be called
through references and via ampersand syntax. pp_gmtime is modified
to take into account the nulls pushed on to the stack in pp_coreargs,
which happens because pp_coreargs has no other way to tell pp_gmtime
how many arguments it’s actually getting.
I was going to say ‘see commit f6a1686942 for more details’, but found
out, to my horror, that most of the commit message was cut off. I
don’t know which commit-munging part of git is responsible, but I’ve
had similar problems with git am and git commit --amend. But, then,
this could have been sloppy copy and paste. Anyway, here is the
missing part:
Usually, an op that has optional arguments has the number of arguments
indicated with flags on the op itself:
$ ./perl -Ilib -MO=Concise -e 'binmode 1'
6 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
5 <@> binmode vK/1 ->6
- <0> ex-pushmark s ->3
4 <1> rv2gv sK*/1 ->5
3 <$> gv(*1) s ->4
-e syntax OK
$ ./perl -Ilib -MO=Concise -e 'binmode 1,2'
7 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v:{ ->3
6 <@> binmode vK/2 ->7
- <0> ex-pushmark s ->3
4 <1> rv2gv sK*/1 ->5
3 <$> gv(*1) s ->4
5 <$> const(IV 2) s ->6
-e syntax OK
Notice the /1 vs /2 on the binmode op.
With a CORE sub, we have a single op for both cases. So, what this
commit does is set the number of arguments to the maximum, push nulls
on to the stack in pp_coreargs (actually, it was already set up to
do it, so there is no change there), and have the pp_ functions for
each op that has optional arguments do a null check after popping
the stack.
pp_binmode already does a null check, but other pp_ functions will
need to be modified. Since each one is different, those will come in
separate commits.
This is what &CORE::binmode’s op tree looks like:
$ ./perl -Ilib -MO=Concise,CORE::binmode -e 'BEGIN{\&CORE::binmode}'
CORE::binmode:
3 <1> leavesub[1 ref] K/REFC,1 ->(end)
2 <@> binmode sK/2 ->3
- <0> ex-pushmark s ->1
1 <$> coreargs(IV 212) s ->2
-e syntax OK
|
|
|
|
|
|
|
| |
This commit allows &CORE::getpgrp to be called through references and
via ampersand syntax. pp_getpgrp is modified to take into account the
nulls pushed on to the stack in pp_coreargs, since pp_coreargs has no
other way to tell getpgrp how many arguments it’s actually getting.
|
|
|
|
|
|
|
| |
This commit allows &CORE::exit to be called through references and
via ampersand syntax. pp_exit is modified to take into account the
nulls pushed on to the stack in pp_coreargs, since pp_coreargs has no
other way to tell exit how many arguments it’s actually getting.
|
|
|
|
|
|
|
|
|
|
| |
This commit allows the subs in the CORE package for close, getc and
readline to be called through references and via ampersand syntax. A
special case for each of them is added to pp_coreargs to deal with
calls with no arguments. Pushing a null on to the stack (which I’m
doing for other ops) won’t work, as a null already means something for
these cases: close($f) won’t vivify a typeglob if $f is a string, so
the implicit rv2gv pushes a null on to the stack.
|
|
|
|
|
|
|
| |
This commit allows the subs in the CORE package for close, getc and
readline to be called through references and via ampersand syntax. The
pp functions are modified to take into account the nulls that coreargs
pushes on to the stack to indicate that there is no argument.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit allows the CORE subroutines for functions with @
and $@ prototypes to be called through references and via amper-
sand syntax.
unlink is not included in this commit, as it requires special casing
due to its use of implicit $_.
Since these functions require a pushmark, and since it has to come
between two things that pp_coreargs does, it’s easiest to flag the
coreargs op (with the OPpCOREARGS_PUSHMARK flag added in the previous
commit) and call pp_pushmark directly from pp_coreargs.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit allows &CORE::caller to be called through references and
via ampersand syntax. pp_caller is modified to take into account
two things:
1) pp_coreargs pushes a null on to the stack, since it has no other
way to tell caller whether it has an argument.
2) The value coming from pp_coreargs (when not null) is off by
one. The OPpOFFYBONE flag was added in commit 93f0bc4935 for
this purpose.
pp_coreargs is also modified, since it assumed till now that an
optional first argument was an implicit $_.
|
|
|
|
|
|
|
| |
This commit allows &CORE::bless to be called through references and
via ampersand syntax. pp_bless is modified to take into account the
nulls pushed on to the stack in pp_coreargs, since pp_coreargs has no
other way to tell bless how many arguments it’s actually getting.
|
|
|
|
|
|
|
|
| |
This commit allows &CORE::binmode to be called through references and
via ampersand syntax.
Usually, an op that has optional arguments has the number of arguments
indicated with flags on the op itself:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This enables ampersand calls and calls through references for CORE
subs that have * and $ in their prototypes and a fixed number of
arguments.
Usually, the *-prototyped ops have their child ops wrapped in rv2gv’s
(*{}) implicitly. The rv2gv op is sometimes flagged as an autoviv-
ificatory op, such as the first argument to accept() or open().
S_is_handle_constructor contains the list of ops that turn on
that flag.
This commit makes the coreargs op use a couple of flags to serve the
same purpose. pp_coreargs itself calls S_rv2gv (split out from
pp_rv2gv recently for precisely this purpose) with arguments based on
its own flags.
Currently the autovivified glob gets a name like main::_GEN_0 instead
of main::$a. I think we can live with that.
|
|
|
|
|
| |
This fixes some infelicities in the new tests I added to this
file recently.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This applies to functions that just take plain scalar arguments, all
of which are mandatory. Functions that take optional arguments are
not supported yet. truncate() is not supported yet, either (its $$
prototype is not entirely veracious).
This commit enables those functions to be called via &CORE::foo() syn-
tax or through references.
You can now encrypt a string like this: "string"->CORE::crypt($salt).
Each function’s op tree is like this:
$ ./perl -Ilib -MO=Concise,CORE::atan2 -e 'BEGIN{\&CORE::atan2}'
CORE::atan2:
3 <1> leavesub[1 ref] K/REFC,1 ->(end)
2 <@> atan2[t1] sK ->3
- <0> ex-pushmark s ->1
1 <$> coreargs(IV 100) s ->2
-e syntax OK
This commit adds code to ck_fun to skip the argument check if
coresubs is present. Otherwise we get a ‘Not enough arguments for
atan2’ error.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit adds all subs with a (_) prototype to the list of those
that can be called with ampersand syntax or through references. These
have bodies like this:
$ ./perl -Ilib -MO=Concise,CORE::abs -e 'BEGIN{\&CORE::abs}'
CORE::abs:
3 <1> leavesub[1 ref] K/REFC,1 ->(end)
2 <1> abs[t1] sK/1 ->3
1 <$> coreargs(IV 111) s ->2
-e syntax OK
coreargs fetches the caller’s $_ if there are no arguments passed.
|
|
|
|
|
| |
This is another nullary function that I forgot to give a body
to make it callable via &break syntax.
|
|
|
|
|
|
|
| |
In commit 7fa5bd9b5, I not only forgot about getpwent (see commit
cc131e4, in which I mistakenly called it pwent), but fork as well.
Again, all this commit has to do is add it to the list of ‘ampable’
functions in gv.c. The rest already works.
|
|
|
|
|
|
| |
In commit 7fa5bd9b5, I forgot about pwent. All this commit has
to do is add it to the list of ‘ampable’ functions in gv.c. The
rest already works.
|