diff --git a/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c b/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c index a992a9515142d7fcbe0c1a16dbcf4a64f9adc750..30b78ec6aafcac1fff8add78694b974183a662d5 100644 --- a/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c +++ b/com.oracle.truffle.r.native/fficall/jni/src/rfficall.c @@ -43,6 +43,11 @@ Java_com_oracle_truffle_r_runtime_ffi_jnr_JNI_1CallRFFI_initialize(JNIEnv *env, init_listaccess(env); } +JNIEXPORT void JNICALL +Java_com_oracle_truffle_r_runtime_ffi_jnr_JNI_1CallRFFI_nativeSetTempDir(JNIEnv *env, jclass c, jstring tempDir) { + setTempDir(env, tempDir); +} + static jmp_buf error_jmpbuf; // Boilerplate methods for the actual calls diff --git a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h index 1181bc5aeb6cfef4717e95d637bfe3210f5b91dd..47f4e5235d4be88ca921f14539a55c63351b5c37 100644 --- a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h +++ b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h @@ -80,6 +80,8 @@ void init_vectoraccess(JNIEnv *env); void init_listaccess(JNIEnv *env); void init_utils(JNIEnv *env); +void setTempDir(JNIEnv *, jstring tempDir); + extern jclass RDataFactoryClass; extern jclass CallRFFIHelperClass; extern jclass RRuntimeClass; diff --git a/com.oracle.truffle.r.native/fficall/jni/src/variables.c b/com.oracle.truffle.r.native/fficall/jni/src/variables.c index 07776f29085fd07f70028d94fe69c8bd7c26d330..c461839e551d6b22a85769fed57d161e60d43155 100644 --- a/com.oracle.truffle.r.native/fficall/jni/src/variables.c +++ b/com.oracle.truffle.r.native/fficall/jni/src/variables.c @@ -171,8 +171,6 @@ void init_variables(JNIEnv *env, jobjectArray initialValues) { if (value != NULL) { if (strcmp(nameChars, "R_Home") == 0) { R_Home = (*env)->GetStringUTFChars(env, value, NULL); - } else if (strcmp(nameChars, "R_TempDir") == 0) { - R_TempDir = (*env)->GetStringUTFChars(env, value, NULL); } else if (strcmp(nameChars, "R_NaN") == 0) { R_NaN = (*env)->CallDoubleMethod(env, value, doubleValueMethodID); } else if (strcmp(nameChars, "R_PosInf") == 0) { @@ -274,3 +272,7 @@ void init_variables(JNIEnv *env, jobjectArray initialValues) { } } +void setTempDir(JNIEnv *env, jstring tempDir) { + R_TempDir = (*env)->GetStringUTFChars(env, tempDir, NULL); +} + diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/RFFIUtils.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIUtils.java similarity index 53% rename from com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/RFFIUtils.java rename to com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIUtils.java index ff4f1dbe6318b82093f6350502dc926a5dc854ae..243996320a724189216a0b4d44a9ce6202c7bc2f 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/RFFIUtils.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIUtils.java @@ -20,28 +20,54 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.runtime.ffi.jnr; +package com.oracle.truffle.r.runtime.ffi; import java.io.IOException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.r.runtime.FastROptions; +import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.data.RTypedValue; public class RFFIUtils { - static byte[] wrapChar(char v) { + public static byte[] wrapChar(char v) { return new byte[]{(byte) v}; } - static int[] wrapInt(int v) { + public static int[] wrapInt(int v) { return new int[]{v}; } - static double[] wrapDouble(double v) { + public static double[] wrapDouble(double v) { return new double[]{v}; } @TruffleBoundary - static IOException ioex(String errMsg) throws IOException { + public static IOException ioex(String errMsg) throws IOException { throw new IOException(errMsg); } + public static void traceCall(String name, Object... args) { + if (FastROptions.TraceNativeCalls.getBooleanValue()) { + System.out.print("CallRFFI " + name + ": "); + printArgs(args); + System.out.println(); + } + } + + private static void printArgs(Object[] args) { + for (Object arg : args) { + System.out.print(" "); + System.out.print(arg == null ? "" : arg.getClass().getSimpleName()); + if (arg instanceof RPairList) { + System.out.print("["); + printArgs(((RPairList) arg).toRList().getDataCopy()); + System.out.print("]"); + } + if (!(arg instanceof RTypedValue)) { + System.out.print("(" + arg + ")"); + } + } + } + } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RVariables.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java similarity index 94% rename from com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RVariables.java rename to com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java index ca92588fa01e720c92232cd1ec00a5b97c8f16cb..47948a1b3c010df9e44b7d330f883968267769f2 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RVariables.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java @@ -30,9 +30,9 @@ import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RUnboundValue; import com.oracle.truffle.r.runtime.env.REnvironment; -public enum RVariables { +public enum RFFIVariables { R_Home(REnvVars.rHome()), - R_TempDir("/tmp/R_TMP"), // TODO: supply proper temp directory + R_TempDir(null), // Set later with setTmpDir R_NilValue(RNull.instance), R_UnboundValue(RUnboundValue.instance), R_MissingArg(RMissing.instance), @@ -81,13 +81,17 @@ public enum RVariables { R_FalseValue(RRuntime.LOGICAL_FALSE), R_LogicalNAValue(RRuntime.LOGICAL_NA); - private final Object value; + private Object value; - RVariables(Object value) { + RFFIVariables(Object value) { this.value = value; } public Object getValue() { return value; } + + public static void setTempDir(String tempDir) { + R_TempDir.value = tempDir; + } } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java index 897796c020205b7c308fba898b6fab7a209c6aee..0adb3750888e6f8407ec84e442aeef69ea89f01f 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNI_CallRFFI.java @@ -22,6 +22,8 @@ */ package com.oracle.truffle.r.runtime.ffi.jnr; +import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.traceCall; + import java.util.concurrent.Semaphore; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -31,7 +33,7 @@ import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.ffi.CallRFFI; import com.oracle.truffle.r.runtime.ffi.DLL; -import com.oracle.truffle.r.runtime.ffi.RVariables; +import com.oracle.truffle.r.runtime.ffi.RFFIVariables; import com.oracle.truffle.r.runtime.ffi.DLL.DLLException; import com.oracle.truffle.r.runtime.ffi.LibPaths; @@ -67,17 +69,14 @@ public class JNI_CallRFFI implements CallRFFI { throw new RInternalError(ex, "error while loading " + librffiPath); } System.load(librffiPath); - initialize(RVariables.values()); + traceCall("initialize"); + initialize(RFFIVariables.values()); } private static final Semaphore inCritical = new Semaphore(1, false); public Object invokeCall(long address, String name, Object[] args) { - if (FastROptions.TraceNativeCalls.getBooleanValue()) { - System.out.print("calling " + name + ": "); - printArgs(args); - System.out.println(); - } + traceCall(name, args); try { inCritical.acquire(); switch (args.length) { @@ -103,22 +102,9 @@ public class JNI_CallRFFI implements CallRFFI { } } - private void printArgs(Object[] args) { - for (Object arg : args) { - System.out.print(" "); - System.out.print(arg == null ? "" : arg.getClass().getSimpleName()); - if (arg instanceof RPairList) { - System.out.print("["); - printArgs(((RPairList) arg).toRList().getDataCopy()); - System.out.print("]"); - } - if (!(arg instanceof RTypedValue)) { - System.out.print("(" + arg + ")"); - } - } - } + private static native void initialize(RFFIVariables[] variables); - private static native void initialize(RVariables[] variables); + private static native void nativeSetTempDir(String tempDir); private static native Object call(long address, Object[] args); @@ -143,11 +129,7 @@ public class JNI_CallRFFI implements CallRFFI { private static native Object call9(long address, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8, Object arg9); public void invokeVoidCall(long address, String name, Object[] args) { - if (FastROptions.TraceNativeCalls.getBooleanValue()) { - System.out.print("void-calling " + name + ": "); - printArgs(args); - System.out.println(); - } + traceCall(name, args); try { inCritical.acquire(); switch (args.length) { @@ -165,4 +147,16 @@ public class JNI_CallRFFI implements CallRFFI { private static native void callVoid1(long address, Object arg1); + public void setTempDir(String tempDir) { + traceCall("setTempDir", tempDir); + try { + inCritical.acquire(); + RFFIVariables.setTempDir(tempDir); + nativeSetTempDir(tempDir); + } catch (InterruptedException ex) { + } finally { + inCritical.release(); + } + } + } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Base.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Base.java index fc6e3b43cc3ffe8762bdff694c4efbc89572e3fb..2cd54b6db4db2885ecc9cad9b20232375c9c4257 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Base.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Base.java @@ -22,7 +22,7 @@ */ package com.oracle.truffle.r.runtime.ffi.jnr; -import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.ioex; +import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.ioex; import java.io.IOException; import java.nio.ByteBuffer; diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Lapack.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Lapack.java index eeef7857f90f96701e3918db5a46d2b9a0871266..fedfd56ad65c45322cb822f29f80139e04bfe08a 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Lapack.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Lapack.java @@ -22,9 +22,9 @@ */ package com.oracle.truffle.r.runtime.ffi.jnr; -import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.wrapChar; -import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.wrapDouble; -import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.wrapInt; +import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.wrapChar; +import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.wrapDouble; +import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.wrapInt; import jnr.ffi.LibraryLoader; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java index 90522b8bce43d4b11c404b08952da623ca8d4fbe..3038ba1ff00fc32bb494dda3325842bd0c26edc5 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_RAppl.java @@ -22,8 +22,8 @@ */ package com.oracle.truffle.r.runtime.ffi.jnr; -import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.wrapDouble; -import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.wrapInt; +import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.wrapDouble; +import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.wrapInt; import jnr.ffi.LibraryLoader; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Stats.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Stats.java index 31814b04f6cc85b1097a1390d2af48de16faac5b..b012dbca503412095153feff304c5d60b34b9f2c 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Stats.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/JNR_Stats.java @@ -22,7 +22,7 @@ */ package com.oracle.truffle.r.runtime.ffi.jnr; -import static com.oracle.truffle.r.runtime.ffi.jnr.RFFIUtils.*; +import static com.oracle.truffle.r.runtime.ffi.RFFIUtils.*; import jnr.ffi.LibraryLoader; import jnr.ffi.annotations.In; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java index 9f497a9c02e4be0cf0e1c9428906a3156bc0dd67..babcda198be0be8a0558eebdab2ef30b95c242ae 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java @@ -68,6 +68,7 @@ public class TempPathName { } else { Utils.fail("cannot create 'R_TempDir'"); } + RFFIFactory.getRFFI().getCallRFFI().setTempDir(tempDirPath); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java index 1565fe9c605e9960e198154fea66849fecb89ef2..57aaccd52db9cf7d102cb569d1d1b67215f2436b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java @@ -41,4 +41,10 @@ public interface CallRFFI { * Variant that does not return a result (primarily for library "init" methods). */ void invokeVoidCall(long address, String name, Object[] args); + + /** + * This interface is initialized very early, before the {@code tempDir} is established. This + * call sets the value. + */ + void setTempDir(String tempDir); }