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 a5c4ac637f69b5193a979f241931a08f918a5da4..2b3a43d94cc357500dd485a4cc5c61203324491a 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c @@ -150,7 +150,7 @@ void init_internals(JNIEnv *env) { 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_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); RprintfMethodID = checkGetMethodID(env, CallRFFIHelperClass, "printf", "(Ljava/lang/String;)V", 1); @@ -382,7 +382,14 @@ SEXP Rf_setAttrib(SEXP vec, SEXP name, SEXP val) { SEXP Rf_duplicate(SEXP x) { TRACE(TARGp, x); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_duplicateMethodID, x); + SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_duplicateMethodID, x, 1); + return checkRef(thisenv, result); +} + +SEXP Rf_shallow_duplicate(SEXP x) { + TRACE(TARGp, x); + JNIEnv *thisenv = getEnv(); + SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_duplicateMethodID, x, 0); return checkRef(thisenv, result); } 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 3d6bbf5431b18850e1cb6488f3ad68289ca8c137..90b4c432b56edd5a12d9ad6264a3a351a6f13b89 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 @@ -703,12 +703,17 @@ public class CallRFFIHelper { } } - public static Object Rf_duplicate(Object x) { + public static Object Rf_duplicate(Object x, int deep) { if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_duplicate", x); + RFFIUtils.traceUpCall("Rf_duplicate", x, deep); + } + guarantee(x != null, "unexpected type: null instead of " + x.getClass().getSimpleName()); + guarantee(x instanceof RShareable || x instanceof RExternalPtr, "unexpected type: " + x + " is " + x.getClass().getSimpleName() + " instead of RShareable or RExternalPtr"); + if (x instanceof RShareable) { + return deep == 1 ? ((RShareable) x).deepCopy() : ((RShareable) x).copy(); + } else { + return ((RExternalPtr) x).copy(); } - guaranteeInstanceOf(x, RAbstractVector.class); - return ((RAbstractVector) x).copy(); } public static int Rf_anyDuplicated(Object x, int fromLast) {