diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Crc64.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Crc64.java index fe6fe915efc8e6c10890ff80642d3ce1cae7b02b..7e7d2f9c5c2f583a9ab695182fa8408487fe1c2a 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Crc64.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/Crc64.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, 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 @@ -22,30 +22,42 @@ */ package com.oracle.truffle.r.library.utils; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; - import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 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.RExternalBuiltinNode; -import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; public abstract class Crc64 extends RExternalBuiltinNode.Arg1 { + @Override + protected void createCasts(CastBuilder casts) { + casts.arg(0).mustNotBeNull(RError.NO_CALLER, + RError.Message.INPUT_MUST_BE_STRING).mustBe(stringValue(), RError.NO_CALLER, RError.Message.INPUT_MUST_BE_STRING); + } + @Specialization - @TruffleBoundary - protected String crc64(RAbstractStringVector input) { - try { - MessageDigest md = MessageDigest.getInstance("MD5"); - byte[] digest = md.digest(input.getDataAt(0).getBytes()); - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < digest.length; i++) { - sb.append(Integer.toHexString(digest[i] & 0xFF)); - } - return sb.toString(); - } catch (NoSuchAlgorithmException ex) { - throw RInternalError.shouldNotReachHere(ex); + public String crc64(RAbstractStringVector x) { + return crc(x); + } + + public static String crc(RAbstractStringVector x) { + final String string = x.getDataAt(0); + byte[] bytes = string.getBytes(); + bytes = crc64(bytes); + long l = 0; + for (int i = 0; i < bytes.length; i++) { + l += (bytes[i] & 0xffL) << (8 * i); } + return Long.toHexString(l); + } + + @TruffleBoundary + private static byte[] crc64(byte[] bytes) { + org.tukaani.xz.check.CRC64 crc = new org.tukaani.xz.check.CRC64(); + crc.update(bytes); + return crc.finish(); } } 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 index c492da931b26adedf73a7520833fdd76fd63ed4d..932b06f368fd4e81dd7afcadafe45fce41c5bf26 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, 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 @@ -22,11 +22,11 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 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.library.utils.Crc64; 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; @@ -47,21 +47,7 @@ public abstract class CRC64 extends RBuiltinNode { @Specialization protected RAbstractStringVector crc64(RAbstractStringVector x) { - final String string = x.getDataAt(0); - byte[] bytes = string.getBytes(); - bytes = crc64(bytes); - long l = 0; - for (int i = 0; i < bytes.length; i++) { - l += (bytes[i] & 0xffL) << (8 * i); - } - return RDataFactory.createStringVector(Long.toHexString(l)); - } - - @TruffleBoundary - private static byte[] crc64(byte[] bytes) { - org.tukaani.xz.check.CRC64 crc = new org.tukaani.xz.check.CRC64(); - crc.update(bytes); - return crc.finish(); + return RDataFactory.createStringVector(Crc64.crc(x)); } } 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 b57be5195c88678ead1cdcb11e99a400b411629a..9eceeafd7c2beebadca1ddfafe8ca60b63d6887d 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 @@ -14910,83 +14910,157 @@ Error in cospi(argv[[1]]) : unimplemented complex function Warning message: In cospi(argv[[1]]) : NaNs produced -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call#Ignored.ImplementationError# +#.Call(utils:::C_crc64) +Error in .Call(utils:::C_crc64) : + Incorrect number of arguments (0), expecting 1 for 'crc64' + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call#Ignored.ImplementationError# +#.Call(utils:::C_crc64, 'a', 'b') +Error in .Call(utils:::C_crc64, "a", "b") : + Incorrect number of arguments (2), expecting 1 for 'crc64' + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, 'abc') +[1] "2cd8094a1a277627" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, 01) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, NA) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, NULL) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, c('a')) +[1] "330284772e652b05" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, c('a', 'b')) +[1] "330284772e652b05" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, c(1, 2)) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, c(NULL)) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, double(0)) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, environment) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, integer(0)) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, list(NULL)) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, list(list())) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, new.env()) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, paste(c(letters, LETTERS, 0:9), collapse=""))) +Error: unexpected ')' in ".Call(utils:::C_crc64, paste(c(letters, LETTERS, 0:9), collapse="")))" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Call# +#.Call(utils:::C_crc64, stdout()) +Error: input must be a character string + +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64('a')) [1] "330284772e652b05" -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64#Ignored.ImplementationError# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal#Ignored.ImplementationError# #.Internal(crc64('a', 'b')) Error: 2 arguments passed to .Internal(crc64) which requires 1 -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64()) Error: 0 arguments passed to .Internal(crc64) which requires 1 -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(01)) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(NA)) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(NULL)) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(c('a'))) [1] "330284772e652b05" -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(c('a', 'b'))) [1] "330284772e652b05" -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(c(1, 2))) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(c(NULL))) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(double(0))) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(environment)) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(integer(0))) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(list(NULL))) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(list(list()))) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(new.env())) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(paste(c(letters, LETTERS, 0:9), collapse=""))) [1] "90db9ccd9021d2d7" -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #.Internal(crc64(stdout())) Error: input must be a character string -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #crc64('a') Error: could not find function "crc64" -##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64# +##com.oracle.truffle.r.test.builtins.TestBuiltin_crc64.testCrc64_Internal# #crc64() Error: could not find function "crc64" 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 index 46a350685807ec058e04582969772e62009ac049..b0ebeac7548245f11423f29c00c6e85a10512ab9 100644 --- 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2017, 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 @@ -30,7 +30,7 @@ import com.oracle.truffle.r.test.TestBase; public class TestBuiltin_crc64 extends TestBase { @Test - public void testCrc64() { + public void testCrc64_Internal() { assertEval("crc64()"); assertEval("crc64('a')"); @@ -65,4 +65,40 @@ public class TestBuiltin_crc64 extends TestBase { assertEval(".Internal(crc64(stdout()))"); } + @Test + public void testCrc64_Call() { + + assertEval(".Call(utils:::C_crc64, 'abc')"); + + assertEval(".Call(utils:::C_crc64, paste(c(letters, LETTERS, 0:9), collapse=\"\")))"); + + assertEval(".Call(utils:::C_crc64, c('a'))"); + + // // Expected output: Incorrect number of arguments (2), expecting 1 for 'crc64' + // // FastR output: throws com.oracle.truffle.r.runtime.RInternalError: should not reach + // here: mismatching number of arguments to foreign function + // // should be handled in .Call-s impl ? + assertEval(Ignored.ImplementationError, ".Call(utils:::C_crc64, 'a', 'b')"); + assertEval(Ignored.ImplementationError, ".Call(utils:::C_crc64)"); + + assertEval(".Call(utils:::C_crc64, c(1, 2))"); + + assertEval(".Call(utils:::C_crc64, c('a', 'b'))"); + + assertEval(".Call(utils:::C_crc64, NA)"); + assertEval(".Call(utils:::C_crc64, NULL)"); + assertEval(".Call(utils:::C_crc64, list(list()))"); + assertEval(".Call(utils:::C_crc64, list(NULL))"); + assertEval(".Call(utils:::C_crc64, c(NULL))"); + + assertEval(".Call(utils:::C_crc64, integer(0))"); + assertEval(".Call(utils:::C_crc64, double(0))"); + + assertEval(".Call(utils:::C_crc64, 01)"); + + assertEval(".Call(utils:::C_crc64, new.env())"); + assertEval(".Call(utils:::C_crc64, environment)"); + assertEval(".Call(utils:::C_crc64, stdout())"); + + } }