Operand |
IR_Builder.buildDAsgn(DAsgnNode dasgnNode,
IR_Scope s)
public Operand buildGetDefinitionBase(final Node node, IR_Scope m) {
switch (node.getNodeType()) {
case CLASSVARASGNNODE:
case CLASSVARDECLNODE:
case CONSTDECLNODE:
case DASGNNODE:
case GLOBALASGNNODE:
case LOCALASGNNODE:
case MULTIPLEASGNNODE:
case OPASGNNODE:
case OPELEMENTASGNNODE:
case DVARNODE:
case FALSENODE:
case TRUENODE:
case LOCALVARNODE:
case INSTVARNODE:
case BACKREFNODE:
case SELFNODE:
case VCALLNODE:
case YIELDNODE:
case GLOBALVARNODE:
case CONSTNODE:
case FCALLNODE:
case CLASSVARNODE:
// these are all simple cases that don't require the heavier defined logic
buildGetDefinition(node, m);
break;
default:
BranchCallback reg = new BranchCallback() {
public void branch(IR_Scope m) {
m.inDefined();
buildGetDefinition(node, m);
}
};
BranchCallback out = new BranchCallback() {
public void branch(IR_Scope m) {
m.outDefined();
}
};
m.protect(reg, out, String.class);
}
}
public Operand buildDefined(final Node node, IR_Scope m) {
buildGetDefinitionBase(((DefinedNode) node).getExpressionNode(), m);
m.stringOrNil();
}
public Operand buildGetArgumentDefinition(final Node node, IR_Scope m, String type) {
if (node == null) {
return new StringLiteral(type);
} else if (node instanceof ArrayNode) {
Object endToken = m.getNewEnding();
for (int i = 0; i < ((ArrayNode) node).size(); i++) {
Node iterNode = ((ArrayNode) node).get(i);
buildGetDefinition(iterNode, m);
m.ifNull(endToken);
}
Operand sl = new StringLiteral(type);
Object realToken = m.getNewEnding();
m.go(realToken);
m.setEnding(endToken);
m.pushNull();
m.setEnding(realToken);
} else {
buildGetDefinition(node, m);
Object endToken = m.getNewEnding();
m.ifNull(endToken);
Operand sl = new StringLiteral(type);
Object realToken = m.getNewEnding();
m.go(realToken);
m.setEnding(endToken);
m.pushNull();
m.setEnding(realToken);
}
}
public Operand buildGetDefinition(final Node node, IR_Scope m) {
switch (node.getNodeType()) {
case CLASSVARASGNNODE:
case CLASSVARDECLNODE:
case CONSTDECLNODE:
case DASGNNODE:
case GLOBALASGNNODE:
case LOCALASGNNODE:
case MULTIPLEASGNNODE:
case OPASGNNODE:
case OPELEMENTASGNNODE:
return new StringLiteral("assignment");
case BACKREFNODE:
// SSS FIXME!
Operand x = m.backref();
return x instanceof RubyMatchData.class ? new StringLiteral("$" + ((BackRefNode) node).getType()) : Nil.NIL;
case DVARNODE:
return new StringLiteral("local-variable(in-block)");
case FALSENODE:
return new StringLiteral("false");
case TRUENODE:
return new StringLiteral("true");
case LOCALVARNODE:
return new StringLiteral("local-variable");
case MATCH2NODE:
case MATCH3NODE:
return new StringLiteral("method");
case NILNODE:
return new StringLiteral("nil");
case NTHREFNODE:
m.isCaptured(((NthRefNode) node).getMatchNumber(),
new BranchCallback() {
public void branch(IR_Scope m) {
return new StringLiteral("$" + ((NthRefNode) node).getMatchNumber());
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
return Nil.NIL;
}
});
break;
case SELFNODE:
return new StringLiteral("self");
case VCALLNODE:
m.loadSelf();
m.isMethodBound(((VCallNode) node).getName(),
new BranchCallback() {
public void branch(IR_Scope m) {
return new StringLiteral("method");
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
return Nil.NIL;
}
});
break;
case YIELDNODE:
m.hasBlock(new BranchCallback() {
public void branch(IR_Scope m) {
return new StringLiteral("yield");
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
return Nil.NIL;
}
});
break;
case GLOBALVARNODE:
m.isGlobalDefined(((GlobalVarNode) node).getName(),
new BranchCallback() {
public void branch(IR_Scope m) {
return new StringLiteral("global-variable");
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
return Nil.NIL;
}
});
break;
case INSTVARNODE:
m.isInstanceVariableDefined(((InstVarNode) node).getName(),
new BranchCallback() {
public void branch(IR_Scope m) {
return new StringLiteral("instance-variable");
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
return Nil.NIL;
}
});
break;
case CONSTNODE:
m.isConstantDefined(((ConstNode) node).getName(),
new BranchCallback() {
public void branch(IR_Scope m) {
return new StringLiteral("constant");
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
return Nil.NIL;
}
});
break;
case FCALLNODE:
m.loadSelf();
m.isMethodBound(((FCallNode) node).getName(),
new BranchCallback() {
public void branch(IR_Scope m) {
buildGetArgumentDefinition(((FCallNode) node).getArgsNode(), m, "method");
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
return Nil.NIL;
}
});
break;
case COLON3NODE:
case COLON2NODE:
{
final Colon3Node iVisited = (Colon3Node) node;
final String name = iVisited.getName();
BranchCallback setup = new BranchCallback() {
public void branch(IR_Scope m) {
if (iVisited instanceof Colon2Node) {
final Node leftNode = ((Colon2Node) iVisited).getLeftNode();
build(leftNode, m,true);
} else {
m.loadObject();
}
}
};
BranchCallback isConstant = new BranchCallback() {
public void branch(IR_Scope m) {
return new StringLiteral("constant");
}
};
BranchCallback isMethod = new BranchCallback() {
public void branch(IR_Scope m) {
return new StringLiteral("method");
}
};
BranchCallback none = new BranchCallback() {
public void branch(IR_Scope m) {
return Nil.NIL;
}
};
m.isConstantBranch(setup, isConstant, isMethod, none, name);
break;
}
case CALLNODE:
{
final CallNode iVisited = (CallNode) node;
Object isnull = m.getNewEnding();
Object ending = m.getNewEnding();
buildGetDefinition(iVisited.getReceiverNode(), m);
m.ifNull(isnull);
m.rescue(new BranchCallback() {
public void branch(IR_Scope m) {
build(iVisited.getReceiverNode(), m,true); //[IRubyObject]
m.duplicateCurrentValue(); //[IRubyObject, IRubyObject]
m.metaclass(); //[IRubyObject, RubyClass]
m.duplicateCurrentValue(); //[IRubyObject, RubyClass, RubyClass]
m.getVisibilityFor(iVisited.getName()); //[IRubyObject, RubyClass, Visibility]
m.duplicateCurrentValue(); //[IRubyObject, RubyClass, Visibility, Visibility]
final Object isfalse = m.getNewEnding();
Object isreal = m.getNewEnding();
Object ending = m.getNewEnding();
m.isPrivate(isfalse, 3); //[IRubyObject, RubyClass, Visibility]
m.isNotProtected(isreal, 1); //[IRubyObject, RubyClass]
m.selfIsKindOf(isreal); //[IRubyObject]
m.consumeCurrentValue();
m.go(isfalse);
m.setEnding(isreal); //[]
m.isMethodBound(iVisited.getName(), new BranchCallback() {
public void branch(IR_Scope m) {
buildGetArgumentDefinition(iVisited.getArgsNode(), m, "method");
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
m.go(isfalse);
}
});
m.go(ending);
m.setEnding(isfalse);
m.pushNull();
m.setEnding(ending);
}
}, JumpException.class,
new BranchCallback() {
public void branch(IR_Scope m) {
m.pushNull();
}
}, String.class);
// m.swapValues();
//m.consumeCurrentValue();
m.go(ending);
m.setEnding(isnull);
m.pushNull();
m.setEnding(ending);
break;
}
case CLASSVARNODE:
{
ClassVarNode iVisited = (ClassVarNode) node;
final Object ending = m.getNewEnding();
final Object failure = m.getNewEnding();
final Object singleton = m.getNewEnding();
Object second = m.getNewEnding();
Object third = m.getNewEnding();
m.loadCurrentModule(); //[RubyClass]
m.duplicateCurrentValue(); //[RubyClass, RubyClass]
m.ifNotNull(second); //[RubyClass]
m.consumeCurrentValue(); //[]
m.loadSelf(); //[self]
m.metaclass(); //[RubyClass]
m.duplicateCurrentValue(); //[RubyClass, RubyClass]
m.isClassVarDefined(iVisited.getName(),
new BranchCallback() {
public void branch(IR_Scope m) {
m.consumeCurrentValue();
Operand sl = new StringLiteral("class variable");
m.go(ending);
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
}
});
m.setEnding(second); //[RubyClass]
m.duplicateCurrentValue();
m.isClassVarDefined(iVisited.getName(),
new BranchCallback() {
public void branch(IR_Scope m) {
m.consumeCurrentValue();
Operand sl = new StringLiteral("class variable");
m.go(ending);
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
}
});
m.setEnding(third); //[RubyClass]
m.duplicateCurrentValue(); //[RubyClass, RubyClass]
m.ifSingleton(singleton); //[RubyClass]
m.consumeCurrentValue();//[]
m.go(failure);
m.setEnding(singleton);
m.attached();//[RubyClass]
m.notIsModuleAndClassVarDefined(iVisited.getName(), failure); //[]
Operand sl = new StringLiteral("class variable");
m.go(ending);
m.setEnding(failure);
m.pushNull();
m.setEnding(ending);
}
break;
case ZSUPERNODE:
{
Object fail = m.getNewEnding();
Object fail2 = m.getNewEnding();
Object fail_easy = m.getNewEnding();
Object ending = m.getNewEnding();
m.getFrameName(); //[String]
m.duplicateCurrentValue(); //[String, String]
m.ifNull(fail); //[String]
m.getFrameKlazz(); //[String, RubyClass]
m.duplicateCurrentValue(); //[String, RubyClass, RubyClass]
m.ifNull(fail2); //[String, RubyClass]
m.superClass();
m.ifNotSuperMethodBound(fail_easy);
Operand sl = new StringLiteral("super");
m.go(ending);
m.setEnding(fail2);
m.consumeCurrentValue();
m.setEnding(fail);
m.consumeCurrentValue();
m.setEnding(fail_easy);
m.pushNull();
m.setEnding(ending);
}
break;
case SUPERNODE:
{
Object fail = m.getNewEnding();
Object fail2 = m.getNewEnding();
Object fail_easy = m.getNewEnding();
Object ending = m.getNewEnding();
m.getFrameName(); //[String]
m.duplicateCurrentValue(); //[String, String]
m.ifNull(fail); //[String]
m.getFrameKlazz(); //[String, RubyClass]
m.duplicateCurrentValue(); //[String, RubyClass, RubyClass]
m.ifNull(fail2); //[String, RubyClass]
m.superClass();
m.ifNotSuperMethodBound(fail_easy);
buildGetArgumentDefinition(((SuperNode) node).getArgsNode(), m, "super");
m.go(ending);
m.setEnding(fail2);
m.consumeCurrentValue();
m.setEnding(fail);
m.consumeCurrentValue();
m.setEnding(fail_easy);
m.pushNull();
m.setEnding(ending);
break;
}
case ATTRASSIGNNODE:
{
final AttrAssignNode iVisited = (AttrAssignNode) node;
Object isnull = m.getNewEnding();
Object ending = m.getNewEnding();
buildGetDefinition(iVisited.getReceiverNode(), m);
m.ifNull(isnull);
m.rescue(new BranchCallback() {
public void branch(IR_Scope m) {
build(iVisited.getReceiverNode(), m,true); //[IRubyObject]
m.duplicateCurrentValue(); //[IRubyObject, IRubyObject]
m.metaclass(); //[IRubyObject, RubyClass]
m.duplicateCurrentValue(); //[IRubyObject, RubyClass, RubyClass]
m.getVisibilityFor(iVisited.getName()); //[IRubyObject, RubyClass, Visibility]
m.duplicateCurrentValue(); //[IRubyObject, RubyClass, Visibility, Visibility]
final Object isfalse = m.getNewEnding();
Object isreal = m.getNewEnding();
Object ending = m.getNewEnding();
m.isPrivate(isfalse, 3); //[IRubyObject, RubyClass, Visibility]
m.isNotProtected(isreal, 1); //[IRubyObject, RubyClass]
m.selfIsKindOf(isreal); //[IRubyObject]
m.consumeCurrentValue();
m.go(isfalse);
m.setEnding(isreal); //[]
m.isMethodBound(iVisited.getName(), new BranchCallback() {
public void branch(IR_Scope m) {
buildGetArgumentDefinition(iVisited.getArgsNode(), m, "assignment");
}
},
new BranchCallback() {
public void branch(IR_Scope m) {
m.go(isfalse);
}
});
m.go(ending);
m.setEnding(isfalse);
m.pushNull();
m.setEnding(ending);
}
}, JumpException.class,
new BranchCallback() {
public void branch(IR_Scope m) {
m.pushNull();
}
}, String.class);
m.go(ending);
m.setEnding(isnull);
m.pushNull();
m.setEnding(ending);
break;
}
default:
m.rescue(new BranchCallback() {
public void branch(IR_Scope m) {
build(node, m,true);
m.consumeCurrentValue();
m.pushNull();
}
}, JumpException.class,
new BranchCallback() {
public void branch(IR_Scope m) {
m.pushNull();
}
}, String.class);
m.consumeCurrentValue();
//MPS_FIXME: new StringLiteral("expression");
}
} |