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 b86229a115ec850ed2d81b4533c2efdd51a16cb7..d6e16e35f3ab64c5b53d685795487bde09fe74b5 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 @@ -13,6 +13,7 @@ #include <Rdynload.h> // Registering routines from loaded shared libraries +// Currently an exception to the rule that all upcalls go via CallRFFIHelper static jclass DLLClass; static jclass JNI_PkgInitClass; 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 ff81c0002ad83c7a456d22843abb2b4c022290bd..3972ae97f451a894d5e79a20b95c3e47276496b6 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c @@ -30,6 +30,8 @@ // to ensure that a global JNI handle is created (if necessary) and returned, // otherwise a GC might reclaim the result. +// N.B. ALL functions go via CallRFFIHelper to provide a single point of re-entry + static jmethodID Rf_ScalarIntegerMethodID; static jmethodID Rf_ScalarDoubleMethodID; static jmethodID Rf_ScalarStringMethodID; @@ -50,10 +52,11 @@ static jmethodID Rf_getAttribMethodID; static jmethodID Rf_setAttribMethodID; static jmethodID Rf_isStringMethodID; static jmethodID Rf_isNullMethodID; +static jmethodID Rf_installMethodID; static jmethodID Rf_warningcallMethodID; static jmethodID Rf_warningMethodID; static jmethodID Rf_errorMethodID; -static jmethodID Rf_NewHashedEnvMethodID; +static jmethodID R_NewHashedEnvMethodID; static jmethodID Rf_classgetsMethodID; static jmethodID Rf_rPsortMethodID; static jmethodID Rf_iPsortMethodID; @@ -110,22 +113,16 @@ static jmethodID PRVALUEMethodID; static jmethodID R_lsInternal3MethodID; static jmethodID R_do_MAKE_CLASS_MethodID; -static jclass rErrorHandlingClass; -static jclass handlerStacksClass; static jmethodID resetAndGetHandlerStacksMethodID; static jmethodID restoreHandlerStacksMethodID; -static jclass SymbolHandleClass; -static jmethodID symbolHandleConsMethodID; - -static jclass RExternalPtrClass; -static jmethodID createExternalPtrMethodID; -static jmethodID externalPtrGetAddrMethodID; -static jmethodID externalPtrGetTagMethodID; -static jmethodID externalPtrGetProtMethodID; -static jmethodID externalPtrSetAddrMethodID; -static jmethodID externalPtrSetTagMethodID; -static jmethodID externalPtrSetProtMethodID; +static jmethodID R_MakeExternalPtrMethodID; +static jmethodID R_ExternalPtrAddrMethodID; +static jmethodID R_ExternalPtrTagMethodID; +static jmethodID R_ExternalPtrProtMethodID; +static jmethodID R_SetExternalPtrAddrMethodID; +static jmethodID R_SetExternalPtrTagMethodID; +static jmethodID R_SetExternalPtrProtMethodID; static jmethodID R_computeIdenticalMethodID; static jmethodID Rf_copyListMatrixMethodID; @@ -154,6 +151,7 @@ void init_internals(JNIEnv *env) { Rf_setAttribMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_setAttrib", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 1); Rf_isStringMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_isString", "(Ljava/lang/Object;)I", 1); Rf_isNullMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_isNull", "(Ljava/lang/Object;)I", 1); + Rf_installMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_install", "(Ljava/lang/String;)Ljava/lang/Object;", 1); Rf_warningMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_warning", "(Ljava/lang/String;)V", 1); Rf_warningcallMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_warningcall", "(Ljava/lang/Object;Ljava/lang/String;)V", 1); Rf_errorMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_error", "(Ljava/lang/String;)V", 1); @@ -162,7 +160,7 @@ void init_internals(JNIEnv *env) { Rf_allocateArrayMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_allocateArray", "(ILjava/lang/Object;)Ljava/lang/Object;", 1); Rf_duplicateMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_duplicate", "(Ljava/lang/Object;I)Ljava/lang/Object;", 1); Rf_anyDuplicatedMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_anyDuplicated", "(Ljava/lang/Object;I)I", 1); - Rf_NewHashedEnvMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_createNewEnv", "(Lcom/oracle/truffle/r/runtime/env/REnvironment;Ljava/lang/String;ZI)Lcom/oracle/truffle/r/runtime/env/REnvironment;", 1); + R_NewHashedEnvMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_NewHashedEnv", "(Lcom/oracle/truffle/r/runtime/env/REnvironment;Ljava/lang/String;ZI)Lcom/oracle/truffle/r/runtime/env/REnvironment;", 1); Rf_classgetsMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_classgets", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); RprintfMethodID = checkGetMethodID(env, CallRFFIHelperClass, "printf", "(Ljava/lang/String;)V", 1); R_do_MAKE_CLASS_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_do_MAKE_CLASS", "(Ljava/lang/String;)Ljava/lang/Object;", 1); @@ -218,22 +216,17 @@ void init_internals(JNIEnv *env) { PRVALUEMethodID = checkGetMethodID(env, CallRFFIHelperClass, "PRVALUE", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); R_lsInternal3MethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_lsInternal3", "(Ljava/lang/Object;II)Ljava/lang/Object;", 1); - rErrorHandlingClass = checkFindClass(env, "com/oracle/truffle/r/runtime/RErrorHandling"); - handlerStacksClass = checkFindClass(env, "com/oracle/truffle/r/runtime/RErrorHandling$HandlerStacks"); - resetAndGetHandlerStacksMethodID = checkGetMethodID(env, rErrorHandlingClass, "resetAndGetHandlerStacks", "()Lcom/oracle/truffle/r/runtime/RErrorHandling$HandlerStacks;", 1); - restoreHandlerStacksMethodID = checkGetMethodID(env, rErrorHandlingClass, "restoreHandlerStacks", "(Lcom/oracle/truffle/r/runtime/RErrorHandling$HandlerStacks;)V", 1); - - RExternalPtrClass = checkFindClass(env, "com/oracle/truffle/r/runtime/data/RExternalPtr"); - createExternalPtrMethodID = checkGetMethodID(env, RDataFactoryClass, "createExternalPtr", "(Lcom/oracle/truffle/r/runtime/ffi/DLL$SymbolHandle;Ljava/lang/Object;Ljava/lang/Object;)Lcom/oracle/truffle/r/runtime/data/RExternalPtr;", 1); - externalPtrGetAddrMethodID = checkGetMethodID(env, RExternalPtrClass, "getAddr", "()Lcom/oracle/truffle/r/runtime/ffi/DLL$SymbolHandle;", 0); - externalPtrGetTagMethodID = checkGetMethodID(env, RExternalPtrClass, "getTag", "()Ljava/lang/Object;", 0); - externalPtrGetProtMethodID = checkGetMethodID(env, RExternalPtrClass, "getProt", "()Ljava/lang/Object;", 0); - externalPtrSetAddrMethodID = checkGetMethodID(env, RExternalPtrClass, "setAddr", "(Lcom/oracle/truffle/r/runtime/ffi/DLL$SymbolHandle;)V", 0); - externalPtrSetTagMethodID = checkGetMethodID(env, RExternalPtrClass, "setTag", "(Ljava/lang/Object;)V", 0); - externalPtrSetProtMethodID = checkGetMethodID(env, RExternalPtrClass, "setProt", "(Ljava/lang/Object;)V", 0); - - SymbolHandleClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/DLL$SymbolHandle"); - symbolHandleConsMethodID = checkGetMethodID(env, SymbolHandleClass, "<init>", "(Ljava/lang/Object;)V", 0); + resetAndGetHandlerStacksMethodID = checkGetMethodID(env, CallRFFIHelperClass, "resetAndGetErrorHandlerStacks", "()Ljava/lang/Object;", 1); + restoreHandlerStacksMethodID = checkGetMethodID(env, CallRFFIHelperClass, "restoreErrorHandlerStacks", "(Ljava/lang/Object;)V", 1); + + R_MakeExternalPtrMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_MakeExternalPtr", "(JLjava/lang/Object;Ljava/lang/Object;)Lcom/oracle/truffle/r/runtime/data/RExternalPtr;", 1); + R_ExternalPtrAddrMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_ExternalPtrAddr", "(Ljava/lang/Object;)J", 1); + R_ExternalPtrTagMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_ExternalPtrTag", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); + R_ExternalPtrProtMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_ExternalPtrProt", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); + R_SetExternalPtrAddrMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_SetExternalPtrAddr", "(Ljava/lang/Object;J)V", 1); + R_SetExternalPtrTagMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_SetExternalPtrTag", "(Ljava/lang/Object;Ljava/lang/Object;)V", 1); + R_SetExternalPtrProtMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_SetExternalPtrProt", "(Ljava/lang/Object;Ljava/lang/Object;)V", 1); + CharSXPWrapperClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper$CharSXPWrapper"); CharSXPWrapperContentsFieldID = checkGetFieldID(env, CharSXPWrapperClass, "contents", "Ljava/lang/String;", 0); @@ -484,7 +477,7 @@ SEXP Rf_install(const char *name) { TRACE(TARGs, name); JNIEnv *thisenv = getEnv(); jstring string = (*thisenv)->NewStringUTF(thisenv, name); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createSymbolMethodID, string); + SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_installMethodID, string); return checkRef(thisenv, result); } @@ -492,7 +485,7 @@ SEXP Rf_installChar(SEXP charsxp) { TRACE(TARGp, charsxp); JNIEnv *thisenv = getEnv(); jstring string = stringFromCharSXP(thisenv, charsxp); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createSymbolMethodID, string); + SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_installMethodID, string); return checkRef(thisenv, result); } @@ -533,7 +526,7 @@ SEXP Rf_mkCharLenCE(const char *x, int len, cetype_t enc) { TRACE(TARGsdd, x, len, enc); JNIEnv *thisenv = getEnv(); jbyteArray bytes = (*thisenv)->NewByteArray(thisenv, len); - (*thisenv)->SetByteArrayRegion(thisenv, bytes, 0, len, x); + (*thisenv)->SetByteArrayRegion(thisenv, bytes, 0, len, (const jbyte *) x); SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_mkCharLenCEMethodID, bytes, (int) enc); return checkRef(thisenv, result); } @@ -550,13 +543,13 @@ SEXP Rf_mkString(const char *s) { int Rf_ncols(SEXP x) { TRACE(TARGs, x); JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_ncolsMethodID, x); + return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_ncolsMethodID, x); } int Rf_nrows(SEXP x) { TRACE(TARGs, x); JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_nrowsMethodID, x); + return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_nrowsMethodID, x); } @@ -686,17 +679,15 @@ void R_ProcessEvents(void) { } // Tools package support, not in public API - SEXP R_NewHashedEnv(SEXP parent, SEXP size) { JNIEnv *thisenv = getEnv(); - int sizeAsInt = Rf_asInteger(size); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, Rf_NewHashedEnvMethodID, parent, NULL, JNI_TRUE, sizeAsInt); + SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_NewHashedEnvMethodID, parent, size); return checkRef(thisenv, result); } SEXP Rf_classgets(SEXP vec, SEXP klass) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, Rf_classgetsMethodID, vec, klass); + SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_classgetsMethodID, vec, klass); return checkRef(thisenv, result); } @@ -1342,7 +1333,7 @@ const char *R_CHAR(SEXP charsxp) { TRACE("%s(%p)", charsxp); JNIEnv *thisenv = getEnv(); jstring string = stringFromCharSXP(thisenv, charsxp); - char *copyChars = stringToChars(thisenv, string); + char *copyChars = (char *) stringToChars(thisenv, string); TRACE(" %s(%s)\n", copyChars); return copyChars; } @@ -1516,41 +1507,40 @@ SEXP R_forceAndCall(SEXP e, int n, SEXP rho) { SEXP R_MakeExternalPtr(void *p, SEXP tag, SEXP prot) { JNIEnv *thisenv = getEnv(); - jobject handle = (*thisenv)->CallStaticObjectMethod(thisenv, SymbolHandleClass, symbolHandleConsMethodID, (jobject) p); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, RDataFactoryClass, createExternalPtrMethodID, handle, tag, prot); + SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_MakeExternalPtrMethodID, (jlong) p, tag, prot); return checkRef(thisenv, result); } void *R_ExternalPtrAddr(SEXP s) { JNIEnv *thisenv = getEnv(); - return (void *) (*thisenv)->CallLongMethod(thisenv, s, externalPtrGetAddrMethodID); + return (void *) (*thisenv)->CallStaticLongMethod(thisenv, CallRFFIHelperClass, R_ExternalPtrAddrMethodID, s); } SEXP R_ExternalPtrTag(SEXP s) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallObjectMethod(thisenv, s, externalPtrGetTagMethodID); + SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_ExternalPtrTagMethodID, s); return checkRef(thisenv, result); } SEXP R_ExternalPtrProt(SEXP s) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallObjectMethod(thisenv, s, externalPtrGetProtMethodID); + SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_ExternalPtrProtMethodID, s); return checkRef(thisenv, result); } void R_SetExternalPtrAddr(SEXP s, void *p) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallLongMethod(thisenv, s, externalPtrSetAddrMethodID, (jlong) p); + (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, R_SetExternalPtrAddrMethodID, s, (jlong) p); } void R_SetExternalPtrTag(SEXP s, SEXP tag) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallObjectMethod(thisenv, s, externalPtrSetTagMethodID, tag); + (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, R_SetExternalPtrTagMethodID, s, tag); } void R_SetExternalPtrProtected(SEXP s, SEXP p) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallObjectMethod(thisenv, s, externalPtrSetProtMethodID, p); + (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, R_SetExternalPtrProtMethodID, s, p); } void R_ClearExternalPtr(SEXP s) { 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 aa7a7506b4e8ff58c4fde9ed424c98c9ff848c64..0010587bccde3b3ea603407a66e2a05727d9f2f9 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c @@ -33,13 +33,8 @@ * (portably) for MT use. JNI provides no help. */ jclass CallRFFIHelperClass; -jclass RDataFactoryClass; -jclass RRuntimeClass; jclass CharSXPWrapperClass; -static jclass RInternalErrorClass; -static jmethodID unimplementedMethodID; -jmethodID createSymbolMethodID; static jmethodID validateMethodID; static JNIEnv *curenv = NULL; @@ -114,12 +109,7 @@ void init_utils(JNIEnv *env) { setvbuf(traceFile, (char*) NULL, _IONBF, 0); } } - RDataFactoryClass = checkFindClass(env, "com/oracle/truffle/r/runtime/data/RDataFactory"); CallRFFIHelperClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/jni/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, "createSymbolInterned", "(Ljava/lang/String;)Lcom/oracle/truffle/r/runtime/data/RSymbol;", 1); validateMethodID = checkGetMethodID(env, CallRFFIHelperClass, "validate", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); cachedGlobalRefs = calloc(CACHED_GLOBALREFS_INITIAL_SIZE, sizeof(GlobalRefElem)); cachedGlobalRefsLength = CACHED_GLOBALREFS_INITIAL_SIZE; 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 9ace813ba473f3d71d4f44b9972c9aea3fc26eda..3a3539579ec0912b64229bbe5709c4c1cab4c719 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h +++ b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h @@ -38,7 +38,6 @@ void setEnv(JNIEnv *env); jclass checkFindClass(JNIEnv *env, const char *name); jmethodID checkGetMethodID(JNIEnv *env, jclass klass, const char *name, const char *sig, int isStatic); jfieldID checkGetFieldID(JNIEnv *env, jclass klass, const char *name, const char *sig, int isStatic); -extern jmethodID createSymbolMethodID; // use for an unimplemented API function void *unimplemented(char *msg); @@ -91,9 +90,7 @@ void setEmbedded(void); void setTempDir(JNIEnv *, jstring tempDir); -extern jclass RDataFactoryClass; extern jclass CallRFFIHelperClass; -extern jclass RRuntimeClass; extern FILE *traceFile; // tracing/debugging support, set to 1 and recompile to enable diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java index 5849eeabcc7cd2fcd6e7d881864ba24a800d6020..fa73127bcec10decf22135b9317a62cbf70d5ce1 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java @@ -78,6 +78,7 @@ 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; +import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.RFFIUtils; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; import com.oracle.truffle.r.runtime.nodes.DuplicationHelper; @@ -99,6 +100,14 @@ import com.oracle.truffle.r.runtime.rng.RRNG; */ public class CallRFFIHelper { + /** + * Internally GNU R distinguishes "strings" and "vectors of strings" using the {@code CHARSXP} + * and {@code STRSXP} types, respectively. Although this difference is invisible at the R level, + * it manifests itself in the R FFI as several functions traffic in the {@code CHARSXP} type. + * Since FastR already uses {@code String} to denote a length-1 string vector, it cannot be used + * to represent a {@code CHARSXP}, so this class exists to do so. + * + */ public static final class CharSXPWrapper { private final String contents; @@ -420,6 +429,13 @@ public class CallRFFIHelper { return result; } + public static Object Rf_install(String name) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_install", name); + } + return RDataFactory.createSymbolInterned(name); + } + public static Object Rf_lengthgets(Object x, int newSize) { if (RFFIUtils.traceEnabled()) { RFFIUtils.traceUpCall("Rf_lengthgets", x, newSize); @@ -1018,15 +1034,6 @@ public class CallRFFIHelper { // TODO: copy OBJECT? and S4 attributes } - public static REnvironment Rf_createNewEnv(REnvironment parent, String name, boolean hashed, int initialSize) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_createNewEnv", parent, name, hashed, initialSize); - } - REnvironment env = RDataFactory.createNewEnv(name, hashed, initialSize); - RArguments.initializeEnclosingFrame(env.getFrame(), parent.getFrame()); - return env; - } - public static int R_computeIdentical(Object x, Object y, int flags) { if (RFFIUtils.traceEnabled()) { RFFIUtils.traceUpCall("R_computeIdentical", x, y, flags); @@ -1071,6 +1078,27 @@ public class CallRFFIHelper { } } + /** + * Helper function for {@code R_TopLevelExec} which is similar to {@code R_TryEval} except that + * a C function is invoked (in the native layer) instead of an R expression. assert: this is + * ONLY called from R_TopLevelExec prior to calling C function. + */ + public static Object resetAndGetErrorHandlerStacks() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_TopLevelExec"); + } + return RErrorHandling.resetAndGetHandlerStacks(); + } + + /** + * Helper function for {@code R_TopLevelExec}, see {@link #resetAndGetErrorHandlerStacks()}, + * called after C function returns. + */ + public static void restoreErrorHandlerStacks(Object stacks) { + RErrorHandling.HandlerStacks handlerStacks = guaranteeInstanceOf(stacks, RErrorHandling.HandlerStacks.class); + RErrorHandling.restoreHandlerStacks(handlerStacks); + } + public static int RDEBUG(Object x) { if (RFFIUtils.traceEnabled()) { RFFIUtils.traceUpCall("RDEBUG", x); @@ -1436,4 +1464,68 @@ public class CallRFFIHelper { return RNull.instance; } + public static RExternalPtr R_MakeExternalPtr(long addr, Object tag, Object prot) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_MakeExternalPtr", addr, tag, prot); + } + return RDataFactory.createExternalPtr(new SymbolHandle(addr), tag, prot); + } + + public static long R_ExternalPtrAddr(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_ExternalPtrAddr", x); + } + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + return p.getAddr().asAddress(); + } + + public static Object R_ExternalPtrTag(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_ExternalPtrTag", x); + } + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + return p.getTag(); + } + + public static Object R_ExternalPtrProt(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_ExternalPtrProt", x); + } + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + return p.getProt(); + } + + public static void R_SetExternalPtrAddr(Object x, long addr) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_SetExternalPtrAddr", x); + } + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + p.setAddr(new SymbolHandle(addr)); + } + + public static void R_SetExternalPtrTag(Object x, Object tag) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_SetExternalPtrTag", x); + } + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + p.setTag(tag); + } + + public static void R_SetExternalPtrProt(Object x, Object prot) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_ExternalPtrProt", x); + } + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + p.setProt(prot); + } + + public static REnvironment R_NewHashedEnv(REnvironment parent, String name, boolean hashed, int initialSize) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_NewHashedEnv", parent, name, hashed, initialSize); + } + REnvironment env = RDataFactory.createNewEnv(name, hashed, initialSize); + RArguments.initializeEnclosingFrame(env.getFrame(), parent.getFrame()); + return env; + } + } diff --git a/mx.fastr/mx_fastr.py b/mx.fastr/mx_fastr.py index 8b88672dec8e4eabbae35236a26d532e6f0a01c5..6815ab54d6de730e1afd12291a18fd8c4ddde57f 100644 --- a/mx.fastr/mx_fastr.py +++ b/mx.fastr/mx_fastr.py @@ -533,6 +533,26 @@ def gnu_rscript(args, env=None): cmd = [join(_gnur_path(), 'Rscript')] + args return mx.run(cmd, nonZeroIsFatal=False, env=env) +def nativebuild(args): + ''' + force the build of part or all of the native project + ''' + parser = ArgumentParser(prog='nativebuild') + parser.add_argument('--all', action='store_true', help='clean and build everything, else just ffi') + args = parser.parse_args(args) + nativedir = mx.project('com.oracle.truffle.r.native').dir + if args.all: + return subprocess.call(['make clean && make'], shell=True, cwd=nativedir) + else: + ffidir = join(nativedir, 'fficall') + jni_done = join(ffidir, 'jni.done') + jniboot_done = join(ffidir, 'jniboot.done') + if os.path.exists(jni_done): + os.remove(jni_done) + if os.path.exists(jniboot_done): + os.remove(jniboot_done) + return mx.build(['--no-java']) + def mx_post_parse_cmd_line(opts): mx_fastr_dists.mx_post_parse_cmd_line(opts) @@ -563,6 +583,7 @@ _commands = { 'rupdatelib' : [mx_copylib.updatelib, '[]'], 'gnu-r' : [gnu_r, '[]'], 'gnu-rscript' : [gnu_rscript, '[]'], + 'nativebuild' : [nativebuild, '[]'], } mx.update_commands(_fastr_suite, _commands)