From 2ffceff9e893cfcea70e7c851008ad296b2fd9f8 Mon Sep 17 00:00:00 2001 From: Florian Angerer <florian.angerer@oracle.com> Date: Mon, 27 Mar 2017 10:59:23 +0200 Subject: [PATCH] Using RExternalPtr to represent native address instead of a long. --- .../fficall/src/jni/Connections.c | 30 +++++++--------- .../r/nodes/ffi/JavaUpCallsRFFIImpl.java | 5 +-- .../r/nodes/ffi/TracingUpCallsRFFIImpl.java | 2 +- .../r/runtime/conn/NativeConnections.java | 36 +++++++------------ .../truffle/r/runtime/ffi/StdUpCallsRFFI.java | 2 +- 5 files changed, 29 insertions(+), 46 deletions(-) diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Connections.c b/com.oracle.truffle.r.native/fficall/src/jni/Connections.c index 5b2f516c15..0cf9704787 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Connections.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Connections.c @@ -81,7 +81,7 @@ void init_connections(JNIEnv *env) { getOpenModeMethodID = checkGetMethodID(env, UpCallsRFFIClass, "getOpenModeString", "(Ljava/lang/Object;)Ljava/lang/String;", 0); /* int R_new_custom_connection(String, String, String) */ - newCustomConnectionMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_new_custom_connection", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;J)Ljava/lang/Object;", 0); + newCustomConnectionMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_new_custom_connection", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); } static char *connStringToChars(JNIEnv *env, jstring string) { @@ -190,7 +190,8 @@ SEXP R_new_custom_connection(const char *description, const char *mode, const ch jstring jsDescription = (*thisenv)->NewStringUTF(thisenv, description); jstring jsMode = (*thisenv)->NewStringUTF(thisenv, mode); jstring jsClassName = (*thisenv)->NewStringUTF(thisenv, class_name); - ans = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, newCustomConnectionMethodID, jsDescription, jsMode, jsClassName, (jlong)new); + jobject addrObj = R_MakeExternalPtr(new, R_NilValue, R_NilValue); + ans = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, newCustomConnectionMethodID, jsDescription, jsMode, jsClassName, addrObj); if (ans) { new->class = (char *) malloc(strlen(class_name) + 1); @@ -236,19 +237,12 @@ SEXP R_new_custom_connection(const char *description, const char *mode, const ch * Position 0 is the lower part and position 1 is the higher part of the address. * This currently assumes max. 64-bit addresses ! */ -static Rconnection convertToAddress(SEXP intVec) { - if(!Rf_isVector(intVec)) { +static Rconnection convertToAddress(SEXP addrObj) { + if(!inherits(addrObj, "externalptr")) { error(_("invalid address object")); } + return (Rconnection) R_ExternalPtrAddr(addrObj); - // convert integer vector to array - int *arr = INTEGER(intVec); - - // bit-fiddle address - jlong ptr = (jlong) arr[1]; - ptr = (ptr<<32) | ((jlong)arr[0] & 0xFFFFFFFFl); - - return (Rconnection) ptr; } /* @@ -279,7 +273,7 @@ SEXP __GetFlagNativeConnection(SEXP rConnAddrObj, jstring jname) { } free(name); - return Rf_ScalarLogical(result); + return ScalarLogical(result); } /* @@ -290,7 +284,7 @@ SEXP __GetFlagNativeConnection(SEXP rConnAddrObj, jstring jname) { SEXP __OpenNativeConnection(SEXP rConnAddrObj) { Rconnection con = convertToAddress(rConnAddrObj); Rboolean success = con->open(con); - return Rf_ScalarLogical(success); + return ScalarLogical(success); } /* @@ -317,7 +311,7 @@ SEXP __ReadNativeConnection(SEXP rConnAddrObj, jbyteArray bufObj, SEXP nVec) { size_t nread = con->read(tmp_buf, 1, n, con); // copy back and release buffer (*thisenv)->ReleaseByteArrayElements(thisenv, bufObj, tmp_buf, JNI_COMMIT); - return Rf_ScalarInteger(nread); + return ScalarInteger(nread); } /* @@ -333,7 +327,7 @@ SEXP __WriteNativeConnection(SEXP rConnAddrObj, jbyteArray bufObj, SEXP nVec) { size_t nwritten = con->write(bytes, 1, n, con); // just release buffer (*thisenv)->ReleaseByteArrayElements(thisenv, bufObj, bytes, JNI_ABORT); - return Rf_ScalarInteger(nwritten); + return ScalarInteger(nwritten); } /* @@ -343,11 +337,11 @@ SEXP __WriteNativeConnection(SEXP rConnAddrObj, jbyteArray bufObj, SEXP nVec) { */ SEXP __SeekNativeConnection(SEXP rConnAddrObj, SEXP whereObj, SEXP originObj, SEXP rwObj) { Rconnection con = convertToAddress(rConnAddrObj); - double where = adDouble(whereObj); + double where = asReal(whereObj); int origin = asInteger(originObj); int rw = asInteger(rwObj); double oldPos = con->seek(con, where, origin, rw); - return Rf_ScalarReal(oldPos); + return ScalarReal(oldPos); } size_t R_ReadConnection(Rconnection con, void *buf, size_t n) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java index 70bc2ec622..c06af8b64f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java @@ -1204,13 +1204,14 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { } @Override - public Object R_new_custom_connection(Object description, Object mode, Object className, long readAddr) { + public Object R_new_custom_connection(Object description, Object mode, Object className, Object connAddrObj) { // TODO handle encoding properly ! String strDescription = (String) description; String strMode = (String) mode; String strClassName = (String) className; + RExternalPtr connAddr = guaranteeInstanceOf(connAddrObj, RExternalPtr.class); try { - return new NativeRConnection(strDescription, strMode, strClassName, readAddr).asVector(); + return new NativeRConnection(strDescription, strMode, strClassName, connAddr).asVector(); } catch (IOException e) { return InvalidConnection.instance.asVector(); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TracingUpCallsRFFIImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TracingUpCallsRFFIImpl.java index 7cdfff95c3..b89d83cc56 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TracingUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TracingUpCallsRFFIImpl.java @@ -742,7 +742,7 @@ final class TracingUpCallsRFFIImpl implements UpCallsRFFI { } @Override - public Object R_new_custom_connection(Object description, Object mode, Object className, long readAddr) { + public Object R_new_custom_connection(Object description, Object mode, Object className, Object readAddr) { RFFIUtils.traceUpCall("R_new_custom_connection", description, mode, className, readAddr); return delegate.R_new_custom_connection(description, mode, className, readAddr); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/NativeConnections.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/NativeConnections.java index cb0f5f655d..e6e7baa075 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/NativeConnections.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/NativeConnections.java @@ -38,6 +38,7 @@ import com.oracle.truffle.r.runtime.conn.ConnectionSupport.ConnectionClass; import com.oracle.truffle.r.runtime.conn.RConnection.SeekMode; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RLogicalVector; import com.oracle.truffle.r.runtime.ffi.CallRFFI; @@ -75,9 +76,9 @@ public class NativeConnections { public static class NativeRConnection extends BaseRConnection { private final String customConClass; private final String description; - private final long addr; + private final RExternalPtr addr; - public NativeRConnection(String description, String modeString, String customConClass, long addr) throws IOException { + public NativeRConnection(String description, String modeString, String customConClass, RExternalPtr addr) throws IOException { super(ConnectionClass.NATIVE, modeString, AbstractOpenMode.Read); this.customConClass = Objects.requireNonNull(customConClass); this.description = Objects.requireNonNull(description); @@ -117,7 +118,7 @@ public class NativeConnections { return customConClass; } - public long getNativeAddress() { + public RExternalPtr getNativeAddress() { return addr; } @@ -135,8 +136,7 @@ public class NativeConnections { NativeCallInfo ni = NativeConnections.getNativeFunctionInfo(GET_FLAG_NATIVE_CONNECTION); RootCallTarget nativeCallTarget = CallRFFI.InvokeCallRootNode.create().getCallTarget(); - RIntVector addrVec = convertAddrToIntVec(addr); - Object result = nativeCallTarget.call(ni, new Object[]{addrVec, name}); + Object result = nativeCallTarget.call(ni, new Object[]{addr, name}); if (result instanceof RLogicalVector) { return ((RLogicalVector) result).getDataAt(0) == RRuntime.LOGICAL_TRUE; } @@ -151,7 +151,7 @@ public class NativeConnections { * @param rw seek mode (read=1, write=2, last) * @return the old cursor position */ - private static long seekSingleMode(long addr, long offset, SeekMode seekMode, int rw) { + private static long seekSingleMode(RExternalPtr addr, long offset, SeekMode seekMode, int rw) { RDoubleVector where = RDataFactory.createDoubleVectorFromScalar(offset); RIntVector seekCode; switch (seekMode) { @@ -172,8 +172,7 @@ public class NativeConnections { NativeCallInfo ni = NativeConnections.getNativeFunctionInfo(SEEK_NATIVE_CONNECTION); RootCallTarget nativeCallTarget = CallRFFI.InvokeCallRootNode.create().getCallTarget(); - RIntVector addrVec = convertAddrToIntVec(addr); - Object result = nativeCallTarget.call(ni, new Object[]{addrVec, where, seekCode, rwCode}); + Object result = nativeCallTarget.call(ni, new Object[]{addr, where, seekCode, rwCode}); if (result instanceof RDoubleVector) { return (long) ((RDoubleVector) result).getDataAt(0); } @@ -286,12 +285,11 @@ public class NativeConnections { } } - private static void openNative(long addr) throws IOException { + private static void openNative(RExternalPtr addr) throws IOException { NativeCallInfo ni = NativeConnections.getNativeFunctionInfo(OPEN_NATIVE_CONNECTION); RootCallTarget nativeCallTarget = CallRFFI.InvokeCallRootNode.create().getCallTarget(); - RIntVector addrVec = convertAddrToIntVec(addr); - Object result = nativeCallTarget.call(ni, new Object[]{addrVec}); + Object result = nativeCallTarget.call(ni, new Object[]{addr}); if (!(result instanceof RLogicalVector && ((RLogicalVector) result).getDataAt(0) == RRuntime.LOGICAL_TRUE)) { throw new IOException("could not open connection"); } @@ -309,8 +307,7 @@ public class NativeConnections { public int read(ByteBuffer dst) throws IOException { NativeCallInfo ni = NativeConnections.getNativeFunctionInfo(READ_NATIVE_CONNECTION); RootCallTarget nativeCallTarget = CallRFFI.InvokeCallRootNode.create().getCallTarget(); - RIntVector vec = NativeConnections.convertAddrToIntVec(base.addr); - Object call = nativeCallTarget.call(ni, new Object[]{vec, dst.array(), dst.remaining()}); + Object call = nativeCallTarget.call(ni, new Object[]{base.addr, dst.array(), dst.remaining()}); if (call instanceof RIntVector) { int nread = ((RIntVector) call).getDataAt(0); @@ -331,8 +328,7 @@ public class NativeConnections { public void close() throws IOException { NativeCallInfo ni = NativeConnections.getNativeFunctionInfo(CLOSE_NATIVE_CONNECTION); RootCallTarget nativeCallTarget = CallRFFI.InvokeCallRootNode.create().getCallTarget(); - RIntVector vec = NativeConnections.convertAddrToIntVec(base.addr); - nativeCallTarget.call(ni, new Object[]{vec}); + nativeCallTarget.call(ni, new Object[]{base.addr}); } @Override @@ -340,8 +336,7 @@ public class NativeConnections { NativeCallInfo ni = NativeConnections.getNativeFunctionInfo(WRITE_NATIVE_CONNECTION); RootCallTarget nativeCallTarget = CallRFFI.InvokeCallRootNode.create().getCallTarget(); - RIntVector vec = NativeConnections.convertAddrToIntVec(base.addr); - Object result = nativeCallTarget.call(ni, new Object[]{vec, src.array(), src.remaining()}); + Object result = nativeCallTarget.call(ni, new Object[]{base.addr, src.array(), src.remaining()}); if (result instanceof RIntVector) { return ((RIntVector) result).getDataAt(0); @@ -350,11 +345,4 @@ public class NativeConnections { throw RInternalError.shouldNotReachHere("unexpected result type"); } } - - static RIntVector convertAddrToIntVec(long addr) { - int high = (int) (addr >> 32); - int low = (int) addr; - RIntVector vec = RDataFactory.createIntVector(new int[]{low, high}, true); - return vec; - } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java index 82a1e81ff4..dceb6d282d 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StdUpCallsRFFI.java @@ -254,7 +254,7 @@ public interface StdUpCallsRFFI { Object R_CHAR(Object x); - Object R_new_custom_connection(@RFFICstring Object description, @RFFICstring Object mode, @RFFICstring Object className, long readAddr); + Object R_new_custom_connection(@RFFICstring Object description, @RFFICstring Object mode, @RFFICstring Object className, Object readAddr); int R_ReadConnection(int fd, byte[] buf); -- GitLab