Truffle: [TypeSystemCodeGenerator + ShortCircuit] generate a buggy code
christian.humer at gmail.com
christian.humer at gmail.com
Fri Jun 5 12:10:56 UTC 2015
Hi,
Thanks for the report. This is indeed broken. I fixed it and it will
arrive in the OpenJDK repository sometime today.
Some further remarks about your code.
1) The order attribute declarations in your specializations have no
effect anymore. You can safely remove them. The method declaration order
is now used to define the order in which specializations are
specialized.
2) In our current languages we tend to implement short circuiting or
nodes like this without specializations:
@NodeInfo(shortName = "or")
public abstract static class OrNode extends ExpressionNode {
@Child private ExpressionNode leftNode;
@Child private ExpressionNode rightNode;
@Child private YesNode booleanCast = YesNodeFactory.create(null);
public OrNode(ExpressionNode leftNode, ExpressionNode rightNode) {
this.leftNode = leftNode;
this.rightNode = rightNode;
}
public Object execute(VirtualFrame frame) {
Object left = leftNode.execute(frame);
if (booleanCast.executeBoolean(frame, left)) {
return rightNode.execute(frame);
}
return left;
}
}
This would also be a valid workaround for the bug you have reported.
Thanks again, and have fun.
- Christian Humer
------ Original Message ------
From: "Mohaned Y Qunaibit" <mqunaibi at uci.edu>
To: graal-dev at openjdk.java.net
Sent: 05.06.2015 09:19:50
Subject: Truffle: [TypeSystemCodeGenerator + ShortCircuit] generate a
buggy code
>Hi,
>
>When we have a binary node that doesn't always execute both nodes,
>(like
>AND, OR), TypeSystemCodeGenerator generate a type specialized node but
>with
>the assumption that it can read both two children types.
>Example:
>Evaluate: "2 or 0"
>
> @NodeInfo(shortName = "or")
> @GenerateNodeFactory
> public abstract static class OrNode extends BinaryOpNode {
>
> @Child protected YesNode booleanCast;
> public OrNode() {
> this.booleanCast =
>YesNodeFactory.create(EmptyNode.create());
> }
>
> @ShortCircuit("rightNode")
> public boolean needsRightNode(VirtualFrame frame, Object left)
>{
> return !booleanCast.executeBoolean(frame, left);
> }
>
> @Specialization(order = 0)
> public boolean doBoolean(boolean left, boolean needsRight,
>boolean
>right) {
> return needsRight ? right : left;
> }
>
> @Specialization(order = 1)
> public int doInteger(int left, boolean needsRight, int right) {
> return needsRight ? right : left;
> }
>
> }
>
>Generated node:
>
> @GeneratedBy(OrNode.class)
> public static final class OrNodeGen extends OrNode implements
>SpecializedNode {
> ...
> public Object execute(VirtualFrame frameValue) {
> Object leftNodeValue_ =
>executeLeftNode_(frameValue);
> boolean hasRightNodeValue =
>root.needsRightNode(frameValue, leftNodeValue_); // return false
> Object *rightNodeValue_ = null*;
> if (hasRightNodeValue) {
> rightNodeValue_ =
>executeRightNode_(frameValue);
> }
> return execute_(frameValue, leftNodeValue_,
>hasRightNodeValue, *rightNodeValue_*);
> }
>
> ...
> @GeneratedBy(methodName = "doInteger(int, boolean, int)",
>value
>= OrNode.class)
> private static final class IntegerNode_ extends BaseNode_ {
>
> private final Class<?> leftNodeImplicitType;
> private final Class<?> rightNodeImplicitType;
>
> IntegerNode_(OrNodeGen root, Object leftNodeValue,
>Object
>*rightNodeValue*) { // rightNodeValue = null
> super(root, 2);
> this.leftNodeImplicitType =
>LanguageTypesGen.getImplicitIntegerClass(leftNodeValue);
> this.rightNodeImplicitType =
>*LanguageTypesGen.getImplicitIntegerClass(rightNodeValue);
>// Throws exception*
> }
> ...
> }
> ...
> }
>
>Here after the executing of the uninitialized node, *rightNodeValue_*
>will
>carry a *null* value all the way until it gets replaced with
>*IntegerNode_* which
>will call *getImplicitIntegerClass* and throw an exception because of
>the
>*null* value.
>
>The suggested fix:
>TypeSystemCodeGenerator.java:53
>- builder.startStaticCall(createTypeSystemGen(typeSystem),
>getImplicitClass(typeSystem,
>type)).tree(value);
>*+ builder.startParantheses().tree(value).string(" ==
>").nullLiteral().end().string(" ? ").nullLiteral().string(" : ")*
>*+
> .startStaticCall(createTypeSystemGen(typeSystem),
>getImplicitClass(typeSystem,
>type)).tree(value);*
>
>
>
>Best,
>Mohaned Qunaibit
More information about the graal-dev
mailing list