@@ -628,37 +628,49 @@ QAST::MASTOperations.add_core_op('hash', -> $qastcomp, $op {
628
628
});
629
629
630
630
# Chaining.
631
+ # TODO: Provide static-optimizations where possible for invocations involving metaops
631
632
my $ chain_gen := sub ($ qastcomp , $ op ) {
632
633
# First, we build up the list of nodes in the chain
633
634
my @ clist ;
634
635
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
+
635
641
while nqp ::istype($ cqast , QAST ::Op)
636
642
&& ($ cqast . op eq ' chain' || $ cqast . op eq ' chainstatic' ) {
637
643
nqp :: push (@ clist , $ cqast );
638
- $ cqast := $ cqast [0 ];
644
+ $ arg_idx := get_arg_idx($ cqast );
645
+ $ cqast := $ cqast [$ arg_idx ];
639
646
}
640
647
641
648
my @ ops ;
642
649
my $ regalloc := $ * REGALLOC ;
643
650
my $ res_reg := $ regalloc . fresh_register($ MVM_reg_obj );
651
+ my $ decont_reg := $ regalloc . fresh_register($ MVM_reg_obj );
644
652
my $ endlabel := MAST::Label. new ();
645
653
646
654
$ cqast := nqp :: pop (@ clist );
647
- my $ aqast := $ cqast [0 ];
655
+ $ arg_idx := get_arg_idx($ cqast );
656
+
657
+ my $ aqast := $ cqast [$ arg_idx ];
648
658
my $ acomp := $ qastcomp . as_mast($ aqast , : want($ MVM_reg_obj ));
649
659
push_ilist(@ ops , $ acomp );
650
660
651
661
my $ more := 1 ;
652
662
while $ more {
653
- my $ bqast := $ cqast [1 ];
663
+ my $ bqast := $ cqast [$ arg_idx + 1 ];
654
664
my $ bcomp := $ qastcomp . as_mast($ bqast , : want($ MVM_reg_obj ));
655
665
push_ilist(@ ops , $ bcomp );
656
666
657
667
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 >;
662
674
663
675
push_ilist(@ ops , $ callee );
664
676
nqp :: push (@ ops , MAST::Call. new (
@@ -667,13 +679,16 @@ my $chain_gen := sub ($qastcomp, $op) {
667
679
: result($ res_reg ),
668
680
$ acomp . result_reg, $ bcomp . result_reg
669
681
));
682
+ push_op(@ ops , ' decont' , $ decont_reg , $ callee . result_reg);
670
683
671
684
$ regalloc . release_register($ callee . result_reg, $ MVM_reg_obj );
685
+ $ regalloc . release_register($ decont_reg , $ MVM_reg_obj );
672
686
$ regalloc . release_register($ acomp . result_reg, $ MVM_reg_obj );
673
687
674
688
if @ clist {
675
689
push_op(@ ops , ' unless_o' , $ res_reg , $ endlabel );
676
690
$ cqast := nqp :: pop (@ clist );
691
+ $ arg_idx := get_arg_idx($ cqast );
677
692
$ acomp := $ bcomp ;
678
693
}
679
694
else {
0 commit comments