@@ -390,6 +390,75 @@ class QAST::OperationsJAST {
390
390
}
391
391
}
392
392
393
+ # Chaining.
394
+ QAST ::OperationsJAST. add_core_op(' chain' , -> $ qastcomp , $ op {
395
+ # First, we build up the list of nodes in the chain
396
+ my @ clist ;
397
+ my $ cpast := $ op ;
398
+ while nqp ::istype($ cpast , QAST ::Op) && $ cpast . op eq ' chain' {
399
+ nqp :: push (@ clist , $ cpast );
400
+ $ cpast := $ cpast [0 ];
401
+ }
402
+
403
+ my $ il := JAST::InstructionList. new ();
404
+ my $ result := $ * TA . fresh_o();
405
+ my $ endlabel := JAST::Label. new (: name($ qastcomp . unique (' chain_end_' )));
406
+
407
+ $ cpast := nqp :: pop (@ clist );
408
+ my $ apast := $ cpast [0 ];
409
+ my $ ares := $ qastcomp . as_jast($ apast , : want($ RT_OBJ ));
410
+ my $ atmp := $ * TA . fresh_o();
411
+ $ il . append ($ ares . jast);
412
+ $ * STACK . obtain($ il , $ ares );
413
+ $ il . append (JAST::Instruction. new ( : op(' astore' ), $ atmp ));
414
+
415
+ my $ more := 1 ;
416
+ while $ more {
417
+ my $ bpast := $ cpast [1 ];
418
+ my $ bres := $ qastcomp . as_jast($ bpast , : want($ RT_OBJ ));
419
+ my $ btmp := $ * TA . fresh_o();
420
+ $ il . append ($ bres . jast);
421
+ $ * STACK . obtain($ il , $ bres );
422
+ $ il . append (JAST::Instruction. new ( : op(' astore' ), $ btmp ));
423
+
424
+ my $ cs_idx := $ * CODEREFS . get_callsite_idx([$ ARG_OBJ , $ ARG_OBJ ], []);
425
+ $ il . append ($ ALOAD_1 );
426
+ $ il . append (JAST::Instruction. new ( : op(' aload' ), $ atmp ));
427
+ $ il . append (JAST::Instruction. new ( : op(' aload' ), $ btmp ));
428
+ $ il . append (JAST::InvokeDynamic. new (
429
+ ' subcall' , ' V' , [$ TYPE_TC , $ TYPE_SMO , $ TYPE_SMO ],
430
+ ' org/perl6/nqp/runtime/IndyBootstrap' , ' subcall' ,
431
+ [
432
+ JAST::PushSVal. new ( : value($ cpast . name ) ),
433
+ JAST::PushIndex. new ( : value($ cs_idx ) )
434
+ ]
435
+ ));
436
+ $ il . append (JAST::Instruction. new ( : op(' aload' ), ' cf' ));
437
+ $ il . append (JAST::Instruction. new ( : op(' invokestatic' ), $ TYPE_OPS ,
438
+ ' result_o' , $ TYPE_SMO , $ TYPE_CF ));
439
+ $ il . append (JAST::Instruction. new ( : op(' astore' ), $ result ));
440
+
441
+ if @ clist {
442
+ $ il . append (JAST::Instruction. new ( : op(' aload' ), $ result ));
443
+ $ il . append ($ ALOAD_1 );
444
+ $ il . append (JAST::Instruction. new ( : op(' invokestatic' ),
445
+ $ TYPE_OPS , ' istrue' , ' Long' , $ TYPE_SMO , $ TYPE_TC ));
446
+ $ il . append ($ IVAL_ZERO );
447
+ $ il . append ($ LCMP );
448
+ $ il . append (JAST::Instruction. new ( : op(' ifeq' ), $ endlabel ));
449
+ $ cpast := nqp :: pop (@ clist );
450
+ $ atmp := $ btmp ;
451
+ }
452
+ else {
453
+ $ more := 0 ;
454
+ }
455
+ }
456
+
457
+ $ il . append ($ endlabel );
458
+ $ il . append (JAST::Instruction. new ( : op(' aload' ), $ result ));
459
+ result($ il , $ RT_OBJ )
460
+ });
461
+
393
462
# Set of sequential statements
394
463
QAST ::OperationsJAST. add_core_op(' stmts' , -> $ qastcomp , $ op {
395
464
$ qastcomp . as_jast(QAST ::Stmts. new ( | @ ($ op ) ))
0 commit comments