diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java index 523b80e3b1e3fd1e07026931e2e2f47a1c1caffa..b88e5f750fc84c9ccc9c4960e8e4f529b261f2ba 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java @@ -635,18 +635,20 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { } @Override - @TruffleBoundary public long Rf_any_duplicated(Object x, int fromLast) { - RAbstractVector vec = (RAbstractVector) x; - if (vec.getLength() <= 1) { - return 0; - } else { - return DuplicationHelper.analyze(vec, null, true, fromLast != 0).getIndex(); - } + throw implementedAsNode(); + } + + @Override + public long Rf_any_duplicated3(Object x, Object incomparables, int fromLast) { + throw implementedAsNode(); } @Override public Object PRINTNAME(Object x) { + if (x == RNull.instance) { + return x; + } guaranteeInstanceOf(x, RSymbol.class); return CharSXPWrapper.create(((RSymbol) x).getName()); } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DuplicateNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DuplicateNodes.java index 4eab0d8673373a401ed93d7e7091d7ae122d7e62..ff0dbb981c6475531d933cf9613037766f642b0b 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DuplicateNodes.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/DuplicateNodes.java @@ -23,14 +23,21 @@ package com.oracle.truffle.r.ffi.impl.nodes; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodesFactory.DuplicateNodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodesFactory.RfAnyDuplicated3NodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodesFactory.RfAnyDuplicatedNodeGen; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RSequence; import com.oracle.truffle.r.runtime.data.RShareable; import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.nodes.DuplicationHelper; public final class DuplicateNodes { @@ -58,6 +65,11 @@ public final class DuplicateNodes { return val; } + @Fallback + public Object doOther(Object x, Object y) { + throw unsupportedTypes("Rf_duplicate", x, y); + } + protected static boolean isReusableForDuplicate(Object o) { return o == RNull.instance || o instanceof REnvironment || o instanceof RSymbol; } @@ -67,4 +79,45 @@ public final class DuplicateNodes { } } + public abstract static class RfAnyDuplicated extends FFIUpCallNode.Arg2 { + @Specialization + public int doDuplicate(RAbstractVector vec, int fromLast, + @Cached("createBinaryProfile()") ConditionProfile isEmptyProfile) { + if (isEmptyProfile.profile(vec.getLength() <= 1)) { + return 0; + } else { + return DuplicationHelper.analyze(vec, null, true, fromLast != 0).getIndex(); + } + } + + @Fallback + public Object doOthers(Object vec, Object fromLast) { + throw unsupportedTypes("Rf_any_duplicated", vec, fromLast); + } + + public static RfAnyDuplicated create() { + return RfAnyDuplicatedNodeGen.create(); + } + } + + public abstract static class RfAnyDuplicated3 extends FFIUpCallNode.Arg3 { + @Specialization + public int doDuplicate(RAbstractVector vec, RAbstractVector incomparables, int fromLast, + @Cached("createBinaryProfile()") ConditionProfile isEmptyProfile) { + if (isEmptyProfile.profile(vec.getLength() <= 1)) { + return 0; + } else { + return DuplicationHelper.analyze(vec, incomparables, true, fromLast != 0).getIndex(); + } + } + + @Fallback + public Object doOthers(Object vec, Object incomparables, Object fromLast) { + throw unsupportedTypes("Rf_any_duplicated3", vec, incomparables, fromLast); + } + + public static RfAnyDuplicated3 create() { + return RfAnyDuplicated3NodeGen.create(); + } + } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java index 5df825b06b78e80c37dfb663f2f3b2c4c311a156..4a86d30d42e81a4811fdde6e7983a6328b67e30b 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,11 +22,26 @@ */ package com.oracle.truffle.r.ffi.impl.nodes; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RError.Message; +import com.oracle.truffle.r.runtime.Utils; public abstract class FFIUpCallNode extends Node { protected abstract int numArgs(); + @TruffleBoundary + protected final RError unsupportedTypes(String name, Object... args) { + assert args.length > 0; + StringBuilder sb = new StringBuilder(args.length * 15); + sb.append("wrong argument types provided to Rf_duplicated: ").append(Utils.getTypeName(args[0])); + for (int i = 1; i < args.length; i++) { + sb.append(',').append(Utils.getTypeName(args[i])); + } + throw RError.error(RError.NO_CALLER, Message.GENERIC, sb); + } + public abstract static class Arg0 extends FFIUpCallNode { public abstract Object executeObject(); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java index a576084b4f92e967c536c75f70d17c849d4f3745..c74c97380988dc47a87c715faa2f94fa57be56f2 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java @@ -34,9 +34,11 @@ import com.oracle.truffle.r.ffi.impl.nodes.CoerceNodes.CoerceVectorNode; import com.oracle.truffle.r.ffi.impl.nodes.CoerceNodes.VectorToPairListNode; import com.oracle.truffle.r.ffi.impl.nodes.DoMakeClassNode; import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodes; -import com.oracle.truffle.r.ffi.impl.nodes.GetClassDefNode; +import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodes.RfAnyDuplicated; +import com.oracle.truffle.r.ffi.impl.nodes.DuplicateNodes.RfAnyDuplicated3; import com.oracle.truffle.r.ffi.impl.nodes.EnvNodes.LockBindingNode; import com.oracle.truffle.r.ffi.impl.nodes.EnvNodes.UnlockBindingNode; +import com.oracle.truffle.r.ffi.impl.nodes.GetClassDefNode; import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CAARNode; import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CAD4RNode; import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CADDDRNode; @@ -206,8 +208,12 @@ public interface StdUpCallsRFFI { @RFFIUpCallNode(DuplicateNodes.DuplicateNode.class) Object Rf_duplicate(Object x, int deep); + @RFFIUpCallNode(RfAnyDuplicated.class) long Rf_any_duplicated(Object x, int fromLast); + @RFFIUpCallNode(RfAnyDuplicated3.class) + long Rf_any_duplicated3(Object x, Object incomparables, int fromLast); + Object PRINTNAME(Object x); @RFFIUpCallNode(TAG.class) diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h index 1a6bc2c49b7a21559098ea7126a3d1a70ec9c902..e60dcbfe7fe9af0207c983535a0907aca7533757 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h +++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h @@ -57,6 +57,7 @@ typedef SEXP (*call_Rf_duplicate)(SEXP x, int v); typedef SEXP (*call_Rf_shallow_duplicate)(SEXP x); typedef SEXP (*call_Rf_coerceVector)(SEXP x, SEXPTYPE mode); typedef R_xlen_t (*call_Rf_any_duplicated)(SEXP x, Rboolean from_last); +typedef R_xlen_t (*call_Rf_any_duplicated3)(SEXP x, SEXP y, Rboolean from_last); typedef SEXP (*call_Rf_duplicated)(SEXP x, Rboolean y); typedef SEXP (*call_Rf_applyClosure)(SEXP x, SEXP y, SEXP z, SEXP a, SEXP b); typedef int (*call_Rf_copyMostAttrib)(SEXP x, SEXP y); diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h index 8c6c12994411ddc5c7c0fa7a6e43e5ce5c922238..1dc742abd6f75f1fc437844b34bf8872c4e2dd37 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h +++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h @@ -104,98 +104,99 @@ #define Rf_allocMatrix_x 99 #define Rf_allocVector_x 100 #define Rf_any_duplicated_x 101 -#define Rf_asChar_x 102 -#define Rf_asCharacterFactor_x 103 -#define Rf_asInteger_x 104 -#define Rf_asLogical_x 105 -#define Rf_asReal_x 106 -#define Rf_classgets_x 107 -#define Rf_coerceVector_x 108 -#define Rf_cons_x 109 -#define Rf_copyListMatrix_x 110 -#define Rf_copyMatrix_x 111 -#define Rf_copyMostAttrib_x 112 -#define Rf_dchisq_x 113 -#define Rf_defineVar_x 114 -#define Rf_dnchisq_x 115 -#define Rf_dunif_x 116 -#define Rf_duplicate_x 117 -#define Rf_error_x 118 -#define Rf_errorcall_x 119 -#define Rf_eval_x 120 -#define Rf_findFun_x 121 -#define Rf_findVar_x 122 -#define Rf_findVarInFrame_x 123 -#define Rf_findVarInFrame3_x 124 -#define Rf_getAttrib_x 125 -#define Rf_gsetVar_x 126 -#define Rf_inherits_x 127 -#define Rf_install_x 128 -#define Rf_installChar_x 129 -#define Rf_isNull_x 130 -#define Rf_isString_x 131 -#define Rf_lengthgets_x 132 -#define Rf_match_x 133 -#define Rf_mkCharLenCE_x 134 -#define Rf_namesgets_x 135 -#define Rf_ncols_x 136 -#define Rf_nrows_x 137 -#define Rf_pchisq_x 138 -#define Rf_pnchisq_x 139 -#define Rf_protect_x 140 -#define Rf_punif_x 141 -#define Rf_qchisq_x 142 -#define Rf_qnchisq_x 143 -#define Rf_qunif_x 144 -#define Rf_rchisq_x 145 -#define Rf_rnchisq_x 146 -#define Rf_runif_x 147 -#define Rf_setAttrib_x 148 -#define Rf_str2type_x 149 -#define Rf_unprotect_x 150 -#define Rf_unprotect_ptr_x 151 -#define Rf_warning_x 152 -#define Rf_warningcall_x 153 -#define Rprintf_x 154 -#define SETCAD4R_x 155 -#define SETCADDDR_x 156 -#define SETCADDR_x 157 -#define SETCADR_x 158 -#define SETCAR_x 159 -#define SETCDR_x 160 -#define SET_BODY_x 161 -#define SET_CLOENV_x 162 -#define SET_FORMALS_x 163 -#define SET_NAMED_FASTR_x 164 -#define SET_RDEBUG_x 165 -#define SET_RSTEP_x 166 -#define SET_S4_OBJECT_x 167 -#define SET_STRING_ELT_x 168 -#define SET_SYMVALUE_x 169 -#define SET_TAG_x 170 -#define SET_TYPEOF_FASTR_x 171 -#define SET_VECTOR_ELT_x 172 -#define STRING_ELT_x 173 -#define SYMVALUE_x 174 -#define TAG_x 175 -#define TYPEOF_x 176 -#define UNSET_S4_OBJECT_x 177 -#define VECTOR_ELT_x 178 -#define forceSymbols_x 179 -#define getCCallable_x 180 -#define getConnectionClassString_x 181 -#define getEmbeddingDLLInfo_x 182 -#define getOpenModeString_x 183 -#define getSummaryDescription_x 184 -#define isSeekable_x 185 -#define octsize_x 186 -#define registerCCallable_x 187 -#define registerRoutines_x 188 -#define restoreHandlerStacks_x 189 -#define setDotSymbolValues_x 190 -#define unif_rand_x 191 -#define useDynamicSymbols_x 192 +#define Rf_any_duplicated3_x 102 +#define Rf_asChar_x 103 +#define Rf_asCharacterFactor_x 104 +#define Rf_asInteger_x 105 +#define Rf_asLogical_x 106 +#define Rf_asReal_x 107 +#define Rf_classgets_x 108 +#define Rf_coerceVector_x 109 +#define Rf_cons_x 110 +#define Rf_copyListMatrix_x 111 +#define Rf_copyMatrix_x 112 +#define Rf_copyMostAttrib_x 113 +#define Rf_dchisq_x 114 +#define Rf_defineVar_x 115 +#define Rf_dnchisq_x 116 +#define Rf_dunif_x 117 +#define Rf_duplicate_x 118 +#define Rf_error_x 119 +#define Rf_errorcall_x 120 +#define Rf_eval_x 121 +#define Rf_findFun_x 122 +#define Rf_findVar_x 123 +#define Rf_findVarInFrame_x 124 +#define Rf_findVarInFrame3_x 125 +#define Rf_getAttrib_x 126 +#define Rf_gsetVar_x 127 +#define Rf_inherits_x 128 +#define Rf_install_x 129 +#define Rf_installChar_x 130 +#define Rf_isNull_x 131 +#define Rf_isString_x 132 +#define Rf_lengthgets_x 133 +#define Rf_match_x 134 +#define Rf_mkCharLenCE_x 135 +#define Rf_namesgets_x 136 +#define Rf_ncols_x 137 +#define Rf_nrows_x 138 +#define Rf_pchisq_x 139 +#define Rf_pnchisq_x 140 +#define Rf_protect_x 141 +#define Rf_punif_x 142 +#define Rf_qchisq_x 143 +#define Rf_qnchisq_x 144 +#define Rf_qunif_x 145 +#define Rf_rchisq_x 146 +#define Rf_rnchisq_x 147 +#define Rf_runif_x 148 +#define Rf_setAttrib_x 149 +#define Rf_str2type_x 150 +#define Rf_unprotect_x 151 +#define Rf_unprotect_ptr_x 152 +#define Rf_warning_x 153 +#define Rf_warningcall_x 154 +#define Rprintf_x 155 +#define SETCAD4R_x 156 +#define SETCADDDR_x 157 +#define SETCADDR_x 158 +#define SETCADR_x 159 +#define SETCAR_x 160 +#define SETCDR_x 161 +#define SET_BODY_x 162 +#define SET_CLOENV_x 163 +#define SET_FORMALS_x 164 +#define SET_NAMED_FASTR_x 165 +#define SET_RDEBUG_x 166 +#define SET_RSTEP_x 167 +#define SET_S4_OBJECT_x 168 +#define SET_STRING_ELT_x 169 +#define SET_SYMVALUE_x 170 +#define SET_TAG_x 171 +#define SET_TYPEOF_FASTR_x 172 +#define SET_VECTOR_ELT_x 173 +#define STRING_ELT_x 174 +#define SYMVALUE_x 175 +#define TAG_x 176 +#define TYPEOF_x 177 +#define UNSET_S4_OBJECT_x 178 +#define VECTOR_ELT_x 179 +#define forceSymbols_x 180 +#define getCCallable_x 181 +#define getConnectionClassString_x 182 +#define getEmbeddingDLLInfo_x 183 +#define getOpenModeString_x 184 +#define getSummaryDescription_x 185 +#define isSeekable_x 186 +#define octsize_x 187 +#define registerCCallable_x 188 +#define registerRoutines_x 189 +#define restoreHandlerStacks_x 190 +#define setDotSymbolValues_x 191 +#define unif_rand_x 192 +#define useDynamicSymbols_x 193 -#define UPCALLS_TABLE_SIZE 193 +#define UPCALLS_TABLE_SIZE 194 #endif // RFFI_UPCALLSINDEX_H diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h index 82bf7b8f64b6c1c2a002a7b769f31f757865f43d..628f5974c669df680434ae9d71055dadf09a01de 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h @@ -448,6 +448,13 @@ R_xlen_t Rf_any_duplicated(SEXP x, Rboolean from_last) { return result; } +R_xlen_t Rf_any_duplicated3(SEXP x, SEXP incomp, Rboolean from_last) { + TRACE0(); + R_xlen_t result = (R_xlen_t) ((call_Rf_any_duplicated3) callbacks[Rf_any_duplicated3_x])(x, incomp, from_last); + checkExitCall(); + return result; +} + SEXP Rf_duplicated(SEXP x, Rboolean y) { TRACE0(); unimplemented("Rf_duplicated"); diff --git a/com.oracle.truffle.r.native/version.source b/com.oracle.truffle.r.native/version.source index fb1e7bc86996a80d4a16529b990adda1d3434c92..c3f407c0955bb5738e40a82664c79b63f04a9adb 100644 --- a/com.oracle.truffle.r.native/version.source +++ b/com.oracle.truffle.r.native/version.source @@ -1 +1 @@ -54 +55 diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java index 9f542e9f7a5d049ba41de0dc0aee624b31949749..aad7079a8101d62d73865029366576cf63a7a6ac 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java @@ -37,6 +37,7 @@ import java.util.function.Function; import com.oracle.truffle.api.CallTarget; import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleRuntime; @@ -57,6 +58,7 @@ import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor.MultiSlotData; import com.oracle.truffle.r.runtime.ffi.BaseRFFI; @@ -678,6 +680,21 @@ public final class Utils { return String.format(format, objects); } + /** + * Makes the best effort to create end user understandable String representation of the type of + * the parameter. When the parameter is null, returns "null". + */ + public static String getTypeName(Object value) { + // Typically part of error reporting. The whole error reporting should be behind TB. + CompilerAsserts.neverPartOfCompilation(); + if (value == null) { + return "null"; + } else if (value instanceof RTypedValue) { + return ((RTypedValue) value).getRType().getName(); + } + return value.getClass().getSimpleName(); + } + private static boolean isWriteableDirectory(String path) { File f = new File(path); return f.exists() && f.isDirectory() && f.canWrite(); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExternalPtr.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExternalPtr.java index fa03686af947f9cc3137ef97fbcb97ac4f14b686..5112b663132a02c31723cd5da68c103149ac51bf 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExternalPtr.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExternalPtr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,6 +56,7 @@ public final class RExternalPtr extends RAttributeStorage implements RTypedValue } public SymbolHandle getAddr() { + // TODO: can be null? Callers do dereference the return value. return handle; }