From fdf125cbe4f52806347b341638a13d8c93ffe1c5 Mon Sep 17 00:00:00 2001
From: Tomas Stupka <tomas.stupka@oracle.com>
Date: Tue, 20 Dec 2016 16:28:47 +0100
Subject: [PATCH] implemented crc64 builtin

---
 .../r/nodes/builtin/base/BasePackage.java     |  1 +
 .../truffle/r/nodes/builtin/base/CRC64.java   | 61 +++++++++++++++++++
 .../com/oracle/truffle/r/runtime/RError.java  |  2 +
 .../r/test/builtins/TestBuiltin_crc64.java    | 56 +++++++++++++++++
 4 files changed, 120 insertions(+)
 create mode 100644 com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CRC64.java
 create mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_crc64.java

diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
index 8b3b8edcc9..f6f78ccaa1 100644
--- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java
@@ -277,6 +277,7 @@ public class BasePackage extends RBuiltinPackage {
         add(Contributors.class, ContributorsNodeGen::create);
         add(CopyDFAttr.class, CopyDFAttrNodeGen::create);
         add(Crossprod.class, CrossprodNodeGen::create);
+        add(CRC64.class, CRC64NodeGen::create);
         add(CumMax.class, CumMaxNodeGen::create);
         add(CumMin.class, CumMinNodeGen::create);
         add(CumProd.class, CumProdNodeGen::create);
diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CRC64.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CRC64.java
new file mode 100644
index 0000000000..f3ec23c073
--- /dev/null
+++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CRC64.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.r.nodes.builtin.base;
+
+import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE;
+import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL;
+
+import com.oracle.truffle.api.dsl.Specialization;
+import com.oracle.truffle.r.nodes.builtin.CastBuilder;
+import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue;
+import com.oracle.truffle.r.nodes.builtin.RBuiltinNode;
+import com.oracle.truffle.r.runtime.RError;
+import com.oracle.truffle.r.runtime.RError.Message;
+import com.oracle.truffle.r.runtime.builtins.RBuiltin;
+import com.oracle.truffle.r.runtime.data.RDataFactory;
+import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
+
+@RBuiltin(name = "crc64", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE)
+public abstract class CRC64 extends RBuiltinNode {
+
+    @Override
+    protected void createCasts(CastBuilder casts) {
+        casts.arg("x").conf(x -> x.mustNotBeMissing(RError.SHOW_CALLER2, Message.ARGUMENTS_PASSED_INTERNAL_0_1, getRBuiltin().name())).mustNotBeNull(RError.NO_CALLER,
+                        Message.INPUT_MUST_BE_STRING).mustBe(stringValue(), RError.NO_CALLER, Message.INPUT_MUST_BE_STRING);
+    }
+
+    @Specialization
+    protected RAbstractStringVector crc64(RAbstractStringVector x) {
+        final String string = x.getDataAt(0);
+        byte[] bytes = string.getBytes();
+        org.tukaani.xz.check.CRC64 crc = new org.tukaani.xz.check.CRC64();
+        crc.update(bytes);
+        bytes = crc.finish();
+        long l = 0;
+        for (int i = 0; i < bytes.length; i++) {
+            l += ((long) bytes[i] & 0xffL) << (8 * i);
+        }
+        return RDataFactory.createStringVector(Long.toHexString(l));
+    }
+
+}
diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
index 9337e810d8..39504baf8e 100644
--- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
+++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java
@@ -281,6 +281,7 @@ public final class RError extends RuntimeException {
         LINE_ELEMENTS("line %d did not have %d elements"),
         ITEMS_NOT_MULTIPLE("number of items read is not a multiple of the number of columns"),
         TRACEMEM_NOT_NULL("cannot trace NULL"),
+        INPUT_MUST_BE_STRING("input must be a character string"),
         // below: GNU R gives also expression for the argument
         NOT_FUNCTION("'%s' is not a function, character or symbol"),
         NOT_A_FUNCTION("'%s' is not a function"),
@@ -565,6 +566,7 @@ public final class RError extends RuntimeException {
         RECURSIVE_INDEXING_FAILED("recursive indexing failed at level %d"),
         ARGUMENTS_PASSED("%d arguments passed to '%s' which requires %d"),
         ARGUMENTS_PASSED_0_1("0 arguments passed to '%s' which requires 1"),
+        ARGUMENTS_PASSED_INTERNAL_0_1("0 arguments passed to .Internal(%s) which requires 1"),
         ARGUMENT_IGNORED("argument '%s' will be ignored"),
         NOT_CHARACTER_VECTOR("'%s' must be a character vector"),
         WRONG_WINSLASH("'winslash' must be '/' or '\\\\\\\\'"),
diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_crc64.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_crc64.java
new file mode 100644
index 0000000000..7646923109
--- /dev/null
+++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_crc64.java
@@ -0,0 +1,56 @@
+/*
+ * This material is distributed under the GNU General Public License
+ * Version 2. You may review the terms of this license at
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * Copyright (c) 2014, Purdue University
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates
+ *
+ * All rights reserved.
+ */
+package com.oracle.truffle.r.test.builtins;
+
+import org.junit.Test;
+
+import com.oracle.truffle.r.test.TestBase;
+
+// Checkstyle: stop line length check
+public class TestBuiltin_crc64 extends TestBase {
+
+    @Test
+    public void testCrc64() {
+
+        assertEval("crc64()");
+        assertEval("crc64('a')");
+        assertEval(".Internal(crc64())");
+        assertEval(".Internal(crc64('a'))");
+        assertEval(".Internal(crc64(paste(c(letters, LETTERS, 0:9), collapse=\"\")))");
+        assertEval(".Internal(crc64(c('a')))");
+
+        // Expression: .Internal(crc64('a', 'b'))
+        // Expected output: Error: 2 arguments passed to .Internal(crc64) which requires 1
+        // FastR output: Error in crc64("a", "b") : unused argument ('b')
+        // should be handled in .Internal-s impl ?
+        assertEval(Ignored.ImplementationError, ".Internal(crc64('a', 'b'))");
+
+        assertEval(".Internal(crc64(c(1, 2)))");
+
+        assertEval(".Internal(crc64(c('a', 'b')))");
+
+        assertEval(".Internal(crc64(NA))");
+        assertEval(".Internal(crc64(NULL))");
+        assertEval(".Internal(crc64(list(list())))");
+        assertEval(".Internal(crc64(list(NULL)))");
+        assertEval(".Internal(crc64(c(NULL)))");
+
+        assertEval(".Internal(crc64(integer(0)))");
+        assertEval(".Internal(crc64(double(0)))");
+
+        assertEval(".Internal(crc64(01))");
+
+        assertEval(".Internal(crc64(new.env()))");
+        assertEval(".Internal(crc64(environment))");
+        assertEval(".Internal(crc64(stdout()))");
+    }
+
+}
-- 
GitLab