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 c8ef247f6f7abc76ac41990dbf06f05d035dcc58..d097f37157957d136746c9e209fd3834bd0c0f8d 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c @@ -715,7 +715,7 @@ const char *Rf_translateCharUTF8(SEXP x) { SEXP Rf_lengthgets(SEXP x, R_len_t y) { TRACE(TARGp, x); JNIEnv *thisenv = getEnv(); - invalidateCopiedObject(thisenv, x); + invalidateNativeArray(thisenv, x); SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_lengthgetsMethodID, x, y); return checkRef(thisenv, result); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java index 60f28c4e3c08f2e47e3f6efaf291fc0a47e8526f..5b859523cf466216bc992d97418613df6164e8d2 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java @@ -206,7 +206,14 @@ public abstract class DotC extends RBuiltinNode { results[i] = RDataFactory.createIntVector((int[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); break; case SCALAR_LOGICAL: - results[i] = RDataFactory.createLogicalVector((byte[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); + // have to convert back from int[] + int[] nativeIntArgs = (int[]) nativeArgs[i]; + byte[] nativeByteArgs = new byte[nativeIntArgs.length]; + for (int j = 0; j < nativeByteArgs.length; j++) { + int nativeInt = nativeIntArgs[j]; + nativeByteArgs[j] = (byte) (nativeInt == RRuntime.INT_NA ? RRuntime.LOGICAL_NA : nativeInt & 0xFF); + } + results[i] = RDataFactory.createLogicalVector(nativeByteArgs, RDataFactory.COMPLETE_VECTOR); break; case VECTOR_DOUBLE: results[i] = ((RAbstractDoubleVector) array[i]).materialize().copyResetData((double[]) nativeArgs[i]); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java index bd01a896e59b7d4c30544cdec78bebafca66c4bc..14adfe090df8ff15546d3b3680d86abfba13f872 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java @@ -45,6 +45,7 @@ import com.oracle.truffle.r.library.parallel.ParallelFunctionsFactory.MCIsChildN import com.oracle.truffle.r.library.stats.CdistNodeGen; import com.oracle.truffle.r.library.stats.CompleteCases; import com.oracle.truffle.r.library.stats.CovcorNodeGen; +import com.oracle.truffle.r.library.stats.CutreeNodeGen; import com.oracle.truffle.r.library.stats.Dbinom; import com.oracle.truffle.r.library.stats.DoubleCentreNodeGen; import com.oracle.truffle.r.library.stats.GammaFunctionsFactory.QgammaNodeGen; @@ -383,8 +384,8 @@ public class ForeignFunctions { return CdistNodeGen.create(); case "DoubleCentre": return DoubleCentreNodeGen.create(); - case "cutree": + return CutreeNodeGen.create(); case "isoreg": case "monoFC_m": case "numeric_deriv": 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 f1818466bd3b1643929479caff96594ccd93fb1c..add58098c44adde2a5b5cd6009911202cb70cba0 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 @@ -79,6 +79,7 @@ import com.oracle.truffle.r.runtime.env.REnvironment.PutException; import com.oracle.truffle.r.runtime.ffi.RFFIUtils; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; import com.oracle.truffle.r.runtime.nodes.DuplicationHelper; +import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.rng.RRNG; /** @@ -86,6 +87,13 @@ import com.oracle.truffle.r.runtime.rng.RRNG; * R header files, e.g. {@code Rinternals.h} that are used by C/C++ code. For ease of * identification, we use method names that, as far as possible, match the names in the header * files. These methods should never be called from normal FastR code. + * + * TODO Many of the implementations here are incomplete and/or duplicate code that exists in the + * Truffle side of the implementation, i.e., {@link RNode} subclasses. A complete refactoring that + * accesses the Truffle implementations (possibly somewhat refactored owing to the fact that the + * Truffle side is driven by the builtins yet these functions don't not always map 1-1 to a builtin) + * is desirable. In some cases it may be possible to "implement" the functions in R (which is a + * simple way to achieve the above). */ public class CallRFFIHelper { @@ -183,12 +191,15 @@ public class CallRFFIHelper { if (RFFIUtils.traceEnabled()) { RFFIUtils.traceUpCall("Rf_asInteger", x); } + // TODO this is quite incomplete and really should be implemented with CastIntegerNode if (x instanceof Integer) { return ((Integer) x).intValue(); } else if (x instanceof Double) { return RRuntime.double2int((Double) x); } else if (x instanceof Byte) { return RRuntime.logical2int((Byte) x); + } else if (x instanceof RLogicalVector) { + return RRuntime.logical2int(((RLogicalVector) x).getDataAt(0)); } else { guaranteeInstanceOf(x, RIntVector.class); return ((RIntVector) x).getDataAt(0); @@ -722,7 +733,8 @@ public class CallRFFIHelper { 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"); + guarantee(x instanceof RShareable || x instanceof RIntSequence || 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 if (x instanceof RIntSequence) {