public Operand getArg(int argIndex, boolean restOfArgArray) { if (!restOfArgArray) return getArg(argIndex); if (isClosure) throw new RuntimeException("Cannot get rest yield arg at inline time!"); if (argIndex >= callArgs.length) return new Array(); Operand[] tmp = new Operand[callArgs.length - argIndex]; System.arraycopy(callArgs, argIndex, tmp, 0, callArgs.length - argIndex); return new Array(tmp); }
public Operand getArg(int index) { // yield 1 -> { |a| } case if (canMapArgsStatically && isClosure && !(yieldArg instanceof Array)) return yieldArg; return index < getArgsCount() ? (isClosure ? ((Array)yieldArg).get(index) : callArgs[index]) : null; }
@Override public Operand getSimplifiedOperand(Map<Operand, Operand> valueMap, boolean force) { Operand newArray = array.getSimplifiedOperand(valueMap, force); if (newArray instanceof Array) { Array a = (Array) newArray; return (a.getElts().length == 1) ? a.getElts()[0] : a; } else { return (newArray == array) ? this : new SValue(newArray); } }
@Override public Operand cloneForInlining(InlinerInfo ii) { if (hasKnownValue()) return this; Operand[] newElts = new Operand[elts.length]; for (int i = 0; i < elts.length; i++) { newElts[i] = elts[i].cloneForInlining(ii); } return new Array(newElts); }
public void setupYieldArgsAndYieldResult(YieldInstr yi, BasicBlock yieldBB, int blockArityValue) { Operand yieldInstrArg = yi.getYieldArg(); if ((yieldInstrArg == UndefinedValue.UNDEFINED) || blockArityValue == 0) { yieldArg = new Array(); // Zero-elt array } else if (yieldInstrArg instanceof Array) { yieldArg = yieldInstrArg; // 1:1 arg match if (((Array) yieldInstrArg).size() == blockArityValue) canMapArgsStatically = true; } else if (blockArityValue == 1 && yi.unwrapArray == false) { yieldArg = yieldInstrArg; 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 = getHostScope(); Variable yieldArgArray = callerScope.createTemporaryVariable(); yieldBB.addInstr(new ToAryInstr(yieldArgArray, yieldInstrArg)); yieldArg = yieldArgArray; } yieldResult = yi.getResult(); }
@Override public Operand simplifyAndGetResult(IRScope scope, Map<Operand, Operand> valueMap) { simplifyOperands(valueMap, false); Operand val = getArray().getValue(valueMap); if (val instanceof Array) { Array a = (Array)val; int n = a.size(); int i = IRRuntimeHelpers.irReqdArgMultipleAsgnIndex(n, preArgsCount, index, postArgsCount); return i == -1 ? scope.getManager().getNil() : a.get(i); } else { return null; } }
public int getArgsCount() { return canMapArgsStatically ? (isClosure ? ((Array)yieldArg).size() : callArgs.length) : -1; }
@Interp @Override public Object interpret(ThreadContext context, StaticScope currScope, DynamicScope currDynScope, IRubyObject self, Object[] temp) { Block blk = (Block)getBlockArg().retrieve(context, self, currScope, currDynScope, temp); if (getYieldArg() == UndefinedValue.UNDEFINED) { return IRRuntimeHelpers.yieldSpecific(context, blk); } else { Operand yieldOp = getYieldArg(); if (unwrapArray && yieldOp instanceof Array && ((Array)yieldOp).size() > 1) { // Special case this path! // Don't build a RubyArray. return blk.yieldValues(context, ((Array)yieldOp).retrieveArrayElts(context, self, currScope, currDynScope, temp)); } else { IRubyObject yieldVal = (IRubyObject) yieldOp.retrieve(context, self, currScope, currDynScope, temp); return IRRuntimeHelpers.yield(context, blk, yieldVal, unwrapArray); } } }
@Override public String toString() { return "Array:" + (isBlank() ? "[]" : java.util.Arrays.toString(elts)); }
@Override public Object retrieve(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) { switch (elts.length) { case 0: return context.runtime.newEmptyArray(); case 1: return context.runtime.newArray((IRubyObject) elts[0].retrieve(context, self, currScope, currDynScope, temp)); case 2: return context.runtime.newArray((IRubyObject) elts[0].retrieve(context, self, currScope, currDynScope, temp), (IRubyObject) elts[1].retrieve(context, self, currScope, currDynScope, temp)); default: return RubyArray.newArrayMayCopy(context.runtime, retrieveArrayElts(context, self, currScope, currDynScope, temp)); } }
case ARRAY: return Array.decode(this); case AS_STRING: return AsString.decode(this); case BIGNUM: return Bignum.decode(this);
@Override public Operand cloneForInlining(InlinerInfo ii) { if (hasKnownValue()) return this; Operand[] newElts = new Operand[elts.length]; for (int i = 0; i < elts.length; i++) { newElts[i] = elts[i].cloneForInlining(ii); } return new Array(newElts); }
public void setupYieldArgsAndYieldResult(YieldInstr yi, BasicBlock yieldBB, int blockArityValue) { Operand yieldInstrArg = yi.getYieldArg(); if ((yieldInstrArg == UndefinedValue.UNDEFINED) || blockArityValue == 0) { yieldArg = new Array(); // Zero-elt array } else if (yieldInstrArg instanceof Array) { yieldArg = yieldInstrArg; // 1:1 arg match if (((Array) yieldInstrArg).size() == blockArityValue) canMapArgsStatically = true; } else if (blockArityValue == 1 && yi.unwrapArray == false) { yieldArg = yieldInstrArg; 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 = getHostScope(); Variable yieldArgArray = callerScope.createTemporaryVariable(); yieldBB.addInstr(new ToAryInstr(yieldArgArray, yieldInstrArg)); yieldArg = yieldArgArray; } yieldResult = yi.getResult(); }
@Override public Operand simplifyAndGetResult(IRScope scope, Map<Operand, Operand> valueMap) { simplifyOperands(valueMap, false); Operand val = getArray().getValue(valueMap); if (val instanceof Array) { Array a = (Array)val; int n = a.size(); int i = IRRuntimeHelpers.irReqdArgMultipleAsgnIndex(n, preArgsCount, index, postArgsCount); return i == -1 ? scope.getManager().getNil() : a.get(i); } else { return null; } }
public int getArgsCount() { return canMapArgsStatically ? (isClosure ? ((Array)yieldArg).size() : callArgs.length) : -1; }
@Interp @Override public Object interpret(ThreadContext context, StaticScope currScope, DynamicScope currDynScope, IRubyObject self, Object[] temp) { Block blk = (Block)getBlockArg().retrieve(context, self, currScope, currDynScope, temp); if (getYieldArg() == UndefinedValue.UNDEFINED) { return IRRuntimeHelpers.yieldSpecific(context, blk); } else { Operand yieldOp = getYieldArg(); if (unwrapArray && yieldOp instanceof Array && ((Array)yieldOp).size() > 1) { // Special case this path! // Don't build a RubyArray. return blk.yieldValues(context, ((Array)yieldOp).retrieveArrayElts(context, self, currScope, currDynScope, temp)); } else { IRubyObject yieldVal = (IRubyObject) yieldOp.retrieve(context, self, currScope, currDynScope, temp); return IRRuntimeHelpers.yield(context, blk, yieldVal, unwrapArray); } } }
@Override public String toString() { return "Array:" + (isBlank() ? "[]" : java.util.Arrays.toString(elts)); }
@Override public Object retrieve(ThreadContext context, IRubyObject self, StaticScope currScope, DynamicScope currDynScope, Object[] temp) { switch (elts.length) { case 0: return context.runtime.newEmptyArray(); case 1: return context.runtime.newArray((IRubyObject) elts[0].retrieve(context, self, currScope, currDynScope, temp)); case 2: return context.runtime.newArray((IRubyObject) elts[0].retrieve(context, self, currScope, currDynScope, temp), (IRubyObject) elts[1].retrieve(context, self, currScope, currDynScope, temp)); default: return RubyArray.newArrayMayCopy(context.runtime, retrieveArrayElts(context, self, currScope, currDynScope, temp)); } }
case ARRAY: return Array.decode(this); case AS_STRING: return AsString.decode(this); case BIGNUM: return Bignum.decode(this);
public Operand getArg(int argIndex, boolean restOfArgArray) { if (!restOfArgArray) return getArg(argIndex); if (isClosure) throw new RuntimeException("Cannot get rest yield arg at inline time!"); if (argIndex >= callArgs.length) return new Array(); Operand[] tmp = new Operand[callArgs.length - argIndex]; System.arraycopy(callArgs, argIndex, tmp, 0, callArgs.length - argIndex); return new Array(tmp); }