From 3910da97a53de87920616673f446888ad617f7e8 Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Thu, 16 Jun 2016 13:50:55 -0700
Subject: [PATCH] add stringToChars to rffiutil

---
 .../fficall/src/jni/Rinternals.c                   |  9 +--------
 .../fficall/src/jni/rffiutils.c                    | 14 +++++++++++++-
 .../fficall/src/jni/rffiutils.h                    |  3 +++
 .../truffle/r/runtime/ffi/jnr/CallRFFIHelper.java  |  6 ++++++
 4 files changed, 23 insertions(+), 9 deletions(-)

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 70402b1ef2..5151b22ef3 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 f009ca873b..2018a4e1dc 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 24e89fee06..ee28f6641b 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 2ca54315c6..7a850063c2 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) {
-- 
GitLab