From 4cb44ebe4c0ef9a4de9dc3e414f0e62b7100b13d Mon Sep 17 00:00:00 2001
From: Florian Angerer <florian.angerer@oracle.com>
Date: Tue, 21 Nov 2017 16:05:43 +0100
Subject: [PATCH] Added tests and updated native version.

---
 .../truffle/r/ffi/impl/nodes/MiscNodes.java   |  2 +-
 .../truffle/r/library/utils/OctSizeNode.java  |  2 +-
 com.oracle.truffle.r.native/version.source    |  2 +-
 .../r/nodes/unary/SizeToOctalRawNode.java     | 13 ++++++++++--
 .../truffle/r/test/ExpectedTestOutput.test    | 20 +++++++++++++++++++
 .../r/test/library/utils/TestUtils.java       |  7 +++++++
 6 files changed, 41 insertions(+), 5 deletions(-)

diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java
index 2c5d6f3ec0..1c6562db63 100644
--- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java
+++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java
@@ -279,7 +279,7 @@ public final class MiscNodes {
         }
 
         protected CastNode createCast() {
-            HeadPhaseBuilder<Double> findFirst = CastNodeBuilder.newCastBuilder().mustNotBeMissing().mustNotBeNull().asDoubleVector().findFirst();
+            HeadPhaseBuilder<Double> findFirst = CastNodeBuilder.newCastBuilder().mustNotBeMissing().allowNull().asDoubleVector().findFirst();
             return findFirst.buildCastNode();
         }
 
diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/OctSizeNode.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/OctSizeNode.java
index 4f334e8429..77e95ccbfc 100644
--- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/OctSizeNode.java
+++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/OctSizeNode.java
@@ -13,7 +13,7 @@ public abstract class OctSizeNode extends RExternalBuiltinNode.Arg1 {
 
     static {
         Casts casts = new Casts(OctSizeNode.class);
-        casts.arg(0).mustNotBeMissing().mustNotBeNull().returnIf(Predef.integerValue()).asDoubleVector().findFirst();
+        casts.arg(0).mustNotBeMissing().allowNull().returnIf(Predef.integerValue()).asDoubleVector().findFirst();
     }
 
     @Child private SizeToOctalRawNode sizeToOctal = SizeToOctalRawNode.create();
diff --git a/com.oracle.truffle.r.native/version.source b/com.oracle.truffle.r.native/version.source
index c739b42c4d..ea90ee3198 100644
--- a/com.oracle.truffle.r.native/version.source
+++ b/com.oracle.truffle.r.native/version.source
@@ -1 +1 @@
-44
+45
diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/SizeToOctalRawNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/SizeToOctalRawNode.java
index f63915dbfb..c0bdbc429e 100644
--- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/SizeToOctalRawNode.java
+++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/SizeToOctalRawNode.java
@@ -10,6 +10,7 @@ import com.oracle.truffle.api.dsl.Specialization;
 import com.oracle.truffle.r.runtime.RError;
 import com.oracle.truffle.r.runtime.RRuntime;
 import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.RNull;
 import com.oracle.truffle.r.runtime.data.RRawVector;
 import com.oracle.truffle.r.runtime.data.nodes.SetDataAt;
 
@@ -31,9 +32,12 @@ public abstract class SizeToOctalRawNode extends UnaryNode {
         }
 
         ByteBuffer encode = asciiCharset.encode(Integer.toOctalString(s));
+        // reverse
         byte[] result = new byte[11];
-        Arrays.fill(result, (byte) 48);
-        encode.get(result);
+        Arrays.fill(result, (byte) '0');
+        for (int i = result.length - 1; i >= 0 && encode.hasRemaining(); i--) {
+            result[i] = encode.get();
+        }
         return result;
     }
 
@@ -59,6 +63,11 @@ public abstract class SizeToOctalRawNode extends UnaryNode {
         return ans;
     }
 
+    @Specialization
+    protected RRawVector octSize(@SuppressWarnings("unused") RNull n) {
+        return RDataFactory.createRawVector(11);
+    }
+
     public static SizeToOctalRawNode create() {
         return SizeToOctalRawNodeGen.create();
 
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 ea87c1d8a9..ad916edb9a 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
@@ -167456,6 +167456,26 @@ Error: the first argument must be of mode character
 [28] plot.ts             plot.tskernel*
 see '?methods' for accessing help and source code
 
+##com.oracle.truffle.r.test.library.utils.TestUtils.testOctSize#
+#.Call(utils:::C_octsize, 1.0)
+ [1] 30 30 30 30 30 30 30 30 30 30 31
+
+##com.oracle.truffle.r.test.library.utils.TestUtils.testOctSize#
+#.Call(utils:::C_octsize, 1L)
+ [1] 30 30 30 30 30 30 30 30 30 30 31
+
+##com.oracle.truffle.r.test.library.utils.TestUtils.testOctSize#
+#.Call(utils:::C_octsize, 2147483647)
+ [1] 31 37 37 37 37 37 37 37 37 37 37
+
+##com.oracle.truffle.r.test.library.utils.TestUtils.testOctSize#
+#.Call(utils:::C_octsize, NA)
+ [1] 00 00 00 00 00 00 00 00 00 00 00
+
+##com.oracle.truffle.r.test.library.utils.TestUtils.testOctSize#
+#.Call(utils:::C_octsize, NULL)
+ [1] 00 00 00 00 00 00 00 00 00 00 00
+
 ##com.oracle.truffle.r.test.library.utils.TestWriteTable.testTable#
 #write.table(data.frame(col=c(1,2,3,4), col2=c(T, F, T, F)))
 "col" "col2"
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestUtils.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestUtils.java
index dd5c91b83e..9153421fab 100644
--- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestUtils.java
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestUtils.java
@@ -44,4 +44,11 @@ public class TestUtils extends TestBase {
         // The vector of methods is not sorted alphabetically
         assertEval(Ignored.ImplementationError, "methods(plot)");
     }
+
+    private static final String[] TEST_OCTSIZE_PARAMS = {"1L", "1.0", Integer.toString(Integer.MAX_VALUE), "NA", "NULL"};
+
+    @Test
+    public void testOctSize() {
+        assertEval(template(".Call(utils:::C_octsize, %0)", TEST_OCTSIZE_PARAMS));
+    }
 }
-- 
GitLab