From 082651003d21f093f65400953aaa73aaec36fbfd Mon Sep 17 00:00:00 2001
From: Mick Jordan <mick.jordan@oracle.com>
Date: Sun, 23 Aug 2015 12:37:49 -0700
Subject: [PATCH] FFI additions

---
 .../fficall/jni/src/misc.c                    |  25 ++++
 .../fficall/jni/src/rf_functions.c            | 115 ++++++++++++++++++
 .../fficall/jni/src/rffiutils.c               |   2 +
 .../fficall/jni/src/rffiutils.h               |   1 +
 .../fficall/jni/src/variables.c               |  94 ++++++++++----
 .../include/jni/ed_Rinterface                 |   1 +
 .../include/jni/ed_Rinternals                 |   4 +
 com.oracle.truffle.r.native/run/Makefile      |   4 +-
 .../r/runtime/ffi/jnr/CallRFFIHelper.java     |  22 ++++
 .../r/runtime/ffi/jnr/CallRFFIWithJNI.java    |  48 ++++----
 10 files changed, 267 insertions(+), 49 deletions(-)

diff --git a/com.oracle.truffle.r.native/fficall/jni/src/misc.c b/com.oracle.truffle.r.native/fficall/jni/src/misc.c
index fb9dfbcf89..7b0cf110fc 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/misc.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/misc.c
@@ -24,8 +24,12 @@
 #include <stdlib.h>
 #include <string.h>
 
