diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rdynload_fastr.c b/com.oracle.truffle.r.native/fficall/src/jni/Rdynload_fastr.c index 2983383669e0e48e612c4ae8793ffe1aeb54a755..417885a2ce745b30695e0ed1dd6fcb9a1f274925 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rdynload_fastr.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rdynload_fastr.c @@ -141,3 +141,7 @@ DL_FUNC R_FindSymbol(char const *name, char const *pkg, unimplemented("R_FindSymbol"); return NULL; } + +DllInfo *R_getEmbeddingDllInfo(void) { + return (DllInfo*) unimplemented("R_getEmbeddingDllInfo"); +} diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c b/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c index 5aab42e58b92512ac9851bccbbc4a8d57d98ceec..736ef923a833bddd37e907c0bc3f9746147f1513 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c @@ -29,7 +29,9 @@ int R_running_as_main_program; int R_SignalHandlers; FILE * R_Consolefile; FILE * R_Outputfile; - +int R_DirtyImage; // TODO update this +void *R_GlobalContext; // TODO what? +SA_TYPE SaveAction; // ?? typedef jint (JNICALL *JNI_CreateJavaVMFunc) (JavaVM **pvm, void **penv, void *args); @@ -147,6 +149,18 @@ int Rf_initialize_R(int argc, char *argv[]) { return 0; } +char *R_HomeDir(void) { + return (char*) unimplemented("R_HomeDir"); +} + +void R_SaveGlobalEnvToFile(const char *f) { + unimplemented("R_SaveGlobalEnvToFile"); +} + +void R_Suicide(const char *x) { + unimplemented("R_Suicide"); +} + void R_DefParams(Rstart rs) { // These are the GnuR defaults and correspond to the settings in RStartParams // None of the size params make any sense for FastR @@ -371,8 +385,6 @@ JNIEXPORT void JNICALL Java_com_oracle_truffle_r_runtime_ffi_jnr_JNI_1REmbed_nat REmbed_nativeWriteConsole(jniEnv, c, string, 1); } - - JNIEXPORT jstring JNICALL Java_com_oracle_truffle_r_runtime_ffi_jnr_JNI_1REmbed_nativeReadConsole(JNIEnv *env, jclass c, jstring prompt) { const char *cprompt = (*jniEnv)->GetStringUTFChars(jniEnv, prompt, NULL); unsigned char cbuf[1024]; @@ -383,3 +395,24 @@ JNIEXPORT jstring JNICALL Java_com_oracle_truffle_r_runtime_ffi_jnr_JNI_1REmbed_ return result; } +void uR_PolledEvents(void) { + unimplemented("R_PolledEvents"); +} + +void (* R_PolledEvents)(void) = uR_PolledEvents; + +void Rf_jump_to_toplevel() { + unimplemented("Rf_jump_to_toplevel"); +} + +#include <R_ext/eventloop.h> + +fd_set *R_checkActivity(int usec, int ignore_stdin) { + return (fd_set*) unimplemented("R_checkActivity"); +} + +void R_runHandlers(InputHandler *handlers, fd_set *mask) { + unimplemented("R_runHandlers"); +} + +int R_wait_usec; 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 ea9b013cdc14ad8ee3947e78ee4b2dc9379cc94b..8137cc8b1982e88fbd239dababebea3b639a3570 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c @@ -87,6 +87,10 @@ static jmethodID OBJECT_MethodID; static jmethodID DUPLICATE_ATTRIB_MethodID; static jmethodID isS4ObjectMethodID; static jmethodID logObject_MethodID; +static jclass TryEvalResultClass; +static jmethodID R_tryEvalMethodID; +static jfieldID TryEvalResultValueFieldID; +static jfieldID TryEvalResultErrorFieldID; static jclass RExternalPtrClass; static jmethodID createExternalPtrMethodID; @@ -102,7 +106,7 @@ static jmethodID Rf_copyListMatrixMethodID; static jmethodID Rf_copyMatrixMethodID; static jclass CharSXPWrapperClass; -static jfieldID CharXSPWrapperContentsFieldID; +static jfieldID CharSXPWrapperContentsFieldID; void init_internals(JNIEnv *env) { Rf_ScalarIntegerMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarInteger", "(I)Lcom/oracle/truffle/r/runtime/data/RIntVector;", 1); @@ -166,6 +170,10 @@ void init_internals(JNIEnv *env) { DUPLICATE_ATTRIB_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "DUPLICATE_ATTRIB", "(Ljava/lang/Object;Ljava/lang/Object;)V", 1); isS4ObjectMethodID = checkGetMethodID(env, CallRFFIHelperClass, "isS4Object", "(Ljava/lang/Object;)I", 1); logObject_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "logObject", "(Ljava/lang/Object;)V", 1); + TryEvalResultClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper$TryEvalResult"); + R_tryEvalMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_tryEval", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); + TryEvalResultValueFieldID = checkGetFieldID(env, TryEvalResultClass, "value", "Ljava/lang/Object", 0); + TryEvalResultErrorFieldID = checkGetFieldID(env, TryEvalResultClass, "error", "Ljava/lang/Object", 0); RExternalPtrClass = checkFindClass(env, "com/oracle/truffle/r/runtime/data/RExternalPtr"); createExternalPtrMethodID = checkGetMethodID(env, RDataFactoryClass, "createExternalPtr", "(JLjava/lang/Object;Ljava/lang/Object;)Lcom/oracle/truffle/r/runtime/data/RExternalPtr;", 1); @@ -177,7 +185,7 @@ void init_internals(JNIEnv *env) { externalPtrSetProtMethodID = checkGetMethodID(env, RExternalPtrClass, "setProt", "(Ljava/lang/Object;)V", 0); CharSXPWrapperClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/jnr/CallRFFIHelper$CharSXPWrapper"); - CharXSPWrapperContentsFieldID = checkGetFieldID(env, CharSXPWrapperClass, "contents", "Ljava/lang/String;", 0); + CharSXPWrapperContentsFieldID = checkGetFieldID(env, CharSXPWrapperClass, "contents", "Ljava/lang/String;", 0); R_computeIdenticalMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_computeIdentical", "(Ljava/lang/Object;Ljava/lang/Object;I)I", 1); Rf_copyListMatrixMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_copyListMatrix", "(Ljava/lang/Object;Ljava/lang/Object;I)V", 1); @@ -193,7 +201,7 @@ static jstring stringFromCharSXP(JNIEnv *thisenv, SEXP charsxp) { fatalError("only CharSXPWrapper expected in stringFromCharSXP"); } #endif - return (*thisenv)->GetObjectField(thisenv, charsxp, CharXSPWrapperContentsFieldID); + return (*thisenv)->GetObjectField(thisenv, charsxp, CharSXPWrapperContentsFieldID); } SEXP Rf_ScalarInteger(int value) { @@ -308,6 +316,10 @@ SEXP Rf_findVarInFrame(SEXP symbol, SEXP rho) { return checkRef(thisenv, result); } +SEXP Rf_findVarInFrame3(SEXP symbol, SEXP rho, Rboolean b) { + return unimplemented("Rf_findVarInFrame3"); +} + SEXP Rf_getAttrib(SEXP vec, SEXP name) { JNIEnv *thisenv = getEnv(); SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_getAttribMethodID, vec, name); @@ -349,6 +361,10 @@ void Rf_copyVector(SEXP x, SEXP y) { unimplemented("Rf_copyVector"); } +int Rf_countContexts(int x, int y) { + return (int) unimplemented("Rf_countContexts"); +} + Rboolean Rf_inherits(SEXP x, const char * klass) { JNIEnv *thisenv = getEnv(); jstring klazz = (*thisenv)->NewStringUTF(thisenv, klass); @@ -620,12 +636,6 @@ const char *Rf_translateCharUTF8(SEXP x) { return NULL; } -SEXP R_FindNamespace(SEXP info) { - JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_FindNamespaceMethodID, info); - return checkRef(thisenv, result); -} - SEXP Rf_lengthgets(SEXP x, R_len_t y) { TRACE("%s(%p)\n", x); JNIEnv *thisenv = getEnv(); @@ -639,6 +649,10 @@ SEXP Rf_xlengthgets(SEXP x, R_xlen_t y) { } +SEXP R_lsInternal(SEXP x, Rboolean y) { + return unimplemented("R_lsInternal"); +} + SEXP Rf_namesgets(SEXP x, SEXP y) { return unimplemented("Rf_namesgets"); } @@ -1299,12 +1313,100 @@ SEXP R_ExecWithCleanup(SEXP (*fun)(void *), void *data, return unimplemented("R_ExecWithCleanup"); } -SEXP R_tryEval(SEXP x, SEXP y, int *z) { - return unimplemented("R_tryEval"); +/* Environment and Binding Features */ +void R_RestoreHashCount(SEXP rho) { + unimplemented("R_RestoreHashCount"); +} + +Rboolean R_IsPackageEnv(SEXP rho) { + unimplemented("R_IsPackageEnv"); +} + +SEXP R_PackageEnvName(SEXP rho) { + return unimplemented("R_PackageEnvName"); +} + +SEXP R_FindPackageEnv(SEXP info) { + return unimplemented("R_FindPackageEnv"); +} + +Rboolean R_IsNamespaceEnv(SEXP rho) { + return (Rboolean) unimplemented("R_IsNamespaceEnv"); +} + +SEXP R_NamespaceEnvSpec(SEXP rho) { + return unimplemented("R_NamespaceEnvSpec"); +} + +SEXP R_FindNamespace(SEXP info) { + JNIEnv *thisenv = getEnv(); + SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_FindNamespaceMethodID, info); + return checkRef(thisenv, result); +} + +void R_LockEnvironment(SEXP env, Rboolean bindings) { + unimplemented("R_LockEnvironment"); +} + +Rboolean R_EnvironmentIsLocked(SEXP env) { + unimplemented(""); +} + +void R_LockBinding(SEXP sym, SEXP env) { + unimplemented("R_LockBinding"); +} + +void R_unLockBinding(SEXP sym, SEXP env) { + unimplemented("R_unLockBinding"); } -SEXP R_tryEvalSilent(SEXP x, SEXP y, int *z) { - return unimplemented("R_tryEvalSilent"); +void R_MakeActiveBinding(SEXP sym, SEXP fun, SEXP env) { + unimplemented("R_MakeActiveBinding"); +} + +Rboolean R_BindingIsLocked(SEXP sym, SEXP env) { + return (Rboolean) unimplemented("R_BindingIsLocked"); +} + +Rboolean R_BindingIsActive(SEXP sym, SEXP env) { + return (Rboolean) unimplemented("R_BindingIsActive"); +} + +Rboolean R_HasFancyBindings(SEXP rho) { + return (Rboolean) unimplemented("R_HasFancyBindings"); +} + +Rboolean Rf_isS4(SEXP x) { + return (Rboolean) unimplemented("Rf_isS4"); +} + +SEXP Rf_asS4(SEXP x, Rboolean b, int i) { + unimplemented("Rf_asS4"); +} + +static SEXP R_tryEvalInternal(SEXP x, SEXP y, int *ErrorOccurred, jboolean silent) { + JNIEnv *thisenv = getEnv(); + jobject tryResult = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_tryEvalMethodID, x, y, silent); + SEXP value = (*thisenv)->GetObjectField(thisenv, tryResult, TryEvalResultValueFieldID); + jboolean error = (*thisenv)->GetBooleanField(thisenv, tryResult, TryEvalResultErrorFieldID); + if (ErrorOccurred) { + *ErrorOccurred = error = JNI_TRUE; + } + if (error == JNI_TRUE) { + return NULL; + } else { + return value; + } +} + + + +SEXP R_tryEval(SEXP x, SEXP y, int *ErrorOccurred) { + return R_tryEvalInternal(x, y, ErrorOccurred, JNI_FALSE); +} + +SEXP R_tryEvalSilent(SEXP x, SEXP y, int *ErrorOccurred) { + return R_tryEvalInternal(x, y, ErrorOccurred, JNI_TRUE); } double R_atof(const char *str) { @@ -1391,6 +1493,26 @@ void R_RunPendingFinalizers(void) { // TODO implement, but not fail for now } +SEXP R_MakeWeakRef(SEXP key, SEXP val, SEXP fin, Rboolean onexit) { + unimplemented("R_MakeWeakRef"); +} + +SEXP R_MakeWeakRefC(SEXP key, SEXP val, R_CFinalizer_t fin, Rboolean onexit) { + unimplemented("R_MakeWeakRefC"); +} + +SEXP R_WeakRefKey(SEXP w) { + unimplemented("R_WeakRefKey"); +} + +SEXP R_WeakRefValue(SEXP w) { + unimplemented("R_WeakRefValue"); +} + +void R_RunWeakRefFinalizer(SEXP w) { + // TODO implement, but not fail for now +} + SEXP R_do_slot(SEXP obj, SEXP name) { return unimplemented("R_do_slot"); } @@ -1431,6 +1553,11 @@ void R_ReleaseObject(SEXP x) { // Not applicable } +void R_dot_Last(void) { + unimplemented("R_dot_Last"); +} + + Rboolean R_compute_identical(SEXP x, SEXP y, int flags) { JNIEnv *thisenv = getEnv(); return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, R_computeIdenticalMethodID, x, y, flags); @@ -1438,10 +1565,10 @@ Rboolean R_compute_identical(SEXP x, SEXP y, int flags) { void Rf_copyListMatrix(SEXP s, SEXP t, Rboolean byrow) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_copyListMatrixMethodID, s, t, byrow); + (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_copyListMatrixMethodID, s, t, byrow); } void Rf_copyMatrix(SEXP s, SEXP t, Rboolean byrow) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_copyMatrixMethodID, s, t, byrow); + (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_copyMatrixMethodID, s, t, byrow); } 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 0f111ee0ce09b054d39da5f04230805375193a3b..2ca54315c685bd13f33e5de1cba488c94a150f01 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 @@ -711,6 +711,31 @@ public class CallRFFIHelper { throw unimplemented(); } + private static class TryEvalResult { + @SuppressWarnings("unused") final Object value; + @SuppressWarnings("unused") final boolean error; + + TryEvalResult(Object value, boolean error) { + this.value = value; + this.error = error; + } + } + + @SuppressWarnings("unused") + public static TryEvalResult R_tryEval(Object expr, Object env, boolean silent) { + Object handlerStack = RErrorHandling.getHandlerStack(); + Object restartStack = RErrorHandling.getRestartStack(); + try { + // TODO handle silent + RErrorHandling.resetStacks(); + Object result = Rf_eval(expr, env); + // TODO did an error occur? + return new TryEvalResult(result, false); + } finally { + RErrorHandling.restoreStacks(handlerStack, restartStack); + } + } + // Checkstyle: resume method name check public static Object validate(Object x) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java index 508a44b4e52978d05d46a854080aa70fd7b58392..01acffda1dbacd00a9937820fe7afb2734e3ae78 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java @@ -177,6 +177,17 @@ public class RErrorHandling { return getRErrorHandlingState().restartStack; } + /** + * Resets the handler stacks for a "top-level" evaluation ({@code Rf_tryEval} in the R FFI. This + * must be preceded by calls to {@link #getHandlerStack} and {@link #getRestartStack()} and + * followed by {@link #restoreStacks} after the evaluation completes. + */ + public static void resetStacks() { + ContextStateImpl errorHandlingState = getRErrorHandlingState(); + errorHandlingState.handlerStack = RNull.instance; + errorHandlingState.restartStack = RNull.instance; + } + public static void restoreStacks(Object savedHandlerStack, Object savedRestartStack) { ContextStateImpl errorHandlingState = getRErrorHandlingState(); errorHandlingState.handlerStack = savedHandlerStack; diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c index ec033b48756d757747777234d4b97e39887da035..3c30a0cde37903f79cdba7eb4f349e9d85f32d3d 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c @@ -140,3 +140,7 @@ SEXP interactive(void) { return ScalarLogical(R_Interactive); } +SEXP tryEval(SEXP expr, SEXP env) { +} + +}