From eeca21c887da7ae7aa72174f6ad5fa5aee7de1ac Mon Sep 17 00:00:00 2001
From: Zbynek Slajchrt <zbynek.slajchrt@oracle.com>
Date: Mon, 20 Mar 2017 12:24:39 +0100
Subject: [PATCH] PipelineReturnException handling fixed and other minor fixes

---
 .../CastBuilderTest.java                      | 27 ++++++++++++++-----
 .../CastUtilsTest.java                        |  2 +-
 .../ResultTypesAnalyserTest.java              |  5 ++--
 .../SampleCollectorTest.java                  |  5 ++--
 .../{builtin => castsTests}/TypeExprTest.java |  2 +-
 .../builtin/casts/PipelineToCastNode.java     |  2 +-
 .../r/nodes/unary/ChainedCastNode.java        | 15 ++++++++---
 .../oracle/truffle/r/runtime/RRuntime.java    |  4 +--
 8 files changed, 43 insertions(+), 19 deletions(-)
 rename com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/{builtin => castsTests}/CastBuilderTest.java (97%)
 rename com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/{builtin => castsTests}/CastUtilsTest.java (99%)
 rename com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/{builtin => castsTests}/ResultTypesAnalyserTest.java (99%)
 rename com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/{builtin => castsTests}/SampleCollectorTest.java (99%)
 rename com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/{builtin => castsTests}/TypeExprTest.java (99%)

diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java
similarity index 97%
rename from com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
rename to com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java
index 0e432013b9..7a3a51a35b 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastBuilderTest.java
@@ -20,7 +20,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.nodes.builtin;
+package com.oracle.truffle.r.nodes.castsTests;
 
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.abstractVectorValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.anyValue;
@@ -78,6 +78,9 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
+import com.oracle.truffle.api.RootCallTarget;
+import com.oracle.truffle.api.nodes.RootNode;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef;
 import com.oracle.truffle.r.nodes.builtin.casts.fluent.InitialPhaseBuilder;
 import com.oracle.truffle.r.nodes.builtin.casts.fluent.PreinitialPhaseBuilder;
@@ -93,6 +96,7 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.builtins.RBuiltinKind;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
 import com.oracle.truffle.r.runtime.data.RDoubleVector;
+import com.oracle.truffle.r.runtime.data.RFunction;
 import com.oracle.truffle.r.runtime.data.RIntSequence;
 import com.oracle.truffle.r.runtime.data.RIntVector;
 import com.oracle.truffle.r.runtime.data.RList;
@@ -331,10 +335,10 @@ public class CastBuilderTest {
     public void testFindFirstWithoutDefaultValue() {
         arg.asIntegerVector().findFirst();
 
-        assertCastFail(RNull.instance, "argument is of length zero");
-        assertCastFail(RMissing.instance, "argument is of length zero");
-        assertCastFail(RDataFactory.createIntVector(0), "argument is of length zero");
-        assertCastFail(RDataFactory.createList(), "argument is of length zero");
+        assertCastFail(RNull.instance, "invalid 'x' argument");
+        assertCastFail(RMissing.instance, "invalid 'x' argument");
+        assertCastFail(RDataFactory.createIntVector(0), "invalid 'x' argument");
+        assertCastFail(RDataFactory.createList(), "invalid 'x' argument");
         assertEquals(1, cast(1));
         assertEquals(1, cast(RDataFactory.createIntVector(new int[]{1, 2}, true)));
         assertEquals(1, cast("1"));
@@ -399,7 +403,7 @@ public class CastBuilderTest {
         arg.asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean());
         assertEquals(Boolean.TRUE, cast(RRuntime.LOGICAL_TRUE));
         assertEquals(Boolean.FALSE, cast(RRuntime.LOGICAL_FALSE));
-        assertEquals(Boolean.FALSE, cast(RRuntime.LOGICAL_NA));
+        assertEquals(Boolean.TRUE, cast(RRuntime.LOGICAL_NA));
         assertEquals(Boolean.TRUE, cast(RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE}, true)));
         assertEquals(Boolean.FALSE, cast(RDataFactory.createLogicalVector(0)));
         testPipeline(NO_FILTER_EXPECT_EMPTY_SAMPLES);
@@ -872,6 +876,17 @@ public class CastBuilderTest {
         Assert.assertEquals(RError.Message.NA_INTRODUCED_COERCION.message, CastNode.getLastWarning());
     }
 
