In perl.git, the branch smoke-me/davem/sub_argsB3 has been created
<http://perl5.git.perl.org/perl.git/commitdiff/89251161ea05a6c1feff7d40d7d1a9838ad96e71?hp=0000000000000000000000000000000000000000>
at 89251161ea05a6c1feff7d40d7d1a9838ad96e71 (commit)
- Log -----------------------------------------------------------------
commit 89251161ea05a6c1feff7d40d7d1a9838ad96e71
Author: David Mitchell <[email protected]>
Date: Fri Jul 22 21:26:44 2016 +0100
more pruning of Porting/deparse-skips.txt
In the summary output of
cd t; ./perl TEST -deparse
it doesn't distinguish between test scripts expected to pass that fail,
and those expected to fail that succeed. They're all listed as failures.
So I've just removed 5 further entries from deparse-skips.txt that I
hadn't noticed were passing. I don't know when they first started
unexpectedly passing.
It's down to 78 unexpected failures now. Not good, since a couple of
years ago there were no unexpected failures, but at least its down from
the 194 at the start of this branch. The entries in deparse-skips.txt
have also reduced by about 28 over the course of this branch.
M Porting/deparse-skips.txt
commit 604de00bea43e56ae99de17a916dfb51311ab315
Author: David Mitchell <[email protected]>
Date: Fri Jul 22 18:25:08 2016 +0100
deparse subroutine signatures
If 'use feature "signatures"' is in scope, deparse subs using the
sub foo ($a,$b) { ... }
syntax rather than
sub foo {
my $a = $_[0];
my $b = $_[0];
...
}
Only do this where the sequence of OP_SIGCHECK and OP_SIGELEM etc ops
make up a consistent signature. Otherwise (e.g. someone's modified
it with a parser hook), fall back to 'my $a = $_[0]' syntax.
M lib/B/Deparse.pm
M lib/B/Deparse.t
commit 660e0823fea9e708fc08eb4fc12b1b287da8bcc6
Author: David Mitchell <[email protected]>
Date: Fri Jul 22 14:24:33 2016 +0100
fix deparsing of Test::More's use_ok()
Code like
BEGIN {use_ok 'Net::Ping'};
got deparsed as:
BEGIN {use_ok 'Net::Ping'};
use Net::Ping (@{$args[0];});
This is due to the tricks it plays faking up and evaling a use statement.
This commit filters out these spurious 'use's in the Deparse output.
With this commit, 109 'TEST -deparse' tests that were expected to pass
but had been failing for some time, now pass; and 22 tests that were
expected to fail, now pass.
I also removed the entry for lib/Switch/t/ in Porting/deparse-skips.txt,
since Switch is no longer bundled.
M Porting/deparse-skips.txt
M lib/B/Deparse.pm
commit d7b88708f96b975f68e11458a8827002a4102562
Author: David Mitchell <[email protected]>
Date: Fri Jul 22 13:12:17 2016 +0100
OP_MULTIDEREF: remove ghost entry in op_aux list
In the case where a multideref expression ends with an index that initially
looks simple (e.g. const or var) but turns out to be complex, the code
which optimises a sequence of aelem etc into a single multideref backs off
from including that last index expression in the multideref, but still
allocates a slot in the op_aux array for that ghost index.
For example in
$expr->{foo}[0][1+$x]
it allocates a slot for the "1" constant but then doesn;t use it.
This isn't an issue for multideref itself, but when running Deparse or
otherwise inspecting the op tree, the $op->aux_list() method returns a
list of the elements of the op_aux array with an extra garbage element at
the end, which can cause Deparse to crash.
M lib/B/Deparse.t
M op.c
commit 7832d296529cf9a5817f11e9be4c19f9e5e7287c
Author: David Mitchell <[email protected]>
Date: Fri Jul 22 12:19:03 2016 +0100
fix up exists etc deparsing
a general multideref expression like
exists +($r//{})->{foo}
was being deparsed without the '+', meaning it was being interpreted
as
(exists ($r//{}))->{foo}
M lib/B/Deparse.pm
commit 2e6a13d87d036222a38da6d1b0930dfbae4488c3
Author: David Mitchell <[email protected]>
Date: Fri Jul 22 10:08:50 2016 +0100
handle deparsing of sub prototypes with sigs
when 'use feature "signatures"' is in scope, subroutine prototypes
should be deparsed as ':prototype($$)' rather than '($$)'
I've also tweaked the sub in question slightly to make adding
signature deparsing easier later on.
M Porting/deparse-skips.txt
M lib/B/Deparse.pm
commit 15e1235d2aed98b9c3a61302d78a7a356715af5f
Author: David Mitchell <[email protected]>
Date: Thu Jul 21 15:11:50 2016 +0100
Deparse: emit pragmas before each sub
Before deparsing a sub, emit any pragma changes associated with the
first nextstate in the sub *before* emitting the sub itself.
So this:
use strict;
sub f { ...}
doesn't get deparsed as
sub f { use strict; ...}
There was already a partial fix for this in pp_nextstate. Making
next_todo() always emit pragmas catches more cases and makes pp_nextstate
simpler.
M lib/B/Deparse.pm
M lib/B/Deparse.t
commit 8950c747c350bb9be5ea6f506910208ffe2c178d
Author: David Mitchell <[email protected]>
Date: Thu Jul 21 14:21:01 2016 +0100
Deparse: use more local vars in next_todo()
assign @$ent to some local vars rather than directly using $ent->[2] etc:
makes the code more self-documenting.
Should be no functional changes.
M lib/B/Deparse.pm
commit 648cc59dddb1b7bb52194c0bab968967e9a37d50
Author: David Mitchell <[email protected]>
Date: Thu Jul 21 14:01:17 2016 +0100
Deparse: move pragma deparsing into separate sub
Currently this is done in pp_nextstate(). Move it out into a separate
method called praggmata() so in the next commit it can be used elsewhere.
Should be no functional changes.
M lib/B/Deparse.pm
commit 1ebdfcc97bf1725ce252806664ea80e03bca49d0
Author: David Mitchell <[email protected]>
Date: Wed Jul 20 17:31:00 2016 +0100
deparse pragmas before subs
Currently something like this:
use strict;
sub f {
print;
}
print;
deparses as:
sub f {
use strict;
print $_;
}
use strict;
print $_;
(Note where the 'strict's appear). Although ugly, this is semantically
correct for most pragmas. However, it breaks down for "use feature
'signatures'", since that needs to appear before the sub if the
deparsing of the sub's header is altered to reflect signature syntax or
not, based on whether the pragma is in scope.
This commit changes the deparsing of each nextstate op so that it outputs
any pragmas which reflect changes since the last nextstate's hints etc,
*before* deparsing any subs whose COP is less than that of the new
nextstate. After this commit, the code above deparses as:
use strict;
sub f {
print $_;
}
print $_;
It also allows some hacky code to be removed from Deparse.pm that
ensured that "no warnings experimental::lexical_subs" appeared before
each lexical sub was deparsed.
M lib/B/Deparse-core.t
M lib/B/Deparse.pm
M lib/B/Deparse.t
commit bb4e407f3ca121b64de68e45649784a5d45de19b
Author: David Mitchell <[email protected]>
Date: Sat Jul 9 10:41:08 2016 +0100
add OP_ARGELEM, OP_ARGDEFELEM, OP_ARGCHECK ops
Currently subroutine signature parsing emits many small discrete ops
to implement arg handling. This commit replaces them with a couple of ops
per signature element, plus an initial signature check op.
These new ops are added to the OP tree during parsing, so will be visible
to hooks called up to and including peephole optimisation. It is intended,
in a few commits time, that the peephole optimiser will take these
per-element ops, and replace them with a single OP_SIGNATURE op which
handles the whole signature in a single go. So normally these ops wont
actually get executed much. But adding these intermediate-level ops gives
three advantages:
1) it allows the parser to efficiently generate subtrees containing
individual signature elements, which can't be done if only OP_SIGNATURE
or discrete ops are available;
2) prior to optimisation, it provides a simple and straightforward
representation of the signature;
3) hooks can mess with the signature OP subtree in ways that make it
no longer possible to optimise into an OP_SIGNATURE, but which can
still be executed, deparsed etc (if less efficiently).
This code:
use feature "signatures";
sub f($a, $, $b = 1, @c) {$a}
under 'perl -MO=Concise,f' now gives:
d <1> leavesub[1 ref] K/REFC,1 ->(end)
- <@> lineseq KP ->d
1 <;> nextstate(main 84 foo:6) v:%,469762048 ->2
2 <+> argcheck(3,1,@) v ->3
3 <;> nextstate(main 81 foo:6) v:%,469762048 ->4
4 <+> argelem(0)[$a:81,84] v/SV ->5
5 <;> nextstate(main 82 foo:6) v:%,469762048 ->6
8 <+> argelem(2)[$b:82,84] vKS/SV ->9
6 <|> argdefelem(other->7)[2] sK ->8
7 <$> const(IV 1) s ->8
9 <;> nextstate(main 83 foo:6) v:%,469762048 ->a
a <+> argelem(3)[@c:83,84] v/AV ->b
- <;> ex-nextstate(main 84 foo:6) v:%,469762048 ->b
b <;> nextstate(main 84 foo:6) v:%,469762048 ->c
c <0> padsv[$a:81,84] s ->d
The argcheck(3,1,@) op knows the number of positional params (3), the
number of optional params (1), and whether it has an array / hash slurpy
element at the end. This op is responsible for checking that @_ contains
the right number of args.
A simple argelem(0)[$a] op does the equivalent of 'my $a = $_[0]'.
Similarly, argelem(3)[@c] is equivalent to 'my @c = @_[3..$#_]'.
If it has a child, it gets its arg from the stack rather than using $_[N].
Currently the only used child is the logop argdefelem.
argdefelem(other->7)[2] is equivalent to '@_ > 2 ? $_[2] : other'.
But note that these ops assume that the lexical var being introduced
is undef/empty, so can only be used at the top of the sub, or where
tricksy gotos, closures and 'if 0's aren't used.
M dump.c
M embed.fnc
M embed.h
M ext/B/B.pm
M ext/B/B.xs
M ext/B/B/Concise.pm
M ext/Opcode/Opcode.pm
M lib/B/Deparse.pm
M lib/B/Op_private.pm
M op.c
M opcode.h
M opnames.h
M perly.act
M perly.h
M perly.tab
M perly.y
M pod/perldiag.pod
M pp.c
M pp_hot.c
M pp_proto.h
M proto.h
M regen/op_private
M regen/opcodes
M t/op/signatures.t
M toke.c
commit 29d37808d70fee2b8d01a201c89cedf82bab65c7
Author: David Mitchell <[email protected]>
Date: Thu Jul 14 10:47:01 2016 +0100
make op.c:S_alloc_LOGOP() non-static
... principally so that it can be accessed from perly.y too.
M embed.fnc
M embed.h
M op.c
M proto.h
commit 14b1032158684457ae3dd442f8638164d493bdd3
Author: David Mitchell <[email protected]>
Date: Thu Jan 28 15:14:57 2016 +0000
sub signatures: use parser rather than lexer
Currently the signature of a sub (i.e. the '($a, $b = 1)' bit) is parsed
in toke.c using a roll-your-own mini-parser. This commit makes
the signature be part of the general grammar in perly.y instead.
In theory it should still generate the same optree as before, except
that an OP_STUB is no longer appended to each signature optree: it's
unnecessary, and I assume that was a hangover from early development of
the original signature code.
Error messages have changed somewhat: the generic 'Parse error' has
changed to the generic 'syntax error', with the addition of ', near "xyz"'
now appended to each message.
Also, some specific error messages have been added; for example
(@a=1) now says that slurpy params can't have a default vale, rather than
just giving 'Parse error'.
It introduces a new lexer expect state, XSIGVAR, since otherwise when
the lexer saw something like '($, ...)' it would see the identifier
'$,' rather than the tokens '$' and ','.
Since it no longer uses parse_termexpr(), it is no longer subject to the
bug (#123010) associated with that; so sub f($x = print, $y) {}
is no longer mis-interpreted as sub f($x = print($_, $y)) {}
M embed.fnc
M embed.h
M op.c
M parser.h
M perl.h
M perly.act
M perly.c
M perly.h
M perly.tab
M perly.y
M pod/perldiag.pod
M proto.h
M sv.c
M t/op/signatures.t
M toke.c
-----------------------------------------------------------------------
--
Perl5 Master Repository