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 d8522ba773cd3c17651ed7ede84c26e3ca0aa60b..ff17f75a31b843c87431e068c6495444d61ae1df 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 @@ -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.ffi.impl.interop.NativePointer; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.interop.RNullMRContextState; 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/common/CallToNativeNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/CallToNativeNode.java deleted file mode 100644 index ff28a7c795dba76aa2539603df8787b36b04d72c..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/CallToNativeNode.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2017, 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.common; - -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -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.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.runtime.RInternalError; -import com.oracle.truffle.r.runtime.ffi.DLL; -import com.oracle.truffle.r.runtime.ffi.NativeFunction; -import com.oracle.truffle.r.runtime.ffi.RFFIFactory; - -public abstract class CallToNativeNode extends Node { - - @Child private Node message; - protected final NativeFunction function; - - private CallToNativeNode(NativeFunction function) { - this.function = function; - } - - public CallToNativeNode create(NativeFunction f) { - switch (RFFIFactory.getFactoryType()) { - case LLVM: - return new NFI(f); - case NFI: - return new LLVM(f); - default: - throw RInternalError.shouldNotReachHere(); - } - } - - protected abstract TruffleObject getTarget(); - - protected final Object call(Object... args) { - try { - if (message == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - message = insert(Message.createExecute(function.getArgumentCount()).createNode()); - } - wrapArguments(args); - return ForeignAccess.sendExecute(message, getTarget(), args); - } catch (InteropException e) { - throw RInternalError.shouldNotReachHere(e); - } finally { - finishArguments(args); - } - } - - protected abstract void wrapArguments(Object[] args); - - protected abstract void finishArguments(Object[] args); - - private final class NFI extends CallToNativeNode { - - @CompilationFinal private TruffleObject target; - - private NFI(NativeFunction function) { - super(function); - } - - @Override - protected TruffleObject getTarget() { - throw RInternalError.unimplemented("unused implementation"); - // return function.getFunction(); - } - - @SuppressWarnings("cast") - @Override - @ExplodeLoop - protected void wrapArguments(Object[] args) { - for (int i = 0; i < args.length; i++) { - Object obj = args[i]; - if (obj instanceof double[]) { - args[i] = JavaInterop.asTruffleObject((double[]) obj); - } else if (obj instanceof int[] || obj == null) { - args[i] = JavaInterop.asTruffleObject((int[]) obj); - } - } - } - - @Override - @ExplodeLoop - protected void finishArguments(Object[] args) { - for (Object obj : args) { - if (obj instanceof NativeNACheck<?>) { - ((NativeNACheck<?>) obj).close(); - } - } - } - } - - private final class LLVM extends CallToNativeNode { - - @CompilationFinal private TruffleObject target; - - private LLVM(NativeFunction function) { - super(function); - } - - @Override - protected TruffleObject getTarget() { - if (target == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - target = DLL.findSymbol(function.getCallName(), null).asTruffleObject(); - } - return target; - } - - @Override - @ExplodeLoop - protected void wrapArguments(Object[] args) { - for (int i = 0; i < args.length; i++) { - Object obj = args[i]; - if (obj instanceof double[]) { - args[i] = new NativeDoubleArray((double[]) obj); - } else if (obj instanceof int[]) { - args[i] = new NativeIntegerArray((int[]) obj); - } else if (obj == null) { - args[i] = 0; - } - } - } - - @Override - @ExplodeLoop - protected void finishArguments(Object[] args) { - for (Object obj : args) { - if (obj instanceof NativeNACheck<?>) { - ((NativeNACheck<?>) obj).close(); - } - } - } - } -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/DownCallNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/DownCallNode.java deleted file mode 100644 index a554e2dd93ee7dfe148eaa61884fde33f9aff335..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/DownCallNode.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2017, 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.common; - -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -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.ffi.NativeFunction; - -public abstract class DownCallNode extends Node { - - @Child private Node message; - @CompilationFinal private TruffleObject target; - - protected abstract TruffleObject getTarget(); - - protected abstract NativeFunction getFunction(); - - protected final Object call(Object... args) { - try { - if (message == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - message = insert(Message.createExecute(getFunction().getArgumentCount()).createNode()); - } - if (target == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - target = getTarget(); - } - wrapArguments(args); - return ForeignAccess.sendExecute(message, target, args); - } catch (InteropException e) { - throw RInternalError.shouldNotReachHere(e); - } finally { - finishArguments(args); - } - } - - protected abstract void wrapArguments(Object[] args); - - protected abstract void finishArguments(Object[] args); -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/Generic_Tools.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/Generic_Tools.java deleted file mode 100644 index 6ba135893500d83227032afcf8fd1dd69512e369..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/Generic_Tools.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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 - * 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.common; - -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.r.runtime.RInternalError; -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.env.REnvironment; -import com.oracle.truffle.r.runtime.ffi.CallRFFI; -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.NativeCallInfo; -import com.oracle.truffle.r.runtime.ffi.RFFIFactory; -import com.oracle.truffle.r.runtime.ffi.ToolsRFFI; - -public class Generic_Tools implements ToolsRFFI { - public static class Generic_ToolsRFFINode extends Node implements ParseRdNode { - private static final String C_PARSE_RD = "C_parseRd"; - protected static final String TOOLS = "tools"; - - @Child private CallRFFI.InvokeCallNode callRFFINode = RFFIFactory.getCallRFFI().createInvokeCallNode(); - @Child private DLL.RFindSymbolNode findSymbolNode = DLL.RFindSymbolNode.create(); - - @CompilationFinal private NativeCallInfo nativeCallInfo; - - /** - * Invoke C implementation, N.B., code is not thread safe. - */ - @Override - public Object execute(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros, - RLogicalVector warndups) { - synchronized (Generic_Tools.class) { - try { - if (nativeCallInfo == null) { - // lookup entry point (assert library is loaded) - DLLInfo toolsDLLInfo = DLL.findLibrary(TOOLS); - assert toolsDLLInfo != null; - SymbolHandle symbolHandle = findSymbolNode.execute(C_PARSE_RD, TOOLS, DLL.RegisteredNativeSymbol.any()); - assert symbolHandle != DLL.SYMBOL_NOT_FOUND; - nativeCallInfo = new NativeCallInfo(C_PARSE_RD, symbolHandle, toolsDLLInfo); - } - return callRFFINode.dispatch(nativeCallInfo, - new Object[]{con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups}); - } catch (Throwable ex) { - throw RInternalError.shouldNotReachHere(ex, "error during Rd parsing" + ex.getMessage()); - } - } - } - } - - @Override - public ParseRdNode createParseRdNode() { - return new Generic_ToolsRFFINode(); - } -} 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 95c06bb5e6d83f99ec1824e1ba016a9234ac963c..f632643a7b287d73817527c8353d76afd289d44d 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 @@ -52,7 +52,7 @@ public class CharSXPWrapperMR { @Resolve(message = "HAS_SIZE") public abstract static class NCAHasSizeNode extends Node { - protected boolean access(@SuppressWarnings("unused") NativeCharArray receiver) { + protected boolean access(@SuppressWarnings("unused") Object receiver) { return true; } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeIntegerArrayMR.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeIntegerArrayMR.java index d92725c8fd8ea5bb3e3a1b63b8f5f258944ad4f2..aa6edfb67d5892b158eb7ef574b8a3dc00a05fcd 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeIntegerArrayMR.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeIntegerArrayMR.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,6 +28,7 @@ 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.RRuntime; +import com.oracle.truffle.r.runtime.ffi.interop.NativePointer; @MessageResolution(receiverType = NativeIntegerArray.class) public class NativeIntegerArrayMR { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Base.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Base.java deleted file mode 100644 index 0f61b48a678c82be4291124847ffa9a88b9879e0..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Base.java +++ /dev/null @@ -1,299 +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 java.io.IOException; -import java.util.ArrayList; -import java.util.Map; - -import com.oracle.truffle.r.ffi.impl.interop.NativeCharArray; -import com.oracle.truffle.r.ffi.impl.interop.base.ESoftVersionResult; -import com.oracle.truffle.r.ffi.impl.interop.base.GlobResult; -import com.oracle.truffle.r.ffi.impl.interop.base.ReadlinkResult; -import com.oracle.truffle.r.ffi.impl.interop.base.StrtolResult; -import com.oracle.truffle.r.ffi.impl.interop.base.UnameResult; -import com.oracle.truffle.r.runtime.ffi.BaseRFFI; -import com.oracle.truffle.r.runtime.ffi.NativeFunction; - -public class TruffleLLVM_Base implements BaseRFFI { - private static final class TruffleLLVM_GetpidNode extends TruffleLLVM_DownCallNode implements GetpidNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.getpid; - } - - @Override - public int execute() { - return (int) call(); - } - } - - private static class TruffleLLVM_GetwdNode extends TruffleLLVM_DownCallNode implements GetwdNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.getcwd; - } - - @Override - public String execute() { - // TODO: pass buf to "call" and do the wrapping inside wrapArguments - byte[] buf = new byte[4096]; - NativeCharArray nativeBuf = new NativeCharArray(buf); - int result = (int) call(nativeBuf, buf.length); - if (result == 0) { - return null; - } else { - byte[] mbuf = nativeBuf.getValue(); - int i = 0; - while (mbuf[i] != 0 && i < mbuf.length) { - i++; - } - return new String(mbuf, 0, i); - } - } - } - - private static class TruffleLLVM_SetwdNode extends TruffleLLVM_DownCallNode implements SetwdNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.chdir; - } - - @Override - public int execute(String dir) { - NativeCharArray nativeBuf = new NativeCharArray(dir.getBytes()); - return (int) call(nativeBuf); - } - } - - private static class TruffleLLVM_MkdirNode extends TruffleLLVM_DownCallNode implements MkdirNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.mkdir; - } - - @Override - public void execute(String dir, int mode) throws IOException { - NativeCharArray nativeBuf = new NativeCharArray(dir.getBytes()); - int result = (int) call(nativeBuf, mode); - if (result != 0) { - throw new IOException("mkdir " + dir + " failed"); - } - } - } - - private static class TruffleLLVM_ReadlinkNode extends TruffleLLVM_DownCallNode implements ReadlinkNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.readlink; - } - - private static final int EINVAL = 22; - - @Override - public String execute(String path) throws IOException { - NativeCharArray nativePath = new NativeCharArray(path.getBytes()); - ReadlinkResult callback = new ReadlinkResult(); - call(callback, nativePath); - String link = callback.getLink(); - if (link == null) { - if (callback.getErrno() == EINVAL) { - return path; - } else { - // some other error - throw new IOException("readlink failed: " + callback.getErrno()); - } - } - return link; - } - } - - private static class TruffleLLVM_MkdtempNode extends TruffleLLVM_DownCallNode implements MkdtempNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.mkdtemp; - } - - @Override - public String execute(String template) { - /* - * Not only must the (C) string end in XXXXXX it must also be null-terminated. Since it - * is modified by mkdtemp we must make a copy. - */ - byte[] bytes = template.getBytes(); - byte[] ztbytes = new byte[bytes.length + 1]; - System.arraycopy(bytes, 0, ztbytes, 0, bytes.length); - ztbytes[bytes.length] = 0; - NativeCharArray nativeZtbytes = new NativeCharArray(ztbytes); - int result = (int) call(nativeZtbytes); - if (result == 0) { - return null; - } else { - byte[] mztBytes = nativeZtbytes.getValue(); - return new String(mztBytes, 0, bytes.length); - } - } - } - - private static class TruffleLLVM_ChmodNode extends TruffleLLVM_DownCallNode implements ChmodNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.chmod; - } - - @Override - public int execute(String path, int mode) { - NativeCharArray nativePath = new NativeCharArray(path.getBytes()); - return (int) call(nativePath, mode); - } - } - - private static class TruffleLLVM_StrtolNode extends TruffleLLVM_DownCallNode implements StrtolNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.strtol; - } - - @Override - public long execute(String s, int base) throws IllegalArgumentException { - NativeCharArray nativeString = new NativeCharArray(s.getBytes()); - StrtolResult callback = new StrtolResult(); - call(callback, nativeString, base); - if (callback.getErrno() != 0) { - throw new IllegalArgumentException("strtol failure"); - } else { - return callback.getResult(); - } - } - } - - private static class TruffleLLVM_UnameNode extends TruffleLLVM_DownCallNode implements UnameNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.uname; - } - - @Override - public UtsName execute() { - UnameResult baseUnameResultCallback = new UnameResult(); - call(baseUnameResultCallback); - return baseUnameResultCallback; - } - } - - private static class TruffleLLVM_GlobNode extends TruffleLLVM_DownCallNode implements GlobNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.glob; - } - - @Override - public ArrayList<String> glob(String pattern) { - NativeCharArray nativePattern = new NativeCharArray(pattern.getBytes()); - GlobResult baseGlobResultCallback = new GlobResult(); - call(baseGlobResultCallback, nativePattern); - return baseGlobResultCallback.getPaths(); - } - } - - private static class TruffleLLVM_ESoftVersionNode extends TruffleLLVM_DownCallNode implements ESoftVersionNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.eSoftVersion; - } - - @Override - public Map<String, String> eSoftVersion() { - ESoftVersionResult result = new ESoftVersionResult(); - call(result); - return result.getVersions(); - } - - } - - @Override - public GetpidNode createGetpidNode() { - return new TruffleLLVM_GetpidNode(); - } - - @Override - public GetwdNode createGetwdNode() { - return new TruffleLLVM_GetwdNode(); - } - - @Override - public SetwdNode createSetwdNode() { - return new TruffleLLVM_SetwdNode(); - } - - @Override - public MkdirNode createMkdirNode() { - return new TruffleLLVM_MkdirNode(); - } - - @Override - public ReadlinkNode createReadlinkNode() { - return new TruffleLLVM_ReadlinkNode(); - } - - @Override - public MkdtempNode createMkdtempNode() { - return new TruffleLLVM_MkdtempNode(); - } - - @Override - public ChmodNode createChmodNode() { - return new TruffleLLVM_ChmodNode(); - } - - @Override - public StrtolNode createStrtolNode() { - return new TruffleLLVM_StrtolNode(); - } - - @Override - public UnameNode createUnameNode() { - return new TruffleLLVM_UnameNode(); - } - - @Override - public GlobNode createGlobNode() { - return new TruffleLLVM_GlobNode(); - } - - @Override - public ESoftVersionNode createESoftVersionNode() { - return new TruffleLLVM_ESoftVersionNode(); - } -} 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 e9792234bc5f6a2b384540a3320a5036e6e41efb..496e75c66772ebe742fb085878293a364ae48a6e 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 @@ -30,10 +30,10 @@ 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; -import com.oracle.truffle.r.ffi.impl.interop.NativeRawArray; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.ffi.CRFFI; import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; +import com.oracle.truffle.r.runtime.ffi.interop.NativeRawArray; class TruffleLLVM_C implements CRFFI { private static class TruffleLLVM_InvokeCNode extends InvokeCNode { 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 c9365ee397a93eb2610792546e53564a89a7ce02..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 @@ -26,9 +26,17 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.r.ffi.impl.common.LibPaths; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext.ContextState; +import com.oracle.truffle.r.runtime.ffi.BaseRFFI; import com.oracle.truffle.r.runtime.ffi.DLL; +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; +import com.oracle.truffle.r.runtime.ffi.ZipRFFI; /** * A facade for the context state for the Truffle LLVM factory. Delegates to the various @@ -36,13 +44,14 @@ import com.oracle.truffle.r.runtime.ffi.RFFIContext; */ final class TruffleLLVM_Context extends RFFIContext { - final TruffleLLVM_DLL.ContextStateImpl dllState = new TruffleLLVM_DLL.ContextStateImpl(); + private final TruffleLLVM_DLL.ContextStateImpl dllState = new TruffleLLVM_DLL.ContextStateImpl(); final TruffleLLVM_Call.ContextStateImpl callState = new TruffleLLVM_Call.ContextStateImpl(); 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()); + 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 REmbedRFFI(TruffleLLVM_DownCallNodeFactory.INSTANCE), new MiscRFFI(TruffleLLVM_DownCallNodeFactory.INSTANCE)); } static TruffleLLVM_Context getContextState() { @@ -67,11 +76,16 @@ final class TruffleLLVM_Context extends RFFIContext { @Override public void initializeVariables(RContext context) { super.initializeVariables(context); - callState.initializeVariables(); - ((TruffleLLVM_PCRE) pcreRFFI).initialize(); - ((TruffleLLVM_Lapack) lapackRFFI).initialize(); - ((TruffleLLVM_Zip) zipRFFI).initialize(); + + // Load dependencies that don't automatically get loaded: + TruffleLLVM_Lapack.load(); + + String pcrePath = LibPaths.getBuiltinLibPath("pcre"); + TruffleLLVM_NativeDLL.NativeDLOpenRootNode.create().getCallTarget().call(pcrePath, false, true); + + String libzPath = LibPaths.getBuiltinLibPath("z"); + TruffleLLVM_NativeDLL.NativeDLOpenRootNode.create().getCallTarget().call(libzPath, false, true); } @Override 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 deleted file mode 100644 index 9bdf1ad1c0bc344ec53f02a4bd93ea61e2c17b02..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNode.java +++ /dev/null @@ -1,67 +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.llvm; - -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.nodes.ExplodeLoop; -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 { - - @Override - protected final TruffleObject getTarget() { - CompilerAsserts.neverPartOfCompilation(); - return DLL.findSymbol(getFunction().getCallName(), null).asTruffleObject(); - } - - @Override - @ExplodeLoop - protected void wrapArguments(Object[] args) { - for (int i = 0; i < args.length; i++) { - Object obj = args[i]; - if (obj instanceof double[]) { - args[i] = new NativeDoubleArray((double[]) obj); - } else if (obj instanceof int[]) { - args[i] = new NativeIntegerArray((int[]) obj); - } else if (obj == null) { - args[i] = NativePointer.NULL_NATIVEPOINTER; - } - } - } - - @Override - @ExplodeLoop - protected void finishArguments(Object[] args) { - for (Object obj : args) { - if (obj instanceof NativeNACheck<?>) { - ((NativeNACheck<?>) obj).close(); - } - } - } -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNodeFactory.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNodeFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..722f0a242cc963a2ee2a412ca4562e7c409ed212 --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_DownCallNodeFactory.java @@ -0,0 +1,104 @@ +/* + * 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.llvm; + +import static com.oracle.truffle.r.runtime.ffi.NativeFunction.anyLibrary; + +import java.nio.charset.StandardCharsets; + +import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.ExplodeLoop; +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.runtime.RInternalError; +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.DownCallNodeFactory; +import com.oracle.truffle.r.runtime.ffi.NativeFunction; +import com.oracle.truffle.r.runtime.ffi.interop.NativeCharArray; +import com.oracle.truffle.r.runtime.ffi.interop.NativePointer; + +final class TruffleLLVM_DownCallNodeFactory extends DownCallNodeFactory { + + static final TruffleLLVM_DownCallNodeFactory INSTANCE = new TruffleLLVM_DownCallNodeFactory(); + + private TruffleLLVM_DownCallNodeFactory() { + } + + @Override + public DownCallNode createDownCallNode(NativeFunction function) { + return new DownCallNode(function) { + @Override + protected TruffleObject getTarget(NativeFunction function) { + CompilerAsserts.neverPartOfCompilation(); + String library = function.getLibrary(); + DLLInfo dllInfo = null; + if (library != anyLibrary()) { + dllInfo = DLL.findLibrary(library); + } + SymbolHandle result = DLL.findSymbol(function.getCallName(), dllInfo); + if (result == DLL.SYMBOL_NOT_FOUND) { + throw RInternalError.shouldNotReachHere("Could not find function " + function.getCallName() + " in library " + library); + } + return result.asTruffleObject(); + } + + @Override + @ExplodeLoop + protected long beforeCall(NativeFunction nativeFunction, TruffleObject function, Object[] args) { + for (int i = 0; i < args.length; i++) { + Object obj = args[i]; + if (obj instanceof double[]) { + args[i] = new NativeDoubleArray((double[]) obj); + } else if (obj instanceof int[]) { + args[i] = new NativeIntegerArray((int[]) obj); + } else if (obj == null) { + args[i] = NativePointer.NULL_NATIVEPOINTER; + } else if (obj instanceof String) { + args[i] = new NativeCharArray(getStringBytes((String) obj)); + } + } + return 0; + } + + @TruffleBoundary + private byte[] getStringBytes(String obj) { + return obj.getBytes(StandardCharsets.UTF_8); + } + + @Override + @ExplodeLoop + protected void afterCall(long before, NativeFunction function, TruffleObject target, Object[] args) { + for (Object obj : args) { + if (obj instanceof NativeNACheck<?>) { + ((NativeNACheck<?>) obj).close(); + } + } + } + }; + } +} 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 8b0dd787556fa9ce0146288da2181acd299afa2b..30ce4603df574624ec46e549067b233f1beae106 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 @@ -26,8 +26,6 @@ import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.r.ffi.impl.common.LibPaths; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.ffi.DLLRFFI; -import com.oracle.truffle.r.runtime.ffi.LapackRFFI; -import com.oracle.truffle.r.runtime.ffi.NativeFunction; /** * When the embedded GNU R is built, LLVM is created for the components of the {@code libRblas} and @@ -43,9 +41,9 @@ import com.oracle.truffle.r.runtime.ffi.NativeFunction; * when this API is requested. * */ -public class TruffleLLVM_Lapack implements LapackRFFI { +final class TruffleLLVM_Lapack { - void initialize() { + static void load() { /* * 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 @@ -64,8 +62,7 @@ public class TruffleLLVM_Lapack implements LapackRFFI { } // 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_". + // 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); } @@ -78,314 +75,4 @@ public class TruffleLLVM_Lapack implements LapackRFFI { TruffleLLVM_NativeDLL.NativeDLOpenRootNode rootNode = TruffleLLVM_NativeDLL.NativeDLOpenRootNode.create(); return rootNode.getCallTarget(); } - - private static final class TruffleLLVM_IlaverNode extends TruffleLLVM_DownCallNode implements IlaverNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.ilaver; - } - - @Override - public void execute(int[] version) { - call(version); - } - } - - private static final class TruffleLLVM_DgeevNode extends TruffleLLVM_DownCallNode implements DgeevNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgeev; - } - - @Override - public int execute(char jobVL, char jobVR, int n, double[] a, int lda, double[] wr, double[] wi, double[] vl, int ldvl, double[] vr, int ldvr, double[] work, int lwork) { - return (int) call(jobVL, jobVR, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork); - } - } - - private static final class TruffleLLVM_Dgeqp3Node extends TruffleLLVM_DownCallNode implements Dgeqp3Node { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgeqp3; - } - - @Override - public int execute(int m, int n, double[] a, int lda, int[] jpvt, double[] tau, double[] work, int lwork) { - return (int) call(m, n, a, lda, jpvt, tau, work, lwork); - } - } - - private static final class TruffleLLVM_DormqrNode extends TruffleLLVM_DownCallNode implements DormqrNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dormq; - } - - @Override - public int execute(char side, char trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork) { - return (int) call(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork); - } - } - - private static final class TruffleLLVM_DtrtrsNode extends TruffleLLVM_DownCallNode implements DtrtrsNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dtrtrs; - } - - @Override - public int execute(char uplo, char trans, char diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb) { - return (int) call(uplo, trans, diag, n, nrhs, a, lda, b, ldb); - } - } - - private static final class TruffleLLVM_DgetrfNode extends TruffleLLVM_DownCallNode implements DgetrfNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgetrf; - } - - @Override - public int execute(int m, int n, double[] a, int lda, int[] ipiv) { - return (int) call(m, n, a, lda, ipiv); - } - } - - private static final class TruffleLLVM_DpotrfNode extends TruffleLLVM_DownCallNode implements DpotrfNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dpotrf; - } - - @Override - public int execute(char uplo, int n, double[] a, int lda) { - return (int) call(uplo, n, a, lda); - } - } - - private static final class TruffleLLVM_DpotriNode extends TruffleLLVM_DownCallNode implements DpotriNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dpotri; - } - - @Override - public int execute(char uplo, int n, double[] a, int lda) { - return (int) call(uplo, n, a, lda); - } - } - - private static final class TruffleLLVM_DpstrfNode extends TruffleLLVM_DownCallNode implements DpstrfNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dpstrf; - } - - @Override - public int execute(char uplo, int n, double[] a, int lda, int[] piv, int[] rank, double tol, double[] work) { - return (int) call(uplo, n, a, lda, piv, rank, tol, work); - } - } - - private static final class TruffleLLVM_DgesvNode extends TruffleLLVM_DownCallNode implements DgesvNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgesv; - } - - @Override - public int execute(int n, int nrhs, double[] a, int lda, int[] ipiv, double[] b, int ldb) { - return (int) call(n, nrhs, a, lda, ipiv, b, ldb); - } - } - - private static final class TruffleLLVM_DgesddNode extends TruffleLLVM_DownCallNode implements DgesddNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgesdd; - } - - @Override - public int execute(char jobz, int m, int n, double[] a, int lda, double[] s, double[] u, int ldu, double[] vt, int ldtv, double[] work, int lwork, int[] iwork) { - return (int) call(jobz, m, n, a, lda, s, u, ldu, vt, ldtv, work, lwork, iwork); - } - } - - private static final class TruffleLLVM_DlangeNode extends TruffleLLVM_DownCallNode implements DlangeNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dlange; - } - - @Override - public double execute(char norm, int m, int n, double[] a, int lda, double[] work) { - return (double) call(norm, m, n, a, lda, work); - } - } - - private static final class TruffleLLVM_DgeconNode extends TruffleLLVM_DownCallNode implements DgeconNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgecon; - } - - @Override - public int execute(char norm, int n, double[] a, int lda, double anorm, double[] rcond, double[] work, int[] iwork) { - return (int) call(norm, n, a, lda, anorm, rcond, work, iwork); - } - } - - private static final class TruffleLLVM_DsyevrNode extends TruffleLLVM_DownCallNode implements DsyevrNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dsyevr; - } - - @Override - public int execute(char jobz, char range, char uplo, int n, double[] a, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, double[] w, double[] z, int ldz, int[] isuppz, - double[] work, int lwork, int[] iwork, int liwork) { - return (int) call(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, isuppz, work, lwork, iwork, liwork); - } - } - - private static final class TruffleLLVM_ZunmqrNode extends TruffleLLVM_DownCallNode implements ZunmqrNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.zunmqr; - } - - @Override - public int execute(String side, String trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork) { - return (int) call(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork); - } - - } - - private static final class TruffleLLVM_ZtrtrsNode extends TruffleLLVM_DownCallNode implements ZtrtrsNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.ztrtrs; - } - - @Override - public int execute(String uplo, String trans, String diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb) { - return (int) call(uplo, trans, diag, n, nrhs, a, lda, b, ldb); - } - - } - - private static final class TruffleLLVM_DtrsmNode extends TruffleLLVM_DownCallNode implements DtrsmNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dtrsm; - } - - @Override - public void execute(String side, String uplo, String transa, String diag, int m, int n, double alpha, double[] a, int lda, double[] b, int ldb) { - call(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb); - } - - } - - @Override - public IlaverNode createIlaverNode() { - return new TruffleLLVM_IlaverNode(); - } - - @Override - public DgeevNode createDgeevNode() { - return new TruffleLLVM_DgeevNode(); - } - - @Override - public Dgeqp3Node createDgeqp3Node() { - return new TruffleLLVM_Dgeqp3Node(); - } - - @Override - public DormqrNode createDormqrNode() { - return new TruffleLLVM_DormqrNode(); - } - - @Override - public DtrtrsNode createDtrtrsNode() { - return new TruffleLLVM_DtrtrsNode(); - } - - @Override - public DgetrfNode createDgetrfNode() { - return new TruffleLLVM_DgetrfNode(); - } - - @Override - public DpotrfNode createDpotrfNode() { - return new TruffleLLVM_DpotrfNode(); - } - - @Override - public DpotriNode createDpotriNode() { - return new TruffleLLVM_DpotriNode(); - } - - @Override - public DpstrfNode createDpstrfNode() { - return new TruffleLLVM_DpstrfNode(); - } - - @Override - public DgesvNode createDgesvNode() { - return new TruffleLLVM_DgesvNode(); - } - - @Override - public DgesddNode createDgesddNode() { - return new TruffleLLVM_DgesddNode(); - } - - @Override - public DlangeNode createDlangeNode() { - return new TruffleLLVM_DlangeNode(); - } - - @Override - public DgeconNode createDgeconNode() { - return new TruffleLLVM_DgeconNode(); - } - - @Override - public DsyevrNode createDsyevrNode() { - return new TruffleLLVM_DsyevrNode(); - } - - @Override - public ZunmqrNode createZunmqrNode() { - return new TruffleLLVM_ZunmqrNode(); - } - - @Override - public ZtrtrsNode createZtrtrsNode() { - return new TruffleLLVM_ZtrtrsNode(); - } - - @Override - public DtrsmNode createDtrsmNode() { - return new TruffleLLVM_DtrsmNode(); - } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Misc.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Misc.java deleted file mode 100644 index f30eb295eff47b3c0b73b5ddd9149f8faf03b90f..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Misc.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 - * 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.ffi.MiscRFFI; -import com.oracle.truffle.r.runtime.ffi.NativeFunction; - -public class TruffleLLVM_Misc implements MiscRFFI { - - private static class TruffleLLVM_ExactSumNode extends TruffleLLVM_DownCallNode implements ExactSumNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.exactSumFunc; - } - - @Override - public double execute(double[] values, boolean hasNa, boolean naRm) { - return (double) call(values, values.length, hasNa ? 1 : 0, naRm ? 1 : 0); - } - } - - private static final class TruffleLLVM_DqrlsNode extends TruffleLLVM_DownCallNode implements DqrlsNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dqrls; - } - - @Override - public void execute(double[] x, int n, int p, double[] y, int ny, double tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work) { - call(x, n, p, y, ny, tol, b, rsd, qty, k, jpvt, qraux, work); - } - } - - @Override - public ExactSumNode createExactSumNode() { - return new TruffleLLVM_ExactSumNode(); - } - - @Override - public DqrlsNode createDqrlsNode() { - return new TruffleLLVM_DqrlsNode(); - } - -} 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 0bf28ec5788c21541caa8fb30769659f18f86faa..433b1e9c1727ed8b9356f48365f84d1fc2ebf83e 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 @@ -33,12 +33,12 @@ 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.ffi.impl.interop.NativeCharArray; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.RTruffleObject; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.RFFIRootNode; +import com.oracle.truffle.r.runtime.ffi.interop.NativeCharArray; /** * Direct access to native {@code dlopen} for libraries for which no LLVM code is available. 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 deleted file mode 100644 index ce5be6d55534084ea9f6f32297251c93d5043d88..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_PCRE.java +++ /dev/null @@ -1,149 +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.api.CompilerDirectives; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.r.ffi.impl.common.LibPaths; -import com.oracle.truffle.r.ffi.impl.interop.NativeCharArray; -import com.oracle.truffle.r.ffi.impl.interop.pcre.CaptureNamesResult; -import com.oracle.truffle.r.ffi.impl.interop.pcre.CompileResult; -import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_Utils.AsPointerNode; -import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.ffi.NativeFunction; -import com.oracle.truffle.r.runtime.ffi.PCRERFFI; - -public class TruffleLLVM_PCRE implements PCRERFFI { - - 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); - } - - private static class TruffleLLVM_MaketablesNode extends TruffleLLVM_DownCallNode implements MaketablesNode { - - @Child private AsPointerNode asPointer = new AsPointerNode(); - - @Override - protected NativeFunction getFunction() { - return NativeFunction.maketables; - } - - @Override - public long execute() { - return asPointer.execute((TruffleObject) call()); - } - } - - private static class TruffleLLVM_GetCaptureCountNode extends TruffleLLVM_DownCallNode implements GetCaptureCountNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.getcapturecount; - } - - @Override - public int execute(long code, long extra) { - return (int) call(code, extra); - } - } - - private static class TruffleLLVM_GetCaptureNamesNode extends TruffleLLVM_DownCallNode implements GetCaptureNamesNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.getcapturenames; - } - - @Override - public String[] execute(long code, long extra, int captureCount) { - CaptureNamesResult captureNamesCallback = new CaptureNamesResult(captureCount); - int result = (int) call(captureNamesCallback, code, extra); - if (result < 0) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(RError.NO_CALLER, RError.Message.WRONG_PCRE_INFO, result); - } else { - return captureNamesCallback.getCaptureNames(); - } - } - } - - private static class TruffleLLVM_CompileNode extends TruffleLLVM_DownCallNode implements CompileNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.compile; - } - - @Override - public Result execute(String pattern, int options, long tables) { - NativeCharArray pattenChars = new NativeCharArray(pattern.getBytes()); - CompileResult data = new CompileResult(); - call(data, pattenChars, options, tables); - return data.getResult(); - } - } - - private static class TruffleLLVM_ExecNode extends TruffleLLVM_DownCallNode implements ExecNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.exec; - } - - @Override - public int execute(long code, long extra, String subject, int offset, int options, int[] ovector) { - byte[] subjectBytes = subject.getBytes(); - NativeCharArray subjectChars = new NativeCharArray(subjectBytes); - return (int) call(code, extra, subjectChars, subjectBytes.length, offset, options, ovector, ovector.length); - } - } - - @Override - public MaketablesNode createMaketablesNode() { - return new TruffleLLVM_MaketablesNode(); - } - - @Override - public CompileNode createCompileNode() { - return new TruffleLLVM_CompileNode(); - } - - @Override - public GetCaptureCountNode createGetCaptureCountNode() { - return new TruffleLLVM_GetCaptureCountNode(); - } - - @Override - public GetCaptureNamesNode createGetCaptureNamesNode() { - return new TruffleLLVM_GetCaptureNamesNode(); - } - - @Override - public StudyNode createStudyNode() { - throw RInternalError.unimplemented(); - } - - @Override - public ExecNode createExecNode() { - return new TruffleLLVM_ExecNode(); - } -} 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/llvm/TruffleLLVM_Stats.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Stats.java deleted file mode 100644 index e2c6e30f11f817f7c9c2617e8f7e8bc755ad8374..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Stats.java +++ /dev/null @@ -1,192 +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.api.dsl.Cached; -import com.oracle.truffle.api.dsl.ImportStatic; -import com.oracle.truffle.api.dsl.Specialization; -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.nodes.Node; -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.llvm.TruffleLLVM_StatsFactory.ExecuteFactorNodeGen; -import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_StatsFactory.ExecuteWorkNodeGen; -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.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; - -public class TruffleLLVM_Stats implements StatsRFFI { - - public enum FFT_FUN { - fft_work, - fft_factor; - } - - public abstract static class LookupAdapter extends Node { - @Child private DLLRFFI.DLSymNode dllSymNode = RFFIFactory.getDLLRFFI().createDLSymNode(); - - public SymbolHandle lookup(String name) { - DLLInfo dllInfo = DLL.findLibrary("stats"); - // cannot go through DLL because stats does not allow dynamic lookup - // and these symbols are not registered (only fft) - SymbolHandle result = dllSymNode.execute(dllInfo.handle, name); - if (result == DLL.SYMBOL_NOT_FOUND) { - throw RInternalError.shouldNotReachHere(); - } - return result; - } - } - - @ImportStatic({RContext.class}) - public abstract static class ExecuteWork extends LookupAdapter { - public abstract int execute(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork, RContext context); - - @Specialization(guards = "context == cachedContext") - protected int executeWorkCached(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork, @SuppressWarnings("unused") RContext context, - @SuppressWarnings("unused") @Cached("getInstance()") RContext cachedContext, - @Cached("createMessageNode()") Node messageNode, - @Cached("lookupWork()") SymbolHandle fftWork) { - return doWork(a, nseg, n, nspn, isn, work, iwork, messageNode, fftWork); - } - - @Specialization(replaces = "executeWorkCached") - protected int executeWorkNormal(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork, @SuppressWarnings("unused") RContext context) { - return doWork(a, nseg, n, nspn, isn, work, iwork, createMessageNode(), lookup("fft_work")); - } - - private static int doWork(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork, Node messageNode, SymbolHandle fftWork) { - try (NativeDoubleArray na = new NativeDoubleArray(a); - NativeDoubleArray nwork = new NativeDoubleArray(work); - NativeIntegerArray niwork = new NativeIntegerArray(iwork)) { - return (int) ForeignAccess.sendExecute(messageNode, fftWork.asTruffleObject(), na, nseg, n, nspn, isn, nwork, niwork); - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } - } - - public static Node createMessageNode() { - return Message.createExecute(7).createNode(); - } - - public static ExecuteWork create() { - return ExecuteWorkNodeGen.create(); - } - - public SymbolHandle lookupWork() { - return lookup("fft_work"); - } - } - - @ImportStatic({RContext.class}) - public abstract static class ExecuteFactor extends LookupAdapter { - protected abstract void execute(int n, int[] pmaxf, int[] pmaxp, RContext context); - - @Specialization(guards = "context == cachedContext") - protected void executeFactorCached(int n, int[] pmaxf, int[] pmaxp, @SuppressWarnings("unused") RContext context, - @SuppressWarnings("unused") @Cached("getInstance()") RContext cachedContext, - @Cached("createMessageNode()") Node messageNode, - @Cached("lookupFactor()") SymbolHandle fftFactor) { - doFactor(n, pmaxf, pmaxp, messageNode, fftFactor); - } - - @Specialization(replaces = "executeFactorCached") - protected void executeFactorNormal(int n, int[] pmaxf, int[] pmaxp, @SuppressWarnings("unused") RContext context) { - doFactor(n, pmaxf, pmaxp, createMessageNode(), lookup("fft_factor")); - } - - private static void doFactor(int n, int[] pmaxf, int[] pmaxp, Node messageNode, SymbolHandle fftFactor) { - try (NativeIntegerArray npmaxf = new NativeIntegerArray(pmaxf); - NativeIntegerArray npmaxp = new NativeIntegerArray(pmaxp)) { - ForeignAccess.sendExecute(messageNode, fftFactor.asTruffleObject(), n, npmaxf, npmaxp); - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } - } - - public static Node createMessageNode() { - return Message.createExecute(3).createNode(); - } - - public static ExecuteFactor create() { - return ExecuteFactorNodeGen.create(); - } - - public SymbolHandle lookupFactor() { - return lookup("fft_factor"); - } - } - - private static class Truffle_FactorNode extends Node implements FactorNode { - @Child private ExecuteFactor executeFactor = ExecuteFactor.create(); - - @Override - public void execute(int n, int[] pmaxf, int[] pmaxp) { - executeFactor.execute(n, pmaxf, pmaxp, RContext.getInstance()); - } - } - - private static class Truffle_WorkNode extends Node implements WorkNode { - @Child private ExecuteWork executeWork = ExecuteWork.create(); - - @Override - public int execute(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork) { - return executeWork.execute(a, nseg, n, nspn, isn, work, iwork, RContext.getInstance()); - } - } - - 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) { - call(x, ldx, n, k, docoef, qraux, resid, hat, coef, sigma, tol); - } - } - - @Override - public FactorNode createFactorNode() { - return new Truffle_FactorNode(); - } - - @Override - public WorkNode createWorkNode() { - return new Truffle_WorkNode(); - } - - @Override - public LminflNode createLminflNode() { - return new TruffleLLVM_LminflNode(); - } -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Tools.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Tools.java deleted file mode 100644 index 5e0d1feead4941ca78725f517ffbda4a51616428..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Tools.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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 - * 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.ffi.impl.common.Generic_Tools; -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.env.REnvironment; -import com.oracle.truffle.r.runtime.ffi.ToolsRFFI; - -public class TruffleLLVM_Tools implements ToolsRFFI { - - private static class TruffleLLVM_ToolsRFFINode extends Generic_Tools.Generic_ToolsRFFINode { - /** - * Invoke C implementation, N.B., code is not thread safe. - */ - @Override - public Object execute(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros, - RLogicalVector warndups) { - return super.execute(con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups); - } - } - - @Override - public ParseRdNode createParseRdNode() { - return new TruffleLLVM_ToolsRFFINode(); - } -} 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 e1d6e40f1ca421fb2303eb2fe27af8dc97847ae6..d6a1f4b67f5d8153fc01a3d1bf6abb775ef4b247 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 @@ -29,7 +29,6 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.ffi.impl.common.JavaUpCallsRFFIImpl; import com.oracle.truffle.r.ffi.impl.common.RFFIUtils; -import com.oracle.truffle.r.ffi.impl.interop.NativeCharArray; import com.oracle.truffle.r.ffi.impl.upcalls.Callbacks; import com.oracle.truffle.r.ffi.impl.upcalls.FFIUnwrapNode; import com.oracle.truffle.r.runtime.REnvVars; @@ -46,6 +45,7 @@ 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; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; +import com.oracle.truffle.r.runtime.ffi.interop.NativeCharArray; /** * (Incomplete) Variant of {@link JavaUpCallsRFFIImpl} for Truffle LLVM. 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 deleted file mode 100644 index b6922d7ec1c89d39a6d501a8c52c5dea829aa46e..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/llvm/TruffleLLVM_Zip.java +++ /dev/null @@ -1,85 +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.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 - protected NativeFunction getFunction() { - return NativeFunction.compress; - } - - @Override - public int execute(byte[] dest, byte[] source) { - NativeRawArray nativeDest = new NativeRawArray(dest); - NativeRawArray nativeSource = new NativeRawArray(source); - try { - return (int) call(nativeDest, dest.length, nativeSource, source.length); - } finally { - nativeDest.getValue(); - } - } - } - - private static class TruffleLLVM_UncompressNode extends TruffleLLVM_DownCallNode implements UncompressNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.uncompress; - } - - @Override - public int execute(byte[] dest, byte[] source) { - NativeRawArray nativeDest = new NativeRawArray(dest); - NativeRawArray nativeSource = new NativeRawArray(source); - try { - return (int) call(nativeDest, dest.length, nativeSource, source.length); - } finally { - nativeDest.getValue(); - } - } - } - - @Override - public CompressNode createCompressNode() { - return new TruffleLLVM_CompressNode(); - } - - @Override - public UncompressNode createUncompressNode() { - return new TruffleLLVM_UncompressNode(); - } -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java deleted file mode 100644 index a1280ebd9b70b973f6ccb6d4c1d772b1de1350d6..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_Base.java +++ /dev/null @@ -1,208 +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.FilesystemUtils.permissionsFromMode; -import static com.oracle.truffle.r.ffi.impl.managed.Managed_RFFIFactory.unsupported; - -import java.io.IOException; -import java.nio.file.FileAlreadyExistsException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.attribute.PosixFilePermission; -import java.nio.file.attribute.PosixFilePermissions; -import java.util.Set; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RError.Message; -import com.oracle.truffle.r.runtime.ffi.BaseRFFI; - -public class Managed_Base implements BaseRFFI { - - private static final class ManagedGetpidNode extends Node implements GetpidNode { - private int fakePid = (int) System.currentTimeMillis(); - - @Override - public int execute() { - return fakePid; - } - } - - /** - * Process id is used as seed for random number generator. We return another "random" number. - */ - @Override - public GetpidNode createGetpidNode() { - return new ManagedGetpidNode(); - } - - private static final class ManagedGetwdNode extends Node implements GetwdNode { - @Override - @TruffleBoundary - public String execute() { - return Paths.get(".").toAbsolutePath().normalize().toString(); - } - } - - @Override - public GetwdNode createGetwdNode() { - return new ManagedGetwdNode(); - } - - private static final class ManagedSetwdNode extends Node implements SetwdNode { - @Override - public int execute(String dir) { - throw unsupported("setwd"); - } - } - - @Override - public SetwdNode createSetwdNode() { - return new ManagedSetwdNode(); - } - - private static final class ManagedMkdirNode extends Node implements MkdirNode { - @Override - @TruffleBoundary - public void execute(String dir, int mode) throws IOException { - Set<PosixFilePermission> permissions = permissionsFromMode(mode); - Files.createDirectories(Paths.get(dir), PosixFilePermissions.asFileAttribute(permissions)); - } - } - - @Override - public MkdirNode createMkdirNode() { - return new ManagedMkdirNode(); - } - - private static final class ManagedReadLinkNode extends Node implements ReadlinkNode { - @Override - public String execute(String path) throws IOException { - throw unsupported("linknode"); - } - } - - @Override - public ReadlinkNode createReadlinkNode() { - return new ManagedReadLinkNode(); - } - - private static final class ManagedMkdtempNode extends Node implements MkdtempNode { - @Override - @TruffleBoundary - public String execute(String template) { - Path path = null; - boolean done = false; - while (!done) { - try { - path = Paths.get(template); - Files.createDirectories(path); - done = true; - } catch (FileAlreadyExistsException e) { - // nop - } catch (IOException e) { - throw RError.error(RError.NO_CALLER, Message.GENERIC, "Cannot create temp directories."); - } - } - return path.toString(); - } - } - - @Override - public MkdtempNode createMkdtempNode() { - return new ManagedMkdtempNode(); - } - - private static final class ManagedChmodNode extends Node implements ChmodNode { - @Override - @TruffleBoundary - public int execute(String path, int mode) { - try { - Files.setPosixFilePermissions(Paths.get(path), permissionsFromMode(mode)); - return mode; - } catch (IOException e) { - throw RError.error(RError.NO_CALLER, Message.GENERIC, "Cannot change file permissions."); - } - } - } - - @Override - public ChmodNode createChmodNode() { - return new ManagedChmodNode(); - } - - @Override - public StrtolNode createStrtolNode() { - return null; - } - - private static final class ManagedUnameNode extends Node implements UnameNode { - @Override - public UtsName execute() { - return new UtsName() { - @Override - public String sysname() { - return System.getProperty("os.name"); - } - - @Override - public String release() { - return ""; - } - - @Override - public String version() { - return System.getProperty("os.version"); - } - - @Override - public String machine() { - return System.getProperty("os.arch"); - } - - @Override - public String nodename() { - return ""; - } - }; - } - } - - @Override - public UnameNode createUnameNode() { - return new ManagedUnameNode(); - } - - @Override - public GlobNode createGlobNode() { - return null; - } - - @Override - public ESoftVersionNode createESoftVersionNode() { - return null; - } -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_DownCallNodeFactory.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_DownCallNodeFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..13eb6601ce8a4908d412362f3b9261621aa06d2d --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_DownCallNodeFactory.java @@ -0,0 +1,205 @@ +/* + * 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.managed; + +import java.io.IOException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +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.r.runtime.RError; +import com.oracle.truffle.r.runtime.RError.Message; +import com.oracle.truffle.r.runtime.ffi.DownCallNodeFactory; +import com.oracle.truffle.r.runtime.ffi.NativeFunction; +import com.oracle.truffle.r.runtime.ffi.interop.NativeCharArray; + +public final class Managed_DownCallNodeFactory extends DownCallNodeFactory { + + static final Managed_DownCallNodeFactory INSTANCE = new Managed_DownCallNodeFactory(); + + private Managed_DownCallNodeFactory() { + } + + @Override + public DownCallNode createDownCallNode(NativeFunction function) { + return new DownCallNode(function) { + @Override + protected TruffleObject getTarget(NativeFunction function) { + if (function == NativeFunction.getpid) { + return new GetPID(); + } else if (function == NativeFunction.mkdtemp) { + return new Mkdtemp(); + } else if (function == NativeFunction.getcwd) { + return new Getwd(); + } + return new DummyFunctionObject(function); + } + + @Override + protected long beforeCall(NativeFunction nativeFunction, TruffleObject function, Object[] args) { + // Report unsupported functions at invocation time + if (function instanceof DummyFunctionObject) { + throw Managed_RFFIFactory.unsupported(((DummyFunctionObject) function).function.getCallName()); + } + return 0; + } + + @Override + protected void afterCall(long before, NativeFunction function, TruffleObject target, Object[] args) { + // nop + } + }; + } + + private static final class DummyFunctionObject implements TruffleObject { + final NativeFunction function; + + private DummyFunctionObject(NativeFunction function) { + this.function = function; + } + + @Override + public ForeignAccess getForeignAccess() { + return null; + } + } + + // PID is used as a seed for random numbers generation. We still want to support random numbers + // in managed mode so we make up some (random) value + private static final class GetPID implements TruffleObject { + private static final int fakePid = (int) System.currentTimeMillis(); + + @Override + public ForeignAccess getForeignAccess() { + return ForeignAccess.create(GetPID.class, new StandardFactory() { + @Override + public CallTarget accessIsExecutable() { + return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(true)); + } + + @Override + public CallTarget accessExecute(int argumentsLength) { + return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(fakePid)); + } + }); + } + } + + /** + * Implements simplified version of the {@code mkdtemp} from {@code stdlib}. The reason why we + * do not use only Java version is that the real {@code mkdtemp} seems to be more reliable and + * secure. + */ + private static final class Mkdtemp implements TruffleObject { + private static final FileAttribute<Set<PosixFilePermission>> irwxuPermissions = PosixFilePermissions.asFileAttribute( + EnumSet.of(PosixFilePermission.OWNER_EXECUTE, PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE)); + + @Override + public ForeignAccess getForeignAccess() { + return ForeignAccess.create(GetPID.class, new StandardFactory() { + @Override + public CallTarget accessIsExecutable() { + return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(true)); + } + + @Override + public CallTarget accessExecute(int argumentsLength) { + return Truffle.getRuntime().createCallTarget(new RootNode(null) { + @Override + public Object execute(VirtualFrame frame) { + NativeCharArray templateBytes = (NativeCharArray) ForeignAccess.getArguments(frame).get(0); + String template = new String(templateBytes.getValue(), 0, templateBytes.getValue().length - 1); + if (!template.endsWith("XXXXXX")) { + throw new IllegalArgumentException("template must end with XXXXXX"); + } + String templatePrefix = template.substring(0, template.length() - 6); + Path path = null; + int counter = 0; + boolean done = false; + while (!done) { + try { + path = Paths.get(templatePrefix + String.format("%06d", counter++)); + if (Files.exists(path)) { + continue; + } + Files.createDirectories(path, irwxuPermissions); + done = true; + } catch (FileAlreadyExistsException e) { + // nop + } catch (IOException e) { + throw RError.error(RError.NO_CALLER, Message.GENERIC, "Cannot create temp directories."); + } + } + byte[] resultBytes = path.toString().getBytes(); + System.arraycopy(resultBytes, 0, templateBytes.getValue(), 0, Math.min(resultBytes.length, templateBytes.getValue().length)); + return 1; + } + }); + } + }); + } + } + + /** + * Gives the current working directory. For some reasons, this is not exactly equivalent to + * calling the C function, which manifests itself during codetools package installation. + */ + private static final class Getwd implements TruffleObject { + @Override + public ForeignAccess getForeignAccess() { + return ForeignAccess.create(GetPID.class, new StandardFactory() { + @Override + public CallTarget accessIsExecutable() { + return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(true)); + } + + @Override + public CallTarget accessExecute(int argumentsLength) { + return Truffle.getRuntime().createCallTarget(new RootNode(null) { + @Override + public Object execute(VirtualFrame frame) { + NativeCharArray buffer = (NativeCharArray) ForeignAccess.getArguments(frame).get(0); + byte[] bytes = Paths.get(".").toAbsolutePath().normalize().toString().getBytes(); + System.arraycopy(bytes, 0, buffer.getValue(), 0, Math.min(bytes.length, buffer.getValue().length)); + return 1; + } + }); + } + }); + } + } +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_LapackRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_LapackRFFI.java deleted file mode 100644 index bc1cb7872eb6887d04a9ec7a0915c20b7024fe41..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_LapackRFFI.java +++ /dev/null @@ -1,114 +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.ffi.LapackRFFI; - -public class Managed_LapackRFFI implements LapackRFFI { - @Override - public IlaverNode createIlaverNode() { - throw unsupported("lapack"); - } - - @Override - public DgeevNode createDgeevNode() { - throw unsupported("lapack"); - } - - @Override - public Dgeqp3Node createDgeqp3Node() { - throw unsupported("lapack"); - } - - @Override - public DormqrNode createDormqrNode() { - throw unsupported("lapack"); - } - - @Override - public DtrtrsNode createDtrtrsNode() { - throw unsupported("lapack"); - } - - @Override - public DgetrfNode createDgetrfNode() { - throw unsupported("lapack"); - } - - @Override - public DpotrfNode createDpotrfNode() { - throw unsupported("lapack"); - } - - @Override - public DpotriNode createDpotriNode() { - throw unsupported("lapack"); - } - - @Override - public DpstrfNode createDpstrfNode() { - throw unsupported("lapack"); - } - - @Override - public DgesvNode createDgesvNode() { - throw unsupported("lapack"); - } - - @Override - public DgesddNode createDgesddNode() { - throw unsupported("lapack"); - } - - @Override - public DlangeNode createDlangeNode() { - throw unsupported("lapack"); - } - - @Override - public DgeconNode createDgeconNode() { - throw unsupported("lapack"); - } - - @Override - public DsyevrNode createDsyevrNode() { - throw unsupported("lapack"); - } - - @Override - public ZunmqrNode createZunmqrNode() { - throw unsupported("lapack"); - } - - @Override - public ZtrtrsNode createZtrtrsNode() { - throw unsupported("lapack"); - } - - @Override - public DtrsmNode createDtrsmNode() { - throw unsupported("lapack"); - } -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_PCRERFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_PCRERFFI.java deleted file mode 100644 index 7fe533a23ff5cf7b179199facffb450a39ae81ea..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/Managed_PCRERFFI.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.managed; - -import static com.oracle.truffle.r.ffi.impl.managed.Managed_RFFIFactory.unsupported; - -import com.oracle.truffle.r.runtime.ffi.PCRERFFI; - -public class Managed_PCRERFFI implements PCRERFFI { - @Override - public MaketablesNode createMaketablesNode() { - throw unsupported("PCRE"); - } - - @Override - public CompileNode createCompileNode() { - throw unsupported("PCRE"); - } - - @Override - public GetCaptureCountNode createGetCaptureCountNode() { - throw unsupported("PCRE"); - } - - @Override - public GetCaptureNamesNode createGetCaptureNamesNode() { - throw unsupported("PCRE"); - } - - @Override - public StudyNode createStudyNode() { - throw unsupported("PCRE"); - } - - @Override - public ExecNode createExecNode() { - throw unsupported("PCRE"); - } -} 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 2e4f6ad6a48b23c12c8605e1adda92724b0acbf5..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 @@ -28,12 +28,16 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; +import com.oracle.truffle.r.runtime.ffi.BaseRFFI; import com.oracle.truffle.r.runtime.ffi.CRFFI; import com.oracle.truffle.r.runtime.ffi.CallRFFI; import com.oracle.truffle.r.runtime.ffi.CallRFFI.HandleUpCallExceptionNode; import com.oracle.truffle.r.runtime.ffi.DLLRFFI; +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; @@ -54,7 +58,7 @@ public final class Managed_RFFIFactory extends RFFIFactory { public InvokeCNode createInvokeCNode() { throw unsupported("invoke"); } - }, new Managed_Base(), new CallRFFI() { + }, new BaseRFFI(Managed_DownCallNodeFactory.INSTANCE), new CallRFFI() { @Override public InvokeCallNode createInvokeCallNode() { throw unsupported("native code invocation"); @@ -104,51 +108,12 @@ public final class Managed_RFFIFactory extends RFFIFactory { public SeedsNode createSeedsNode() { throw unsupported("user defined RNG"); } - }, new ZipRFFI() { - @Override - public CompressNode createCompressNode() { - throw unsupported("zip compression"); - } - - @Override - public UncompressNode createUncompressNode() { - throw unsupported("zip decompression"); - } - }, new Managed_PCRERFFI(), new Managed_LapackRFFI(), - new StatsRFFI() { - @Override - public FactorNode createFactorNode() { - throw unsupported("factor"); - } - - @Override - public WorkNode createWorkNode() { - throw unsupported("work"); - } - - @Override - public LminflNode createLminflNode() { - throw unsupported("lminfl"); - } - }, new ToolsRFFI() { - @Override - public ParseRdNode createParseRdNode() { - throw unsupported("parseRD"); - } - }, new Managed_REmbedRFFI(), new MiscRFFI() { - @Override - public ExactSumNode createExactSumNode() { - throw unsupported("exactsum"); - } - - @Override - public DqrlsNode createDqrlsNode() { - throw unsupported("dqrls"); - } - }); + }, new ZipRFFI(Managed_DownCallNodeFactory.INSTANCE), new PCRERFFI(Managed_DownCallNodeFactory.INSTANCE), new LapackRFFI(Managed_DownCallNodeFactory.INSTANCE), + new StatsRFFI(Managed_DownCallNodeFactory.INSTANCE), new ToolsRFFI(), new REmbedRFFI(Managed_DownCallNodeFactory.INSTANCE), + new MiscRFFI(Managed_DownCallNodeFactory.INSTANCE)); } - static class IgnoreUpCallExceptionNode extends Node implements HandleUpCallExceptionNode { + private static class IgnoreUpCallExceptionNode extends Node implements HandleUpCallExceptionNode { @Override public void execute(Throwable ex) { // nop diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/HandleNFIUpCallExceptionNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/HandleNFIUpCallExceptionNode.java index b1620ab0921265178c6b4adbb85c04d028369fef..4c3835c1d68b5de9b9fd93ccccaa24471d3f9b1a 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/HandleNFIUpCallExceptionNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/HandleNFIUpCallExceptionNode.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 @@ -25,15 +25,16 @@ package com.oracle.truffle.r.ffi.impl.nfi; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.ffi.CallRFFI.HandleUpCallExceptionNode; +import com.oracle.truffle.r.runtime.ffi.DownCallNodeFactory.DownCallNode; import com.oracle.truffle.r.runtime.ffi.NativeFunction; public class HandleNFIUpCallExceptionNode extends Node implements HandleUpCallExceptionNode { - @Child private SetFlagNode setFlagNode = new SetFlagNode(); + @Child private DownCallNode setFlagNode = TruffleNFI_DownCallNodeFactory.INSTANCE.createDownCallNode(NativeFunction.set_exception_flag); @Override @TruffleBoundary public void execute(Throwable originalEx) { - setFlagNode.execute(); + setFlagNode.call(); RuntimeException ex; if (originalEx instanceof RuntimeException) { ex = (RuntimeException) originalEx; @@ -42,15 +43,4 @@ public class HandleNFIUpCallExceptionNode extends Node implements HandleUpCallEx } TruffleNFI_Context.getInstance().setLastUpCallException(ex); } - - private static final class SetFlagNode extends TruffleNFI_DownCallNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.set_exception_flag; - } - - public void execute() { - call(); - } - } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Base.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Base.java deleted file mode 100644 index 7d8f8a9a8a5300fe18ec2e0fd0fbff81a0c044bc..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Base.java +++ /dev/null @@ -1,290 +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.nfi; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Map; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.interop.java.JavaInterop; -import com.oracle.truffle.r.ffi.impl.interop.base.ESoftVersionResult; -import com.oracle.truffle.r.ffi.impl.interop.base.GlobResult; -import com.oracle.truffle.r.ffi.impl.interop.base.ReadlinkResult; -import com.oracle.truffle.r.ffi.impl.interop.base.StrtolResult; -import com.oracle.truffle.r.ffi.impl.interop.base.UnameResult; -import com.oracle.truffle.r.runtime.ffi.BaseRFFI; -import com.oracle.truffle.r.runtime.ffi.NativeFunction; - -public class TruffleNFI_Base implements BaseRFFI { - - private static class TruffleNFI_GetpidNode extends TruffleNFI_DownCallNode implements GetpidNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.getpid; - } - - @Override - public int execute() { - return (int) call(); - } - } - - private static final class TruffleNFI_GetwdNode extends TruffleNFI_DownCallNode implements GetwdNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.getcwd; - } - - @TruffleBoundary - @Override - public String execute() { - byte[] buf = new byte[4096]; - int result = (int) call(JavaInterop.asTruffleObject(buf), buf.length); - if (result == 0) { - return null; - } else { - int i = 0; - while (buf[i] != 0 && i < buf.length) { - i++; - } - return new String(buf, 0, i); - } - } - } - - private static class TruffleNFI_SetwdNode extends TruffleNFI_DownCallNode implements SetwdNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.chdir; - } - - @Override - public int execute(String dir) { - return (int) call(dir); - } - } - - private static class TruffleNFI_MkdirNode extends TruffleNFI_DownCallNode implements MkdirNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.mkdir; - } - - @Override - public void execute(String dir, int mode) throws IOException { - if ((int) call(dir, mode) != 0) { - throw new IOException("mkdir " + dir + " failed"); - } - } - } - - private static class TruffleNFI_ReadlinkNode extends TruffleNFI_DownCallNode implements ReadlinkNode { - private static final int EINVAL = 22; - - @Override - protected NativeFunction getFunction() { - return NativeFunction.readlink; - } - - @Override - public String execute(String path) throws IOException { - ReadlinkResult data = new ReadlinkResult(); - call(data, path); - if (data.getLink() == null) { - if (data.getErrno() == EINVAL) { - return path; - } else { - // some other error - throw new IOException("readlink failed: " + data.getErrno()); - } - } - return data.getLink(); - } - } - - private static class TruffleNFI_MkdtempNode extends TruffleNFI_DownCallNode implements MkdtempNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.mkdtemp; - } - - @TruffleBoundary - @Override - public String execute(String template) { - /* - * Not only must the (C) string end in XXXXXX it must also be null-terminated. Since it - * is modified by mkdtemp we must make a copy. - */ - byte[] bytes = template.getBytes(); - byte[] ztbytes = new byte[bytes.length + 1]; - System.arraycopy(bytes, 0, ztbytes, 0, bytes.length); - ztbytes[bytes.length] = 0; - int result = (int) call(JavaInterop.asTruffleObject(ztbytes)); - if (result == 0) { - return null; - } else { - return new String(ztbytes, 0, bytes.length); - } - } - } - - private static class TruffleNFI_ChmodNode extends TruffleNFI_DownCallNode implements ChmodNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.chmod; - } - - @Override - public int execute(String path, int mode) { - return (int) call(path, mode); - } - } - - private static class TruffleNFI_StrtolNode extends TruffleNFI_DownCallNode implements StrtolNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.strtol; - } - - @Override - public long execute(String s, int base) throws IllegalArgumentException { - StrtolResult data = new StrtolResult(); - call(data, s, base); - if (data.getErrno() != 0) { - throw new IllegalArgumentException("strtol failure"); - } else { - return data.getResult(); - } - } - } - - private static class TruffleNFI_UnameNode extends TruffleNFI_DownCallNode implements UnameNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.uname; - } - - @Override - public UtsName execute() { - UnameResult data = new UnameResult(); - call(data); - return data; - } - } - - private static class TruffleNFI_GlobNode extends TruffleNFI_DownCallNode implements GlobNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.glob; - } - - @Override - public ArrayList<String> glob(String pattern) { - GlobResult data = new GlobResult(); - call(data, pattern); - return data.getPaths(); - } - } - - private static class TruffleNFI_ESoftVersionNode extends TruffleNFI_DownCallNode implements ESoftVersionNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.eSoftVersion; - } - - @Override - public Map<String, String> eSoftVersion() { - ESoftVersionResult result = new ESoftVersionResult(); - call(result); - return result.getVersions(); - } - - } - - @Override - public GetpidNode createGetpidNode() { - return new TruffleNFI_GetpidNode(); - } - - @Override - public GetwdNode createGetwdNode() { - return new TruffleNFI_GetwdNode(); - } - - @Override - public SetwdNode createSetwdNode() { - return new TruffleNFI_SetwdNode(); - } - - @Override - public MkdirNode createMkdirNode() { - return new TruffleNFI_MkdirNode(); - } - - @Override - public ReadlinkNode createReadlinkNode() { - return new TruffleNFI_ReadlinkNode(); - } - - @Override - public MkdtempNode createMkdtempNode() { - return new TruffleNFI_MkdtempNode(); - } - - @Override - public ChmodNode createChmodNode() { - return new TruffleNFI_ChmodNode(); - } - - @Override - public StrtolNode createStrtolNode() { - return new TruffleNFI_StrtolNode(); - } - - @Override - public UnameNode createUnameNode() { - return new TruffleNFI_UnameNode(); - } - - @Override - public GlobNode createGlobNode() { - return new TruffleNFI_GlobNode(); - } - - @Override - public ESoftVersionNode createESoftVersionNode() { - return new TruffleNFI_ESoftVersionNode(); - } - -} 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 affec6643ad9a42772210aefa6bc04dbc64accf4..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 @@ -50,13 +50,21 @@ import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext.ContextKind; import com.oracle.truffle.r.runtime.context.RContext.ContextState; +import com.oracle.truffle.r.runtime.ffi.BaseRFFI; 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.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; +import com.oracle.truffle.r.runtime.ffi.ToolsRFFI; +import com.oracle.truffle.r.runtime.ffi.ZipRFFI; import sun.misc.Unsafe; @@ -84,8 +92,10 @@ final class TruffleNFI_Context extends RFFIContext { private static ReentrantLock accessLock; TruffleNFI_Context() { - super(new TruffleNFI_C(), new TruffleNFI_Base(), new TruffleNFI_Call(), new TruffleNFI_DLL(), new TruffleNFI_UserRng(), new TruffleNFI_Zip(), new TruffleNFI_PCRE(), new TruffleNFI_Lapack(), - new TruffleNFI_Stats(), new TruffleNFI_Tools(), new TruffleNFI_REmbed(), new TruffleNFI_Misc()); + 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 REmbedRFFI(TruffleNFI_DownCallNodeFactory.INSTANCE), + new MiscRFFI(TruffleNFI_DownCallNodeFactory.INSTANCE)); // forward constructor } @@ -337,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(); @@ -346,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); @@ -354,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_DownCallNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_DownCallNode.java deleted file mode 100644 index 3f0177ab38d1386c26b7c8653e25081079642f8d..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_DownCallNode.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.nfi; - -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.r.ffi.impl.common.DownCallNode; -import com.oracle.truffle.r.ffi.impl.interop.NativeNACheck; - -public abstract class TruffleNFI_DownCallNode extends DownCallNode { - - @Override - protected final TruffleObject getTarget() { - // TODO: this lookupNativeFunction function can exist in all FFI Contexts - return TruffleNFI_Context.getInstance().lookupNativeFunction(getFunction()); - } - - @SuppressWarnings("cast") - @Override - @ExplodeLoop - protected void wrapArguments(Object[] args) { - for (int i = 0; i < args.length; i++) { - Object obj = args[i]; - // TODO: this could use the wrappers from LLVM - if (obj instanceof double[]) { - args[i] = JavaInterop.asTruffleObject((double[]) obj); - } else if (obj instanceof int[] || obj == null) { - args[i] = JavaInterop.asTruffleObject((int[]) obj); - } - } - } - - @Override - @ExplodeLoop - protected void finishArguments(Object[] args) { - for (Object obj : args) { - // TODO: can this ever happen in NFI? - if (obj instanceof NativeNACheck<?>) { - ((NativeNACheck<?>) obj).close(); - } - } - } -} 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 new file mode 100644 index 0000000000000000000000000000000000000000..c54cca485f6a5db8e33ef0cbc90c815430c5c7c5 --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_DownCallNodeFactory.java @@ -0,0 +1,106 @@ +/* + * 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.nfi; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +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.r.ffi.impl.interop.NativeNACheck; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.ffi.DownCallNodeFactory; +import com.oracle.truffle.r.runtime.ffi.NativeFunction; +import com.oracle.truffle.r.runtime.ffi.interop.NativeUInt8Array; + +public final class TruffleNFI_DownCallNodeFactory extends DownCallNodeFactory { + public static final TruffleNFI_DownCallNodeFactory INSTANCE = new TruffleNFI_DownCallNodeFactory(); + + private TruffleNFI_DownCallNodeFactory() { + } + + @Override + public DownCallNode createDownCallNode(NativeFunction function) { + return new DownCallNode(function) { + @Override + protected TruffleObject getTarget(NativeFunction function) { + // TODO: this lookupNativeFunction function can exist in all FFI Contexts + return TruffleNFI_Context.getInstance().lookupNativeFunction(function); + } + + @SuppressWarnings("cast") + @Override + @ExplodeLoop + protected long beforeCall(NativeFunction function, TruffleObject target, Object[] args) { + for (int i = 0; i < args.length; i++) { + Object obj = args[i]; + if (obj instanceof double[]) { + args[i] = JavaInterop.asTruffleObject(obj); + } else if (obj instanceof int[] || obj == null) { + args[i] = JavaInterop.asTruffleObject(obj); + } else if (obj instanceof NativeUInt8Array) { + // accounts for NativeCharArray and NativeRawArray + // the assumption is that getValue() gives us the actual backing array and + // NFI will transfer any changes back to this array + NativeUInt8Array nativeArr = (NativeUInt8Array) obj; + byte[] data; + if (nativeArr.fakesNullTermination()) { + data = getNullTerminatedBytes(nativeArr.getValue()); + nativeArr.setValue(data, false); + } else { + data = nativeArr.getValue(); + } + args[i] = JavaInterop.asTruffleObject(data); + } + } + + if (function.hasComplexInteraction()) { + return ((TruffleNFI_Context) RContext.getInstance().getRFFI()).beforeDowncall(); + } + return 0; + } + + @TruffleBoundary + private byte[] getNullTerminatedBytes(byte[] data) { + byte[] newData = new byte[data.length + 1]; + System.arraycopy(data, 0, newData, 0, data.length); + newData[data.length] = 0; + return newData; + } + + @Override + @ExplodeLoop + protected void afterCall(long before, NativeFunction function, TruffleObject target, Object[] args) { + if (function.hasComplexInteraction()) { + ((TruffleNFI_Context) RContext.getInstance().getRFFI()).afterDowncall(before); + } + + for (Object obj : args) { + // TODO: can this ever happen in NFI? + if (obj instanceof NativeNACheck<?>) { + ((NativeNACheck<?>) obj).close(); + } + } + } + }; + } +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Lapack.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Lapack.java deleted file mode 100644 index 613826464867598da3b2d9a949aa7cd87534ab3d..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Lapack.java +++ /dev/null @@ -1,323 +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.nfi; - -import com.oracle.truffle.r.runtime.ffi.LapackRFFI; -import com.oracle.truffle.r.runtime.ffi.NativeFunction; - -public class TruffleNFI_Lapack implements LapackRFFI { - - private static class TruffleNFI_IlaverNode extends TruffleNFI_DownCallNode implements IlaverNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.ilaver; - } - - @Override - public void execute(int[] version) { - call(version); - } - } - - private static class TruffleNFI_DgeevNode extends TruffleNFI_DownCallNode implements DgeevNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgeev; - } - - @Override - public int execute(char jobVL, char jobVR, int n, double[] a, int lda, double[] wr, double[] wi, double[] vl, int ldvl, double[] vr, int ldvr, double[] work, int lwork) { - return (int) call(jobVL, jobVR, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork); - } - } - - private static class TruffleNFI_Dgeqp3Node extends TruffleNFI_DownCallNode implements Dgeqp3Node { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgeqp3; - } - - @Override - public int execute(int m, int n, double[] a, int lda, int[] jpvt, double[] tau, double[] work, int lwork) { - return (int) call(m, n, a, lda, jpvt, tau, work, lwork); - } - } - - private static class TruffleNFI_DormqrNode extends TruffleNFI_DownCallNode implements DormqrNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dormq; - } - - @Override - public int execute(char side, char trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork) { - return (int) call(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork); - } - } - - private static class TruffleNFI_DtrtrsNode extends TruffleNFI_DownCallNode implements DtrtrsNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dtrtrs; - } - - @Override - public int execute(char uplo, char trans, char diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb) { - return (int) call(uplo, trans, diag, n, nrhs, a, lda, b, ldb); - } - } - - private static class TruffleNFI_DgetrfNode extends TruffleNFI_DownCallNode implements DgetrfNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgetrf; - } - - @Override - public int execute(int m, int n, double[] a, int lda, int[] ipiv) { - return (int) call(m, n, a, lda, ipiv); - } - } - - private static class TruffleNFI_DpotrfNode extends TruffleNFI_DownCallNode implements DpotrfNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dpotrf; - } - - @Override - public int execute(char uplo, int n, double[] a, int lda) { - return (int) call(uplo, n, a, lda); - } - } - - private static class TruffleNFI_DpotriNode extends TruffleNFI_DownCallNode implements DpotriNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dpotri; - } - - @Override - public int execute(char uplo, int n, double[] a, int lda) { - return (int) call(uplo, n, a, lda); - } - } - - private static class TruffleNFI_DpstrfNode extends TruffleNFI_DownCallNode implements DpstrfNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dpstrf; - } - - @Override - public int execute(char uplo, int n, double[] a, int lda, int[] piv, int[] rank, double tol, double[] work) { - return (int) call(uplo, n, a, lda, piv, rank, tol, work); - } - } - - private static class TruffleNFI_DgesvNode extends TruffleNFI_DownCallNode implements DgesvNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgesv; - } - - @Override - public int execute(int n, int nrhs, double[] a, int lda, int[] ipiv, double[] b, int ldb) { - return (int) call(n, nrhs, a, lda, ipiv, b, ldb); - } - } - - private static class TruffleNFI_DgesddNode extends TruffleNFI_DownCallNode implements DgesddNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgesdd; - } - - @Override - public int execute(char jobz, int m, int n, double[] a, int lda, double[] s, double[] u, int ldu, double[] vt, int ldtv, double[] work, int lwork, int[] iwork) { - return (int) call(jobz, m, n, a, lda, s, u, ldu, vt, ldtv, work, lwork, iwork); - } - } - - private static class TruffleNFI_DlangeNode extends TruffleNFI_DownCallNode implements DlangeNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dlange; - } - - @Override - public double execute(char norm, int m, int n, double[] a, int lda, double[] work) { - return (double) call(norm, m, n, a, lda, work); - } - } - - private static class TruffleNFI_DgeconNode extends TruffleNFI_DownCallNode implements DgeconNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dgecon; - } - - @Override - public int execute(char norm, int n, double[] a, int lda, double anorm, double[] rcond, double[] work, int[] iwork) { - return (int) call(norm, n, a, lda, anorm, rcond, work, iwork); - } - } - - private static class TruffleNFI_DsyevrNode extends TruffleNFI_DownCallNode implements DsyevrNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dsyevr; - } - - @Override - public int execute(char jobz, char range, char uplo, int n, double[] a, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, double[] w, double[] z, int ldz, int[] isuppz, - double[] work, int lwork, int[] iwork, int liwork) { - return (int) call(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, isuppz, work, lwork, iwork, liwork); - } - } - - private static class TruffleNFI_ZunmqrNode extends TruffleNFI_DownCallNode implements ZunmqrNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.zunmqr; - } - - @Override - public int execute(String side, String trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork) { - return (int) call(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork); - } - - } - - private static final class TruffleNFI_ZtrtrsNode extends TruffleNFI_DownCallNode implements ZtrtrsNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.ztrtrs; - } - - @Override - public int execute(String uplo, String trans, String diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb) { - return (int) call(uplo, trans, diag, n, nrhs, a, lda, b, ldb); - } - } - - private static class TruffleNFI_DtrsmNode extends TruffleNFI_DownCallNode implements DtrsmNode { - - @Override - protected NativeFunction getFunction() { - return NativeFunction.dtrsm; - } - - @Override - public void execute(String side, String uplo, String transa, String diag, int m, int n, double alpha, double[] a, int lda, double[] b, int ldb) { - call(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb); - } - - } - - @Override - public IlaverNode createIlaverNode() { - return new TruffleNFI_IlaverNode(); - } - - @Override - public DgeevNode createDgeevNode() { - return new TruffleNFI_DgeevNode(); - } - - @Override - public Dgeqp3Node createDgeqp3Node() { - return new TruffleNFI_Dgeqp3Node(); - } - - @Override - public DormqrNode createDormqrNode() { - return new TruffleNFI_DormqrNode(); - } - - @Override - public DtrtrsNode createDtrtrsNode() { - return new TruffleNFI_DtrtrsNode(); - } - - @Override - public DgetrfNode createDgetrfNode() { - return new TruffleNFI_DgetrfNode(); - } - - @Override - public DpotrfNode createDpotrfNode() { - return new TruffleNFI_DpotrfNode(); - } - - @Override - public DpotriNode createDpotriNode() { - return new TruffleNFI_DpotriNode(); - } - - @Override - public DpstrfNode createDpstrfNode() { - return new TruffleNFI_DpstrfNode(); - } - - @Override - public DgesvNode createDgesvNode() { - return new TruffleNFI_DgesvNode(); - } - - @Override - public DgesddNode createDgesddNode() { - return new TruffleNFI_DgesddNode(); - } - - @Override - public DlangeNode createDlangeNode() { - return new TruffleNFI_DlangeNode(); - } - - @Override - public DgeconNode createDgeconNode() { - return new TruffleNFI_DgeconNode(); - } - - @Override - public DsyevrNode createDsyevrNode() { - return new TruffleNFI_DsyevrNode(); - } - - @Override - public ZunmqrNode createZunmqrNode() { - return new TruffleNFI_ZunmqrNode(); - } - - @Override - public ZtrtrsNode createZtrtrsNode() { - return new TruffleNFI_ZtrtrsNode(); - } - - @Override - public DtrsmNode createDtrsmNode() { - return new TruffleNFI_DtrsmNode(); - } -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Misc.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Misc.java deleted file mode 100644 index e94bcccd814c111c7c13e3e4a69bba301a89990f..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Misc.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2017, 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.nfi; - -import com.oracle.truffle.r.runtime.ffi.MiscRFFI; -import com.oracle.truffle.r.runtime.ffi.NativeFunction; - -public class TruffleNFI_Misc implements MiscRFFI { - - private static final class TruffleNFI_ExactSumNode extends TruffleNFI_DownCallNode implements ExactSumNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.exactSumFunc; - } - - @Override - public double execute(double[] values, boolean hasNa, boolean naRm) { - return (double) call(values, values.length, hasNa ? 1 : 0, naRm ? 1 : 0); - } - } - - private static class TruffleNFI_DqrlsNode extends TruffleNFI_DownCallNode implements DqrlsNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.dqrls; - } - - @Override - public void execute(double[] x, int n, int p, double[] y, int ny, double tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work) { - call(x, n, p, y, ny, tol, b, rsd, qty, k, jpvt, qraux, work); - } - } - - @Override - public ExactSumNode createExactSumNode() { - return new TruffleNFI_ExactSumNode(); - } - - @Override - public DqrlsNode createDqrlsNode() { - return new TruffleNFI_DqrlsNode(); - } - -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_PCRE.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_PCRE.java deleted file mode 100644 index 0be4447c546dd8d4d48125bc01feff222d0606e0..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_PCRE.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * 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 - * 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 java.nio.charset.StandardCharsets; - -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.interop.java.JavaInterop; -import com.oracle.truffle.r.ffi.impl.interop.pcre.CaptureNamesResult; -import com.oracle.truffle.r.ffi.impl.interop.pcre.CompileResult; -import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.ffi.NativeFunction; -import com.oracle.truffle.r.runtime.ffi.PCRERFFI; - -public class TruffleNFI_PCRE implements PCRERFFI { - - private static class TruffleNFI_MaketablesNode extends TruffleNFI_DownCallNode implements MaketablesNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.maketables; - } - - @Override - public long execute() { - return (long) call(); - } - } - - private static class TruffleNFI_GetCaptureCountNode extends TruffleNFI_DownCallNode implements GetCaptureCountNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.getcapturecount; - } - - @Override - public int execute(long code, long extra) { - return (int) call(code, extra); - } - } - - private static class TruffleNFI_GetCaptureNamesNode extends TruffleNFI_DownCallNode implements GetCaptureNamesNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.getcapturenames; - } - - @Override - public String[] execute(long code, long extra, int captureCount) { - CaptureNamesResult data = new CaptureNamesResult(captureCount); - int result = (int) call(data, code, extra); - if (result < 0) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(RError.NO_CALLER, RError.Message.WRONG_PCRE_INFO, result); - } else { - return data.getCaptureNames(); - } - } - } - - private static class TruffleNFI_CompileNode extends TruffleNFI_DownCallNode implements CompileNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.compile; - } - - @Override - public Result execute(String pattern, int options, long tables) { - CompileResult data = new CompileResult(); - call(data, pattern, options, tables); - return data.getResult(); - } - } - - private static class TruffleNFI_ExecNode extends TruffleNFI_DownCallNode implements ExecNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.exec; - } - - @Override - public int execute(long code, long extra, String subject, int offset, int options, int[] ovector) { - byte[] subjectBytes = subject.getBytes(StandardCharsets.UTF_8); - return (int) call(code, extra, JavaInterop.asTruffleObject(subjectBytes), subjectBytes.length, offset, options, ovector, ovector.length); - } - } - - @Override - public MaketablesNode createMaketablesNode() { - return new TruffleNFI_MaketablesNode(); - } - - @Override - public CompileNode createCompileNode() { - return new TruffleNFI_CompileNode(); - } - - @Override - public GetCaptureCountNode createGetCaptureCountNode() { - return new TruffleNFI_GetCaptureCountNode(); - } - - @Override - public GetCaptureNamesNode createGetCaptureNamesNode() { - return new TruffleNFI_GetCaptureNamesNode(); - } - - @Override - public StudyNode createStudyNode() { - throw RInternalError.unimplemented(); - } - - @Override - public ExecNode createExecNode() { - return new TruffleNFI_ExecNode(); - } -} 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.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Stats.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Stats.java deleted file mode 100644 index 86a8ce5bf347346ffc3aaf48f0908e5a5a058d50..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Stats.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 - * 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.r.runtime.ffi.NativeFunction; -import com.oracle.truffle.r.runtime.ffi.StatsRFFI; - -public class TruffleNFI_Stats implements StatsRFFI { - - private static class TruffleNFI_FactorNode extends TruffleNFI_DownCallNode implements FactorNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.fft_factor; - } - - @Override - public void execute(int n, int[] pmaxf, int[] pmaxp) { - call(n, pmaxf, pmaxp); - } - } - - private static class TruffleNFI_WorkNode extends TruffleNFI_DownCallNode implements WorkNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.fft_work; - } - - @Override - public int execute(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork) { - return (int) call(a, nseg, n, nspn, isn, work, iwork); - } - } - - private static class TruffleNFI_LminflNode extends TruffleNFI_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) { - call(x, ldx, n, k, docoef, qraux, resid, hat, coef, sigma, tol); - } - } - - @Override - public FactorNode createFactorNode() { - return new TruffleNFI_FactorNode(); - } - - @Override - public WorkNode createWorkNode() { - return new TruffleNFI_WorkNode(); - } - - @Override - public LminflNode createLminflNode() { - return new TruffleNFI_LminflNode(); - } -} 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 deleted file mode 100644 index ca3cebfcfc3afcecddff9b59c82236f861f7267b..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Tools.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 - * 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.r.ffi.impl.common.Generic_Tools; -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.env.REnvironment; -import com.oracle.truffle.r.runtime.ffi.ToolsRFFI; - -public class TruffleNFI_Tools implements ToolsRFFI { - - private static class TruffleNFI_ToolsRFFINode extends Generic_Tools.Generic_ToolsRFFINode { - - @Override - public Object execute(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros, - RLogicalVector warndups) { - return super.execute(con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups); - } - } - - @Override - public ParseRdNode createParseRdNode() { - return new TruffleNFI_ToolsRFFINode(); - } -} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Zip.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Zip.java deleted file mode 100644 index c3340a66c97ae4b8aede53b9fb21cde3e3b2dd0a..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Zip.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 - * 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.interop.java.JavaInterop; -import com.oracle.truffle.r.runtime.ffi.NativeFunction; -import com.oracle.truffle.r.runtime.ffi.ZipRFFI; - -public class TruffleNFI_Zip implements ZipRFFI { - - private static class TruffleNFI_CompressNode extends TruffleNFI_DownCallNode implements ZipRFFI.CompressNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.compress; - } - - @Override - public int execute(byte[] dest, byte[] source) { - return (int) call(JavaInterop.asTruffleObject(dest), (long) dest.length, JavaInterop.asTruffleObject(source), source.length); - } - } - - private static class TruffleNFI_UncompressNode extends TruffleNFI_DownCallNode implements ZipRFFI.UncompressNode { - @Override - protected NativeFunction getFunction() { - return NativeFunction.uncompress; - } - - @Override - public int execute(byte[] dest, byte[] source) { - return (int) call(JavaInterop.asTruffleObject(dest), (long) dest.length, JavaInterop.asTruffleObject(source), source.length); - } - } - - @Override - public CompressNode createCompressNode() { - return new TruffleNFI_CompressNode(); - } - - @Override - public UncompressNode createUncompressNode() { - return new TruffleNFI_UncompressNode(); - } -} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/DirChmod.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/DirChmod.java index 38bc4c0ad22ad375ff0353bb898501f73dfaa44d..3622ed37c173e237a26414a2e7c5b32d3601c496 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/DirChmod.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/DirChmod.java @@ -5,7 +5,7 @@ * * Copyright (c) 1995-2015, 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. */ @@ -27,11 +27,11 @@ 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.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.runtime.FileSystemUtils; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.ffi.BaseRFFI; public abstract class DirChmod extends RExternalBuiltinNode.Arg2 { @@ -46,8 +46,6 @@ public abstract class DirChmod extends RExternalBuiltinNode.Arg2 { casts.arg(1).asLogicalVector().findFirst(RRuntime.LOGICAL_FALSE).map(toBoolean()); } - @Child private BaseRFFI.ChmodNode chmodNode = BaseRFFI.ChmodNode.create(); - @Specialization @TruffleBoundary protected RNull dirChmod(String pathName, boolean setGroupWrite) { @@ -69,7 +67,7 @@ public abstract class DirChmod extends RExternalBuiltinNode.Arg2 { int elementMode = Utils.intFilePermissions(pfa.permissions()); int newMode = Files.isDirectory(element) ? elementMode | dirMask : elementMode | fileMask; // System.out.printf("path %s: old %o, new %o%n", element, elementMode, newMode); - chmodNode.execute(element.toString(), newMode); + FileSystemUtils.chmod(element.toString(), newMode); } } catch (IOException ex) { // ignore diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/base_rffi.c b/com.oracle.truffle.r.native/fficall/src/truffle_common/base_rffi.c index db79b2215ba6b5029038ba6705ce42c0bb802a79..73fc274caa466d2c1e57c5d868bebe252520076c 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_common/base_rffi.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/base_rffi.c @@ -46,10 +46,6 @@ int call_base_chdir(char *dir) { return chdir(dir); } -int call_base_mkdir(char *dir, int mode) { - return mkdir(dir, mode); -} - int call_base_mkdtemp(char *template) { char *r = mkdtemp(template); if (r == NULL) { @@ -59,10 +55,6 @@ int call_base_mkdtemp(char *template) { } } -int call_base_chmod(char *path, int mode) { - return chmod(path, mode); -} - void call_base_uname(void (*call_uname_setfields)(char *sysname, char *release, char *version, char *machine, char *nodename)) { struct utsname name; 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 147982d7a0f0fb133b2a6ef6eb354b9f4ac199eb..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; @@ -503,23 +503,16 @@ void R_runHandlers(InputHandler *handlers, fd_set *mask) { // ----------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------- -// Downcalls from Java. We invoke these functions via .Call interface so that the callbacks -// variable gets properly initialized and in general the R API is available. These functions -// delegate to user provided C routines that may want to access the R API. -// NOTE: those two functions are looked up by name! +// Downcalls from Java. We invoke these functions via REmbedRFFI -SEXP invokeCleanUp(SEXP x, SEXP y, SEXP z) { - ptr_R_CleanUp(Rf_asInteger(x), Rf_asInteger(y), Rf_asInteger(z)); - return R_NilValue; +void rembedded_cleanup(int x, int y, int z) { + ptr_R_CleanUp(x, y, z); } -SEXP invokeSuicide(SEXP msg) { - ptr_R_Suicide(R_CHAR(STRING_ELT(msg, 0))); - return R_NilValue; +void rembedded_suicide(char* msg) { + ptr_R_Suicide(msg); } -// TODO: these 3 are not yet invoked via .Call - void rembedded_write_console(char *cbuf, int len) { writeConsoleImpl(cbuf, len, 0); } @@ -529,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.native/version.source b/com.oracle.truffle.r.native/version.source index 95f9650f0151d7c0d3aecf40355d88effbd5b7a7..e373ee695f6e76d7d3f8f8c4e92d1d60995352e5 100644 --- a/com.oracle.truffle.r.native/version.source +++ b/com.oracle.truffle.r.native/version.source @@ -1 +1 @@ -49 +50 diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java index 8dacc87f84f7ace1d6b955df48b6959c128204ac..45461997df5e49761b91fe8ffce544761b4cac25 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java @@ -63,6 +63,7 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClass import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; +import com.oracle.truffle.r.runtime.FileSystemUtils; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RInternalError; @@ -81,7 +82,6 @@ import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.ffi.BaseRFFI; // Much of this code was influences/transcribed from GnuR src/main/platform.c @@ -1210,8 +1210,6 @@ public class FileFunctions { casts.arg("mode").asIntegerVector().findFirst().mapIf(intNA(), constant(0777)); } - @Child private BaseRFFI.MkdirNode mkdirNode = BaseRFFI.MkdirNode.create(); - @Specialization @TruffleBoundary protected byte dirCreate(String pathIn, boolean showWarnings, boolean recursive, int octMode) { @@ -1247,7 +1245,7 @@ public class FileFunctions { private boolean mkdir(String path, boolean showWarnings, int mode) { try { - mkdirNode.execute(path, mode); + FileSystemUtils.mkdir(path, mode); return true; } catch (IOException ex) { if (showWarnings) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java index 27f194f7e9031c4e03ef06dc8729b38bd3f75360..985bc810a81cc5028e3d71a67b119e224b3040f8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.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 @@ -53,6 +53,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinPackages; +import com.oracle.truffle.r.runtime.FileSystemUtils; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.REnvVars; @@ -300,8 +301,6 @@ public class SysFunctions { casts.arg("use_umask").asLogicalVector().findFirst().mustNotBeNA().map(toBoolean()); } - @Child private BaseRFFI.ChmodNode chmodNode = BaseRFFI.ChmodNode.create(); - @Specialization @TruffleBoundary protected RLogicalVector sysChmod(RAbstractStringVector pathVec, RAbstractIntVector octmode, @SuppressWarnings("unused") boolean useUmask) { @@ -311,7 +310,7 @@ public class SysFunctions { if (path.length() == 0 || RRuntime.isNA(path)) { continue; } - int result = chmodNode.execute(path, octmode.getDataAt(i % octmode.getLength())); + int result = FileSystemUtils.chmod(path, octmode.getDataAt(i % octmode.getLength())); data[i] = RRuntime.asLogical(result == 0); } return RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/FilesystemUtils.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FileSystemUtils.java similarity index 55% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/FilesystemUtils.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FileSystemUtils.java index 5a4a822f7aa4d7e32203f6ae8fcc0afddfdd5683..8d9a196593dcbc57fbbe798bdc4323ab6d62daaf 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/managed/FilesystemUtils.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/FileSystemUtils.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 @@ -20,16 +20,26 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.managed; +package com.oracle.truffle.r.runtime; +import java.io.IOException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.attribute.FileAttribute; import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; import java.util.EnumSet; import java.util.Set; -class FilesystemUtils { +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.r.runtime.RError.Message; + +public class FileSystemUtils { private static PosixFilePermission[] permissionValues = PosixFilePermission.values(); - static Set<PosixFilePermission> permissionsFromMode(int mode) { + private static Set<PosixFilePermission> permissionsFromMode(int mode) { Set<PosixFilePermission> permissions = EnumSet.noneOf(PosixFilePermission.class); for (int i = 0; i < permissionValues.length; i++) { if ((mode & (1 << (permissionValues.length - i - 1))) != 0) { @@ -38,4 +48,20 @@ class FilesystemUtils { } return permissions; } + + @TruffleBoundary + public static int chmod(String path, int mode) { + try { + Files.setPosixFilePermissions(Paths.get(path), permissionsFromMode(mode)); + return mode; + } catch (IOException e) { + throw RError.error(RError.NO_CALLER, Message.GENERIC, "Cannot change file permissions."); + } + } + + @TruffleBoundary + public static void mkdir(String dir, int mode) throws IOException { + Set<PosixFilePermission> permissions = permissionsFromMode(mode); + Files.createDirectory(Paths.get(dir), PosixFilePermissions.asFileAttribute(permissions)); + } } 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/BaseRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java index 4dd512a84a0a8283b8ecb4afed0dfb7e8d053656..a6589707125cfd506561878dc0a2874844a8c0db 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/BaseRFFI.java @@ -26,60 +26,96 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Map; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.NodeInterface; +import com.oracle.truffle.api.interop.java.JavaInterop; +import com.oracle.truffle.r.runtime.ffi.base.ESoftVersionResult; +import com.oracle.truffle.r.runtime.ffi.base.GlobResult; +import com.oracle.truffle.r.runtime.ffi.base.ReadlinkResult; +import com.oracle.truffle.r.runtime.ffi.base.StrtolResult; +import com.oracle.truffle.r.runtime.ffi.base.UnameResult; +import com.oracle.truffle.r.runtime.ffi.interop.NativeCharArray; /** * A statically typed interface to exactly those native functions required by the R {@code base} * package, because the functionality is not provided by the JDK. These methods do not necessarily * map 1-1 to a native function, they may involve the invocation of several native functions. */ -public interface BaseRFFI { +public final class BaseRFFI { - interface GetpidNode extends NodeInterface { - int execute(); + private final DownCallNodeFactory downCallNodeFactory; - static GetpidNode create() { + public BaseRFFI(DownCallNodeFactory downCallNodeFactory) { + this.downCallNodeFactory = downCallNodeFactory; + } + + public static final class GetpidNode extends NativeCallNode { + + private GetpidNode(DownCallNodeFactory parent) { + super(parent.createDownCallNode(NativeFunction.getpid)); + } + + public int execute() { + return (int) call(); + } + + public static GetpidNode create() { return RFFIFactory.getBaseRFFI().createGetpidNode(); } } - interface GetwdNode extends NodeInterface { + public static final class GetwdNode extends NativeCallNode { + private static final int BUFFER_LEN = 4096; + + private GetwdNode(DownCallNodeFactory parent) { + super(parent.createDownCallNode(NativeFunction.getcwd)); + } + /** * Returns the current working directory, in the face of calls to {@code setwd}. */ - String execute(); + public String execute() { + NativeCharArray nativeBuf = NativeCharArray.crateOutputBuffer(BUFFER_LEN); + int result = (int) call(nativeBuf, BUFFER_LEN); + if (result == 0) { + return null; + } else { + return nativeBuf.getStringFromOutputBuffer(); + } + } - static GetwdNode create() { + public static GetwdNode create() { return RFFIFactory.getBaseRFFI().createGetwdNode(); } } - interface SetwdNode extends NodeInterface { + public static final class SetwdNode extends NativeCallNode { + + private SetwdNode(DownCallNodeFactory parent) { + super(parent.createDownCallNode(NativeFunction.chdir)); + } + /** * Sets the current working directory to {@code dir}. (cf. Unix {@code chdir}). * * @return 0 if successful. */ - int execute(String dir); + public int execute(String dir) { + return (int) call(dir); + } - static SetwdNode create() { + public static SetwdNode create() { return RFFIFactory.getBaseRFFI().createSetwdNode(); } } - interface MkdirNode extends NodeInterface { - /** - * Create directory with given mode. Exception is thrown on error. - */ - void execute(String dir, int mode) throws IOException; + public static final class ReadlinkNode extends NativeCallNode { + private static final int EINVAL = 22; - static MkdirNode create() { - return RFFIFactory.getBaseRFFI().createMkdirNode(); + private ReadlinkNode(DownCallNodeFactory parent) { + super(parent.createDownCallNode(NativeFunction.readlink)); } - } - interface ReadlinkNode extends NodeInterface { /** * Try to convert a symbolic link to it's target. * @@ -87,43 +123,75 @@ public interface BaseRFFI { * @return the target if {@code path} is a link else {@code null} * @throws IOException for any other error except "not a link" */ - String execute(String path) throws IOException; + public String execute(String path) throws IOException { + ReadlinkResult data = new ReadlinkResult(); + call(data, path); + if (data.getLink() == null) { + if (data.getErrno() == EINVAL) { + return path; + } else { + // some other error + throw new IOException("readlink failed: " + data.getErrno()); + } + } + return data.getLink(); + } - static ReadlinkNode create() { + public static ReadlinkNode create() { return RFFIFactory.getBaseRFFI().createReadlinkNode(); } } - interface MkdtempNode extends NodeInterface { + public static final class MkdtempNode extends NativeCallNode { + + private MkdtempNode(DownCallNodeFactory parent) { + super(parent.createDownCallNode(NativeFunction.mkdtemp)); + } + /** * Creates a temporary directory using {@code template} and return the resulting path or * {@code null} if error. */ - String execute(String template); + @TruffleBoundary + public String execute(String template) { + /* + * Not only must the (C) string end in XXXXXX it must also be null-terminated. Since it + * is modified by mkdtemp we must make a copy. + */ + NativeCharArray nativeZtbytes = new NativeCharArray(template); + int result = (int) call(nativeZtbytes); + if (result == 0) { + return null; + } else { + return nativeZtbytes.getString(); + } + } - static MkdtempNode create() { + public static MkdtempNode create() { return RFFIFactory.getBaseRFFI().createMkdtempNode(); } } - interface ChmodNode extends NodeInterface { - /** - * Change the file mode of {@code path}. - */ - int execute(String path, int mode); + public static final class StrtolNode extends NativeCallNode { - static ChmodNode create() { - return RFFIFactory.getBaseRFFI().createChmodNode(); + private StrtolNode(DownCallNodeFactory parent) { + super(parent.createDownCallNode(NativeFunction.strtol)); } - } - interface StrtolNode extends NodeInterface { /** * Convert string to long. */ - long execute(String s, int base) throws IllegalArgumentException; + public long execute(String s, int base) throws IllegalArgumentException { + StrtolResult data = new StrtolResult(); + call(data, s, base); + if (data.getErrno() != 0) { + throw new IllegalArgumentException("strtol failure"); + } else { + return data.getResult(); + } + } - static StrtolNode create() { + public static StrtolNode create() { return RFFIFactory.getBaseRFFI().createStrtolNode(); } } @@ -140,71 +208,105 @@ public interface BaseRFFI { String nodename(); } - interface UnameNode extends NodeInterface { + public static final class UnameNode extends NativeCallNode { + + private UnameNode(DownCallNodeFactory parent) { + super(parent.createDownCallNode(NativeFunction.uname)); + } + /** * Return {@code utsname} info. */ - UtsName execute(); + public UtsName execute() { + UnameResult data = new UnameResult(); + call(data); + return data; + } - static UnameNode create() { + public static UnameNode create() { return RFFIFactory.getBaseRFFI().createUnameNode(); } } - interface GlobNode extends NodeInterface { + public static final class GlobNode extends NativeCallNode { + + private GlobNode(DownCallNodeFactory parent) { + super(parent.createDownCallNode(NativeFunction.glob)); + } + /** * Returns an array of pathnames that match {@code pattern} using the OS glob function. This * is done in native code because it is very hard to write in Java in the face of * {@code setwd}. */ - ArrayList<String> glob(String pattern); + public ArrayList<String> glob(String pattern) { + GlobResult data = new GlobResult(); + call(data, pattern); + return data.getPaths(); + } - static GlobNode create() { + public static GlobNode create() { return RFFIFactory.getBaseRFFI().createGlobNode(); } } - interface ESoftVersionNode extends NodeInterface { - Map<String, String> eSoftVersion(); + public static final class ESoftVersionNode extends NativeCallNode { - static ESoftVersionNode create() { - return RFFIFactory.getBaseRFFI().createESoftVersionNode(); + private ESoftVersionNode(DownCallNodeFactory parent) { + super(parent.createDownCallNode(NativeFunction.eSoftVersion)); } - } - /* - * The RFFI implementation influences exactly what subclass of the above nodes is created. Each - * implementation must therefore, implement these methods that are called by the associated - * "public static create()" methods above. - */ - - GetpidNode createGetpidNode(); + public Map<String, String> eSoftVersion() { + ESoftVersionResult result = new ESoftVersionResult(); + call(result); + return result.getVersions(); + } - GetwdNode createGetwdNode(); + public static ESoftVersionNode create() { + return RFFIFactory.getBaseRFFI().createESoftVersionNode(); + } + } - SetwdNode createSetwdNode(); + public GetpidNode createGetpidNode() { + return new GetpidNode(downCallNodeFactory); + } - MkdirNode createMkdirNode(); + public GetwdNode createGetwdNode() { + return new GetwdNode(downCallNodeFactory); + } - ReadlinkNode createReadlinkNode(); + public SetwdNode createSetwdNode() { + return new SetwdNode(downCallNodeFactory); + } - MkdtempNode createMkdtempNode(); + public ReadlinkNode createReadlinkNode() { + return new ReadlinkNode(downCallNodeFactory); + } - ChmodNode createChmodNode(); + public MkdtempNode createMkdtempNode() { + return new MkdtempNode(downCallNodeFactory); + } - StrtolNode createStrtolNode(); + public StrtolNode createStrtolNode() { + return new StrtolNode(downCallNodeFactory); + } - UnameNode createUnameNode(); + public UnameNode createUnameNode() { + return new UnameNode(downCallNodeFactory); + } - GlobNode createGlobNode(); + public GlobNode createGlobNode() { + return new GlobNode(downCallNodeFactory); + } - ESoftVersionNode createESoftVersionNode(); + public ESoftVersionNode createESoftVersionNode() { + return new ESoftVersionNode(downCallNodeFactory); + } /* * Some functions are called from non-Truffle contexts, which requires a RootNode */ - - final class GetpidRootNode extends RFFIRootNode<GetpidNode> { + public static final class GetpidRootNode extends RFFIRootNode<GetpidNode> { private GetpidRootNode() { super(RFFIFactory.getBaseRFFI().createGetpidNode()); @@ -220,7 +322,7 @@ public interface BaseRFFI { } } - final class GetwdRootNode extends RFFIRootNode<GetwdNode> { + public static final class GetwdRootNode extends RFFIRootNode<GetwdNode> { private GetwdRootNode() { super(RFFIFactory.getBaseRFFI().createGetwdNode()); @@ -236,7 +338,7 @@ public interface BaseRFFI { } } - final class MkdtempRootNode extends RFFIRootNode<MkdtempNode> { + public static final class MkdtempRootNode extends RFFIRootNode<MkdtempNode> { private MkdtempRootNode() { super(RFFIFactory.getBaseRFFI().createMkdtempNode()); @@ -253,7 +355,7 @@ public interface BaseRFFI { } } - final class UnameRootNode extends RFFIRootNode<UnameNode> { + public static final class UnameRootNode extends RFFIRootNode<UnameNode> { private UnameRootNode() { super(RFFIFactory.getBaseRFFI().createUnameNode()); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DownCallNodeFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DownCallNodeFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..af484e9aeee40bfe2225c722bcae3ca0569b6dfd --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DownCallNodeFactory.java @@ -0,0 +1,107 @@ +/* + * 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.ffi; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +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; + +/** + * Factory for RFFI implementation specific {@link DownCallNode} which is responsible for + * implementing the invocation of functions from {@link NativeFunction}. + */ +public abstract class DownCallNodeFactory { + public abstract DownCallNode createDownCallNode(NativeFunction function); + + /** + * This node has RFFI backend (LLVM/NFI) specific implementation and its purpose is to provide + * functionality to invoke functions from {@link NativeFunction}. + */ + public abstract static class DownCallNode extends Node { + + private final NativeFunction function; + @Child private Node message; + // TODO: can this be really shared across contexts? + @CompilationFinal private TruffleObject target; + + protected DownCallNode(NativeFunction function) { + assert function != null; + this.function = function; + } + + /** + * The arguments may contain primitive java types, Strings, arrays of any primitive Java + * types, {@link TruffleObject}s, + * {@link com.oracle.truffle.r.runtime.ffi.interop.NativeCharArray}s and + * {@link com.oracle.truffle.r.runtime.ffi.interop.NativeRawArray}s. {@link TruffleObject} + * should be passed to LLVM/NFI as is. + * {@link com.oracle.truffle.r.runtime.ffi.interop.NativeRawArray} and + * {@link com.oracle.truffle.r.runtime.ffi.interop.NativeCharArray} have special handling in + * NFI where the array should be passed as Java array, not as Truffle Object. + */ + public final Object call(Object... args) { + long before = -1; + try { + if (message == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + message = insert(Message.createExecute(function.getArgumentCount()).createNode()); + } + if (target == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + target = getTarget(function); + } + before = beforeCall(function, target, args); + return ForeignAccess.sendExecute(message, target, args); + } catch (InteropException e) { + throw RInternalError.shouldNotReachHere(e); + } finally { + afterCall(before, function, target, args); + } + } + + /** + * Should return a {@link TruffleObject} that will invoke the given function upon the + * {@code EXECUTE} message. + */ + protected abstract TruffleObject getTarget(NativeFunction function); + + /** + * Allows to transform the arguments before the execute message is sent to the result of + * {@link #getTarget(NativeFunction)}. + */ + protected abstract long beforeCall(NativeFunction nativeFunction, TruffleObject function, Object[] args); + + /** + * Allows to post-process the arguments after the execute message was sent to the result of + * {@link #getTarget(NativeFunction)}. If the call to + * {@link #beforeCall(NativeFunction, TruffleObject, Object[])} was not successfull, the + * {@code before} parameter will have value {@code -1}. + */ + protected abstract void afterCall(long before, NativeFunction function, TruffleObject target, Object[] args); + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LapackRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LapackRFFI.java index eaff8035fce6dcb980593fdf3c8c2ebfbe27a2df..ff82db0fafbdbdfb456ba01b51c91b66a6835652 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LapackRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LapackRFFI.java @@ -22,232 +22,343 @@ */ package com.oracle.truffle.r.runtime.ffi; -import com.oracle.truffle.api.nodes.NodeInterface; - /** * Collection of statically typed Lapack methods that are used in the {@code base} package. The * signatures match the Fortran definition with the exception that the "info" value is returned as * the result of the call. + * + * The documentation for individual functions can be found in the + * <a href="http://www.netlib.org/lapack/explore-html">spec</a>. */ -public interface LapackRFFI { - interface IlaverNode extends NodeInterface { - /** - * Return version info, mjor, minor, patch, in {@code version}. - */ - void execute(int[] version); - - static IlaverNode create() { +public final class LapackRFFI { + private final DownCallNodeFactory downCallNodeFactory; + + public LapackRFFI(DownCallNodeFactory downCallNodeFactory) { + this.downCallNodeFactory = downCallNodeFactory; + } + + public static final class IlaverNode extends NativeCallNode { + public static IlaverNode create() { return RFFIFactory.getLapackRFFI().createIlaverNode(); } + + private IlaverNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.ilaver)); + } + + public void execute(int[] version) { + call((Object) version); + } } - interface DgeevNode extends NodeInterface { - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d9/d28/dgeev_8f.html">spec</a>. - */ - int execute(char jobVL, char jobVR, int n, double[] a, int lda, double[] wr, double[] wi, double[] vl, int ldvl, double[] vr, int ldvr, double[] work, int lwork); + public static final class DgeevNode extends NativeCallNode { - static DgeevNode create() { + public static DgeevNode create() { return RFFIFactory.getLapackRFFI().createDgeevNode(); } + + private DgeevNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dgeev)); + } + + public int execute(char jobVL, char jobVR, int n, double[] a, int lda, double[] wr, double[] wi, double[] vl, int ldvl, double[] vr, int ldvr, double[] work, int lwork) { + return (int) call(jobVL, jobVR, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork); + } } - interface Dgeqp3Node extends NodeInterface { - /** - * See <a href="http://www.netlib.org/lapack/explore-html/db/de5/dgeqp3_8f.html">spec</a>. - */ - int execute(int m, int n, double[] a, int lda, int[] jpvt, double[] tau, double[] work, int lwork); + public static final class Dgeqp3Node extends NativeCallNode { - static Dgeqp3Node create() { + public static Dgeqp3Node create() { return RFFIFactory.getLapackRFFI().createDgeqp3Node(); } + + private Dgeqp3Node(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dgeqp3)); + } + + public int execute(int m, int n, double[] a, int lda, int[] jpvt, double[] tau, double[] work, int lwork) { + return (int) call(m, n, a, lda, jpvt, tau, work, lwork); + } } - interface DormqrNode extends NodeInterface { - /** - * See <a href="http://www.netlib.org/lapack/explore-html/da/d82/dormqr_8f.html">spec</a>. - */ - int execute(char side, char trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork); + public static final class DormqrNode extends NativeCallNode { - static DormqrNode create() { + public static DormqrNode create() { return RFFIFactory.getLapackRFFI().createDormqrNode(); } - } - interface DtrtrsNode extends NodeInterface { + private DormqrNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dormq)); + } - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d6/d6f/dtrtrs_8f.html">spec</a>. - */ - int execute(char uplo, char trans, char diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb); + public int execute(char side, char trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork) { + return (int) call(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork); + } + } - static DtrtrsNode create() { + public static final class DtrtrsNode extends NativeCallNode { + + public static DtrtrsNode create() { return RFFIFactory.getLapackRFFI().createDtrtrsNode(); } - } - interface DgetrfNode extends NodeInterface { + private DtrtrsNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dtrtrs)); + } + + public int execute(char uplo, char trans, char diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb) { + return (int) call(uplo, trans, diag, n, nrhs, a, lda, b, ldb); + } + } - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d3/d6a/dgetrf_8f.html">spec</a>. - */ - int execute(int m, int n, double[] a, int lda, int[] ipiv); + public static final class DgetrfNode extends NativeCallNode { - static DgetrfNode create() { + public static DgetrfNode create() { return RFFIFactory.getLapackRFFI().createDgetrfNode(); } - } - interface DpotrfNode extends NodeInterface { + private DgetrfNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dgetrf)); + } - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d0/d8a/dpotrf_8f.html">spec</a>. - */ - int execute(char uplo, int n, double[] a, int lda); + public int execute(int m, int n, double[] a, int lda, int[] ipiv) { + return (int) call(m, n, a, lda, ipiv); + } + } - static DpotrfNode create() { + public static final class DpotrfNode extends NativeCallNode { + + public static DpotrfNode create() { return RFFIFactory.getLapackRFFI().createDpotrfNode(); } - } - interface DpotriNode extends NodeInterface { + private DpotrfNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dpotrf)); + } - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d0/d8a/dpotri_8f.html">spec</a>. - */ - int execute(char uplo, int n, double[] a, int lda); + public int execute(char uplo, int n, double[] a, int lda) { + return (int) call(uplo, n, a, lda); + } + } + + public static final class DpotriNode extends NativeCallNode { - static DpotriNode create() { + public static DpotriNode create() { return RFFIFactory.getLapackRFFI().createDpotriNode(); } + + private DpotriNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dpotri)); + } + + public int execute(char uplo, int n, double[] a, int lda) { + return (int) call(uplo, n, a, lda); + } } - interface DpstrfNode extends NodeInterface { - /** - * See <a href="http://www.netlib.org/lapack/explore-html/dd/dad/dpstrf_8f.html">spec</a>. - */ - int execute(char uplo, int n, double[] a, int lda, int[] piv, int[] rank, double tol, double[] work); + public static final class DpstrfNode extends NativeCallNode { - static DpstrfNode create() { + public static DpstrfNode create() { return RFFIFactory.getLapackRFFI().createDpstrfNode(); } + + private DpstrfNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dpstrf)); + } + + public int execute(char uplo, int n, double[] a, int lda, int[] piv, int[] rank, double tol, double[] work) { + return (int) call(uplo, n, a, lda, piv, rank, tol, work); + } } - interface DgesvNode extends NodeInterface { - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d8/d72/dgesv_8f.html">spec</a>. - */ - int execute(int n, int nrhs, double[] a, int lda, int[] ipiv, double[] b, int ldb); + public static final class DgesvNode extends NativeCallNode { - static DgesvNode create() { + public static DgesvNode create() { return RFFIFactory.getLapackRFFI().createDgesvNode(); } + + private DgesvNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dgesv)); + } + + public int execute(int n, int nrhs, double[] a, int lda, int[] ipiv, double[] b, int ldb) { + return (int) call(n, nrhs, a, lda, ipiv, b, ldb); + } } - interface DgesddNode extends NodeInterface { - /** - * See <a href="http://www.netlib.org/lapack/explore-html/db/db4/dgesdd_8f.html">spec</a>. - */ - int execute(char jobz, int m, int n, double[] a, int lda, double[] s, double[] u, int ldu, double[] vt, int ldtv, double[] work, int lwork, int[] iwork); + public static final class DgesddNode extends NativeCallNode { - static DgesddNode create() { + public static DgesddNode create() { return RFFIFactory.getLapackRFFI().createDgesddNode(); } - } - interface DlangeNode extends NodeInterface { + private DgesddNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dgesdd)); + } + + public int execute(char jobz, int m, int n, double[] a, int lda, double[] s, double[] u, int ldu, double[] vt, int ldtv, double[] work, int lwork, int[] iwork) { + return (int) call(jobz, m, n, a, lda, s, u, ldu, vt, ldtv, work, lwork, iwork); + } + } - /** - * See <a href="http://www.netlib.org/lapack/explore-html/dc/d09/dlange_8f.html">spec</a>. - */ - double execute(char norm, int m, int n, double[] a, int lda, double[] work); + public static final class DlangeNode extends NativeCallNode { - static DlangeNode create() { + public static DlangeNode create() { return RFFIFactory.getLapackRFFI().createDlangeNode(); } - } - interface DgeconNode extends NodeInterface { + private DlangeNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dlange)); + } + + public double execute(char norm, int m, int n, double[] a, int lda, double[] work) { + return (double) call(norm, m, n, a, lda, work); + } + } - /** - * See <a href="http://www.netlib.org/lapack/explore-html/db/de4/dgecon_8f.html">spec</a>. - */ - int execute(char norm, int n, double[] a, int lda, double anorm, double[] rcond, double[] work, int[] iwork); + public static final class DgeconNode extends NativeCallNode { - static DgeconNode create() { + public static DgeconNode create() { return RFFIFactory.getLapackRFFI().createDgeconNode(); } - } - interface DsyevrNode extends NodeInterface { + private DgeconNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dgecon)); + } + + public int execute(char norm, int n, double[] a, int lda, double anorm, double[] rcond, double[] work, int[] iwork) { + return (int) call(norm, n, a, lda, anorm, rcond, work, iwork); + } + } - int execute(char jobz, char range, char uplo, int n, double[] a, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, double[] w, double[] z, int ldz, int[] isuppz, - double[] work, int lwork, int[] iwork, int liwork); + public static final class DsyevrNode extends NativeCallNode { - static DsyevrNode create() { + public static DsyevrNode create() { return RFFIFactory.getLapackRFFI().createDsyevrNode(); } - } - interface ZunmqrNode extends NodeInterface { + private DsyevrNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dsyevr)); + } + + public int execute(char jobz, char range, char uplo, int n, double[] a, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, double[] w, double[] z, int ldz, int[] isuppz, + double[] work, int lwork, int[] iwork, int liwork) { + return (int) call(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, isuppz, work, lwork, iwork, liwork); + } + } - int execute(String side, String trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork); + public static final class ZunmqrNode extends NativeCallNode { - static ZunmqrNode create() { + public static ZunmqrNode create() { return RFFIFactory.getLapackRFFI().createZunmqrNode(); } - } - interface ZtrtrsNode extends NodeInterface { + private ZunmqrNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.zunmqr)); + } - int execute(String uplo, String trans, String diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb); + public int execute(String side, String trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork) { + return (int) call(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork); + } - static ZtrtrsNode create() { + } + + public static final class ZtrtrsNode extends NativeCallNode { + + public static ZtrtrsNode create() { return RFFIFactory.getLapackRFFI().createZtrtrsNode(); } - } - interface DtrsmNode extends NodeInterface { + private ZtrtrsNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.ztrtrs)); + } - void execute(String side, String uplo, String transa, String diag, int m, int n, double alpha, double[] a, int lda, double[] b, int ldb); + public int execute(String uplo, String trans, String diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb) { + return (int) call(uplo, trans, diag, n, nrhs, a, lda, b, ldb); + } + } + + public static final class DtrsmNode extends NativeCallNode { - static DtrsmNode create() { + public static DtrsmNode create() { return RFFIFactory.getLapackRFFI().createDtrsmNode(); } - } - IlaverNode createIlaverNode(); + private DtrsmNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dtrsm)); + } - DgeevNode createDgeevNode(); + public void execute(String side, String uplo, String transa, String diag, int m, int n, double alpha, double[] a, int lda, double[] b, int ldb) { + call(side, uplo, transa, diag, m, n, alpha, a, lda, b, ldb); + } - Dgeqp3Node createDgeqp3Node(); + } - DormqrNode createDormqrNode(); + public IlaverNode createIlaverNode() { + return new IlaverNode(downCallNodeFactory); + } - DtrtrsNode createDtrtrsNode(); + public DgeevNode createDgeevNode() { + return new DgeevNode(downCallNodeFactory); + } - DgetrfNode createDgetrfNode(); + public Dgeqp3Node createDgeqp3Node() { + return new Dgeqp3Node(downCallNodeFactory); + } - DpotrfNode createDpotrfNode(); + public DormqrNode createDormqrNode() { + return new DormqrNode(downCallNodeFactory); + } - DpotriNode createDpotriNode(); + public DtrtrsNode createDtrtrsNode() { + return new DtrtrsNode(downCallNodeFactory); + } - DpstrfNode createDpstrfNode(); + public DgetrfNode createDgetrfNode() { + return new DgetrfNode(downCallNodeFactory); + } - DgesvNode createDgesvNode(); + public DpotrfNode createDpotrfNode() { + return new DpotrfNode(downCallNodeFactory); + } - DgesddNode createDgesddNode(); + public DpotriNode createDpotriNode() { + return new DpotriNode(downCallNodeFactory); + } + + public DpstrfNode createDpstrfNode() { + return new DpstrfNode(downCallNodeFactory); + } - DlangeNode createDlangeNode(); + public DgesvNode createDgesvNode() { + return new DgesvNode(downCallNodeFactory); + } + + public DgesddNode createDgesddNode() { + return new DgesddNode(downCallNodeFactory); + } - DgeconNode createDgeconNode(); + public DlangeNode createDlangeNode() { + return new DlangeNode(downCallNodeFactory); + } - DsyevrNode createDsyevrNode(); + public DgeconNode createDgeconNode() { + return new DgeconNode(downCallNodeFactory); + } - ZunmqrNode createZunmqrNode(); + public DsyevrNode createDsyevrNode() { + return new DsyevrNode(downCallNodeFactory); + } - ZtrtrsNode createZtrtrsNode(); + public ZunmqrNode createZunmqrNode() { + return new ZunmqrNode(downCallNodeFactory); + } - DtrsmNode createDtrsmNode(); + public ZtrtrsNode createZtrtrsNode() { + return new ZtrtrsNode(downCallNodeFactory); + } + public DtrsmNode createDtrsmNode() { + return new DtrsmNode(downCallNodeFactory); + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/MiscRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/MiscRFFI.java index 9fb02a1e8ebb16bb3e11e874ad010d1e8ff8da6a..12d634f4f64e78d2f5841b19e9c3cc0e3e2fac77 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/MiscRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/MiscRFFI.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 @@ -22,30 +22,50 @@ */ package com.oracle.truffle.r.runtime.ffi; -import com.oracle.truffle.api.nodes.NodeInterface; - /** * Miscellaneous methods implemented in native code. * */ -public interface MiscRFFI { - interface ExactSumNode extends NodeInterface { - double execute(double[] values, boolean hasNa, boolean naRm); +public final class MiscRFFI { + private final DownCallNodeFactory downCallNodeFactory; + + public MiscRFFI(DownCallNodeFactory downCallNodeFactory) { + this.downCallNodeFactory = downCallNodeFactory; + } + + public static final class ExactSumNode extends NativeCallNode { + private ExactSumNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.exactSumFunc)); + } + + public double execute(double[] values, boolean hasNa, boolean naRm) { + return (double) call(values, values.length, hasNa ? 1 : 0, naRm ? 1 : 0); + } - static ExactSumNode create() { + public static ExactSumNode create() { return RFFIFactory.getMiscRFFI().createExactSumNode(); } } - interface DqrlsNode extends NodeInterface { - void execute(double[] x, int n, int p, double[] y, int ny, double tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work); + public static final class DqrlsNode extends NativeCallNode { + private DqrlsNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.dqrls)); + } + + public void execute(double[] x, int n, int p, double[] y, int ny, double tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work) { + call(x, n, p, y, ny, tol, b, rsd, qty, k, jpvt, qraux, work); + } - static DqrlsNode create() { + public static DqrlsNode create() { return RFFIFactory.getMiscRFFI().createDqrlsNode(); } } - ExactSumNode createExactSumNode(); + public ExactSumNode createExactSumNode() { + return new ExactSumNode(downCallNodeFactory); + } - DqrlsNode createDqrlsNode(); + public DqrlsNode createDqrlsNode() { + return new DqrlsNode(downCallNodeFactory); + } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeCharArray.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeCallNode.java similarity index 62% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeCharArray.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeCallNode.java index cbba5538b356b1c9f3d4448752e3654e34318916..c192214100f7f8141e5ad9f325eb3c7a9ebb98b3 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeCharArray.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeCallNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 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 @@ -20,23 +20,22 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop; +package com.oracle.truffle.r.runtime.ffi; -import com.oracle.truffle.api.interop.ForeignAccess; -import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; /** - * A {@link TruffleObject} that represents an array of {@code unsigned char} values, that is - * {@code NULL} terminated in the C domain. + * Convenient base class for nodes invoking + * {@link com.oracle.truffle.r.runtime.ffi.DownCallNodeFactory.DownCallNode}. */ -public final class NativeCharArray extends NativeUInt8Array { +public class NativeCallNode extends Node { + @Child private DownCallNodeFactory.DownCallNode downCallNode; - public NativeCharArray(byte[] bytes) { - super(bytes, true); + public NativeCallNode(DownCallNodeFactory.DownCallNode downCallNode) { + this.downCallNode = downCallNode; } - @Override - public ForeignAccess getForeignAccess() { - return NativeCharArrayMRForeign.ACCESS; + protected Object call(Object... args) { + return downCallNode.call(args); } } 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 f30a5dfbf4854a96bab0cbe6633a37fde148360f..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 @@ -36,10 +36,8 @@ public enum NativeFunction { getpid("(): sint32", "call_base_"), getcwd("([uint8], sint32): sint32", "call_base_"), chdir("(string): sint32", "call_base_"), - mkdir("(string, sint32): sint32", "call_base_"), readlink("((string, sint32): void, string): void", "call_base_"), mkdtemp("([uint8]): sint32", "call_base_"), - chmod("(string, sint32): sint32", "call_base_"), strtol("((sint64, sint32): void, string, sint32): void", "call_base_"), uname("((string, string, string, string, string): void): void", "call_base_"), glob("((string): void, string): void", "call_base_"), @@ -84,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"), - rembedded_write_err_console("(string, sint32):void"), - rembedded_read_console("(string):string"), - rembedded_native_clean_up("(sint32, sint32, sint32):void"), - rembedded_native_suicide("(string):void"), + 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()), @@ -96,6 +96,7 @@ public enum NativeFunction { unif_nseed("(): pointer", "user_", anyLibrary()), unif_seedloc("(): pointer", "user_", anyLibrary()), // memory access helper functions + // TODO: these could use Unsafe instead read_pointer_int("(pointer): sint32", "caccess_"), read_array_int("(pointer, sint64): sint32", "caccess_"), read_pointer_double("(pointer): double", "caccess_"), @@ -111,12 +112,18 @@ public enum NativeFunction { private final String signature; private final int argumentCount; private final String library; + private final boolean complexInteraction; - NativeFunction(String signature, String prefix, String library) { + NativeFunction(String signature, String prefix, String library, boolean complexInteraction) { this.callName = prefix + name(); this.signature = signature; this.argumentCount = getArgCount(signature); this.library = library; + this.complexInteraction = complexInteraction; + } + + NativeFunction(String signature, String prefix, String library) { + this(signature, prefix, library, false); } NativeFunction(String signature, String prefix) { @@ -143,6 +150,15 @@ public enum NativeFunction { return library; } + /** + * Returns {@code true} if the function has complex interaction with its environment, including + * that it is not reentrant, uses R API (e.g. {@code allocVector}), or may invoke arbitrary user + * code. + */ + public boolean hasComplexInteraction() { + return complexInteraction; + } + // Functions because the enum constants cannot refer to static final fields: public static String anyLibrary() { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/PCRERFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/PCRERFFI.java index 90489b5ffc5ac02677c3454379bb3b45015dac57..4bc7d2fc40c411c98f1ecbfd3bdc405ed638fdeb 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/PCRERFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/PCRERFFI.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 @@ -22,22 +22,41 @@ */ package com.oracle.truffle.r.runtime.ffi; -import com.oracle.truffle.api.nodes.NodeInterface; +import java.nio.charset.StandardCharsets; + +import com.oracle.truffle.api.CompilerDirectives; +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.Node; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.ffi.interop.NativeCharArray; +import com.oracle.truffle.r.runtime.ffi.interop.pcre.CaptureNamesResult; +import com.oracle.truffle.r.runtime.ffi.interop.pcre.CompileResult; /** * An interface to the <a href="http://www.pcre.org/original/doc/html/index.html">PCRE</a> library * for Perl regular expressions. */ -public interface PCRERFFI { - int NOTBOL = 0x00000080; - int CASELESS = 0x1; +public final class PCRERFFI { + public static final int NOTBOL = 0x00000080; + public static final int CASELESS = 0x1; + + private final DownCallNodeFactory downCallNodeFactory; + + public PCRERFFI(DownCallNodeFactory downCallNodeFactory) { + this.downCallNodeFactory = downCallNodeFactory; + } /** * PCRE uses call by reference for error-related information, which we encapsulate and sanitize * in this class. The {@code result} value (which is typically an opaque pointer to an internal * C struct), is the actual result of the function as per the PCRE spec. */ - class Result { + public static final class Result { public final long result; public final String errorMessage; public final int errOffset; @@ -49,64 +68,142 @@ public interface PCRERFFI { } } - interface MaketablesNode extends NodeInterface { - long execute(); + public static final class MaketablesNode extends NativeCallNode { + @Child private Node asPointerNode; + + private MaketablesNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.maketables)); + } + + public long execute() { + Object result = call(); + if (result instanceof Long) { + return (long) result; + } + assert result instanceof TruffleObject; + if (asPointerNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + asPointerNode = insert(Message.AS_POINTER.createNode()); + } + try { + return ForeignAccess.sendAsPointer(asPointerNode, (TruffleObject) result); + } catch (UnsupportedMessageException e) { + throw RInternalError.shouldNotReachHere("PCRE function maketables should return long or TruffleObject that represents a pointer."); + } + } - static MaketablesNode create() { + public static MaketablesNode create() { return RFFIFactory.getPCRERFFI().createMaketablesNode(); } } - interface CompileNode extends NodeInterface { - Result execute(String pattern, int options, long tables); + public static final class CompileNode extends NativeCallNode { + private CompileNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.compile)); + } + + public Result execute(String pattern, int options, long tables) { + CompileResult data = new CompileResult(); + call(data, pattern, options, tables); + return data.getResult(); + } - static CompileNode create() { + public static CompileNode create() { return RFFIFactory.getPCRERFFI().createCompileNode(); } } - interface GetCaptureCountNode extends NodeInterface { - int execute(long code, long extra); + public static final class GetCaptureCountNode extends NativeCallNode { + private GetCaptureCountNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.getcapturecount)); + } + + public int execute(long code, long extra) { + return (int) call(code, extra); + } - static GetCaptureCountNode create() { + public static GetCaptureCountNode create() { return RFFIFactory.getPCRERFFI().createGetCaptureCountNode(); } } - interface GetCaptureNamesNode extends NodeInterface { - String[] execute(long code, long extra, int captureCount); + public static final class GetCaptureNamesNode extends NativeCallNode { + private GetCaptureNamesNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.getcapturenames)); + } + + public String[] execute(long code, long extra, int captureCount) { + CaptureNamesResult data = new CaptureNamesResult(captureCount); + int result = (int) call(data, code, extra); + if (result < 0) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(RError.NO_CALLER, RError.Message.WRONG_PCRE_INFO, result); + } else { + return data.getCaptureNames(); + } + } - static GetCaptureNamesNode create() { + public static GetCaptureNamesNode create() { return RFFIFactory.getPCRERFFI().createGetCaptureNamesNode(); } } - interface StudyNode extends NodeInterface { - Result execute(long code, int options); + public static final class StudyNode extends NativeCallNode { + private StudyNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.study)); + } + + public Result execute(long code, int options) { + throw RInternalError.shouldNotReachHere("The factory method should throw unimplemented already"); + } - static StudyNode create() { + public static StudyNode create() { return RFFIFactory.getPCRERFFI().createStudyNode(); } } - interface ExecNode extends NodeInterface { - int execute(long code, long extra, String subject, int offset, int options, int[] ovector); + public static final class ExecNode extends NativeCallNode { + private ExecNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.exec)); + } + + public int execute(long code, long extra, String subject, int offset, int options, int[] ovector) { + byte[] subjectBytes = getBytes(subject); + NativeCharArray subjectChars = new NativeCharArray(subjectBytes); + return (int) call(code, extra, subjectChars, subjectBytes.length, offset, options, ovector, ovector.length); + } + + @TruffleBoundary + private static byte[] getBytes(String subject) { + return subject.getBytes(StandardCharsets.UTF_8); + } - static ExecNode create() { + public static ExecNode create() { return RFFIFactory.getPCRERFFI().createExecNode(); } } - MaketablesNode createMaketablesNode(); - - CompileNode createCompileNode(); + public MaketablesNode createMaketablesNode() { + return new MaketablesNode(downCallNodeFactory); + } - GetCaptureCountNode createGetCaptureCountNode(); + public CompileNode createCompileNode() { + return new CompileNode(downCallNodeFactory); + } - GetCaptureNamesNode createGetCaptureNamesNode(); + public GetCaptureCountNode createGetCaptureCountNode() { + return new GetCaptureCountNode(downCallNodeFactory); + } - StudyNode createStudyNode(); + public GetCaptureNamesNode createGetCaptureNamesNode() { + return new GetCaptureNamesNode(downCallNodeFactory); + } - ExecNode createExecNode(); + public StudyNode createStudyNode() { + throw RInternalError.unimplemented("study function in PCRE"); + } + public ExecNode createExecNode() { + return new ExecNode(downCallNodeFactory); + } } 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); + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java index 5fcbb0417f429677b0e2d52588462c62b953a8db..7bb4b22dbf286d135040a4dc1d80623091f91668 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.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 @@ -22,41 +22,69 @@ */ package com.oracle.truffle.r.runtime.ffi; -import com.oracle.truffle.api.nodes.NodeInterface; - /** * Interface to native (C) methods provided by the {@code stats} package that are used to implement - * {@code.Call(C_fft)}. The implementation is split into a Java part which calls the + * {@code .Call(C_fft)}. The implementation is split into a Java part which calls the * {@code fft_factor} and {@code fft_work}. functions from the GNU R C code. */ -public interface StatsRFFI { - interface FactorNode extends NodeInterface { - void execute(int n, int[] pmaxf, int[] pmaxp); +public final class StatsRFFI { + private final DownCallNodeFactory downCallNodeFactory; + + public StatsRFFI(DownCallNodeFactory downCallNodeFactory) { + this.downCallNodeFactory = downCallNodeFactory; + } + + public static final class FactorNode extends NativeCallNode { + private FactorNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.fft_factor)); + } + + public void execute(int n, int[] pmaxf, int[] pmaxp) { + call(n, pmaxf, pmaxp); + } - static FactorNode create() { + public static FactorNode create() { return RFFIFactory.getStatsRFFI().createFactorNode(); } } - interface WorkNode extends NodeInterface { - int execute(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork); + public static final class WorkNode extends NativeCallNode { + private WorkNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.fft_work)); + } + + public int execute(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork) { + return (int) call(a, nseg, n, nspn, isn, work, iwork); + } - static WorkNode create() { + public static WorkNode create() { return RFFIFactory.getStatsRFFI().createWorkNode(); } } - interface LminflNode extends NodeInterface { - void execute(double[] x, int ldx, int n, int k, int docoef, double[] qraux, double[] resid, double[] hat, double[] coef, double[] sigma, double tol); + public static final class LminflNode extends NativeCallNode { + private LminflNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.lminfl)); + } + + 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) { + call(x, ldx, n, k, docoef, qraux, resid, hat, coef, sigma, tol); + } - static LminflNode create() { + public static LminflNode create() { return RFFIFactory.getStatsRFFI().createLminflNode(); } } - FactorNode createFactorNode(); + public FactorNode createFactorNode() { + return new FactorNode(downCallNodeFactory); + } - WorkNode createWorkNode(); + public WorkNode createWorkNode() { + return new WorkNode(downCallNodeFactory); + } - LminflNode createLminflNode(); + public LminflNode createLminflNode() { + return new LminflNode(downCallNodeFactory); + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ToolsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ToolsRFFI.java index 629bc1a5889deaf3bfc9beaa9784423f32ae5e16..34ef4a966a9d902205ce7a03b932b5fe1b5d8b69 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ToolsRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ToolsRFFI.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 @@ -22,17 +22,30 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInterface; +import com.oracle.truffle.r.runtime.RInternalError; 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.env.REnvironment; +import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; +import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; /** * Interface to native (C) methods provided by the {@code tools} package. */ -public interface ToolsRFFI { - interface ParseRdNode extends NodeInterface { +public final class ToolsRFFI { + public static class ParseRdNode extends Node { + private static final String C_PARSE_RD = "C_parseRd"; + protected static final String TOOLS = "tools"; + + @Child private CallRFFI.InvokeCallNode callRFFINode = RFFIFactory.getCallRFFI().createInvokeCallNode(); + @Child private DLL.RFindSymbolNode findSymbolNode = DLL.RFindSymbolNode.create(); + + @CompilationFinal private NativeCallInfo nativeCallInfo; + /** * This invokes the Rd parser, written in C, and part of GnuR, that does its work using the * R FFI interface. The R code initially invokes this via {@code .External2(C_parseRd, ...)} @@ -41,9 +54,28 @@ public interface ToolsRFFI { * code. We can't go straight to the GnuR C entry point as that makes GnuR-specific * assumptions about, for example, how connections are implemented. */ - Object execute(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros, - RLogicalVector warndups); + public Object execute(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros, + RLogicalVector warndups) { + synchronized (ToolsRFFI.class) { + try { + if (nativeCallInfo == null) { + // lookup entry point (assert library is loaded) + DLLInfo toolsDLLInfo = DLL.findLibrary(TOOLS); + assert toolsDLLInfo != null; + SymbolHandle symbolHandle = findSymbolNode.execute(C_PARSE_RD, TOOLS, DLL.RegisteredNativeSymbol.any()); + assert symbolHandle != DLL.SYMBOL_NOT_FOUND; + nativeCallInfo = new NativeCallInfo(C_PARSE_RD, symbolHandle, toolsDLLInfo); + } + return callRFFINode.dispatch(nativeCallInfo, + new Object[]{con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups}); + } catch (Throwable ex) { + throw RInternalError.shouldNotReachHere(ex, "error during Rd parsing" + ex.getMessage()); + } + } + } } - ParseRdNode createParseRdNode(); + public ParseRdNode createParseRdNode() { + return new ParseRdNode(); + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ZipRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ZipRFFI.java index b02f3fefda00323895da30c32733c2394f1ed0fe..122b0af2d475c5fbceaca8975fca7360d0fc929c 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ZipRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ZipRFFI.java @@ -24,43 +24,77 @@ package com.oracle.truffle.r.runtime.ffi; import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.NodeInterface; import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.ffi.interop.NativeRawArray; /** * zip compression/uncompression. */ -public interface ZipRFFI { +public final class ZipRFFI { + + private final DownCallNodeFactory downCallNodeFactory; + + public ZipRFFI(DownCallNodeFactory downCallNodeFactory) { + this.downCallNodeFactory = downCallNodeFactory; + } + + public static final class CompressNode extends NativeCallNode { + private CompressNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.compress)); + } - interface CompressNode extends NodeInterface { /** * compress {@code source} into {@code dest}. * * @return standard return code (0 ok) */ - int execute(byte[] dest, byte[] source); + public int execute(byte[] dest, byte[] source) { + NativeRawArray nativeDest = new NativeRawArray(dest); + NativeRawArray nativeSource = new NativeRawArray(source); + try { + return (int) call(nativeDest, dest.length, nativeSource, source.length); + } finally { + nativeDest.getValue(); + } + } - static CompressNode create() { + public static CompressNode create() { return RFFIFactory.getZipRFFI().createCompressNode(); } } - interface UncompressNode extends NodeInterface { + public static final class UncompressNode extends NativeCallNode { + private UncompressNode(DownCallNodeFactory factory) { + super(factory.createDownCallNode(NativeFunction.uncompress)); + } + /** * uncompress {@code source} into {@code dest}. * * @return standard return code (0 ok) */ - int execute(byte[] dest, byte[] source); + public int execute(byte[] dest, byte[] source) { + NativeRawArray nativeDest = new NativeRawArray(dest); + NativeRawArray nativeSource = new NativeRawArray(source); + try { + return (int) call(nativeDest, dest.length, nativeSource, source.length); + } finally { + nativeDest.getValue(); + } + } } - CompressNode createCompressNode(); + public CompressNode createCompressNode() { + return new CompressNode(downCallNodeFactory); + } - UncompressNode createUncompressNode(); + public UncompressNode createUncompressNode() { + return new UncompressNode(downCallNodeFactory); + } // RootNodes for calling when not in Truffle context - final class CompressRootNode extends RFFIRootNode<CompressNode> { + public static final class CompressRootNode extends RFFIRootNode<CompressNode> { protected CompressRootNode(CompressNode wrapped) { super(wrapped); } @@ -76,7 +110,7 @@ public interface ZipRFFI { } } - final class UncompressRootNode extends RFFIRootNode<UncompressNode> { + public static final class UncompressRootNode extends RFFIRootNode<UncompressNode> { protected UncompressRootNode(UncompressNode wrapped) { super(wrapped); } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ESoftVersionResult.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ESoftVersionResult.java similarity index 96% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ESoftVersionResult.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ESoftVersionResult.java index a3e8e86c2f81530097ea840db51d5df9eb2b62fe..c4416b12ec5180dc8708aec4f1bf95702306e205 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ESoftVersionResult.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ESoftVersionResult.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.base; +package com.oracle.truffle.r.runtime.ffi.base; import java.util.HashMap; import java.util.Map; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ESoftVersionResultMR.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ESoftVersionResultMR.java similarity index 97% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ESoftVersionResultMR.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ESoftVersionResultMR.java index fc958b7b30ff2f235e3ff12999bb024c86b95d03..6eab2ce42bf835d0243924128675a6968e318a17 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ESoftVersionResultMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ESoftVersionResultMR.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.base; +package com.oracle.truffle.r.runtime.ffi.base; import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/GlobResult.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/GlobResult.java similarity index 92% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/GlobResult.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/GlobResult.java index f16e91a2fd014471506fee031d659465fddc5608..13bbc84cdd403559187bff7e225147e2339e4e6c 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/GlobResult.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/GlobResult.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.base; +package com.oracle.truffle.r.runtime.ffi.base; import java.util.ArrayList; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/GlobResultMR.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/GlobResultMR.java similarity index 94% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/GlobResultMR.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/GlobResultMR.java index 2c7d26e85ebb434f93a49538445f719cba5a7375..1aaf118a5287670f12e1860b28c3a408684ab016 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/GlobResultMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/GlobResultMR.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.base; +package com.oracle.truffle.r.runtime.ffi.base; import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ReadlinkResult.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ReadlinkResult.java similarity index 92% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ReadlinkResult.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ReadlinkResult.java index 266efc5acd98170a936c2be67035fd96826d5183..3466cf3bb0e759f7c740748741b970c1e06b8dc0 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ReadlinkResult.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ReadlinkResult.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.base; +package com.oracle.truffle.r.runtime.ffi.base; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.r.runtime.data.RTruffleObject; 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.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ReadlinkResultMR.java similarity index 98% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ReadlinkResultMR.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ReadlinkResultMR.java index c17152410ed4da5918bf3224085f47774076a21e..98e1f175a90e5fca475665fb9814437725f7f2cf 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/ReadlinkResultMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/ReadlinkResultMR.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.base; +package com.oracle.truffle.r.runtime.ffi.base; import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.ForeignAccess; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/StrtolResult.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/StrtolResult.java similarity index 92% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/StrtolResult.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/StrtolResult.java index 1884ad0bfabd6141941fe6c87e211e476a2bb673..4585fa57f17e5135dee4277a60325b3129b9c0d5 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/StrtolResult.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/StrtolResult.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.base; +package com.oracle.truffle.r.runtime.ffi.base; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.r.runtime.data.RTruffleObject; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/StrtolResultMR.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/StrtolResultMR.java similarity index 94% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/StrtolResultMR.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/StrtolResultMR.java index 0b306587388575e332cb810dcfcb9bb583ae2f19..be8acf978ed2bde78fd1cb60911c4960cc07a567 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/StrtolResultMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/StrtolResultMR.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.base; +package com.oracle.truffle.r.runtime.ffi.base; import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/UnameResult.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/UnameResult.java similarity index 88% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/UnameResult.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/UnameResult.java index 097610794db07e03b3776ce21e35dade8c0e7d60..ef8c8e5ce50c31144806857d3abbcb9d812bbefe 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/UnameResult.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/UnameResult.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 @@ -20,13 +20,13 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.base; +package com.oracle.truffle.r.runtime.ffi.base; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.r.runtime.data.RTruffleObject; -import com.oracle.truffle.r.runtime.ffi.BaseRFFI; +import com.oracle.truffle.r.runtime.ffi.BaseRFFI.UtsName; -public final class UnameResult implements BaseRFFI.UtsName, RTruffleObject { +public final class UnameResult implements UtsName, RTruffleObject { private String sysname; private String release; private String version; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/UnameResultMR.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/UnameResultMR.java similarity index 94% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/UnameResultMR.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/UnameResultMR.java index e63607fbadda495659e53bb855afef2f44343882..bf9a16a1aceb6515aa58fb0f9e46c1e0979f630c 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/base/UnameResultMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/base/UnameResultMR.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.base; +package com.oracle.truffle.r.runtime.ffi.base; import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArray.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArray.java new file mode 100644 index 0000000000000000000000000000000000000000..cf414ccbd0164fea7831a2bd7e7c38b8feb1f3e6 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArray.java @@ -0,0 +1,80 @@ +/* + * 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.runtime.ffi.interop; + +import java.nio.charset.StandardCharsets; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.TruffleObject; + +/** + * A {@link TruffleObject} that represents an array of {@code unsigned char} values, that is + * {@code NULL} terminated in the C domain. + */ +public final class NativeCharArray extends NativeUInt8Array { + + public NativeCharArray(byte[] bytes) { + super(bytes, true); + } + + @TruffleBoundary + public NativeCharArray(String value) { + super(value.getBytes(StandardCharsets.UTF_8), true); + } + + private NativeCharArray(byte[] bytes, boolean nullTerminate) { + super(bytes, nullTerminate); + } + + /** + * Creates {@link NativeCharArray} of given length that can be used for output parameters, it is + * not null terminated. + */ + public static NativeCharArray crateOutputBuffer(int length) { + return new NativeCharArray(new byte[length], false); + } + + /** + * Finds the null terminator and creates the Java String accordingly. + */ + public String getStringFromOutputBuffer() { + assert !fakesNullTermination() : "create the buffer string via createOutputBuffer()"; + byte[] mbuf = getValue(); + int i = 0; + while (mbuf[i] != 0 && i < mbuf.length) { + i++; + } + return new String(mbuf, 0, i); + } + + public String getString() { + byte[] val = getValue(); + return new String(val, 0, fakesNullTermination() ? val.length : val.length - 1); + } + + @Override + public ForeignAccess getForeignAccess() { + return NativeCharArrayMRForeign.ACCESS; + } +} diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeCharArrayMR.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArrayMR.java similarity index 98% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeCharArrayMR.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArrayMR.java index ed1b0f2f724a39dae220fef5fe7dee7aae049e87..f52dd8e2e15a2b90da13f3c84f66b2de3814e5e4 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeCharArrayMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeCharArrayMR.java @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop; +package com.oracle.truffle.r.runtime.ffi.interop; import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativePointer.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativePointer.java similarity index 87% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativePointer.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativePointer.java index 4202b55d79b54e8f96eaf3149a1a7ddfe2b296f7..a42e1133dc9f28558d8e186774bf7c0e3586fdc1 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativePointer.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativePointer.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 @@ -20,12 +20,11 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop; +package com.oracle.truffle.r.runtime.ffi.interop; 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.r.ffi.impl.llvm.TruffleLLVM_Utils; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RTruffleObject; @@ -79,16 +78,6 @@ public class NativePointer implements TruffleObject { return obj instanceof NativePointer; } - public static TruffleObject check(TruffleObject object) { - long nativePointer = TruffleLLVM_Utils.getNativeAddress(object); - for (int i = tableHwm - 1; i >= 0; i--) { - if (table[i].nativePointer == nativePointer) { - return table[i].object; - } - } - return null; - } - final long asPointer() { long result = asPointerImpl(); boolean newPointer = true; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativePointerMR.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativePointerMR.java similarity index 93% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativePointerMR.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativePointerMR.java index b8b73f6378c2b02ff692b92b425fa8d69a5526d4..604aef2eb8ece9561c3c7d227574c43b9c49c00c 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativePointerMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativePointerMR.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop; +package com.oracle.truffle.r.runtime.ffi.interop; import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.Resolve; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeRawArray.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeRawArray.java similarity index 91% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeRawArray.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeRawArray.java index 631188e69b63a5c702720eadfad09fff01772e19..7194fccdbfa6abec4d74072e6a2a41d4cd3f94e0 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeRawArray.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeRawArray.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop; +package com.oracle.truffle.r.runtime.ffi.interop; import com.oracle.truffle.api.interop.ForeignAccess; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeRawArrayMR.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeRawArrayMR.java similarity index 96% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeRawArrayMR.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeRawArrayMR.java index a17becc8ed2f2a4433bccc8b11b32517df567f2f..21d367ac68ef86d580f089f60c8d168cfbf98a90 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeRawArrayMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeRawArrayMR.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop; +package com.oracle.truffle.r.runtime.ffi.interop; import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.MessageResolution; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeUInt8Array.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeUInt8Array.java similarity index 77% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeUInt8Array.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeUInt8Array.java index 4bf73b78c4c4c7517fd31ffb4dd4c53f95beed58..033d78e53b96f2ee582c71c3147a368d23ccb9fe 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/NativeUInt8Array.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/NativeUInt8Array.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 @@ -20,11 +20,10 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop; +package com.oracle.truffle.r.runtime.ffi.interop; -import static com.oracle.truffle.r.ffi.impl.interop.UnsafeAdapter.UNSAFE; +import static com.oracle.truffle.r.runtime.ffi.UnsafeAdapter.UNSAFE; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.data.RTruffleObject; @@ -38,26 +37,26 @@ import sun.misc.Unsafe; * N.B. Java never stores a {@code NULL} value in a String or the byte array from * {@link String#getBytes}. * - * If {@link #fakeNull()} is {@code true}, then {@link #read} returns 0, else it is an error; - * similar for {@link #write}. + * If {@link #fakesNullTermination()} is {@code true}, then {@link #read} returns 0, else it is an + * error; similar for {@link #write}. */ public abstract class NativeUInt8Array implements RTruffleObject { - public final byte[] bytes; + public byte[] bytes; /** * If the array escapes the Truffle world via {@link #convertToNative()}, this value will be * non-zero and is used exclusively thereafter. */ - @CompilationFinal protected long nativeAddress; - private final int effectiveLength; + protected long nativeAddress; + private int effectiveLength; protected NativeUInt8Array(byte[] bytes, boolean nullTerminate) { this.bytes = bytes; this.effectiveLength = bytes.length + (nullTerminate ? 1 : 0); } - private boolean fakeNull() { + public boolean fakesNullTermination() { return bytes.length != effectiveLength; } @@ -72,7 +71,7 @@ public abstract class NativeUInt8Array implements RTruffleObject { checkNativeIndex(index); UNSAFE.putByte(nativeAddress + index, value); } else { - if (index == bytes.length && fakeNull()) { + if (index == bytes.length && fakesNullTermination()) { // ignore } else { bytes[index] = value; @@ -85,7 +84,7 @@ public abstract class NativeUInt8Array implements RTruffleObject { checkNativeIndex(index); return UNSAFE.getByte(nativeAddress + index); } else { - if (index == bytes.length && fakeNull()) { + if (index == bytes.length && fakesNullTermination()) { return (byte) 0; } return bytes[index]; @@ -107,21 +106,26 @@ public abstract class NativeUInt8Array implements RTruffleObject { private void allocateNative() { nativeAddress = UNSAFE.allocateMemory(effectiveLength); UNSAFE.copyMemory(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, nativeAddress, bytes.length); - if (fakeNull()) { + if (fakesNullTermination()) { UNSAFE.putByte(nativeAddress + bytes.length, (byte) 0); } } public byte[] getValue() { if (nativeAddress != 0) { - copyBackFromNative(); + copyBackFromNative(bytes); } return bytes; } + public void setValue(byte[] newBytes, boolean isNullTerminated) { + bytes = newBytes; + effectiveLength = isNullTerminated ? bytes.length + 1 : bytes.length; + } + @TruffleBoundary - private void copyBackFromNative() { + private void copyBackFromNative(byte[] target) { // copy back - UNSAFE.copyMemory(null, nativeAddress, bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, bytes.length); + UNSAFE.copyMemory(null, nativeAddress, target, Unsafe.ARRAY_BYTE_BASE_OFFSET, bytes.length); } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CaptureNamesResult.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CaptureNamesResult.java similarity index 92% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CaptureNamesResult.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CaptureNamesResult.java index e54b5787ad7be62e23ff9d5f422a873cd5df595c..3e8ab84265cc3599f8fd1777755aecbe5e2367ec 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CaptureNamesResult.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CaptureNamesResult.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.pcre; +package com.oracle.truffle.r.runtime.ffi.interop.pcre; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.r.runtime.data.RTruffleObject; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CaptureNamesResultMR.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CaptureNamesResultMR.java similarity index 95% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CaptureNamesResultMR.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CaptureNamesResultMR.java index b836331256e6177b658fbdfa449e6df65398e4aa..32f06e731380f335f03aabe220dddca1fe618258 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CaptureNamesResultMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CaptureNamesResultMR.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.pcre; +package com.oracle.truffle.r.runtime.ffi.interop.pcre; import com.oracle.truffle.api.interop.CanResolve; import com.oracle.truffle.api.interop.ForeignAccess; diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CompileResult.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CompileResult.java similarity index 85% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CompileResult.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CompileResult.java index 946d2a8b8d27cd7cd0b8ec6f60938c3828c95060..fb3fb04f813456ab0597f2e4b94f247bc3707435 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CompileResult.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CompileResult.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 @@ -20,17 +20,18 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.pcre; +package com.oracle.truffle.r.runtime.ffi.interop.pcre; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.r.runtime.data.RTruffleObject; import com.oracle.truffle.r.runtime.ffi.PCRERFFI; +import com.oracle.truffle.r.runtime.ffi.PCRERFFI.Result; public final class CompileResult implements RTruffleObject { private PCRERFFI.Result result; public void set(long pcreResult, String errorMessage, int errOffset) { - result = new PCRERFFI.Result(pcreResult, errorMessage, errOffset); + result = new Result(pcreResult, errorMessage, errOffset); } public PCRERFFI.Result getResult() { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CompileResultMR.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CompileResultMR.java similarity index 96% rename from com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CompileResultMR.java rename to com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CompileResultMR.java index 76562a7e33a500bff2fe2568dcf7431996048011..e6ecb9e2f8da05b14fb92ccd674cacb34e1171d0 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/interop/pcre/CompileResultMR.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/interop/pcre/CompileResultMR.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 @@ -20,7 +20,7 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.ffi.impl.interop.pcre; +package com.oracle.truffle.r.runtime.ffi.interop.pcre; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.CanResolve;