+jmethodID iS4ObjectMethodID;
+jmethodID isFiniteMethodID;
 
 void init_misc(JNIEnv *env) {
+	iS4ObjectMethodID = checkGetMethodID(env, CallRFFIHelperClass, "isS4Object", "(Ljava/lang/Object;)I", 1);
+	isFiniteMethodID = checkGetMethodID(env, RRuntimeClass, "isFinite", "(D)Z", 1);
 }
 
 const char *R_CHAR(SEXP string) {
@@ -53,6 +57,27 @@ void R_rsort(double *x, int n) {
 	unimplemented("R_rsort");
 }
 
+void R_qsort_int_I(int *iv, int *II, int i, int j) {
+	unimplemented("R_qsort_int_I");
+}
+
 void R_CheckUserInterrupt() {
 // TODO (we don't even do this in the Java code)
 }
+
+int R_finite(double x) {
+	JNIEnv *env = getEnv();
+	jboolean r = (*env)->CallStaticBooleanMethod(env, RRuntimeClass, isFiniteMethodID, x);
+}
+
+int IS_S4_OBJECT(SEXP x) {
+	JNIEnv *env = getEnv();
+	return 	(*env)->CallStaticIntMethod(env, CallRFFIHelperClass, iS4ObjectMethodID, x);
+}
+
+void SET_S4_OBJECT(SEXP x) {
+	unimplemented("SET_S4_OBJECT");
+}
+void UNSET_S4_OBJECT(SEXP x) {
+	unimplemented("UNSET_S4_OBJECT");
+}
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/rf_functions.c b/com.oracle.truffle.r.native/fficall/jni/src/rf_functions.c
index 3dcf32959d..24825674fa 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/rf_functions.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/rf_functions.c
@@ -29,7 +29,9 @@
 static jmethodID Rf_ScalarIntegerMethodID;
 static jmethodID Rf_ScalarDoubleMethodID;
 static jmethodID Rf_ScalarStringMethodID;
+static jmethodID Rf_ScalarLogicalMethodID;
 static jmethodID Rf_allocateVectorMethodID;
+static jmethodID Rf_allocateArrayMethodID;
 static jmethodID Rf_allocateMatrixMethodID;
 static jmethodID Rf_duplicateMethodID;
 static jmethodID Rf_consMethodID;
@@ -49,6 +51,7 @@ void init_rf_functions(JNIEnv *env) {
 	Rf_ScalarIntegerMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarInteger", "(I)Lcom/oracle/truffle/r/runtime/data/RIntVector;", 1);
 	Rf_ScalarDoubleMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarDouble", "(D)Lcom/oracle/truffle/r/runtime/data/RDoubleVector;", 1);
 	Rf_ScalarStringMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarString", "(Ljava/lang/String;)Lcom/oracle/truffle/r/runtime/data/RStringVector;", 1);
+	Rf_ScalarLogicalMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarLogical", "(I)Lcom/oracle/truffle/r/runtime/data/RLogicalVector;", 1);
 	Rf_consMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_cons", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1);
 	Rf_defineVarMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_defineVar", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 1);
 	Rf_findVarMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_findVar", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1);
@@ -60,6 +63,7 @@ void init_rf_functions(JNIEnv *env) {
 	Rf_errorMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_error", "(Ljava/lang/String;)V", 1);
 	Rf_allocateVectorMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_allocateVector", "(II)Ljava/lang/Object;", 1);
 	Rf_allocateMatrixMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_allocateMatrix", "(III)Ljava/lang/Object;", 1);
+	Rf_allocateArrayMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_allocateArray", "(ILjava/lang/Object;)Ljava/lang/Object;", 1);
 	Rf_duplicateMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_duplicate", "(Ljava/lang/Object;)Ljava/lang/Object;", 1);
 	Rf_NewHashedEnvMethodID = checkGetMethodID(env, RDataFactoryClass, "createNewEnv", "(Lcom/oracle/truffle/r/runtime/env/REnvironment;Ljava/lang/String;ZI)Lcom/oracle/truffle/r/runtime/env/REnvironment;", 1);
 //	Rf_rPsortMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_rPsort", "(Lcom/oracle/truffle/r/runtime/data/RDoubleVector;II)", 1);
@@ -86,6 +90,13 @@ SEXP Rf_ScalarString(SEXP value) {
     return checkRef(thisenv, result);
 }
 
+SEXP Rf_ScalarLogical(int value) {
+	TRACE(TARG1, value);
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_ScalarLogicalMethodID, value);
+    return checkRef(thisenv, result);
+}
+
 SEXP Rf_allocVector(SEXPTYPE t, R_xlen_t len) {
 	TRACE(TARG2d, t, len);
 	JNIEnv *thisenv = getEnv();
@@ -93,6 +104,13 @@ SEXP Rf_allocVector(SEXPTYPE t, R_xlen_t len) {
 	return checkRef(thisenv, result);
 }
 
+SEXP Rf_allocArray(SEXPTYPE t, SEXP dims) {
+	TRACE(TARG2d, t, len);
+	JNIEnv *thisenv = getEnv();
+	SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_allocateArrayMethodID, t, dims);
+	return checkRef(thisenv, result);
+}
+
 SEXP Rf_allocMatrix(SEXPTYPE mode, int nrow, int ncol) {
 	TRACE(TARG2d, t, len);
 	JNIEnv *thisenv = getEnv();
@@ -111,6 +129,10 @@ void Rf_defineVar(SEXP symbol, SEXP value, SEXP rho) {
 	(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_defineVarMethodID, symbol, value, rho);
 }
 
+SEXP Rf_eval(SEXP expr, SEXP env) {
+	unimplemented("Rf_eval)");
+}
+
 SEXP Rf_findVar(SEXP symbol, SEXP rho) {
 	JNIEnv *thisenv = getEnv();
 	SEXP result =(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findVarMethodID, symbol, rho);
@@ -135,6 +157,94 @@ SEXP Rf_duplicate(SEXP x) {
 	return checkRef(thisenv, result);
 }
 
+Rboolean Rf_inherits(SEXP x, const char * klass) {
+	unimplemented("Rf_inherits)");
+}
+
+Rboolean Rf_isFunction(SEXP x) {
+	unimplemented("Rf_isFunction)");
+}
+
+Rboolean Rf_isArray(SEXP x) {
+    unimplemented("Rf_isArray");
+}
+
+Rboolean Rf_isFactor(SEXP x) {
+    unimplemented("Rf_isFactor");
+}
+
+Rboolean Rf_isFrame(SEXP x) {
+    unimplemented("Rf_isFrame");
+}
+
+Rboolean Rf_isInteger(SEXP x) {
+    unimplemented("Rf_isInteger");
+}
+
+Rboolean Rf_isLanguage(SEXP x) {
+    unimplemented("Rf_isLanguage");
+}
+
+Rboolean Rf_isList(SEXP x) {
+    unimplemented("Rf_isList");
+}
+
+Rboolean Rf_isMatrix(SEXP x) {
+    unimplemented("Rf_isMatrix");
+}
+
+Rboolean Rf_isNewList(SEXP x) {
+    unimplemented("Rf_isNewList");
+}
+
+Rboolean Rf_isNumber(SEXP x) {
+    unimplemented("Rf_isNumber");
+}
+
+Rboolean Rf_isNumeric(SEXP x) {
+    unimplemented("Rf_isNumeric");
+}
+
+Rboolean Rf_isPairList(SEXP x) {
+    unimplemented("Rf_isPairList");
+}
+
+Rboolean Rf_isPrimitive(SEXP x) {
+    unimplemented("Rf_isPrimitive");
+}
+
+Rboolean Rf_isTs(SEXP x) {
+    unimplemented("Rf_isTs");
+}
+
+Rboolean Rf_isUserBinop(SEXP x) {
+    unimplemented("Rf_isUserBinop");
+}
+
+Rboolean Rf_isValidString(SEXP x) {
+    unimplemented("Rf_isValidString");
+}
+
+Rboolean Rf_isValidStringF(SEXP x) {
+    unimplemented("Rf_isValidStringF");
+}
+
+Rboolean Rf_isVector(SEXP x) {
+    unimplemented("Rf_isVector");
+}
+
+Rboolean Rf_isVectorAtomic(SEXP x) {
+    unimplemented("Rf_isVectorAtomic");
+}
+
+Rboolean Rf_isVectorList(SEXP x) {
+    unimplemented("Rf_isVectorList");
+}
+
+Rboolean Rf_isVectorizable(SEXP x) {
+    unimplemented("Rf_isVectorizable");
+}
+
 SEXP Rf_install(const char *name) {
 	JNIEnv *thisenv = getEnv();
 	jstring string = (*thisenv)->NewStringUTF(thisenv, name);
@@ -153,6 +263,11 @@ Rboolean Rf_isString(SEXP s) {
 
 }
 
+SEXP Rf_lcons(SEXP x, SEXP y) {
+	unimplemented("Rf_lcons");
+}
+
+
 SEXP Rf_mkChar(const char *x) {
 	JNIEnv *thisenv = getEnv();
 	// TODO encoding, assume UTF for now
diff --git a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.c b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.c
index 46984b1255..8811ec1af1 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.c
@@ -34,6 +34,7 @@
  */
 jclass CallRFFIHelperClass;
 jclass RDataFactoryClass;
+jclass RRuntimeClass;
 
 static jclass RInternalErrorClass;
 static jmethodID unimplementedMethodID;
@@ -69,6 +70,7 @@ void init_utils(JNIEnv *env) {
 	curenv = env;
 	RDataFactoryClass = checkFindClass(env, "com/oracle/truffle/r/runtime/data/RDataFactory");
 	CallRFFIHelperClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper");
+	RRuntimeClass = checkFindClass(env, "com/oracle/truffle/r/runtime/RRuntime");
 	RInternalErrorClass = checkFindClass(env, "com/oracle/truffle/r/runtime/RInternalError");
 	unimplementedMethodID = checkGetMethodID(env, RInternalErrorClass, "unimplemented", "(Ljava/lang/String;)Ljava/lang/RuntimeException;", 1);
 	createSymbolMethodID = checkGetMethodID(env, RDataFactoryClass, "createSymbol", "(Ljava/lang/String;)Lcom/oracle/truffle/r/runtime/data/RSymbol;", 1);
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 691a89c709..68b98a8665 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h
+++ b/com.oracle.truffle.r.native/fficall/jni/src/rffiutils.h
@@ -78,6 +78,7 @@ void init_utils(JNIEnv *env);
 
 extern jclass RDataFactoryClass;
 extern jclass CallRFFIHelperClass;
+extern jclass RRuntimeClass;
 
 #define TRACE_UPCALLS 0
 
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 5dada5d6d7..15ac1ac69e 100644
--- a/com.oracle.truffle.r.native/fficall/jni/src/variables.c
+++ b/com.oracle.truffle.r.native/fficall/jni/src/variables.c
@@ -46,32 +46,32 @@ SEXP R_UnboundValue;
 SEXP R_MissingArg;
 
 /* Symbol Table Shortcuts */
-//SEXP R_Bracket2Symbol;   /* "[[" */
-//SEXP R_BracketSymbol;    /* "[" */
-//SEXP R_BraceSymbol;      /* "{" */
+SEXP R_Bracket2Symbol;   /* "[[" */
+SEXP R_BracketSymbol;    /* "[" */
+SEXP R_BraceSymbol;      /* "{" */
 SEXP R_ClassSymbol;     /* "class" */
-//SEXP R_DeviceSymbol;     /* ".Device" */
+SEXP R_DeviceSymbol;     /* ".Device" */
 SEXP R_DimNamesSymbol;   /* "dimnames" */
 SEXP R_DimSymbol;     /* "dim" */
-//SEXP R_DollarSymbol;     /* "$" */
-//SEXP R_DotsSymbol;     /* "..." */
-//SEXP R_DropSymbol;     /* "drop" */
-//SEXP R_LastvalueSymbol;  /* ".Last.value" */
-//SEXP R_LevelsSymbol;     /* "levels" */
-//SEXP R_ModeSymbol;     /* "mode" */
-//SEXP R_NameSymbol;     /* "name" */
-//SEXP R_NamesSymbol;     /* "names" */
-//SEXP R_NaRmSymbol;     /* "na.rm" */
-//SEXP R_PackageSymbol;    /* "package" */
-//SEXP R_QuoteSymbol;     /* "quote" */
-//SEXP R_RowNamesSymbol;   /* "row.names" */
-//SEXP R_SeedsSymbol;     /* ".Random.seed" */
-//SEXP R_SourceSymbol;     /* "source" */
-//SEXP R_TspSymbol;     /* "tsp" */
-
-//SEXP  R_dot_defined;      /* ".defined" */
-//SEXP  R_dot_Method;       /* ".Method" */
-//SEXP  R_dot_target;       /* ".target" */
+SEXP R_DollarSymbol;     /* "$" */
+SEXP R_DotsSymbol;     /* "..." */
+SEXP R_DropSymbol;     /* "drop" */
+SEXP R_LastvalueSymbol;  /* ".Last.value" */
+SEXP R_LevelsSymbol;     /* "levels" */
+SEXP R_ModeSymbol;     /* "mode" */
+SEXP R_NameSymbol;     /* "name" */
+SEXP R_NamesSymbol;     /* "names" */
+SEXP R_NaRmSymbol;     /* "na.rm" */
+SEXP R_PackageSymbol;    /* "package" */
+SEXP R_QuoteSymbol;     /* "quote" */
+SEXP R_RowNamesSymbol;   /* "row.names" */
+SEXP R_SeedsSymbol;     /* ".Random.seed" */
+SEXP R_SourceSymbol;     /* "source" */
+SEXP R_TspSymbol;     /* "tsp" */
+
+SEXP  R_dot_defined;      /* ".defined" */
+SEXP  R_dot_Method;       /* ".Method" */
+SEXP  R_dot_target;       /* ".target" */
 SEXP	R_NaString;	    /* NA_STRING as a CHARSXP */
 SEXP	R_BlankString;	    /* "" as a CHARSXP */
 
@@ -166,8 +166,56 @@ void init_variables(JNIEnv *env, jobjectArray initialValues) {
 					R_UnboundValue = ref;
 				} else if (strcmp(nameChars, "R_MissingArg") == 0) {
 					R_MissingArg = ref;
+				} else if (strcmp(nameChars, "R_Bracket2Symbol") == 0) {
+					R_Bracket2Symbol = ref;
+				} else if (strcmp(nameChars, "R_BracketSymbol") == 0) {
+					R_BracketSymbol = ref;
+				} else if (strcmp(nameChars, "R_BraceSymbol") == 0) {
+					R_BraceSymbol = ref;
 				} else if (strcmp(nameChars, "R_ClassSymbol") == 0) {
 					R_ClassSymbol = ref;
+				} else if (strcmp(nameChars, "R_DeviceSymbol") == 0) {
+					R_DeviceSymbol = ref;
+				} else if (strcmp(nameChars, "R_DimNamesSymbol") == 0) {
+					R_DimNamesSymbol = ref;
+				} else if (strcmp(nameChars, "R_DimSymbol") == 0) {
+					R_DimSymbol = ref;
+				} else if (strcmp(nameChars, "R_DollarSymbol") == 0) {
+					R_DollarSymbol = ref;
+				} else if (strcmp(nameChars, "R_DotsSymbol") == 0) {
+					R_DotsSymbol = ref;
+				} else if (strcmp(nameChars, "R_DropSymbol") == 0) {
+					R_DropSymbol = ref;
+				} else if (strcmp(nameChars, "R_LastvalueSymbol") == 0) {
+					R_LastvalueSymbol = ref;
+				} else if (strcmp(nameChars, "R_LevelsSymbol") == 0) {
+					R_LevelsSymbol = ref;
+				} else if (strcmp(nameChars, "R_ModeSymbol") == 0) {
+					R_ModeSymbol = ref;
+				} else if (strcmp(nameChars, "R_NameSymbol") == 0) {
+					R_NameSymbol = ref;
+				} else if (strcmp(nameChars, "R_NamesSymbol") == 0) {
+					R_NamesSymbol = ref;
+				} else if (strcmp(nameChars, "R_NaRmSymbol") == 0) {
+					R_NaRmSymbol = ref;
+				} else if (strcmp(nameChars, "R_PackageSymbol") == 0) {
+					R_PackageSymbol = ref;
+				} else if (strcmp(nameChars, "R_QuoteSymbol") == 0) {
+					R_QuoteSymbol = ref;
+				} else if (strcmp(nameChars, "R_RowNamesSymbol") == 0) {
+					R_RowNamesSymbol = ref;
+				} else if (strcmp(nameChars, "R_SeedsSymbol") == 0) {
+					R_SeedsSymbol = ref;
+				} else if (strcmp(nameChars, "R_SourceSymbol") == 0) {
+					R_SourceSymbol = ref;
+				} else if (strcmp(nameChars, "R_TspSymbol") == 0) {
+					R_TspSymbol = ref;
+				} else if (strcmp(nameChars, "R_dot_defined") == 0) {
+					R_dot_defined = ref;
+				} else if (strcmp(nameChars, "R_dot_Method") == 0) {
+					R_dot_Method = ref;
+				} else if (strcmp(nameChars, "R_dot_target") == 0) {
+					R_dot_target = ref;
 				} else if (strcmp(nameChars, "R_SrcfileSymbol") == 0) {
 					R_SrcfileSymbol = ref;
 				} else if (strcmp(nameChars, "R_SrcrefSymbol") == 0) {
diff --git a/com.oracle.truffle.r.native/include/jni/ed_Rinterface b/com.oracle.truffle.r.native/include/jni/ed_Rinterface
index 9a4c42008d..c8e97b9b39 100644
--- a/com.oracle.truffle.r.native/include/jni/ed_Rinterface
+++ b/com.oracle.truffle.r.native/include/jni/ed_Rinterface
@@ -1,6 +1,7 @@
 /R_Interactive/
 i
 #ifdef FASTR
+LibExtern Rboolean FASTR_Interactive();
 #define R_Interactive FASTR_Interactive()
 #else
 .
diff --git a/com.oracle.truffle.r.native/include/jni/ed_Rinternals b/com.oracle.truffle.r.native/include/jni/ed_Rinternals
index 3072074539..247b85858f 100644
--- a/com.oracle.truffle.r.native/include/jni/ed_Rinternals
+++ b/com.oracle.truffle.r.native/include/jni/ed_Rinternals
@@ -11,6 +11,7 @@ a
 /R_GlobalEnv/
 i
 #ifdef FASTR
+LibExtern SEXP FASTR_GlobalEnv();
 #define R_GlobalEnv FASTR_GlobalEnv()
 #else
 .
@@ -21,6 +22,7 @@ a
 /R_BaseEnv/
 i
 #ifdef FASTR
+LibExtern SEXP FASTR_BaseEnv();
 #define R_BaseEnv FASTR_BaseEnv()
 #else
 .
@@ -31,6 +33,7 @@ a
 /R_BaseNamespace/
 i
 #ifdef FASTR
+LibExtern SEXP FASTR_BaseNamespace();
 #define R_BaseNamespace FASTR_BaseNamespace()
 #else
 .
@@ -41,6 +44,7 @@ a
 /R_NamespaceRegistry/
 i
 #ifdef FASTR
+LibExtern SEXP FASTR_R_NamespaceRegistry();
 #define R_NamespaceRegistry FASTR_NamespaceRegistry()
 #else
 .
diff --git a/com.oracle.truffle.r.native/run/Makefile b/com.oracle.truffle.r.native/run/Makefile
index d3a025305e..a33ef4a509 100644
--- a/com.oracle.truffle.r.native/run/Makefile
+++ b/com.oracle.truffle.r.native/run/Makefile
@@ -79,8 +79,8 @@ $(FASTR_BIN_DIR)/R: Makefile R.sh Rscript.sh Rscript_exec.sh
 	# overrides
 	cp examples-header.R examples-footer.R $(FASTR_SHARE_DIR)/R
 
-includedir: Makefile $(TOPDIR)/include/jni/include/R.h
-	cp -r $(TOPDIR)/include/jni/include $(FASTR_R_HOME)/include
+includedir: Makefile $(TOPDIR)/include/jni/include/Rinternals.h
+	cp -r $(TOPDIR)/include/jni/include/* $(FASTR_R_HOME)/include
 
 clean:
 	rm -rf $(FASTR_BIN_DIR)
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 727f091adc..f1745cb7fe 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
@@ -46,6 +46,10 @@ public class CallRFFIHelper {
         return RDataFactory.createIntVectorFromScalar(value);
     }
 
+    static RLogicalVector Rf_ScalarLogical(int value) {
+        return RDataFactory.createLogicalVectorFromScalar(value != 0);
+    }
+
     static RDoubleVector Rf_ScalarDouble(double value) {
         return RDataFactory.createDoubleVectorFromScalar(value);
     }
@@ -199,6 +203,21 @@ public class CallRFFIHelper {
 
     }
 
+    static Object Rf_allocateArray(int mode, Object dimsObj) {
+        RIntVector dims = (RIntVector) dimsObj;
+        int n = 1;
+        int[] newDims = new int[dims.getLength()];
+        // TODO check long vector
+        for (int i = 0; i < newDims.length; i++) {
+            newDims[i] = dims.getDataAt(i);
+            n *= newDims[i];
+        }
+        RAbstractVector result = (RAbstractVector) Rf_allocateVector(mode, n);
+        result.setDimensions(newDims);
+        return result;
+
+    }
+
     static Object Rf_allocateMatrix(int mode, int ncol, int nrow) {
         SEXPTYPE type = SEXPTYPE.mapInt(mode);
         if (nrow < 0 || ncol < 0) {
@@ -377,4 +396,7 @@ public class CallRFFIHelper {
         return RContext.getInstance().isInteractive() ? 1 : 0;
     }
 
+    static int isS4Object(Object x) {
+        return x instanceof RS4Object ? 1 : 0;
+    }
 }
diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIWithJNI.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIWithJNI.java
index 8b4a963f07..8b1e635f17 100644
--- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIWithJNI.java
+++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIWithJNI.java
@@ -58,31 +58,31 @@ public class CallRFFIWithJNI implements CallRFFI {
         R_BaseNamespace(null),
         R_NamespaceRegistry(null),
         R_Srcref(null),
-        R_Bracket2Symbol(null),
-        R_BracketSymbol(null),
-        R_BraceSymbol(null),
+        R_Bracket2Symbol(RDataFactory.createSymbol("[[")),
+        R_BracketSymbol(RDataFactory.createSymbol("[")),
+        R_BraceSymbol(RDataFactory.createSymbol("{")),
         R_ClassSymbol(RDataFactory.createSymbol("class")),
-        R_DeviceSymbol(null),
-        R_DimNamesSymbol(RDataFactory.createStringVectorFromScalar(RRuntime.DIMNAMES_ATTR_KEY)),
-        R_DimSymbol(RDataFactory.createStringVectorFromScalar(RRuntime.DIM_ATTR_KEY)),
-        R_DollarSymbol(null),
-        R_DotsSymbol(null),
-        R_DropSymbol(null),
-        R_LastvalueSymbol(null),
-        R_LevelsSymbol(null),
-        R_ModeSymbol(null),
-        R_NameSymbol(null),
-        R_NamesSymbol(null),
-        R_NaRmSymbol(null),
-        R_PackageSymbol(null),
-        R_QuoteSymbol(null),
-        R_RowNamesSymbol(null),
-        R_SeedsSymbol(null),
-        R_SourceSymbol(null),
-        R_TspSymbol(null),
-        R_dot_defined(null),
-        R_dot_Method(null),
-        R_dot_target(null),
+        R_DeviceSymbol(RDataFactory.createSymbol(".Device")),
+        R_DimNamesSymbol(RDataFactory.createSymbol("dimnames")),
+        R_DimSymbol(RDataFactory.createSymbol("dim")),
+        R_DollarSymbol(RDataFactory.createSymbol("$")),
+        R_DotsSymbol(RDataFactory.createSymbol("...")),
+        R_DropSymbol(RDataFactory.createSymbol("drop")),
+        R_LastvalueSymbol(RDataFactory.createSymbol(".Last.value")),
+        R_LevelsSymbol(RDataFactory.createSymbol("levels")),
+        R_ModeSymbol(RDataFactory.createSymbol("mode")),
+        R_NameSymbol(RDataFactory.createSymbol("name")),
+        R_NamesSymbol(RDataFactory.createSymbol("names")),
+        R_NaRmSymbol(RDataFactory.createSymbol("na.rm")),
+        R_PackageSymbol(RDataFactory.createSymbol("package")),
+        R_QuoteSymbol(RDataFactory.createSymbol("quote")),
+        R_RowNamesSymbol(RDataFactory.createSymbol("row.names")),
+        R_SeedsSymbol(RDataFactory.createSymbol(".Random.seed")),
+        R_SourceSymbol(RDataFactory.createSymbol("source")),
+        R_TspSymbol(RDataFactory.createSymbol("tsp")),
+        R_dot_defined(RDataFactory.createSymbol(".defined")),
+        R_dot_Method(RDataFactory.createSymbol(".Method")),
+        R_dot_target(RDataFactory.createSymbol(".target")),
         R_SrcrefSymbol(RDataFactory.createSymbol("srcref")),
         R_SrcfileSymbol(RDataFactory.createSymbol("srcfile")),
         R_NaString(RDataFactory.createStringVectorFromScalar(RRuntime.STRING_NA)),
-- 
GitLab