Skip to content
Snippets Groups Projects
Commit 08265100 authored by Mick Jordan's avatar Mick Jordan
Browse files

FFI additions

parent 6608f761
No related branches found
No related tags found
No related merge requests found
Showing
with 267 additions and 49 deletions
......@@ -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");
}
......@@ -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
......
......@@ -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);
......
......@@ -78,6 +78,7 @@ void init_utils(JNIEnv *env);
extern jclass RDataFactoryClass;
extern jclass CallRFFIHelperClass;
extern jclass RRuntimeClass;
#define TRACE_UPCALLS 0
......
......@@ -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) {
......
/R_Interactive/
i
#ifdef FASTR
LibExtern Rboolean FASTR_Interactive();
#define R_Interactive FASTR_Interactive()
#else
.
......
......@@ -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
.
......
......@@ -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)
......
......@@ -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;
}
}
......@@ -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)),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment