diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/tools/RConnGetCCall.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/tools/RConnGetCCall.java new file mode 100644 index 0000000000000000000000000000000000000000..d1843bda4ef40b23f6e3340e25745bacf0a19454 --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/tools/RConnGetCCall.java @@ -0,0 +1,39 @@ +/* + * 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 + * 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.interop.tools; + +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.r.runtime.data.RTruffleObject; + +public class RConnGetCCall implements RTruffleObject { + public static boolean isInstance(TruffleObject value) { + return value instanceof RConnGetCCall; + } + + @Override + public ForeignAccess getForeignAccess() { + return RConnGetCCallMRForeign.ACCESS; + } + +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/tools/RConnGetCCallMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/tools/RConnGetCCallMR.java new file mode 100644 index 0000000000000000000000000000000000000000..77605f4c403f993ae9de6040cabe805c4285e872 --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/tools/RConnGetCCallMR.java @@ -0,0 +1,52 @@ +/* + * 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 + * 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.interop.tools; + +import java.io.IOException; + +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.Resolve; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.conn.RConnection; + +@MessageResolution(receiverType = RConnGetCCall.class) +public class RConnGetCCallMR { + @Resolve(message = "EXECUTE") + public abstract static class RConnGetCCallExecute extends Node { + protected java.lang.Object access(@SuppressWarnings("unused") RConnGetCCall receiver, Object[] arguments) { + try { + return ((RConnection) arguments[0]).getc(); + } catch (IOException ex) { + return -1; + } + } + } + + @Resolve(message = "IS_EXECUTABLE") + public abstract static class RConnGetCCallIsExecutable extends Node { + protected Object access(@SuppressWarnings("unused") RConnGetCCall receiver) { + return true; + } + } + +} 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 f176f495f889174f351dd6c8e117949a838ababc..bb37da5ddb5a1226022cce5129b39349ea01e459 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 @@ -32,6 +32,7 @@ import com.oracle.truffle.r.ffi.impl.common.LibPaths; import com.oracle.truffle.r.ffi.impl.interop.NativeDoubleArray; import com.oracle.truffle.r.ffi.impl.interop.NativeIntegerArray; import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.DLLRFFI; @@ -75,8 +76,7 @@ public class TruffleLLVM_Lapack implements LapackRFFI { } private static RootCallTarget openLLVMLibraries() { - DLLRFFI.DLOpenRootNode rootNode = DLLRFFI.DLOpenRootNode.create(); - return rootNode.getCallTarget(); + return DLLRFFI.DLOpenRootNode.create(RContext.getInstance()); } private static RootCallTarget openNativeLibraries() { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_CAccess.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_CAccess.java index 455749f2a40242522a4a3f6bf2eb8b8c49eff301..abf88e618ab4b4038d2ffe8163b34cba7854ec85 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_CAccess.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_CAccess.java @@ -29,6 +29,7 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.ffi.impl.common.LibPaths; import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLLRFFI; @@ -51,7 +52,7 @@ public class TruffleNFI_CAccess { public TruffleObject getSymbolFunction() { if (handle == null) { - handle = (TruffleNFI_DLL.NFIHandle) DLLRFFI.DLOpenRootNode.create().getCallTarget().call(LibPaths.getBuiltinLibPath("caccess"), true, true); + handle = (TruffleNFI_DLL.NFIHandle) DLLRFFI.DLOpenRootNode.create(RContext.getInstance()).call(LibPaths.getBuiltinLibPath("caccess"), true, true); } if (symbolFunction == null) { DLL.SymbolHandle symbolHandle = (DLL.SymbolHandle) DLLRFFI.DLSymRootNode.create().getCallTarget().call(handle, cName()); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java index b23501a1d05665284eda1bb6c5036f8c122948af..c9c523c07ce5356ce16f41b62efb46204283c54b 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java @@ -50,7 +50,7 @@ import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; public class TruffleNFI_Call implements CallRFFI { private enum INIT_VAR_FUN { - OBJ("(sint32, object) : void"), + OBJ("(env, sint32, object) : void"), DOUBLE("(sint32, double): void"), STRING("(sint32, string): void"), INT("(sint32, sint32) : void"); @@ -122,7 +122,7 @@ public class TruffleNFI_Call implements CallRFFI { try { Callbacks.createCalls(upCallsImpl); for (Callbacks callback : Callbacks.values()) { - String addCallbackSignature = String.format("(sint32, %s): void", callback.nfiSignature); + String addCallbackSignature = String.format("(env, sint32, %s): void", callback.nfiSignature); TruffleObject addCallbackFunction = (TruffleObject) ForeignAccess.sendInvoke(bind, symbolHandle.asTruffleObject(), "bind", addCallbackSignature); ForeignAccess.sendExecute(executeNode, addCallbackFunction, callback.ordinal(), callback.call); } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_PkgInit.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_PkgInit.java index bab18c4333a12d42a732c7379d8247b52f033353..cac38b61b9f97b3ef7d41731f27f212ce182311c 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_PkgInit.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_PkgInit.java @@ -133,7 +133,7 @@ public final class TruffleNFI_PkgInit { try { for (UpCall upCall : UpCall.values()) { Object upCallMethodObject = ForeignAccess.sendRead(readNode, upCallsObject, upCall.name()); - String addCallbackSignature = String.format("(sint32, %s): void", upCall.signature); + String addCallbackSignature = String.format("(env, sint32, %s): void", upCall.signature); TruffleObject addCallbackFunction = (TruffleObject) ForeignAccess.sendInvoke(bind, symbolHandle.asTruffleObject(), "bind", addCallbackSignature); ForeignAccess.sendExecute(executeNode, addCallbackFunction, upCall.ordinal(), upCallMethodObject); } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_RFFIFactory.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_RFFIFactory.java index 3cd9176a1b7776ec495f379862cb761974075f1b..bde10e1f4de16e30ac8c5560515c5b0bab8f899e 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_RFFIFactory.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_RFFIFactory.java @@ -48,9 +48,12 @@ public class TruffleNFI_RFFIFactory extends RFFIFactory implements RFFI { private static class ContextStateImpl implements RContext.ContextState { @Override public ContextState initialize(RContext context) { + String librffiPath = LibPaths.getBuiltinLibPath("R"); if (context.isInitial()) { - String librffiPath = LibPaths.getBuiltinLibPath("R"); DLL.loadLibR(librffiPath); + } else { + // force initialization of NFI + DLLRFFI.DLOpenRootNode.create(context).call(librffiPath, false, false); } return this; } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Tools.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Tools.java index 1d4d9c202ad4f136f2ea9e7d3536e98e6e2a672c..d9fa3345f779223257c442449a99c63ca25c2365 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Tools.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Tools.java @@ -22,20 +22,17 @@ */ package com.oracle.truffle.r.ffi.impl.nfi; -import java.io.IOException; - 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.common.Generic_Tools; -import com.oracle.truffle.r.ffi.impl.common.RFFIUtils; import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.ffi.impl.interop.tools.RConnGetCCall; import com.oracle.truffle.r.runtime.conn.RConnection; import com.oracle.truffle.r.runtime.data.RLogicalVector; import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RTruffleObject; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; @@ -46,24 +43,6 @@ import com.oracle.truffle.r.runtime.ffi.ToolsRFFI; public class TruffleNFI_Tools implements ToolsRFFI { private static class TruffleNFI_ToolsRFFINode extends Generic_Tools.Generic_ToolsRFFINode { - private interface RConnGetC { - int getc(RConnection conn); - } - - private static class RConnGetCImpl implements RConnGetC, RTruffleObject { - @Override - public int getc(RConnection conn) { - RFFIUtils.traceUpCall("getc"); - try { - int r = conn.getc(); - RFFIUtils.traceUpCallReturn("getc", r); - return r; - } catch (IOException ex) { - return -1; - } - } - } - private static boolean initialized; @Child private DLLRFFI.DLSymNode dysymNode = DLLRFFI.DLSymNode.create(); @@ -86,8 +65,8 @@ public class TruffleNFI_Tools implements ToolsRFFI { Node bind = Message.createInvoke(1).createNode(); Node executeNode = Message.createExecute(1).createNode(); try { - TruffleObject function = (TruffleObject) ForeignAccess.sendInvoke(bind, symbolHandle.asTruffleObject(), "bind", "((object): sint32): void"); - ForeignAccess.sendExecute(executeNode, function, new RConnGetCImpl()); + TruffleObject function = (TruffleObject) ForeignAccess.sendInvoke(bind, symbolHandle.asTruffleObject(), "bind", "(env, (object): sint32): void"); + ForeignAccess.sendExecute(executeNode, function, new RConnGetCCall()); } catch (InteropException t) { throw RInternalError.shouldNotReachHere(t); } diff --git a/com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/FFIProcessor.java b/com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/FFIProcessor.java index e413931ca4d468f9fba2698305c89380133e0d49..a4623218d73a45941398777933459fb8fa86935f 100644 --- a/com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/FFIProcessor.java +++ b/com.oracle.truffle.r.ffi.processor/src/com/oracle/truffle/r/ffi/processor/FFIProcessor.java @@ -341,12 +341,16 @@ public final class FFIProcessor extends AbstractProcessor { return "uint8"; case "int": return "sint32"; + case "long": + return "sint64"; case "double": return "double"; case "void": return "void"; case "int[]": return "[sint32]"; + case "long[]": + return "[sint64]"; case "double[]": return "[double]"; case "byte[]": 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 a064a07ce8f21f2e372eedfc7aa32c4baa0946f5..48d0c6dc45acf72d59a8346ce01fcc188e5dd07b 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 @@ -270,7 +270,7 @@ typedef SEXP (*call_R_BaseNamespace)(); typedef SEXP (*call_R_MethodsNamespace)(); typedef SEXP (*call_R_GlobalEnv)(); typedef SEXP (*call_R_NamespaceRegistry)(); -typedef SEXP (*call_R_Interactive)(); +typedef int (*call_R_Interactive)(); typedef SEXP (*call_R_GlobalContext)(); typedef SEXP (*call_R_CHAR)(SEXP x); typedef char *(*call_R_HomeDir)(); diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rdynload_fastr.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rdynload_fastr.c index 4a0ffaaae603d76c60e22df03ca9641d731431a9..1969c0253b620eda6c3f70831768ac87cd019436 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rdynload_fastr.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rdynload_fastr.c @@ -23,8 +23,8 @@ static int (*call_forceSymbols)(DllInfo *dllInfo, Rboolean value); #define setDotSymbolValues_x 2 #define forceSymbols_x 3 -void Rdynload_init(int index, void* closure) { - newClosureRef(closure); +void Rdynload_init(TruffleEnv* env, int index, void* closure) { + (*env)->newClosureRef(env, closure); switch (index) { case registerRoutines_x: call_registerRoutines = closure; break; case useDynamicSymbols_x: call_useDynamicSymbols = closure; break; 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 3b3f98f0e92d49c839336c08bcb25a2c7c6941a2..6b5569d2973f0d2bf0b3b963739adfe56a445955 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 @@ -27,11 +27,16 @@ void **callbacks = NULL; -void Rinternals_addCallback(int index, void *closure) { +static TruffleContext* truffleContext = NULL; + +void Rinternals_addCallback(TruffleEnv* env, int index, void *closure) { + if (truffleContext == NULL) { + truffleContext = (*env)->getTruffleContext(env); + } if (callbacks == NULL) { callbacks = malloc(UPCALLS_TABLE_SIZE * sizeof(void*)); } - newClosureRef(closure); + (*env)->newClosureRef(env, closure); callbacks[index] = closure; } @@ -104,7 +109,7 @@ CTXT FASTR_GlobalContext() { } Rboolean FASTR_R_Interactive() { - return (int) ((call_R_Interactive) callbacks[R_Interactive_x])(); + return ((call_R_Interactive) callbacks[R_Interactive_x])(); } SEXP CAR(SEXP e) { @@ -368,7 +373,7 @@ SEXP Rf_shallow_duplicate(SEXP x) { } R_xlen_t Rf_any_duplicated(SEXP x, Rboolean from_last) { - return (R_xlen_t) ((call_Rf_any_duplicated) callbacks[Rf_any_duplicated_x])(x, from_last); + return ((call_Rf_any_duplicated) callbacks[Rf_any_duplicated_x])(x, from_last); } SEXP Rf_duplicated(SEXP x, Rboolean y) { @@ -389,11 +394,12 @@ void Rf_copyVector(SEXP x, SEXP y) { } int Rf_countContexts(int x, int y) { - return (int) unimplemented("Rf_countContexts"); + unimplemented("Rf_countContexts"); + return 0; } Rboolean Rf_inherits(SEXP x, const char * klass) { - return (Rboolean) ((call_Rf_inherits) callbacks[Rf_inherits_x])(x, klass); + return ((call_Rf_inherits) callbacks[Rf_inherits_x])(x, klass); } Rboolean Rf_isObject(SEXP s) { @@ -414,16 +420,16 @@ SEXP Rf_installChar(SEXP charsxp) { } Rboolean Rf_isNull(SEXP s) { - return (Rboolean) ((call_Rf_isNull) callbacks[Rf_isNull_x])(s); + return ((call_Rf_isNull) callbacks[Rf_isNull_x])(s); } Rboolean Rf_isString(SEXP s) { - return (Rboolean) ((call_Rf_isString) callbacks[Rf_isString_x])(s); + return ((call_Rf_isString) callbacks[Rf_isString_x])(s); } Rboolean R_cycle_detected(SEXP s, SEXP child) { unimplemented("R_cycle_detected"); - return 0; + return FALSE; } cetype_t Rf_getCharCE(SEXP x) { @@ -438,11 +444,11 @@ const char *Rf_reEnc(const char *x, cetype_t ce_in, cetype_t ce_out, int subst) } int Rf_ncols(SEXP x) { - return (int) ((call_Rf_ncols) callbacks[Rf_ncols_x])(x); + return ((call_Rf_ncols) callbacks[Rf_ncols_x])(x); } int Rf_nrows(SEXP x) { - return (int) ((call_Rf_nrows) callbacks[Rf_nrows_x])(x); + return ((call_Rf_nrows) callbacks[Rf_nrows_x])(x); } @@ -856,11 +862,12 @@ double Rf_asReal(SEXP x) { Rcomplex Rf_asComplex(SEXP x){ unimplemented("Rf_asComplex"); - Rcomplex c; return c; + Rcomplex c; + return c; } int TYPEOF(SEXP x) { - return (int) ((call_TYPEOF) callbacks[TYPEOF_x])(x); + return ((call_TYPEOF) callbacks[TYPEOF_x])(x); } SEXP ATTRIB(SEXP x){ @@ -869,7 +876,7 @@ SEXP ATTRIB(SEXP x){ } int OBJECT(SEXP x){ - return (int) ((call_OBJECT) callbacks[OBJECT_x])(x); + return ((call_OBJECT) callbacks[OBJECT_x])(x); } int MARK(SEXP x){ @@ -878,7 +885,7 @@ int MARK(SEXP x){ } int NAMED(SEXP x){ - return (int) ((call_NAMED) callbacks[NAMED_x])(x); + return ((call_NAMED) callbacks[NAMED_x])(x); } int REFCNT(SEXP x){ @@ -919,11 +926,12 @@ void R_qsort_int_I(int *iv, int *II, int i, int j) { } R_len_t R_BadLongVector(SEXP x, const char *y, int z) { - return (R_len_t) unimplemented("R_BadLongVector"); + unimplemented("R_BadLongVector"); + return 0; } int IS_S4_OBJECT(SEXP x) { - return (int) ((call_IS_S4_OBJECT) callbacks[IS_S4_OBJECT_x])(x); + return ((call_IS_S4_OBJECT) callbacks[IS_S4_OBJECT_x])(x); } void SET_S4_OBJECT(SEXP x) { @@ -935,7 +943,8 @@ void UNSET_S4_OBJECT(SEXP x) { } Rboolean R_ToplevelExec(void (*fun)(void *), void *data) { - return (Rboolean) unimplemented("R_ToplevelExec"); + unimplemented("R_ToplevelExec"); + return FALSE; } SEXP R_ExecWithCleanup(SEXP (*fun)(void *), void *data, @@ -961,7 +970,8 @@ SEXP R_FindPackageEnv(SEXP info) { } Rboolean R_IsNamespaceEnv(SEXP rho) { - return (Rboolean) unimplemented("R_IsNamespaceEnv"); + unimplemented("R_IsNamespaceEnv"); + return FALSE; } SEXP R_FindNamespace(SEXP info) { @@ -993,16 +1003,17 @@ void R_MakeActiveBinding(SEXP sym, SEXP fun, SEXP env) { } Rboolean R_BindingIsLocked(SEXP sym, SEXP env) { - return (Rboolean) ((call_R_BindingIsLocked) callbacks[R_BindingIsLocked_x])(sym, env); + return ((call_R_BindingIsLocked) callbacks[R_BindingIsLocked_x])(sym, env); } Rboolean R_BindingIsActive(SEXP sym, SEXP env) { // TODO: for now, I believe all bindings are false - return (Rboolean)0; + return FALSE; } Rboolean R_HasFancyBindings(SEXP rho) { - return (Rboolean) unimplemented("R_HasFancyBindings"); + unimplemented("R_HasFancyBindings"); + return FALSE; } Rboolean Rf_isS4(SEXP x) { @@ -1011,10 +1022,12 @@ Rboolean Rf_isS4(SEXP x) { SEXP Rf_asS4(SEXP x, Rboolean b, int i) { unimplemented("Rf_asS4"); + return NULL; } static SEXP R_tryEvalInternal(SEXP x, SEXP y, int *ErrorOccurred, int silent) { unimplemented("R_tryEvalInternal"); + return NULL; } SEXP R_tryEval(SEXP x, SEXP y, int *ErrorOccurred) { @@ -1088,7 +1101,6 @@ void R_RegisterCFinalizer(SEXP s, R_CFinalizer_t fun) { void R_RegisterFinalizerEx(SEXP s, SEXP fun, Rboolean onexit) { // TODO implement, but not fail for now - } void R_RegisterCFinalizerEx(SEXP s, R_CFinalizer_t fun, Rboolean onexit) { @@ -1101,18 +1113,22 @@ void R_RunPendingFinalizers(void) { SEXP R_MakeWeakRef(SEXP key, SEXP val, SEXP fin, Rboolean onexit) { unimplemented("R_MakeWeakRef"); + return NULL; } SEXP R_MakeWeakRefC(SEXP key, SEXP val, R_CFinalizer_t fin, Rboolean onexit) { unimplemented("R_MakeWeakRefC"); + return NULL; } SEXP R_WeakRefKey(SEXP w) { unimplemented("R_WeakRefKey"); + return NULL; } SEXP R_WeakRefValue(SEXP w) { unimplemented("R_WeakRefValue"); + return NULL; } void R_RunWeakRefFinalizer(SEXP w) { @@ -1128,7 +1144,8 @@ SEXP R_do_slot_assign(SEXP obj, SEXP name, SEXP value) { } int R_has_slot(SEXP obj, SEXP name) { - return (int) unimplemented("R_has_slot"); + unimplemented("R_has_slot"); + return 0; } SEXP R_do_MAKE_CLASS(const char *what) { @@ -1152,11 +1169,13 @@ int R_check_class_etc (SEXP x, const char **valid) { } SEXP R_PreserveObject(SEXP x) { - return newObjectRef(x); + TruffleEnv* env = (*truffleContext)->getTruffleEnv(truffleContext); + return (*env)->newObjectRef(env, x); } void R_ReleaseObject(SEXP x) { - releaseObjectRef(x); + TruffleEnv* env = (*truffleContext)->getTruffleEnv(truffleContext); + (*env)->releaseObjectRef(env, x); } void R_dot_Last(void) { @@ -1165,7 +1184,7 @@ void R_dot_Last(void) { Rboolean R_compute_identical(SEXP x, SEXP y, int flags) { - return (Rboolean) ((call_R_compute_identical) callbacks[R_compute_identical_x])(x, y, flags); + return ((call_R_compute_identical) callbacks[R_compute_identical_x])(x, y, flags); } void Rf_copyListMatrix(SEXP s, SEXP t, Rboolean byrow) { diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c index fd2a3c2d49c781dc7c559269498e46bc465c222e..7e45c3b7b5164611720dde1f6cbda7cd34bc7c4e 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/rffiutils.c @@ -34,24 +34,28 @@ typedef struct globalRefTable_struct { } GlobalRefElem; #define CACHED_GLOBALREFS_INITIAL_SIZE 64 + static GlobalRefElem *cachedGlobalRefs = NULL; static int cachedGlobalRefsHwm; static int cachedGlobalRefsLength; +static TruffleContext* truffleContext; -void init_utils() { +void init_utils(TruffleEnv* env) { if (cachedGlobalRefs == NULL) { + truffleContext = (*env)->getTruffleContext(env); cachedGlobalRefs = calloc(CACHED_GLOBALREFS_INITIAL_SIZE, sizeof(GlobalRefElem)); cachedGlobalRefsLength = CACHED_GLOBALREFS_INITIAL_SIZE; cachedGlobalRefsHwm = 0; } } static SEXP findCachedGlobalRef(SEXP obj) { + TruffleEnv* env = (*truffleContext)->getTruffleEnv(truffleContext); for (int i = 0; i < cachedGlobalRefsHwm; i++) { GlobalRefElem elem = cachedGlobalRefs[i]; if (elem.gref == NULL) { continue; } - if (isSameObject(elem.gref, obj)) { + if ((*env)->isSameObject(env, elem.gref, obj)) { return elem.gref; } } @@ -71,7 +75,8 @@ SEXP addGlobalRef(SEXP obj, int permanent) { cachedGlobalRefs = newCachedGlobalRefs; cachedGlobalRefsLength = newLength; } - gref = newObjectRef(obj); + TruffleEnv* env = (*truffleContext)->getTruffleEnv(truffleContext); + gref = (*env)->newObjectRef(env, obj); cachedGlobalRefs[cachedGlobalRefsHwm].gref = gref; cachedGlobalRefs[cachedGlobalRefsHwm].permanent = permanent; cachedGlobalRefsHwm++; @@ -96,13 +101,14 @@ SEXP createGlobalRef(SEXP obj, int permanent) { } void releaseGlobalRef(SEXP obj) { + TruffleEnv* env = (*truffleContext)->getTruffleEnv(truffleContext); for (int i = 0; i < cachedGlobalRefsHwm; i++) { GlobalRefElem elem = cachedGlobalRefs[i]; if (elem.gref == NULL || elem.permanent) { continue; } - if (isSameObject(elem.gref, obj)) { - releaseObjectRef(elem.gref); + if ((*env)->isSameObject(env, elem.gref, obj)) { + (*env)->releaseObjectRef(env, elem.gref); cachedGlobalRefs[i].gref = NULL; } } 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 72765550b53b2e4e08f39d1a3465ac32ce16c608..1997890c2b17c6cb45a7a324e35d37be5cd764f9 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 @@ -30,7 +30,7 @@ #include <trufflenfi.h> extern void init_memory(); -extern void init_utils(); +extern void init_utils(TruffleEnv* env); // use for an unimplemented API function void *unimplemented(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 00fd6647fd50160d255aff8d55a4d1cd589e3997..0b4db6c0ac10227c85ef5fdcba64a2afde9dea9d 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 @@ -300,8 +300,8 @@ void Call_initvar_string(int index, char *value) { } } -void Call_initvar_obj(int index, void* value) { - init_utils(); +void Call_initvar_obj(TruffleEnv* env, int index, void* value) { + init_utils(env); switch (index) { case R_NilValue_x: R_NilValue_static = createGlobalRef(value, 1); break; case R_UnboundValue_x: R_UnboundValue_static = createGlobalRef(value, 1); break; diff --git a/com.oracle.truffle.r.native/library/tools/Makefile b/com.oracle.truffle.r.native/library/tools/Makefile index bd62cb85150fc07d1b2c525e58b6811481f03501..9c415e7f92e967f064f4844ba8170c6043556189 100644 --- a/com.oracle.truffle.r.native/library/tools/Makefile +++ b/com.oracle.truffle.r.native/library/tools/Makefile @@ -65,7 +65,7 @@ $(OBJ)/%.o: $(GNUR_SRC)/%.c $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ $(OBJ)/gramRd_nfi.o: $(SRC)/truffle_nfi/gramRd_nfi.c - $(CC) $(CFLAGS) $(FFI_INCLUDES) -c $< -o $@ + $(CC) $(CFLAGS) $(FFI_INCLUDES) $(NFI_INCLUDES) -c $< -o $@ $(OBJ)/gramRd_llvm.o: $(SRC)/truffle_llvm/gramRd_llvm.c $(CC) $(CFLAGS) $(FFI_INCLUDES) $(SULONG_INCLUDES) -c $< -o $@ diff --git a/com.oracle.truffle.r.native/library/tools/src/truffle_nfi/gramRd_nfi.c b/com.oracle.truffle.r.native/library/tools/src/truffle_nfi/gramRd_nfi.c index c5716bb4c39a020499f69b2c1d97ecc4edb3d2a1..db70c16af36dc2bf5c8f571fa2d5e8c9a4c1bcbb 100644 --- a/com.oracle.truffle.r.native/library/tools/src/truffle_nfi/gramRd_nfi.c +++ b/com.oracle.truffle.r.native/library/tools/src/truffle_nfi/gramRd_nfi.c @@ -21,10 +21,12 @@ * questions. */ #include "../gramRd_fastr.h" +#include <trufflenfi.h> static int (*call_RConnGetC)(void *conn); -void gramRd_nfi_init(void *closure) { +void gramRd_nfi_init(TruffleEnv* env, void *closure) { + (*env)->newClosureRef(env, closure); call_RConnGetC = closure; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java index 5edca517e3f581854ba40b093adbf42254b22eee..a921bd0a56251c74bad87338690aadc9d1880957 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java @@ -42,13 +42,17 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.EnumSet; import java.util.HashMap; +import java.util.Map; import java.util.TimeZone; import java.util.WeakHashMap; import java.util.concurrent.Executor; +import java.util.function.Supplier; import com.oracle.truffle.api.Assumption; +import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleLanguage.Env; @@ -237,6 +241,16 @@ public final class RContext implements RTruffleObject { private final String[] environment; private final RContext.ContextKind contextKind; private final TimeZone systemTimeZone; + public final Map<Class<?>, RootCallTarget> nativeCallTargets = new HashMap<>(); + + public RootCallTarget getOrCreateNativeCallTarget(Class<?> clazz, Supplier<RootCallTarget> creatFunction) { + RootCallTarget result = nativeCallTargets.get(clazz); + if (result == null) { + result = creatFunction.get(); + nativeCallTargets.put(clazz, result); + } + return result; + } /** * Any context created by another has a parent. When such a context is destroyed we must reset diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java index e9c3c18299f0a77df1b9e728ac9e2543c33e14a5..37031964a37ad06ce86e6ccf85ec0b34b7bb898f 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java @@ -406,7 +406,7 @@ public class DLL { */ public static void loadLibR(String path) { RContext context = RContext.getInstance(); - Object handle = DLLRFFI.DLOpenRootNode.create().getCallTarget().call(path, false, false); + Object handle = DLLRFFI.DLOpenRootNode.create(context).call(path, false, false); if (handle == null) { throw Utils.rSuicide("error loading libR from: " + path + "\n"); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLLRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLLRFFI.java index fecf157ec83894882d71052ca23f81d31f587cf8..81eeb2d2aa308a8d0443e2addc20d78dce0f1934 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLLRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLLRFFI.java @@ -22,8 +22,11 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; public interface DLLRFFI { @@ -74,8 +77,6 @@ public interface DLLRFFI { // RootNodes final class DLOpenRootNode extends RFFIRootNode<DLOpenNode> { - private static DLOpenRootNode dlOpenRootNode; - private DLOpenRootNode() { super(RFFIFactory.getRFFI().getDLLRFFI().createDLOpenNode()); } @@ -86,11 +87,8 @@ public interface DLLRFFI { return rffiNode.execute((String) args[0], (boolean) args[1], (boolean) args[2]); } - public static DLOpenRootNode create() { - if (dlOpenRootNode == null) { - dlOpenRootNode = new DLOpenRootNode(); - } - return dlOpenRootNode; + public static RootCallTarget create(RContext context) { + return context.getOrCreateNativeCallTarget(DLOpenRootNode.class, () -> new DLOpenRootNode().getCallTarget()); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/shell/TestJLineConsoleCompleter.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/shell/TestJLineConsoleCompleter.java index 62c394af99bc92277b408f3d7c395590b61cf656..eaabb32efebf6e106e3d3b75a0b94911d2edf486 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/shell/TestJLineConsoleCompleter.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/shell/TestJLineConsoleCompleter.java @@ -32,6 +32,7 @@ import org.graalvm.polyglot.Context; import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import com.oracle.truffle.r.launcher.JLineConsoleCompleter; @@ -55,6 +56,8 @@ public class TestJLineConsoleCompleter { } } + // disabled because it uses Engine, which clashes with other tests that use PolyglotEngine + @Ignore @Test public void testCompl() { assertCompl("", 0); diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py index d0cbb8486c0ec3b5d3eebcf9d0417cf6a96366f1..2cdaca86d260da7b39d40e97e669cd90d61c58ec 100644 --- a/mx.fastr/suite.py +++ b/mx.fastr/suite.py @@ -29,7 +29,7 @@ suite = { { "name" : "truffle", "subdir" : True, - "version" : "90f29df947c052acb20be84e4278c8e522d0fa63", + "version" : "b7848be486a979673f6f695b9b0ca78b2e0d9164", "urls" : [ {"url" : "https://github.com/graalvm/graal", "kind" : "git"}, {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},