public void setupYieldArgsAndYieldResult(YieldInstr yi, BasicBlock yieldBB, Arity blockArity) { int blockArityValue = blockArity.getValue(); Operand yieldInstrArg = yi.getYieldArg(); if ((yieldInstrArg == UndefinedValue.UNDEFINED) || (blockArityValue == 0)) { this.yieldArg = new Array(); // Zero-elt array } else if (yieldInstrArg instanceof Array) { this.yieldArg = yieldInstrArg; // 1:1 arg match if (((Array) yieldInstrArg).size() == blockArityValue) canMapArgsStatically = true; } else { // SSS FIXME: The code below is not entirely correct. We have to process 'yi.getYieldArg()' // similar // to how InterpretedIRBlockBody (1.8 and 1.9 modes) processes it. We may need a special // instruction // that takes care of aligning the stars and bringing good fortune to arg yielder and arg // receiver. IRScope callerScope = getInlineHostScope(); boolean needSpecialProcessing = (blockArityValue != -1) && (blockArityValue != 1); Variable yieldArgArray = callerScope.getNewTemporaryVariable(); yieldBB.addInstr( new ToAryInstr(yieldArgArray, yieldInstrArg, callerScope.getManager().getTrue())); this.yieldArg = yieldArgArray; } this.yieldResult = yi.getResult(); }
public void processClosureArgAndReturnInstrs(InlinerInfo ii, YieldInstr yi) { Variable yieldResult = ii.getRenamedVariable(yi.result); Operand[] yieldArgs = yi.getNonBlockOperands(); for (ListIterator<Instr> it = ((ArrayList<Instr>) _instrs).listIterator(); it.hasNext(); ) { Instr i = it.next(); if (i instanceof ClosureReturnInstr) { // Replace the closure return receive with a simple copy it.set(new CopyInstr(yieldResult, ((ClosureReturnInstr) i).getArg())); } else if (i instanceof ReceiveSelfInstruction) { ReceiveSelfInstruction rsi = (ReceiveSelfInstruction) i; // SSS FIXME: It is not always the case that the call receiver is also the %self within // a block Ex: ... r.foo(args) { ... blah .. }. i.e. there are scenarios where %self // within the block is not identical to 'r'. Handle this! if (!rsi.result.equals(ii.getCallReceiver())) it.set(new CopyInstr(rsi.result, ii.getCallReceiver())); else it.set(NopInstr.NOP); } else if (i instanceof ReceiveClosureInstr) { ReceiveClosureInstr rci = (ReceiveClosureInstr) i; if (!rci.result.equals(ii.getCallClosure())) it.set(new CopyInstr(rci.result, ii.getCallClosure())); else it.set(NopInstr.NOP); } else if (i instanceof ReceiveClosureArgInstr) { Operand closureArg; ReceiveClosureArgInstr rcai = (ReceiveClosureArgInstr) i; int argIndex = rcai.argIndex; boolean restOfArgs = rcai.restOfArgArray; if (argIndex < yieldArgs.length) { closureArg = yieldArgs[argIndex].cloneForInlining(ii); } else if (argIndex >= yieldArgs.length) { closureArg = new Array(); } else { Operand[] tmp = new Operand[yieldArgs.length - argIndex]; for (int j = argIndex; j < yieldArgs.length; j++) tmp[j - argIndex] = yieldArgs[j].cloneForInlining(ii); closureArg = new Array(tmp); } // Replace the arg receive with a simple copy it.set(new CopyInstr(rcai.result, closureArg)); } } }