From fc96c25672d9048dfe358757d01d5cb35eca8631 Mon Sep 17 00:00:00 2001 From: Tomas Stupka <tomas.stupka@oracle.com> Date: Wed, 18 Apr 2018 12:26:50 +0200 Subject: [PATCH] fixed UnsupportedSpecializationException in BinaryBooleanNode if list contains NULL --- .../r/nodes/binary/BinaryBooleanNode.java | 16 +++++++++++++++- .../truffle/r/test/ExpectedTestOutput.test | 12 ++++++++++++ .../r/test/builtins/TestBuiltin_operators.java | 7 +++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java index 201bde0fdc..c7ee5c887e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java @@ -29,6 +29,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.attributes.CopyAttributesNode; import com.oracle.truffle.r.nodes.attributes.CopyAttributesNodeGen; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; @@ -45,6 +46,7 @@ import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RLogicalVector; +import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RRaw; import com.oracle.truffle.r.runtime.data.RRawVector; import com.oracle.truffle.r.runtime.data.RString; @@ -174,7 +176,8 @@ public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 { @Specialization(guards = {"isOneList(left, right)"}) protected Object doList(VirtualFrame frame, RAbstractVector left, RAbstractVector right, @Cached("create()") CastTypeNode cast, - @Cached("createRecursive()") BinaryBooleanNode recursive) { + @Cached("createRecursive()") BinaryBooleanNode recursive, + @Cached("create()") BranchProfile listCoercionErrorBranch) { Object recursiveLeft = left; if (isRAbstractListVector(left)) { if (copyAttributes == null) { @@ -182,6 +185,10 @@ public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 { copyAttributes = insert(CopyAttributesNodeGen.create(true)); } recursiveLeft = castListToAtomic((RAbstractListBaseVector) left, cast, right.getRType(), copyAttributes); + if (recursiveLeft == null) { + listCoercionErrorBranch.enter(); + throw RError.error(RError.NO_CALLER, RError.Message.LIST_COERCION, right.getRType().getName()); + } } Object recursiveRight = right; if (isRAbstractListVector(right)) { @@ -190,6 +197,10 @@ public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 { copyAttributes = insert(CopyAttributesNodeGen.create(true)); } recursiveRight = castListToAtomic((RAbstractListBaseVector) right, cast, left.getRType(), copyAttributes); + if (recursiveRight == null) { + listCoercionErrorBranch.enter(); + throw RError.error(RError.NO_CALLER, RError.Message.LIST_COERCION, left.getRType().getName()); + } } return recursive.execute(frame, recursiveLeft, recursiveRight); } @@ -200,6 +211,9 @@ public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 { Object store = result.getInternalStore(); for (int i = 0; i < source.getLength(); i++) { Object value = source.getDataAt(i); + if (value == RNull.instance) { + return null; + } if (type == RType.Character) { if (!(value instanceof String)) { value = RDeparse.deparse(value); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index a589460550..c0d15c5eb8 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -43348,6 +43348,18 @@ Error in Ops.factor(factor(c("a", "b", "c")), factor(c(1, 2, 3))) : #{ c(1,2,3,4,5) %in% c(1,2,1,2) } [1] TRUE TRUE FALSE FALSE FALSE +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testListWithNull# +#{ c(1, 1) < list(1, NULL) } +Error: (list) object cannot be coerced to type 'double' + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testListWithNull# +#{ list(1, NULL) < c(1, 1) } +Error: (list) object cannot be coerced to type 'double' + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testListWithNull# +#{ list(NULL) < 1 } +Error: (list) object cannot be coerced to type 'double' + ##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testMatMult# #{ as.vector(c(1,2,3)) %*% t(as.vector(c(1,2))) } [,1] [,2] diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java index c5b231862d..26b615f6c3 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java @@ -2079,4 +2079,11 @@ public class TestBuiltin_operators extends TestBase { assertEval("{ l <- list(an=T, bn=F, T, F); l == T }"); assertEval("{ l <- list(an=T, bn=F, T, F); T == l }"); } + + @Test + public void testListWithNull() { + assertEval("{ list(NULL) < 1 }"); + assertEval("{ list(1, NULL) < c(1, 1) }"); + assertEval("{ c(1, 1) < list(1, NULL) }"); + } } -- GitLab