diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/EmbeddedConsoleHandler.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/EmbeddedConsoleHandler.java index d0249e7a18639dd18ef3faa1a91d1b44073a93b1..e551bd71487c301541e4e1a2c9a3e800f11d7453 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/EmbeddedConsoleHandler.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/EmbeddedConsoleHandler.java @@ -39,8 +39,11 @@ import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.r.launcher.ConsoleHandler; import com.oracle.truffle.r.launcher.DelegatingConsoleHandler; import com.oracle.truffle.r.runtime.RInterfaceCallbacks; +import com.oracle.truffle.r.runtime.ffi.REmbedRFFI; import com.oracle.truffle.r.runtime.ffi.REmbedRFFI.ReadConsoleNode; import com.oracle.truffle.r.runtime.ffi.REmbedRFFI.WriteConsoleBaseNode; +import com.oracle.truffle.r.runtime.ffi.REmbedRFFI.WriteConsoleNode; +import com.oracle.truffle.r.runtime.ffi.REmbedRFFI.WriteErrConsoleNode; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; /** @@ -195,7 +198,7 @@ public final class EmbeddedConsoleHandler extends DelegatingConsoleHandler { private CallTarget getReadLineCallTarget() { if (readLineCallTarget == null) { readLineCallTarget = Truffle.getRuntime().createCallTarget(new RootNode(null) { - @Child private ReadConsoleNode readConsoleNode = RFFIFactory.getREmbedRFFI().createReadConsoleNode(); + @Child private ReadConsoleNode readConsoleNode = ReadConsoleNode.create(); @Override public Object execute(VirtualFrame frame) { @@ -208,14 +211,14 @@ public final class EmbeddedConsoleHandler extends DelegatingConsoleHandler { private CallTarget getWriteCallTarget() { if (writeCallTarget == null) { - writeCallTarget = createWriteCallTarget(RFFIFactory.getREmbedRFFI().createWriteConsoleNode()); + writeCallTarget = createWriteCallTarget(WriteConsoleNode.create()); } return writeCallTarget; } private CallTarget getWriteErrCallTarget() { if (writeErrCallTarget == null) { - writeErrCallTarget = createWriteCallTarget(RFFIFactory.getREmbedRFFI().createWriteErrConsoleNode()); + writeErrCallTarget = createWriteCallTarget(WriteErrConsoleNode.create()); } return writeErrCallTarget; } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java index 34d2a00ddf87b52bb24badd850aa5de3d5976906..65330af2da6f961259a4a971e22658e46c856f6c 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Context.java @@ -32,6 +32,7 @@ import com.oracle.truffle.r.runtime.ffi.LapackRFFI; import com.oracle.truffle.r.runtime.ffi.MiscRFFI; import com.oracle.truffle.r.runtime.ffi.NativeFunction; import com.oracle.truffle.r.runtime.ffi.PCRERFFI; +import com.oracle.truffle.r.runtime.ffi.REmbedRFFI; import com.oracle.truffle.r.runtime.ffi.RFFIContext; import com.oracle.truffle.r.runtime.ffi.StatsRFFI; import com.oracle.truffle.r.runtime.ffi.ToolsRFFI; @@ -50,7 +51,7 @@ final class TruffleLLVM_Context extends RFFIContext { super(new TruffleLLVM_C(), new BaseRFFI(TruffleLLVM_DownCallNodeFactory.INSTANCE), new TruffleLLVM_Call(), new TruffleLLVM_DLL(), new TruffleLLVM_UserRng(), new ZipRFFI(TruffleLLVM_DownCallNodeFactory.INSTANCE), new PCRERFFI(TruffleLLVM_DownCallNodeFactory.INSTANCE), new LapackRFFI(TruffleLLVM_DownCallNodeFactory.INSTANCE), new StatsRFFI(TruffleLLVM_DownCallNodeFactory.INSTANCE), - new ToolsRFFI(), new TruffleLLVM_REmbed(), new MiscRFFI(TruffleLLVM_DownCallNodeFactory.INSTANCE)); + new ToolsRFFI(), new REmbedRFFI(TruffleLLVM_DownCallNodeFactory.INSTANCE), new MiscRFFI(TruffleLLVM_DownCallNodeFactory.INSTANCE)); } static TruffleLLVM_Context getContextState() { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_REmbed.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_REmbed.java deleted file mode 100644 index 7fa4235085bc75b739e7300b48932b08d3adb697..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_REmbed.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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. - */ -package com.oracle.truffle.r.ffi.impl.llvm; - -import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.ffi.REmbedRFFI; - -public class TruffleLLVM_REmbed implements REmbedRFFI { - @Override - public ReadConsoleNode createReadConsoleNode() { - throw RInternalError.unimplemented("TODO"); - } - - @Override - public WriteConsoleNode createWriteConsoleNode() { - throw RInternalError.unimplemented("TODO"); - } - - @Override - public WriteErrConsoleNode createWriteErrConsoleNode() { - throw RInternalError.unimplemented("TODO"); - } -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_REmbedRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_REmbedRFFI.java deleted file mode 100644 index 7a99eaba80463fa098dee79c767c50859c3268be..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_REmbedRFFI.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 - * 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.managed; - -import static com.oracle.truffle.r.ffi.impl.managed.Managed_RFFIFactory.unsupported; - -import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.ffi.REmbedRFFI; - -public class Managed_REmbedRFFI implements REmbedRFFI { - @Override - public ReadConsoleNode createReadConsoleNode() { - throw unsupported("REmbed"); - } - - @Override - public WriteConsoleNode createWriteConsoleNode() { - throw unsupported("REmbed"); - } - - @Override - public WriteErrConsoleNode createWriteErrConsoleNode() { - throw unsupported("REmbed"); - } -} 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 728b244fa3b67f40b4a1b7cccbf702a0bc0dea6e..3d32fdf2838e08d6b5e1c1c9bf0587a980b3d2c0 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 @@ -37,6 +37,7 @@ import com.oracle.truffle.r.runtime.ffi.LapackRFFI; import com.oracle.truffle.r.runtime.ffi.MiscRFFI; import com.oracle.truffle.r.runtime.ffi.NativeFunction; import com.oracle.truffle.r.runtime.ffi.PCRERFFI; +import com.oracle.truffle.r.runtime.ffi.REmbedRFFI; import com.oracle.truffle.r.runtime.ffi.RFFIContext; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.ffi.StatsRFFI; @@ -108,7 +109,8 @@ public final class Managed_RFFIFactory extends RFFIFactory { throw unsupported("user defined RNG"); } }, new ZipRFFI(Managed_DownCallNodeFactory.INSTANCE), new PCRERFFI(Managed_DownCallNodeFactory.INSTANCE), new LapackRFFI(Managed_DownCallNodeFactory.INSTANCE), - new StatsRFFI(Managed_DownCallNodeFactory.INSTANCE), new ToolsRFFI(), new Managed_REmbedRFFI(), new MiscRFFI(Managed_DownCallNodeFactory.INSTANCE)); + new StatsRFFI(Managed_DownCallNodeFactory.INSTANCE), new ToolsRFFI(), new REmbedRFFI(Managed_DownCallNodeFactory.INSTANCE), + new MiscRFFI(Managed_DownCallNodeFactory.INSTANCE)); } private static class IgnoreUpCallExceptionNode extends Node implements HandleUpCallExceptionNode { 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 98bea5a094ff0a446211952b5e7dd6295edb56ba..9489dea36533d1a22dcdc453ec77aa1c149709dc 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 @@ -185,13 +185,6 @@ public class TruffleNFI_Call implements CallRFFI { if (traceEnabled()) { traceDownCallReturn(name, result); } - TruffleNFI_Context nfiCtx = (TruffleNFI_Context) RContext.getInstance().getStateRFFI(); - RuntimeException lastUpCallEx = nfiCtx.getLastUpCallException(); - if (lastUpCallEx != null) { - CompilerDirectives.transferToInterpreter(); - nfiCtx.setLastUpCallException(null); - throw lastUpCallEx; - } } @Override diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Context.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Context.java index 31635cc690c340ab23191edd67aee486b20b13c7..7b4c1ecec2669cd03be24e4aa23852b22db14b1b 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Context.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Context.java @@ -59,6 +59,7 @@ import com.oracle.truffle.r.runtime.ffi.LapackRFFI; import com.oracle.truffle.r.runtime.ffi.MiscRFFI; import com.oracle.truffle.r.runtime.ffi.NativeFunction; import com.oracle.truffle.r.runtime.ffi.PCRERFFI; +import com.oracle.truffle.r.runtime.ffi.REmbedRFFI; import com.oracle.truffle.r.runtime.ffi.RFFIContext; import com.oracle.truffle.r.runtime.ffi.RFFIVariables; import com.oracle.truffle.r.runtime.ffi.StatsRFFI; @@ -93,7 +94,8 @@ final class TruffleNFI_Context extends RFFIContext { TruffleNFI_Context() { super(new TruffleNFI_C(), new BaseRFFI(TruffleNFI_DownCallNodeFactory.INSTANCE), new TruffleNFI_Call(), new TruffleNFI_DLL(), new TruffleNFI_UserRng(), new ZipRFFI(TruffleNFI_DownCallNodeFactory.INSTANCE), new PCRERFFI(TruffleNFI_DownCallNodeFactory.INSTANCE), new LapackRFFI(TruffleNFI_DownCallNodeFactory.INSTANCE), - new StatsRFFI(TruffleNFI_DownCallNodeFactory.INSTANCE), new ToolsRFFI(), new TruffleNFI_REmbed(), new MiscRFFI(TruffleNFI_DownCallNodeFactory.INSTANCE)); + new StatsRFFI(TruffleNFI_DownCallNodeFactory.INSTANCE), new ToolsRFFI(), new REmbedRFFI(TruffleNFI_DownCallNodeFactory.INSTANCE), + new MiscRFFI(TruffleNFI_DownCallNodeFactory.INSTANCE)); // forward constructor } @@ -345,6 +347,7 @@ final class TruffleNFI_Context extends RFFIContext { @Override public long beforeDowncall() { + assert transientAllocations.size() == 0 : "transientAllocations should have been cleared in afterDowncall"; super.beforeDowncall(); if (hasAccessLock) { acquireLock(); @@ -354,6 +357,7 @@ final class TruffleNFI_Context extends RFFIContext { @Override public void afterDowncall(long beforeValue) { + super.afterDowncall(beforeValue); popCallbacks(beforeValue); for (Long ptr : transientAllocations) { UnsafeAdapter.UNSAFE.freeMemory(ptr); @@ -362,7 +366,12 @@ final class TruffleNFI_Context extends RFFIContext { if (hasAccessLock) { releaseLock(); } - super.afterDowncall(beforeValue); + RuntimeException lastUpCallEx = getLastUpCallException(); + if (lastUpCallEx != null) { + CompilerDirectives.transferToInterpreter(); + setLastUpCallException(null); + throw lastUpCallEx; + } } public static TruffleNFI_Context getInstance() { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_DownCallNodeFactory.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_DownCallNodeFactory.java index 60eea1dfb8dcce3dd65a2cc61e1ad3ee1b658f19..c54cca485f6a5db8e33ef0cbc90c815430c5c7c5 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_DownCallNodeFactory.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_DownCallNodeFactory.java @@ -91,7 +91,7 @@ public final class TruffleNFI_DownCallNodeFactory extends DownCallNodeFactory { @ExplodeLoop protected void afterCall(long before, NativeFunction function, TruffleObject target, Object[] args) { if (function.hasComplexInteraction()) { - RContext.getInstance().getRFFI().afterDowncall(before); + ((TruffleNFI_Context) RContext.getInstance().getRFFI()).afterDowncall(before); } for (Object obj : args) { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_REmbed.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_REmbed.java deleted file mode 100644 index 64c70971c20435a6d83a151bbfe696cf21cc670b..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_REmbed.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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 - * 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.nfi; - -import com.oracle.truffle.api.CompilerDirectives; -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.ffi.NativeFunction; -import com.oracle.truffle.r.runtime.ffi.REmbedRFFI; - -public class TruffleNFI_REmbed implements REmbedRFFI { - - private static class TruffleNFI_ReadConsoleNode extends TruffleNFI_DownCallNode implements ReadConsoleNode { - @Child private Node unboxNode; - - @Override - protected NativeFunction getFunction() { - return NativeFunction.rembedded_read_console; - } - - @Override - public String execute(String prompt) { - Object result = call(prompt); - if (result instanceof String) { - return (String) result; - } - assert result instanceof TruffleObject : "NFI is expected to send us TruffleObject or String"; - if (unboxNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - unboxNode = insert(Message.UNBOX.createNode()); - } - try { - return (String) ForeignAccess.sendUnbox(unboxNode, (TruffleObject) result); - } catch (ClassCastException | UnsupportedMessageException e) { - CompilerDirectives.transferToInterpreter(); - throw RInternalError.shouldNotReachHere("Unboxing TruffleObject from NFI, which should be String wrapper, failed. " + e.getMessage()); - } - } - } - - private static class TruffleNFI_WriteConsoleNode extends TruffleNFI_DownCallNode implements WriteConsoleNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.rembedded_write_console; - } - - @Override - public void execute(String x) { - call(x, x.length()); - } - } - - private static class TruffleNFI_WriteErrConsoleNode extends TruffleNFI_DownCallNode implements WriteErrConsoleNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.rembedded_write_err_console; - } - - @Override - public void execute(String x) { - call(x, x.length()); - } - } - - @Override - public ReadConsoleNode createReadConsoleNode() { - return new TruffleNFI_ReadConsoleNode(); - } - - @Override - public WriteConsoleNode createWriteConsoleNode() { - return new TruffleNFI_WriteConsoleNode(); - } - - @Override - public WriteErrConsoleNode createWriteErrConsoleNode() { - return new TruffleNFI_WriteErrConsoleNode(); - } -} diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rembedded.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rembedded.c index 21214ae229252fa78034d2e6714096e7ec3acb20..2ee67837291d22f7397d77cd232ddf33f0f8de98 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rembedded.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rembedded.c @@ -420,7 +420,7 @@ void uR_ProcessEvents(void) { } void uR_CleanUp(SA_TYPE x, int y, int z) { - return ((call_R_CleanUp) callbacks[R_CleanUp_x])(x, y, z); + ((call_R_CleanUp) callbacks[R_CleanUp_x])(x, y, z); } void (*ptr_R_Suicide)(const char *) = uR_Suicide; @@ -505,11 +505,11 @@ void R_runHandlers(InputHandler *handlers, fd_set *mask) { // ----------------------------------------------------------------------------------------------- // Downcalls from Java. We invoke these functions via REmbedRFFI -void invokeCleanUp(int x, int y, int z) { +void rembedded_cleanup(int x, int y, int z) { ptr_R_CleanUp(x, y, z); } -void invokeSuicide(char* msg) { +void rembedded_suicide(char* msg) { ptr_R_Suicide(msg); } @@ -522,7 +522,7 @@ void rembedded_write_err_console(char *cbuf, int len) { } char* rembedded_read_console(const char* prompt) { - char* cbuf = malloc(sizeof(char) * 1024); + unsigned char* cbuf = malloc(sizeof(char) * 1024); int n = (*ptr_R_ReadConsole)(prompt, cbuf, 1024, 0); return cbuf; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCleanUp.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCleanUp.java index 4d5f97ecf48f8962ac593aec7fc5e76284e0ef2a..61ddc58a29f36f818353ceb8ad4264d102d68ce8 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCleanUp.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RCleanUp.java @@ -27,6 +27,8 @@ import com.oracle.truffle.r.runtime.ffi.CallRFFI.InvokeCallNode; import com.oracle.truffle.r.runtime.ffi.DLL.RFindSymbolNode; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; +import com.oracle.truffle.r.runtime.ffi.REmbedRFFI; +import com.oracle.truffle.r.runtime.ffi.REmbedRFFI.EmbeddedCleanUpNode; import com.oracle.truffle.r.runtime.gnur.SA_TYPE; import com.oracle.truffle.r.runtime.instrument.InstrumentationState; @@ -44,8 +46,7 @@ public abstract class RCleanUp { public static void cleanUp(RContext ctx, SA_TYPE saveType, int status, boolean runLast) { if (RInterfaceCallbacks.R_CleanUp.isOverridden()) { RootCallTarget invokeUserCleanup = ctx.getOrCreateCachedCallTarget(UserDefinedCleanUpRootNode.class, () -> new UserDefinedCleanUpRootNode(ctx).getCallTarget()); - Object[] args = new Object[]{asVector(saveType.ordinal()), asVector(status), asVector(runLast ? 1 : 0)}; - invokeUserCleanup.call(args); + invokeUserCleanup.call(saveType.ordinal(), status, runLast ? 1 : 0); } else { stdCleanUp(saveType, status, runLast); } @@ -134,29 +135,18 @@ public abstract class RCleanUp { RContext.getEngine().checkAndRunStartupShutdownFunction(".Last.sys"); } - private static RIntVector asVector(int value) { - return RDataFactory.createIntVectorFromScalar(value); - } - private static final class UserDefinedCleanUpRootNode extends RootNode { protected UserDefinedCleanUpRootNode(RContext ctx) { super(null); - invokeCallNode = ctx.getRFFI().callRFFI.createInvokeCallNode(); + cleanUpNode = ctx.getRFFI().embedRFFI.createEmbeddedCleanUpNode(); Truffle.getRuntime().createCallTarget(this); } - private static final String SYMBOL_NAME = "invokeCleanUp"; - @Child InvokeCallNode invokeCallNode; - @Child RFindSymbolNode findSymbolNode = RFindSymbolNode.create(); + @Child private EmbeddedCleanUpNode cleanUpNode; @Override public Object execute(VirtualFrame frame) { - SymbolHandle invokeCleanUp = findSymbolNode.execute(SYMBOL_NAME, null, null); - if (invokeCleanUp == null) { - CompilerDirectives.transferToInterpreter(); - throw RInternalError.shouldNotReachHere("Cannot find " + SYMBOL_NAME + " symbol which should be declared in Rembedded.c"); - } - invokeCallNode.dispatch(new NativeCallInfo(SYMBOL_NAME, invokeCleanUp, null), frame.getArguments()); + cleanUpNode.execute((int) frame.getArguments()[0], (int) frame.getArguments()[1], (int) frame.getArguments()[2]); return null; } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSuicide.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSuicide.java index 632e7b2594bccddec8fb27cb642881f09b3823b1..18e74dc486654fc7ec677b7bf7906ea82c453c5e 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSuicide.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSuicide.java @@ -34,6 +34,7 @@ import com.oracle.truffle.r.runtime.ffi.CallRFFI.InvokeCallNode; import com.oracle.truffle.r.runtime.ffi.DLL.RFindSymbolNode; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; +import com.oracle.truffle.r.runtime.ffi.REmbedRFFI.EmbeddedSuicideNode; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; public abstract class RSuicide { @@ -73,36 +74,25 @@ public abstract class RSuicide { throw new ExitException(2, false); } - private static RStringVector asVector(String value) { - return RDataFactory.createStringVector(value); - } - private static void invokeUserDefinedSuicide(RContext ctx, String msg) { if (ctx != null && RInterfaceCallbacks.R_Suicide.isOverridden()) { RootCallTarget invokeUserCleanup = ctx.getOrCreateCachedCallTarget(UserDefinedSuicideRootNode.class, () -> new UserDefinedSuicideRootNode(ctx).getCallTarget()); - invokeUserCleanup.call(new Object[]{asVector(msg)}); + invokeUserCleanup.call(msg); } } private static final class UserDefinedSuicideRootNode extends RootNode { protected UserDefinedSuicideRootNode(RContext ctx) { super(null); - invokeCallNode = ctx.getRFFI().callRFFI.createInvokeCallNode(); + suicideNode = ctx.getRFFI().embedRFFI.createEmbeddedSuicideNode(); Truffle.getRuntime().createCallTarget(this); } - private static final String SYMBOL_NAME = "invokeSuicide"; - @Child InvokeCallNode invokeCallNode; - @Child RFindSymbolNode findSymbolNode = RFindSymbolNode.create(); + @Child private EmbeddedSuicideNode suicideNode; @Override public Object execute(VirtualFrame frame) { - SymbolHandle invokeSuicide = findSymbolNode.execute(SYMBOL_NAME, null, null); - if (invokeSuicide == null) { - CompilerDirectives.transferToInterpreter(); - throw RInternalError.shouldNotReachHere("Cannot find " + SYMBOL_NAME + " symbol which should be declared in Rembedded.c"); - } - invokeCallNode.dispatch(new NativeCallInfo(SYMBOL_NAME, invokeSuicide, null), frame.getArguments()); + suicideNode.execute((String) frame.getArguments()[0]); return null; } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeFunction.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeFunction.java index de1d47a0f6518e4c141c5b6a3a70459e7cae8ba5..091ab6b5132bf935b2cc5041ddb5c0735652db3d 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeFunction.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeFunction.java @@ -82,11 +82,13 @@ public enum NativeFunction { // FastR helpers set_exception_flag("(): void"), // FastR internal helper for R embedded mode - rembedded_write_console("(string, sint32):void", "", anyLibrary(), true), - rembedded_write_err_console("(string, sint32):void", "", anyLibrary(), true), - rembedded_read_console("(string):string", "", anyLibrary(), true), - rembedded_native_clean_up("(sint32, sint32, sint32):void", "", anyLibrary(), true), - rembedded_native_suicide("(string):void", "", anyLibrary(), true), + rembedded_cleanup("(sint32, sint32, sint32):void", "", baseLibrary(), true), + rembedded_suicide("(string):void", "", baseLibrary(), true), + rembedded_write_console("(string, sint32):void", "", baseLibrary(), true), + rembedded_write_err_console("(string, sint32):void", "", baseLibrary(), true), + rembedded_read_console("(string):string", "", baseLibrary(), true), + rembedded_native_clean_up("(sint32, sint32, sint32):void", "", baseLibrary(), true), + rembedded_native_suicide("(string):void", "", baseLibrary(), true), // user-defined RNG unif_init("(sint32): void", "user_", anyLibrary()), norm_rand("(): pointer", "user_", anyLibrary()), diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/REmbedRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/REmbedRFFI.java index 929f2558b46f0d5de02413c1f7c6c30f4e75ef66..52a059a1558a5553aeeb015339b7a1bbc4a8d673 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/REmbedRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/REmbedRFFI.java @@ -22,40 +22,131 @@ */ package com.oracle.truffle.r.runtime.ffi; -import com.oracle.truffle.api.nodes.NodeInterface; +import com.oracle.truffle.api.CompilerDirectives; +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.ffi.DownCallNodeFactory.DownCallNode; /** * Function down-calls related to the embedded API. TODO: these all should be invoked as proper * down-calls because the user code may want to use R API. */ -public interface REmbedRFFI { - interface ReadConsoleNode extends NodeInterface { - String execute(String prompt); +public final class REmbedRFFI { + private final DownCallNodeFactory downCallNodeFactory; - static REmbedRFFI.ReadConsoleNode create() { + public REmbedRFFI(DownCallNodeFactory downCallNodeFactory) { + this.downCallNodeFactory = downCallNodeFactory; + } + + public static final class ReadConsoleNode extends NativeCallNode { + @Child private Node unboxNode; + + private ReadConsoleNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.rembedded_read_console)); + } + + public String execute(String prompt) { + Object result = call(prompt); + if (result instanceof String) { + return (String) result; + } + assert result instanceof TruffleObject : "NFI is expected to send us TruffleObject or String"; + if (unboxNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + unboxNode = insert(Message.UNBOX.createNode()); + } + try { + return (String) ForeignAccess.sendUnbox(unboxNode, (TruffleObject) result); + } catch (ClassCastException | UnsupportedMessageException e) { + CompilerDirectives.transferToInterpreter(); + throw RInternalError.shouldNotReachHere("Unboxing TruffleObject from NFI, which should be String wrapper, failed. " + e.getMessage()); + } + } + + public static REmbedRFFI.ReadConsoleNode create() { return RFFIFactory.getREmbedRFFI().createReadConsoleNode(); } } - interface WriteConsoleBaseNode extends NodeInterface { - void execute(String x); + public abstract static class WriteConsoleBaseNode extends NativeCallNode { + private WriteConsoleBaseNode(DownCallNode downCallNode) { + super(downCallNode); + } + + public final void execute(String x) { + call(x, x.length()); + } } - interface WriteConsoleNode extends WriteConsoleBaseNode { - static REmbedRFFI.WriteConsoleNode create() { + public static final class WriteConsoleNode extends WriteConsoleBaseNode { + public static REmbedRFFI.WriteConsoleNode create() { return RFFIFactory.getREmbedRFFI().createWriteConsoleNode(); } + + public WriteConsoleNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.rembedded_write_console)); + } } - interface WriteErrConsoleNode extends WriteConsoleBaseNode { - static REmbedRFFI.WriteErrConsoleNode create() { + public static final class WriteErrConsoleNode extends WriteConsoleBaseNode { + public static REmbedRFFI.WriteErrConsoleNode create() { return RFFIFactory.getREmbedRFFI().createWriteErrConsoleNode(); } + + public WriteErrConsoleNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.rembedded_write_err_console)); + } } - ReadConsoleNode createReadConsoleNode(); + public static final class EmbeddedSuicideNode extends NativeCallNode { + private EmbeddedSuicideNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.rembedded_suicide)); + } - WriteConsoleNode createWriteConsoleNode(); + public void execute(String message) { + call(message); + } - WriteErrConsoleNode createWriteErrConsoleNode(); + public static EmbeddedSuicideNode create() { + return RFFIFactory.getREmbedRFFI().createEmbeddedSuicideNode(); + } + } + + public static final class EmbeddedCleanUpNode extends NativeCallNode { + private EmbeddedCleanUpNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.rembedded_cleanup)); + } + + public void execute(int x, int y, int z) { + call(x, y, z); + } + + public static EmbeddedCleanUpNode create() { + return RFFIFactory.getREmbedRFFI().createEmbeddedCleanUpNode(); + } + } + + ReadConsoleNode createReadConsoleNode() { + return new ReadConsoleNode(downCallNodeFactory); + } + + WriteConsoleNode createWriteConsoleNode() { + return new WriteConsoleNode(downCallNodeFactory); + } + + WriteErrConsoleNode createWriteErrConsoleNode() { + return new WriteErrConsoleNode(downCallNodeFactory); + } + + public EmbeddedSuicideNode createEmbeddedSuicideNode() { + return new EmbeddedSuicideNode(downCallNodeFactory); + } + + public EmbeddedCleanUpNode createEmbeddedCleanUpNode() { + return new EmbeddedCleanUpNode(downCallNodeFactory); + } }