Skip to content

Commit ec34571

Browse files
authored
Merge pull request #387 from jstuder-gh/neg_chaining
Rakudo Issue 1304: Preserve operator chaining when operators negated
2 parents 5b80052 + 92d1d56 commit ec34571

File tree

1 file changed

+22
-7
lines changed

1 file changed

+22
-7
lines changed

src/vm/moar/QAST/QASTOperationsMAST.nqp

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -628,37 +628,49 @@ QAST::MASTOperations.add_core_op('hash', -> $qastcomp, $op {
628628
});
629629

630630
# Chaining.
631+
# TODO: Provide static-optimizations where possible for invocations involving metaops
631632
my $chain_gen := sub ($qastcomp, $op) {
632633
# First, we build up the list of nodes in the chain
633634
my @clist;
634635
my $cqast := $op;
636+
637+
# Check if callee sub in name, if not first child is callee, not arg
638+
my $arg_idx;
639+
my &get_arg_idx := -> $cq { nqp::if( $cq.name, 0, 1 ) };
640+
635641
while nqp::istype($cqast, QAST::Op)
636642
&& ($cqast.op eq 'chain' || $cqast.op eq 'chainstatic') {
637643
nqp::push(@clist, $cqast);
638-
$cqast := $cqast[0];
644+
$arg_idx := get_arg_idx($cqast);
645+
$cqast := $cqast[$arg_idx];
639646
}
640647

641648
my @ops;
642649
my $regalloc := $*REGALLOC;
643650
my $res_reg := $regalloc.fresh_register($MVM_reg_obj);
651+
my $decont_reg := $regalloc.fresh_register($MVM_reg_obj);
644652
my $endlabel := MAST::Label.new();
645653

646654
$cqast := nqp::pop(@clist);
647-
my $aqast := $cqast[0];
655+
$arg_idx := get_arg_idx($cqast);
656+
657+
my $aqast := $cqast[$arg_idx];
648658
my $acomp := $qastcomp.as_mast($aqast, :want($MVM_reg_obj));
649659
push_ilist(@ops, $acomp);
650660

651661
my $more := 1;
652662
while $more {
653-
my $bqast := $cqast[1];
663+
my $bqast := $cqast[$arg_idx + 1];
654664
my $bcomp := $qastcomp.as_mast($bqast, :want($MVM_reg_obj));
655665
push_ilist(@ops, $bcomp);
656666

657667
my $callee := $qastcomp.as_mast: :want($MVM_reg_obj),
658-
$cqast.op eq 'chainstatic'
659-
?? QAST::VM.new: :moarop<getlexstatic_o>,
660-
QAST::SVal.new: :value($cqast.name)
661-
!! QAST::Var.new: :name( $cqast.name), :scope<lexical>;
668+
!$cqast.name
669+
?? $cqast[0]
670+
!! $cqast.op eq 'chainstatic'
671+
?? QAST::VM.new: :moarop<getlexstatic_o>,
672+
QAST::SVal.new: :value($cqast.name)
673+
!! QAST::Var.new: :name( $cqast.name), :scope<lexical>;
662674

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

671684
$regalloc.release_register($callee.result_reg, $MVM_reg_obj);
685+
$regalloc.release_register($decont_reg, $MVM_reg_obj);
672686
$regalloc.release_register($acomp.result_reg, $MVM_reg_obj);
673687

674688
if @clist {
675689
push_op(@ops, 'unless_o', $res_reg, $endlabel);
676690
$cqast := nqp::pop(@clist);
691+
$arg_idx := get_arg_idx($cqast);
677692
$acomp := $bcomp;
678693
}
679694
else {

0 commit comments

Comments
 (0)