| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
| |
* Add feature, experimental warning, keyword
* Basic parsing
* Basic implementation as optree fragment
See also
https://github.com/Perl/perl5/issues/18504
|
|
|
|
|
|
|
|
|
|
|
| |
They generate C files.
Bump feature.pm and warnings.pm versions to satisfy cmpVERSION.pl.
I can't get it to easily ignore whitespace, `git diff --name-only`
does not respect the -w flag.
regen_perly.pl is left alone. That would require rebuilding
perly.* which is beyond a simple indentation change.
|
| |
|
|
|
|
|
|
|
|
| |
This was originally added for MinGW, which no longer needs it, and
only still used by Symbian, which is now removed.
This also leaves perlapi.[ch] empty, but we keep the header for CPAN
backwards compatibility.
|
| |
|
|
|
|
|
| |
and the associated commits, at least until a way to make
wrap_op_checker() work is available.
|
|
|
|
| |
Fixes issue #14816
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Adds a new infix operator named `isa`, with the semantics that
$x isa SomeClass
is true if and only if `$x` is a blessed object reference that is either
`SomeClass` directly, or includes the class somewhere in its @ISA
hierarchy. It is false without warning or error for non-references or
non-blessed references.
This operator respects `->isa` method overloading, and is intended to
replace boilerplate code such as
use Scalar::Util 'blessed';
blessed($x) and $x->isa("SomeClass")
|
|
|
|
|
|
|
| |
These two flags will shortly become obsolete, replaced by ones with
different meanings. This flag makes the new ones the normal ones, and
makes the old names synonyms so that code that refers to them can
compile.
|
|
|
|
|
| |
It no longer needs ck_bitop, which it only used before for the
experimental warning that has been removed.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The pumpking has determined that the CPAN breakage caused by changing
smartmatch [perl #132594] is too great for the smartmatch changes to
stay in for 5.28.
This reverts most of the merge in commit
da4e040f42421764ef069371d77c008e6b801f45. All core behaviour and
documentation is reverted. The removal of use of smartmatch from a couple
of tests (that aren't testing smartmatch) remains. Customisation of
a couple of CPAN modules to make them portable across smartmatch types
remains. A small bugfix in scope.c also remains.
|
|\ |
|
| |
| |
| |
| |
| | |
The names of ops, context types, functions, etc., all change in accordance
with the change of keyword.
|
| | |
|
| |
| |
| |
| |
| | |
The leaveloop op type can already do the whole job, with leavegiven being
a near duplicate of it. Replace all uses of leavegiven with leaveloop.
|
| |
| |
| |
| |
| | |
These were used to identify foreach loops that qualify as topicalizers.
That's no longer a relevant classification.
|
| | |
|
| |
| |
| |
| |
| | |
This will support the upcoming change to let loop control ops apply to
"given" blocks.
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Regularise smartmatch's operand handling, by removing the implicit
enreferencement and just supplying scalar context. Eviscerate its runtime
behaviour, by removing all the matching rules other than rhs overloading.
Overload smartmatching in the Regexp package to perform regexp matching.
There are consequential customisations to autodie, in two areas. Firstly,
autodie::exception objects are matchers, but autodie has been advising
smartmatching with the exception on the lhs. This has to change to the
rhs, in both documentation and tests. Secondly, it uses smartmatching as
part of its hint mechanism. Most of the hint examples, in documentation
and tests, have to change to subroutines, to be portable across Perl
versions.
|
|/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This flag makes no functional difference to runtime (it merely flags
that an optimisation has been performed), but it will shortly be used to
assist Deparse and warnings.
OPf_STACKED, when set on a OP_CONCAT, normally indicates .=; but it
also gets set to optimise
$a . $b . $c
into
($a . $b) .= $c
so that the first concat's PADTMP (which holds the result of $a.$b) can be
reused. Set a flag in this case to help deparse and warn distinguish the
cases.
|
|
|
|
| |
[perl #119635]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Allow multiple OP_CONCAT, OP_CONST ops, plus optionally an OP_SASSIGN
or OP_STRINGIFY, to be combined into a single OP_MULTICONCAT op, which can
make things a *lot* faster: 4x or more.
In more detail: it will optimise into a single OP_MULTICONCAT, most
expressions of the form
LHS RHS
where LHS is one of
(empty)
my $lexical =
$lexical =
$lexical .=
expression =
expression .=
and RHS is one of
(A . B . C . ...) where A,B,C etc are expressions and/or
string constants
"aAbBc..." where a,A,b,B etc are expressions and/or
string constants
sprintf "..%s..%s..", A,B,.. where the format is a constant string
containing only '%s' and '%%' elements,
and A,B, etc are scalar expressions (so
only a fixed, compile-time-known number of
args: no arrays or list context function
calls etc)
It doesn't optimise other forms, such as
($a . $b) . ($c. $d)
((($a .= $b) .= $c) .= $d);
(although sub-parts of those expressions might be converted to an
OP_MULTICONCAT). This is partly because it would be hard to maintain the
correct ordering of tie or overload calls.
The compiler uses heuristics to determine when to convert: in general,
expressions involving a single OP_CONCAT aren't converted, unless some
other saving can be made, for example if an OP_CONST can be eliminated, or
in the presence of 'my $x = .. ' which OP_MULTICONCAT can apply
OPpTARGET_MY to, but OP_CONST can't.
The multiconcat op is of type UNOP_AUX, with the op_aux structure directly
holding a pointer to a single constant char* string plus a list of segment
lengths. So for
"a=$a b=$b\n";
the constant string is "a= b=\n", and the segment lengths are (2,3,1).
If the constant string has different non-utf8 and utf8 representations
(such as "\x80") then both variants are pre-computed and stored in the aux
struct, along with two sets of segment lengths.
For all the above LHS types, any SASSIGN op is optimised away. For a LHS
of '$lex=', '$lex.=' or 'my $lex=', the PADSV is optimised away too.
For example where $a and $b are lexical vars, this statement:
my $c = "a=$a, b=$b\n";
formerly compiled to
const[PV "a="] s
padsv[$a:1,3] s
concat[t4] sK/2
const[PV ", b="] s
concat[t5] sKS/2
padsv[$b:1,3] s
concat[t6] sKS/2
const[PV "\n"] s
concat[t7] sKS/2
padsv[$c:2,3] sRM*/LVINTRO
sassign vKS/2
and now compiles to:
padsv[$a:1,3] s
padsv[$b:1,3] s
multiconcat("a=, b=\n",2,4,1)[$c:2,3] vK/LVINTRO,TARGMY,STRINGIFY
In terms of how much faster it is, this code:
my $a = "the quick brown fox jumps over the lazy dog";
my $b = "to be, or not to be; sorry, what was the question again?";
for my $i (1..10_000_000) {
my $c = "a=$a, b=$b\n";
}
runs 2.7 times faster, and if you throw utf8 mixtures in it gets even
better. This loop runs 4 times faster:
my $s;
my $a = "ab\x{100}cde";
my $b = "fghij";
my $c = "\x{101}klmn";
for my $i (1..10_000_000) {
$s = "\x{100}wxyz";
$s .= "foo=$a bar=$b baz=$c";
}
The main ways in which OP_MULTICONCAT gains its speed are:
* any OP_CONSTs are eliminated, and the constant bits (already in the
right encoding) are copied directly from the constant string attached to
the op's aux structure.
* It optimises away any SASSIGN op, and possibly a PADSV op on the LHS, in
all cases; OP_CONCAT only did this in very limited circumstances.
* Because it has a holistic view of the entire concatenation expression,
it can do the whole thing in one efficient go, rather than creating and
copying intermediate results. pp_multiconcat() goes to considerable
efforts to avoid inefficiencies. For example it will only SvGROW() the
target once, and to the exact size needed, no matter what mix of utf8
and non-utf8 appear on the LHS and RHS. It never allocates any
temporary SVs except possibly in the case of tie or overloading.
* It does all its own appending and utf8 handling rather than calling
out to functions like sv_catsv().
* It's very good at handling the LHS appearing on the RHS; for example in
$x = "abcd";
$x = "-$x-$x-";
It will do roughly the equivalent of the following (where targ is $x);
SvPV_force(targ);
SvGROW(targ, 11);
p = SvPVX(targ);
Move(p, p+1, 4, char);
Copy("-", p, 1, char);
Copy("-", p+5, 1, char);
Copy(p+1, p+6, 4, char);
Copy("-", p+10, 1, char);
SvCUR(targ) = 11;
p[11] = '\0';
Formerly, pp_concat would have used multiple PADTMPs or temporary SVs to
handle situations like that.
The code is quite big; both S_maybe_multiconcat() and pp_multiconcat()
(the main compile-time and runtime parts of the implementation) are over
700 lines each. It turns out that when you combine multiple ops, the
number of edge cases grows exponentially ;-)
|
|
|
|
| |
This affects the generated opcode.h.
|
|
|
|
|
|
|
|
| |
This will allow a future commit to make mergesort unstable when
the user specifies ‘no sort stable’, since it has been decided
that mergesort should remain stable by default.
This bit is not yet used, but is quite harmless.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I added ck_eq() recently; it's used for the EQ and NE ops, while ck_cmp()
is used for LT, GT, LE, GE.
This commit eliminates the ck_eq() function and makes ck_cmp() handle
EQ/NE too.
This will will make it easier to extend the index() == -1 optimisation
to handle index() >= 0 etc too.
At the moment there should be no functional differences.
|
|
|
|
|
|
|
| |
OP_RV2AV already has one; its not clear why OP_RV2HV didn't.
Having one means that in scalar context it can return an int value
without having to create a mortal. Ditto when its doing 'keys %h' via
OPpRV2HV_ISKEYS.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Unusually, index() and rindex() return -1 on failure.
So it's reasonably common to see code like
if (index(...) != -1) { ... }
and variants.
For such code, this commit optimises away to OP_EQ and OP_CONST,
and sets a couple of private flags on the index op instead, indicating:
OPpTRUEBOOL return a boolean which is a comparison of
what the return would have been, against -1
OPpINDEX_BOOLNEG negate the boolean result
Its also supports OPpTRUEBOOL in conjunction with the existing
OPpTARGET_MY flag, so for example in
$lexical = (index(...) == -1)
the padmy, sassign, eq and const ops are all optimised away.
|
|
|
|
|
|
| |
there's a block of method_foo ops, and method was apart from them.
No functional difference and part from auto-allocated op numbers.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For some ops which return integer values and which have a reasonable
likelihood of being used in a boolean context, set the OPpTRUEBOOL
flag on the op as appropriate, and at runtime return &PL_sv_yes /
&PL_sv_zero rather than an integer value.
This is especially beneficial where the op doesn't have a targ, so has
to create a mortal SV to return the integer value.
Similarly, its a win where it may be expensive to calculate an integer
return value, such as pos() or length() converting between byte and char
offset.
Ops done:
OP_SUBST
OP_AASSIGN
OP_POS
OP_LENGTH
OP_GREPWHILE
|
|
|
|
|
|
|
|
|
| |
It's quicker to return (and to test for) &PL_sv_zero or &PL_sv_yes,
than setting a targ to an integer value or, in the vase of padav,
creating a mortal sv and setting it to an integer value.
In fact for padav, even in the scalar but non-boolean case, return
&PL_sv_zero if the value is zero rather than creating and setting a mortal.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In something like
if (keys %h) { ... }
the 'keys %h' is implemented as the op sequences
gv[*h] s
rv2hv lKRM/1
keys[t2] sK/1
or
padhv[%h:1,6] lRM
keys[t2] sK/1
It turns out that (%h) in scalar and void context now behaves very
similarly to (keys %h) (except that it reset the iterator), so in these
cases, convert the two ops
rv2hv/padhv, keys
into the single op
rv2hv/padhv
with a private flag indicating that the op is handling the 'keys' action
by itself.
As well as one less op to execute, this brings the boolean-context
optimisation already present in padhv/rv2sv to keys. So
if (keys %h) { ... }
is no longer slower than
if (%h) { ... }
|
|
|
|
|
|
| |
This op doesn't use that bit, but it calls the function Perl_do_kv(),
which is called by several different ops which *do* use that bit.
So ensure no-one in future thinks that bit is spare in OP_VALUES.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
RT #78288
When ref() is used in a boolean context, it's not necessary to return
the name of the package which an object is blessed into; instead a simple
truth value can be returned, which is faster.
Note that it has to cope with the subtlety of an object blessed into the
class "0", which should return false.
Porting/bench.pl shows for the expression !ref($r), approximately:
unchanged for a non-reference $r
doubling of speed for a reference $r
tripling of speed for a blessed reference $r
This commit builds on the mechanism already used to set the OPpTRUEBOOL
and OPpMAYBE_TRUEBOOL flags on padhv and rv2hv ops when used in boolean
context.
|
| |
|
|
|
|
|
|
| |
This flag was added in 5.004 and even then it didn't seem to be used for
anything. It gets set and unset in various places, but is never tested.
I'm not even sure what it was intended for.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There are currently two optimisations for when the results of a split
are assigned to an array.
For the first,
@array = split(...);
the aassign and padav/rv2av are optimised away, and pp_split() directly
assigns to the array attached to the split op (via op_pmtargetoff or
op_pmtargetgv).
For the second,
my @array = split(...);
local @array = split(...);
@{$expr} = split(...);
The aassign is optimised away, but the padav/rv2av is kept as an additional
arg to split. pp_split itself then uses the first arg popped off the stack
as the array (This was introduced by FC with v5.21.4-409-gef7999f).
This commit moves these two:
my @array = split(...);
local @array = split(...);
from the second case to the first case, by simply setting OPpLVAL_INTRO
on the OP_SPLIT, and making pp_split() do SAVECLEARSV() or save_ary()
as appropriate.
This makes my @a = split(...) a few percent faster.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Most ops that execute a regex, such as match and subst, are of type PMOP.
A PMOP allows the actual regex to be attached directly to that op, due
to its extra fields.
OP_SPLIT is different; it is just a plain LISTOP, but it always has an
OP_PUSHRE as its first child, which *is* a PMOP and which has the regex
attached.
At runtime, pp_pushre()'s only job is to push itself (i.e. the current
PL_op) onto the stack. Later pp_split() pops this to get access to the
regex it wants to execute.
This is a bit unpleasant, because we're pushing an OP* onto the stack,
which is supposed to be an array of SV*'s. As a bit of a hack, on
DEBUGGING builds we push a PVLV with the PL_op address embedded instead,
but this still isn't very satisfactory.
Now that regexes are first-class SVs, we could push a REGEXP onto the
stack rather than PL_op. However, there is an optimisation of @array =
split which eliminates the assign and embeds the array's GV/padix directly
in the PUSHRE op. So split still needs access to that op. But the pushre
op will always be splitop->op_first anyway, so one possibility is to just
skip executing the pushre altogether, and make pp_split just directly
access op_first instead to get the regex and @array info.
But if we're doing that, then why not just go the full hog and make
OP_SPLIT into a PMOP, and eliminate the OP_PUSHRE op entirely: with the
data that was spread across the two ops now combined into just the one
split op.
That is exactly what this commit does.
For a simple compile-time pattern like split(/foo/, $s, 1), the optree
looks like:
before:
<@> split[t2] lK
</> pushre(/"foo"/) s/RTIME
<0> padsv[$s:1,2] s
<$> const(IV 1) s
after:
</> split(/"foo"/)[t2] lK/RTIME
<0> padsv[$s:1,2] s
<$> const[IV 1] s
while for a run-time expression like split(/$pat/, $s, 1),
before:
<@> split[t3] lK
</> pushre() sK/RTIME
<|> regcomp(other->8) sK
<0> padsv[$pat:2,3] s
<0> padsv[$s:1,3] s
<$> const(IV 1)s
after:
</> split()[t3] lK/RTIME
<|> regcomp(other->8) sK
<0> padsv[$pat:2,3] s
<0> padsv[$s:1,3] s
<$> const[IV 1] s
This makes the code faster and simpler.
At the same time, two new private flags have been added for OP_SPLIT -
OPpSPLIT_ASSIGN and OPpSPLIT_LEX - which make it explicit that the
assign op has been optimised away, and if so, whether the array is
lexical.
Also, deparsing of split has been improved, to the extent that
perl TEST -deparse op/split.t
now passes.
Also, a couple of panic messages in pp_split() have been replaced with
asserts().
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
[ DAPM:
To clarify: OP_SASSIGN is always allocated as a BINOP (or occasionally
as a UNOP - see the next commit), but is listed as a BASEOP in
regen/opcodes. Because of this, various bits of code that rely on e.g.
PL_opargs[] have to be special-cased for OP_SASSIGN. This commit changes
the entry in regen/opcodes to list it as BINOP, and removes the
special-casing.
I've also added a temporary workaround marked by XXX to make the commit
work under PERL_OP_PARENT, which is the default now. This will be
removed in a couple if commits' time.
]
This was wrong from the very beginning:
added with 79072805bf lwall perl 5.0 alpha 2 1993 with class s, not 0,
but missing the 2 S S args, which are present in aassign.
Changed to BASEOP with db173bac9b6de7d by mbeattie in 1997.
The '# sassign is special-cased for op class' comment is suspicious.
Fix it in ck_sassign also, it is created as BINOP in newASSIGNOP.
In 202206897 dapm 2014 complained about it also. Remove some special
cases where it should be a BINOP but was not.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Change the output of Concise etc:
$ perl -MO=Concise -e'my (@a,$b,$c); $a[5];'
from:
3 <0> padrange[@a:1,2; $b:1,2; $c:1,2] vM/LVINTRO,3
...
5 <0> aelemfast_lex[@a:1,2] sR/5
to:
3 <0> padrange[@a:1,2; $b:1,2; $c:1,2] vM/LVINTRO,range=3
...
5 <0> aelemfast_lex[@a:1,2] sR/key=5
See http://nntp.perl.org/group/perl.perl5.porters/220208.
|
|
|
|
|
| |
Add OPpAVHVSWITCH_MASK and make Concise etc display the offset as
/offset=2 rather than /2.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
soon 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'.
[ These ops currently assume that the lexical var being introduced
is undef/empty and non-magival etc. This is an incorrect assumption and
is fixed in a few commits' time ]
|
|
|
|
|
| |
The string bitwise ops have dots in them, which should be included
in the op descriptions.
|
|
|
|
| |
Oops!
|
| |
|
|
|
|
|
| |
&CORE::keys() et al. will use this to switch between keys and akeys
depending on the argument type.
|
|
|
|
|
| |
In a forthcoming commit, I will need them to be in the same order as
the corresponding hash functions.
|
|
|
|
|
| |
This is a continuation of this commit’s great grandparent, extending
the error to arrays.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Create a new context type so that "for (1,2,3)" and "for (@ary)"
are now two separate types.
For the list type, we store the index of the base stack element in the
state union rather than having an array pointer. Currently this is just
the same as blk_resetsp, but this will shortly allow us to eliminate the
resetsp field from the struct block_loop - which is currently the largest
sub-struct within the block union.
Having two separate types also allows the two cases to be handled directly
in the main switch in the hot pp_iter code, rather than having extra
conditionals.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
pp_postinc() handles both $x++ and $x-- (and the integer variants
pp_i_postinc/dec). Split it into two separate functions, as handling
both inc and dec in the same function requires 3 extra conditionals.
At the same time make the code more efficient.
As currently written it:
1) checked for "bad" SVs (such as read-only) and croaked;
2) did a sv_setsv(TARG, TOPs) to return a copy of the original value;
2) checked for a IOK-only SV and if so, directly incremented the IVX slot;
3) else called out to sv_inc/dec() to handle the more complex cases.
This commit combines the checks in (1) and (3) into one single big
check of flags, and for the simple integer case, skips 2) and does
a more efficient SETi() instead.
For the non-simple case, both pp_postinc() and pp_postdec() now call a
common static function to handle everything else.
Porting/bench.pl shows the following raw numbers for
'$y = $x++' ($x and $y lexical and holding integers):
before after
------ -----
Ir 306.0 223.0
Dr 106.0 82.0
Dw 51.0 44.0
COND 48.0 33.0
IND 8.0 6.0
COND_m 1.9 0.0
IND_m 4.0 4.0
|