From a63626a62c4449d96e2dad7a6a2e4d156dc57c7c Mon Sep 17 00:00:00 2001 From: Zbynek Slajchrt <zbynek.slajchrt@oracle.com> Date: Mon, 5 Feb 2018 21:49:11 +0100 Subject: [PATCH] Adopting LLVM into FastR --- ci.hocon | 78 +++- .../r/engine/interop/ActiveBindingMR.java | 14 +- .../truffle/r/engine/interop/ListMR.java | 61 ++-- .../interop/RAbstractVectorAccessFactory.java | 85 ++++- .../engine/interop/RArgsValuesAndNamesMR.java | 16 +- .../r/engine/interop/RConnectionMR.java | 16 +- .../truffle/r/engine/interop/REmptyMR.java | 16 +- .../r/engine/interop/REnvironmentMR.java | 23 +- .../r/engine/interop/RExternalPtrMR.java | 17 +- .../truffle/r/engine/interop/RFunctionMR.java | 23 +- .../truffle/r/engine/interop/RLanguageMR.java | 23 +- .../truffle/r/engine/interop/RMissingMR.java | 16 +- .../truffle/r/engine/interop/RNullMR.java | 16 +- .../truffle/r/engine/interop/RPromiseMR.java | 23 +- .../truffle/r/engine/interop/RS4ObjectMR.java | 16 +- .../truffle/r/engine/interop/RSymbolMR.java | 23 +- .../r/engine/interop/RUnboundValueMR.java | 16 +- .../ffi/impl/common/JavaUpCallsRFFIImpl.java | 333 ++++++++++++++++-- .../r/ffi/impl/interop/CharSXPWrapperMR.java | 73 +++- .../truffle/r/ffi/impl/interop/DLLInfoMR.java | 18 +- .../r/ffi/impl/interop/NativeCharArrayMR.java | 26 +- .../r/ffi/impl/interop/NativeNACheck.java | 3 +- .../impl/interop/base/ReadlinkResultMR.java | 23 +- .../r/ffi/impl/llvm/TruffleLLVM_C.java | 5 +- .../r/ffi/impl/llvm/TruffleLLVM_Call.java | 107 ++++-- ...extState.java => TruffleLLVM_Context.java} | 32 +- .../r/ffi/impl/llvm/TruffleLLVM_DLL.java | 23 +- .../impl/llvm/TruffleLLVM_DownCallNode.java | 5 +- .../r/ffi/impl/llvm/TruffleLLVM_Lapack.java | 16 +- .../ffi/impl/llvm/TruffleLLVM_NativeDLL.java | 6 +- .../r/ffi/impl/llvm/TruffleLLVM_PCRE.java | 4 +- .../impl/llvm/TruffleLLVM_RFFIFactory.java | 4 +- .../r/ffi/impl/llvm/TruffleLLVM_Stats.java | 13 +- .../llvm/TruffleLLVM_UpCallsRFFIImpl.java | 42 +-- .../r/ffi/impl/llvm/TruffleLLVM_Zip.java | 10 +- .../upcalls/CharSXPToNativeArrayCallMR.java | 3 +- .../ffi/impl/managed/Managed_RFFIFactory.java | 3 +- .../impl/nfi/TruffleNFI_UpCallsRFFIImpl.java | 153 +------- .../truffle/r/ffi/impl/nodes/CoerceNodes.java | 1 - .../truffle/r/ffi/impl/nodes/EnvNodes.java | 5 +- .../impl/nodes/NewCustomConnectionNode.java | 79 +++++ .../ffi/impl/nodes/RMakeExternalPtrNode.java | 48 +++ .../r/ffi/impl/nodes/TryRfEvalNode.java | 2 +- .../r/ffi/impl/upcalls/FFIUnwrapNode.java | 7 +- .../r/ffi/impl/upcalls/FFIWrapNode.java | 6 +- .../r/ffi/impl/upcalls/StdUpCallsRFFI.java | 14 +- .../library/methods/MethodsListDispatch.java | 12 +- .../fficall/src/common/rffi_upcalls.h | 4 +- .../fficall/src/truffle_common/Connections.c | 3 +- .../Rinternals_truffle_common.h | 30 +- .../src/truffle_common/variables_common.h | 204 +++++++++++ .../fficall/src/truffle_llvm/Makefile | 4 +- .../fficall/src/truffle_llvm/Rembedded.c | 30 ++ .../fficall/src/truffle_llvm/Rinternals.c | 57 ++- .../fficall/src/truffle_llvm/rffiutils.c | 5 +- .../fficall/src/truffle_llvm/rffiutils.h | 6 +- .../fficall/src/truffle_llvm/variables.c | 188 +--------- .../fficall/src/truffle_nfi/Rinternals.c | 6 +- .../fficall/src/truffle_nfi/rffiutils.h | 4 +- .../fficall/src/truffle_nfi/variables.c | 183 +--------- .../gnur/Makefile.libs | 7 +- .../patch/src/library/base/src/registration.c | 1 - .../patch/src/library/graphics/src/base.c | 2 + .../gnur/patch/src/library/grid/src/grid.h | 8 +- .../gnur/patch/src/library/grid/src/unit.c | 24 +- .../gnur/patch/src/library/grid/src/util.c | 2 +- .../patch/src/library/utils/src/utils_dummy.c | 2 +- .../llvm_tools/llvm-ar | 37 ++ .../llvm_tools/llvm-c++ | 8 +- .../llvm_tools/llvm-cc | 9 +- .../llvm_tools/llvm-fc | 5 +- .../llvm_tools/llvm-helper | 8 +- .../run/edMakeconf.etc.llvm | 5 + .../oracle/truffle/r/nodes/test/TestBase.java | 2 +- .../vector/CachedReplaceVectorNode.java | 8 +- .../access/vector/ReplaceVectorNode.java | 14 +- .../truffle/r/runtime/FastROptions.java | 4 +- .../oracle/truffle/r/runtime/RDeparse.java | 9 +- .../r/runtime/data/CharSXPWrapper.java | 6 +- .../r/runtime/data/NativeDataAccess.java | 32 +- .../truffle/r/runtime/interop/Foreign2R.java | 3 +- .../runtime/interop/RObjectNativeWrapper.java | 100 ++++++ com.oracle.truffle.r.test.native/Makefile | 4 +- .../packages/testrffi/testrffi/src/testrffi.c | 4 +- .../testrffi/testrffi/tests/simpleTests.R | 1 + .../truffle/r/test/ExpectedTestOutput.test | 20 +- .../com/oracle/truffle/r/test/TestBase.java | 2 +- .../truffle/r/test/TestContextConfig.java | 77 ++++ .../r/test/engine/interop/AbstractMRTest.java | 36 +- .../r/test/engine/interop/ListMRTest.java | 4 +- .../r/test/engine/interop/VectorMRTest.java | 3 +- .../truffle/r/test/generate/FastRSession.java | 2 +- .../r/test/library/base/TestConnections.java | 4 +- .../test/library/base/TestSharedCluster.java | 8 +- .../test/library/stats/TestExternal_Rmd5.java | 10 +- .../r/test/library/stats/TestFitting.java | 13 +- .../library/utils/TestInteractiveDebug.java | 4 +- documentation/dev/build-process.md | 2 +- mx.fastr/copyrights/overrides | 4 + 99 files changed, 1739 insertions(+), 1037 deletions(-) rename com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/{TruffleLLVM_RFFIContextState.java => TruffleLLVM_Context.java} (70%) create mode 100644 com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NewCustomConnectionNode.java create mode 100644 com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RMakeExternalPtrNode.java create mode 100644 com.oracle.truffle.r.native/fficall/src/truffle_common/variables_common.h create mode 100644 com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rembedded.c create mode 100755 com.oracle.truffle.r.native/llvm_tools/llvm-ar create mode 100644 com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/RObjectNativeWrapper.java create mode 100644 com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestContextConfig.java diff --git a/ci.hocon b/ci.hocon index b3433d1ec9..1c4145a32e 100644 --- a/ci.hocon +++ b/ci.hocon @@ -111,7 +111,7 @@ darwinEnvironment : { PATH : "/usr/local/bin:$JAVA_HOME/bin:$PATH" F77: "/usr/local/bin/gfortran-4.9" TZDIR: "/usr/share/zoneinfo" - PKG_INCLUDE_FLAGS_OVERRIDE : """-I/cm/shared/apps/pcre/8.38/include -I/cm/shared/apps/bzip2/1.0.6/include -I/cm/shared/apps/xz/5.2.2/include -I/cm/shared/apps/curl/7.50.1/include""" + PKG_INCLUDE_FLAGS_OVERRIDE : """-I/cm/shared/apps/pcre/8.38/include -I/cm/shared/apps/bzip2/1.0.6/include -I/cm/shared/apps/xz/5.2.2/include -I/cm/shared/apps/curl/7.50.1/include""" PKG_LDFLAGS_OVERRIDE : """" -L/cm/shared/apps/bzip2/1.0.6/lib -L/cm/shared/apps/xz/5.2.2/lib -L/cm/shared/apps/pcre/8.38/lib -L/cm/shared/apps/curl/7.50.1/lib -L/cm/shared/apps/gcc/4.9.1/lib64 -L/usr/local/Cellar/gcc@4.9/4.9.4/lib/gcc/4.9/ -L/usr/lib"""" } } @@ -127,6 +127,43 @@ gateTestLinuxNFI : ${gateTestCommon} { } } +requireGCC: { + downloads: { + DRAGONEGG_GCC: {name: "gcc+dragonegg", version: "4.6.4-1", platformspecific: true} + DRAGONEGG_LLVM: {name: "clang+llvm", version: "3.2", platformspecific: true} + } +} + +gateTestLinuxLLVM : ${common} ${requireGCC} { + capabilities: [linux, amd64] + + packages: { + llvm: "==3.8" + } + + environment : { + TZDIR: "/usr/share/zoneinfo" + FASTR_RFFI : "llvm" + FASTR_LLVM_HOME : "$DRAGONEGG_LLVM/bin" + FASTR_LLVM_GFORTRAN_LLVM_AS : "$DRAGONEGG_LLVM/bin/llvm-as" + FASTR_LLVM_GFORTRAN : "$DRAGONEGG_GCC/bin/gfortran" + FASTR_LLVM_DRAGONEGG : "$DRAGONEGG_GCC/lib/dragonegg.so" + DEFAULT_DYNAMIC_IMPORTS : "sulong" + } + + setup: [ + ["git", "clone", ["mx", "urlrewrite", "https://github.com/graalvm/sulong.git"], "../sulong"], + ["mx", "sforceimports"], + ["git","clone", "--depth", "1", ${repoBase}"r-apptests.git", "../r-apptests"] + ] + + run : [ + ${gateCmd} ["Versions,JDKReleaseInfo,BuildJavaWithJavac"] + ["mx", "rscript", "../r-apptests/renjin-tests/driver.R", "--setwd", "../r-apptests/renjin-tests/"] + ["mx", "pkgtest", "--repos", "FASTR", "--run-tests", "testrffi"] + ] +} + gateTestManagedLinux: ${common} { environment : { FASTR_RFFI : "managed" @@ -144,6 +181,43 @@ gateTestJava9Linux : ${java9Downloads} ${gateTestCommon} { } } +gateTestDarwinLLVM: ${common} ${darwinEnvironment} ${requireGCC} { + capabilities: [darwin_sierra, amd64] + + packages : ${packagesDarwin} { + llvm: "==4.0.1" + } + + environment : { + FASTR_RFFI : "llvm" + FASTR_LLVM_HOME : "$DRAGONEGG_LLVM/bin" + FASTR_LLVM_GFORTRAN_LLVM_AS : "$DRAGONEGG_LLVM/bin/llvm-as" + FASTR_LLVM_GFORTRAN : "$DRAGONEGG_GCC/bin/gfortran" + FASTR_LLVM_DRAGONEGG : "$DRAGONEGG_GCC/lib/dragonegg.so" + DEFAULT_DYNAMIC_IMPORTS : "sulong" + # homebrew doesn't put llvm on the path by default + PATH: "/usr/local/Cellar/llvm@4/4.0.1/bin:$PATH" + LC_MESSAGES: "en_US" + LC_COLLATE: "en_US" + LC_TIME: "en_US" + LC_MONETARY: "en_US" + LC_COLLATE: "en_US.UTF-8" + } + + setup: [ + ["ls", "/usr/local/Cellar"] + ["git", "clone", ["mx", "urlrewrite", "https://github.com/graalvm/sulong.git"], "../sulong"], + ["mx", "sforceimports"], + ["git", "clone", "--depth", "1", ${repoBase}"r-apptests.git", "../r-apptests"] + ] + + run : [ + ${gateCmd} ["Versions,JDKReleaseInfo,BuildJavaWithJavac"] + ["mx", "rscript", "../r-apptests/renjin-tests/driver.R", "--setwd", "../r-apptests/renjin-tests/"] + ["mx", "pkgtest", "--repos", "FASTR", "--run-tests", "testrffi"] + ] +} + # This performs a number of "style" checks on the code to ensure it confirms to the project standards. gateStyle : ${common} { @@ -199,4 +273,6 @@ builds = [ #${gateTestManagedLinux} {capabilities : [linux, amd64, fast], targets : [gate], name: "gate-test-managed-linux-amd64"} ${gateTestJava9Linux} {capabilities : [linux, amd64, fast], targets : [gate], name: "gate-test-java9-linux-amd64"} ${gnurTests} {capabilities : [linux, amd64, fast], targets : [gate], name: "gate-gnur-tests"} + ${gateTestLinuxLLVM} { targets : [gate], name: "gate-test-llvm-linux-amd64" } + ${gateTestDarwinLLVM} { targets : [gate], name: "gate-test-llvm-darwin-amd64" } ] diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ActiveBindingMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ActiveBindingMR.java index 6dc535b570..7a4f338ce4 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ActiveBindingMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ActiveBindingMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -27,7 +27,6 @@ import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.env.frame.ActiveBinding; @MessageResolution(receiverType = ActiveBinding.class) @@ -56,15 +55,8 @@ public class ActiveBindingMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); - } - } - - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java index a92ef70a06..c7134106be 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -51,6 +51,7 @@ import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RLogical; import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RTruffleObject; @@ -58,6 +59,7 @@ import com.oracle.truffle.r.runtime.interop.Foreign2R; import com.oracle.truffle.r.runtime.interop.Foreign2RNodeGen; import com.oracle.truffle.r.runtime.interop.R2Foreign; import com.oracle.truffle.r.runtime.interop.R2ForeignNodeGen; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; public class ListMR { @@ -116,24 +118,17 @@ public class ListMR { } } - @Resolve(message = "TO_NATIVE") - public abstract static class RListToNativeNode extends Node { - protected Object access(RTruffleObject receiver) { - return NativeDataAccess.toNative(receiver); - } - } - @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } @@ -214,24 +209,17 @@ public class ListMR { } } - @Resolve(message = "TO_NATIVE") - public abstract static class RExpressionToNativeNode extends Node { - protected Object access(RTruffleObject receiver) { - return NativeDataAccess.toNative(receiver); - } - } - @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } @@ -306,24 +294,17 @@ public class ListMR { } } - @Resolve(message = "TO_NATIVE") - public abstract static class RPairListToNativeNode extends Node { - protected Object access(RPairList receiver) { - return NativeDataAccess.toNative(receiver); - } - } - @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RAbstractVectorAccessFactory.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RAbstractVectorAccessFactory.java index 1295fc5a51..d93ad5d947 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RAbstractVectorAccessFactory.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RAbstractVectorAccessFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -50,14 +50,21 @@ import com.oracle.truffle.r.engine.interop.RAbstractVectorAccessFactoryFactory.V import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNode; +import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNodeGen; import com.oracle.truffle.r.nodes.control.RLengthNode; +import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RLogical; +import com.oracle.truffle.r.runtime.data.RObject; +import com.oracle.truffle.r.runtime.data.RRaw; +import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.interop.Foreign2R; import com.oracle.truffle.r.runtime.interop.Foreign2RNodeGen; import com.oracle.truffle.r.runtime.interop.R2Foreign; import com.oracle.truffle.r.runtime.interop.R2ForeignNodeGen; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; abstract class InteropRootNode extends RootNode { @@ -148,6 +155,66 @@ public final class RAbstractVectorAccessFactory implements StandardFactory { protected abstract Object execute(VirtualFrame frame, Object receiver, Object identifier, Object valueObj); + @Specialization + protected Object write(RAbstractRawVector receiver, int idx, byte valueObj) { + return writeRaw(receiver, new Object[]{idx + 1}, valueObj); + } + + @Specialization + protected Object write(RAbstractRawVector receiver, long idx, byte valueObj) { + return writeRaw(receiver, new Object[]{idx + 1}, valueObj); + } + + private Object writeRaw(RAbstractRawVector receiver, Object[] positions, byte valueObj) { + if (replace == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + replace = insert(ReplaceVectorNodeGen.create(ElementAccessMode.SUBSCRIPT, false, true, true)); + } + return replace.apply(receiver, positions, RRaw.valueOf(valueObj)); + } + + @Specialization + protected Object write(RAbstractLogicalVector receiver, int idx, byte valueObj) { + return writeLogical(receiver, new Object[]{idx + 1}, valueObj); + } + + @Specialization + protected Object write(RAbstractLogicalVector receiver, long idx, byte valueObj) { + return writeLogical(receiver, new Object[]{idx + 1}, valueObj); + } + + protected static boolean isIntNA(int valueObj) { + return RRuntime.isNA(valueObj); + } + + @Specialization(guards = "isIntNA(valueObj)") + protected Object writeLogicalNA(RAbstractLogicalVector receiver, int idx, @SuppressWarnings("unused") int valueObj) { + return writeLogical(receiver, new Object[]{idx + 1}, RRuntime.LOGICAL_NA); + } + + @Specialization(guards = "!isIntNA(valueObj)") + protected Object writeLogicalNonNA(RAbstractLogicalVector receiver, int idx, int valueObj) { + return writeLogical(receiver, new Object[]{idx + 1}, (byte) valueObj); + } + + @Specialization(guards = "isIntNA(valueObj)") + protected Object writeLogicalNA(RAbstractLogicalVector receiver, long idx, @SuppressWarnings("unused") int valueObj) { + return writeLogical(receiver, new Object[]{idx + 1}, RRuntime.LOGICAL_NA); + } + + @Specialization(guards = "!isIntNA(valueObj)") + protected Object writeLogicalNonNA(RAbstractLogicalVector receiver, long idx, int valueObj) { + return writeLogical(receiver, new Object[]{idx + 1}, (byte) valueObj); + } + + private Object writeLogical(RAbstractLogicalVector receiver, Object[] positions, byte valueObj) { + if (replace == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + replace = insert(ReplaceVectorNodeGen.create(ElementAccessMode.SUBSCRIPT, false, true, true)); + } + return replace.apply(receiver, positions, valueObj); + } + @Specialization protected Object write(TruffleObject receiver, int idx, Object valueObj) { // idx + 1 R is indexing from 1 @@ -168,7 +235,7 @@ public final class RAbstractVectorAccessFactory implements StandardFactory { Object value = foreign2R.execute(valueObj); if (replace == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - replace = insert(ReplaceVectorNode.create(ElementAccessMode.SUBSCRIPT, true)); + replace = insert(ReplaceVectorNodeGen.create(ElementAccessMode.SUBSCRIPT, false, true, true)); } return replace.apply(receiver, positions, value); } @@ -356,12 +423,12 @@ public final class RAbstractVectorAccessFactory implements StandardFactory { @Override public CallTarget accessIsPointer() { - return NativeDataAccess.createIsPointer(); - } - - @Override - public CallTarget accessAsPointer() { - return NativeDataAccess.createAsPointer(); + return Truffle.getRuntime().createCallTarget(new InteropRootNode() { + @Override + public Object execute(VirtualFrame frame) { + return false; + } + }); } @Override @@ -370,7 +437,7 @@ public final class RAbstractVectorAccessFactory implements StandardFactory { @Override public Object execute(VirtualFrame frame) { RAbstractVector arg = (RAbstractVector) ForeignAccess.getReceiver(frame); - return NativeDataAccess.toNative(arg); + return new RObjectNativeWrapper((RObject) arg); } }); } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RArgsValuesAndNamesMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RArgsValuesAndNamesMR.java index 73b2ae57b8..63ff4f7cfa 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RArgsValuesAndNamesMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RArgsValuesAndNamesMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -40,8 +40,10 @@ import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.interop.R2Foreign; import com.oracle.truffle.r.runtime.interop.R2ForeignNodeGen; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RArgsValuesAndNames.class) public class RArgsValuesAndNamesMR { @@ -92,15 +94,15 @@ public class RArgsValuesAndNamesMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RConnectionMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RConnectionMR.java index 2ca10db203..eb2e28eba0 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RConnectionMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RConnectionMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -29,6 +29,8 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.conn.RConnection; import com.oracle.truffle.r.runtime.data.NativeDataAccess; +import com.oracle.truffle.r.runtime.data.RObject; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RConnection.class) public class RConnectionMR { @@ -42,15 +44,15 @@ public class RConnectionMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REmptyMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REmptyMR.java index fe15844891..69cf785f0d 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REmptyMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REmptyMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -29,6 +29,8 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.REmpty; +import com.oracle.truffle.r.runtime.data.RObject; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = REmpty.class) public class REmptyMR { @@ -42,15 +44,15 @@ public class REmptyMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REnvironmentMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REnvironmentMR.java index 09fe5cd331..cd81b31eec 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REnvironmentMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/REnvironmentMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -46,22 +46,17 @@ import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNode; import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.interop.Foreign2R; import com.oracle.truffle.r.runtime.interop.Foreign2RNodeGen; import com.oracle.truffle.r.runtime.interop.R2Foreign; import com.oracle.truffle.r.runtime.interop.R2ForeignNodeGen; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = REnvironment.class) public class REnvironmentMR { - @Resolve(message = "TO_NATIVE") - public abstract static class REnvironmentToNativeNode extends Node { - protected Object access(REnvironment receiver) { - return NativeDataAccess.toNative(receiver); - } - } - @Resolve(message = "READ") public abstract static class REnvironmentReadNode extends Node { @Child private REnvironmentReadImplNode readNode = REnvironmentReadImplNodeGen.create(); @@ -99,15 +94,15 @@ public class REnvironmentMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RExternalPtrMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RExternalPtrMR.java index 255ce94646..404c5af7f1 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RExternalPtrMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RExternalPtrMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -27,8 +27,9 @@ import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RExternalPtr; +import com.oracle.truffle.r.runtime.data.RObject; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RExternalPtr.class) public class RExternalPtrMR { @@ -42,15 +43,15 @@ public class RExternalPtrMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java index 1aeb17a752..509fef6826 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RFunctionMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -39,12 +39,14 @@ import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; import com.oracle.truffle.r.runtime.env.frame.RFrameSlot; import com.oracle.truffle.r.runtime.interop.Foreign2R; import com.oracle.truffle.r.runtime.interop.Foreign2RNodeGen; import com.oracle.truffle.r.runtime.interop.R2Foreign; import com.oracle.truffle.r.runtime.interop.R2ForeignNodeGen; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RFunction.class) public class RFunctionMR { @@ -63,13 +65,6 @@ public class RFunctionMR { } } - @Resolve(message = "TO_NATIVE") - public abstract static class RFunctionToNativeNode extends Node { - protected Object access(RFunction receiver) { - return NativeDataAccess.toNative(receiver); - } - } - @Resolve(message = "EXECUTE") public abstract static class RFunctionExecuteNode extends Node { @Child private Foreign2R foreign2R = Foreign2RNodeGen.create(); @@ -106,15 +101,15 @@ public class RFunctionMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RLanguageMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RLanguageMR.java index 3dc32e487f..c05941b896 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RLanguageMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RLanguageMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -41,8 +41,10 @@ import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RLogical; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.interop.R2Foreign; import com.oracle.truffle.r.runtime.interop.R2ForeignNodeGen; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RLanguage.class) public class RLanguageMR { @@ -61,13 +63,6 @@ public class RLanguageMR { } } - @Resolve(message = "TO_NATIVE") - public abstract static class RLanguageToNativeNode extends Node { - protected Object access(RLanguage receiver) { - return NativeDataAccess.toNative(receiver); - } - } - @Resolve(message = "READ") public abstract static class RLanguageReadNode extends Node { @Child private ReadNode readNode = RLanguageMRFactory.ReadNodeGen.create(); @@ -88,15 +83,15 @@ public class RLanguageMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RMissingMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RMissingMR.java index 53e246cf04..bc802da515 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RMissingMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RMissingMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -29,6 +29,8 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.RUnboundValue; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RMissing.class) public class RMissingMR { @@ -42,15 +44,15 @@ public class RMissingMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RMissing receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RNullMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RNullMR.java index 472757526d..611a2532fd 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RNullMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RNullMR.java @@ -32,6 +32,7 @@ import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.interop.RNullMRContextState; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RNull.class) public class RNullMR { @@ -52,22 +53,15 @@ public class RNullMR { @Resolve(message = "TO_NATIVE") public abstract static class RNullToNativeNode extends Node { - protected Object access(@SuppressWarnings("unused") RNull receiver) { - return NativePointer.NULL_NATIVEPOINTER; + protected Object access(RNull receiver) { + return new RObjectNativeWrapper(receiver); } } @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); - } - } - - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RPromiseMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RPromiseMR.java index 2e1bb6799d..5418eefaae 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RPromiseMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RPromiseMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -41,7 +41,9 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.data.RPromise; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RPromise.class) public class RPromiseMR { @@ -86,24 +88,17 @@ public class RPromiseMR { } } - @Resolve(message = "TO_NATIVE") - public abstract static class RPromiseToNativeNode extends Node { - protected Object access(RPromise receiver) { - return NativeDataAccess.toNative(receiver); - } - } - @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RS4ObjectMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RS4ObjectMR.java index 0e944adbbe..4c47887fb2 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RS4ObjectMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RS4ObjectMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -48,12 +48,14 @@ import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.data.RS4Object; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.interop.Foreign2R; import com.oracle.truffle.r.runtime.interop.Foreign2RNodeGen; import com.oracle.truffle.r.runtime.interop.R2Foreign; import com.oracle.truffle.r.runtime.interop.R2ForeignNodeGen; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RS4Object.class) public class RS4ObjectMR { @@ -105,15 +107,15 @@ public class RS4ObjectMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RSymbolMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RSymbolMR.java index 4fed921ae4..bc48d623e3 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RSymbolMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RSymbolMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -28,7 +28,9 @@ import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.data.NativeDataAccess; +import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RSymbol.class) public class RSymbolMR { @@ -40,24 +42,17 @@ public class RSymbolMR { } } - @Resolve(message = "TO_NATIVE") - public abstract static class RSymbolToNativeNode extends Node { - protected Object access(RSymbol receiver) { - return NativeDataAccess.toNative(receiver); - } - } - @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RUnboundValueMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RUnboundValueMR.java index c20ef87dfe..e94e8adcd4 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RUnboundValueMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RUnboundValueMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -27,8 +27,8 @@ import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RUnboundValue; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = RUnboundValue.class) public class RUnboundValueMR { @@ -42,15 +42,15 @@ public class RUnboundValueMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RUnboundValue receiver) { + return new RObjectNativeWrapper(receiver); } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java index 9c89ec3258..5b8a625813 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java @@ -38,15 +38,32 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; +import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.ArityException; +import com.oracle.truffle.api.interop.CanResolve; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.ForeignAccess.StandardFactory; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.java.JavaInterop; +import com.oracle.truffle.api.interop.UnknownIdentifierException; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.interop.UnsupportedTypeException; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.ffi.impl.common.JavaUpCallsRFFIImplFactory.VectorWrapperNativePointerFactory.DispatchAllocateNodeGen; import com.oracle.truffle.r.ffi.impl.upcalls.UpCallsRFFI; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; @@ -55,9 +72,7 @@ import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RCleanUp; import com.oracle.truffle.r.runtime.REnvVars; import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RErrorHandling; -import com.oracle.truffle.r.runtime.RErrorHandling.HandlerStacks; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RSource; @@ -65,15 +80,15 @@ import com.oracle.truffle.r.runtime.RSrcref; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.conn.ConnectionSupport.BaseRConnection; -import com.oracle.truffle.r.runtime.conn.ConnectionSupport.InvalidConnection; -import com.oracle.truffle.r.runtime.conn.NativeConnections.NativeRConnection; import com.oracle.truffle.r.runtime.conn.RConnection; import com.oracle.truffle.r.runtime.context.Engine.IncompleteSourceException; import com.oracle.truffle.r.runtime.context.Engine.ParseException; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.CharSXPWrapper; +import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributesLayout; +import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RExpression; @@ -88,11 +103,13 @@ import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RPromise.EagerPromise; +import com.oracle.truffle.r.runtime.data.RRawVector; import com.oracle.truffle.r.runtime.data.RShareable; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.data.RUnboundValue; +import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -568,7 +585,7 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { RShareable r = (RShareable) x; int actual = getNamed(r); if (v < actual) { - RError.warning(RError.NO_CALLER, Message.GENERIC, "Native code attempted to decrease the reference count. This operation is ignored."); + RError.warning(RError.NO_CALLER, RError.Message.GENERIC, "Native code attempted to decrease the reference count. This operation is ignored."); return RNull.instance; } if (v == 2) { @@ -1229,8 +1246,8 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { } @Override - public RExternalPtr R_MakeExternalPtr(long addr, Object tag, Object prot) { - return RDataFactory.createExternalPtr(new SymbolHandle(addr), tag, prot); + public RExternalPtr R_MakeExternalPtr(Object addr, Object tag, Object prot) { + throw implementedAsNode(); } @Override @@ -1311,14 +1328,8 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { @Override @TruffleBoundary - public Object R_new_custom_connection(String description, String mode, String className, Object connAddrObj) { - // TODO handle encoding properly ! - RExternalPtr connAddr = guaranteeInstanceOf(connAddrObj, RExternalPtr.class); - try { - return new NativeRConnection(description, mode, className, connAddr).asVector(); - } catch (IOException e) { - return InvalidConnection.instance.asVector(); - } + public Object R_new_custom_connection(Object description, Object mode, Object className, Object connAddrObj) { + throw implementedAsNode(); } @Override @@ -1358,25 +1369,31 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { return RConnection.fromIndex(fd); } + private static VectorWrapper wrapString(String s) { + CharSXPWrapper v = CharSXPWrapper.create(s); + NativeDataAccess.asPointer(v); + return new VectorWrapper(v); + } + @Override @TruffleBoundary - public String getSummaryDescription(Object x) { + public Object getSummaryDescription(Object x) { BaseRConnection conn = guaranteeInstanceOf(x, BaseRConnection.class); - return conn.getSummaryDescription(); + return wrapString(conn.getSummaryDescription()); } @Override @TruffleBoundary - public String getConnectionClassString(Object x) { + public Object getConnectionClassString(Object x) { BaseRConnection conn = guaranteeInstanceOf(x, BaseRConnection.class); - return conn.getConnectionClass(); + return wrapString(conn.getConnectionClass()); } @Override @TruffleBoundary - public String getOpenModeString(Object x) { + public Object getOpenModeString(Object x) { BaseRConnection conn = guaranteeInstanceOf(x, BaseRConnection.class); - return conn.getOpenMode().toString(); + return wrapString(conn.getOpenMode().toString()); } @Override @@ -1645,4 +1662,276 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { throw implementedAsNode(); } + public static class VectorWrapperNativePointer implements TruffleObject { + + private final TruffleObject vector; + + VectorWrapperNativePointer(TruffleObject vector) { + this.vector = vector; + assert vector instanceof RObject; + NativeDataAccess.asPointer(vector); // initialize the native mirror in the vector + } + + abstract static class InteropRootNode extends RootNode { + InteropRootNode() { + super(/* TruffleRLanguageImpl.getCurrentLanguage() */null); + } + + @Override + public final SourceSection getSourceSection() { + return RSyntaxNode.INTERNAL; + } + } + + // TODO: with separate version of this for the different types, it would be more efficient + // and not need the dispatch + public abstract static class DispatchAllocate extends Node { + private static final long EMPTY_DATA_ADDRESS = 0x1BAD; + + public abstract long execute(Object vector); + + @Specialization + protected static long get(RIntVector vector) { + return vector.allocateNativeContents(); + } + + @Specialization + protected static long get(RLogicalVector vector) { + return vector.allocateNativeContents(); + } + + @Specialization + protected static long get(RRawVector vector) { + return vector.allocateNativeContents(); + } + + @Specialization + protected static long get(RDoubleVector vector) { + return vector.allocateNativeContents(); + } + + @Specialization + protected static long get(RComplexVector vector) { + return vector.allocateNativeContents(); + } + + @Specialization + protected static long get(CharSXPWrapper vector) { + return vector.allocateNativeContents(); + } + + @Specialization + protected static long get(@SuppressWarnings("unused") RNull nullValue) { + // Note: GnuR is OK with, e.g., INTEGER(NULL), but it's illegal to read from or + // write to the resulting address. + return EMPTY_DATA_ADDRESS; + } + + @Fallback + protected static long get(Object vector) { + throw RInternalError.shouldNotReachHere("invalid wrapped object " + vector.getClass().getSimpleName()); + } + } + + @Override + public ForeignAccess getForeignAccess() { + return ForeignAccess.create(VectorWrapperNativePointer.class, new StandardFactory() { + @Override + public CallTarget accessIsNull() { + return Truffle.getRuntime().createCallTarget(new InteropRootNode() { + @Override + public Object execute(VirtualFrame frame) { + return false; + } + }); + } + + @Override + public CallTarget accessIsPointer() { + return Truffle.getRuntime().createCallTarget(new InteropRootNode() { + @Override + public Object execute(VirtualFrame frame) { + return true; + } + }); + } + + @Override + public CallTarget accessAsPointer() { + return Truffle.getRuntime().createCallTarget(new InteropRootNode() { + @Child private DispatchAllocate dispatch = DispatchAllocateNodeGen.create(); + + @Override + public Object execute(VirtualFrame frame) { + VectorWrapperNativePointer receiver = (VectorWrapperNativePointer) ForeignAccess.getReceiver(frame); + return dispatch.execute(receiver.vector); + } + }); + } + + @Override + public CallTarget accessToNative() { + return Truffle.getRuntime().createCallTarget(new InteropRootNode() { + @Override + public Object execute(VirtualFrame frame) { + return ForeignAccess.getReceiver(frame); + } + }); + } + }); + } + } + + @MessageResolution(receiverType = VectorWrapper.class) + public static class VectorWrapperMR { + + @Resolve(message = "IS_POINTER") + public abstract static class IntVectorWrapperNativeIsPointerNode extends Node { + protected Object access(@SuppressWarnings("unused") VectorWrapper receiver) { + return false; + } + } + + @Resolve(message = "TO_NATIVE") + public abstract static class IntVectorWrapperNativeAsPointerNode extends Node { + protected Object access(VectorWrapper receiver) { + return new VectorWrapperNativePointer(receiver.vector); + } + } + + @Resolve(message = "HAS_SIZE") + public abstract static class VectorWrapperHasSizeNode extends Node { + protected Object access(@SuppressWarnings("unused") VectorWrapper receiver) { + return true; + } + } + + @Resolve(message = "GET_SIZE") + public abstract static class VectorWrapperGetSizeNode extends Node { + @Child private Node getSizeMsg = Message.GET_SIZE.createNode(); + + protected Object access(VectorWrapper receiver) { + try { + return ForeignAccess.sendGetSize(getSizeMsg, receiver.vector); + } catch (UnsupportedMessageException e) { + throw RInternalError.shouldNotReachHere(e); + } + } + } + + @Resolve(message = "READ") + abstract static class VectorWrapperReadNode extends Node { + @Child private Node readMsg = Message.READ.createNode(); + + public Object access(VectorWrapper receiver, Object index) { + try { + return ForeignAccess.sendRead(readMsg, receiver.vector, index); + } catch (UnsupportedMessageException | UnknownIdentifierException e) { + throw RInternalError.shouldNotReachHere(e); + } + } + } + + @Resolve(message = "WRITE") + abstract static class VectorWrapperWriteNode extends Node { + @Child private Node writeMsg = Message.WRITE.createNode(); + + public Object access(VectorWrapper receiver, Object index, Object value) { + try { + return ForeignAccess.sendWrite(writeMsg, receiver.vector, index, value); + } catch (UnsupportedMessageException | UnknownIdentifierException | UnsupportedTypeException e) { + throw RInternalError.shouldNotReachHere(e); + } + } + } + + @Resolve(message = "IS_EXECUTABLE") + abstract static class VectorWrapperIsExecutableNode extends Node { + @Child private Node isExecMsg = Message.IS_EXECUTABLE.createNode(); + + public Object access(VectorWrapper receiver) { + return ForeignAccess.sendIsExecutable(isExecMsg, receiver.vector); + } + } + + @Resolve(message = "EXECUTE") + abstract static class VectorWrapperExecuteNode extends Node { + @Child private Node execMsg = Message.createExecute(0).createNode(); + + protected Object access(VectorWrapper receiver, Object[] arguments) { + try { + // Currently, there is only one "executable" object, which is CharSXPWrapper. + // See CharSXPWrapperMR for the EXECUTABLE message handler. + assert arguments.length == 0 && receiver.vector instanceof CharSXPWrapper; + return ForeignAccess.sendExecute(execMsg, receiver.vector); + } catch (UnsupportedMessageException | UnsupportedTypeException | ArityException e) { + throw RInternalError.shouldNotReachHere(e); + } + } + } + + @CanResolve + public abstract static class VectorWrapperCheck extends Node { + protected static boolean test(TruffleObject receiver) { + return receiver instanceof VectorWrapper; + } + } + } + + public static final class VectorWrapper implements TruffleObject { + + private final TruffleObject vector; + + public VectorWrapper(TruffleObject vector) { + this.vector = vector; + } + + public TruffleObject getVector() { + return vector; + } + + @Override + public ForeignAccess getForeignAccess() { + return VectorWrapperMRForeign.ACCESS; + } + } + + @Override + public Object INTEGER(Object x) { + // also handles LOGICAL + assert x instanceof RIntVector || x instanceof RLogicalVector || x == RNull.instance; + return new VectorWrapper(guaranteeVectorOrNull(x, RVector.class)); + } + + @Override + public Object LOGICAL(Object x) { + return new VectorWrapper(guaranteeVectorOrNull(x, RLogicalVector.class)); + } + + @Override + public Object REAL(Object x) { + return new VectorWrapper(guaranteeVectorOrNull(x, RDoubleVector.class)); + } + + @Override + public Object RAW(Object x) { + return new VectorWrapper(guaranteeVectorOrNull(x, RRawVector.class)); + } + + @Override + public Object COMPLEX(Object x) { + return new VectorWrapper(guaranteeVectorOrNull(x, RComplexVector.class)); + } + + @Override + public Object R_CHAR(Object x) { + return new VectorWrapper(guaranteeVectorOrNull(x, CharSXPWrapper.class)); + } + + private static TruffleObject guaranteeVectorOrNull(Object obj, Class<? extends TruffleObject> clazz) { + if (obj == RNull.instance) { + return RNull.instance; + } + return guaranteeInstanceOf(obj, clazz); + } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/CharSXPWrapperMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/CharSXPWrapperMR.java index a59156ff9f..5ba2936057 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/CharSXPWrapperMR.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/CharSXPWrapperMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -27,23 +27,80 @@ import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.CharSXPWrapper; -import com.oracle.truffle.r.runtime.data.NativeDataAccess; +import com.oracle.truffle.r.runtime.data.RObject; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = CharSXPWrapper.class) public class CharSXPWrapperMR { @Resolve(message = "IS_POINTER") public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); + protected boolean access(@SuppressWarnings("unused") Object receiver) { + return false; } } - @Resolve(message = "AS_POINTER") - public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + @Resolve(message = "TO_NATIVE") + public abstract static class ToNativeNode extends Node { + protected Object access(RObject receiver) { + return new RObjectNativeWrapper(receiver); + } + } + + @Resolve(message = "HAS_SIZE") + public abstract static class NCAHasSizeNode extends Node { + protected boolean access(@SuppressWarnings("unused") NativeCharArray receiver) { + return true; + } + } + + @Resolve(message = "GET_SIZE") + public abstract static class GetSizeNode extends Node { + protected Object access(CharSXPWrapper receiver) { + return receiver.getLength(); + } + } + + @Resolve(message = "READ") + public abstract static class ReadNode extends Node { + private final ConditionProfile prof1 = ConditionProfile.createBinaryProfile(); + private final ConditionProfile prof2 = ConditionProfile.createBinaryProfile(); + + protected Object access(CharSXPWrapper receiver, Number indexNum) { + int index = indexNum.intValue(); + String contents = receiver.getContents(); + int len = contents.length(); + if (prof1.profile(index < len)) { + return contents.charAt(index); + } else if (prof2.profile(index == len)) { + return 0; + } else { + throw RInternalError.shouldNotReachHere(); + } + } + } + + /** + * The <code>EXECUTABLE</code> message is used to extract the string wrapped in + * {@link CharSXPWrapper}. It is called only from the LLVM version of the + * <code>ensure_string</code> function in + * <code>com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c</code>. + */ + @Resolve(message = "EXECUTE") + public abstract static class NCAToStringNode extends Node { + + protected java.lang.Object access(CharSXPWrapper receiver, @SuppressWarnings("unused") Object[] arguments) { + return receiver.getContents(); + } + } + + @Resolve(message = "IS_EXECUTABLE") + public abstract static class NCAToStringIsExecutableNode extends Node { + protected Object access(@SuppressWarnings("unused") CharSXPWrapper receiver) { + return true; } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/DLLInfoMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/DLLInfoMR.java index 7027783e7e..57ee20e69d 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/DLLInfoMR.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/DLLInfoMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -27,8 +27,9 @@ import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.r.runtime.data.NativeDataAccess; import com.oracle.truffle.r.runtime.ffi.DLL; +import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; +import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; @MessageResolution(receiverType = DLL.DLLInfo.class) public class DLLInfoMR { @@ -40,17 +41,10 @@ public class DLLInfoMR { } } - @Resolve(message = "IS_POINTER") - public abstract static class IsPointerNode extends Node { - protected boolean access(Object receiver) { - return NativeDataAccess.isPointer(receiver); - } - } - - @Resolve(message = "AS_POINTER") + @Resolve(message = "TO_NATIVE") public abstract static class AsPointerNode extends Node { - protected long access(Object receiver) { - return NativeDataAccess.asPointer(receiver); + protected Object access(Object receiver) { + return new RObjectNativeWrapper((DLLInfo) receiver); } } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeCharArrayMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeCharArrayMR.java index 1b5d2ff3ca..ed1b0f2f72 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeCharArrayMR.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeCharArrayMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -35,6 +35,10 @@ public class NativeCharArrayMR { protected byte access(NativeCharArray receiver, int index) { return receiver.read(index); } + + protected byte access(NativeCharArray receiver, long index) { + return receiver.read((int) index); + } } @Resolve(message = "WRITE") @@ -43,6 +47,11 @@ public class NativeCharArrayMR { receiver.write(index, value); return value; } + + protected Object access(NativeCharArray receiver, long index, byte value) { + receiver.write((int) index, value); + return value; + } } @Resolve(message = "HAS_SIZE") @@ -66,6 +75,21 @@ public class NativeCharArrayMR { } } + @Resolve(message = "EXECUTE") + public abstract static class NCAToStringNode extends Node { + + protected java.lang.Object access(NativeCharArray receiver, @SuppressWarnings("unused") Object[] arguments) { + return new String(receiver.getValue()); + } + } + + @Resolve(message = "IS_EXECUTABLE") + public abstract static class NCAToStringIsExecutableNode extends Node { + protected Object access(@SuppressWarnings("unused") NativeCharArray receiver) { + return true; + } + } + @CanResolve public abstract static class NCACheck extends Node { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeNACheck.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeNACheck.java index b6aa85883d..35bc457616 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeNACheck.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeNACheck.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -23,6 +23,7 @@ package com.oracle.truffle.r.ffi.impl.interop; import static com.oracle.truffle.r.ffi.impl.interop.UnsafeAdapter.UNSAFE; + import com.oracle.truffle.r.runtime.data.RVector; /** diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ReadlinkResultMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ReadlinkResultMR.java index f11046518f..c17152410e 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ReadlinkResultMR.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ReadlinkResultMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -27,9 +27,7 @@ import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.r.runtime.RInternalError; @MessageResolution(receiverType = ReadlinkResult.class) public class ReadlinkResultMR { @@ -51,16 +49,21 @@ public class ReadlinkResultMR { @Resolve(message = "EXECUTE") public abstract static class BaseReadlinkResultCallbackExecute extends Node { - @Child private Node uboxNode = com.oracle.truffle.api.interop.Message.UNBOX.createNode(); + @Child private Node isNullNode = com.oracle.truffle.api.interop.Message.IS_NULL.createNode(); protected Object access(ReadlinkResult receiver, Object[] arguments) { - try { - Object link = ForeignAccess.sendUnbox(uboxNode, (TruffleObject) arguments[0]); - receiver.setResult(link instanceof String ? (String) link : null, (int) arguments[1]); - return receiver; - } catch (UnsupportedMessageException e) { - throw RInternalError.shouldNotReachHere(e); + Object link = arguments[0]; + if (link instanceof TruffleObject) { + if (ForeignAccess.sendIsNull(isNullNode, (TruffleObject) link)) { + link = null; + } else { + assert false; + } + } else { + assert link instanceof String; } + receiver.setResult((String) link, (int) arguments[1]); + return receiver; } } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java index b4e29fbcad..e9792234bc 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_C.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -26,6 +26,7 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.ffi.impl.interop.NativeDoubleArray; import com.oracle.truffle.r.ffi.impl.interop.NativeIntegerArray; @@ -68,6 +69,8 @@ class TruffleLLVM_C implements CRFFI { narg = new NativeDoubleArray((double[]) arg); } else if (arg instanceof byte[]) { narg = new NativeRawArray((byte[]) arg); + } else if (arg instanceof TruffleObject) { + narg = arg; } else { throw RInternalError.unimplemented(".C type: " + arg.getClass().getSimpleName()); } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java index 5c79a86f02..1075ab3f63 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Call.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -31,6 +31,7 @@ import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.java.JavaInterop; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.ffi.impl.common.RFFIUtils; @@ -40,7 +41,6 @@ import com.oracle.truffle.r.ffi.impl.llvm.upcalls.BytesToNativeCharArrayCall; import com.oracle.truffle.r.ffi.impl.llvm.upcalls.CharSXPToNativeArrayCall; import com.oracle.truffle.r.ffi.impl.upcalls.Callbacks; import com.oracle.truffle.r.ffi.impl.upcalls.FFIUnwrapNode; -import com.oracle.truffle.r.ffi.impl.upcalls.UpCallsRFFI; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.context.RContext; @@ -55,28 +55,59 @@ import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.ffi.RFFIVariables; final class TruffleLLVM_Call implements CallRFFI { - private static TruffleLLVM_UpCallsRFFIImpl upCallsRFFIImpl; TruffleLLVM_Call() { - upCallsRFFIImpl = new TruffleLLVM_UpCallsRFFIImpl(); RFFIUtils.initializeTracing(); } - static class ContextStateImpl implements RContext.ContextState { + static final class ContextStateImpl implements RContext.ContextState { + private final TruffleLLVM_UpCallsRFFIImpl upCallsRFFIImpl = new TruffleLLVM_UpCallsRFFIImpl(); private RContext context; - private boolean initDone; + private boolean initVarsDone; + private TruffleObject callbacksAddress; + private TruffleObject callbacks; @Override public ContextState initialize(RContext contextA) { this.context = contextA; RFFIFactory.getCallRFFI(); - if (!initDone) { + upCallsRFFIImpl.initialize(); + initCallbacks(); + return this; + } + + public void initializeVariables() { + if (!initVarsDone) { initVariables(context); - initCallbacks(context, upCallsRFFIImpl); - initDone = true; + initVarsDone = true; + } + } + + private void initCallbacks() { + try { + Callbacks.createCalls(upCallsRFFIImpl); + + TruffleObject[] callbacksArray = new TruffleObject[Callbacks.values().length + 2]; + for (Callbacks callback : Callbacks.values()) { + callbacksArray[callback.ordinal()] = callback.call; + } + callbacksArray[Callbacks.values().length] = new BytesToNativeCharArrayCall(upCallsRFFIImpl); + callbacksArray[Callbacks.values().length + 1] = new CharSXPToNativeArrayCall(upCallsRFFIImpl); + + callbacks = (TruffleObject) JavaInterop.asTruffleValue(callbacksArray); + + Node executeNode = Message.createExecute(0).createNode(); + SymbolHandle symbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + "Rinternals_getCallbacksAddress")); + + callbacksAddress = (TruffleObject) ForeignAccess.sendExecute(executeNode, symbolHandle.asTruffleObject()); + // Initialize the callbacks global variable + ForeignAccess.sendWrite(Message.WRITE.createNode(), callbacksAddress, 0, JavaInterop.asTruffleValue(new TruffleObject[0])); + + } catch (InteropException ex) { + throw RInternalError.shouldNotReachHere(ex); } - return this; } + } private enum INIT_VAR_FUN { @@ -90,9 +121,10 @@ final class TruffleLLVM_Call implements CallRFFI { INIT_VAR_FUN() { funName = "Call_initvar_" + name().toLowerCase(); } + } - private static void initVariables(RContext context) { + public static void initVariables(RContext context) { // must have parsed the variables module in libR for (INIT_VAR_FUN initVarFun : INIT_VAR_FUN.values()) { initVarFun.symbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + initVarFun.funName)); @@ -124,25 +156,6 @@ final class TruffleLLVM_Call implements CallRFFI { } } - private static void initCallbacks(RContext context, UpCallsRFFI upCallsImpl) { - Node executeNode = Message.createExecute(2).createNode(); - SymbolHandle symbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + "Rinternals_addCallback")); - - try { - // standard callbacks - Callbacks[] callbacks = Callbacks.values(); - Callbacks.createCalls(upCallsImpl); - for (Callbacks callback : callbacks) { - ForeignAccess.sendExecute(executeNode, symbolHandle.asTruffleObject(), callback.ordinal(), callback.call); - } - // llvm specific callbacks - ForeignAccess.sendExecute(executeNode, symbolHandle.asTruffleObject(), callbacks.length, new BytesToNativeCharArrayCall(upCallsRFFIImpl)); - ForeignAccess.sendExecute(executeNode, symbolHandle.asTruffleObject(), callbacks.length + 1, new CharSXPToNativeArrayCall(upCallsRFFIImpl)); - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } - } - abstract static class ToNativeNode extends Node { public abstract Object execute(Object value); @@ -187,6 +200,8 @@ final class TruffleLLVM_Call implements CallRFFI { abstract static class TruffleLLVM_InvokeCallNode extends Node implements InvokeCallNode { @Child private FFIUnwrapNode unwrap; + @Child private PushCallbacksNode pushCallbacks = new PushCallbacksNode(); + @Child private PopCallbacksNode popCallbacks = new PopCallbacksNode(); private final boolean isVoid; protected TruffleLLVM_InvokeCallNode(boolean isVoid) { @@ -202,6 +217,17 @@ final class TruffleLLVM_Call implements CallRFFI { return result; } + @Override + public Object dispatch(NativeCallInfo nativeCallInfo, Object[] args) { + TruffleLLVM_Context rffiCtx = TruffleLLVM_Context.getContextState(); + pushCallbacks.execute(rffiCtx.callState.callbacksAddress, rffiCtx.callState.callbacks); + try { + return InvokeCallNode.super.dispatch(nativeCallInfo, args); + } finally { + popCallbacks.execute(); + } + } + @Specialization(guards = {"cachedNativeCallInfo.name.equals(nativeCallInfo.name)", "args.length == cachedArgCount"}) protected Object invokeCallCached(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") @Cached("nativeCallInfo") NativeCallInfo cachedNativeCallInfo, @@ -280,4 +306,25 @@ final class TruffleLLVM_Call implements CallRFFI { public HandleUpCallExceptionNode createHandleUpCallExceptionNode() { return new HandleLLVMUpCallExceptionNode(); } + + public static final class PushCallbacksNode extends Node { + @Child private Node readPreviousCallbacks = Message.READ.createNode(); + @Child private Node setCallbacks = Message.WRITE.createNode(); + + public void execute(TruffleObject callbacksAddress, TruffleObject callbacks) { + try { + ForeignAccess.sendWrite(setCallbacks, callbacksAddress, 0, callbacks); + } catch (InteropException ex) { + throw RInternalError.shouldNotReachHere(ex); + } + } + } + + public static final class PopCallbacksNode extends Node { + @Child private Node setCallbacks = Message.WRITE.createNode(); + + public void execute() { + } + } + } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIContextState.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java similarity index 70% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIContextState.java rename to com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java index 220e1f7908..c7ddced84a 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIContextState.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -34,23 +34,23 @@ import com.oracle.truffle.r.runtime.ffi.RFFIContext; * A facade for the context state for the Truffle LLVM factory. Delegates to the various * module-specific pieces of state. */ -final class TruffleLLVM_RFFIContextState extends RFFIContext { +final class TruffleLLVM_Context extends RFFIContext { - TruffleLLVM_DLL.ContextStateImpl dllState = new TruffleLLVM_DLL.ContextStateImpl(); - TruffleLLVM_Call.ContextStateImpl callState = new TruffleLLVM_Call.ContextStateImpl(); + final TruffleLLVM_DLL.ContextStateImpl dllState = new TruffleLLVM_DLL.ContextStateImpl(); + final TruffleLLVM_Call.ContextStateImpl callState = new TruffleLLVM_Call.ContextStateImpl(); - TruffleLLVM_RFFIContextState() { + TruffleLLVM_Context() { super(new TruffleLLVM_C(), new TruffleLLVM_Base(), new TruffleLLVM_Call(), new TruffleLLVM_DLL(), new TruffleLLVM_UserRng(), new TruffleLLVM_Zip(), new TruffleLLVM_PCRE(), new TruffleLLVM_Lapack(), new TruffleLLVM_Stats(), new TruffleLLVM_Tools(), new TruffleLLVM_REmbed(), new TruffleLLVM_Misc()); } - static TruffleLLVM_RFFIContextState getContextState() { - return (TruffleLLVM_RFFIContextState) RContext.getInstance().getStateRFFI(); + static TruffleLLVM_Context getContextState() { + return (TruffleLLVM_Context) RContext.getInstance().getStateRFFI(); } - static TruffleLLVM_RFFIContextState getContextState(RContext context) { - return (TruffleLLVM_RFFIContextState) context.getStateRFFI(); + static TruffleLLVM_Context getContextState(RContext context) { + return (TruffleLLVM_Context) context.getStateRFFI(); } @Override @@ -64,6 +64,16 @@ final class TruffleLLVM_RFFIContextState extends RFFIContext { return this; } + @Override + public void initializeVariables(RContext context) { + super.initializeVariables(context); + + callState.initializeVariables(); + ((TruffleLLVM_PCRE) pcreRFFI).initialize(); + ((TruffleLLVM_Lapack) lapackRFFI).initialize(); + ((TruffleLLVM_Zip) zipRFFI).initialize(); + } + @Override public void beforeDispose(RContext context) { dllState.beforeDispose(context); @@ -72,7 +82,7 @@ final class TruffleLLVM_RFFIContextState extends RFFIContext { @Override public TruffleObject lookupNativeFunction(NativeFunction function) { - // TODO Auto-generated method stub - return null; + Object symValue = RContext.getInstance().getEnv().importSymbol("@" + function.getCallName()); + return (TruffleObject) symValue; } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java index b27c82d307..568b273a72 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DLL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -35,6 +35,7 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.r.runtime.RInternalError; @@ -95,7 +96,9 @@ public class TruffleLLVM_DLL implements DLLRFFI { private static TruffleLLVM_DLL truffleDLL; TruffleLLVM_DLL() { - assert truffleDLL == null; + if (truffleDLL != null) { + libRModules = truffleDLL.libRModules; + } truffleDLL = this; } @@ -185,10 +188,18 @@ public class TruffleLLVM_DLL implements DLLRFFI { parseLLVM(libName, ir); } return new LLVM_Handle(libName, irs); - } catch ( - - Exception ex) { - throw new UnsatisfiedLinkError(ex.getMessage()); + } catch (Exception ex) { + CompilerDirectives.transferToInterpreter(); + StringBuilder sb = new StringBuilder(); + Throwable t = ex; + while (t != null) { + if (t != ex) { + sb.append(": "); + } + sb.append(t.getMessage()); + t = t.getCause(); + } + throw new UnsatisfiedLinkError(sb.toString()); } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNode.java index b32c26f9cb..9bdf1ad1c0 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -29,6 +29,7 @@ import com.oracle.truffle.r.ffi.impl.common.DownCallNode; import com.oracle.truffle.r.ffi.impl.interop.NativeDoubleArray; import com.oracle.truffle.r.ffi.impl.interop.NativeIntegerArray; import com.oracle.truffle.r.ffi.impl.interop.NativeNACheck; +import com.oracle.truffle.r.ffi.impl.interop.NativePointer; import com.oracle.truffle.r.runtime.ffi.DLL; public abstract class TruffleLLVM_DownCallNode extends DownCallNode { @@ -49,7 +50,7 @@ public abstract class TruffleLLVM_DownCallNode extends DownCallNode { } else if (obj instanceof int[]) { args[i] = new NativeIntegerArray((int[]) obj); } else if (obj == null) { - args[i] = 0; + args[i] = NativePointer.NULL_NATIVEPOINTER; } } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Lapack.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Lapack.java index 08a6b293b9..e86d8513af 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Lapack.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Lapack.java @@ -45,7 +45,7 @@ import com.oracle.truffle.r.runtime.ffi.NativeFunction; */ public class TruffleLLVM_Lapack implements LapackRFFI { - TruffleLLVM_Lapack() { + void initialize() { /* * This is a workaround for bad LLVM generated by DragonEgg for (some) of the Lapack * functions; additional spurious arguments. Unfortunately for this to be portable we would @@ -58,12 +58,16 @@ public class TruffleLLVM_Lapack implements LapackRFFI { callTarget = openLLVMLibraries(); } else { callTarget = openNativeLibraries(); - callTarget.call(LibPaths.getBuiltinLibPath("gcc_s.1"), false, true); - callTarget.call(LibPaths.getBuiltinLibPath("quadmath.0"), false, true); - callTarget.call(LibPaths.getBuiltinLibPath("gfortran.3"), false, true); + callTarget.call(LibPaths.getBuiltinLibPath("gcc_s"), false, true); + callTarget.call(LibPaths.getBuiltinLibPath("quadmath"), false, true); + callTarget.call(LibPaths.getBuiltinLibPath("gfortran"), false, true); } - callTarget.call(LibPaths.getBuiltinLibPath("Rblas"), false, true); - callTarget.call(LibPaths.getBuiltinLibPath("Rlapack"), false, true); + + // The following libraries should be loaded eagerly (i.e. with the last parameter true), + // however, + // they do not load on Linux due to unbound symbols, such as "xerbla_". + callTarget.call(LibPaths.getBuiltinLibPath("Rblas"), false, false); + callTarget.call(LibPaths.getBuiltinLibPath("Rlapack"), false, false); } private static RootCallTarget openLLVMLibraries() { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_NativeDLL.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_NativeDLL.java index d1e460a9f2..0bf28ec578 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_NativeDLL.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_NativeDLL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -96,7 +96,7 @@ class TruffleLLVM_NativeDLL { @Resolve(message = "EXECUTE") public abstract static class ErrorCallbackExecuteNode extends Node { protected Object access(@SuppressWarnings("unused") VirtualFrame frame, ErrorCallback receiver, Object[] arguments) { - receiver.setResult((String) arguments[0]); + receiver.setResult("" + arguments[0]); return receiver; } } @@ -115,7 +115,7 @@ class TruffleLLVM_NativeDLL { long result = (long) ForeignAccess.sendExecute(Function.dlopen.executeNode, symbolHandle.asTruffleObject(), errorCallbackImpl, new NativeCharArray(path.getBytes()), local ? 1 : 0, now ? 1 : 0); if (result == 0) { - throw new UnsatisfiedLinkError(errorCallbackImpl.errorMessage); + throw new UnsatisfiedLinkError(errorCallbackImpl.errorMessage + " : " + path); } return result; } catch (InteropException e) { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_PCRE.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_PCRE.java index 468d499b72..ce5be6d555 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_PCRE.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_PCRE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -36,7 +36,7 @@ import com.oracle.truffle.r.runtime.ffi.PCRERFFI; public class TruffleLLVM_PCRE implements PCRERFFI { - TruffleLLVM_PCRE() { + void initialize() { // Need to ensure that the native pcre library is loaded String pcrePath = LibPaths.getBuiltinLibPath("pcre"); TruffleLLVM_NativeDLL.NativeDLOpenRootNode.create().getCallTarget().call(pcrePath, false, true); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIFactory.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIFactory.java index 15330cda36..573c9a73e1 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIFactory.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_RFFIFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -31,6 +31,6 @@ public final class TruffleLLVM_RFFIFactory extends RFFIFactory { @Override protected RFFIContext createRFFIContext() { CompilerAsserts.neverPartOfCompilation(); - return new TruffleLLVM_RFFIContextState(); + return new TruffleLLVM_Context(); } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Stats.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Stats.java index 9623d02f48..e2c6e30f11 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Stats.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Stats.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -39,6 +39,7 @@ import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.DLLRFFI; +import com.oracle.truffle.r.runtime.ffi.NativeFunction; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.ffi.StatsRFFI; @@ -161,10 +162,16 @@ public class TruffleLLVM_Stats implements StatsRFFI { } } - private static class TruffleLLVM_LminflNode extends Node implements LminflNode { + private static class TruffleLLVM_LminflNode extends TruffleLLVM_DownCallNode implements LminflNode { + + @Override + protected NativeFunction getFunction() { + return NativeFunction.lminfl; + } + @Override public void execute(double[] x, int ldx, int n, int k, int docoef, double[] qraux, double[] resid, double[] hat, double[] coef, double[] sigma, double tol) { - throw RInternalError.unimplemented("lfmin for LLVM backend, lfmin is used in influence external."); + call(x, ldx, n, k, docoef, qraux, resid, hat, coef, sigma, tol); } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java index d4a5792760..e1d6e40f1c 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_UpCallsRFFIImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -53,9 +53,9 @@ import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; */ public class TruffleLLVM_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl { - private static TruffleObject setSymbolHandle; + private TruffleObject setSymbolHandle; - public TruffleLLVM_UpCallsRFFIImpl() { + void initialize() { setSymbolHandle = new SymbolHandle(RContext.getInstance().getEnv().importSymbol("@" + "Rdynload_setSymbol")).asTruffleObject(); } @@ -73,7 +73,11 @@ public class TruffleLLVM_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl { @Override public Object Rf_mkCharLenCE(Object obj, int len, int encoding) { - if (obj instanceof NativeCharArray) { + if (obj instanceof VectorWrapper) { + Object wrappedCharSXP = ((VectorWrapper) obj).getVector(); + assert wrappedCharSXP instanceof CharSXPWrapper; + return wrappedCharSXP; + } else if (obj instanceof NativeCharArray) { byte[] bytes = ((NativeCharArray) obj).getValue(); return super.Rf_mkCharLenCE(bytes, bytes.length, encoding); } else { @@ -81,31 +85,6 @@ public class TruffleLLVM_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl { } } - @Override - public Object RAW(Object x) { - throw RInternalError.unimplemented(); - } - - @Override - public Object LOGICAL(Object x) { - throw RInternalError.unimplemented(); - } - - @Override - public Object INTEGER(Object x) { - throw RInternalError.unimplemented(); - } - - @Override - public Object REAL(Object x) { - throw RInternalError.unimplemented(); - } - - @Override - public Object COMPLEX(Object x) { - throw RInternalError.unimplemented(); - } - @Override public Object R_Home() { byte[] sbytes = REnvVars.rHome().getBytes(); @@ -134,11 +113,6 @@ public class TruffleLLVM_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl { } } - @Override - public Object R_CHAR(Object x) { - throw RInternalError.unimplemented(); - } - public Object getCallback(int index) { return Callbacks.values()[index].call; } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Zip.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Zip.java index f2338db68a..b6922d7ec1 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Zip.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Zip.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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,19 @@ */ package com.oracle.truffle.r.ffi.impl.llvm; +import com.oracle.truffle.r.ffi.impl.common.LibPaths; import com.oracle.truffle.r.ffi.impl.interop.NativeRawArray; import com.oracle.truffle.r.runtime.ffi.NativeFunction; import com.oracle.truffle.r.runtime.ffi.ZipRFFI; public class TruffleLLVM_Zip implements ZipRFFI { + + void initialize() { + // Need to ensure that the native libz library is loaded + String libzPath = LibPaths.getBuiltinLibPath("z"); + TruffleLLVM_NativeDLL.NativeDLOpenRootNode.create().getCallTarget().call(libzPath, false, true); + } + private static class TruffleLLVM_CompressNode extends TruffleLLVM_DownCallNode implements CompressNode { @Override diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/upcalls/CharSXPToNativeArrayCallMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/upcalls/CharSXPToNativeArrayCallMR.java index 3b29c21a0e..b0707c36a1 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/upcalls/CharSXPToNativeArrayCallMR.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/upcalls/CharSXPToNativeArrayCallMR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 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 @@ -32,6 +32,7 @@ public class CharSXPToNativeArrayCallMR implements RTruffleObject { @Resolve(message = "EXECUTE") public abstract static class CharSXPToNativeArrayCallExecute extends Node { + protected java.lang.Object access(CharSXPToNativeArrayCall receiver, Object[] arguments) { return receiver.upCallsImpl.charSXPToNativeCharArray(arguments[0]); } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java index 6b6ed65054..2e4f6ad6a4 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_RFFIFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -24,7 +24,6 @@ package com.oracle.truffle.r.ffi.impl.managed; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.RError; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_UpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_UpCallsRFFIImpl.java index 81e786669c..1727090487 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_UpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_UpCallsRFFIImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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,34 +22,19 @@ */ package com.oracle.truffle.r.ffi.impl.nfi; -import static com.oracle.truffle.r.ffi.impl.common.RFFIUtils.guaranteeInstanceOf; - import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.Message; -import com.oracle.truffle.api.interop.MessageResolution; -import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.ffi.impl.common.JavaUpCallsRFFIImpl; -import com.oracle.truffle.r.ffi.impl.nfi.TruffleNFI_UpCallsRFFIImplFactory.VectorWrapperMRFactory.DispatchAllocateNodeGen; import com.oracle.truffle.r.ffi.impl.upcalls.FFIUnwrapNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.CharSXPWrapper; -import com.oracle.truffle.r.runtime.data.RComplexVector; -import com.oracle.truffle.r.runtime.data.RDoubleVector; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLogicalVector; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RRawVector; -import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.CEntry; import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; @@ -82,136 +67,6 @@ public class TruffleNFI_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl { return result; } - @MessageResolution(receiverType = VectorWrapper.class) - public static class VectorWrapperMR { - - @Resolve(message = "IS_POINTER") - public abstract static class IntVectorWrapperNativeIsPointerNode extends Node { - protected Object access(@SuppressWarnings("unused") VectorWrapper receiver) { - return true; - } - } - - // TODO: with separate version of this for the different types, it would be more efficient - // and not need the dispatch - public abstract static class DispatchAllocate extends Node { - private static final long EMPTY_DATA_ADDRESS = 0x1BAD; - - public abstract long execute(Object vector); - - @Specialization - protected static long get(RIntVector vector) { - return vector.allocateNativeContents(); - } - - @Specialization - protected static long get(RLogicalVector vector) { - return vector.allocateNativeContents(); - } - - @Specialization - protected static long get(RRawVector vector) { - return vector.allocateNativeContents(); - } - - @Specialization - protected static long get(RDoubleVector vector) { - return vector.allocateNativeContents(); - } - - @Specialization - protected static long get(RComplexVector vector) { - return vector.allocateNativeContents(); - } - - @Specialization - protected static long get(CharSXPWrapper vector) { - return vector.allocateNativeContents(); - } - - @Specialization - protected static long get(@SuppressWarnings("unused") RNull nullValue) { - // Note: GnuR is OK with, e.g., INTEGER(NULL), but it's illegal to read from or - // write to the resulting address. - return EMPTY_DATA_ADDRESS; - } - - @Fallback - protected static long get(Object vector) { - throw RInternalError.shouldNotReachHere("invalid wrapped object " + vector.getClass().getSimpleName()); - } - } - - // TODO: "TO_NATIVE" should do the actual work of transferring the data - - @Resolve(message = "AS_POINTER") - public abstract static class IntVectorWrapperNativeAsPointerNode extends Node { - @Child private DispatchAllocate dispatch = DispatchAllocateNodeGen.create(); - - protected long access(VectorWrapper receiver) { - long address = dispatch.execute(receiver.vector); - // System.out.println(String.format("allocating native buffer for %s at %16x", - // receiver.vector.getClass().getSimpleName(), address)); - return address; - } - } - - // TODO: "READ", "WRITE" - - @CanResolve - public abstract static class VectorWrapperCheck extends Node { - protected static boolean test(TruffleObject receiver) { - return receiver instanceof VectorWrapper; - } - } - } - - public static final class VectorWrapper implements TruffleObject { - - private final Object vector; - - public VectorWrapper(Object vector) { - this.vector = vector; - } - - @Override - public ForeignAccess getForeignAccess() { - return VectorWrapperMRForeign.ACCESS; - } - } - - @Override - public Object INTEGER(Object x) { - // also handles LOGICAL - assert x instanceof RIntVector || x instanceof RLogicalVector || x == RNull.instance; - return new VectorWrapper(guaranteeVectorOrNull(x, RVector.class)); - } - - @Override - public Object LOGICAL(Object x) { - return new VectorWrapper(guaranteeVectorOrNull(x, RLogicalVector.class)); - } - - @Override - public Object REAL(Object x) { - return new VectorWrapper(guaranteeVectorOrNull(x, RDoubleVector.class)); - } - - @Override - public Object RAW(Object x) { - return new VectorWrapper(guaranteeVectorOrNull(x, RRawVector.class)); - } - - @Override - public Object COMPLEX(Object x) { - return new VectorWrapper(guaranteeVectorOrNull(x, RComplexVector.class)); - } - - @Override - public Object R_CHAR(Object x) { - return new VectorWrapper(guaranteeVectorOrNull(x, CharSXPWrapper.class)); - } - @Override @TruffleBoundary public Object getCCallable(String pkgName, String functionName) { @@ -239,10 +94,4 @@ public class TruffleNFI_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl { return (TruffleNFI_Context) RContext.getInstance().getStateRFFI(); } - private static Object guaranteeVectorOrNull(Object obj, Class<?> clazz) { - if (obj == RNull.instance) { - return RNull.instance; - } - return guaranteeInstanceOf(obj, clazz); - } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java index a47e196933..bc51d6d45c 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java @@ -28,7 +28,6 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode; -import com.oracle.truffle.r.nodes.attributes.GetAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode; import com.oracle.truffle.r.nodes.helpers.RFactorNodes; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/EnvNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/EnvNodes.java index e493bd7828..1aaa4af3d1 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/EnvNodes.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/EnvNodes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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,10 +22,11 @@ */ package com.oracle.truffle.r.ffi.impl.nodes; +import static com.oracle.truffle.r.ffi.impl.common.RFFIUtils.guaranteeInstanceOf; + import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.TypeSystemReference; -import static com.oracle.truffle.r.ffi.impl.common.RFFIUtils.guaranteeInstanceOf; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTypes; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NewCustomConnectionNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NewCustomConnectionNode.java new file mode 100644 index 0000000000..c0939de055 --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/NewCustomConnectionNode.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2018, 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.ffi.impl.nodes; + +import static com.oracle.truffle.r.runtime.data.NativeDataAccess.readNativeString; + +import java.io.IOException; + +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.conn.ConnectionSupport.InvalidConnection; +import com.oracle.truffle.r.runtime.conn.NativeConnections.NativeRConnection; +import com.oracle.truffle.r.runtime.data.RExternalPtr; + +public abstract class NewCustomConnectionNode extends FFIUpCallNode.Arg4 { + + public static NewCustomConnectionNode create() { + return NewCustomConnectionNodeGen.create(); + } + + @Specialization + Object handleStrings(String description, String mode, String className, RExternalPtr connAddr) { + try { + return new NativeRConnection(description, mode, className, connAddr).asVector(); + } catch (IOException e) { + return InvalidConnection.instance.asVector(); + } + } + + protected static Node createAsPointerNode() { + return Message.AS_POINTER.createNode(); + } + + @Specialization + Object handleAddresses(TruffleObject description, TruffleObject mode, TruffleObject className, RExternalPtr connAddr, + @Cached("createAsPointerNode()") Node descriptionAsPtrNode, @Cached("createAsPointerNode()") Node modeAsPtrNode, @Cached("createAsPointerNode()") Node classNameAsPtrNode) { + try { + return handleAddresses(ForeignAccess.sendAsPointer(descriptionAsPtrNode, description), ForeignAccess.sendAsPointer(modeAsPtrNode, mode), + ForeignAccess.sendAsPointer(classNameAsPtrNode, className), connAddr); + } catch (UnsupportedMessageException e) { + throw RInternalError.shouldNotReachHere(e); + } + } + + private static Object handleAddresses(long description, long mode, long className, RExternalPtr connAddr) { + try { + return new NativeRConnection(readNativeString(description), readNativeString(mode), readNativeString(className), connAddr).asVector(); + } catch (IOException e) { + return InvalidConnection.instance.asVector(); + } + } + +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RMakeExternalPtrNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RMakeExternalPtrNode.java new file mode 100644 index 0000000000..9ab584f34c --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RMakeExternalPtrNode.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, 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.ffi.impl.nodes; + +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.InteropException; +import com.oracle.truffle.api.interop.Message; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; + +public final class RMakeExternalPtrNode extends FFIUpCallNode.Arg3 { + + @Child Node asPointerNode = Message.AS_POINTER.createNode(); + + @Override + public Object executeObject(Object addrObj, Object tag, Object prot) { + try { + long addr = ForeignAccess.sendAsPointer(asPointerNode, (TruffleObject) addrObj); + return RDataFactory.createExternalPtr(new SymbolHandle(addr), tag, prot); + } catch (InteropException e) { + throw RInternalError.shouldNotReachHere(e); + } + + } +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/TryRfEvalNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/TryRfEvalNode.java index 56d24ce8d3..7048ab7c49 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/TryRfEvalNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/TryRfEvalNode.java @@ -34,7 +34,7 @@ public final class TryRfEvalNode extends FFIUpCallNode.Arg4 { @Child Node writeErrorFlagNode = Message.WRITE.createNode(); @Override - public Object executeObject(Object expr, Object env, Object errorFlag, @SuppressWarnings("unused") Object silent) { + public Object executeObject(Object expr, Object env, Object errorFlag, Object silent) { Object handlerStack = RErrorHandling.getHandlerStack(); Object restartStack = RErrorHandling.getRestartStack(); try { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIUnwrapNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIUnwrapNode.java index d1228b6459..4d5aafa461 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIUnwrapNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIUnwrapNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -48,6 +48,7 @@ public final class FFIUnwrapNode extends Node { private final BranchProfile isRTruffleObject = BranchProfile.create(); private final BranchProfile isNonBoxed = BranchProfile.create(); + private final BranchProfile isString = BranchProfile.create(); public Object execute(Object x) { if (x instanceof RTruffleObject) { @@ -93,10 +94,14 @@ public final class FFIUnwrapNode extends Node { } isNonBoxed.enter(); return x; + } else if (x instanceof String) { + isString.enter(); + return x; } else { CompilerDirectives.transferToInterpreter(); throw RInternalError.shouldNotReachHere("unexpected primitive value of class " + x.getClass().getSimpleName()); } + } public static FFIUnwrapNode create() { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java index 2693615f50..115713faba 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -26,7 +26,7 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.r.ffi.impl.nfi.TruffleNFI_UpCallsRFFIImpl.VectorWrapper; +import com.oracle.truffle.r.ffi.impl.common.JavaUpCallsRFFIImpl; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -103,7 +103,7 @@ public abstract class FFIWrapNode extends Node { } @Specialization - protected static Object wrap(VectorWrapper value) { + protected static Object wrap(JavaUpCallsRFFIImpl.VectorWrapper value) { return value; } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java index 90b7e0bbf1..d0d1530031 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java @@ -50,6 +50,8 @@ import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.SETCARNode; import com.oracle.truffle.r.ffi.impl.nodes.MatchNodes; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodes; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodes.LENGTHNode; +import com.oracle.truffle.r.ffi.impl.nodes.NewCustomConnectionNode; +import com.oracle.truffle.r.ffi.impl.nodes.RMakeExternalPtrNode; import com.oracle.truffle.r.ffi.impl.nodes.RandFunctionsNodes; import com.oracle.truffle.r.ffi.impl.nodes.RfEvalNode; import com.oracle.truffle.r.ffi.impl.nodes.TryRfEvalNode; @@ -317,7 +319,8 @@ public interface StdUpCallsRFFI { Object Rf_classgets(Object x, Object y); - Object R_MakeExternalPtr(long addr, Object tag, Object prot); + @RFFIUpCallNode(RMakeExternalPtrNode.class) + Object R_MakeExternalPtr(@RFFICpointer Object addr, Object tag, Object prot); long R_ExternalPtrAddr(Object x); @@ -345,7 +348,8 @@ public interface StdUpCallsRFFI { Object R_CHAR(Object x); - Object R_new_custom_connection(@RFFICstring String description, @RFFICstring String mode, @RFFICstring String className, Object readAddr); + @RFFIUpCallNode(NewCustomConnectionNode.class) + Object R_new_custom_connection(@RFFICstring(convert = false) Object description, @RFFICstring(convert = false) Object mode, @RFFICstring(convert = false) Object className, Object readAddr); int R_ReadConnection(int fd, long bufAddress, int size); @@ -353,11 +357,11 @@ public interface StdUpCallsRFFI { Object R_GetConnection(int fd); - String getSummaryDescription(Object x); + Object getSummaryDescription(Object x); - String getConnectionClassString(Object x); + Object getConnectionClassString(Object x); - String getOpenModeString(Object x); + Object getOpenModeString(Object x); boolean isSeekable(Object x); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java index 24ccf148b3..b425dc3efb 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java @@ -5,7 +5,7 @@ * * Copyright (c) 1995-2012, The R Core Team * Copyright (c) 2003, The R Foundation - * Copyright (c) 2015, 2017, Oracle and/or its affiliates + * Copyright (c) 2015, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -48,6 +48,7 @@ import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.context.RContext.ContextKind; import com.oracle.truffle.r.runtime.data.Closure; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -280,7 +281,14 @@ public class MethodsListDispatch { if (code == MethodCode.NO_METHODS && value != null) { primMethodsInfo.setPrimGeneric(primMethodIndex, null); primMethodsInfo.setPrimMethodList(primMethodIndex, null); - } else if (fundef != RNull.instance && value == null) { + } else if (fundef != RNull.instance && (value == null || RContext.getInstance().getKind() == ContextKind.SHARE_NOTHING)) { + // If the context kind is SHARE_NOTHING, primMethodsInfo must also be updated. + // Otherwise, the standard generic dispatcher (see StandardGeneric) running in a + // child context would get an invalid method table for a given primitive + // generic function obtained from the enclosing environment of that generic + // primitive function from the initial context. NB: The setMethod function, if + // called from a child context, uses the enclosing environment of the generic + // function from the current context to update the method table. if (!(fundef instanceof RFunction)) { throw error(RError.Message.PRIM_GENERIC_NOT_FUNCTION, fundef.getRType().getName()); } diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h index 1aaaaa7341..e0d64df093 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h +++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -302,7 +302,7 @@ typedef int (*call_isSeekable)(SEXP conn); typedef void (*call_registerRoutines)(DllInfo *dllInfo, int nstOrd, int num, const void* routines); typedef int (*call_useDynamicSymbols)(DllInfo *dllInfo, Rboolean value); -typedef void * (*call_setDotSymbolValues)(DllInfo *dllInfo, char *name, void *fun, int numArgs); +typedef void * (*call_setDotSymbolValues)(DllInfo *dllInfo, char *name, DL_FUNC fun, int numArgs); typedef int (*call_forceSymbols)(DllInfo *dllInfo, Rboolean value); typedef int (*call_registerCCallable)(const char *pkgname, const char *name, void *fun); typedef void* (*call_getCCallable)(const char *pkgname, const char *name); diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Connections.c b/com.oracle.truffle.r.native/fficall/src/truffle_common/Connections.c index 04bcb4e84c..64b41f963a 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Connections.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Connections.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -298,7 +298,6 @@ Rconnection R_GetConnection(SEXP sConn) { } init_con(new, summaryDesc, 0, openMode); - free(openMode); // the init_con function makes a copy new->class = connClass; new->canseek = (Rboolean) isSeekable; setFd(new, fd); diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h index 62570bfb08..6fc12a3a36 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h @@ -23,7 +23,7 @@ /* This file is "included" by the corresponding Rinternals.c in the truffle_nfi and truffle_llvm directories. - The implementation must define the following five functions: + The implementation must define the following functions: char *ensure_truffle_chararray_n(const char *x, int n) Ensures that the sequence of 'n' bytes starting at 'x' is in the @@ -33,6 +33,10 @@ Ensures that (on the Java side of the upcall) x, which must be null-terminated, appears as a java.lang.String + void *ensure_function(void *fptr) + Ensures that (on the Java side of the upcall) fptr appears as an executable + Truffle object. + Any of these functions could be the identity function. */ @@ -1018,30 +1022,30 @@ int *FASTR_INTEGER(SEXP x) { return result; } -int *LOGICAL(SEXP x){ - TRACE0(); - int *result = ((call_LOGICAL) callbacks[LOGICAL_x])(x); +double *FASTR_REAL(SEXP x){ + TRACE(TARGp, x); + double *result = ((call_REAL) callbacks[REAL_x])(x); checkExitCall(); return result; } -double *FASTR_REAL(SEXP x){ - TRACE(TARGp, x); - double *result = ((call_REAL) callbacks[REAL_x])(x); +Rcomplex *COMPLEX(SEXP x) { + TRACE0(); + Rcomplex *result = ((call_COMPLEX) callbacks[COMPLEX_x])(x); checkExitCall(); return result; } -Rbyte *RAW(SEXP x) { +int *LOGICAL(SEXP x){ TRACE0(); - Rbyte *result = ((call_RAW) callbacks[RAW_x])(x); + int *result = ((call_LOGICAL) callbacks[LOGICAL_x])(x); checkExitCall(); return result; } -Rcomplex *COMPLEX(SEXP x) { +Rbyte *RAW(SEXP x) { TRACE0(); - Rcomplex *result = ((call_COMPLEX) callbacks[COMPLEX_x])(x); + Rbyte *result = ((call_RAW) callbacks[RAW_x])(x); checkExitCall(); return result; } @@ -1655,7 +1659,7 @@ Rboolean R_forceSymbols(DllInfo *dllInfo, Rboolean value) { void *Rdynload_setSymbol(DllInfo *info, int nstOrd, void* routinesAddr, int index) { TRACE0(); const char *name; - void * fun; + void *fun; int numArgs; switch (nstOrd) { TRACE0(); @@ -1688,7 +1692,7 @@ void *Rdynload_setSymbol(DllInfo *info, int nstOrd, void* routinesAddr, int inde break; } } - void *result = ((call_setDotSymbolValues) callbacks[setDotSymbolValues_x])(info, ensure_string(name), fun, numArgs); + void *result = ((call_setDotSymbolValues) callbacks[setDotSymbolValues_x])(info, ensure_string(name), (DL_FUNC) ensure_function(fun), numArgs); checkExitCall(); return result; } diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/variables_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/variables_common.h new file mode 100644 index 0000000000..50855e8d24 --- /dev/null +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/variables_common.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2018, 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. + */ +#define NO_FASTR_REDEFINE +#include <string.h> +#include <Rinterface.h> +#include <trufflenfi.h> +#include "../common/rffi_variablesindex.h" + +// various ignored flags and variables nevertheless needed to resolve symbols +Rboolean R_Visible; +Rboolean R_interrupts_suspended; +int R_interrupts_pending; +Rboolean mbcslocale; +Rboolean useaqua; +char* OutDec = "."; +Rboolean utf8locale = FALSE; +Rboolean mbcslocale = FALSE; +Rboolean latin1locale = FALSE; +int R_dec_min_exponent = -308; +int max_contour_segments = 25000; + +// from sys-std.c +#include <R_ext/eventloop.h> + +InputHandler BasicInputHandler = {2, -1, NULL}; +InputHandler *R_InputHandlers = &BasicInputHandler; + +char *copystring(char *value) { + char *result = malloc(strlen(value) + 1); + strcpy(result, value); + return result; +} + +// --------------------------------------------------- +// Generated by RFFIVariables.java: + +char* R_Home; +char* R_TempDir; +SEXP R_GlobalEnv; +SEXP R_BaseEnv; +SEXP R_BaseNamespace; +SEXP R_NamespaceRegistry; +Rboolean R_Interactive; +SEXP R_NilValue; +SEXP R_UnboundValue; +SEXP R_MissingArg; +SEXP R_EmptyEnv; +SEXP R_Srcref; +SEXP R_Bracket2Symbol; /* "[[" */ +SEXP R_BracketSymbol; /* "[" */ +SEXP R_BraceSymbol; /* "{" */ +SEXP R_DoubleColonSymbol; /* "::" */ +SEXP R_ClassSymbol; /* "class" */ +SEXP R_DeviceSymbol; /* ".Device" */ +SEXP R_DevicesSymbol; /* ".Devices" */ +SEXP R_DimNamesSymbol; /* "dimnames" */ +SEXP R_DimSymbol; /* "dim" */ +SEXP R_DollarSymbol; /* "$" */ +SEXP R_DotsSymbol; /* "..." */ +SEXP R_DropSymbol; /* "drop" */ +SEXP R_LastvalueSymbol; /* ".Last.value" */ +SEXP R_LevelsSymbol; /* "levels" */ +SEXP R_ModeSymbol; /* "mode" */ +SEXP R_NameSymbol; /* "name" */ +SEXP R_NamesSymbol; /* "names" */ +SEXP R_NaRmSymbol; /* "na.rm" */ +SEXP R_PackageSymbol; /* "package" */ +SEXP R_QuoteSymbol; /* "quote" */ +SEXP R_RowNamesSymbol; /* "row.names" */ +SEXP R_SeedsSymbol; /* ".Random.seed" */ +SEXP R_SourceSymbol; /* "source" */ +SEXP R_TspSymbol; /* "tsp" */ +SEXP R_dot_defined; /* ".defined" */ +SEXP R_dot_Method; /* ".Method" */ +SEXP R_dot_target; /* ".target" */ +SEXP R_dot_packageName; /* ".packageName" */ +SEXP R_dot_Generic; /* ".Generic" */ +SEXP R_SrcrefSymbol; /* "srcref" */ +SEXP R_SrcfileSymbol; /* "srcfile" */ +SEXP R_NaString; +double R_NaN; +double R_PosInf; +double R_NegInf; +double R_NaReal; +int R_NaInt; +SEXP R_BlankString; +SEXP R_BlankScalarString; +SEXP R_BaseSymbol; /* "base" */ +SEXP R_NamespaceEnvSymbol; /* ".__NAMESPACE__." */ +SEXP R_RestartToken; /* "" */ +SEXP R_SortListSymbol; /* "sort.list" */ +SEXP R_SpecSymbol; /* "spec" */ +SEXP R_TripleColonSymbol; /* ":::" */ +SEXP R_PreviousSymbol; /* "previous" */ + +void Call_initvar_double(int index, double value) { + switch (index) { + case R_NaN_x: R_NaN = value; break; + case R_PosInf_x: R_PosInf = value; break; + case R_NegInf_x: R_NegInf = value; break; + case R_NaReal_x: R_NaReal = value; break; + default: + printf("Call_initvar_double: unimplemented index %d\n", index); + exit(1); + } +} + +void Call_initvar_int(int index, int value) { + switch (index) { + case R_Interactive_x: R_Interactive = value; break; + case R_NaInt_x: R_NaInt = value; break; + default: + printf("Call_initvar_int: unimplemented index %d\n", index); + exit(1); + } +} + +void Call_initvar_string(int index, char* value) { + switch (index) { + case R_Home_x: R_Home = copystring(value); break; + case R_TempDir_x: R_TempDir = copystring(value); break; + default: + printf("Call_initvar_string: unimplemented index %d\n", index); + exit(1); + } +} + +void Call_initvar_obj_common(int index, void* value) { + switch (index) { + case R_GlobalEnv_x: R_GlobalEnv = value; break; + case R_BaseEnv_x: R_BaseEnv = value; break; + case R_BaseNamespace_x: R_BaseNamespace = value; break; + case R_NamespaceRegistry_x: R_NamespaceRegistry = value; break; + case R_NilValue_x: R_NilValue = value; break; + case R_UnboundValue_x: R_UnboundValue = value; break; + case R_MissingArg_x: R_MissingArg = value; break; + case R_EmptyEnv_x: R_EmptyEnv = value; break; + case R_Srcref_x: R_Srcref = value; break; + case R_Bracket2Symbol_x: R_Bracket2Symbol = value; break; + case R_BracketSymbol_x: R_BracketSymbol = value; break; + case R_BraceSymbol_x: R_BraceSymbol = value; break; + case R_DoubleColonSymbol_x: R_DoubleColonSymbol = value; break; + case R_ClassSymbol_x: R_ClassSymbol = value; break; + case R_DeviceSymbol_x: R_DeviceSymbol = value; break; + case R_DevicesSymbol_x: R_DevicesSymbol = value; break; + case R_DimNamesSymbol_x: R_DimNamesSymbol = value; break; + case R_DimSymbol_x: R_DimSymbol = value; break; + case R_DollarSymbol_x: R_DollarSymbol = value; break; + case R_DotsSymbol_x: R_DotsSymbol = value; break; + case R_DropSymbol_x: R_DropSymbol = value; break; + case R_LastvalueSymbol_x: R_LastvalueSymbol = value; break; + case R_LevelsSymbol_x: R_LevelsSymbol = value; break; + case R_ModeSymbol_x: R_ModeSymbol = value; break; + case R_NameSymbol_x: R_NameSymbol = value; break; + case R_NamesSymbol_x: R_NamesSymbol = value; break; + case R_NaRmSymbol_x: R_NaRmSymbol = value; break; + case R_PackageSymbol_x: R_PackageSymbol = value; break; + case R_QuoteSymbol_x: R_QuoteSymbol = value; break; + case R_RowNamesSymbol_x: R_RowNamesSymbol = value; break; + case R_SeedsSymbol_x: R_SeedsSymbol = value; break; + case R_SourceSymbol_x: R_SourceSymbol = value; break; + case R_TspSymbol_x: R_TspSymbol = value; break; + case R_dot_defined_x: R_dot_defined = value; break; + case R_dot_Method_x: R_dot_Method = value; break; + case R_dot_target_x: R_dot_target = value; break; + case R_dot_packageName_x: R_dot_packageName = value; break; + case R_dot_Generic_x: R_dot_Generic = value; break; + case R_SrcrefSymbol_x: R_SrcrefSymbol = value; break; + case R_SrcfileSymbol_x: R_SrcfileSymbol = value; break; + case R_NaString_x: R_NaString = value; break; + case R_BlankString_x: R_BlankString = value; break; + case R_BlankScalarString_x: R_BlankScalarString = value; break; + case R_BaseSymbol_x: R_BaseSymbol = value; break; + case R_NamespaceEnvSymbol_x: R_NamespaceEnvSymbol = value; break; + case R_RestartToken_x: R_RestartToken = value; break; + case R_SortListSymbol_x: R_SortListSymbol = value; break; + case R_SpecSymbol_x: R_SpecSymbol = value; break; + case R_TripleColonSymbol_x: R_TripleColonSymbol = value; break; + case R_PreviousSymbol_x: R_PreviousSymbol = value; break; + default: + printf("Call_initvar_obj: unimplemented index %d\n", index); + exit(1); + } +} diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Makefile b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Makefile index 3077166a29..d3e7348634 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Makefile +++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2018, 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 @@ -67,7 +67,7 @@ SULONG_INCLUDES = -I$(SULONG_DIR)/include FFI_INCLUDES = -I$(TOPDIR)/include -I$(TOPDIR)/include/R_ext LOCAL_INCLUDES = -I . -I $(abspath ../include) -I $(abspath ../common) -INCLUDES := $(LOCAL_INCLUDES) $(FFI_INCLUDES) $(SULONG_INCLUDES) +INCLUDES := $(LOCAL_INCLUDES) $(FFI_INCLUDES) $(SULONG_INCLUDES) $(NFI_INCLUDES) FFLAGS := diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rembedded.c b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rembedded.c new file mode 100644 index 0000000000..30b330b406 --- /dev/null +++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rembedded.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014, 2018, 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. + */ +#include <Rinterface.h> +#include <rffiutils.h> +#include "../common/rffi_upcalls.h" + +char *R_HomeDir(void) { + return ((call_R_HomeDir) callbacks[R_HomeDir_x])(); +} + diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c index d47eaaf32b..4b3d916edd 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/Rinternals.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -37,9 +37,9 @@ typedef char* (*call_bytesToNativeCharArray)(SEXP e); typedef char* (*call_charSXPToNativeCharArray)(SEXP e); typedef char* (*call_R_Home)(); -void **callbacks = NULL; +__thread void **callbacks = NULL; -void Rinternals_addCallback(int index, void *callback) { +void Rinternals_addCallback(void** theCallbacks, int index, void *callback) { if (callbacks == NULL) { callbacks = truffle_managed_malloc(INTERNAL_UPCALLS_TABLE_SIZE * sizeof(void*)); } @@ -47,6 +47,17 @@ void Rinternals_addCallback(int index, void *callback) { callbacks[index] = callback; } +void*** Rinternals_getCallbacksAddress() { + return &callbacks; +} + +typedef SEXP (*call_Test)(const char *name); + +SEXP Rinternals_invoke(int index) { + void *callback = callbacks[index]; + return ((call_Test) callback)("aaa"); +} + static char *ensure_truffle_chararray_n(const char *x, int n) { if (truffle_is_truffle_object(x)) { return x; @@ -60,11 +71,21 @@ char *ensure_truffle_chararray(const char *x) { return (char *)x; } else { return ((call_bytesToNativeCharArray) callbacks[bytesToNativeCharArray_x])(truffle_read_n_bytes(x, strlen(x))); - } + } } void *ensure_string(const char *x) { - return truffle_read_string(x); + if (truffle_is_truffle_object(x)) { + // The input argument may also be a NativeCharArray object. The wrapped String is + // extracted by sending the EXECUTE message. + return ((void*(*)())x)(); + } else { + return x == NULL ? NULL : truffle_read_string(x); + } +} + +void *ensure_function(void *fptr) { + return truffle_address_to_function(fptr); } char *FASTR_R_Home() { @@ -75,34 +96,10 @@ char *FASTR_R_Home() { #include <string.h> #include "../truffle_common/Rinternals_truffle_common.h" -int *LOGICAL(SEXP x){ - return (int*) ((call_INTEGER) callbacks[LOGICAL_x])(x); -} - int *INTEGER(SEXP x){ return (int*) ((call_INTEGER) callbacks[INTEGER_x])(x); } - -Rbyte *RAW(SEXP x){ - return (Rbyte *) ((call_INTEGER) callbacks[REAL_x])(x); -} - - double *REAL(SEXP x){ - return (double*) ((call_INTEGER) callbacks[INTEGER_x])(x); -} - - -const char *R_CHAR(SEXP charsxp) { - return ((call_charSXPToNativeCharArray) callbacks[charSXPToNativeCharArray_x])(charsxp); + return (double*) ((call_REAL) callbacks[REAL_x])(x); } - -int *INTEGER(SEXP x) { - return FASTR_INTEGER(x); -} - -double *REAL(SEXP x){ - return FASTR_REAL(x); -} - diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.c b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.c index cbadacc9c0..31b3040430 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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,6 +22,9 @@ */ #include <rffiutils.h> +void checkExitCall() { +} + SEXP unimplemented(const char *name) { printf("unimplemented %s\n", name); exit(1); diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.h b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.h index 8413ee815f..e31231957f 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.h +++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/rffiutils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -31,6 +31,8 @@ char *ensure_truffle_chararray(const char *x); void *ensure_string(const char *x); -SEXP unimplemented(char *name); +void *ensure_function(void *fptr); +void checkExitCall(); +SEXP unimplemented(const char *name); #endif /* RFFIUTILS_H */ diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/variables.c b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/variables.c index 55fc5d08c6..0fa9e21035 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_llvm/variables.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_llvm/variables.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -20,189 +20,9 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ +#include "../truffle_common/variables_common.h" #include <rffiutils.h> -#include "../common/rffi_variablesindex.h" - -// TODO: this file can likely simply be removed, using the NFI version instead - - -// Arith.h -double R_NaN; /* IEEE NaN */ -double R_PosInf; /* IEEE Inf */ -double R_NegInf; /* IEEE -Inf */ -double R_NaReal; /* NA_REAL: IEEE */ -int R_NaInt; /* NA_INTEGER:= INT_MIN currently */ - -static void **variables = NULL; - -SEXP FASTR_R_NilValue() { - return (SEXP) variables[R_NilValue_x]; -} - -SEXP FASTR_R_UnboundValue() { - return variables[R_UnboundValue_x]; -} - -SEXP FASTR_R_EmptyEnv() { - return variables[R_EmptyEnv_x]; -} - -SEXP FASTR_R_MissingArg() { - return variables[R_MissingArg_x]; -} - -SEXP FASTR_R_BaseSymbol() { - return variables[R_BaseSymbol_x]; -} - -SEXP FASTR_R_BraceSymbol() { - return variables[R_BraceSymbol_x]; -} - -SEXP FASTR_R_Bracket2Symbol() { - return variables[R_Bracket2Symbol_x]; -} - -SEXP FASTR_R_BracketSymbol() { - return variables[R_BracketSymbol_x]; -} - -SEXP FASTR_R_ClassSymbol() { - return variables[R_ClassSymbol_x]; -} - -SEXP FASTR_R_DeviceSymbol() { - return variables[R_DeviceSymbol_x]; -} - -SEXP FASTR_R_DevicesSymbol() { - return variables[R_DevicesSymbol_x]; -} - -SEXP FASTR_R_DimNamesSymbol() { - return variables[R_DimNamesSymbol_x]; -} - -SEXP FASTR_R_DimSymbol() { - return variables[R_DimSymbol_x]; -} - -SEXP FASTR_R_DollarSymbol() { - return variables[R_DollarSymbol_x]; -} - -SEXP FASTR_R_DotsSymbol() { - return variables[R_DotsSymbol_x]; -} - -SEXP FASTR_R_DropSymbol() { - return variables[R_DropSymbol_x]; -} - -SEXP FASTR_R_LastvalueSymbol() { - return variables[R_LastvalueSymbol_x]; -} - -SEXP FASTR_R_LevelsSymbol() { - return variables[R_LevelsSymbol_x]; -} - -SEXP FASTR_R_ModeSymbol() { - return variables[R_ModeSymbol_x]; -} - -SEXP FASTR_R_NaRmSymbol() { - return variables[R_NaRmSymbol_x]; -} - -SEXP FASTR_R_NameSymbol() { - return variables[R_NameSymbol_x]; -} - -SEXP FASTR_R_NamesSymbol() { - return variables[R_NamesSymbol_x]; -} - -SEXP FASTR_R_NamespaceEnvSymbol() { - return variables[R_NamespaceEnvSymbol_x]; -} - -SEXP FASTR_R_PackageSymbol() { - return variables[R_PackageSymbol_x]; -} - -SEXP FASTR_R_QuoteSymbol() { - return variables[R_QuoteSymbol_x]; -} - -SEXP FASTR_R_RowNamesSymbol() { - return variables[R_RowNamesSymbol_x]; -} - -SEXP FASTR_R_SeedsSymbol() { - return variables[R_SeedsSymbol_x]; -} - -SEXP FASTR_R_SourceSymbol() { - return variables[R_SourceSymbol_x]; -} - -SEXP FASTR_R_TspSymbol() { - return variables[R_TspSymbol_x]; -} - -SEXP FASTR_R_dot_defined() { - return variables[R_dot_defined_x]; +void Call_initvar_obj(int index, void* value) { + Call_initvar_obj_common(index, value); } - -SEXP FASTR_R_dot_Method() { - return variables[R_dot_Method_x]; -} - -SEXP FASTR_R_dot_target() { - return variables[R_dot_target_x]; -} - -SEXP FASTR_R_NaString() { - return variables[R_NaString_x]; -} - -SEXP FASTR_R_BlankString() { - return variables[R_BlankString_x]; -} - -SEXP FASTR_R_BlankScalarString() { - return variables[R_BlankScalarString_x]; -} - -SEXP FASTR_R_SrcrefSymbol() { - return variables[R_SrcrefSymbol_x]; -} - -SEXP FASTR_R_SrcfileSymbol() { - return variables[R_SrcfileSymbol_x]; -} -void Call_initvar_double(int index, double value) { - switch (index) { - case R_NaN_x: R_NaN = value; break; - } -} - -void Call_initvar_int(int index, int value) { - switch (index) { - case R_NaInt_x: R_NaInt = value; break; - case R_PosInf_x: R_PosInf = value; break; - case R_NegInf_x: R_NegInf = value; break; - case R_NaReal_x: R_NaReal = value; break; - } -} - -void Call_initvar_obj(int index, void *value) { - if (variables == NULL) { - variables = truffle_managed_malloc(VARIABLES_TABLE_SIZE * sizeof(void*)); - } - variables[index] = value; -} - - diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rinternals.c index e2f6f44c8f..39b2d0b9ab 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rinternals.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -44,6 +44,10 @@ void *ensure_string(const char * x) { return (void *) x; } +void *ensure_function(void *fptr) { + return fptr; +} + #include "../truffle_common/Rinternals_truffle_common.h" #define ARRAY_CACHE_SIZE 5 diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h index d403ecedb5..6a628e6826 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h +++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -38,6 +38,8 @@ char *ensure_truffle_chararray(const char *x); void *ensure_string(const char *x); +void *ensure_function(void *fptr); + // use for an unimplemented API function void *unimplemented(const char *msg) __attribute__((noreturn)); diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/variables.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/variables.c index ed88cdaf12..05fdb4be58 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/variables.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/variables.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -20,187 +20,10 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -#define NO_FASTR_REDEFINE -#include <string.h> -#include <Rinterface.h> -#include <trufflenfi.h> +#include "../truffle_common/variables_common.h" #include <rffiutils.h> -#include "../common/rffi_variablesindex.h" - -// various ignored flags and variables nevertheless needed to resolve symbols -Rboolean R_Visible; -Rboolean R_interrupts_suspended; -int R_interrupts_pending; -Rboolean mbcslocale; -Rboolean useaqua; -char* OutDec = "."; -Rboolean utf8locale = FALSE; -Rboolean mbcslocale = FALSE; -Rboolean latin1locale = FALSE; -int R_dec_min_exponent = -308; -int max_contour_segments = 25000; - -// from sys-std.c -#include <R_ext/eventloop.h> - -InputHandler BasicInputHandler = {2, -1, NULL}; -InputHandler *R_InputHandlers = &BasicInputHandler; - -char *copystring(char *value) { - char *result = malloc(strlen(value) + 1); - strcpy(result, value); - return result; -} - -// --------------------------------------------------- -// Generated by RFFIVariables.java: - -char* R_Home; -char* R_TempDir; -SEXP R_GlobalEnv; -SEXP R_BaseEnv; -SEXP R_BaseNamespace; -SEXP R_NamespaceRegistry; -Rboolean R_Interactive; -SEXP R_NilValue; -SEXP R_UnboundValue; -SEXP R_MissingArg; -SEXP R_EmptyEnv; -SEXP R_Srcref; -SEXP R_Bracket2Symbol; /* "[[" */ -SEXP R_BracketSymbol; /* "[" */ -SEXP R_BraceSymbol; /* "{" */ -SEXP R_DoubleColonSymbol; /* "::" */ -SEXP R_ClassSymbol; /* "class" */ -SEXP R_DeviceSymbol; /* ".Device" */ -SEXP R_DevicesSymbol; /* ".Devices" */ -SEXP R_DimNamesSymbol; /* "dimnames" */ -SEXP R_DimSymbol; /* "dim" */ -SEXP R_DollarSymbol; /* "$" */ -SEXP R_DotsSymbol; /* "..." */ -SEXP R_DropSymbol; /* "drop" */ -SEXP R_LastvalueSymbol; /* ".Last.value" */ -SEXP R_LevelsSymbol; /* "levels" */ -SEXP R_ModeSymbol; /* "mode" */ -SEXP R_NameSymbol; /* "name" */ -SEXP R_NamesSymbol; /* "names" */ -SEXP R_NaRmSymbol; /* "na.rm" */ -SEXP R_PackageSymbol; /* "package" */ -SEXP R_QuoteSymbol; /* "quote" */ -SEXP R_RowNamesSymbol; /* "row.names" */ -SEXP R_SeedsSymbol; /* ".Random.seed" */ -SEXP R_SourceSymbol; /* "source" */ -SEXP R_TspSymbol; /* "tsp" */ -SEXP R_dot_defined; /* ".defined" */ -SEXP R_dot_Method; /* ".Method" */ -SEXP R_dot_target; /* ".target" */ -SEXP R_dot_packageName; /* ".packageName" */ -SEXP R_dot_Generic; /* ".Generic" */ -SEXP R_SrcrefSymbol; /* "srcref" */ -SEXP R_SrcfileSymbol; /* "srcfile" */ -SEXP R_NaString; -double R_NaN; -double R_PosInf; -double R_NegInf; -double R_NaReal; -int R_NaInt; -SEXP R_BlankString; -SEXP R_BlankScalarString; -SEXP R_BaseSymbol; /* "base" */ -SEXP R_NamespaceEnvSymbol; /* ".__NAMESPACE__." */ -SEXP R_RestartToken; /* "" */ -SEXP R_SortListSymbol; /* "sort.list" */ -SEXP R_SpecSymbol; /* "spec" */ -SEXP R_TripleColonSymbol; /* ":::" */ -SEXP R_PreviousSymbol; /* "previous" */ - -void Call_initvar_double(int index, double value) { - switch (index) { - case R_NaN_x: R_NaN = value; break; - case R_PosInf_x: R_PosInf = value; break; - case R_NegInf_x: R_NegInf = value; break; - case R_NaReal_x: R_NaReal = value; break; - default: - printf("Call_initvar_double: unimplemented index %d\n", index); - exit(1); - } -} - -void Call_initvar_int(int index, int value) { - switch (index) { - case R_Interactive_x: R_Interactive = value; break; - case R_NaInt_x: R_NaInt = value; break; - default: - printf("Call_initvar_int: unimplemented index %d\n", index); - exit(1); - } -} - -void Call_initvar_string(int index, char* value) { - switch (index) { - case R_Home_x: R_Home = copystring(value); break; - case R_TempDir_x: R_TempDir = copystring(value); break; - default: - printf("Call_initvar_string: unimplemented index %d\n", index); - exit(1); - } -} void Call_initvar_obj(TruffleEnv* env, int index, void* value) { init_utils(env); - switch (index) { - case R_GlobalEnv_x: R_GlobalEnv = value; break; - case R_BaseEnv_x: R_BaseEnv = value; break; - case R_BaseNamespace_x: R_BaseNamespace = value; break; - case R_NamespaceRegistry_x: R_NamespaceRegistry = value; break; - case R_NilValue_x: R_NilValue = value; break; - case R_UnboundValue_x: R_UnboundValue = value; break; - case R_MissingArg_x: R_MissingArg = value; break; - case R_EmptyEnv_x: R_EmptyEnv = value; break; - case R_Srcref_x: R_Srcref = value; break; - case R_Bracket2Symbol_x: R_Bracket2Symbol = value; break; - case R_BracketSymbol_x: R_BracketSymbol = value; break; - case R_BraceSymbol_x: R_BraceSymbol = value; break; - case R_DoubleColonSymbol_x: R_DoubleColonSymbol = value; break; - case R_ClassSymbol_x: R_ClassSymbol = value; break; - case R_DeviceSymbol_x: R_DeviceSymbol = value; break; - case R_DevicesSymbol_x: R_DevicesSymbol = value; break; - case R_DimNamesSymbol_x: R_DimNamesSymbol = value; break; - case R_DimSymbol_x: R_DimSymbol = value; break; - case R_DollarSymbol_x: R_DollarSymbol = value; break; - case R_DotsSymbol_x: R_DotsSymbol = value; break; - case R_DropSymbol_x: R_DropSymbol = value; break; - case R_LastvalueSymbol_x: R_LastvalueSymbol = value; break; - case R_LevelsSymbol_x: R_LevelsSymbol = value; break; - case R_ModeSymbol_x: R_ModeSymbol = value; break; - case R_NameSymbol_x: R_NameSymbol = value; break; - case R_NamesSymbol_x: R_NamesSymbol = value; break; - case R_NaRmSymbol_x: R_NaRmSymbol = value; break; - case R_PackageSymbol_x: R_PackageSymbol = value; break; - case R_QuoteSymbol_x: R_QuoteSymbol = value; break; - case R_RowNamesSymbol_x: R_RowNamesSymbol = value; break; - case R_SeedsSymbol_x: R_SeedsSymbol = value; break; - case R_SourceSymbol_x: R_SourceSymbol = value; break; - case R_TspSymbol_x: R_TspSymbol = value; break; - case R_dot_defined_x: R_dot_defined = value; break; - case R_dot_Method_x: R_dot_Method = value; break; - case R_dot_target_x: R_dot_target = value; break; - case R_dot_packageName_x: R_dot_packageName = value; break; - case R_dot_Generic_x: R_dot_Generic = value; break; - case R_SrcrefSymbol_x: R_SrcrefSymbol = value; break; - case R_SrcfileSymbol_x: R_SrcfileSymbol = value; break; - case R_NaString_x: R_NaString = value; break; - case R_BlankString_x: R_BlankString = value; break; - case R_BlankScalarString_x: R_BlankScalarString = value; break; - case R_BaseSymbol_x: R_BaseSymbol = value; break; - case R_NamespaceEnvSymbol_x: R_NamespaceEnvSymbol = value; break; - case R_RestartToken_x: R_RestartToken = value; break; - case R_SortListSymbol_x: R_SortListSymbol = value; break; - case R_SpecSymbol_x: R_SpecSymbol = value; break; - case R_TripleColonSymbol_x: R_TripleColonSymbol = value; break; - case R_PreviousSymbol_x: R_PreviousSymbol = value; break; - default: - printf("Call_initvar_obj: unimplemented index %d\n", index); - exit(1); - } + Call_initvar_obj_common(index, value); } diff --git a/com.oracle.truffle.r.native/gnur/Makefile.libs b/com.oracle.truffle.r.native/gnur/Makefile.libs index c27c541500..db85bb8d5a 100644 --- a/com.oracle.truffle.r.native/gnur/Makefile.libs +++ b/com.oracle.truffle.r.native/gnur/Makefile.libs @@ -61,8 +61,8 @@ ifeq ($(OS_NAME),Darwin) endif # we can't create exact dependencies since we don't know exactly -# what versions of the lubs (if any) will be copied, so we use a sentinel -# file to indicate that the check has been done. +# what versions of the libs (if any) will be copied, so we use a sentinel +# file to indicate that the check has been done. rcopylib.done: for target in $(OTHER_LIB_TARGETS); do \ mx rcopylib $$target $(FASTR_LIB_DIR) || exit 1; \ @@ -70,7 +70,6 @@ rcopylib.done: touch rcopylib.done clean: - rm -f $(BLAS_TARGET) $(LAPACK_TARGET) + rm -f $(BLAS_TARGET) $(LAPACK_TARGET) rm -f $(foreach target,$(OTHER_LIB_TARGETS),$(wildcard $(FASTR_LIB_DIR)/lib$(target).*)) rm -f rcopylib.done - diff --git a/com.oracle.truffle.r.native/gnur/patch/src/library/base/src/registration.c b/com.oracle.truffle.r.native/gnur/patch/src/library/base/src/registration.c index 4681057ce9..520b8ce467 100644 --- a/com.oracle.truffle.r.native/gnur/patch/src/library/base/src/registration.c +++ b/com.oracle.truffle.r.native/gnur/patch/src/library/base/src/registration.c @@ -83,7 +83,6 @@ static R_FortranMethodDef fortranMethods[] = { void R_init_base(DllInfo *dll) { -// R_registerRoutines(dll, NULL, callMethods, fortranMethods, NULL); R_registerRoutines(dll, NULL, NULL, fortranMethods, NULL); R_useDynamicSymbols(dll, FALSE); } diff --git a/com.oracle.truffle.r.native/gnur/patch/src/library/graphics/src/base.c b/com.oracle.truffle.r.native/gnur/patch/src/library/graphics/src/base.c index 1e6dfcbe7d..dd227c4564 100644 --- a/com.oracle.truffle.r.native/gnur/patch/src/library/graphics/src/base.c +++ b/com.oracle.truffle.r.native/gnur/patch/src/library/graphics/src/base.c @@ -387,12 +387,14 @@ GPar* gpptr(pGEDevDesc dd) { return &(bss->gp); } +/* It's already defined in src/main/devices.c GPar* dpptr(pGEDevDesc dd) { if (baseRegisterIndex == -1) error(_("the base graphics system is not registered")); baseSystemState *bss = dd->gesd[baseRegisterIndex]->systemSpecific; return &(bss->dp); } +*/ /* called in GNewPlot to mark device as 'dirty' */ void Rf_setBaseDevice(Rboolean val, pGEDevDesc dd) { diff --git a/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/grid.h b/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/grid.h index f71c915955..8e9dacc062 100644 --- a/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/grid.h +++ b/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/grid.h @@ -441,8 +441,12 @@ double convertJust(int vjust); void justification(double width, double height, double hjust, double vjust, double *hadj, double *vadj); -/* From util.c */ -SEXP getListElement(SEXP list, char *str); +/* + * From util.c + * + * The original name was getListElement, but it has to be changed to a unique name due to a clash during LLVM compilation. + */ +SEXP gridGetListElement(SEXP list, char *str); void setListElement(SEXP list, char *str, SEXP value); diff --git a/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/unit.c b/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/unit.c index bfd3414457..67caf7dcdb 100644 --- a/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/unit.c +++ b/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/unit.c @@ -91,15 +91,15 @@ SEXP unitData(SEXP unit, int index) { /* Accessor functions for unit arithmetic object */ const char* fName(SEXP ua) { - return CHAR(STRING_ELT(getListElement(ua, "fname"), 0)); + return CHAR(STRING_ELT(gridGetListElement(ua, "fname"), 0)); } SEXP arg1(SEXP ua) { - return getListElement(ua, "arg1"); + return gridGetListElement(ua, "arg1"); } SEXP arg2(SEXP ua) { - return getListElement(ua, "arg2"); + return gridGetListElement(ua, "arg2"); } int fNameMatch(SEXP ua, char *aString) { @@ -310,14 +310,14 @@ int pureNullUnit(SEXP unit, int index, pGEDevDesc dd) { PROTECT(findGrobFn = findFun(install("findGrobinDL"), R_gridEvalEnv)); PROTECT(R_fcall0 = lang2(findGrobFn, - getListElement(grob, "name"))); + gridGetListElement(grob, "name"))); grob = eval(R_fcall0, R_gridEvalEnv); } else { PROTECT(findGrobFn =findFun(install("findGrobinChildren"), R_gridEvalEnv)); PROTECT(R_fcall0 = lang3(findGrobFn, - getListElement(grob, "name"), - getListElement(savedgrob, + gridGetListElement(grob, "name"), + gridGetListElement(savedgrob, "children"))); grob = eval(R_fcall0, R_gridEvalEnv); } @@ -356,14 +356,14 @@ int pureNullUnit(SEXP unit, int index, pGEDevDesc dd) { PROTECT(findGrobFn = findFun(install("findGrobinDL"), R_gridEvalEnv)); PROTECT(R_fcall0 = lang2(findGrobFn, - getListElement(grob, "name"))); + gridGetListElement(grob, "name"))); grob = eval(R_fcall0, R_gridEvalEnv); } else { PROTECT(findGrobFn =findFun(install("findGrobinChildren"), R_gridEvalEnv)); PROTECT(R_fcall0 = lang3(findGrobFn, - getListElement(grob, "name"), - getListElement(savedgrob, + gridGetListElement(grob, "name"), + gridGetListElement(savedgrob, "children"))); grob = eval(R_fcall0, R_gridEvalEnv); } @@ -513,14 +513,14 @@ double evaluateGrobUnit(double value, SEXP grob, PROTECT(findGrobFn = findFun(install("findGrobinDL"), R_gridEvalEnv)); PROTECT(R_fcall0 = lang2(findGrobFn, - getListElement(grob, "name"))); + gridGetListElement(grob, "name"))); PROTECT(grob = eval(R_fcall0, R_gridEvalEnv)); } else { PROTECT(findGrobFn = findFun(install("findGrobinChildren"), R_gridEvalEnv)); PROTECT(R_fcall0 = lang3(findGrobFn, - getListElement(grob, "name"), - getListElement(savedgrob, "children"))); + gridGetListElement(grob, "name"), + gridGetListElement(savedgrob, "children"))); PROTECT(grob = eval(R_fcall0, R_gridEvalEnv)); } /* diff --git a/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/util.c b/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/util.c index 2a7c44832e..1aebdd2cb6 100644 --- a/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/util.c +++ b/com.oracle.truffle.r.native/gnur/patch/src/library/grid/src/util.c @@ -24,7 +24,7 @@ /* Get the list element named str, or return NULL. * Copied from the Writing R Extensions manual (which copied it from nls) */ -SEXP getListElement(SEXP list, char *str) +SEXP gridGetListElement(SEXP list, char *str) { SEXP elmt = R_NilValue; SEXP names = getAttrib(list, R_NamesSymbol); diff --git a/com.oracle.truffle.r.native/gnur/patch/src/library/utils/src/utils_dummy.c b/com.oracle.truffle.r.native/gnur/patch/src/library/utils/src/utils_dummy.c index 34baf763e4..89e126526e 100644 --- a/com.oracle.truffle.r.native/gnur/patch/src/library/utils/src/utils_dummy.c +++ b/com.oracle.truffle.r.native/gnur/patch/src/library/utils/src/utils_dummy.c @@ -55,4 +55,4 @@ SEXP selectlist(SEXP call, SEXP op, SEXP args, SEXP rho) UNIMPLEMENTED SEXP processevents(void) UNIMPLEMENTED -SEXP octsize(SEXP s) UNIMPLEMENTED +//SEXP octsize(SEXP s) UNIMPLEMENTED diff --git a/com.oracle.truffle.r.native/llvm_tools/llvm-ar b/com.oracle.truffle.r.native/llvm_tools/llvm-ar new file mode 100755 index 0000000000..2462ea65ed --- /dev/null +++ b/com.oracle.truffle.r.native/llvm_tools/llvm-ar @@ -0,0 +1,37 @@ +#!/bin/bash +# +# Copyright (c) 2018, 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. +# + +SOURCE="$0" +DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" + +while [[ $# -gt 0 ]] +do + f=`basename $1` + ext=${f##*.} + if [ $ext == 'o' ] + then + echo $1 >> $R_PACKAGE_DIR/libobjects + fi + shift +done diff --git a/com.oracle.truffle.r.native/llvm_tools/llvm-c++ b/com.oracle.truffle.r.native/llvm_tools/llvm-c++ index 6708749372..ee6af85450 100755 --- a/com.oracle.truffle.r.native/llvm_tools/llvm-c++ +++ b/com.oracle.truffle.r.native/llvm_tools/llvm-c++ @@ -1,5 +1,6 @@ +#!/bin/bash # -# Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2018, 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 @@ -20,7 +21,6 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -#!/bin/bash SOURCE="$0" DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" @@ -31,7 +31,8 @@ analyze_args "$@" if [ $is_link -eq 1 ] then - create_bc_lib "$@" + extraObj=`cat $R_PACKAGE_DIR/libobjects` + create_bc_lib $@ $extraObj else llvm_tool=clang++ get_llvm_tool @@ -39,4 +40,3 @@ else mem2reg_opt fake_obj fi - diff --git a/com.oracle.truffle.r.native/llvm_tools/llvm-cc b/com.oracle.truffle.r.native/llvm_tools/llvm-cc index 69ddd766c9..1d88276ba5 100755 --- a/com.oracle.truffle.r.native/llvm_tools/llvm-cc +++ b/com.oracle.truffle.r.native/llvm_tools/llvm-cc @@ -1,5 +1,6 @@ +#!/bin/bash # -# Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2018, 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 @@ -20,7 +21,6 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -#!/bin/bash SOURCE="$0" DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" @@ -32,7 +32,8 @@ analyze_args "$@" if [ $is_link -eq 1 ] then - create_bc_lib "$@" + extraObj=`cat $R_PACKAGE_DIR/libobjects` + create_bc_lib $@ $extraObj else llvm_tool=clang get_llvm_tool @@ -40,5 +41,3 @@ else mem2reg_opt fake_obj fi - - diff --git a/com.oracle.truffle.r.native/llvm_tools/llvm-fc b/com.oracle.truffle.r.native/llvm_tools/llvm-fc index 1cbd628818..084f68d2df 100755 --- a/com.oracle.truffle.r.native/llvm_tools/llvm-fc +++ b/com.oracle.truffle.r.native/llvm_tools/llvm-fc @@ -1,5 +1,6 @@ +#!/bin/bash # -# Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2017, 2018, 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 @@ -20,7 +21,6 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -#!/bin/bash SOURCE="$0" DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" @@ -61,4 +61,3 @@ runit rm $llvm_ir_file llvm_ir_file=$llvm_ir_bc_file mem2reg_opt fake_obj - diff --git a/com.oracle.truffle.r.native/llvm_tools/llvm-helper b/com.oracle.truffle.r.native/llvm_tools/llvm-helper index 57a9292e58..598bb39e40 100644 --- a/com.oracle.truffle.r.native/llvm_tools/llvm-helper +++ b/com.oracle.truffle.r.native/llvm_tools/llvm-helper @@ -156,6 +156,10 @@ function create_bc_lib() { # we do not have the luxury of controlling the name of the entry (unlike in python) # it will be the pathname, which we will reduce to a module name on input in FastR -# TODO: this should link the bitcode files into a single one using llvm-link before zipping it - runit zip -r $lib $bcfiles +# link the bitcode files into a single one using llvm-link before zipping it + llvm_tool=llvm-link + get_llvm_tool + runit $llvm_tool_bin $bcfiles -o $lib.bc + runit zip -r $lib $lib.bc + rm $lib.bc } diff --git a/com.oracle.truffle.r.native/run/edMakeconf.etc.llvm b/com.oracle.truffle.r.native/run/edMakeconf.etc.llvm index b079665f85..d9a5864d77 100644 --- a/com.oracle.truffle.r.native/run/edMakeconf.etc.llvm +++ b/com.oracle.truffle.r.native/run/edMakeconf.etc.llvm @@ -23,5 +23,10 @@ d i OBJC = $(R_HOME)/bin/llvm-cc . +/^AR =/ +d +i +AR = $(R_HOME)/bin/llvm-ar +. w q diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/TestBase.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/TestBase.java index 6b1b8c0569..3ae46c2727 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/TestBase.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/TestBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java index 43e9de314e..e7659abe39 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -85,6 +85,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { private final boolean updatePositionNames; private final boolean isValueGt1; + protected final boolean ignoreRefCount; @Child private WriteIndexedVectorNode writeVectorNode; @Child private PositionsCheckNode positionsCheckNode; @@ -97,7 +98,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { @CompilationFinal protected Runnable error; CachedReplaceVectorNode(ElementAccessMode mode, RAbstractVector vector, Object[] positions, Class<?> valueClass, RType valueType, boolean updatePositionNames, boolean recursive, - boolean isValueGt1) { + boolean isValueGt1, boolean ignoreRefCount) { super(mode, vector, positions, recursive); assert vectorType.isVector(); @@ -111,6 +112,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { this.valueClass = valueClass; this.valueType = valueType; this.isValueGt1 = isValueGt1; + this.ignoreRefCount = ignoreRefCount; // determine the target cast type if (vectorType == RType.List && mode.isSubscript()) { @@ -228,7 +230,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { if (valueLengthOneProfile.profile(valueLength != 1)) { verifyValueLength(positionProfiles, valueLength); } - if (vector instanceof RShareable) { + if (vector instanceof RShareable && !ignoreRefCount) { RShareable shareable = (RShareable) vector; // TODO find out if we need to copy always in the recursive case if (recursive || sharedConditionProfile.execute(shareable.isShared()) || valueEqualsVectorProfile.profile(vector == value)) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java index 093cee2ae2..9368b84e5d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -79,14 +79,16 @@ public abstract class ReplaceVectorNode extends RBaseNode { protected final ElementAccessMode mode; private final boolean recursive; protected final boolean ignoreRecursive; + protected final boolean ignoreRefCount; @Child private BoxPrimitiveNode boxVector = BoxPrimitiveNode.create(); @Child private BoxPrimitiveNode boxValue = BoxPrimitiveNode.create(); - ReplaceVectorNode(ElementAccessMode mode, boolean recursive, boolean ignoreRecursive) { + ReplaceVectorNode(ElementAccessMode mode, boolean recursive, boolean ignoreRecursive, boolean ignoreRefCount) { this.mode = mode; this.recursive = recursive; this.ignoreRecursive = ignoreRecursive; + this.ignoreRefCount = ignoreRefCount; } public final Object apply(Object vector, Object[] positions, Object value) { @@ -96,11 +98,11 @@ public abstract class ReplaceVectorNode extends RBaseNode { protected abstract Object execute(Object vector, Object[] positions, Object value); public static ReplaceVectorNode create(ElementAccessMode mode, boolean ignoreRecursive) { - return ReplaceVectorNodeGen.create(mode, false, ignoreRecursive); + return ReplaceVectorNodeGen.create(mode, false, ignoreRecursive, false); } protected static ReplaceVectorNode createRecursive(ElementAccessMode mode) { - return ReplaceVectorNodeGen.create(mode, true, false); + return ReplaceVectorNodeGen.create(mode, true, false, false); } private boolean isRecursiveSubscript(Object vector, Object[] positions) { @@ -125,7 +127,7 @@ public abstract class ReplaceVectorNode extends RBaseNode { return null; } return new CachedReplaceVectorNode(mode, vector, positions, value.getClass(), RRuntime.isForeignObject(value) ? RType.TruffleObject : ((RTypedValue) value).getRType(), true, - recursive, CachedReplaceVectorNode.isValueLengthGreaterThanOne(value)); + recursive, CachedReplaceVectorNode.isValueLengthGreaterThanOne(value), ignoreRefCount); } @Specialization(limit = "CACHE_LIMIT", guards = {"!isForeignObject(vector)", "cached != null", "cached.isSupported(vector, positions, value)"}) @@ -168,7 +170,7 @@ public abstract class ReplaceVectorNode extends RBaseNode { } protected ReplaceVectorNode createForContainerTypes() { - return ReplaceVectorNodeGen.create(mode, false, false); + return ReplaceVectorNodeGen.create(mode, false, false, false); } @Specialization diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java index e4360fc26b..a59a136417 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FastROptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -60,7 +60,7 @@ public enum FastROptions { EmitTmpSource("Write deparsed source code to temporary files for better debugging.", true), EmitTmpDir("The directory where to allocate temporary files with deparsed source code.", null, true), EmitTmpHashed("Use an SHA-256 hash as file name to reduce temporary file creation.", true), - SpawnUsesPolyglot("use PolyglotEngine for .fastr.context.spwan", false), + SpawnUsesPolyglot("use PolyglotEngine for .fastr.context.spawn", false), SynchronizeNativeCode("allow only one thread to enter packages' native code", false), ForeignObjectWrappers("use wrappers for foreign objects (as opposed to full conversion)", false), diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java index 5a8cf2b880..8dcaee7c02 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java @@ -5,7 +5,7 @@ * * Copyright (c) 1995-2012, The R Core Team * Copyright (c) 2003, The R Foundation - * Copyright (c) 2013, 2017, Oracle and/or its affiliates + * Copyright (c) 2013, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -29,7 +29,10 @@ import java.util.HashSet; import java.util.Iterator; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.source.Source; @@ -793,7 +796,9 @@ public class RDeparse { append(')'); } else if (value instanceof RExternalPtr) { SymbolHandle handle = ((RExternalPtr) value).getAddr(); - if (handle.isLong()) { + if (handle == null) { + append("<pointer: 0x?>"); + } else if (handle.isLong()) { append("<pointer: 0x").append(Long.toHexString(handle.asAddress())).append('>'); } else { append("<pointer: external ptr 0x").append(Long.toHexString(System.identityHashCode(handle.asTruffleObject()))).append('>'); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/CharSXPWrapper.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/CharSXPWrapper.java index bd79d8d202..63927cd2d1 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/CharSXPWrapper.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/CharSXPWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -46,6 +46,10 @@ public final class CharSXPWrapper extends RObject implements RTruffleObject { return NativeDataAccess.getData(this, contents); } + public int getLength() { + return NativeDataAccess.getDataLength(this, contents); + } + @Override public String toString() { return "CHARSXP(" + getContents() + ")"; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java index 3db3d8c55f..0f60201c90 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/NativeDataAccess.java @@ -399,7 +399,7 @@ public final class NativeDataAccess { private static final Assumption noDoubleNative = Truffle.getRuntime().createAssumption(); private static final Assumption noComplexNative = Truffle.getRuntime().createAssumption(); private static final Assumption noRawNative = Truffle.getRuntime().createAssumption(); - private static final Assumption noCahrSXPNative = Truffle.getRuntime().createAssumption(); + private static final Assumption noCharSXPNative = Truffle.getRuntime().createAssumption(); static int getData(RIntVector vector, int[] data, int index) { if (noIntNative.isValid() || data != null) { @@ -554,7 +554,7 @@ public final class NativeDataAccess { } static String getData(CharSXPWrapper vector, String data) { - if (noCahrSXPNative.isValid() || data != null) { + if (noCharSXPNative.isValid() || data != null) { return data; } else { NativeMirror mirror = (NativeMirror) vector.getNativeMirror(); @@ -570,6 +570,21 @@ public final class NativeDataAccess { } } + static int getDataLength(CharSXPWrapper vector, String data) { + if (noCharSXPNative.isValid() || data != null) { + return data.length(); + } else { + NativeMirror mirror = (NativeMirror) vector.getNativeMirror(); + long address = mirror.dataAddress; + assert address != 0; + int length = 0; + while (length < mirror.length && UnsafeAdapter.UNSAFE.getByte(address + length) != 0) { + length++; + } + return length; + } + } + static long allocateNativeContents(RLogicalVector vector, byte[] data, int length) { NativeMirror mirror = (NativeMirror) vector.getNativeMirror(); assert mirror != null; @@ -634,12 +649,23 @@ public final class NativeDataAccess { assert mirror != null; assert mirror.dataAddress == 0 ^ contents == null; if (mirror.dataAddress == 0) { - noCahrSXPNative.invalidate(); + noCharSXPNative.invalidate(); mirror.allocateNative(contents); } return mirror.dataAddress; } + public static String readNativeString(long addr) { + int len; + for (len = 0; UnsafeAdapter.UNSAFE.getByte(addr + len) != 0; len++) { + } + byte[] bytes = new byte[len]; + for (int i = 0; i < len; i++) { + bytes[i] = UnsafeAdapter.UNSAFE.getByte(addr + i); + } + return new String(bytes); + } + public static void setNativeContents(RObject obj, long address, int length) { assert obj.getNativeMirror() != null; if (noDoubleNative.isValid() && obj instanceof RDoubleVector) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java index 42019995a4..04b9b22843 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/Foreign2R.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -34,6 +34,7 @@ import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RRaw; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @ImportStatic({RRuntime.class}) diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/RObjectNativeWrapper.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/RObjectNativeWrapper.java new file mode 100644 index 0000000000..9302f98f67 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/interop/RObjectNativeWrapper.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2018, 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.runtime.interop; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.ForeignAccess.StandardFactory; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.runtime.data.NativeDataAccess; +import com.oracle.truffle.r.runtime.data.RObject; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; + +public class RObjectNativeWrapper implements TruffleObject { + private final RObject obj; + + public RObjectNativeWrapper(RObject obj) { + this.obj = obj; + } + + @Override + public ForeignAccess getForeignAccess() { + return ForeignAccess.create(RObjectNativeWrapper.class, new StandardFactory() { + @Override + public CallTarget accessIsNull() { + return Truffle.getRuntime().createCallTarget(new InteropRootNode() { + @Override + public Object execute(VirtualFrame frame) { + return false; + } + }); + } + + @Override + public CallTarget accessIsPointer() { + return Truffle.getRuntime().createCallTarget(new InteropRootNode() { + @Override + public Object execute(VirtualFrame frame) { + return true; + } + }); + } + + @Override + public CallTarget accessAsPointer() { + return Truffle.getRuntime().createCallTarget(new InteropRootNode() { + @Override + public Object execute(VirtualFrame frame) { + RObjectNativeWrapper receiver = (RObjectNativeWrapper) ForeignAccess.getReceiver(frame); + return NativeDataAccess.asPointer(receiver.obj); + } + }); + } + + @Override + public CallTarget accessToNative() { + return Truffle.getRuntime().createCallTarget(new InteropRootNode() { + @Override + public Object execute(VirtualFrame frame) { + return ForeignAccess.getReceiver(frame); + } + }); + } + }); + } +} + +abstract class InteropRootNode extends RootNode { + InteropRootNode() { + super(null); + } + + @Override + public final SourceSection getSourceSection() { + return RSyntaxNode.INTERNAL; + } +} diff --git a/com.oracle.truffle.r.test.native/Makefile b/com.oracle.truffle.r.test.native/Makefile index 8045621a3c..e19effc9d8 100644 --- a/com.oracle.truffle.r.test.native/Makefile +++ b/com.oracle.truffle.r.test.native/Makefile @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2018, 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 @@ -27,6 +27,8 @@ export TOPDIR = $(CURDIR) # all output goes into the com.oracle.truffle.r.test project for packaging into a single distribution export MX_OUTPUT_DIR = $(abspath $(TOPDIR)/../mxbuild/com.oracle.truffle.r.test/bin/com/oracle/truffle/r/test) export REPO_DIR := $(TOPDIR)/packages/repo/src/contrib +export FASTR_NATIVE_DIR = $(subst test.native,native,$(TOPDIR)) + OSNAME := $(shell uname) all: diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c index a705c1cd9c..04839457c1 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, 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 @@ -284,7 +284,7 @@ SEXP preserve_object(SEXP val) { int *iv = INTEGER(v); if(LENGTH(val) > 0) { int *ival = INTEGER(val); - iv[0] = ival[1]; + iv[0] = ival[0]; } else { iv[0] = 1234; } diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R index 37a36ada65..edd4098bf3 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/simpleTests.R @@ -107,6 +107,7 @@ for(i in seq(5000)) { for(i in seq(5000)) { obj <- preserved_objects[[i]] + stopifnot(obj == i) rffi.release_object(obj) } 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 cd370d6523..3cc0656d66 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 @@ -157499,24 +157499,20 @@ Error: 'R_get_primname' called on a non-primitive [1] TRUE ##com.oracle.truffle.r.test.library.stats.TestExternal_Rmd5.testRmd5# -#.Call(tools:::Rmd5, "abc") -Error in get(name, envir = asNamespace(pkg), inherits = FALSE) : - object 'Rmd5' not found +#.Call(tools:::C_Rmd5, "abc") +[1] NA ##com.oracle.truffle.r.test.library.stats.TestExternal_Rmd5.testRmd5# -#.Call(tools:::Rmd5, 1) -Error in get(name, envir = asNamespace(pkg), inherits = FALSE) : - object 'Rmd5' not found +#.Call(tools:::C_Rmd5, 1) +Error: argument 'files' must be character ##com.oracle.truffle.r.test.library.stats.TestExternal_Rmd5.testRmd5# -#.Call(tools:::Rmd5, NULL) -Error in get(name, envir = asNamespace(pkg), inherits = FALSE) : - object 'Rmd5' not found +#.Call(tools:::C_Rmd5, NULL) +Error: argument 'files' must be character ##com.oracle.truffle.r.test.library.stats.TestExternal_Rmd5.testRmd5# -#.Call(tools:::Rmd5, c("abc","xyz")) -Error in get(name, envir = asNamespace(pkg), inherits = FALSE) : - object 'Rmd5' not found +#.Call(tools:::C_Rmd5, c("abc","xyz")) +[1] NA NA ##com.oracle.truffle.r.test.library.stats.TestExternal_completecases.testCompleteCases# #stats::complete.cases(data.frame(col1=c(1,2,NA), col2=c(1,2,3))) diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java index 0e511773b4..42217d82d1 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java @@ -4,7 +4,7 @@ * http://www.gnu.org/licenses/gpl-2.0.html * * Copyright (c) 2012-2014, Purdue University - * Copyright (c) 2013, 2017, Oracle and/or its affiliates + * Copyright (c) 2013, 2018, Oracle and/or its affiliates * * All rights reserved. */ diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestContextConfig.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestContextConfig.java new file mode 100644 index 0000000000..ead76ae78c --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestContextConfig.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013, 2018, 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.test; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.runner.Description; + +import com.oracle.truffle.r.runtime.context.RContext.ContextKind; + +public class TestContextConfig { + public static final Set<String> BLACKLIST = new HashSet<>(); + + private static final boolean IS_LLVM_ENV = "llvm".equals(System.getenv().get("FASTR_RFFI")); + + static { + BLACKLIST.add("testMisc(com.oracle.truffle.r.test.library.base.TestSimpleAssignment)"); + BLACKLIST.add("testError(com.oracle.truffle.r.test.library.base.TestSimpleErrorHandling)"); + BLACKLIST.add("testLookup(com.oracle.truffle.r.test.library.base.TestEnvironments)"); + BLACKLIST.add("testEnvironment(com.oracle.truffle.r.test.library.base.TestEnvironments)"); + BLACKLIST.add("testScalarUpdate(com.oracle.truffle.r.test.library.base.TestSimpleVectors)"); + BLACKLIST.add("testObject(com.oracle.truffle.r.test.library.base.TestSimpleVectors)"); + BLACKLIST.add("testSimple(com.oracle.truffle.r.test.library.utils.TestInteractiveDebug)"); + BLACKLIST.add("testNestedDebugging(com.oracle.truffle.r.test.library.utils.TestInteractiveDebug)"); + BLACKLIST.add("testSetBreakpoint(com.oracle.truffle.r.test.library.utils.TestInteractiveDebug)"); + BLACKLIST.add("testLoop(com.oracle.truffle.r.test.library.utils.TestInteractiveDebug)"); + BLACKLIST.add("testConditionalBreakpoint(com.oracle.truffle.r.test.library.utils.TestInteractiveDebug)"); + BLACKLIST.add("testConditionalBreakpoint(com.oracle.truffle.r.test.library.utils.TestInteractiveDebug)"); + BLACKLIST.add("testInvalidName(com.oracle.truffle.r.test.library.utils.TestInteractiveDebug)"); + BLACKLIST.add("testmatchfun(com.oracle.truffle.r.test.builtins.TestBuiltin_matchfun)"); + BLACKLIST.add("basicTests(com.oracle.truffle.r.test.builtins.TestBuiltin_attach)"); + BLACKLIST.add("testGenericDispatch(com.oracle.truffle.r.test.builtins.TestBuiltin_rbind)"); + BLACKLIST.add("testWithNonStandardLength(com.oracle.truffle.r.test.builtins.TestBuiltin_seq_along)"); + BLACKLIST.add("testEnvVars(com.oracle.truffle.r.test.builtins.TestBuiltin_Sysgetenv)"); + BLACKLIST.add("testInternalDispatch(com.oracle.truffle.r.test.S4.TestS4)"); + BLACKLIST.add("testActiveBindings(com.oracle.truffle.r.test.S4.TestS4)"); + BLACKLIST.add("testc14(com.oracle.truffle.r.test.builtins.TestBuiltin_c)"); + BLACKLIST.add("testGenericDispatch(com.oracle.truffle.r.test.builtins.TestBuiltin_cbind)"); + BLACKLIST.add("testDoCall(com.oracle.truffle.r.test.builtins.TestBuiltin_docall)"); + BLACKLIST.add("testEval(com.oracle.truffle.r.test.builtins.TestBuiltin_eval)"); + BLACKLIST.add("testLapply(com.oracle.truffle.r.test.builtins.TestBuiltin_lapply)"); + BLACKLIST.add("testMGet(com.oracle.truffle.r.test.builtins.TestBuiltin_mget)"); + BLACKLIST.add("testArgsCast(com.oracle.truffle.r.test.builtins.TestBuiltin_RNGkind)"); + BLACKLIST.add("testwarning(com.oracle.truffle.r.test.builtins.TestBuiltin_warning)"); + BLACKLIST.add("runRSourceTests(com.oracle.truffle.r.test.library.fastr.TestChannels)"); + BLACKLIST.add("testCasts(com.oracle.truffle.r.test.builtins.TestMiscBuiltins)"); + } + + public static ContextKind getTestContextKind() { + return IS_LLVM_ENV ? ContextKind.SHARE_NOTHING : ContextKind.SHARE_PARENT_RW; + } + + public static boolean isTestMethodContext(Description testDesc) { + return IS_LLVM_ENV && !BLACKLIST.contains(testDesc.getDisplayName()); + } +} diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java index 23edd664d4..db917705ad 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java @@ -22,16 +22,22 @@ */ package com.oracle.truffle.r.test.engine.interop; -import com.oracle.truffle.api.interop.ArityException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.Callable; +import org.graalvm.polyglot.Context; import org.junit.AfterClass; import org.junit.Assert; +import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Test; +import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.Message; @@ -39,14 +45,7 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.r.ffi.impl.interop.NativePointer; -import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.test.generate.FastRSession; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import org.graalvm.polyglot.Context; -import org.junit.Test; -import java.util.concurrent.Callable; public abstract class AbstractMRTest { @@ -54,7 +53,7 @@ public abstract class AbstractMRTest { @BeforeClass public static void before() { - context = Context.newBuilder("R").build(); + context = Context.newBuilder("R", "llvm").build(); } @AfterClass @@ -66,6 +65,17 @@ public abstract class AbstractMRTest { FastRSession.execInContext(context, c); } + @Before + public void beforeMethod() { + /** + * Currently, the tests derived from this abstract test class fail when running in the LLVM + * mode due to interferences between the engine created in TestBase.RunListener and the one + * created in this class. To run the tests in the LLVM mode there must be only one engine in + * the VM. + */ + org.junit.Assume.assumeTrue(!"llvm".equals(System.getenv().get("FASTR_RFFI"))); + } + /** * Create TruffleObject-s to be rudimentary tested for IS_NULL, IS_BOXED/UNBOX, IS_EXECUTABLE, * IS_POINTER, HAS_SIZE/GET_SIZE/KEYS behavior. @@ -80,7 +90,7 @@ public abstract class AbstractMRTest { protected abstract TruffleObject createEmptyTruffleObject() throws Exception; /** - * + * * @param obj * @return array of keys or <code>null</code> if KEYS message not supported */ @@ -173,11 +183,7 @@ public abstract class AbstractMRTest { continue; } try { - if (obj == RNull.instance) { - assertTrue(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) == NativePointer.NULL_NATIVEPOINTER); - } else { - assertTrue(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) == obj); - } + assertTrue(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) != obj); } catch (UnsupportedMessageException e) { } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java index 1345f65159..df118c0cc4 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java @@ -26,6 +26,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import org.graalvm.polyglot.Value; import org.junit.Test; import com.oracle.truffle.api.interop.ForeignAccess; @@ -41,7 +42,6 @@ import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.test.generate.FastRSession; -import org.graalvm.polyglot.Value; public class ListMRTest extends AbstractMRTest { @@ -51,7 +51,7 @@ public class ListMRTest extends AbstractMRTest { @Test public void testNativePointer() throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException { for (TruffleObject obj : new TruffleObject[]{create("list", testValues), create("pairlist", testValues)}) { - assertTrue(ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) == obj); + assertTrue(ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) != obj); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java index 22e4e0e902..f67990c8f3 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 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 @@ -25,6 +25,7 @@ package com.oracle.truffle.r.test.engine.interop; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import org.junit.Before; import org.junit.Test; import com.oracle.truffle.api.interop.ForeignAccess; diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java index 7f094f6f47..50fa13dc72 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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 diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConnections.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConnections.java index 39ee482d5f..c82c4aeae7 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConnections.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestConnections.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -93,7 +93,7 @@ public class TestConnections extends TestRBase { assertEval(TestBase.template("{ readChar(file(\"%0\"), 3) }", testDir.subDir("wc1"))); } - @Test(timeout = 1000) + @Test(timeout = 5000) public void testFileWriteReadBin() { assertEval(TestBase.template("{ writeBin(\"abc\", file(\"%0\", open=\"wb\")) }", testDir.subDir("wb1"))); assertEval(TestBase.template("{ readBin(file(\"%0\", \"rb\"), 3) }", testDir.subDir("wb1"))); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSharedCluster.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSharedCluster.java index 6d923bc76d..b89883e6b9 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSharedCluster.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSharedCluster.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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,6 +22,7 @@ */ package com.oracle.truffle.r.test.library.base; +import org.junit.Before; import org.junit.Test; import com.oracle.truffle.r.test.TestBase; @@ -29,6 +30,11 @@ import com.oracle.truffle.r.test.TestBase; // Checkstyle: stop line length check public class TestSharedCluster extends TestBase { + @Before + public void beforeMethod() { + org.junit.Assume.assumeTrue(!"llvm".equals(System.getenv().get("FASTR_RFFI"))); + } + @Test public void testSharedCluster() { assertEval(TestBase.template( diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_Rmd5.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_Rmd5.java index 0a76d4f763..3a4f7ff08e 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_Rmd5.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestExternal_Rmd5.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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,9 +30,9 @@ import com.oracle.truffle.r.test.TestBase; public class TestExternal_Rmd5 extends TestBase { @Test public void testRmd5() { - assertEval(".Call(tools:::Rmd5, \"abc\")"); - assertEval(".Call(tools:::Rmd5, c(\"abc\",\"xyz\"))"); - assertEval(".Call(tools:::Rmd5, 1)"); - assertEval(".Call(tools:::Rmd5, NULL)"); + assertEval(".Call(tools:::C_Rmd5, \"abc\")"); + assertEval(".Call(tools:::C_Rmd5, c(\"abc\",\"xyz\"))"); + assertEval(".Call(tools:::C_Rmd5, 1)"); + assertEval(".Call(tools:::C_Rmd5, NULL)"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestFitting.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestFitting.java index 56da0b1072..28bd1e40ae 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestFitting.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestFitting.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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,6 +22,7 @@ */ package com.oracle.truffle.r.test.library.stats; +import org.junit.Before; import org.junit.Test; import com.oracle.truffle.r.test.TestBase; @@ -38,6 +39,16 @@ public class TestFitting extends TestBase { "c(rep(1,8), rep(2,8))" }; + @Before + public void beforeMethod() { + /** + * This test is ignored when running in the LLVM FFFI mode due to minor differences in the + * numerical output. The issue is possibly related to how the BLAS library is loaded, i.e. + * either as a binary library or a LLVM bitcode. + */ + org.junit.Assume.assumeTrue(!"llvm".equals(System.getenv().get("FASTR_RFFI"))); + } + @Test public void testLm() { StringBuilder printCode = new StringBuilder(); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestInteractiveDebug.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestInteractiveDebug.java index 316a9fc7f7..44dbdb2ee4 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestInteractiveDebug.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestInteractiveDebug.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -53,7 +53,7 @@ public class TestInteractiveDebug extends TestBase { @After public void cleanupDebugListeners() { - try (org.graalvm.polyglot.Context context = org.graalvm.polyglot.Context.newBuilder("R").build()) { + try (org.graalvm.polyglot.Context context = org.graalvm.polyglot.Context.newBuilder("R", "llvm").build()) { // a context has to be around when calling DebugHandling.dispose(); execInContext(context, () -> { DebugHandling.dispose(); diff --git a/documentation/dev/build-process.md b/documentation/dev/build-process.md index 4fc6c5bdf0..e8ab78ad51 100644 --- a/documentation/dev/build-process.md +++ b/documentation/dev/build-process.md @@ -143,7 +143,7 @@ _Other required sources_: ### Building `fficall` -It builds `libR` and optionally (JNI) `libjniboot`. +It builds `libR`. See also: [ffi](ffi.md). diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides index b9c0f04a36..0618d6879e 100644 --- a/mx.fastr/copyrights/overrides +++ b/mx.fastr/copyrights/overrides @@ -949,3 +949,7 @@ com.oracle.truffle.r.native/gnur/patch/src/main/rlocale_data.h,no.copyright com.oracle.truffle.r.native/gnur/patch/src/main/sort.c,no.copyright com.oracle.truffle.r.native/gnur/patch/src/main/xspline.c,no.copyright com.oracle.truffle.r.native/gnur/patch/src/nmath/nmath.h,no.copyright +com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h,no.copyright +com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c,no.copyright +com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/REnvironmentMRTest.java,no.copyright +com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java,no.copyright -- GitLab