This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
add padrange op
authorDavid Mitchell <davem@iabyn.com>
Mon, 24 Sep 2012 12:50:22 +0000 (13:50 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sat, 10 Nov 2012 13:39:31 +0000 (13:39 +0000)
commita7fd8ef68b459a13ba95615ec125e2e7ba656b47
tree874247cb2e03f98ee1de71d4a7eb29d3e84a7611
parentad9e6ae10fb581c6c053b862286f8e187063c3ab
add padrange op

This single op can, in some circumstances, replace the sequence of a
pushmark followed by one or more padsv/padav/padhv ops, and possibly
a trailing 'list' op, but only where the targs of the pad ops form
a continuous range.

This is generally more efficient, but is particularly so in the case
of void-context my declarations, such as:

    my ($a,@b);

Formerly this would be executed as the following set of ops:

    pushmark  pushes a new mark
    padsv[$a] pushes $a, does a SAVEt_CLEARSV
    padav[@b] pushes all the flattened elements (i.e. none) of @a,
              does a SAVEt_CLEARSV
    list      pops the mark, and pops all stack elements except the last
    nextstate pops the remaining stack element

It's now:

    padrange[$a..@b] does two SAVEt_CLEARSV's
    nextstate        nothing needing doing to the stack

Note that in the case above, this commit changes user-visible behaviour in
pathological cases; in particular, it has always been possible to modify a
lexical var *before* the my is executed, using goto or closure tricks.
So in principle someone could tie an array, then could notice that FETCH
is no longer being called, e.g.

    f();
    my ($s, @a); # this no longer triggers two FETCHES
    sub f {
tie @a, ...;
push @a, 1,2;
    }

But I think we can live with that.

Note also that having a padrange operator will allow us shortly to have
a corresponding SAVEt_CLEARPADRANGE save type, that will replace multiple
individual SAVEt_CLEARSV's.
18 files changed:
dist/B-Deparse/Deparse.pm
dist/B-Deparse/t/deparse.t
dump.c
ext/B/B/Concise.pm
ext/B/B/Xref.pm
ext/B/t/optree_sort.t
ext/B/t/optree_varinit.t
ext/Opcode/Opcode.pm
op.c
op.h
opcode.h
opnames.h
pp_hot.c
pp_proto.h
regcomp.c
regen/opcodes
sv.c
t/op/sort.t