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 8b3b8edcc9c2ef5dc130f5364527aae53d600f33..f6f78ccaa1d9b849bbfa008dd783be086d4b02d0 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 0000000000000000000000000000000000000000..f3ec23c0732522a77087eff99dc6febaf52083ad --- /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 9337e810d8a898aa8f6c1257525fdbbbdce62cdb..39504baf8e90020ba7d51c19460d27a600f91e3e 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 0000000000000000000000000000000000000000..7646923109b32f8519e0cf718cbe790b95e36e01 --- /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()))"); + } + +}