+    private static final RFunction DUMMY_FUNCTION = RDataFactory.createFunction(RFunction.NO_NAME, RFunction.NO_NAME, null, null, null);
+
+    @Test
+    public void testReturnIfFunction() {
+        arg.allowNull().returnIf(instanceOf(RFunction.class)).asVector(false);
+        RFunction f = DUMMY_FUNCTION;
+        Object o = cast(f);
+        assertEquals(f, o);
+        testPipeline();
+    }
+
     /**
      * Casts given object using the configured pipeline in {@link #arg}.
      */
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastUtilsTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastUtilsTest.java
similarity index 99%
rename from com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastUtilsTest.java
rename to com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastUtilsTest.java
index 00c93678c1..6b0be76aef 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastUtilsTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/CastUtilsTest.java
@@ -20,7 +20,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.nodes.builtin;
+package com.oracle.truffle.r.nodes.castsTests;
 
 import java.io.Serializable;
 import java.lang.reflect.Type;
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/ResultTypesAnalyserTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java
similarity index 99%
rename from com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/ResultTypesAnalyserTest.java
rename to com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java
index d45c80d6e1..3cfa577f86 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/ResultTypesAnalyserTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java
@@ -20,7 +20,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.nodes.builtin;
+package com.oracle.truffle.r.nodes.castsTests;
 
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.emptyIntegerVector;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.nullConstant;
@@ -62,12 +62,13 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
-import com.oracle.truffle.r.nodes.builtin.CastBuilderTest.DummyBuiltin;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep;
 import com.oracle.truffle.r.nodes.builtin.casts.fluent.PreinitialPhaseBuilder;
 import com.oracle.truffle.r.nodes.casts.MarkLookup;
 import com.oracle.truffle.r.nodes.casts.ResultTypesAnalyser;
 import com.oracle.truffle.r.nodes.casts.TypeExpr;
+import com.oracle.truffle.r.nodes.castsTests.CastBuilderTest.DummyBuiltin;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.builtins.RBuiltin;
 import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames;
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/SampleCollectorTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/SampleCollectorTest.java
similarity index 99%
rename from com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/SampleCollectorTest.java
rename to com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/SampleCollectorTest.java
index 52e252a035..38f3f15c26 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/SampleCollectorTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/SampleCollectorTest.java
@@ -20,7 +20,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.nodes.builtin;
+package com.oracle.truffle.r.nodes.castsTests;
 
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.atomicIntegerValue;
 import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.atomicLogicalValue;
@@ -57,10 +57,11 @@ import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
-import com.oracle.truffle.r.nodes.builtin.CastBuilderTest.DummyBuiltin;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
 import com.oracle.truffle.r.nodes.builtin.casts.PipelineStep;
 import com.oracle.truffle.r.nodes.builtin.casts.fluent.PreinitialPhaseBuilder;
 import com.oracle.truffle.r.nodes.casts.SamplesCollector;
+import com.oracle.truffle.r.nodes.castsTests.CastBuilderTest.DummyBuiltin;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.RType;
diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/TypeExprTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/TypeExprTest.java
similarity index 99%
rename from com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/TypeExprTest.java
rename to com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/TypeExprTest.java
index a016195821..c9fa1f4d53 100644
--- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/TypeExprTest.java
+++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/TypeExprTest.java
@@ -20,7 +20,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package com.oracle.truffle.r.nodes.builtin;
+package com.oracle.truffle.r.nodes.castsTests;
 
 import static com.oracle.truffle.r.nodes.casts.Not.negateType;
 import static com.oracle.truffle.r.nodes.casts.TypeExpr.atom;
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java
index d00f5c16cb..1a2e496913 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/casts/PipelineToCastNode.java
@@ -147,7 +147,7 @@ public final class PipelineToCastNode {
                     prevCastNode = node;
                 } else {
                     CastNode finalPrevCastNode = prevCastNode;
-                    prevCastNode = new ChainedCastNode(finalPrevCastNode, node);
+                    prevCastNode = new ChainedCastNode(finalPrevCastNode, node, currCastStep.getNext() == null);
                 }
             }
 
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ChainedCastNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ChainedCastNode.java
index fb0da67ec9..ba239b34fe 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ChainedCastNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ChainedCastNode.java
@@ -37,17 +37,24 @@ public final class ChainedCastNode extends CastNode {
     @Child private CastNode firstCast;
     @Child private CastNode secondCast;
 
-    public ChainedCastNode(CastNode firstCast, CastNode secondCast) {
+    private final boolean isFirstNode;
+
+    public ChainedCastNode(CastNode firstCast, CastNode secondCast, boolean isFirstNode) {
         this.firstCast = firstCast;
         this.secondCast = secondCast;
+        this.isFirstNode = isFirstNode;
     }
 
     @Override
     public Object execute(Object value) {
-        try {
+        if (isFirstNode) {
+            try {
+                return secondCast.execute(firstCast.execute(value));
+            } catch (PipelineReturnException ex) {
+                return ex.getResult();
+            }
+        } else {
             return secondCast.execute(firstCast.execute(value));
-        } catch (PipelineReturnException ex) {
-            return ex.getResult();
         }
     }
 
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
index 364e2d8484..2c4d20041d 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java
@@ -277,8 +277,8 @@ public class RRuntime {
         return b == LOGICAL_TRUE;
     }
 
-    public static boolean fromLogical(byte b, boolean naValue) {
-        return naValue ? b != LOGICAL_FALSE : b == LOGICAL_TRUE;
+    public static boolean fromLogical(byte b, boolean naReplacement) {
+        return naReplacement ? b != LOGICAL_FALSE : b == LOGICAL_TRUE;
     }
 
     // conversions from logical
-- 
GitLab