diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c index 70402b1ef21baf9bccefb9447195b17b2244237b..5151b22ef3c8f5bc266caff5be7adf63ae6abf04 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c @@ -1262,15 +1262,8 @@ char *dngettext(const char *domainname, const char *msgid, const char * msgid_pl const char *R_CHAR(SEXP charsxp) { TRACE("%s(%p)", charsxp); JNIEnv *thisenv = getEnv(); - // This is nasty: - // 1. the resulting character array has to be copied and zero-terminated. - // 2. It causes an (inevitable?) memory leak jstring string = stringFromCharSXP(thisenv, charsxp); - jsize len = (*thisenv)->GetStringUTFLength(thisenv, string); - const char *stringChars = (*thisenv)->GetStringUTFChars(thisenv, string, NULL); - char *copyChars = malloc(len + 1); - memcpy(copyChars, stringChars, len); - copyChars[len] = 0; + char *copyChars = stringToChars(thisenv, string); TRACE(" %s(%s)\n", copyChars); return copyChars; } diff --git a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c index f009ca873b9f5227f8689deadb794c71fcaae750..2018a4e1dc1feef251b7eb31ca217117b3357183 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c @@ -42,7 +42,7 @@ static jmethodID unimplementedMethodID; jmethodID createSymbolMethodID; static jmethodID validateMethodID; -JNIEnv *curenv = NULL; +static JNIEnv *curenv = NULL; jmp_buf *callErrorJmpBuf; #define DEBUG_CACHE 0 @@ -84,6 +84,18 @@ void init_utils(JNIEnv *env) { copiedVectorsIndex = 0; } +const char *stringToChars(JNIEnv *jniEnv, jstring string) { + // This is nasty: + // 1. the resulting character array has to be copied and zero-terminated. + // 2. It causes an (inevitable?) memory leak + jsize len = (*jniEnv)->GetStringUTFLength(jniEnv, string); + const char *stringChars = (*jniEnv)->GetStringUTFChars(jniEnv, string, NULL); + char *copyChars = malloc(len + 1); + memcpy(copyChars, stringChars, len); + copyChars[len] = 0; + return copyChars; +} + void callEnter(JNIEnv *env, jmp_buf *jmpbuf) { setEnv(env); callErrorJmpBuf = jmpbuf; diff --git a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h index 24e89fee06e97133581fbffc8068055002666ba6..ee28f6641bec22efe5eef49b6ec13435b46e6e3a 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h +++ b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h @@ -95,4 +95,7 @@ extern jclass RRuntimeClass; #define _(Source) (Source) +// convert a string into a char* +const char *stringToChars(JNIEnv *jniEnv, jstring string); + #endif /* RFFIUTILS_H */ diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java index 2ca54315c685bd13f33e5de1cba488c94a150f01..7a850063c2e04eac9296f05eb993b98f320fa19c 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper.java @@ -27,6 +27,7 @@ import java.nio.charset.StandardCharsets; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RCaller; +import com.oracle.truffle.r.runtime.REnvVars; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RErrorHandling; import com.oracle.truffle.r.runtime.RInternalError; @@ -736,6 +737,11 @@ public class CallRFFIHelper { } } + @SuppressWarnings("unused") + private static String R_HomeDir() { + return REnvVars.rHome(); + } + // Checkstyle: resume method name check public static Object validate(Object x) {