protected LocalVariable getBlockArgVariable(RubySymbol name, int depth) { if (!(scope instanceof IRFor)) throw new NotCompilableException("Cannot ask for block-arg variable in 1.9 mode"); return getLocalVariable(name, depth); }
protected LocalVariable getArgVariable(RubySymbol name, int depth) { // For non-loops, this name will override any name that exists in outer scopes return scope instanceof IRFor ? getLocalVariable(name, depth) : getNewLocalVariable(name, 0); }
protected LocalVariable getBlockArgVariable(RubySymbol name, int depth) { if (!(scope instanceof IRFor)) throw new NotCompilableException("Cannot ask for block-arg variable in 1.9 mode"); return getLocalVariable(name, depth); }
protected LocalVariable getArgVariable(RubySymbol name, int depth) { // For non-loops, this name will override any name that exists in outer scopes return scope instanceof IRFor ? getLocalVariable(name, depth) : getNewLocalVariable(name, 0); }
public Operand buildDVar(DVarNode node) { return getLocalVariable(node.getName(), node.getDepth()); }
public Operand buildLocalVar(LocalVarNode node) { return getLocalVariable(node.getName(), node.getDepth()); }
public Operand buildLocalVar(LocalVarNode node) { return getLocalVariable(node.getName(), node.getDepth()); }
public Operand buildDVar(DVarNode node) { return getLocalVariable(node.getName(), node.getDepth()); }
public Operand buildLocalAsgn(LocalAsgnNode localAsgnNode) { Variable variable = getLocalVariable(localAsgnNode.getName(), localAsgnNode.getDepth()); Operand value = build(variable, localAsgnNode.getValueNode()); // no use copying a variable to itself if (variable == value) return value; addInstr(new CopyInstr(variable, value)); return value; // IMPORTANT: The return value of this method is value, not var! // // Consider this Ruby code: foo((a = 1), (a = 2)) // // If we return 'value' this will get translated to: // a = 1 // a = 2 // call("foo", [1,2]) <---- CORRECT // // If we return 'var' this will get translated to: // a = 1 // a = 2 // call("foo", [a,a]) <---- BUGGY // // This technique only works if 'value' is an immutable value (ex: fixnum) or a variable // So, for Ruby code like this: // def foo(x); x << 5; end; // foo(a=[1,2]); // p a // we are guaranteed that the value passed into foo and 'a' point to the same object // because of the use of copyAndReturnValue method for literal objects. }
Variable arg = getLocalVariable(dasgnNode.getName(), depth); Operand value = build(dasgnNode.getValueNode());
public Operand buildLocalAsgn(LocalAsgnNode localAsgnNode) { Variable variable = getLocalVariable(localAsgnNode.getName(), localAsgnNode.getDepth()); Operand value = build(variable, localAsgnNode.getValueNode()); // no use copying a variable to itself if (variable == value) return value; addInstr(new CopyInstr(variable, value)); return value; // IMPORTANT: The return value of this method is value, not var! // // Consider this Ruby code: foo((a = 1), (a = 2)) // // If we return 'value' this will get translated to: // a = 1 // a = 2 // call("foo", [1,2]) <---- CORRECT // // If we return 'var' this will get translated to: // a = 1 // a = 2 // call("foo", [a,a]) <---- BUGGY // // This technique only works if 'value' is an immutable value (ex: fixnum) or a variable // So, for Ruby code like this: // def foo(x); x << 5; end; // foo(a=[1,2]); // p a // we are guaranteed that the value passed into foo and 'a' point to the same object // because of the use of copyAndReturnValue method for literal objects. }
Variable arg = getLocalVariable(dasgnNode.getName(), depth); Operand value = build(dasgnNode.getValueNode());
public Operand buildMatch2(Variable result, Match2Node matchNode) { Operand receiver = build(matchNode.getReceiverNode()); Operand value = build(matchNode.getValueNode()); if (result == null) result = createTemporaryVariable(); addInstr(new MatchInstr(scope, result, receiver, value)); if (matchNode instanceof Match2CaptureNode) { Match2CaptureNode m2c = (Match2CaptureNode)matchNode; for (int slot: m2c.getScopeOffsets()) { // Static scope scope offsets store both depth and offset int depth = slot >> 16; int offset = slot & 0xffff; // For now, we'll continue to implicitly reference "$~" RubySymbol var = manager.runtime.newSymbol(getVarNameFromScopeTree(scope, depth, offset)); addInstr(new SetCapturedVarInstr(getLocalVariable(var, depth), result, var)); } } return result; }
public Operand buildMatch2(Variable result, Match2Node matchNode) { Operand receiver = build(matchNode.getReceiverNode()); Operand value = build(matchNode.getValueNode()); if (result == null) result = createTemporaryVariable(); addInstr(new MatchInstr(scope, result, receiver, value)); if (matchNode instanceof Match2CaptureNode) { Match2CaptureNode m2c = (Match2CaptureNode)matchNode; for (int slot: m2c.getScopeOffsets()) { // Static scope scope offsets store both depth and offset int depth = slot >> 16; int offset = slot & 0xffff; // For now, we'll continue to implicitly reference "$~" RubySymbol var = manager.runtime.newSymbol(getVarNameFromScopeTree(scope, depth, offset)); addInstr(new SetCapturedVarInstr(getLocalVariable(var, depth), result, var)); } } return result; }
DAsgnNode variable = (DAsgnNode) node; int depth = variable.getDepth(); addInstr(new CopyInstr(getLocalVariable(variable.getName(), depth), rhsVal)); break; LocalAsgnNode localVariable = (LocalAsgnNode) node; int depth = localVariable.getDepth(); addInstr(new CopyInstr(getLocalVariable(localVariable.getName(), depth), rhsVal)); break;
DAsgnNode variable = (DAsgnNode) node; int depth = variable.getDepth(); addInstr(new CopyInstr(getLocalVariable(variable.getName(), depth), rhsVal)); break; LocalAsgnNode localVariable = (LocalAsgnNode) node; int depth = localVariable.getDepth(); addInstr(new CopyInstr(getLocalVariable(localVariable.getName(), depth), rhsVal)); break;