Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Avoid parameter re-containering when possible.
In sub foo(Int $a) { ... }, we needn't wrap the incoming parameter up
in a scalar container, and instead can decontainerize and bind it. It
is safe since Int !~~ Iterable and Iterable !~~ Int, and thus we know
it doesn't need the container to promise non-flattening.
  • Loading branch information
jnthn committed Apr 7, 2014
1 parent ebd3729 commit 2b89776
Showing 1 changed file with 31 additions and 13 deletions.
44 changes: 31 additions & 13 deletions src/Perl6/Actions.nqp
Expand Up @@ -5891,8 +5891,9 @@ class Perl6::Actions is HLL::Actions does STDActions {
my @result;
my $clear_topic_bind;
my $saw_slurpy;
my $Sig := $*W.find_symbol(['Signature']);
my $Param := $*W.find_symbol(['Parameter']);
my $Sig := $*W.find_symbol(['Signature']);
my $Param := $*W.find_symbol(['Parameter']);
my $Iterable := $*W.find_symbol(['Iterable']);
my @p_objs := nqp::getattr($sig, $Sig, '$!params');
my int $i := 0;
my int $n := nqp::elems(@params);
Expand Down Expand Up @@ -6141,18 +6142,35 @@ class Perl6::Actions is HLL::Actions does STDActions {
}
}
else {
# The rw-ness for is copy is handled by the container descriptor.
$var.push(QAST::Op.new(
:op('bind'),
QAST::Var.new( :name(%info<variable_name>), :scope('lexical') ),
QAST::Op.new(
:op('assignunchecked'),
# If the type means there's no way this could possible be
# Iterable, we know it can't flatten. This in turn means
# we need not wrap it in a read-only scalar.
my $wrap := $flags +& $SIG_ELEM_IS_COPY;
unless $wrap {
$wrap := nqp::istype($nomtype, $Iterable) || nqp::istype($Iterable, $nomtype);
}
if $wrap {
$var.push(QAST::Op.new(
:op('bind'),
QAST::Var.new( :name(%info<variable_name>), :scope('lexical') ),
QAST::Op.new(
:op('p6scalarfromdesc'),
QAST::WVal.new( :value(%info<container_descriptor>) )
),
QAST::Var.new( :name($name), :scope('local') )
)));
:op('assignunchecked'),
QAST::Op.new(
:op('p6scalarfromdesc'),
QAST::WVal.new( :value(%info<container_descriptor>) )
),
QAST::Var.new( :name($name), :scope('local') )
)));
}
else {
$var.push(QAST::Op.new(
:op('bind'),
QAST::Var.new( :name(%info<variable_name>), :scope('lexical') ),
QAST::Op.new(
:op('decont'),
QAST::Var.new( :name($name), :scope('local') )
)));
}

# Take care we don't undo explicit $_ bindings.
if %info<variable_name> eq '$_' && $*IMPLICIT {
Expand Down

0 comments on commit 2b89776

Please sign in to comment.