From 9566e0a697ac8fd5aa7793fc4a50d61a8bbb4ce1 Mon Sep 17 00:00:00 2001
From: Lukas Stadler <lukas.stadler@oracle.com>
Date: Thu, 31 Mar 2016 09:51:39 +0200
Subject: [PATCH] various small FFI changes

---
 .../fficall/src/jni/Rinternals.c              | 12 +++------
 .../fficall/src/jni/rffiutils.c               |  4 ++-
 .../r/runtime/ffi/jnr/CallRFFIHelper.java     | 25 +++++++++++++------
 3 files changed, 23 insertions(+), 18 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 5729da8e80..0050adfe49 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c
@@ -385,15 +385,11 @@ cetype_t Rf_getCharCE(SEXP x) {
 }
 
 SEXP Rf_mkChar(const char *x) {
-	JNIEnv *thisenv = getEnv();
-	// TODO encoding, assume UTF for now
-	SEXP result = (*thisenv)->NewStringUTF(thisenv, x);
-	return checkRef(thisenv, result);
+	return Rf_mkCharLenCE(x, strlen(x), CE_NATIVE);
 }
 
 SEXP Rf_mkCharCE(const char *x, cetype_t y) {
-	unimplemented("Rf_mkCharCE");
-	return NULL;
+	return Rf_mkCharLenCE(x, strlen(x), y);
 }
 
 SEXP Rf_mkCharLen(const char *x, int y) {
@@ -416,9 +412,7 @@ const char *Rf_reEnc(const char *x, cetype_t ce_in, cetype_t ce_out, int subst)
 }
 
 SEXP Rf_mkString(const char *s) {
-	JNIEnv *thisenv = getEnv();
-	jstring string = (*thisenv)->NewStringUTF(thisenv, s);
-	return ScalarString(string);
+	return ScalarString(Rf_mkChar(s));
 }
 
 int Rf_ncols(SEXP x) {
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 9953c78ba7..aee0e8150f 100644
--- a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c
+++ b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c
@@ -231,7 +231,9 @@ static SEXP checkCachedGlobalRef(JNIEnv *env, SEXP obj) {
 void validateRef(JNIEnv *env, SEXP x, const char *msg) {
 	jobjectRefType t = (*env)->GetObjectRefType(env, x);
 	if (t == JNIInvalidRefType) {
-		fatalError(msg);
+		char buf[1000];
+		sprintf(buf, "%s %p", msg,x);
+		fatalError(buf);
 	}
 }
 
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 e57c1b5e99..99923af008 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
@@ -56,6 +56,8 @@ import com.oracle.truffle.r.runtime.data.RStringVector;
 import com.oracle.truffle.r.runtime.data.RSymbol;
 import com.oracle.truffle.r.runtime.data.RUnboundValue;
 import com.oracle.truffle.r.runtime.data.model.RAbstractContainer;
+import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
+import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
 import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
 import com.oracle.truffle.r.runtime.env.REnvironment;
 import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
@@ -100,12 +102,23 @@ public class CallRFFIHelper {
         }
     }
 
-    private static void guaranteeInstanceOf(Object x, Class<?> clazz) {
+    private static <T> T guaranteeInstanceOf(Object x, Class<T> clazz) {
         if (x == null) {
             guarantee(false, "unexpected type: null instead of " + clazz.getSimpleName());
         } else if (!clazz.isInstance(x)) {
             guarantee(false, "unexpected type: " + x + " is " + x.getClass().getSimpleName() + " instead of " + clazz.getSimpleName());
         }
+        return clazz.cast(x);
+    }
+
+    private static <T> T guaranteeInstanceOfOrNull(Object x, Class<T> clazz) {
+        if (x == null) {
+            return null;
+        }
+        if (!clazz.isInstance(x)) {
+            guarantee(false, "unexpected type: " + x + " is " + x.getClass().getSimpleName() + " instead of " + clazz.getSimpleName());
+        }
+        return clazz.cast(x);
     }
 
     // Checkstyle: stop method name check
@@ -395,8 +408,7 @@ public class CallRFFIHelper {
     }
 
     public static void SET_VECTOR_ELT(Object x, int i, Object v) {
-        // TODO error checks
-        RList list = (RList) x;
+        RList list = guaranteeInstanceOf(x, RList.class);
         list.setElement(i, v);
     }
 
@@ -473,11 +485,8 @@ public class CallRFFIHelper {
     }
 
     public static Object VECTOR_ELT(Object x, int i) {
-        if (x instanceof RList) {
-            return ((RList) x).getDataAt(i);
-        } else {
-            throw unimplemented();
-        }
+        RAbstractListVector list = guaranteeInstanceOf(RRuntime.asAbstractVector(x), RAbstractListVector.class);
+        return list.getDataAt(i);
     }
 
     public static int NAMED(Object x) {
-- 
GitLab