示例#1
0
  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();
  }
示例#2
0
  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));
      }
    }
  }