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 384967e80570a75ac52aa6a705fdd7597bd54f70..ed489a3e28ac1dd64e86b4f372b20fe4b19a3c66 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 @@ -110,6 +110,7 @@ import com.oracle.truffle.r.runtime.ffi.CharSXPWrapper; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.gnur.SA_TYPE; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; +import com.oracle.truffle.r.runtime.nmath.distr.Unif; import com.oracle.truffle.r.runtime.nodes.DuplicationHelper; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; @@ -1581,4 +1582,30 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { name2typeTable.put("numeric", SEXPTYPE.REALSXP.code); name2typeTable.put("name", SEXPTYPE.SYMSXP.code); } + + @Override + public double Rf_dunif(double a, double b, double c, int d) { + return (double) FFIUpCallRootNode.getCallTarget(RFFIUpCallTable.Rf_dunif).call(a, b, c, d); + } + + @Override + public double Rf_qunif(double a, double b, double c, int d, int e) { + return (double) FFIUpCallRootNode.getCallTarget(RFFIUpCallTable.Rf_qunif).call(a, b, c, d, e); + } + + @Override + public double Rf_punif(double a, double b, double c, int d, int e) { + return (double) FFIUpCallRootNode.getCallTarget(RFFIUpCallTable.Rf_punif).call(a, b, c, d, e); + } + + @Override + public double Rf_runif(double a, double b) { + return (double) FFIUpCallRootNode.getCallTarget(RFFIUpCallTable.Rf_runif).call(a, b); + } + + @Override + public Object Rf_namesgets(Object x, Object y) { + return FFIUpCallRootNode.getCallTarget(RFFIUpCallTable.Rf_namesgets).call(x, y); + } + } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/TracingUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/TracingUpCallsRFFIImpl.java index cf9a072f94d83cd0030b19079852f66b8d6c479a..8b5fc1e7b73848a4d471312f981c1bc9350174b9 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/TracingUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/TracingUpCallsRFFIImpl.java @@ -847,4 +847,35 @@ final class TracingUpCallsRFFIImpl implements UpCallsRFFI { RFFIUtils.traceUpCall("Rf_str2type"); return delegate.Rf_str2type(name); } + + @Override + public double Rf_dunif(double a, double b, double c, int d) { + RFFIUtils.traceUpCall("Rf_dunif", a, b, c, d); + return delegate.Rf_dunif(a, b, c, d); + } + + @Override + public double Rf_qunif(double a, double b, double c, int d, int e) { + RFFIUtils.traceUpCall("Rf_qunif", a, b, c, d, e); + return delegate.Rf_qunif(a, b, c, d, e); + } + + @Override + public double Rf_punif(double a, double b, double c, int d, int e) { + RFFIUtils.traceUpCall("Rf_punif", a, b, c, d, e); + return delegate.Rf_punif(a, b, c, d, e); + } + + @Override + public double Rf_runif(double a, double b) { + RFFIUtils.traceUpCall("Rf_runif", a, b); + return delegate.Rf_runif(a, b); + } + + @Override + public Object Rf_namesgets(Object vec, Object val) { + RFFIUtils.traceUpCall("Rf_namesgets", vec, val); + return delegate.Rf_namesgets(vec, val); + } + } 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 b6a57e296c0af9ffb0e1a1d6a3c079b2a0906937..5df825b06b78e80c37dfb663f2f3b2c4c311a156 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 @@ -62,4 +62,22 @@ public abstract class FFIUpCallNode extends Node { return 3; } } + + public abstract static class Arg4 extends FFIUpCallNode { + public abstract Object executeObject(Object arg0, Object arg1, Object arg2, Object arg3); + + @Override + protected int numArgs() { + return 4; + } + } + + public abstract static class Arg5 extends FFIUpCallNode { + public abstract Object executeObject(Object arg0, Object arg1, Object arg2, Object arg3, Object arg4); + + @Override + protected int numArgs() { + return 5; + } + } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallRootNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallRootNode.java index a3bd560c96916a5e325b4b4ed02a458e5c6e9eb0..4470a37a76c32fce8da819194007efa910eedea4 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallRootNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FFIUpCallRootNode.java @@ -38,9 +38,13 @@ import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.LENGTHNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoNewObjectNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoSlotAssignNodeGen; import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoSlotNodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.RandFunctionsNodesFactory.RandFunction2NodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.RandFunctionsNodesFactory.RandFunction3_1NodeGen; +import com.oracle.truffle.r.ffi.impl.nodes.RandFunctionsNodesFactory.RandFunction3_2NodeGen; import com.oracle.truffle.r.ffi.impl.upcalls.RFFIUpCallTable; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.nmath.distr.Unif; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public final class FFIUpCallRootNode extends RootNode { @@ -105,5 +109,10 @@ public final class FFIUpCallRootNode extends RootNode { FFIUpCallRootNode.add(RFFIUpCallTable.R_do_new_object, RDoNewObjectNodeGen::create); FFIUpCallRootNode.add(RFFIUpCallTable.R_do_slot, RDoSlotNodeGen::create); FFIUpCallRootNode.add(RFFIUpCallTable.R_do_slot_assign, RDoSlotAssignNodeGen::create); + FFIUpCallRootNode.add(RFFIUpCallTable.Rf_runif, () -> RandFunction2NodeGen.create(new Unif.Runif())); + FFIUpCallRootNode.add(RFFIUpCallTable.Rf_dunif, () -> RandFunction3_1NodeGen.create(new Unif.DUnif())); + FFIUpCallRootNode.add(RFFIUpCallTable.Rf_qunif, () -> RandFunction3_2NodeGen.create(new Unif.QUnif())); + FFIUpCallRootNode.add(RFFIUpCallTable.Rf_punif, () -> RandFunction3_2NodeGen.create(new Unif.PUnif())); + FFIUpCallRootNode.add(RFFIUpCallTable.Rf_namesgets, MiscNodesFactory.NamesGetsNodeGen::create); } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java index 8a438e02e744d08033cd05bc86cb964260d5b152..918352aba3a2b7ee6660ef9c5ad7fd41e976f82a 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/MiscNodes.java @@ -30,6 +30,8 @@ import com.oracle.truffle.r.nodes.access.AccessSlotNode; import com.oracle.truffle.r.nodes.access.AccessSlotNodeGen; import com.oracle.truffle.r.nodes.access.UpdateSlotNode; import com.oracle.truffle.r.nodes.access.UpdateSlotNodeGen; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctionsFactory.SetNamesAttributeNodeGen; import com.oracle.truffle.r.nodes.objects.NewObject; import com.oracle.truffle.r.nodes.objects.NewObjectNodeGen; import com.oracle.truffle.r.runtime.RError; @@ -157,4 +159,20 @@ public final class MiscNodes { } } + @TypeSystemReference(RTypes.class) + abstract static class NamesGetsNode extends FFIUpCallNode.Arg2 { + + @Child private SetNamesAttributeNode setNamesNode; + + NamesGetsNode() { + setNamesNode = SetNamesAttributeNodeGen.create(); + } + + @Specialization + Object doNewObject(Object vec, Object val) { + setNamesNode.execute(vec, val); + return vec; + } + } + } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RandFunctionsNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RandFunctionsNodes.java new file mode 100644 index 0000000000000000000000000000000000000000..f168c1caeda218a4a7589d1e2a6edc979faa8fb8 --- /dev/null +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RandFunctionsNodes.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2017, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.ffi.impl.nodes; + +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.runtime.nmath.MathFunctions; +import com.oracle.truffle.r.runtime.nmath.RandomFunctions; +import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandFunction2_Double; +import com.oracle.truffle.r.runtime.nmath.RandomFunctions.RandomNumberProvider; + +public final class RandFunctionsNodes { + + public abstract static class RandFunction3_2Node extends FFIUpCallNode.Arg5 { + private final MathFunctions.Function3_2 inner; + + protected RandFunction3_2Node(MathFunctions.Function3_2 inner) { + this.inner = inner; + } + + @Specialization + protected double evaluate(double a, double b, double c, boolean d, boolean e) { + return inner.evaluate(a, b, c, d, e); + } + } + + public abstract static class RandFunction3_1Node extends FFIUpCallNode.Arg4 { + private final MathFunctions.Function3_1 inner; + + protected RandFunction3_1Node(MathFunctions.Function3_1 inner) { + this.inner = inner; + } + + @Specialization + protected double evaluate(double a, double b, double c, boolean d) { + return inner.evaluate(a, b, c, d); + } + } + + public abstract static class RandFunction2Node extends FFIUpCallNode.Arg2 { + @Child private RandomFunctions.RandFunction2_Double inner; + + protected RandFunction2Node(RandFunction2_Double inner) { + this.inner = inner; + } + + @Specialization + protected double evaluate(double a, double b) { + return inner.execute(a, b, RandomNumberProvider.fromCurrentRNG()); + } + } + +} 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 56faae246c87ac1abc19e78cd8908aeb2c9476cf..76c10d6ac9e1285218e7e2774872b3375cc1ac2a 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 @@ -295,4 +295,14 @@ public interface StdUpCallsRFFI { int Rf_str2type(@RFFICstring Object name); + double Rf_dunif(double a, double b, double c, int d); + + double Rf_qunif(double a, double b, double c, int d, int e); + + double Rf_punif(double a, double b, double c, int d, int e); + + double Rf_runif(double a, double b); + + Object Rf_namesgets(Object vec, Object val); + } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/R/fastrGraphics.R b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/R/fastrGraphics.R index 7a48a7b74ff0f825ec64cfedaa0e264e99931214..2ffbef80c874914e8e0457462f1055a3f1d6ed33 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/R/fastrGraphics.R +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/R/fastrGraphics.R @@ -26,10 +26,23 @@ eval(expression({ graphicsWarning <- function(name) { - function(...) { + # lookup original function and fetch signature + fun <- tryCatch(get(name, environment()), error=function(x) NULL) + if(!is.null(fun)) { + sig <- formals(fun) + } else { + sig <- NULL + } + + replacementFun <- function(...) { warning(paste0(name, " not supported.", " Note: FastR does not support graphics package and most of its functions. Please use grid package or grid based packages like lattice instead.")) NULL } + + if(!is.null(sig)) { + formals(replacementFun) <- sig + } + return(replacementFun) } plot.default <- function (x, y = NULL, type = "p", xlim = NULL, ylim = NULL, 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 48d0c6dc45acf72d59a8346ce01fcc188e5dd07b..44b8bf7102dac472baa11a2dbcc4d41c3aa2842f 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 @@ -277,6 +277,10 @@ typedef char *(*call_R_HomeDir)(); typedef void (*call_R_CleanUp)(int sa, int status, int runlast); typedef void (*call_Rf_gsetVar)(SEXP symbol, SEXP value, SEXP rho); typedef double (*call_unif_rand)(); +typedef double (*call_Rf_qunif)(double a, double b, double c, int d, int e); +typedef double (*call_Rf_dunif)(double a, double b, double c, int d); +typedef double (*call_Rf_punif)(double a, double b, double c, int d, int e); +typedef double (*call_Rf_runif)(double x, double y); typedef SEXP (*call_getvar)(); 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 a08f6c21920e3ae72a3dbd245de6db897f4cbbb5..f17d3f1c1952664e5635140c1d46dbd2461cf3a9 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 @@ -92,54 +92,59 @@ #define Rf_copyListMatrix_x 87 #define Rf_copyMatrix_x 88 #define Rf_defineVar_x 89 -#define Rf_duplicate_x 90 -#define Rf_error_x 91 -#define Rf_errorcall_x 92 -#define Rf_eval_x 93 -#define Rf_findFun_x 94 -#define Rf_findVar_x 95 -#define Rf_findVarInFrame_x 96 -#define Rf_findVarInFrame3_x 97 -#define Rf_getAttrib_x 98 -#define Rf_gsetVar_x 99 -#define Rf_inherits_x 100 -#define Rf_install_x 101 -#define Rf_installChar_x 102 -#define Rf_isNull_x 103 -#define Rf_isString_x 104 -#define Rf_lengthgets_x 105 -#define Rf_mkCharLenCE_x 106 -#define Rf_ncols_x 107 -#define Rf_nrows_x 108 -#define Rf_setAttrib_x 109 -#define Rf_str2type_x 110 -#define Rf_warning_x 111 -#define Rf_warningcall_x 112 -#define Rprintf_x 113 -#define SETCADR_x 114 -#define SETCAR_x 115 -#define SETCDR_x 116 -#define SET_NAMED_FASTR_x 117 -#define SET_RDEBUG_x 118 -#define SET_RSTEP_x 119 -#define SET_S4_OBJECT_x 120 -#define SET_STRING_ELT_x 121 -#define SET_SYMVALUE_x 122 -#define SET_TAG_x 123 -#define SET_TYPEOF_FASTR_x 124 -#define SET_VECTOR_ELT_x 125 -#define STRING_ELT_x 126 -#define SYMVALUE_x 127 -#define TAG_x 128 -#define TYPEOF_x 129 -#define UNSET_S4_OBJECT_x 130 -#define VECTOR_ELT_x 131 -#define getConnectionClassString_x 132 -#define getOpenModeString_x 133 -#define getSummaryDescription_x 134 -#define isSeekable_x 135 -#define unif_rand_x 136 +#define Rf_dunif_x 90 +#define Rf_duplicate_x 91 +#define Rf_error_x 92 +#define Rf_errorcall_x 93 +#define Rf_eval_x 94 +#define Rf_findFun_x 95 +#define Rf_findVar_x 96 +#define Rf_findVarInFrame_x 97 +#define Rf_findVarInFrame3_x 98 +#define Rf_getAttrib_x 99 +#define Rf_gsetVar_x 100 +#define Rf_inherits_x 101 +#define Rf_install_x 102 +#define Rf_installChar_x 103 +#define Rf_isNull_x 104 +#define Rf_isString_x 105 +#define Rf_lengthgets_x 106 +#define Rf_mkCharLenCE_x 107 +#define Rf_namesgets_x 108 +#define Rf_ncols_x 109 +#define Rf_nrows_x 110 +#define Rf_punif_x 111 +#define Rf_qunif_x 112 +#define Rf_runif_x 113 +#define Rf_setAttrib_x 114 +#define Rf_str2type_x 115 +#define Rf_warning_x 116 +#define Rf_warningcall_x 117 +#define Rprintf_x 118 +#define SETCADR_x 119 +#define SETCAR_x 120 +#define SETCDR_x 121 +#define SET_NAMED_FASTR_x 122 +#define SET_RDEBUG_x 123 +#define SET_RSTEP_x 124 +#define SET_S4_OBJECT_x 125 +#define SET_STRING_ELT_x 126 +#define SET_SYMVALUE_x 127 +#define SET_TAG_x 128 +#define SET_TYPEOF_FASTR_x 129 +#define SET_VECTOR_ELT_x 130 +#define STRING_ELT_x 131 +#define SYMVALUE_x 132 +#define TAG_x 133 +#define TYPEOF_x 134 +#define UNSET_S4_OBJECT_x 135 +#define VECTOR_ELT_x 136 +#define getConnectionClassString_x 137 +#define getOpenModeString_x 138 +#define getSummaryDescription_x 139 +#define isSeekable_x 140 +#define unif_rand_x 141 -#define UPCALLS_TABLE_SIZE 137 +#define UPCALLS_TABLE_SIZE 142 #endif // RFFI_UPCALLSINDEX_H 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 0414f5f032cd4daf66d45d49b72ada1b39c15dc0..6b96159ed943fdcb8f106d9675fda498bfa74102 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c @@ -146,6 +146,7 @@ static jmethodID Rf_copyListMatrixMethodID; static jmethodID Rf_copyMatrixMethodID; static jmethodID Rf_nrowsMethodID; static jmethodID Rf_ncolsMethodID; +static jmethodID Rf_namesgetsMethodID; static jclass CharSXPWrapperClass; jclass JNIUpCallsRFFIImplClass; @@ -263,6 +264,7 @@ void init_internals(JNIEnv *env) { Rf_copyMatrixMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_copyMatrix", "(Ljava/lang/Object;Ljava/lang/Object;I)I", 0); Rf_nrowsMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_nrows", "(Ljava/lang/Object;)I", 0); Rf_ncolsMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_ncols", "(Ljava/lang/Object;)I", 0); + Rf_namesgetsMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_namesgets", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); // static JNI-specific methods JNIUpCallsRFFIImplClass = checkFindClass(env, "com/oracle/truffle/r/ffi/impl/jni/JNIUpCallsRFFIImpl"); @@ -740,7 +742,9 @@ SEXP R_lsInternal3(SEXP env, Rboolean all, Rboolean sorted) { } SEXP Rf_namesgets(SEXP x, SEXP y) { - return unimplemented("Rf_namesgets"); + JNIEnv *thisenv = getEnv(); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_namesgetsMethodID, x, y); + return checkRef(thisenv, result); } SEXP GetOption1(SEXP tag) diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rmath.c b/com.oracle.truffle.r.native/fficall/src/jni/Rmath.c index fd82bd58721f03a9131a6453dd480dec48096d7e..400076323adf70436f97874c84e925d54fa812a7 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rmath.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rmath.c @@ -22,8 +22,17 @@ */ #include <rffiutils.h> +static jmethodID Rf_runifMethodID; +static jmethodID Rf_punifMethodID; +static jmethodID Rf_qunifMethodID; +static jmethodID Rf_dunifMethodID; + void init_rmath(JNIEnv *env) { + Rf_runifMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_runif", "(DD)D", 0); + Rf_punifMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_punif", "(DDDII)D", 0); + Rf_qunifMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_qunif", "(DDDII)D", 0); + Rf_dunifMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_dunif", "(DDDI)D", 0); } double Rf_dnorm(double a, double b, double c, int d) { @@ -63,23 +72,27 @@ void Rf_pnorm_both(double a, double * b, double * c, int d, int e) { } double Rf_dunif(double a, double b, double c, int d) { - unimplemented("Rf_dunif"); - return 0; + TRACE(TARGs, a, b); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallDoubleMethod(thisenv, UpCallsRFFIObject, Rf_dunifMethodID, a, b, c, d); } double Rf_punif(double a, double b, double c, int d, int e) { - unimplemented("Rf_punif"); - return 0; + TRACE(TARGs, a, b); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallDoubleMethod(thisenv, UpCallsRFFIObject, Rf_punifMethodID, a, b, c, d, e); } double Rf_qunif(double a, double b, double c, int d, int e) { - unimplemented("Rf_qunif"); - return 0; + TRACE(TARGs, a, b); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallDoubleMethod(thisenv, UpCallsRFFIObject, Rf_qunifMethodID, a, b, c, d, e); } double Rf_runif(double a, double b) { - unimplemented("Rf_runif"); - return 0; + TRACE(TARGs, a, b); + JNIEnv *thisenv = getEnv(); + return (*thisenv)->CallDoubleMethod(thisenv, UpCallsRFFIObject, Rf_runifMethodID, a, b); } double Rf_dgamma(double a, double b, double c, int d) { 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 5e7b770f354ebcd5c52f4b837359c5c82fbfeed9..916a6d0a4be19b603150d698a09baca6a51243b6 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 @@ -449,7 +449,7 @@ SEXP R_lsInternal3(SEXP env, Rboolean all, Rboolean sorted) { } SEXP Rf_namesgets(SEXP x, SEXP y) { - return unimplemented("Rf_namesgets"); + return checkRef(((call_Rf_namesgets) callbacks[Rf_namesgets_x])(x, y)); } SEXP TAG(SEXP e) { diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rmath.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rmath.c index fd9580d182b294ed8f86cd0cf65df2bb9f350e5c..ce049485772734bbf33acd3edfd56a2093174985 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rmath.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rmath.c @@ -21,6 +21,7 @@ * questions. */ #include <rffiutils.h> +#include "../common/rffi_upcalls.h" double Rf_dnorm(double a, double b, double c, int d) { unimplemented("Rf_dnorm"); @@ -59,23 +60,19 @@ void Rf_pnorm_both(double a, double * b, double * c, int d, int e) { } double Rf_dunif(double a, double b, double c, int d) { - unimplemented("Rf_dunif"); - return 0; + return ((call_Rf_dunif) callbacks[Rf_dunif_x])(a, b, c, d); } double Rf_punif(double a, double b, double c, int d, int e) { - unimplemented("Rf_punif"); - return 0; + return ((call_Rf_punif) callbacks[Rf_punif_x])(a, b, c, d, e); } double Rf_qunif(double a, double b, double c, int d, int e) { - unimplemented("Rf_qunif"); - return 0; + return ((call_Rf_qunif) callbacks[Rf_qunif_x])(a, b, c, d, e); } double Rf_runif(double a, double b) { - unimplemented("Rf_runif"); - return 0; + return ((call_Rf_runif) callbacks[Rf_runif_x])(a, b); } double Rf_dgamma(double a, double b, double c, int d) { diff --git a/com.oracle.truffle.r.native/version.source b/com.oracle.truffle.r.native/version.source index bb95160cb6e07358f54a28a208ae41e69889c97b..a7873645902455c63d166fdcaa4b2fe565f6de7d 100644 --- a/com.oracle.truffle.r.native/version.source +++ b/com.oracle.truffle.r.native/version.source @@ -1 +1 @@ -33 +34 diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java index a561a63c48d3a5e8b8910361b93b9ea062a5f7b5..14cc631717cbcc5bcf1db61d9a08a405b3432d25 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java @@ -70,6 +70,7 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; @@ -753,6 +754,11 @@ public class EnvFunctions { return s; } + @Specialization + RExternalPtr copy(RExternalPtr ptr) { + return ptr.copy(); + } + @Specialization RSymbol copy(@SuppressWarnings("unused") RMissing m) { return RDataFactory.createSymbol(" "); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/snow/R/snow_overrides.R b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/snow/R/snow_overrides.R new file mode 100644 index 0000000000000000000000000000000000000000..127fd3195449cee82afb1ca48db71b4ba78a8982 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/snow/R/snow_overrides.R @@ -0,0 +1,131 @@ +# +# This material is distributed under the GNU General Public License +# Version 2. You may review the terms of this license at +# http://www.gnu.org/licenses/gpl-2.0.html +# +# Copyright (c) 1995-2014, The R Core Team +# Copyright (c) 2016, Oracle and/or its affiliates +# +# All rights reserved. +# + +## Derived from snow and parallel packages + +eval(expression({ + +# overwritten functions: + +makeCluster <- function (spec, type = getClusterOption("type"), ...) { + switch(type, + SOCK = snow::makeSOCKcluster(spec, ...), + MPI = snow::makeMPIcluster(spec, ...), + NWS = snow::makeNWScluster(spec, ...), + SHARED = makeSHAREDcluster(spec, ...), # this line was added + stop("unknown cluster type")) +} + +# added functions: + +closeNode.SHAREDnode <- function(node) { + .fastr.channel.close(node$channel) +} + +sendData.SHAREDnode <- function(node, data) { + .fastr.channel.send(node$channel, data) +} + +recvData.SHAREDnode <- function(node) { + .fastr.channel.receive(node$channel) +} + +recvOneData.SHAREDcluster <- function(cl) { + channel_ids = lapply(cl, function(l) l[["channel"]]) + res <- .fastr.channel.select(channel_ids) + selected_id = res[[1]] + # TODO: I am sure there is a better way... + indexes = lapply(cl, function(l, id) if (identical(l[["channel"]], id)) id else as.integer(NA), id=selected_id) + node_ind = which(as.double(indexes)==as.double(selected_id)) + list(node = node_ind, value = res[[2]]) +} + +newSHAREDnodes <- function(nnodes, debug, options = defaultClusterOptions) { + context_code <- vector("character", nnodes) + contexts <- vector("integer", nnodes) + channels <- vector("integer", nnodes) + outfile <- getClusterOption("outfile", options) + + # get initial port number + port <- as.integer(snow:::getClusterOption("port", options)) + + # find first unused port number + continue <- TRUE + firstUnused <- 0 + while(continue) { + tryCatch({ + .fastr.channel.get(port + (firstUnused + 1) * 1000) + firstUnused <- firstUnused + 1 + }, error = function(e) { continue <<- FALSE }) + } + + for (i in 1:nnodes) { + # generate unique values for channel keys (addition factor is chosen based on how snow generates port numbers) + port <- as.integer(snow:::getClusterOption("port", options) + (i + firstUnused) * 1000) + + startup <- substitute(local({ + makeSHAREDmaster <- function(key) { + channel <- .fastr.channel.get(as.integer(key)) + structure(list(channel=channel), class = "SHAREDnode") + } + snow:::sinkWorkerOutput(OUTFILE) + snow:::slaveLoop(makeSHAREDmaster(PORT)) + }), list(OUTFILE=outfile, PORT=port)) + + context_code[[i]] <- paste0(deparse(startup), collapse="\n") + if (isTRUE(debug)) cat(sprintf("Starting context: %d with code %s\n", i, context_code[[i]])) + + ## Need to return a list here, in the same form as the + ## "cluster" data structure. + channels[[i]] <- .fastr.channel.create(port) + if (isTRUE(debug)) cat(sprintf("Context %d started!\n", i)) + } + contexts <- .fastr.context.spawn(context_code) + cl <- vector("list", nnodes) + for (i in 1:nnodes) { + cl[[i]] <- structure(list(channel = channels[[i]], context=contexts[[i]], rank = i), class = "SHAREDnode") + } + cl +} + +makeSHAREDcluster <- function(nnodes = getOption("mc.cores", 2L), options = defaultClusterOptions, ...) { + nnodes <- as.integer(nnodes) + if(is.na(nnodes) || nnodes < 1L) stop("'nnodes' must be >= 1") + options <- addClusterOptions(options, list(...)) + + # Add the "debug" option defaulted to FALSE, if the user didn't specify + # If the user gives TRUE, print extra stuff during cluster setup + debug <- FALSE + if (exists("debug", envir=options, inherits=FALSE)) { + debug <- snow:::getClusterOption("debug", options) + } else { + options <- snow:::addClusterOptions(options, list(debug = debug)) + } + + cl <- newSHAREDnodes(nnodes, debug = debug, options=options) + class(cl) <- c("SHAREDcluster", "cluster") + cl +} + +stopCluster.SHAREDcluster <- function(cl) { + for (n in cl) { + snow:::postNode(n, "DONE") + .fastr.context.join(n$context) + } +} + +## manually register S3 generic methods +registerS3method("closeNode", "SHAREDnode", closeNode.SHAREDnode) +registerS3method("sendData", "SHAREDnode", sendData.SHAREDnode) +registerS3method("recvData", "SHAREDnode", recvData.SHAREDnode) +registerS3method("recvOneData", "SHAREDcluster", recvOneData.SHAREDcluster) +registerS3method("stopCluster", "SHAREDcluster", stopCluster.SHAREDcluster) +}), asNamespace("snow")) diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java index a5287eceb233aed86d7ad08ace8a7944c00dd45b..2a29784e9d0ce13e72fedcfe15f6ef086edab9b0 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalCode.java @@ -44,7 +44,7 @@ public final class RInternalCode { private final String basePackage; private final Source source; - private REnvironment evaluatedEnvironment; + private volatile REnvironment evaluatedEnvironment; private RInternalCode(RContext context, String basePackage, Source source) { this.context = context; @@ -57,7 +57,7 @@ public final class RInternalCode { return Utils.getResourceAsSource(clazz, fileName); } - private REnvironment evaluate() { + private synchronized REnvironment evaluate() { try { RExpression parsedCode = context.getThisEngine().parse(source); REnvironment statsPackage = REnvironment.getRegisteredNamespace(context, basePackage); @@ -72,13 +72,15 @@ public final class RInternalCode { } } - public RFunction lookupFunction(String name) { + public synchronized RFunction lookupFunction(String name) { REnvironment env = this.evaluatedEnvironment; if (env == null) { env = evaluate(); this.evaluatedEnvironment = env; } - return (RFunction) env.get(name); + RFunction fun = (RFunction) env.get(name); + assert fun != null; + return fun; } public static RInternalCode lookup(RContext context, String basePackage, Source source) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java index 9d6cfd297e91be1e4e850222d83da429b89d6e80..00ed14aecea4faa1e75f344e508768d4e918f48c 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java @@ -2744,18 +2744,20 @@ public class RSerialize { assert srcfile instanceof REnvironment; Source source = RSource.fromSrcfile((REnvironment) srcfile); - RList l = (RList) srcref; + RList blockSrcref = (RList) srcref; RSyntaxElement[] syntaxArguments = elem.getSyntaxArguments(); - assert syntaxArguments.length == l.getLength() - 1; - - for (int i = 0; i < l.getLength(); i++) { - Object dataAt = l.getDataAt(i); - assert dataAt instanceof RAbstractIntVector; - SourceSection ss = RSrcref.createSourceSection((RAbstractIntVector) dataAt, source); - if (i == 0) { - elem.setSourceSection(ss); - } else { - syntaxArguments[i - 1].setSourceSection(ss); + assert syntaxArguments.length == blockSrcref.getLength() - 1; + + for (int i = 0; i < blockSrcref.getLength(); i++) { + Object singleSrcref = blockSrcref.getDataAt(i); + // could also be NULL + if (singleSrcref instanceof RAbstractIntVector) { + SourceSection ss = RSrcref.createSourceSection((RAbstractIntVector) singleSrcref, source); + if (i == 0) { + elem.setSourceSection(ss); + } else { + syntaxArguments[i - 1].setSourceSection(ss); + } } } } catch (NoSuchFileException e) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java index a4c446d704934f2d6bb8b4254d852457b6220824..47d82e72ec4d51d22f415a1e825236a9454ed16c 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/frame/FrameSlotChangeMonitor.java @@ -374,14 +374,15 @@ public final class FrameSlotChangeMonitor { invalidateAllNames(target); FrameDescriptor oldEnclosingDescriptor = target.getEnclosingFrameDescriptor(); - assert (oldEnclosingDescriptor == null) == (oldEnclosingFrame == null) : "mismatch " + oldEnclosingDescriptor + " / " + oldEnclosingFrame; + FrameDescriptor newEnclosingDescriptor = handleBaseNamespaceEnv(newEnclosingFrame); + assert newEnclosingDescriptor == oldEnclosingDescriptor || (oldEnclosingDescriptor == null) == (oldEnclosingFrame == null) : "mismatch " + oldEnclosingDescriptor + " / " + oldEnclosingFrame; if (oldEnclosingDescriptor != null) { - assert oldEnclosingDescriptor == oldEnclosingFrame.getFrameDescriptor() : "mismatch " + oldEnclosingDescriptor + " / " + oldEnclosingFrame.getFrameDescriptor(); + assert newEnclosingDescriptor == oldEnclosingDescriptor || oldEnclosingDescriptor == oldEnclosingFrame.getFrameDescriptor() : "mismatch " + oldEnclosingDescriptor + " / " + + oldEnclosingFrame.getFrameDescriptor(); FrameDescriptorMetaData oldEnclosing = getMetaData(oldEnclosingDescriptor); oldEnclosing.subDescriptors.remove(descriptor); } - FrameDescriptor newEnclosingDescriptor = handleBaseNamespaceEnv(newEnclosingFrame); target.updateEnclosingFrameDescriptor(newEnclosingDescriptor); if (newEnclosingDescriptor != null) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java index 74fde8799285b90d7bd9015a852b9df7da0f772a..4bf6fc5df3017989027c04c09bd60e0648dff815 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/DLL.java @@ -32,6 +32,7 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.ReturnException; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.context.RContext.ContextKind; import com.oracle.truffle.r.runtime.context.RContext.ContextState; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExternalPtr; @@ -84,7 +85,7 @@ public class DLL { @Override public ContextState initialize(RContext contextArg) { this.context = contextArg; - if (context.getKind() == RContext.ContextKind.SHARE_PARENT_RW) { + if (isShareDLLKind(context.getKind())) { list = context.getParent().stateDLL.list; } else { list = new ArrayList<>(); @@ -98,7 +99,7 @@ public class DLL { @Override public void beforeDestroy(RContext contextArg) { - if (context.getKind() != RContext.ContextKind.SHARE_PARENT_RW) { + if (!isShareDLLKind(context.getKind())) { for (int i = 1; i < list.size(); i++) { DLLInfo dllInfo = list.get(i); DLLRFFI.DLCloseRootNode.create().getCallTarget().call(dllInfo.handle); @@ -107,6 +108,10 @@ public class DLL { list = null; } + private static boolean isShareDLLKind(RContext.ContextKind kind) { + return kind == ContextKind.SHARE_PARENT_RW || kind == ContextKind.SHARE_ALL; + } + private void addLibR(DLLInfo dllInfo) { assert list.isEmpty(); list.add(dllInfo); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java index e2e074001a610d9986a58019244841194b560ed8..eecc1c27b5f9536182fffd46fdddde09a55d3c1b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/RRNG.java @@ -410,7 +410,7 @@ public class RRNG { public static void putRNGState() { int[] seeds = currentGenerator().getSeeds(); seeds[0] = currentKind().ordinal() + 100 * currentNormKind().ordinal(); - RIntVector vector = RDataFactory.createIntVector(seeds, RDataFactory.COMPLETE_VECTOR); + RIntVector vector = RDataFactory.createIntVector(seeds, RDataFactory.INCOMPLETE_VECTOR); REnvironment.globalEnv().safePut(RANDOM_SEED, vector.makeSharedPermanent()); } }