Skip to content

Commit

Permalink
MoarVM: Allow 'chain' op to use child as callee
Browse files Browse the repository at this point in the history
Modify the 'chain' op to allow the option to use the first child as the
callee. Before the name of the op served as the operator sub and the
children the operands. This modification makes it so that, if there is
no name provided to the chain, child 0 serves as the operator and
children 1 and 2 the operands.

This modification is being made to coincide with a Rakudo development
allowing negated chained ops to continue to work as chained.

See <rakudo/rakudo#1304>.
  • Loading branch information
jstuder-gh committed Jan 8, 2018
1 parent 5b80052 commit 92d1d56
Showing 1 changed file with 22 additions and 7 deletions.
29 changes: 22 additions & 7 deletions src/vm/moar/QAST/QASTOperationsMAST.nqp
Expand Up @@ -628,37 +628,49 @@ QAST::MASTOperations.add_core_op('hash', -> $qastcomp, $op {
});

# Chaining.
# TODO: Provide static-optimizations where possible for invocations involving metaops
my $chain_gen := sub ($qastcomp, $op) {
# First, we build up the list of nodes in the chain
my @clist;
my $cqast := $op;

# Check if callee sub in name, if not first child is callee, not arg
my $arg_idx;
my &get_arg_idx := -> $cq { nqp::if( $cq.name, 0, 1 ) };

while nqp::istype($cqast, QAST::Op)
&& ($cqast.op eq 'chain' || $cqast.op eq 'chainstatic') {
nqp::push(@clist, $cqast);
$cqast := $cqast[0];
$arg_idx := get_arg_idx($cqast);
$cqast := $cqast[$arg_idx];
}

my @ops;
my $regalloc := $*REGALLOC;
my $res_reg := $regalloc.fresh_register($MVM_reg_obj);
my $decont_reg := $regalloc.fresh_register($MVM_reg_obj);
my $endlabel := MAST::Label.new();

$cqast := nqp::pop(@clist);
my $aqast := $cqast[0];
$arg_idx := get_arg_idx($cqast);

my $aqast := $cqast[$arg_idx];
my $acomp := $qastcomp.as_mast($aqast, :want($MVM_reg_obj));
push_ilist(@ops, $acomp);

my $more := 1;
while $more {
my $bqast := $cqast[1];
my $bqast := $cqast[$arg_idx + 1];
my $bcomp := $qastcomp.as_mast($bqast, :want($MVM_reg_obj));
push_ilist(@ops, $bcomp);

my $callee := $qastcomp.as_mast: :want($MVM_reg_obj),
$cqast.op eq 'chainstatic'
?? QAST::VM.new: :moarop<getlexstatic_o>,
QAST::SVal.new: :value($cqast.name)
!! QAST::Var.new: :name( $cqast.name), :scope<lexical>;
!$cqast.name
?? $cqast[0]
!! $cqast.op eq 'chainstatic'
?? QAST::VM.new: :moarop<getlexstatic_o>,
QAST::SVal.new: :value($cqast.name)
!! QAST::Var.new: :name( $cqast.name), :scope<lexical>;

push_ilist(@ops, $callee);
nqp::push(@ops, MAST::Call.new(
Expand All @@ -667,13 +679,16 @@ my $chain_gen := sub ($qastcomp, $op) {
:result($res_reg),
$acomp.result_reg, $bcomp.result_reg
));
push_op(@ops, 'decont', $decont_reg, $callee.result_reg);

$regalloc.release_register($callee.result_reg, $MVM_reg_obj);
$regalloc.release_register($decont_reg, $MVM_reg_obj);
$regalloc.release_register($acomp.result_reg, $MVM_reg_obj);

if @clist {
push_op(@ops, 'unless_o', $res_reg, $endlabel);
$cqast := nqp::pop(@clist);
$arg_idx := get_arg_idx($cqast);
$acomp := $bcomp;
}
else {
Expand Down

0 comments on commit 92d1d56

Please sign in to comment.