diff --git a/.gitignore b/.gitignore index 756f43343ccdae38768bd7d156b05bbf8109fabc..431b9e0bcedb9a1c51376555882b0f4da06fb54d 100644 --- a/.gitignore +++ b/.gitignore @@ -73,7 +73,7 @@ *.dot *.pyc *.hprof -\javafilelist.txt +javafilelist.txt .hprof.txt /compilations-*.cfg /graal/.*/build.xml diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java index cc2f268bcf1070ea534f29baa37af3f52b3fddb8..161c25219a125d9b88ffdf8373e9b68867f40466 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java @@ -33,6 +33,7 @@ import java.util.List; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.nodes.Node; @@ -719,4 +720,10 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { public void checkDebugRequest(RFunction func) { RInstrumentation.checkDebugRequested(func); } + + @SuppressWarnings("rawtypes") + @Override + public Class<? extends TruffleLanguage> getTruffleRLanguage() { + return TruffleRLanguage.class; + } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/DLLDotSymbolMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/DLLDotSymbolMR.java new file mode 100644 index 0000000000000000000000000000000000000000..3342f4a737ae56c2d35cc346a46e3d94a7565624 --- /dev/null +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/DLLDotSymbolMR.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, 2016, 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.engine.interop; + +import com.oracle.truffle.api.interop.CanResolve; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.engine.TruffleRLanguage; +import com.oracle.truffle.r.runtime.ffi.DLL; + +@MessageResolution(receiverType = DLL.DotSymbol.class, language = TruffleRLanguage.class) +public class DLLDotSymbolMR { + @CanResolve + public abstract static class DotSymbolCheck extends Node { + + protected static boolean test(TruffleObject receiver) { + return receiver instanceof DLL.DotSymbol; + } + } + +} diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/DLLInfoMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/DLLInfoMR.java new file mode 100644 index 0000000000000000000000000000000000000000..92a4118c055bfe7c4c27ff88caf52213eb8e25ba --- /dev/null +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/DLLInfoMR.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, 2016, 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.engine.interop; + +import com.oracle.truffle.api.interop.CanResolve; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.engine.TruffleRLanguage; +import com.oracle.truffle.r.runtime.ffi.DLL; + +@MessageResolution(receiverType = DLL.DLLInfo.class, language = TruffleRLanguage.class) +public class DLLInfoMR { + @CanResolve + public abstract static class DLLInfolCheck extends Node { + + protected static boolean test(TruffleObject receiver) { + return receiver instanceof DLL.DLLInfo; + } + } + +} diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RExternalPtrMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RExternalPtrMR.java new file mode 100644 index 0000000000000000000000000000000000000000..3d21bccdf2f6a6d0a2b6dece2a5b38aa99b09598 --- /dev/null +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RExternalPtrMR.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, 2016, 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.engine.interop; + +import com.oracle.truffle.api.interop.CanResolve; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.engine.TruffleRLanguage; +import com.oracle.truffle.r.runtime.data.RExternalPtr; + +@MessageResolution(receiverType = RExternalPtr.class, language = TruffleRLanguage.class) +public class RExternalPtrMR { + @CanResolve + public abstract static class RExternalPtrCheck extends Node { + + protected static boolean test(TruffleObject receiver) { + return receiver instanceof RExternalPtr; + } + } + +} diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java index 03f73455c63146019f8c9bb5a4ffdfead920049b..4e2a81101dde3a94799a5219af80a090d17c33e3 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java @@ -22,88 +22,250 @@ */ package com.oracle.truffle.r.engine.interop; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.Assumption; +import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.interop.ForeignAccess; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.engine.TruffleRLanguage; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RForeignAccessFactory; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.data.RComplexVector; +import com.oracle.truffle.r.runtime.data.RDoubleSequence; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.data.RIntSequence; +import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RLogicalVector; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.data.RRaw; +import com.oracle.truffle.r.runtime.data.RRawVector; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTruffleObject; +import com.oracle.truffle.r.runtime.data.RUnboundValue; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.ffi.DLL; +import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; +import com.oracle.truffle.r.runtime.ffi.DLL.DotSymbol; +/** + * A {@link ForeignAccess} instance captures the {@link Thread} that creates it and all uses are + * checked against the current thread. Therefore, in a world with multiple {@link PolyglotEngine}s, + * aka multiple {@link Thread} and {@link RContext} instances, it is not possible to use a simple + * global constant value for the {@link ForeignAccess} instance that could be associated directly + * with the {@link TruffleObject} class. + * + * This factory provides a generic solution for all FastR types (all of which are + * {@link TruffleObject}s), at some cost in performance. + * + * The REALLY bad news is that we cannot use {@link RContext} to store the state because, although + * that should be possible, at the time the call to {@link #getForeignAccess(RTruffleObject)} + * happens the {@link RContext} may not have been associated with a thread, so + * {@link RContext#getInstance()} will fail. In short the mapping has to be established using + * {@link Thread} not {@link RContext} and there is no call that informs us ahead of a call to + * {@link #getForeignAccess} that a new thread is in play. We use a Truffle {@link Assumption} to + * provide a fast path in the normal, single-threaded, case. TODO Apparently a call to + * {@link #getForeignAccess(RTruffleObject)} should,in fact, only occur on the slow path, and an + * assertion to that effect has been added. If true, then the fast path code can be simplified. + * + * For most types we use the {@link MessageResolution} facility to automatically generate the + * factory for creating the {@link ForeignAccess} instance. The exceptions are the (many) subclasses + * of {@link RAbstractVector} as these have the same handling but the generator cannot handle + * abstract classes. + * + */ public final class RForeignAccessFactoryImpl implements RForeignAccessFactory { + /** + * The subset of the full set of types that are supported for foreign access. N.B. This list + * includes types that are not expected to travel between high-level languages, but may travel + * into the native world (when implemented in Truffle). + */ + private static final Class<?>[] FOREIGN_CLASSES = new Class<?>[]{ + RRaw.class, RComplex.class, RIntSequence.class, + RDoubleSequence.class, RIntVector.class, RDoubleVector.class, + RRawVector.class, RComplexVector.class, RStringVector.class, RLogicalVector.class, + RFunction.class, RNull.class, REnvironment.class, + RList.class, RSymbol.class, + RPairList.class, RExternalPtr.class, RUnboundValue.class, + DLLInfo.class, DotSymbol.class}; + + private static final class ForeignAccessState { + + private static final class TableEntry { + private final Class<? extends RTruffleObject> clazz; // for sanity check + private final ForeignAccess foreignAccess; + + private TableEntry(Class<? extends RTruffleObject> clazz, ForeignAccess foreignAccess) { + this.clazz = clazz; + this.foreignAccess = foreignAccess; + } + } - private static final class TableEntry { - private final Class<? extends RTruffleObject> clazz; - private final ForeignAccess foreignAccess; /** - * {@link PolyglotEngine} checks the thread on a {@link ForeignAccess}. + * Table with a unique index for each class in {@link #FOREIGN_CLASSES}. + */ + private static Class<?>[] classTable; + /** + * Isomorphic to {@link #classTable} but contains the {@link ForeignAccess} instance. + */ + private final TableEntry[] table; + /** + * Mask to efficiently compute the table index. + */ + @CompilationFinal private static int tableMask; + /** + * The thread that this state is generated for. */ private final Thread thread; - private TableEntry(Class<? extends RTruffleObject> clazz, ForeignAccess foreignAccess) { - this.clazz = clazz; + private ForeignAccessState() { this.thread = Thread.currentThread(); - this.foreignAccess = foreignAccess; + table = new TableEntry[classTable.length]; + for (int i = 0; i < table.length; i++) { + @SuppressWarnings("unchecked") + Class<? extends RTruffleObject> checkedClass = (Class<? extends RTruffleObject>) classTable[i]; + if (checkedClass != null) { + table[i] = new TableEntry(checkedClass, createForeignAccess(checkedClass)); + } + } } - } - TableEntry[] table = new TableEntry[32]; - int tableIndex; + private ForeignAccess get(RTruffleObject obj) { + Class<? extends RTruffleObject> clazz = obj.getClass(); + return get(clazz); + } - @Override - public ForeignAccess getForeignAccess(RTruffleObject obj) { - return get(obj); - } + private ForeignAccess get(Class<? extends RTruffleObject> clazz) { + int index = System.identityHashCode(clazz) & tableMask; + assert table[index].clazz == clazz; + return table[index].foreignAccess; + } + + static { + generatePrototypeTable(); + } - private synchronized ForeignAccess get(RTruffleObject obj) { - Class<? extends RTruffleObject> objclazz = obj.getClass(); - Thread thread = Thread.currentThread(); - for (int i = 0; i < tableIndex; i++) { - TableEntry te = table[i]; - if (te.clazz == objclazz && te.thread == thread) { - return te.foreignAccess; + /** + * Create a table that has a unique index for every member of {@link #FOREIGN_CLASSES} for + * efficient access. Since {@link System#identityHashCode(Object)} can vary from run to run, + * the size of the table may vary, but is typically in the range 64-4096. + */ + private static void generatePrototypeTable() { + int ts = 32; + while (true) { + classTable = new Class<?>[ts]; + boolean collision = false; + for (int i = 0; i < FOREIGN_CLASSES.length; i++) { + Class<?> clazz = FOREIGN_CLASSES[i]; + int h = System.identityHashCode(clazz); + int hc = h % ts; + if (classTable[hc] == null) { + classTable[hc] = clazz; + } else { + collision = true; + break; + } + } + if (!collision) { + break; + } else { + ts = ts * 2; + } } + tableMask = ts - 1; } - return createForeignAccess(objclazz); - } - @TruffleBoundary - private ForeignAccess createForeignAccess(Class<? extends RTruffleObject> clazz) { - ForeignAccess foreignAccess = null; - String name = clazz.getSimpleName(); - if (RNull.class.isAssignableFrom(clazz)) { - foreignAccess = RNullMRForeign.createAccess(); - } else if (RList.class.isAssignableFrom(clazz)) { - foreignAccess = RListMRForeign.createAccess(); - } else if (REnvironment.class.isAssignableFrom(clazz)) { - foreignAccess = REnvironmentMRForeign.createAccess(); - } else if (RPairList.class.isAssignableFrom(clazz)) { - foreignAccess = RPairListMRForeign.createAccess(); - } else if (RFunction.class.isAssignableFrom(clazz)) { - foreignAccess = RFunctionMRForeign.createAccess(); - } else { - if (RAbstractVector.class.isAssignableFrom(clazz)) { - foreignAccess = ForeignAccess.create(RAbstractVector.class, new RAbstractVectorAccessFactory()); + @TruffleBoundary + private static ForeignAccess createForeignAccess(Class<? extends RTruffleObject> clazz) { + ForeignAccess foreignAccess = null; + String name = clazz.getSimpleName(); + if (RNull.class.isAssignableFrom(clazz)) { + foreignAccess = RNullMRForeign.createAccess(); + } else if (RList.class.isAssignableFrom(clazz)) { + foreignAccess = RListMRForeign.createAccess(); + } else if (REnvironment.class.isAssignableFrom(clazz)) { + foreignAccess = REnvironmentMRForeign.createAccess(); + } else if (RPairList.class.isAssignableFrom(clazz)) { + foreignAccess = RPairListMRForeign.createAccess(); + } else if (RFunction.class.isAssignableFrom(clazz)) { + foreignAccess = RFunctionMRForeign.createAccess(); + } else if (DLL.DLLInfo.class.isAssignableFrom(clazz)) { + foreignAccess = DLLInfoMRForeign.createAccess(); + } else if (DLL.DotSymbol.class.isAssignableFrom(clazz)) { + foreignAccess = DLLDotSymbolMRForeign.createAccess(); + } else if (RSymbol.class.isAssignableFrom(clazz)) { + foreignAccess = RSymbolMRForeign.createAccess(); + } else if (RExternalPtr.class.isAssignableFrom(clazz)) { + foreignAccess = RExternalPtrMRForeign.createAccess(); + } else if (RUnboundValue.class.isAssignableFrom(clazz)) { + foreignAccess = RUnboundValueMRForeign.createAccess(); } else { - throw RInternalError.unimplemented("foreignAccess: " + name); + if (RAbstractVector.class.isAssignableFrom(clazz)) { + foreignAccess = ForeignAccess.create(RAbstractVector.class, new RAbstractVectorAccessFactory()); + } else { + throw RInternalError.unimplemented("foreignAccess: " + name); + } } + return foreignAccess; } - TableEntry te = new TableEntry(clazz, foreignAccess); - table[tableIndex++] = te; - return te.foreignAccess; } + /** + * In normal execution, there is only one thread. + */ + private static final Assumption singleStateAssumption = Truffle.getRuntime().createAssumption("single ForeignAccessState"); + /** + * In case of multiple threads, the per-thread state. + */ + private static final ThreadLocal<ForeignAccessState> threadLocalState = new ThreadLocal<>(); + /** + * In single thread mode, a fast path to the state. In multi-thread mode set to {@code null}. + */ + @CompilationFinal private static ForeignAccessState singleForeignAccessState; + + @Override + public ForeignAccess getForeignAccess(RTruffleObject obj) { + CompilerAsserts.neverPartOfCompilation("getForeignAccess"); + ForeignAccessState foreignAccessState; + if (singleStateAssumption.isValid()) { + foreignAccessState = singleForeignAccessState; + if (foreignAccessState == null) { + // very first call + foreignAccessState = new ForeignAccessState(); + singleForeignAccessState = foreignAccessState; + threadLocalState.set(foreignAccessState); + } else { + // check thread + if (Thread.currentThread() != foreignAccessState.thread) { + singleStateAssumption.invalidate(); + singleForeignAccessState = null; + foreignAccessState = new ForeignAccessState(); + } + } + } else { + // use the threadLocal + foreignAccessState = threadLocalState.get(); + } + ForeignAccess result = foreignAccessState.get(obj); + return result; + } + @Override public Class<? extends TruffleLanguage<RContext>> getTruffleLanguage() { return TruffleRLanguage.class; } + } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RListMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RListMR.java index e1b29ff4d097c17b20b90f33cd768a97bfffcf2c..d694fbe0c4a3530bf847223c4379d3ee2fccdd9f 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RListMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RListMR.java @@ -32,10 +32,10 @@ import com.oracle.truffle.r.engine.TruffleRLanguage; import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; import com.oracle.truffle.r.nodes.access.vector.ReplaceVectorNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext.RCloseable; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RList; @MessageResolution(receiverType = RList.class, language = TruffleRLanguage.class) @@ -106,12 +106,12 @@ public class RListMR { @Resolve(message = "KEYS") public abstract static class RListKeysNode extends Node { @Child private Node findContext = TruffleRLanguage.INSTANCE.actuallyCreateFindContextNode(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @SuppressWarnings("try") protected Object access(RList receiver) { try (RCloseable c = RContext.withinContext(TruffleRLanguage.INSTANCE.actuallyFindContext0(findContext))) { - return receiver.getNames(attrProfiles); + return getNamesNode.getNames(receiver); } } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RSymbolMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RSymbolMR.java new file mode 100644 index 0000000000000000000000000000000000000000..2eb3cb9661492abbde68aa3821eeb7a614028ec9 --- /dev/null +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RSymbolMR.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016, 2016, 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.engine.interop; + +import com.oracle.truffle.api.interop.CanResolve; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.engine.TruffleRLanguage; +import com.oracle.truffle.r.runtime.data.RSymbol; + +@MessageResolution(receiverType = RSymbol.class, language = TruffleRLanguage.class) +public class RSymbolMR { + @CanResolve + public abstract static class RSymbolCheck extends Node { + + protected static boolean test(TruffleObject receiver) { + return receiver instanceof RSymbol; + } + } + +} diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RUnboundValueMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RUnboundValueMR.java new file mode 100644 index 0000000000000000000000000000000000000000..ff0c179f53dafceb6e7ea0ca17e89896190b0fd2 --- /dev/null +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RUnboundValueMR.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016, 2016, 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.engine.interop; + +import com.oracle.truffle.api.interop.CanResolve; +import com.oracle.truffle.api.interop.MessageResolution; +import com.oracle.truffle.api.interop.Resolve; +import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.engine.TruffleRLanguage; +import com.oracle.truffle.r.runtime.data.RUnboundValue; + +@MessageResolution(receiverType = RUnboundValue.class, language = TruffleRLanguage.class) +public class RUnboundValueMR { + @Resolve(message = "IS_BOXED") + public abstract static class RUnboundValueIsBoxedNode extends Node { + protected Object access(@SuppressWarnings("unused") RUnboundValue receiver) { + return false; + } + } + + @Resolve(message = "HAS_SIZE") + public abstract static class RUnboundValueHasSizeNode extends Node { + protected Object access(@SuppressWarnings("unused") RUnboundValue receiver) { + return false; + } + } + + @Resolve(message = "IS_NULL") + public abstract static class RUnboundValueIsNullNode extends Node { + protected Object access(@SuppressWarnings("unused") RUnboundValue receiver) { + return false; + } + } + + @CanResolve + public abstract static class RUnboundValueCheck extends Node { + + protected static boolean test(TruffleObject receiver) { + return receiver instanceof RUnboundValue; + } + } + +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java index 728a1efd4b830abf09db8db075cd947356ce93ed..72fe424293cbb87439f36e62ac18a963e59595d0 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/graphics/RGraphics.java @@ -26,8 +26,8 @@ import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.ffi.DLL; +import com.oracle.truffle.r.runtime.ffi.FFIRootNode; import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; -import com.oracle.truffle.r.runtime.ffi.RFFIFactory; /** * A placeholder to keep {@code REngine} limited to calling the {@link #initialize} method. Two @@ -64,7 +64,7 @@ public class RGraphics { DLL.RegisteredNativeSymbol rns = DLL.RegisteredNativeSymbol.any(); DLL.SymbolHandle func = DLL.findSymbol("InitGraphics", null, rns); assert func != DLL.SYMBOL_NOT_FOUND; - RFFIFactory.getRFFI().getCallRFFI().invokeVoidCall(new NativeCallInfo("InitGraphics", func, DLL.findLibrary("graphics")), new Object[0]); + FFIRootNode.createCallTarget().call(new NativeCallInfo("InitGraphics", func, DLL.findLibrary("graphics")), true, new Object[0]); } } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/grid/GridFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/grid/GridFunctions.java index 78338d6c6cc4335ed97664ba2bcbe401287e6105..d5b7d3673e414fdb57e61d873620e74941340b9a 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/grid/GridFunctions.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/grid/GridFunctions.java @@ -23,25 +23,31 @@ import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.ffi.GridRFFI; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; /** * The .Call support for the grid package. */ public class GridFunctions { + public abstract static class InitGrid extends RExternalBuiltinNode.Arg1 { + @Child GridRFFI.GridRFFINode gridRFFINode = RFFIFactory.getRFFI().getGridRFFI().createGridRFFINode(); + @Specialization @TruffleBoundary protected Object initGrid(REnvironment gridEvalEnv) { - return RFFIFactory.getRFFI().getGridRFFI().initGrid(gridEvalEnv); + return gridRFFINode.initGrid(gridEvalEnv); } } public static final class KillGrid extends RExternalBuiltinNode { + @Child GridRFFI.GridRFFINode gridRFFINode = RFFIFactory.getRFFI().getGridRFFI().createGridRFFINode(); + @Override @TruffleBoundary public Object call(RArgsValuesAndNames args) { - return RFFIFactory.getRFFI().getGridRFFI().killGrid(); + return gridRFFINode.killGrid(); } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java index 882a6fcf1d1dd0f31aaeb091c4e7c229d3b332e4..8aca802a24be27ab35c04541f29133abeaf55720 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java @@ -39,7 +39,6 @@ import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; @@ -307,10 +306,11 @@ public class MethodsListDispatch { public abstract Object executeObject(String name, REnvironment rho, String pckg); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Child private CastToVectorNode castToVector = CastToVectorNodeGen.create(false); @Child private ClassHierarchyScalarNode classHierarchyNode = ClassHierarchyScalarNodeGen.create(); @Child private PromiseHelperNode promiseHelper; + @Child private GetFixedAttributeNode getGenericAttrNode = GetFixedAttributeNode.create(RRuntime.GENERIC_ATTR_KEY); + @Child private GetFixedAttributeNode getPckgAttrNode = GetFixedAttributeNode.create(RRuntime.PCKG_ATTR_KEY); @Specialization protected Object getGeneric(String name, REnvironment env, String pckg) { @@ -327,9 +327,9 @@ public class MethodsListDispatch { if (o != null) { RAttributable vl = (RAttributable) o; boolean ok = false; - if (vl instanceof RFunction && vl.getAttr(attrProfiles, RRuntime.GENERIC_ATTR_KEY) != null) { + if (vl instanceof RFunction && getGenericAttrNode.execute(vl) != null) { if (pckg.length() > 0) { - Object gpckgObj = vl.getAttr(attrProfiles, RRuntime.PCKG_ATTR_KEY); + Object gpckgObj = getPckgAttrNode.execute(vl); if (gpckgObj != null) { String gpckg = checkSingleString(castToVector.execute(gpckgObj), false, "The \"package\" slot in generic function object", this, classHierarchyNode); ok = pckg.equals(gpckg); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/Slot.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/Slot.java index 201f0d7d149f0946c17019e73cdccd860f6f9cc5..03eb4418b5467abf60e79721eda6931383cef8da 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/Slot.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/Slot.java @@ -25,7 +25,7 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -// Transcribed from src/library/methods/slot.c +// Transcribed from src/library/methods/src/slot.c public class Slot { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java new file mode 100644 index 0000000000000000000000000000000000000000..3ab4aaf4548915fe6de78d90ce103a82f522d559 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java @@ -0,0 +1,157 @@ +/* + * 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) 1998 Ross Ihaka + * Copyright (c) 1998--2008, The R Core Team + * Copyright (c) 2016, 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats; + +import static com.oracle.truffle.r.library.stats.MathConstants.M_PI; +import static com.oracle.truffle.r.library.stats.TOMS708.fabs; + +import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2; + +public final class Cauchy { + private Cauchy() { + // contains only static classes + } + + public static final class RCauchy implements RandFunction2_Double { + @Override + public double evaluate(double location, double scale, RandomNumberProvider rand) { + if (Double.isNaN(location) || !Double.isFinite(scale) || scale < 0) { + return RMath.mlError(); + } + if (scale == 0. || !Double.isFinite(location)) { + return location; + } else { + return location + scale * Math.tan(M_PI * rand.unifRand()); + } + } + } + + public static final class DCauchy implements Function3_1 { + @Override + public double evaluate(double x, double location, double scale, boolean giveLog) { + double y; + /* NaNs propagated correctly */ + if (Double.isNaN(x) || Double.isNaN(location) || Double.isNaN(scale)) { + return x + location + scale; + } + if (scale <= 0) { + return RMath.mlError(); + } + + y = (x - location) / scale; + return giveLog ? -Math.log(M_PI * scale * (1. + y * y)) : 1. / (M_PI * scale * (1. + y * y)); + } + } + + public static final class PCauchy implements Function3_2 { + @Override + public double evaluate(double x, double location, double scale, boolean lowerTail, boolean logP) { + if (Double.isNaN(x) || Double.isNaN(location) || Double.isNaN(scale)) { + return x + location + scale; + } + + if (scale <= 0) { + return RMath.mlError(); + } + + x = (x - location) / scale; + if (Double.isNaN(x)) { + return RMath.mlError(); + } + + if (!Double.isFinite(x)) { + if (x < 0) { + return DPQ.rdt0(lowerTail, logP); + } else { + return DPQ.rdt1(lowerTail, logP); + } + } + + if (!lowerTail) { + x = -x; + } + + /* + * for large x, the standard formula suffers from cancellation. This is from Morten + * Welinder thanks to Ian Smith's atan(1/x) : + */ + + // GnuR has #ifdef HAVE_ATANPI where it uses atanpi function, here we only implement the + // case when atanpi is not available for the moment + if (fabs(x) > 1) { + double y = Math.atan(1 / x) / M_PI; + return (x > 0) ? DPQ.rdclog(y, logP) : DPQ.rdval(-y, logP); + } else { + return DPQ.rdval(0.5 + Math.atan(x) / M_PI, logP); + } + } + } + + public static final class QCauchy implements Function3_2 { + @Override + public double evaluate(double p, double location, double scale, boolean lowerTail, boolean logP) { + if (Double.isNaN(p) || Double.isNaN(location) || Double.isNaN(scale)) { + return p + location + scale; + } + try { + DPQ.rqp01check(p, logP); + } catch (EarlyReturn e) { + return e.result; + } + if (scale <= 0 || !Double.isFinite(scale)) { + if (scale == 0) { + return location; + } + return RMath.mlError(); + } + + if (logP) { + if (p > -1) { + /* + * when ep := Math.exp(p), tan(pi*ep)= -tan(pi*(-ep))= -tan(pi*(-ep)+pi) = + * -tan(pi*(1-ep)) = = -tan(pi*(-Math.expm1(p)) for p ~ 0, Math.exp(p) ~ 1, + * tan(~0) may be better than tan(~pi). + */ + if (p == 0.) { + /* needed, since 1/tan(-0) = -Inf for some arch. */ + return location + (lowerTail ? scale : -scale) * Double.POSITIVE_INFINITY; + } + lowerTail = !lowerTail; + p = -Math.expm1(p); + } else { + p = Math.exp(p); + } + } else { + if (p > 0.5) { + if (p == 1.) { + return location + (lowerTail ? scale : -scale) * Double.POSITIVE_INFINITY; + } + p = 1 - p; + lowerTail = !lowerTail; + } + } + + if (p == 0.5) { + return location; + } // avoid 1/Inf below + if (p == 0.) { + return location + (lowerTail ? scale : -scale) * Double.NEGATIVE_INFINITY; + } // p = 1. is handled above + return location + (lowerTail ? -scale : scale) / RMath.tanpi(p); + /* -1/tan(pi * p) = -cot(pi * p) = tan(pi * (p - 1/2)) */ + } + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java index d4c6dba39241d1d16c7527650a7bcbec5a5c9434..9094f3e34ff8d521a8ec586a20f0686e6d561c10 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java @@ -17,8 +17,10 @@ import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.instanceOf; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; +import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; -import com.oracle.truffle.r.nodes.attributes.SetAttributeNodeGen; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -33,6 +35,8 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class Cdist extends RExternalBuiltinNode.Arg4 { private static final NACheck naCheck = NACheck.create(); + @Child private GetFixedAttributeNode getNamesAttrNode = GetFixedAttributeNode.createNames(); + @Override protected void createCasts(CastBuilder casts) { casts.arg(0).asDoubleVector(); @@ -44,21 +48,24 @@ public abstract class Cdist extends RExternalBuiltinNode.Arg4 { @Specialization(guards = "method == cachedMethod") protected RDoubleVector cdist(RAbstractDoubleVector x, @SuppressWarnings("unused") int method, RList list, double p, @SuppressWarnings("unused") @Cached("method") int cachedMethod, @Cached("getMethod(method)") Method methodObj, - @Cached("create()") SetAttributeNode setAttrNode) { - int nr = RRuntime.nrows(x); - int nc = RRuntime.ncols(x); + @Cached("create()") SetAttributeNode setAttrNode, + @Cached("create()") SetClassAttributeNode setClassAttrNode, + @Cached("create()") GetDimAttributeNode getDimNode) { + int nr = getDimNode.nrows(x); + int nc = getDimNode.ncols(x); int n = nr * (nr - 1) / 2; /* avoid int overflow for N ~ 50,000 */ double[] ans = new double[n]; RDoubleVector xm = x.materialize(); rdistance(xm.getDataWithoutCopying(), nr, nc, ans, false, methodObj, p); RDoubleVector result = RDataFactory.createDoubleVector(ans, naCheck.neverSeenNA()); DynamicObject resultAttrs = result.initAttributes(); - RStringVector names = (RStringVector) list.getAttr(RRuntime.NAMES_ATTR_KEY); + + RStringVector names = (RStringVector) getNamesAttrNode.execute(list); for (int i = 0; i < names.getLength(); i++) { String name = names.getDataAt(i); Object listValue = list.getDataAt(i); if (name.equals(RRuntime.CLASS_ATTR_KEY)) { - result.setClassAttr(listValue instanceof RStringVector ? (RStringVector) listValue : RDataFactory.createStringVectorFromScalar((String) listValue)); + setClassAttrNode.execute(result, listValue instanceof RStringVector ? (RStringVector) listValue : RDataFactory.createStringVectorFromScalar((String) listValue)); } else { setAttrNode.execute(resultAttrs, name, listValue); } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java new file mode 100644 index 0000000000000000000000000000000000000000..c39fa8c5e71ef0ff5c84add184ea21ccee6cd3df --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java @@ -0,0 +1,34 @@ +/* + * 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) 1998 Ross Ihaka + * Copyright (c) 2000, The R Core Team + * Copyright (c) 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats; + +import static com.oracle.truffle.r.library.stats.GammaFunctions.dgamma; +import static com.oracle.truffle.r.library.stats.GammaFunctions.pgamma; + +import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2; + +public final class Chisq { + public static final class PChisq implements Function2_2 { + @Override + public double evaluate(double x, double df, boolean lowerTail, boolean logP) { + return pgamma(x, df / 2., 2., lowerTail, logP); + } + } + + public static final class DChisq implements Function2_1 { + @Override + public double evaluate(double x, double df, boolean giveLog) { + return dgamma(x, df / 2., 2., giveLog); + } + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java index 1aff0091ef52ff496d09f462d7c2a1fd8db2e4dd..5080206bbed26ecd787667839af2adae4bfe9f3f 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java @@ -22,6 +22,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -76,6 +77,8 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { private final BranchProfile error = BranchProfile.create(); private final BranchProfile warning = BranchProfile.create(); + @Child private GetDimAttributeNode getDimsNode = GetDimAttributeNode.create(); + private final LoopConditionProfile loopLength = LoopConditionProfile.createCountingProfile(); public RDoubleVector corcov(RDoubleVector x, RDoubleVector y, @SuppressWarnings("unused") int method, boolean iskendall, RBaseNode invokingNode) throws RError { @@ -175,14 +178,14 @@ public abstract class Covcor extends RExternalBuiltinNode.Arg4 { return ans; } - private static int ncols(RDoubleVector x) { + private int ncols(RDoubleVector x) { assert x.isMatrix(); - return x.getDimensions()[1]; + return getDimsNode.getDimensions(x)[1]; } - private static int nrows(RDoubleVector x) { + private int nrows(RDoubleVector x) { assert x.isMatrix(); - return x.getDimensions()[0]; + return getDimsNode.getDimensions(x)[0]; } private void complete1(int n, int ncx, RDoubleVector x, RIntVector ind, boolean naFail) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java index 2887c8f67d5837b4fe5f76b91940f39a199ac373..8c291da19ee516d98b50441e98361f0af40b22b1 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cutree.java @@ -10,10 +10,11 @@ */ package com.oracle.truffle.r.library.stats; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; -import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -29,7 +30,7 @@ public abstract class Cutree extends RExternalBuiltinNode.Arg2 { } @Specialization - protected RIntVector cutree(RAbstractIntVector mergeIn, RAbstractIntVector whichIn) { + protected RIntVector cutree(RAbstractIntVector mergeIn, RAbstractIntVector whichIn, @Cached("create()") GetDimAttributeNode getDimNode) { RIntVector merge = mergeIn.materialize(); RIntVector which = whichIn.materialize(); int whichLen = which.getLength(); @@ -43,7 +44,7 @@ public abstract class Cutree extends RExternalBuiltinNode.Arg2 { int mm = 0; boolean foundJ; - int n = RRuntime.nrows(merge) + 1; + int n = getDimNode.nrows(merge) + 1; /* * The C code uses 1-based indices for the next three arrays and so set the int * value * behind the actual start of the array. To keep the logic equivalent, we call adj(k) on the diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java new file mode 100644 index 0000000000000000000000000000000000000000..a6a5a767d9e71e9bf4b8f8baa772bdaaf1124178 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java @@ -0,0 +1,95 @@ +/* + * 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) 2000--2014, The R Core Team + * Copyright (c) 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +// Acknowledgement from GnuR header: +// Author: Catherine Loader, catherine@research.bell-labs.com, October 23, 2000. +package com.oracle.truffle.r.library.stats; + +import static com.oracle.truffle.r.library.stats.LBeta.lbeta; + +import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1; + +public class DBeta implements Function3_1 { + @Override + public double evaluate(double x, double a, double b, boolean log) { + /* NaNs propagated correctly */ + if (Double.isNaN(x) || Double.isNaN(a) || Double.isNaN(b)) { + return x + a + b; + } + + if (a < 0 || b < 0) { + return RMath.mlError(); + } + if (x < 0 || x > 1) { + return (DPQ.rd0(log)); + } + + // limit cases for (a,b), leading to point masses + if (a == 0 || b == 0 || !Double.isFinite(a) || !Double.isFinite(b)) { + if (a == 0 && b == 0) { // point mass 1/2 at each of {0,1} : + if (x == 0 || x == 1) { + return Double.POSITIVE_INFINITY; + } else { + return DPQ.rd0(log); + } + } + if (a == 0 || a / b == 0) { // point mass 1 at 0 + if (x == 0) { + return Double.POSITIVE_INFINITY; + } else { + return DPQ.rd0(log); + } + } + if (b == 0 || b / a == 0) { // point mass 1 at 1 + if (x == 1) { + return Double.POSITIVE_INFINITY; + } else { + return DPQ.rd0(log); + } + } + // else, remaining case: a = b = Inf : point mass 1 at 1/2 + if (x == 0.5) { + return Double.POSITIVE_INFINITY; + } else { + return DPQ.rd0(log); + } + } + + if (x == 0) { + if (a > 1) { + return DPQ.rd0(log); + } + if (a < 1) { + return Double.POSITIVE_INFINITY; + } + /* a == 1 : */ + return DPQ.rdval(b, log); + } + if (x == 1) { + if (b > 1) { + return DPQ.rd0(log); + } + if (b < 1) { + return Double.POSITIVE_INFINITY; + } + /* b == 1 : */ + return (DPQ.rdval(a, log)); + } + + double lval; + if (a <= 2 || b <= 2) { + lval = (a - 1) * Math.log(x) + (b - 1) * Math.log1p(-x) - lbeta(a, b); + } else { + lval = Math.log(a + b - 1) + Dbinom.dbinomRaw(a - 1, a + b - 2, x, 1 - x, true); + } + + return DPQ.rdexp(lval, log); + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java index c033762f79c827e92511b4ef33ba34de874e2d4b..4925be2e7668b809c858a9ab8357bf45df62bcdb 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java @@ -10,120 +10,120 @@ */ package com.oracle.truffle.r.library.stats; +import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2; + import com.oracle.truffle.api.nodes.ControlFlowException; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; -// transcribed from dpq.h - +/** + * Contains macros transcribed from dpq.h. Naming convention is all lowercase and remove underscores + * from GnuR name. Some macros change control flow by explicitly returning, this is handled by + * throwing {@link EarlyReturn} exception that encapsulates the desired return value. + */ public final class DPQ { private DPQ() { - // private + // only static methods + } + + public static final class EarlyReturn extends ControlFlowException { + private static final long serialVersionUID = 1182697355931636213L; + public final double result; + + private EarlyReturn(double result) { + this.result = result; + } } // R >= 3.1.0: # define R_nonint(x) (fabs((x) - R_forceint(x)) > 1e-7) + // Note: if true should be followed by "return d0(logP)", consider using nointCheck instead public static boolean nonint(double x) { return Math.abs(x - Math.round(x)) > 1e-7 * Math.max(1., Math.abs(x)); } // R_D__0 - public static double d0(boolean logP) { + public static double rd0(boolean logP) { return logP ? Double.NEGATIVE_INFINITY : 0.; } // R_D__1 - public static double d1(boolean logP) { + public static double rd1(boolean logP) { return logP ? 0. : 1.; } // R_DT_0 - public static double dt0(boolean logP, boolean lowerTail) { - return lowerTail ? d0(logP) : d1(logP); + public static double rdt0(boolean lowerTail, boolean logP) { + return lowerTail ? rd0(logP) : rd1(logP); } - // R_DT_1 - public static double dt1(boolean logP, boolean lowerTail) { - return lowerTail ? d1(logP) : d0(logP); + // R_D_log + public static double rdlog(double p, boolean logP) { + return logP ? p : Math.log(p); } - /* Use 0.5 - p + 0.5 to perhaps gain 1 bit of accuracy */ + public static double rdtlog(double p, boolean lowerTail, boolean logp) { + return lowerTail ? rdlog(p, logp) : rdlexp(p, logp); + } + + // R_DT_1 + public static double rdt1(boolean lowerTail, boolean logP) { + return lowerTail ? rd1(logP) : rd0(logP); + } // R_D_Lval - public static double dLval(boolean lowerTail, double p) { + public static double rdlval(double p, boolean lowerTail) { return lowerTail ? p : 0.5 - p + 0.5; } - public static double dCval(double p, boolean lowerTail) { + public static double rdcval(double p, boolean lowerTail) { return lowerTail ? 0.5 - p + 0.5 : p; /* 1 - p */ } - // - public static double dVal(double x, boolean logP) { + // R_D_val + public static double rdval(double x, boolean logP) { return logP ? Math.log(x) : x; /* x in pF(x,..) */ } - // #define R_D_qIv(p) (log_p ? exp(p) : (p)) /* p in qF(p,..) */ - // R_D_exp - public static double dExp(double x, boolean logP) { + public static double rdexp(double x, boolean logP) { return logP ? x : Math.exp(x); /* exp(x) */ } - // #define R_D_log(p) (log_p ? (p) : log(p)) /* log(p) */ - public static double dClog(double p, boolean logP) { - return logP ? Math.log1p(-p) : 0.5 - p + 0.5; /* [log](1-p) */ + // R_D_LExp + public static double rdlexp(double x, boolean logP) { + return (logP ? rlog1exp(x) : RMath.log1p(-x)); } - // - // // log(1 - exp(x)) in more stable form than log1p(- R_D_qIv(x)) : - // #define R_Log1_Exp(x) ((x) > -M_LN2 ? log(-expm1(x)) : log1p(-exp(x))) - // - // #define R_D_LExp(x) (log_p ? R_Log1_Exp(x) : log1p(-x)) - // - // #define R_DT_val(x) (lower_tail ? R_D_val(x) : R_D_Clog(x)) - public static double dtCval(double x, boolean lowerTail, boolean logP) { - return lowerTail ? dClog(x, logP) : dVal(x, logP); + public static double rdfexp(double f, double x, boolean giveLog) { + return giveLog ? -0.5 * Math.log(f) + x : Math.exp(x) / Math.sqrt(f); } - // - // R_DT_qIv - public static double dtQIv(double p, boolean lowerTail, boolean logP) { - return logP ? lowerTail ? Math.exp(p) : -Math.expm1(p) : dLval(lowerTail, p); + // R_Log1_Exp + public static double rlog1exp(double x) { + return ((x) > -M_LN2 ? Math.log(-RMath.expm1(x)) : RMath.log1p(-Math.exp(x))); } - // /*#define R_DT_CIv(p) R_D_Cval(R_D_qIv(p)) * 1 - p in qF */ - - public static double dtCIv(double p, boolean lowerTail, boolean logP) { - return logP ? lowerTail ? -Math.expm1(p) : Math.exp(p) : dCval(p, lowerTail); + // R_DT_Clog + public static double rdtclog(double p, boolean lowerTail, boolean logP) { + return lowerTail ? rdlexp(p, logP) : rdlog(p, logP); } - // - // #define R_DT_exp(x) R_D_exp(R_D_Lval(x)) /* exp(x) */ - // #define R_DT_Cexp(x) R_D_exp(R_D_Cval(x)) /* exp(1 - x) */ - // - // #define R_DT_log(p) (lower_tail? R_D_log(p) : R_D_LExp(p))/* log(p) in qF */ - // #define R_DT_Clog(p) (lower_tail? R_D_LExp(p): R_D_log(p))/* log(1-p) in qF*/ - // #define R_DT_Log(p) (lower_tail? (p) : R_Log1_Exp(p)) + // R_D_Clog(p) (log_p ? log1p(-(p)) : (0.5 - (p) + 0.5)) /* [log](1-p) */ + public static double rdclog(double p, boolean logP) { + return logP ? RMath.log1p(-(p)) : (0.5 - (p) + 0.5); + } - public static final class EarlyReturn extends ControlFlowException { - private static final long serialVersionUID = 1182697355931636213L; - public final double result; + // R_DT_qIv + public static double rdtqiv(double p, boolean lowerTail, boolean logP) { + return logP ? lowerTail ? Math.exp(p) : -Math.expm1(p) : rdlval(p, lowerTail); + } - private EarlyReturn(double result) { - this.result = result; - } + // R_DT_CIv + public static double rdtciv(double p, boolean lowerTail, boolean logP) { + return logP ? lowerTail ? -Math.expm1(p) : Math.exp(p) : rdcval(p, lowerTail); } - /* - * Do the boundaries exactly for q*() functions : Often _LEFT_ = ML_NEGINF , and very often - * _RIGHT_ = ML_POSINF; - * - * R_Q_P01_boundaries(p, _LEFT_, _RIGHT_) :<==> - * - * R_Q_P01_check(p); if (p == R_DT_0) return _LEFT_ ; if (p == R_DT_1) return _RIGHT_; - * - * the following implementation should be more efficient (less tests): - */ - public static void qP01Boundaries(double p, double left, double right, boolean lowerTail, boolean logP) throws EarlyReturn { + // R_Q_P01_boundaries + public static void rqp01boundaries(double p, double left, double right, boolean lowerTail, boolean logP) throws EarlyReturn { if (logP) { if (p > 0) { throw new EarlyReturn(Double.NaN); @@ -148,17 +148,32 @@ public final class DPQ { } } - /* [neg]ative or [non int]eger : */ - public static boolean dNegInonint(double x) { - return x < 0 || nonint(x); + // R_Q_P01_check + public static void rqp01check(double p, boolean logP) throws EarlyReturn { + if ((logP && p > 0) || (!logP && (p < 0 || p > 1))) { + throw new EarlyReturn(RMath.mlError()); + } + } + + // Unimplemented macros: + // + // #define R_DT_exp(x) R_D_exp(R_D_Lval(x)) /* exp(x) */ + // #define R_DT_Cexp(x) R_D_exp(R_D_Cval(x)) /* exp(1 - x) */ + // + // #define R_DT_log(p) (lower_tail? R_D_log(p) : R_D_LExp(p))/* log(p) in qF */ + // #define R_DT_Clog(p) (lower_tail? R_D_LExp(p): R_D_log(p))/* log(1-p) in qF*/ + // #define R_DT_Log(p) (lower_tail? (p) : R_Log1_Exp(p)) + + // FastR helpers: + + public static void nointCheckWarning(double x, String varName) { + RError.warning(RError.SHOW_CALLER, Message.NON_INTEGER_N, varName, x); } - // for discrete d<distr>(x, ...) : - public static boolean dNonintCheck(double x) { + public static void nonintCheck(double x, boolean giveLog) throws EarlyReturn { if (nonint(x)) { - RError.warning(RError.SHOW_CALLER, Message.NON_INTEGER_N, "x", x); - return true; + nointCheckWarning(x, "x"); + throw new EarlyReturn(rd0(giveLog)); } - return false; } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java new file mode 100644 index 0000000000000000000000000000000000000000..b01d2a4d75603a4b862849e498ef24a41ce0e167 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java @@ -0,0 +1,42 @@ +/* + * 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) 2000--2014, The R Core Team + * Copyright (c) 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +// Acknowledgement from GnuR header: +// Author: Catherine Loader, catherine@research.bell-labs.com, October 23, 2000. +package com.oracle.truffle.r.library.stats; + +import static com.oracle.truffle.r.library.stats.GammaFunctions.dpoisRaw; +import static com.oracle.truffle.r.library.stats.MathConstants.forceint; + +import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1; + +public final class DPois implements Function2_1 { + @Override + public double evaluate(double x, double lambda, boolean giveLog) { + if (Double.isNaN(x) || Double.isNaN(lambda)) { + return x + lambda; + } + if (lambda < 0) { + return RMath.mlError(); + } + + try { + DPQ.nonintCheck(x, giveLog); + } catch (EarlyReturn e) { + return e.result; + } + if (x < 0 || !Double.isFinite(x)) { + return DPQ.rd0(giveLog); + } + + return dpoisRaw(forceint(x), lambda, giveLog); + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java index 4ea79d16d4908eeba50da3b7d8f2ae4937feb969..509f543c81aeb163e1eb86ccf6725ea40a88f95d 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dbinom.java @@ -17,6 +17,7 @@ package com.oracle.truffle.r.library.stats; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn; // transcribed from dbinom.c @@ -24,28 +25,28 @@ public final class Dbinom implements StatsFunctions.Function3_1 { private final BranchProfile nanProfile = BranchProfile.create(); - private static double dbinomRaw(double x, double n, double p, double q, boolean giveLog) { + public static double dbinomRaw(double x, double n, double p, double q, boolean giveLog) { if (p == 0) { - return ((x == 0) ? DPQ.d1(giveLog) : DPQ.d0(giveLog)); + return ((x == 0) ? DPQ.rd1(giveLog) : DPQ.rd0(giveLog)); } if (q == 0) { - return ((x == n) ? DPQ.d1(giveLog) : DPQ.d0(giveLog)); + return ((x == n) ? DPQ.rd1(giveLog) : DPQ.rd0(giveLog)); } if (x == 0) { if (n == 0) { - return DPQ.d1(giveLog); + return DPQ.rd1(giveLog); } double lc = (p < 0.1) ? -GammaFunctions.bd0(n, n * q) - n * p : n * Math.log(q); - return DPQ.dExp(lc, giveLog); + return DPQ.rdexp(lc, giveLog); } if (x == n) { double lc = (q < 0.1) ? -GammaFunctions.bd0(n, n * p) - n * q : n * Math.log(p); - return DPQ.dExp(lc, giveLog); + return DPQ.rdexp(lc, giveLog); } if (x < 0 || x > n) { - return DPQ.d0(giveLog); + return DPQ.rd0(giveLog); } /* @@ -61,7 +62,7 @@ public final class Dbinom implements StatsFunctions.Function3_1 { */ double lf = MathConstants.M_LN_2PI + Math.log(x) + Math.log1p(-x / n); - return DPQ.dExp(lc - 0.5 * lf, giveLog); + return DPQ.rdexp(lc - 0.5 * lf, giveLog); } @Override @@ -72,12 +73,19 @@ public final class Dbinom implements StatsFunctions.Function3_1 { return x + n + p; } - if (p < 0 || p > 1 || DPQ.dNegInonint(n)) { + if (p < 0 || p > 1 || n < 0 || DPQ.nonint(n)) { nanProfile.enter(); return Double.NaN; } - if (DPQ.dNonintCheck(x) || x < 0 || !Double.isFinite(x)) { - return DPQ.d0(giveLog); + + try { + DPQ.nonintCheck(x, giveLog); + } catch (EarlyReturn e) { + return e.result; + } + + if (x < 0 || !Double.isFinite(x)) { + return DPQ.rd0(giveLog); } return dbinomRaw(MathConstants.forceint(x), MathConstants.forceint(n), p, 1 - p, giveLog); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java new file mode 100644 index 0000000000000000000000000000000000000000..ded5ed50571f78b97300e4c76b7d0cdab74cb34c --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java @@ -0,0 +1,70 @@ +/* + * 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) 2000--2014, The R Core Team + * Copyright (c) 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +// Acknowledgement from GnuR header: +// Author: Catherine Loader, catherine@research.bell-labs.com, October 23, 2000. +package com.oracle.truffle.r.library.stats; + +import static com.oracle.truffle.r.library.stats.Dbinom.dbinomRaw; +import static com.oracle.truffle.r.library.stats.GammaFunctions.dgamma; + +import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1; + +public final class Df implements Function3_1 { + @Override + public double evaluate(double x, double m, double n, boolean giveLog) { + double p; + double q; + double f; + double dens; + + if (Double.isNaN(x) || Double.isNaN(m) || Double.isNaN(n)) { + return x + m + n; + } + + if (m <= 0 || n <= 0) { + return RMath.mlError(); + } + if (x < 0.) { + return DPQ.rd0(giveLog); + } + if (x == 0.) { + return m > 2 ? DPQ.rd0(giveLog) : (m == 2 ? DPQ.rd1(giveLog) : Double.POSITIVE_INFINITY); + } + if (!Double.isFinite(m) && !Double.isFinite(n)) { /* both +Inf */ + if (x == 1.) { + return Double.POSITIVE_INFINITY; + } else { + return DPQ.rd0(giveLog); + } + } + if (!Double.isFinite(n)) { + /* must be +Inf by now */ + return dgamma(x, m / 2, 2. / m, giveLog); + } + if (m > 1e14) { /* includes +Inf: code below is inaccurate there */ + dens = dgamma(1. / x, n / 2, 2. / n, giveLog); + return giveLog ? dens - 2 * Math.log(x) : dens / (x * x); + } + + f = 1. / (n + x * m); + q = n * f; + p = x * m * f; + + if (m >= 2) { + f = m * q / 2; + dens = dbinomRaw((m - 2) / 2, (m + n - 2) / 2, p, q, giveLog); + } else { + f = m * m * q / (2 * p * (m + n)); + dens = dbinomRaw(m / 2, (m + n) / 2, p, q, giveLog); + } + return (giveLog ? Math.log(f) + dens : f * dens); + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java index 01a1f747831be975f900f91e34525d9d0cc6dd20..b33d733a7cb6b25fac7190bc27dcaca9a1830b73 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre.java @@ -10,10 +10,11 @@ */ package com.oracle.truffle.r.library.stats; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; -import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; @@ -25,9 +26,9 @@ public abstract class DoubleCentre extends RExternalBuiltinNode.Arg1 { } @Specialization - protected RDoubleVector doubleCentre(RAbstractDoubleVector aVecAbs) { + protected RDoubleVector doubleCentre(RAbstractDoubleVector aVecAbs, @Cached("create()") GetDimAttributeNode getDimNode) { RDoubleVector aVec = aVecAbs.materialize(); - int n = RRuntime.nrows(aVec); + int n = getDimNode.nrows(aVec); double[] a = aVec.getDataWithoutCopying(); // does not copy for (int i = 0; i < n; i++) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java new file mode 100644 index 0000000000000000000000000000000000000000..62245897573ddf9e784b89fd9b97acd1d21fa249 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java @@ -0,0 +1,77 @@ +/* + * 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) 2000--2014, The R Core Team + * Copyright (c) 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +// Acknowledgement from GnuR header: +// Author: Catherine Loader, catherine@research.bell-labs.com, October 23, 2000. +package com.oracle.truffle.r.library.stats; + +import static com.oracle.truffle.r.library.stats.GammaFunctions.bd0; +import static com.oracle.truffle.r.library.stats.GammaFunctions.dnorm; +import static com.oracle.truffle.r.library.stats.GammaFunctions.stirlerr; +import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON; +import static com.oracle.truffle.r.library.stats.MathConstants.M_1_SQRT_2PI; +import static com.oracle.truffle.r.library.stats.MathConstants.M_LN_SQRT_2PI; + +import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1; + +public final class Dt implements Function2_1 { + @Override + public double evaluate(double x, double n, boolean giveLog) { + if (Double.isNaN(x) || Double.isNaN(n)) { + return x + n; + } + + if (n <= 0) { + return RMath.mlError(); + } + + if (!Double.isFinite(x)) { + return DPQ.rd0(giveLog); + } + if (!Double.isFinite(n)) { + return dnorm(x, 0., 1., giveLog); + } + + double u; + double t = -bd0(n / 2., (n + 1) / 2.) + stirlerr((n + 1) / 2.) - stirlerr(n / 2.); + double x2n = x * x / n; // in [0, Inf] + double ax = 0.; // <- -Wpedantic + double lx2n; // := Math.log(Math.sqrt(1 + x2n)) = Math.log(1 + x2n)/2 + boolean lrgx2n = (x2n > 1. / DBL_EPSILON); + if (lrgx2n) { // large x^2/n : + ax = Math.abs(x); + lx2n = Math.log(ax) - Math.log(n) / 2.; // = Math.log(x2n)/2 = 1/2 * Math.log(x^2 / n) + u = // Math.log(1 + x2n) * n/2 = n * Math.log(1 + x2n)/2 = + n * lx2n; + } else if (x2n > 0.2) { + lx2n = Math.log(1 + x2n) / 2.; + u = n * lx2n; + } else { + lx2n = Math.log1p(x2n) / 2.; + u = -bd0(n / 2., (n + x * x) / 2.) + x * x / 2.; + } + + // old: return R_D_fMath.exp(M_2PI*(1+x2n), t-u); + + // R_D_fMath.exp(f,x) := (give_Math.log ? -0.5*Math.log(f)+(x) : Math.exp(x)/Math.sqrt(f)) + // f = 2pi*(1+x2n) + // ==> 0.5*Math.log(f) = Math.log(2pi)/2 + Math.log(1+x2n)/2 = Math.log(2pi)/2 + l_x2n + // 1/Math.sqrt(f) = 1/Math.sqrt(2pi * (1+ x^2 / n)) + // = 1/Math.sqrt(2pi)/(|x|/Math.sqrt(n)*Math.sqrt(1+1/x2n)) + // = M_1_SQRT_2PI * Math.sqrt(n)/ (|x|*Math.sqrt(1+1/x2n)) + if (giveLog) { + return t - u - (M_LN_SQRT_2PI + lx2n); + } + + // else : if(lrg_x2n) : Math.sqrt(1 + 1/x2n) ='= Math.sqrt(1) = 1 + double tmp = (lrgx2n ? Math.sqrt(n) / ax : Math.exp(-lx2n)); + return Math.exp(t - u) * M_1_SQRT_2PI * tmp; + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java new file mode 100644 index 0000000000000000000000000000000000000000..05c81882607860c2964fcd497ca817555579a8b3 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java @@ -0,0 +1,95 @@ +/* + * 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) 1998 Ross Ihaka + * Copyright (c) 2000, The R Core Team + * Copyright (c) 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats; + +import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2; + +public class Exp { + public static final class DExp implements Function2_1 { + @Override + public double evaluate(double x, double scale, boolean giveLog) { + /* NaNs propagated correctly */ + if (Double.isNaN(x) || Double.isNaN(scale)) { + return x + scale; + } + + if (scale <= 0.0) { + return RMath.mlError(); + } + + if (x < 0.) { + return DPQ.rd0(giveLog); + } + return (giveLog ? (-x / scale) - Math.log(scale) : Math.exp(-x / scale) / scale); + } + } + + public static final class RExp implements RandFunction1_Double { + @Override + public double evaluate(double scale, RandomNumberProvider rand) { + if (!Double.isFinite(scale) || scale <= 0.0) { + return scale == 0. ? 0. : RMath.mlError(); + } + return scale * rand.expRand(); + } + } + + public static final class PExp implements Function2_2 { + @Override + public double evaluate(double x, double scale, boolean lowerTail, boolean logP) { + if (Double.isNaN(x) || Double.isNaN(scale)) { + return x + scale; + } + if (scale < 0) { + return RMath.mlError(); + } + + if (x <= 0.) { + return DPQ.rdt0(lowerTail, logP); + } + + /* same as weibull( shape = 1): */ + x = -(x / scale); + return lowerTail ? (logP ? DPQ.rlog1exp(x) : -RMath.expm1(x)) : DPQ.rdexp(x, logP); + } + } + + public static final class QExp implements Function2_2 { + @Override + public double evaluate(double p, double scale, boolean lowerTail, boolean logP) { + if (Double.isNaN(p) || Double.isNaN(scale)) { + return p + scale; + } + + if (scale < 0) { + return RMath.mlError(); + } + + try { + DPQ.rqp01check(p, logP); + } catch (EarlyReturn e) { + return e.result; + } + + if (p == DPQ.rdt0(lowerTail, logP)) { + return 0; + } + + return -scale * DPQ.rdtclog(p, lowerTail, logP); + + } + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java index bdad479b98efd9546b467c40cfb17ba753dc7e19..1638c38e2ce080d756db52c1c368bd0c9044230a 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java @@ -18,29 +18,26 @@ */ package com.oracle.truffle.r.library.stats; -import static com.oracle.truffle.r.library.stats.StatsUtil.DBLEPSILON; -import static com.oracle.truffle.r.library.stats.StatsUtil.M_1_SQRT_2PI; -import static com.oracle.truffle.r.library.stats.StatsUtil.M_2PI; -import static com.oracle.truffle.r.library.stats.StatsUtil.M_LN2; -import static com.oracle.truffle.r.library.stats.StatsUtil.M_SQRT_32; -import static com.oracle.truffle.r.library.stats.StatsUtil.chebyshevEval; -import static com.oracle.truffle.r.library.stats.StatsUtil.expm1; -import static com.oracle.truffle.r.library.stats.StatsUtil.fmax2; -import static com.oracle.truffle.r.library.stats.StatsUtil.log1p; -import static com.oracle.truffle.r.library.stats.StatsUtil.rd0; -import static com.oracle.truffle.r.library.stats.StatsUtil.rd1; -import static com.oracle.truffle.r.library.stats.StatsUtil.rdexp; -import static com.oracle.truffle.r.library.stats.StatsUtil.rdfexp; -import static com.oracle.truffle.r.library.stats.StatsUtil.rdt0; -import static com.oracle.truffle.r.library.stats.StatsUtil.rdt1; -import static com.oracle.truffle.r.library.stats.StatsUtil.rdtclog; -import static com.oracle.truffle.r.library.stats.StatsUtil.rdtlog; -import static com.oracle.truffle.r.library.stats.StatsUtil.rdtqiv; -import static com.oracle.truffle.r.library.stats.StatsUtil.rlog1exp; -import static com.oracle.truffle.r.library.stats.StatsUtil.rqp01check; +import static com.oracle.truffle.r.library.stats.DPQ.rd0; +import static com.oracle.truffle.r.library.stats.DPQ.rd1; +import static com.oracle.truffle.r.library.stats.DPQ.rdexp; +import static com.oracle.truffle.r.library.stats.DPQ.rdfexp; +import static com.oracle.truffle.r.library.stats.DPQ.rdt0; +import static com.oracle.truffle.r.library.stats.DPQ.rdt1; +import static com.oracle.truffle.r.library.stats.DPQ.rdtclog; +import static com.oracle.truffle.r.library.stats.DPQ.rdtqiv; +import static com.oracle.truffle.r.library.stats.DPQ.rlog1exp; +import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON; +import static com.oracle.truffle.r.library.stats.MathConstants.M_1_SQRT_2PI; +import static com.oracle.truffle.r.library.stats.MathConstants.M_2PI; +import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2; +import static com.oracle.truffle.r.library.stats.MathConstants.M_SQRT_32; +import static com.oracle.truffle.r.library.stats.RMath.fmax2; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1; import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; @@ -62,6 +59,13 @@ public abstract class GammaFunctions { } } + public static final class DGamma implements Function3_1 { + @Override + public double evaluate(double x, double shape, double scale, boolean giveLog) { + return dgamma(x, shape, scale, giveLog); + } + } + // The remainder of this file is derived from GNU R (mostly nmath): qgamma.c, nmath.h, lgamma.c, // gamma.c, stirlerr.c, lgammacor.c, pgamma.c, fmax2.c, dpois.c, bd0.c, dgamma.c, pnorm.c, // qnorm.c @@ -178,7 +182,7 @@ public abstract class GammaFunctions { /* allow to underflow below */ } else if (x < xbig) { tmp = 10 / x; - return chebyshevEval(tmp * tmp * 2 - 1, ALGMCS, nalgm) / x; + return RMath.chebyshevEval(tmp * tmp * 2 - 1, ALGMCS, nalgm) / x; } return 1 / (x * 12); } @@ -249,7 +253,7 @@ public abstract class GammaFunctions { } y = x - n; /* n = floor(x) ==> y in [ 0, 1 ) */ --n; - value = chebyshevEval(y * 2 - 1, GAMCS, ngam) + .9375; + value = RMath.chebyshevEval(y * 2 - 1, GAMCS, ngam) + .9375; if (n == 0) { return value; /* x = 1.dddd = 1+y */ } @@ -367,7 +371,7 @@ public abstract class GammaFunctions { } if (x <= 0 && x == (long) x) { /* Negative integer argument */ - RError.warning(RError.SHOW_CALLER2, RError.Message.VALUE_OUT_OF_RANGE, "lgamma"); + RError.warning(RError.SHOW_CALLER, RError.Message.VALUE_OUT_OF_RANGE, "lgamma"); return Double.POSITIVE_INFINITY; /* +Inf, since lgamma(x) = log|gamma(x)| */ } @@ -384,7 +388,7 @@ public abstract class GammaFunctions { */ if (y > gfn_sign_xmax) { - RError.warning(RError.SHOW_CALLER2, RError.Message.VALUE_OUT_OF_RANGE, "lgamma"); + RError.warning(RError.SHOW_CALLER, RError.Message.VALUE_OUT_OF_RANGE, "lgamma"); return Double.POSITIVE_INFINITY; } @@ -453,9 +457,10 @@ public abstract class GammaFunctions { return p + nu; } - if (rqp01check(p, logp)) { - // TODO ML_ERR_return_NAN - return Double.NaN; + try { + DPQ.rqp01check(p, logp); + } catch (EarlyReturn e) { + return e.result; } if (nu <= 0) { @@ -466,7 +471,7 @@ public abstract class GammaFunctions { alpha = 0.5 * nu; /* = [pq]gamma() shape */ c = alpha - 1; - if (nu < (-1.24) * (p1 = rdtlog(p, lowerTail, logp))) { /* for small chi-squared */ + if (nu < (-1.24) * (p1 = DPQ.rdtlog(p, lowerTail, logp))) { /* for small chi-squared */ /* * log(alpha) + g = log(alpha) + log(gamma(alpha)) = = log(alpha*gamma(alpha)) = * lgamma(alpha+1) suffers from catastrophic cancellation when alpha << 1 @@ -769,7 +774,7 @@ public abstract class GammaFunctions { /* Accurate calculation of log(1+x)-x, particularly for small x. */ private static double log1pmx(double x) { if (x > 1 || x < minLog1Value) { - return log1p(x) - x; + return RMath.log1p(x) - x; } else { /* * -.791 <= x <= 1 -- expand in [x/(2+x)]^2 =: y : log(1+x) - x = x/(2+x) * [ 2 * y * * S(y) - x], with --------------------------------------------- S(y) = 1/3 + y/5 @@ -831,7 +836,7 @@ public abstract class GammaFunctions { } /* lgamma1p */ /* If |x| > |k| * M_cutoff, then log[ exp(-x) * k^x ] =~= -x */ - private static final double M_cutoff = M_LN2 * Double.MAX_EXPONENT / DBLEPSILON; + private static final double M_cutoff = M_LN2 * Double.MAX_EXPONENT / DBL_EPSILON; /* * dpois_wrap (x_P_1, lambda, g_log) == dpois (x_P_1 - 1, lambda, g_log) := exp(-L) L^k / @@ -871,10 +876,10 @@ public abstract class GammaFunctions { c *= -x / n; term = c / (alph + n); sum += term; - } while (Math.abs(term) > DBLEPSILON * Math.abs(sum)); + } while (Math.abs(term) > DBL_EPSILON * Math.abs(sum)); if (lowerTail) { - double f1 = logp ? log1p(sum) : 1 + sum; + double f1 = logp ? RMath.log1p(sum) : 1 + sum; double f2; if (alph > 1) { f2 = dpoisRaw(alph, x, logp); @@ -888,10 +893,10 @@ public abstract class GammaFunctions { } else { double lf2 = alph * Math.log(x) - lgamma1p(alph); if (logp) { - return rlog1exp(log1p(sum) + lf2); + return rlog1exp(RMath.log1p(sum) + lf2); } else { double f1m1 = sum; - double f2m1 = expm1(lf2); + double f2m1 = RMath.expm1(lf2); return -(f1m1 + f2m1 + f1m1 * f2m1); } } @@ -906,7 +911,7 @@ public abstract class GammaFunctions { localY++; term *= x / localY; sum += term; - } while (term > sum * DBLEPSILON); + } while (term > sum * DBL_EPSILON); /* * sum = \sum_{n=1}^ oo x^n / (y*(y+1)*...*(y+n-1)) = \sum_{n=0}^ oo x^(n+1) / @@ -948,7 +953,7 @@ public abstract class GammaFunctions { f0 = y / d; /* Needed, e.g. for pgamma(10^c(100,295), shape= 1.1, log=TRUE): */ - if (Math.abs(y - 1) < Math.abs(d) * DBLEPSILON) { /* includes y < d = Inf */ + if (Math.abs(y - 1) < Math.abs(d) * DBL_EPSILON) { /* includes y < d = Inf */ return f0; } @@ -999,7 +1004,7 @@ public abstract class GammaFunctions { if (b2 != 0) { f = a2 / b2; /* convergence check: relative; "absolute" for very small f : */ - if (Math.abs(f - of) <= DBLEPSILON * fmax2(f0, Math.abs(f))) { + if (Math.abs(f - of) <= DBL_EPSILON * fmax2(f0, Math.abs(f))) { return f; } of = f; @@ -1015,7 +1020,7 @@ public abstract class GammaFunctions { double term = 1; double sum = 0; - while (localY >= 1 && term > sum * DBLEPSILON) { + while (localY >= 1 && term > sum * DBL_EPSILON) { term *= localY / lambda; sum += term; localY--; @@ -1076,7 +1081,7 @@ public abstract class GammaFunctions { term *= -i / x2; sum += term; i += 2; - } while (Math.abs(term) > DBLEPSILON * sum); + } while (Math.abs(term) > DBL_EPSILON * sum); return 1 / sum; } else { @@ -1154,7 +1159,7 @@ public abstract class GammaFunctions { if (logp) { double ndOverP = dpnorm(s2pt, !lowerTail, np); - return np + log1p(f * ndOverP); + return np + RMath.log1p(f * ndOverP); } else { double nd = dnorm(s2pt, 0., 1., logp); return np + f * nd; @@ -1190,7 +1195,7 @@ public abstract class GammaFunctions { double sum; double d = dpoisWrap(alph, x, logp); if (alph < 1) { - if (x * DBLEPSILON > 1 - alph) { + if (x * DBL_EPSILON > 1 - alph) { sum = rd1(logp); } else { double f = pdLowerCf(alph, x - (alph - 1)) * x / alph; @@ -1199,7 +1204,7 @@ public abstract class GammaFunctions { } } else { sum = pdLowerSeries(x, alph - 1); /* = (alph-1)/x + o((alph-1)/x) */ - sum = logp ? log1p(sum) : 1 + sum; + sum = logp ? RMath.log1p(sum) : 1 + sum; } if (!lowerTail) { res = logp ? sum + d : sum * d; @@ -1214,7 +1219,7 @@ public abstract class GammaFunctions { * We lose a fair amount of accuracy to underflow in the cases where the final result is * very close to DBL_MIN. In those cases, simply redo via log space. */ - if (!logp && res < Double.MIN_VALUE / DBLEPSILON) { + if (!logp && res < Double.MIN_VALUE / DBL_EPSILON) { /* with(.Machine, double.xmin / double.eps) #|-> 1.002084e-292 */ return Math.exp(pgammaRaw(x, alph, lowerTail, true)); } else { @@ -1246,7 +1251,7 @@ public abstract class GammaFunctions { // dpois // - private static double dpoisRaw(double x, double lambda, boolean giveLog) { + public static double dpoisRaw(double x, double lambda, boolean giveLog) { /* * x >= 0 ; integer for dpois(), but not e.g. for pgamma()! lambda >= 0 */ @@ -1306,7 +1311,7 @@ public abstract class GammaFunctions { // dnorm // - private static double dnorm(double x, double mu, double sigma, boolean giveLog) { + static double dnorm(double x, double mu, double sigma, boolean giveLog) { double localX = x; if (Double.isNaN(localX) || Double.isNaN(mu) || Double.isNaN(sigma)) { return localX + mu + sigma; @@ -1338,7 +1343,7 @@ public abstract class GammaFunctions { // dgamma // - private static double dgamma(double x, double shape, double scale, boolean giveLog) { + public static double dgamma(double x, double shape, double scale, boolean giveLog) { double pr; if (Double.isNaN(x) || Double.isNaN(shape) || Double.isNaN(scale)) { return x + shape + scale; @@ -1431,7 +1436,7 @@ public abstract class GammaFunctions { if (logp) { cum[0] = (-xsq * xsq * 0.5) + (-del * 0.5) + Math.log(temp); if ((lower && x > 0.) || (upper && x <= 0.)) { - ccum[0] = log1p(-Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp); + ccum[0] = RMath.log1p(-Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp); } } else { cum[0] = Math.exp(-xsq * xsq * 0.5) * Math.exp(-del * 0.5) * temp; @@ -1472,7 +1477,7 @@ public abstract class GammaFunctions { } /* Consider changing these : */ - eps = DBLEPSILON * 0.5; + eps = DBL_EPSILON * 0.5; /* i_tail in {0,1,2} =^= {lower, upper, both} */ lower = iTail != 1; diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java new file mode 100644 index 0000000000000000000000000000000000000000..2d9c81f9f15d5b506cc803b3adabdd34cf30ade5 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java @@ -0,0 +1,99 @@ +/* + * 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) 1998 Ross Ihaka + * Copyright (c) 1998--2008, The R Core Team + * Copyright (c) 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +/* + * 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) 2000--2014, The R Core Team + * Copyright (c) 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +/* + * Copyright (C) 1998 Ross Ihaka + * Copyright (C) 2000-12 The R Core Team + * Copyright (C) 2004--2005 The R Foundation + * Copyright (c) 2016, Oracle and/or its affiliates + */ +package com.oracle.truffle.r.library.stats; + +import static com.oracle.truffle.r.library.stats.MathConstants.forceint; + +import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_1; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function2_2; + +public class Geom { + public static final class QGeom implements Function2_2 { + @Override + public double evaluate(double p, double prob, boolean lowerTail, boolean logP) { + if (prob <= 0 || prob > 1) { + return RMath.mlError(); + } + + try { + DPQ.rqp01boundaries(p, 0, Double.POSITIVE_INFINITY, lowerTail, logP); + } catch (EarlyReturn e) { + return e.result; + } + + if (Double.isNaN(p) || Double.isNaN(prob)) { + return p + prob; + } + + if (prob == 1) { + return 0; + } + /* add a fuzz to ensure left continuity, but value must be >= 0 */ + return RMath.fmax2(0, Math.ceil(DPQ.rdtclog(p, lowerTail, logP) / RMath.log1p(-prob) - 1 - 1e-12)); + } + + } + + public static final class DGeom implements Function2_1 { + @Override + public double evaluate(double x, double p, boolean giveLog) { + if (Double.isNaN(x) || Double.isNaN(p)) { + return x + p; + } + if (p <= 0 || p > 1) { + return RMath.mlError(); + } + + try { + DPQ.nonintCheck(x, giveLog); + } catch (EarlyReturn e) { + return e.result; + } + + if (x < 0 || !Double.isFinite(x) || p == 0) { + return DPQ.rd0(giveLog); + } + /* prob = (1-p)^x, stable for small p */ + double prob = Dbinom.dbinomRaw(0., forceint(x), p, 1 - p, giveLog); + return ((giveLog) ? Math.log(p) + prob : p * prob); + } + } + + public static final class RGeom implements RandFunction1_Double { + @Override + public double evaluate(double p, RandomNumberProvider rand) { + if (!Double.isFinite(p) || p <= 0 || p > 1) { + return RMath.mlError(); + } + return RPois.rpois(rand.expRand() * ((1 - p) / p), rand); + } + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java index 6cc0de5a33d977f8dec7d56bf66456d975a15ee3..8f997c3f586187da864b6cb32346d7ea03826c01 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LBeta.java @@ -38,7 +38,7 @@ public final class LBeta { /* both arguments must be >= 0 */ if (p < 0) { - return StatsUtil.mlError(); + return RMath.mlError(); } else if (p == 0) { return Double.POSITIVE_INFINITY; } else if (!Double.isFinite(q)) { /* q == +Inf */ diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java new file mode 100644 index 0000000000000000000000000000000000000000..824a4acef8f241ac6d5d34f358f970ce727e15a7 --- /dev/null +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java @@ -0,0 +1,95 @@ +/* + * 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) 1998 Ross Ihaka + * Copyright (c) 2000--2014, The R Core Team + * Copyright (c) 2005, The R Foundation + * Copyright (c) 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.library.stats; + +import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_1; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2; + +public final class LogNormal { + private LogNormal() { + // only static members + } + + public static final class RLNorm implements RandFunction2_Double { + private final Rnorm rnorm = new Rnorm(); + + @Override + public double evaluate(double meanlog, double sdlog, RandomNumberProvider rand) { + if (Double.isNaN(meanlog) || !Double.isFinite(sdlog) || sdlog < 0.) { + return RMath.mlError(); + } + return Math.exp(rnorm.evaluate(meanlog, sdlog, rand)); + } + } + + public static final class DLNorm implements Function3_1 { + @Override + public double evaluate(double x, double meanlog, double sdlog, boolean giveLog) { + if (Double.isNaN(x) || Double.isNaN(meanlog) || Double.isNaN(sdlog)) { + return x + meanlog + sdlog; + } + if (sdlog <= 0) { + if (sdlog < 0) { + return RMath.mlError(); + } + // sdlog == 0 : + return (Math.log(x) == meanlog) ? Double.POSITIVE_INFINITY : DPQ.rd0(giveLog); + } + if (x <= 0) { + return DPQ.rd0(giveLog); + } + + double y = (Math.log(x) - meanlog) / sdlog; + return (giveLog ? -(MathConstants.M_LN_SQRT_2PI + 0.5 * y * y + Math.log(x * sdlog)) : MathConstants.M_1_SQRT_2PI * Math.exp(-0.5 * y * y) / (x * sdlog)); + /* M_1_SQRT_2PI = 1 / Math.sqrt(2 * pi) */ + } + } + + public static final class QLNorm implements Function3_2 { + private final Qnorm qnorm = new Qnorm(); + + @Override + public double evaluate(double p, double meanlog, double sdlog, boolean lowerTail, boolean logP) { + if (Double.isNaN(p) || Double.isNaN(meanlog) || Double.isNaN(sdlog)) { + return p + meanlog + sdlog; + } + try { + DPQ.rqp01boundaries(p, 0, Double.POSITIVE_INFINITY, lowerTail, logP); + } catch (EarlyReturn e) { + return e.result; + } + return Math.exp(qnorm.evaluate(p, meanlog, sdlog, lowerTail, logP)); + } + } + + public static final class PLNorm implements Function3_2 { + private final Pnorm pnorm = new Pnorm(); + + @Override + public double evaluate(double x, double meanlog, double sdlog, boolean lowerTail, boolean logP) { + if (Double.isNaN(x) || Double.isNaN(meanlog) || Double.isNaN(sdlog)) { + return x + meanlog + sdlog; + } + if (sdlog < 0) { + return RMath.mlError(); + } + if (x > 0) { + return pnorm.evaluate(Math.log(x), meanlog, sdlog, lowerTail, logP); + } + return DPQ.rdt0(lowerTail, logP); + } + } +} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java index 1fbefb2a995f10460e01aef039b2ad94135b163c..0885fbeecf503bb056f1c289b3c2096f5ef3e5a3 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java @@ -3,9 +3,10 @@ * Version 2. You may review the terms of this license at * http://www.gnu.org/licenses/gpl-2.0.html * - * Copyright (c) 1995-2012, The R Core Team - * Copyright (c) 2003, The R Foundation - * Copyright (c) 2016, 2016, Oracle and/or its affiliates + * Copyright (C) 1998 Ross Ihaka + * Copyright (c) 1998--2012, The R Core Team + * Copyright (c) 2004, The R Foundation + * Copyright (c) 2013, 2016, Oracle and/or its affiliates * * All rights reserved. */ @@ -55,7 +56,7 @@ public final class MathConstants { // 1/sqrt(2) public static final double M_SQRT1_2 = 0.707106781186547524400844362105; - /* R-Specific Constants */ + /* R-Specific Constants from dpq.h and Rmath.h and others */ // sqrt(3) public static final double M_SQRT_3 = 1.732050807568877293527446341506; // sqrt(32) @@ -77,6 +78,12 @@ public final class MathConstants { // log(sqrt(pi/2)) == log(pi/2)/2 public static final double M_LN_SQRT_PId2 = 0.225791352644727432363097614947; + public static final double DBL_MANT_DIG = 53; + + public static final int DBL_MAX_EXP = 1024; + + public static final int DBL_MIN_EXP = -1021; + public static final double DBL_EPSILON = Math.ulp(1.0); /** diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java index 4c950e6d35727e6fc3511907fc7f621500f399af..02c713c68abadf8fe6755b5a2ead937269cc88bd 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbeta.java @@ -12,14 +12,21 @@ package com.oracle.truffle.r.library.stats; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.library.stats.StatsFunctions.Function3_2; import com.oracle.truffle.r.library.stats.TOMS708.Bratio; -import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; // transcribed from pbeta.c -public abstract class Pbeta extends RExternalBuiltinNode.Arg5 { +public final class Pbeta implements Function3_2 { + + private final BranchProfile naProfile = BranchProfile.create(); + + @Override + public double evaluate(double x, double a, double b, boolean lowerTail, boolean logP) { + return pbeta(x, a, b, lowerTail, logP, naProfile); + } @TruffleBoundary private static double pbetaRaw(double x, double a, double b, boolean lowerTail, boolean logProb) { @@ -32,19 +39,19 @@ public abstract class Pbeta extends RExternalBuiltinNode.Arg5 { } if (a == 0 || a / b == 0) { // point mass 1 at 0 ==> P(X <= x) = 1, all x > 0 - return DPQ.dt1(logProb, lowerTail); + return DPQ.rdt1(lowerTail, logProb); } if (b == 0 || b / a == 0) { // point mass 1 at 1 ==> P(X <= x) = 0, all x < 1 - return DPQ.dt0(logProb, lowerTail); + return DPQ.rdt0(lowerTail, logProb); } // else, remaining case: a = b = Inf : point mass 1 at 1/2 if (x < 0.5) { - return DPQ.dt0(logProb, lowerTail); + return DPQ.rdt0(lowerTail, logProb); } // else, x >= 0.5 : - return DPQ.dt1(logProb, lowerTail); + return DPQ.rdt1(lowerTail, logProb); } // Now: 0 < a < Inf; 0 < b < Inf @@ -77,10 +84,10 @@ public abstract class Pbeta extends RExternalBuiltinNode.Arg5 { // allowing a==0 and b==0 <==> treat as one- or two-point mass if (x <= 0) { - return DPQ.dt0(logP, lowerTail); + return DPQ.rdt0(lowerTail, logP); } if (x >= 1) { - return DPQ.dt1(logP, lowerTail); + return DPQ.rdt1(lowerTail, logP); } return pbetaRaw(x, a, b, lowerTail, logP); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java index 2885a3c8b596d50c426db8664de8559088826846..70fcce282db80d30395effba2881a35c155aafcb 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pbinom.java @@ -13,7 +13,6 @@ package com.oracle.truffle.r.library.stats; import com.oracle.truffle.api.profiles.BranchProfile; -import com.oracle.truffle.r.runtime.RError; public final class Pbinom implements StatsFunctions.Function3_2 { @@ -34,8 +33,8 @@ public final class Pbinom implements StatsFunctions.Function3_2 { if (DPQ.nonint(size)) { nanProfile.enter(); - RError.warning(RError.SHOW_CALLER, RError.Message.NON_INTEGER_N, "n", size); - return Double.NaN; + DPQ.nointCheckWarning(size, "n"); + return DPQ.rd0(logP); } size = Math.round(size); /* PR#8560: n=0 is a valid value */ @@ -45,11 +44,11 @@ public final class Pbinom implements StatsFunctions.Function3_2 { } if (q < 0) { - return DPQ.dt0(logP, lowerTail); + return DPQ.rdt0(lowerTail, logP); } q = Math.floor(q + 1e-7); if (size <= q) { - return DPQ.dt1(logP, lowerTail); + return DPQ.rdt1(lowerTail, logP); } return Pbeta.pbeta(prob, q + 1, size - q, !lowerTail, logP, nanProfile); } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pf.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pf.java index 51cf4f7e06d1f2833ce943b59dc2296041260add..f595cf1cc339e26326e79c2d9ebe5d3984e182cf 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pf.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pf.java @@ -11,7 +11,8 @@ */ package com.oracle.truffle.r.library.stats; -import static com.oracle.truffle.r.library.stats.StatsUtil.*; +import static com.oracle.truffle.r.library.stats.DPQ.rdt0; +import static com.oracle.truffle.r.library.stats.DPQ.rdt1; import com.oracle.truffle.api.profiles.BranchProfile; @@ -45,7 +46,7 @@ public final class Pf implements StatsFunctions.Function3_2 { return rdt0(lowerTail, logP); } if (x == 1) { - return logP ? -M_LN2 : 0.5; + return logP ? -MathConstants.M_LN2 : 0.5; } if (x > 1) { return rdt1(lowerTail, logP); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnorm.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnorm.java index bae5a546448f141bb8a75e4f012792e19b7fe32b..2d73851c472337e07e46861bed2700d4ccb9a2d2 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnorm.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Pnorm.java @@ -41,11 +41,11 @@ public final class Pnorm implements StatsFunctions.Function3_2 { return Double.NaN; } /* sigma = 0 : */ - return (x < mu) ? DPQ.d0(logP) : DPQ.d1(logP); + return (x < mu) ? DPQ.rdt0(lowerTail, logP) : DPQ.rdt1(lowerTail, logP); } double p = (x - mu) / sigma; if (!Double.isFinite(p)) { - return (x < mu) ? DPQ.d0(logP) : DPQ.d1(logP); + return (x < mu) ? DPQ.rdt0(lowerTail, logP) : DPQ.rdt1(lowerTail, logP); } PnormBoth pnormBoth = new PnormBoth(p); @@ -204,11 +204,11 @@ public final class Pnorm implements StatsFunctions.Function3_2 { swapTail(x, lower); } else { /* large x such that probs are 0 or 1 */ if (x > 0) { - cum = DPQ.d1(logP); - ccum = DPQ.d0(logP); + cum = DPQ.rd1(logP); + ccum = DPQ.rd0(logP); } else { - cum = DPQ.d0(logP); - ccum = DPQ.d1(logP); + cum = DPQ.rd0(logP); + ccum = DPQ.rd1(logP); } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java index d3e23b0e73276ac48c384b17a182ec639278afcb..c3a43d3259eba623afcabfc64774ea901a893bbf 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java @@ -13,9 +13,9 @@ package com.oracle.truffle.r.library.stats; import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON; import static com.oracle.truffle.r.library.stats.MathConstants.forceint; -import static com.oracle.truffle.r.library.stats.StatsUtil.fmax2; -import static com.oracle.truffle.r.library.stats.StatsUtil.fmin2; -import static com.oracle.truffle.r.library.stats.StatsUtil.lfastchoose; +import static com.oracle.truffle.r.library.stats.RMath.fmax2; +import static com.oracle.truffle.r.library.stats.RMath.fmin2; +import static com.oracle.truffle.r.library.stats.RMath.lfastchoose; import com.oracle.truffle.r.library.stats.DPQ.EarlyReturn; @@ -34,7 +34,7 @@ public final class QHyper { return p + nr + nb + n; } if (!Double.isFinite(p) || !Double.isFinite(nr) || !Double.isFinite(nb) || !Double.isFinite(n)) { - return StatsUtil.mlError(); + return RMath.mlError(); } nr = forceint(nr); @@ -42,7 +42,7 @@ public final class QHyper { capN = nr + nb; n = forceint(n); if (nr < 0 || nb < 0 || n < 0 || n > capN) { - return StatsUtil.mlError(); + return RMath.mlError(); } /* @@ -54,7 +54,7 @@ public final class QHyper { xend = fmin2(n, nr); try { - DPQ.qP01Boundaries(p, xstart, xend, lowerTail, logP); + DPQ.rqp01boundaries(p, xstart, xend, lowerTail, logP); } catch (EarlyReturn ex) { return ex.result; } @@ -75,7 +75,7 @@ public final class QHyper { nb -= xb; if (!lowerTail || logP) { - p = DPQ.dtQIv(p, lowerTail, logP); + p = DPQ.rdtqiv(p, lowerTail, logP); } p *= 1 - 1000 * DBL_EPSILON; /* was 64, but failed on FreeBSD sometimes */ sum = smallN ? term : Math.exp(term); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qbinom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qbinom.java index 6bab507fdc59415010679410aaf6d0cdabfcb6c9..32e4f1df57df5f8f87b110d4cdef6dff2ae41402 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qbinom.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qbinom.java @@ -126,7 +126,7 @@ public final class Qbinom implements StatsFunctions.Function3_2 { * [cancellation for p ~= 1, etc]: */ if (!lowerTail || logProb) { - p = DPQ.dtQIv(p, lowerTail, logProb); /* need check again (cancellation!): */ + p = DPQ.rdtqiv(p, lowerTail, logProb); /* need check again (cancellation!): */ if (p == 0) { return 0; } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnorm.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnorm.java index 73dc865c65ef8d64be9ea18e57f867475d5e3a9d..42efb456233e808e5f0119665e833637675143b1 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnorm.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Qnorm.java @@ -31,7 +31,7 @@ public final class Qnorm implements StatsFunctions.Function3_2 { return p + mu + sigma; } try { - DPQ.qP01Boundaries(p, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, lowerTail, logP); + DPQ.rqp01boundaries(p, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, lowerTail, logP); } catch (EarlyReturn early) { return early.result; } @@ -44,7 +44,7 @@ public final class Qnorm implements StatsFunctions.Function3_2 { return mu; } - double p2 = DPQ.dtQIv(p, lowerTail, logP); /* real lower_tail prob. p */ + double p2 = DPQ.rdtqiv(p, lowerTail, logP); /* real lower_tail prob. p */ double q = p2 - 0.5; debugPrintf("qnorm(p=%10.7g, m=%g, s=%g, l.t.= %d, log= %d): q = %g\n", p, mu, sigma, lowerTail, logP, q); @@ -76,7 +76,7 @@ public final class Qnorm implements StatsFunctions.Function3_2 { /* r = min(p, 1-p) < 0.075 */ double r; if (q > 0) { - r = DPQ.dtCIv(p, lowerTail, logP); /* 1-p */ + r = DPQ.rdtciv(p, lowerTail, logP); /* 1-p */ } else { r = p2; /* = R_DT_Iv(p) ^= p */ } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java index 9ba8e64a12ac14fa2575067e12d4dc4b878b8eec..d62ab89e7e74c7d8962352525c10588f022e4c2d 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java @@ -12,10 +12,10 @@ */ package com.oracle.truffle.r.library.stats; +import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MAX_EXP; import static com.oracle.truffle.r.library.stats.MathConstants.M_LN2; -import static com.oracle.truffle.r.library.stats.StatsUtil.DBL_MAX_EXP; -import static com.oracle.truffle.r.library.stats.StatsUtil.fmax2; -import static com.oracle.truffle.r.library.stats.StatsUtil.fmin2; +import static com.oracle.truffle.r.library.stats.RMath.fmax2; +import static com.oracle.truffle.r.library.stats.RMath.fmin2; import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double; import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; @@ -27,7 +27,7 @@ public final class RBeta implements RandFunction2_Double { @Override public double evaluate(double aa, double bb, RandomNumberProvider rand) { if (Double.isNaN(aa) || Double.isNaN(bb) || aa < 0. || bb < 0.) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (!Double.isFinite(aa) && !Double.isFinite(bb)) { // a = b = Inf : all mass at 1/2 return 0.5; diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java deleted file mode 100644 index accf46e7c246e8914ab9075568984edbe7194507..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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) 1998 Ross Ihaka - * Copyright (c) 1998--2008, The R Core Team - * Copyright (c) 2016, 2016, Oracle and/or its affiliates - * - * All rights reserved. - */ -package com.oracle.truffle.r.library.stats; - -import static com.oracle.truffle.r.library.stats.MathConstants.M_PI; - -import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction2_Double; -import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; - -public final class RCauchy implements RandFunction2_Double { - @Override - public double evaluate(double location, double scale, RandomNumberProvider rand) { - if (Double.isNaN(location) || !Double.isFinite(scale) || scale < 0) { - return StatsUtil.mlError(); - } - if (scale == 0. || !Double.isFinite(location)) { - return location; - } else { - return location + scale * Math.tan(M_PI * rand.unifRand()); - } - } -} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java index 3b4c21ac102e287b7f0c21c0fdd01a6dd7eff473..67ba496753caf017b672e0003654a11f1eb4904d 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java @@ -17,7 +17,7 @@ import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberPr public final class RChisq implements RandFunction1_Double { public static double rchisq(double df, RandomNumberProvider rand) { if (!Double.isFinite(df) || df < 0.0) { - return StatsUtil.mlError(); + return RMath.mlError(); } return new RGamma().evaluate(df / 2.0, 2.0, rand); } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RExp.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RExp.java deleted file mode 100644 index 078f113dc20a407979ce7f75e2eb634ac663ea82..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RExp.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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) 1998 Ross Ihaka - * Copyright (c) 1998--2008, The R Core Team - * Copyright (c) 2016, 2016, Oracle and/or its affiliates - * - * All rights reserved. - */ -package com.oracle.truffle.r.library.stats; - -import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double; -import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; - -public final class RExp implements RandFunction1_Double { - @Override - public double evaluate(double scale, RandomNumberProvider rand) { - if (!Double.isFinite(scale) || scale <= 0.0) { - return scale == 0. ? 0. : StatsUtil.mlError(); - } - return scale * rand.expRand(); - } -} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java index 0e8581b5035469b7af5bc26d512b224447bf5dfd..eea9b5aea8027a913db009a0f96260fa22327fed 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGamma.java @@ -66,13 +66,13 @@ public class RGamma implements RandFunction2_Double { double retVal; if (Double.isNaN(a) || Double.isNaN(scale)) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (a <= 0.0 || scale <= 0.0) { if (scale == 0. || a == 0.) { return 0.; } - return StatsUtil.mlError(); + return RMath.mlError(); } if (!Double.isFinite(a) || !Double.isFinite(scale)) { return Double.POSITIVE_INFINITY; @@ -192,7 +192,7 @@ public class RGamma implements RandFunction2_Double { /* Step 11: hat acceptance (h) */ /* (if q not positive go to step 8) */ if (q > 0.0) { - w = StatsUtil.expm1(q); + w = RMath.expm1(q); /* ^^^^^ original code had approximation with rel.err < 2e-7 */ /* if t is rejected sample again at step 8 */ if (c * fabs(u) <= w * Math.exp(e - 0.5 * t * t)) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGeom.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGeom.java deleted file mode 100644 index 555d703a529b0e2021bf70e6ac116b93cdcd9467..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGeom.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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) 1998 Ross Ihaka - * Copyright (c) 1998--2008, The R Core Team - * Copyright (c) 2016, 2016, Oracle and/or its affiliates - * - * All rights reserved. - */ -package com.oracle.truffle.r.library.stats; - -import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandFunction1_Double; -import com.oracle.truffle.r.library.stats.RandGenerationFunctions.RandomNumberProvider; - -public final class RGeom implements RandFunction1_Double { - @Override - public double evaluate(double p, RandomNumberProvider rand) { - if (!Double.isFinite(p) || p <= 0 || p > 1) { - return StatsUtil.mlError(); - } - return RPois.rpois(rand.expRand() * ((1 - p) / p), rand); - } -} diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java index 32d9c6afee1cdf69754660e0d751057aefd13389..7dba16badee221972e01340629a88e35ffe0a1b1 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java @@ -100,7 +100,7 @@ public final class RHyper implements RandFunction3_Double { /* check parameter validity */ if (!Double.isFinite(nn1in) || !Double.isFinite(nn2in) || !Double.isFinite(kkin)) { - return StatsUtil.mlError(); + return RMath.mlError(); } nn1in = forceint(nn1in); @@ -108,7 +108,7 @@ public final class RHyper implements RandFunction3_Double { kkin = forceint(kkin); if (nn1in < 0 || nn2in < 0 || kkin < 0 || kkin > nn1in + nn2in) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (nn1in >= Integer.MAX_VALUE || nn2in >= Integer.MAX_VALUE || kkin >= Integer.MAX_VALUE) { /* @@ -230,7 +230,7 @@ public final class RHyper implements RandFunction3_Double { nUv++; if (nUv >= 10000) { RError.warning(RError.SHOW_CALLER, Message.GENERIC, String.format("rhyper() branch III: giving up after %d rejections", nUv)); - return StatsUtil.mlError(); + return RMath.mlError(); } if (u < p1) { /* rectangular region */ diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java index 007b812f841e234635bf6880d12728f879add390..961dafe00d10a34156926a5b54379f5510e45ebc 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java @@ -18,7 +18,7 @@ public final class RLogis implements RandFunction2_Double { @Override public double evaluate(double location, double scale, RandomNumberProvider rand) { if (Double.isNaN(location) || !Double.isFinite(scale)) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (scale == 0. || !Double.isFinite(location)) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsUtil.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java similarity index 66% rename from com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsUtil.java rename to com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java index 7a5348110e6dcddb2b05578952f40a334ac2f354..7b0d2a4c0dc0e158da8cfad77148cfff9c3028fe 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsUtil.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java @@ -16,12 +16,15 @@ import static com.oracle.truffle.r.library.stats.LBeta.lbeta; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.r.runtime.RRuntime; /** - * Auxiliary functions and constants from GNU R. These are originally found in the source files - * mentioned in the code. + * Encapsulates functions to be found in Rmath.h or in nmath directory in GnuR except for random + * distribution related functions, which usually have their own files. + * + * @see DPQ */ -public class StatsUtil { +public class RMath { /** * corresponds to macro {@code ML_ERR_return_NAN} in GnuR. @@ -30,97 +33,6 @@ public class StatsUtil { return Double.NaN; } - public static final double DBLEPSILON = 2.2204460492503131e-16; - - @TruffleBoundary - private static void fail(String message) { - throw new RuntimeException(message); - } - - // Constants and auxiliary functions originate from dpq.h and Rmath.h. - - public static final double M_LN2 = 0.693147180559945309417232121458; - - public static final double M_PI = 3.141592653589793238462643383280; - - public static final double M_2PI = 6.283185307179586476925286766559; - - public static final double M_1_SQRT_2PI = 0.398942280401432677939946059934; - - public static final double M_SQRT_32 = 5.656854249492380195206754896838; - - public static final double M_LOG10_2 = 0.301029995663981195213738894724; - - public static final double DBL_MANT_DIG = 53; - - public static final int DBL_MAX_EXP = 1024; - - public static final int DBL_MIN_EXP = -1021; - - public static double rdtlog(double p, boolean lowerTail, boolean logp) { - return lowerTail ? rdlog(p, logp) : rdlexp(p, logp); - } - - public static double rdlog(double p, boolean logp) { - return logp ? p : Math.log(p); - } - - public static double rdlexp(double x, boolean logp) { - return logp ? rlog1exp(x) : log1p(-x); - } - - public static double rlog1exp(double x) { - return x > -M_LN2 ? Math.log(-expm1(x)) : log1p(-Math.exp(x)); - } - - public static double rdtclog(double p, boolean lowerTail, boolean logp) { - return lowerTail ? rdlexp(p, logp) : rdlog(p, logp); - } - - public static double rdtqiv(double p, boolean lowerTail, boolean logp) { - return logp ? (lowerTail ? Math.exp(p) : -expm1(p)) : rdlval(p, lowerTail); - } - - public static double rdtciv(double p, boolean lowerTail, boolean logp) { - return logp ? (lowerTail ? -expm1(p) : Math.exp(p)) : rdcval(p, lowerTail); - } - - public static double rdlval(double p, boolean lowerTail) { - return lowerTail ? p : (0.5 - (p) + 0.5); - } - - public static double rdcval(double p, boolean lowerTail) { - return lowerTail ? (0.5 - p + 0.5) : p; - } - - public static double rd0(boolean logp) { - return logp ? Double.NEGATIVE_INFINITY : 0.; - } - - public static double rd1(boolean logp) { - return logp ? 0. : 1.; - } - - public static double rdt0(boolean lowerTail, boolean logp) { - return lowerTail ? rd0(logp) : rd1(logp); - } - - public static double rdt1(boolean lowerTail, boolean logp) { - return lowerTail ? rd1(logp) : rd0(logp); - } - - public static boolean rqp01check(double p, boolean logp) { - return (logp && p > 0) || (!logp && (p < 0 || p > 1)); - } - - public static double rdexp(double x, boolean logp) { - return logp ? x : Math.exp(x); - } - - public static double rdfexp(double f, double x, boolean giveLog) { - return giveLog ? -0.5 * Math.log(f) + x : Math.exp(x) / Math.sqrt(f); - } - public static double lfastchoose(double n, double k) { return -Math.log(n + 1.) - lbeta(n - k + 1., k + 1.); } @@ -132,6 +44,38 @@ public class StatsUtil { return ((y >= 0) ? TOMS708.fabs(x) : -TOMS708.fabs(x)); } + public static double fmod(double a, double b) { + double q = a / b; + if (b != 0) { + double tmp = a - Math.floor(q) * b; + if (RRuntime.isFinite(q) && Math.abs(q) > 1 / RRuntime.EPSILON) { + // TODO support warning here + throw new UnsupportedOperationException(); + } + return tmp - Math.floor(tmp / b) * b; + } else { + return Double.NaN; + } + } + + public static double tanpi(double x) { + if (Double.isNaN(x)) { + return x; + } + if (!Double.isFinite(x)) { + return mlError(); + } + + x = fmod(x, 1.); // tan(pi(x + k)) == tan(pi x) for all integer k + // map (-1,1) --> (-1/2, 1/2] : + if (x <= -0.5) { + x++; + } else if (x > 0.5) { + x--; + } + return (x == 0.) ? 0. : ((x == 0.5) ? Double.NaN : Math.tan(MathConstants.M_PI * x)); + } + // // GNUR from fmin2.c and fmax2 // @@ -158,7 +102,7 @@ public class StatsUtil { double y; double a = Math.abs(x); - if (a < DBLEPSILON) { + if (a < MathConstants.DBL_EPSILON) { return x; } if (a > 0.697) { @@ -173,7 +117,7 @@ public class StatsUtil { } /* Newton step for solving log(1 + y) = x for y : */ /* WARNING: does not work for y ~ -1: bug in 1.5.0 */ - y -= (1 + y) * (log1p(y) - x); + y -= (1 + y) * (RMath.log1p(y) - x); return y; } @@ -216,7 +160,7 @@ public class StatsUtil { /* * Improve on speed (only); again give result accurate to IEEE double precision: */ - if (Math.abs(x) < .5 * DBLEPSILON) { + if (Math.abs(x) < .5 * MathConstants.DBL_EPSILON) { return x; } @@ -263,4 +207,9 @@ public class StatsUtil { } return (b0 - b2) * 0.5; } + + @TruffleBoundary + private static void fail(String message) { + throw new RuntimeException(message); + } } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java index bac788a88f092635d86a66edb0f39d218c08f813..c095616fa14e46565ba778fbf3356a6f257ddc66 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.java @@ -20,7 +20,7 @@ public final class RNbinomMu implements RandFunction2_Double { @Override public double evaluate(double size, double mu, RandomNumberProvider rand) { if (!Double.isFinite(mu) || Double.isNaN(size) || size <= 0 || mu < 0) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (!Double.isFinite(size)) { size = Double.MAX_VALUE / 2.; diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java index da55025e1ad1d072053cd34ce4dab98b98260a8e..5e22bda3f5faf7e3fd655ed596183d3df56e6c07 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java @@ -22,7 +22,7 @@ public final class RNchisq implements RandFunction2_Double { @Override public double evaluate(double df, double lambda, RandomNumberProvider rand) { if (!Double.isFinite(df) || !Double.isFinite(lambda) || df < 0. || lambda < 0.) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (lambda == 0.) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java index ffcc999eace1ce6645b72423f3a7ee81f7cbb191..2638fa34de84ce1797d21b9e75acdb4798ab2ba5 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java @@ -80,7 +80,7 @@ public final class RPois implements RandFunction1_Double { boolean newBigMu = false; if (!Double.isFinite(mu) || mu < 0) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (mu <= 0.) { @@ -219,7 +219,7 @@ public final class RPois implements RandFunction1_Double { * sample t from the laplace 'hat' (if t <= -0.6744 then pk < fk for all mu >= 10.) */ u = 2 * rand.unifRand() - 1.; - t = 1.8 + StatsUtil.fsign(e, u); + t = 1.8 + RMath.fsign(e, u); } if (t > -0.6744 || gotoStepF) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java index 6e1fae2faf3211f4352d2dfae59e4a0a95c3c0d7..3686f96591d283d05747f0a49deb6dbb5b4c1b93 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java @@ -18,7 +18,7 @@ public final class RWeibull implements RandFunction2_Double { @Override public double evaluate(double shape, double scale, RandomNumberProvider rand) { if (!Double.isFinite(shape) || !Double.isFinite(scale) || shape <= 0. || scale <= 0.) { - return scale == 0. ? 0. : StatsUtil.mlError(); + return scale == 0. ? 0. : RMath.mlError(); } return scale * Math.pow(-Math.log(rand.unifRand()), 1.0 / shape); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java index e81ed75ed1f546923c664cb7c2d214909e9f0471..729f0d0833ed777de42e12fc552206ce7d12f58d 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java @@ -11,8 +11,8 @@ */ package com.oracle.truffle.r.library.stats; -import static com.oracle.truffle.r.library.stats.StatsUtil.rdtciv; -import static com.oracle.truffle.r.library.stats.StatsUtil.rdtqiv; +import static com.oracle.truffle.r.library.stats.DPQ.rdtciv; +import static com.oracle.truffle.r.library.stats.DPQ.rdtqiv; /* * Logic derived from GNU-R, see inline comments. diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java index 5d9426797321df6200e4dbc4a00eb9c9e551cb87..21cbb6d2bcf8609018f0fa730b73c6f59f0c8892 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java @@ -18,7 +18,7 @@ public final class Rf implements RandFunction2_Double { @Override public double evaluate(double n1, double n2, RandomNumberProvider rand) { if (Double.isNaN(n1) || Double.isNaN(n2) || n1 <= 0. || n2 <= 0.) { - return StatsUtil.mlError(); + return RMath.mlError(); } double v1; diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java index 24f2aed7d53b9d6f82635bec1bb53b441f4daa9b..1996274e87ea2c9c733dfdf4ad7ff06cb2eb0270 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java @@ -18,7 +18,7 @@ public final class Rnorm implements RandFunction2_Double { @Override public double evaluate(double mu, double sigma, RandomNumberProvider rand) { if (Double.isNaN(mu) || !Double.isFinite(sigma) || sigma < 0.) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (sigma == 0. || !Double.isFinite(mu)) { return mu; /* includes mu = +/- Inf with finite sigma */ diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java index 2ba6a6271371c136fe6a29a544797de96be0513f..51a266499e2e0af2b8c120ff15edcc26ae123310 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java @@ -20,7 +20,7 @@ public final class Rt implements RandFunction1_Double { @Override public double evaluate(double df, RandomNumberProvider rand) { if (Double.isNaN(df) || df <= 0.0) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (!Double.isFinite(df)) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java index 57a877536fa532404eb5899b115ba11e4c812043..5701011cf53f8e9f6ee09cae6e6294696b393de8 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Runif.java @@ -30,7 +30,7 @@ public final class Runif implements RandFunction2_Double { @Override public double evaluate(double min, double max, RandomNumberProvider rand) { if (!RRuntime.isFinite(min) || !RRuntime.isFinite(max) || max < min) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (min == max) { return min; diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java index 422d76cb6f7c006a3e94ad3779e76fc6d9cfb0b2..1b33cb4ddb8d4aeac8960ed8a69100feefeec1e2 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Signrank.java @@ -31,12 +31,12 @@ public final class Signrank { if (Double.isInfinite(n)) { // In GnuR these "results" seem to be generated due to the behaviour of R_forceint, // and the "(int) n" cast, which ends up casting +/-infinity to integer... - return n < 0 ? StatsUtil.mlError() : 0; + return n < 0 ? RMath.mlError() : 0; } n = forceint(n); if (n < 0) { - return StatsUtil.mlError(); + return RMath.mlError(); } if (n == 0) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java index 0f78a1f32eeb141cbe6370b9e7c4cde94bb49a3e..80d764515eef04f25d408662217f208623651a3e 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java @@ -43,6 +43,7 @@ public class SplineFunctions { } public abstract static class SplineEval extends RExternalBuiltinNode.Arg2 { + private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Specialization @TruffleBoundary @@ -90,7 +91,7 @@ public class SplineFunctions { /* * Periodic Spline --------------- The end conditions here match spline (and its derivatives) at * x[1] and x[n]. - * + * * Note: There is an explicit check that the user has supplied data with y[1] equal to y[n]. */ private static void periodicSpline(int n, double[] x, double[] y, double[] b, double[] c, double[] d) { @@ -207,7 +208,7 @@ public class SplineFunctions { /* * Natural Splines --------------- Here the end-conditions are determined by setting the second * derivative of the spline at the end-points to equal to zero. - * + * * There are n-2 unknowns (y[i]'' at x[2], ..., x[n-1]) and n-2 equations to determine them. * Either Choleski or Gaussian elimination could be used. */ diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java index ec49eda23c9b8ba99c2717648e5a5a3595d99f59..48c80044ba8a6b2d181a9f1e1b15564d5e66b66b 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java @@ -14,6 +14,7 @@ package com.oracle.truffle.r.library.stats; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; @@ -27,6 +28,7 @@ import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RDouble; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; @@ -36,6 +38,8 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; // inspired by arithmetic.c public final class StatsFunctions { + @CompilationFinal private static final RDouble DUMMY_VECTOR = RDouble.valueOf(1); + private StatsFunctions() { // private } @@ -53,6 +57,24 @@ public final class StatsFunctions { double evaluate(double a, double b, double c, boolean x); } + public interface Function2_1 extends Function3_2 { + @Override + default double evaluate(double a, double b, double c, boolean x, boolean y) { + return evaluate(a, b, x); + } + + double evaluate(double a, double b, boolean x); + } + + public interface Function2_2 extends Function3_2 { + @Override + default double evaluate(double a, double b, double c, boolean x, boolean y) { + return evaluate(a, b, x, y); + } + + double evaluate(double a, double b, boolean x, boolean y); + } + static final class StatFunctionProfiles { final BranchProfile nan = BranchProfile.create(); final NACheck aCheck = NACheck.create(); @@ -86,6 +108,7 @@ public final class StatsFunctions { profiles.aCheck.enable(a); profiles.bCheck.enable(b); profiles.cCheck.enable(c); + profiles.loopConditionProfile.profileCounted(length); for (int i = 0; profiles.loopConditionProfile.inject(i < length); i++) { double aValue = a.getDataAt(i % aLength); double bValue = b.getDataAt(i % bLength); @@ -150,7 +173,7 @@ public final class StatsFunctions { } public abstract static class Function3_1Node extends RExternalBuiltinNode.Arg4 { - private final Function3_2 function; + private final Function3_1 function; public Function3_1Node(Function3_1 function) { this.function = function; @@ -172,6 +195,51 @@ public final class StatsFunctions { } } + public abstract static class Function2_1Node extends RExternalBuiltinNode.Arg3 { + private final Function2_1 function; + + public Function2_1Node(Function2_1 function) { + this.function = function; + } + + @Override + protected void createCasts(CastBuilder casts) { + casts.arg(0).asDoubleVector(); + casts.arg(1).asDoubleVector(); + casts.arg(2).asLogicalVector().findFirst().map(toBoolean()); + } + + @Specialization + protected RAbstractDoubleVector evaluate(RAbstractDoubleVector a, RAbstractDoubleVector b, boolean x, + @Cached("create()") StatFunctionProfiles profiles, + @Cached("create()") UnaryCopyAttributesNode copyAttributesNode) { + return evaluate3(this, function, a, b, DUMMY_VECTOR, x, false /* dummy */, profiles, copyAttributesNode); + } + } + + public abstract static class Function2_2Node extends RExternalBuiltinNode.Arg4 { + private final Function2_2 function; + + public Function2_2Node(Function2_2 function) { + this.function = function; + } + + @Override + protected void createCasts(CastBuilder casts) { + casts.arg(0).asDoubleVector(); + casts.arg(1).asDoubleVector(); + casts.arg(2).asLogicalVector().findFirst().map(toBoolean()); + casts.arg(3).asLogicalVector().findFirst().map(toBoolean()); + } + + @Specialization + protected RAbstractDoubleVector evaluate(RAbstractDoubleVector a, RAbstractDoubleVector b, boolean x, boolean y, + @Cached("create()") StatFunctionProfiles profiles, + @Cached("create()") UnaryCopyAttributesNode copyAttributesNode) { + return evaluate3(this, function, a, b, DUMMY_VECTOR, x, y, profiles, copyAttributesNode); + } + } + public abstract static class ApproxTest extends RExternalBuiltinNode.Arg4 { @Override protected void createCasts(CastBuilder casts) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java index a61e44b42201c5c5af425fa83c95fd84718d8e8f..65056493bd7f7358f33beff9b9ef16afa8141c67 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java @@ -177,8 +177,8 @@ public class TOMS708 { eps = RRuntime.EPSILON; /* == DBL_EPSILON (in R, Rmath) */ /* ----------------------------------------------------------------------- */ - w = DPQ.d0(logP); - w1 = DPQ.d0(logP); + w = DPQ.rd0(logP); + w1 = DPQ.rd0(logP); if (a < 0.0 || b < 0.0) { return result(w, w1, 1); @@ -206,8 +206,8 @@ public class TOMS708 { return result(w, w1, 6); } // else: - w = DPQ.d0(logP); - w1 = DPQ.d1(logP); + w = DPQ.rd0(logP); + w1 = DPQ.rd1(logP); return result(w, w1, 0); } if (y == 0.0) { @@ -215,20 +215,20 @@ public class TOMS708 { return result(w, w1, 7); } // else: - w = DPQ.d1(logP); - w1 = DPQ.d0(logP); + w = DPQ.rd1(logP); + w1 = DPQ.rd0(logP); return result(w, w1, 0); } if (a == 0.0) { // else: - w = DPQ.d1(logP); - w1 = DPQ.d0(logP); + w = DPQ.rd1(logP); + w1 = DPQ.rd0(logP); return result(w, w1, 0); } if (b == 0.0) { - w = DPQ.d0(logP); - w1 = DPQ.d1(logP); + w = DPQ.rd0(logP); + w1 = DPQ.rd1(logP); return result(w, w1, 0); } @@ -762,7 +762,7 @@ public class TOMS708 { */ if (x == 0.) { - return DPQ.d0(logP); + return DPQ.rd0(logP); } /* ----------------------------------------------------------------------- */ /* compute the factor x^a/(a*Beta(a,b)) */ @@ -850,7 +850,7 @@ public class TOMS708 { } } debugPrintf(" bpser(a=%f, b=%f, x=%f, log=%b): prelim.ans = %.14f;\n", a, b, x, logP, ans); - if (ans == DPQ.d0(logP) || (!logP && a <= eps * 0.1)) { + if (ans == DPQ.rd0(logP) || (!logP && a <= eps * 0.1)) { return ans; } @@ -1059,7 +1059,7 @@ public class TOMS708 { /* R has M_1_SQRT_2PI , and M_LN_SQRT_2PI = ln(sqrt(2*pi)) = 0.918938.. */ if (x == 0.0 || y == 0.0) { - return DPQ.d0(logP); + return DPQ.rd0(logP); } double a0 = min(a, b); if (a0 < 8.0) { @@ -1081,7 +1081,7 @@ public class TOMS708 { double z = a * lnx + b * lny; if (a0 >= 1.) { z -= betaln(a, b); - return DPQ.dExp(z, logP); + return DPQ.rdexp(z, logP); } /* ----------------------------------------------------------------------- */ @@ -1098,7 +1098,7 @@ public class TOMS708 { if (b0 <= 1.0) { /* algorithm for max(a,b) = b0 <= 1 */ - double eZ = DPQ.dExp(z, logP); + double eZ = DPQ.rdexp(z, logP); if (!logP && eZ == 0.0) { /* exp() underflow */ diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java index e793668a8a24f91d57eb57e120592cb04b223961..d1ca9be10dc5ac29f642f8960f8e0c504341cff1 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/tools/C_ParseRd.java @@ -37,8 +37,10 @@ import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; +import com.oracle.truffle.r.runtime.ffi.ToolsRFFI; public abstract class C_ParseRd extends RExternalBuiltinNode.Arg9 { + @Child ToolsRFFI.ToolsRFFINode toolsRFFINode = RFFIFactory.getRFFI().getToolsRFFI().createToolsRFFINode(); @Override protected void createCasts(CastBuilder casts) { @@ -64,7 +66,7 @@ public abstract class C_ParseRd extends RExternalBuiltinNode.Arg9 { try (RConnection openConn = RConnection.fromIndex(con).forceOpen("r")) { // @formatter:off - return RFFIFactory.getRFFI().getToolsRFFI().parseRd(openConn, srcfile, + return toolsRFFINode.parseRd(openConn, srcfile, RDataFactory.createLogicalVectorFromScalar(verboseL), RDataFactory.createLogicalVectorFromScalar(fragmentL), RDataFactory.createStringVectorFromScalar(basename.getDataAt(0)), diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java index e856fd478387c79b96ea48c676b782656aa248d3..49204b765ddbc5dee540d31c69888ec6a8c857f2 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/utils/TypeConvert.java @@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.TreeSet; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -37,6 +38,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; public abstract class TypeConvert extends RExternalBuiltinNode.Arg5 { + @Child private SetFixedAttributeNode setLevelsAttrNode = SetFixedAttributeNode.create(RRuntime.LEVELS_ATTR_KEY); + private static boolean isNA(String s, RAbstractStringVector naStrings) { // naStrings are in addition to NA_character_ if (RRuntime.isNA(s)) { @@ -178,7 +181,7 @@ public abstract class TypeConvert extends RExternalBuiltinNode.Arg5 { } } RIntVector res = RDataFactory.createIntVector(data, complete); - res.setAttr(RRuntime.LEVELS_ATTR_KEY, RDataFactory.createStringVector(levelsArray, RDataFactory.COMPLETE_VECTOR)); + setLevelsAttrNode.execute(res, RDataFactory.createStringVector(levelsArray, RDataFactory.COMPLETE_VECTOR)); return RVector.setVectorClassAttr(res, RDataFactory.createStringVector("factor")); } } diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Parse.c b/com.oracle.truffle.r.native/fficall/src/jni/Parse.c index cc55518f197af736df1fedfb4780aea80643c0c4..233a58dbc129066a73b9a1cb364bc7cffde33b1a 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Parse.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Parse.c @@ -30,15 +30,15 @@ static jfieldID parseExprFieldID; void init_parse(JNIEnv *env) { - parseMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_ParseVector", "(Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;", 1); - parseResultClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper$ParseResult"); + parseMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ParseVector", "(Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;", 0); + parseResultClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/ParseResult"); parseStatusFieldID = checkGetFieldID(env, parseResultClass, "parseStatus", "I", 0); parseExprFieldID = checkGetFieldID(env, parseResultClass, "expr", "Ljava/lang/Object;", 0); } SEXP R_ParseVector(SEXP text, int n, ParseStatus *z, SEXP srcfile) { JNIEnv *env = getEnv(); - jobject result = (*env)->CallStaticObjectMethod(env, CallRFFIHelperClass, parseMethodID, text, n, srcfile); + jobject result = (*env)->CallObjectMethod(env, UpCallsRFFIObject, parseMethodID, text, n, srcfile); *z = (*env)->GetIntField(env, result, parseStatusFieldID); return (*env)->GetObjectField(env, result, parseExprFieldID); } diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Random.c b/com.oracle.truffle.r.native/fficall/src/jni/Random.c index 70341f309a7db4277f773e630c336e597bbfa1e7..4c958521f14747b05fe32b15575b49b1026a53bb 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Random.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Random.c @@ -27,24 +27,24 @@ static jmethodID PutRNGstate_MethodID; static jmethodID UnifRand_MethodID; void init_random(JNIEnv *env) { - GetRNGstate_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "getRNGstate", "()V", 1); - PutRNGstate_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "putRNGstate", "()V", 1); - UnifRand_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "unifRand", "()D", 1); + GetRNGstate_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "GetRNGstate", "()V", 0); + PutRNGstate_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "PutRNGstate", "()V", 0); + UnifRand_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "unif_rand", "()D", 0); } void GetRNGstate() { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, GetRNGstate_MethodID); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, GetRNGstate_MethodID); } void PutRNGstate() { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, PutRNGstate_MethodID); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, PutRNGstate_MethodID); } double unif_rand() { JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticDoubleMethod(thisenv, CallRFFIHelperClass, UnifRand_MethodID); + return (*thisenv)->CallDoubleMethod(thisenv, UpCallsRFFIObject, UnifRand_MethodID); } double norm_rand() { diff --git a/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c b/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c index f7cb4401f5891fd9cfbcf9802c9b52f91c3dc10c..11bfb92d75d0e34e4117a7ad926a9ec098ba92c4 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rembedded.c @@ -178,8 +178,8 @@ int Rf_initialize_R(int argc, char *argv[]) { char *R_HomeDir(void) { JNIEnv *jniEnv = getEnv(); - jmethodID R_HomeDirMethodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_HomeDir", "()Ljava/lang/String;", 1); - jstring homeDir = (*jniEnv)->CallStaticObjectMethod(jniEnv, CallRFFIHelperClass, R_HomeDirMethodID); + jmethodID R_HomeDirMethodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_HomeDir", "()Ljava/lang/String;", 0); + jstring homeDir = (*jniEnv)->CallObjectMethod(jniEnv, UpCallsRFFIObject, R_HomeDirMethodID); const char *homeDirChars = stringToChars(jniEnv, homeDir); return (char *)homeDirChars; } @@ -308,8 +308,8 @@ void uR_Busy(int x) { void uR_CleanUp(SA_TYPE x, int y, int z) { JNIEnv *jniEnv = getEnv(); - jmethodID methodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_CleanUp", "(III)V", 1); - (*jniEnv)->CallStaticVoidMethod(jniEnv, CallRFFIHelperClass, methodID, x, y, z); + jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_CleanUp", "(III)V", 1); + (*jniEnv)->CallStaticVoidMethod(jniEnv, UpCallsRFFIClass, methodID, x, y, z); } int uR_ShowFiles(int a, const char **b, const char **c, @@ -599,63 +599,63 @@ static char **update_environ_with_java_home(void) { CTXT R_getGlobalFunctionContext() { JNIEnv *jniEnv = getEnv(); - jmethodID methodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_getGlobalFunctionContext", "()Ljava/lang/Object;", 1); - CTXT result = (*jniEnv)->CallStaticObjectMethod(jniEnv, CallRFFIHelperClass, methodID); + jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_getGlobalFunctionContext", "()Ljava/lang/Object;", 0); + CTXT result = (*jniEnv)->CallObjectMethod(jniEnv, UpCallsRFFIObject, methodID); SEXP new_result = checkRef(jniEnv, result); return new_result == R_NilValue ? NULL : addGlobalRef(jniEnv, result, 0); } CTXT R_getParentFunctionContext(CTXT c) { JNIEnv *jniEnv = getEnv(); - jmethodID methodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_getParentFunctionContext", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - CTXT result = (*jniEnv)->CallStaticObjectMethod(jniEnv, CallRFFIHelperClass, methodID, c); + jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_getParentFunctionContext", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + CTXT result = (*jniEnv)->CallObjectMethod(jniEnv, UpCallsRFFIObject, methodID, c); SEXP new_result = checkRef(jniEnv, result); return new_result == R_NilValue ? NULL : addGlobalRef(jniEnv, result, 0); } SEXP R_getContextEnv(CTXT context) { JNIEnv *jniEnv = getEnv(); - jmethodID methodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_getContextEnv", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - SEXP result = (*jniEnv)->CallStaticObjectMethod(jniEnv, CallRFFIHelperClass, methodID, context); + jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_getContextEnv", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + SEXP result = (*jniEnv)->CallObjectMethod(jniEnv, UpCallsRFFIObject, methodID, context); return checkRef(jniEnv, result); } SEXP R_getContextFun(CTXT context) { JNIEnv *jniEnv = getEnv(); - jmethodID methodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_getContextFun", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - SEXP result = (*jniEnv)->CallStaticObjectMethod(jniEnv, CallRFFIHelperClass, methodID, context); + jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_getContextFun", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + SEXP result = (*jniEnv)->CallObjectMethod(jniEnv, UpCallsRFFIObject, methodID, context); return checkRef(jniEnv, result); } SEXP R_getContextCall(CTXT context) { JNIEnv *jniEnv = getEnv(); - jmethodID methodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_getContextCall", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - SEXP result = (*jniEnv)->CallStaticObjectMethod(jniEnv, CallRFFIHelperClass, methodID, context); + jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_getContextCall", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + SEXP result = (*jniEnv)->CallObjectMethod(jniEnv, UpCallsRFFIObject, methodID, context); return checkRef(jniEnv, result); } SEXP R_getContextSrcRef(CTXT context) { JNIEnv *jniEnv = getEnv(); - jmethodID methodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_getContextSrcRef", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - SEXP result = (*jniEnv)->CallStaticObjectMethod(jniEnv, CallRFFIHelperClass, methodID, context); + jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_getContextSrcRef", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + SEXP result = (*jniEnv)->CallObjectMethod(jniEnv, UpCallsRFFIObject, methodID, context); result = checkRef(jniEnv, result); return result == R_NilValue ? NULL : result; } int R_insideBrowser() { JNIEnv *jniEnv = getEnv(); - jmethodID methodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_insideBrowser", "()I", 1); - return (*jniEnv)->CallStaticIntMethod(jniEnv, CallRFFIHelperClass, methodID); + jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_insideBrowser", "()I", 0); + return (*jniEnv)->CallStaticIntMethod(jniEnv, UpCallsRFFIClass, methodID); } int R_isGlobal(CTXT context) { JNIEnv *jniEnv = getEnv(); - jmethodID methodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_isGlobal", "(Ljava/lang/Object;)I", 1); - return (*jniEnv)->CallStaticIntMethod(jniEnv, CallRFFIHelperClass, methodID, context); + jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_isGlobal", "(Ljava/lang/Object;)I", 0); + return (*jniEnv)->CallStaticIntMethod(jniEnv, UpCallsRFFIClass, methodID, context); } int R_isEqual(void* x, void* y) { JNIEnv *jniEnv = getEnv(); - jmethodID methodID = checkGetMethodID(jniEnv, CallRFFIHelperClass, "R_isEqual", "(Ljava/lang/Object;Ljava/lang/Object;)I", 1); - return (*jniEnv)->CallStaticIntMethod(jniEnv, CallRFFIHelperClass, methodID, x, y); + jmethodID methodID = checkGetMethodID(jniEnv, UpCallsRFFIClass, "R_isEqual", "(Ljava/lang/Object;Ljava/lang/Object;)I", 0); + return (*jniEnv)->CallStaticIntMethod(jniEnv, UpCallsRFFIClass, methodID, x, y); } 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 3972ae97f451a894d5e79a20b95c3e47276496b6..540621ad1600f0694ab8c21c598f3fbe7efd6dcf 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/Rinternals.c @@ -30,7 +30,7 @@ // 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 +// N.B. ALL functions go via UpCallsRFFI to provide a single point of re-entry static jmethodID Rf_ScalarIntegerMethodID; static jmethodID Rf_ScalarDoubleMethodID; @@ -102,7 +102,7 @@ static jmethodID TYPEOF_MethodID; static jmethodID OBJECT_MethodID; static jmethodID DUPLICATE_ATTRIB_MethodID; static jmethodID isS4ObjectMethodID; -static jmethodID logObject_MethodID; +static jmethodID logNotCharSXPWrapperMethodID; static jmethodID R_tryEvalMethodID; static jmethodID RDEBUGMethodID; static jmethodID SET_RDEBUGMethodID; @@ -113,7 +113,7 @@ static jmethodID PRVALUEMethodID; static jmethodID R_lsInternal3MethodID; static jmethodID R_do_MAKE_CLASS_MethodID; -static jmethodID resetAndGetHandlerStacksMethodID; +static jmethodID R_ToplevelExecMethodID; static jmethodID restoreHandlerStacksMethodID; static jmethodID R_MakeExternalPtrMethodID; @@ -136,107 +136,107 @@ static jfieldID CharSXPWrapperContentsFieldID; jmethodID setCompleteMethodID; void init_internals(JNIEnv *env) { - Rf_ScalarIntegerMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarInteger", "(I)Lcom/oracle/truffle/r/runtime/data/RIntVector;", 1); - Rf_ScalarDoubleMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarDouble", "(D)Lcom/oracle/truffle/r/runtime/data/RDoubleVector;", 1); - Rf_ScalarStringMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarString", "(Ljava/lang/Object;)Lcom/oracle/truffle/r/runtime/data/RStringVector;", 1); - Rf_ScalarLogicalMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ScalarLogical", "(I)Lcom/oracle/truffle/r/runtime/data/RLogicalVector;", 1); - Rf_consMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_cons", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); - Rf_evalMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_eval", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); - Rf_findfunMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_findfun", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); - Rf_defineVarMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_defineVar", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 1); - Rf_findVarMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_findVar", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); - Rf_findVarInFrameMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_findVarInFrame", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); - Rf_findVarInFrame3MethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_findVarInFrame3", "(Ljava/lang/Object;Ljava/lang/Object;I)Ljava/lang/Object;", 1); - Rf_getAttribMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_getAttrib", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); - 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); - 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;I)Ljava/lang/Object;", 1); - Rf_anyDuplicatedMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_anyDuplicated", "(Ljava/lang/Object;I)I", 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); - R_FindNamespaceMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_FindNamespace", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - R_BindingIsLockedID = checkGetMethodID(env, CallRFFIHelperClass, "R_BindingIsLocked", "(Ljava/lang/Object;Ljava/lang/Object;)I", 1); - Rf_GetOption1MethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_GetOption1", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - Rf_gsetVarMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_gsetVar", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 1); - Rf_inheritsMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_inherits", "(Ljava/lang/Object;Ljava/lang/String;)I", 1); - Rf_lengthgetsMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_lengthgets", "(Ljava/lang/Object;I)Ljava/lang/Object;", 1); -// Rf_rPsortMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_rPsort", "(Lcom/oracle/truffle/r/runtime/data/RDoubleVector;II)", 1); -// Rf_iPsortMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_iPsort", "(Lcom/oracle/truffle/r/runtime/data/RIntVector;II)", 1); - CADR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "CADR", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - CADDR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "CADDR", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - TAG_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "TAG", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - PRINTNAME_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "PRINTNAME", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - CAR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "CAR", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - CDR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "CDR", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - CDDR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "CDDR", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - SET_TAG_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SET_TAG", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); - SETCAR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SETCAR", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); - SETCDR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SETCDR", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); - SETCADR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SETCADR", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 1); - SYMVALUE_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SYMVALUE", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - SET_SYMVALUE_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SET_SYMVALUE", "(Ljava/lang/Object;Ljava/lang/Object;)V", 1); - SET_STRING_ELT_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SET_STRING_ELT", "(Ljava/lang/Object;ILjava/lang/Object;)V", 1); - SET_VECTOR_ELT_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SET_VECTOR_ELT", "(Ljava/lang/Object;ILjava/lang/Object;)V", 1); - RAW_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "RAW", "(Ljava/lang/Object;)[B", 1); - REAL_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "REAL", "(Ljava/lang/Object;)[D", 1); - LOGICAL_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "LOGICAL", "(Ljava/lang/Object;)[B", 1); - INTEGER_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "INTEGER", "(Ljava/lang/Object;)[I", 1); - STRING_ELT_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "STRING_ELT", "(Ljava/lang/Object;I)Ljava/lang/Object;", 1); - VECTOR_ELT_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "VECTOR_ELT", "(Ljava/lang/Object;I)Ljava/lang/Object;", 1); - LENGTH_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "LENGTH", "(Ljava/lang/Object;)I", 1); - Rf_asIntegerMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_asInteger", "(Ljava/lang/Object;)I", 1); -// Rf_asRealMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_asReal", "(Ljava/lang/Object;)D", 1); - Rf_asCharMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_asChar", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - Rf_mkCharLenCEMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_mkCharLenCE", "([BI)Ljava/lang/Object;", 1); - Rf_asLogicalMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_asLogical", "(Ljava/lang/Object;)I", 1); - Rf_PairToVectorListMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_PairToVectorList", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - NAMED_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "NAMED", "(Ljava/lang/Object;)I", 1); - SET_TYPEOF_FASTR_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "SET_TYPEOF_FASTR", "(Ljava/lang/Object;I)Ljava/lang/Object;", 1); - TYPEOF_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "TYPEOF", "(Ljava/lang/Object;)I", 1); - OBJECT_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "OBJECT", "(Ljava/lang/Object;)I", 1); - DUPLICATE_ATTRIB_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "DUPLICATE_ATTRIB", "(Ljava/lang/Object;Ljava/lang/Object;)V", 1); - isS4ObjectMethodID = checkGetMethodID(env, CallRFFIHelperClass, "isS4Object", "(Ljava/lang/Object;)I", 1); - logObject_MethodID = checkGetMethodID(env, CallRFFIHelperClass, "logObject", "(Ljava/lang/Object;)V", 1); - R_tryEvalMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_tryEval", "(Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object;", 1); - RDEBUGMethodID = checkGetMethodID(env, CallRFFIHelperClass, "RDEBUG", "(Ljava/lang/Object;)I", 1); - SET_RDEBUGMethodID = checkGetMethodID(env, CallRFFIHelperClass, "SET_RDEBUG", "(Ljava/lang/Object;I)V", 1); - RSTEPMethodID = checkGetMethodID(env, CallRFFIHelperClass, "RSTEP", "(Ljava/lang/Object;)I", 1); - SET_RSTEPMethodID = checkGetMethodID(env, CallRFFIHelperClass, "SET_RSTEP", "(Ljava/lang/Object;I)V", 1); - ENCLOSMethodID = checkGetMethodID(env, CallRFFIHelperClass, "ENCLOS", "(Ljava/lang/Object;)Ljava/lang/Object;", 1); - 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); - - 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"); + Rf_ScalarIntegerMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_ScalarInteger", "(I)Lcom/oracle/truffle/r/runtime/data/RIntVector;", 0); + Rf_ScalarDoubleMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_ScalarDouble", "(D)Lcom/oracle/truffle/r/runtime/data/RDoubleVector;", 0); + Rf_ScalarStringMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_ScalarString", "(Ljava/lang/Object;)Lcom/oracle/truffle/r/runtime/data/RStringVector;", 0); + Rf_ScalarLogicalMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_ScalarLogical", "(I)Lcom/oracle/truffle/r/runtime/data/RLogicalVector;", 0); + Rf_consMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_cons", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + Rf_evalMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_eval", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + Rf_findfunMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_findfun", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + Rf_defineVarMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_defineVar", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 0); + Rf_findVarMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_findVar", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + Rf_findVarInFrameMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_findVarInFrame", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + Rf_findVarInFrame3MethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_findVarInFrame3", "(Ljava/lang/Object;Ljava/lang/Object;I)Ljava/lang/Object;", 0); + Rf_getAttribMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_getAttrib", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + Rf_setAttribMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_setAttrib", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 0); + Rf_isStringMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_isString", "(Ljava/lang/Object;)I", 0); + Rf_isNullMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_isNull", "(Ljava/lang/Object;)I", 0); + Rf_installMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_install", "(Ljava/lang/String;)Ljava/lang/Object;", 0); + Rf_warningMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_warning", "(Ljava/lang/String;)V", 0); + Rf_warningcallMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_warningcall", "(Ljava/lang/Object;Ljava/lang/String;)V", 0); + Rf_errorMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_error", "(Ljava/lang/String;)V", 0); + Rf_allocateVectorMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_allocateVector", "(II)Ljava/lang/Object;", 0); + Rf_allocateMatrixMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_allocateMatrix", "(III)Ljava/lang/Object;", 0); + Rf_allocateArrayMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_allocateArray", "(ILjava/lang/Object;)Ljava/lang/Object;", 0); + Rf_duplicateMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_duplicate", "(Ljava/lang/Object;I)Ljava/lang/Object;", 0); + Rf_anyDuplicatedMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_anyDuplicated", "(Ljava/lang/Object;I)I", 0); + R_NewHashedEnvMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_NewHashedEnv", "(Lcom/oracle/truffle/r/runtime/env/REnvironment;Ljava/lang/String;ZI)Lcom/oracle/truffle/r/runtime/env/REnvironment;", 0); + Rf_classgetsMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_classgets", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + RprintfMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rprintf", "(Ljava/lang/String;)V", 0); + R_do_MAKE_CLASS_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_do_MAKE_CLASS", "(Ljava/lang/String;)Ljava/lang/Object;", 0); + R_FindNamespaceMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_FindNamespace", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + R_BindingIsLockedID = checkGetMethodID(env, UpCallsRFFIClass, "R_BindingIsLocked", "(Ljava/lang/Object;Ljava/lang/Object;)I", 0); + Rf_GetOption1MethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_GetOption1", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + Rf_gsetVarMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_gsetVar", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)V", 0); + Rf_inheritsMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_inherits", "(Ljava/lang/Object;Ljava/lang/String;)I", 0); + Rf_lengthgetsMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_lengthgets", "(Ljava/lang/Object;I)Ljava/lang/Object;", 0); +// Rf_rPsortMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_rPsort", "(Lcom/oracle/truffle/r/runtime/data/RDoubleVector;II)", 0); +// Rf_iPsortMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_iPsort", "(Lcom/oracle/truffle/r/runtime/data/RIntVector;II)", 0); + CADR_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "CADR", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + CADDR_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "CADDR", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + TAG_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "TAG", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + PRINTNAME_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "PRINTNAME", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + CAR_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "CAR", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + CDR_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "CDR", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + CDDR_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "CDDR", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + SET_TAG_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SET_TAG", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + SETCAR_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SETCAR", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + SETCDR_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SETCDR", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + SETCADR_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SETCADR", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", 0); + SYMVALUE_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SYMVALUE", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + SET_SYMVALUE_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SET_SYMVALUE", "(Ljava/lang/Object;Ljava/lang/Object;)V", 0); + SET_STRING_ELT_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SET_STRING_ELT", "(Ljava/lang/Object;ILjava/lang/Object;)V", 0); + SET_VECTOR_ELT_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SET_VECTOR_ELT", "(Ljava/lang/Object;ILjava/lang/Object;)V", 0); + RAW_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "RAW", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + REAL_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "REAL", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + LOGICAL_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "LOGICAL", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + INTEGER_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "INTEGER", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + STRING_ELT_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "STRING_ELT", "(Ljava/lang/Object;I)Ljava/lang/Object;", 0); + VECTOR_ELT_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "VECTOR_ELT", "(Ljava/lang/Object;I)Ljava/lang/Object;", 0); + LENGTH_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "LENGTH", "(Ljava/lang/Object;)I", 0); + Rf_asIntegerMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_asInteger", "(Ljava/lang/Object;)I", 0); +// Rf_asRealMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_asReal", "(Ljava/lang/Object;)D", 0); + Rf_asCharMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_asChar", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + Rf_mkCharLenCEMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_mkCharLenCE", "([BI)Ljava/lang/Object;", 0); + Rf_asLogicalMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_asLogical", "(Ljava/lang/Object;)I", 0); + Rf_PairToVectorListMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_PairToVectorList", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + NAMED_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "NAMED", "(Ljava/lang/Object;)I", 0); + SET_TYPEOF_FASTR_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "SET_TYPEOF_FASTR", "(Ljava/lang/Object;I)Ljava/lang/Object;", 0); + TYPEOF_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "TYPEOF", "(Ljava/lang/Object;)I", 0); + OBJECT_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "OBJECT", "(Ljava/lang/Object;)I", 0); + DUPLICATE_ATTRIB_MethodID = checkGetMethodID(env, UpCallsRFFIClass, "DUPLICATE_ATTRIB", "(Ljava/lang/Object;Ljava/lang/Object;)V", 0); + isS4ObjectMethodID = checkGetMethodID(env, UpCallsRFFIClass, "isS4Object", "(Ljava/lang/Object;)I", 0); + logNotCharSXPWrapperMethodID = checkGetMethodID(env, UpCallsRFFIClass, "logNotCharSXPWrapper", "(Ljava/lang/Object;)V", 0); + R_tryEvalMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_tryEval", "(Ljava/lang/Object;Ljava/lang/Object;Z)Ljava/lang/Object;", 0); + RDEBUGMethodID = checkGetMethodID(env, UpCallsRFFIClass, "RDEBUG", "(Ljava/lang/Object;)I", 0); + SET_RDEBUGMethodID = checkGetMethodID(env, UpCallsRFFIClass, "SET_RDEBUG", "(Ljava/lang/Object;I)V", 0); + RSTEPMethodID = checkGetMethodID(env, UpCallsRFFIClass, "RSTEP", "(Ljava/lang/Object;)I", 0); + SET_RSTEPMethodID = checkGetMethodID(env, UpCallsRFFIClass, "SET_RSTEP", "(Ljava/lang/Object;I)V", 0); + ENCLOSMethodID = checkGetMethodID(env, UpCallsRFFIClass, "ENCLOS", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + PRVALUEMethodID = checkGetMethodID(env, UpCallsRFFIClass, "PRVALUE", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + R_lsInternal3MethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_lsInternal3", "(Ljava/lang/Object;II)Ljava/lang/Object;", 0); + + R_ToplevelExecMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ToplevelExec", "()Ljava/lang/Object;", 0); + restoreHandlerStacksMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ToplevelExecRestoreErrorHandlerStacks", "(Ljava/lang/Object;)V", 0); + + R_MakeExternalPtrMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_MakeExternalPtr", "(JLjava/lang/Object;Ljava/lang/Object;)Lcom/oracle/truffle/r/runtime/data/RExternalPtr;", 0); + R_ExternalPtrAddrMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ExternalPtrAddr", "(Ljava/lang/Object;)J", 0); + R_ExternalPtrTagMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ExternalPtrTag", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + R_ExternalPtrProtMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_ExternalPtrProt", "(Ljava/lang/Object;)Ljava/lang/Object;", 0); + R_SetExternalPtrAddrMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_SetExternalPtrAddr", "(Ljava/lang/Object;J)V", 0); + R_SetExternalPtrTagMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_SetExternalPtrTag", "(Ljava/lang/Object;Ljava/lang/Object;)V", 0); + R_SetExternalPtrProtMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_SetExternalPtrProt", "(Ljava/lang/Object;Ljava/lang/Object;)V", 0); + + CharSXPWrapperClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/CharSXPWrapper"); CharSXPWrapperContentsFieldID = checkGetFieldID(env, CharSXPWrapperClass, "contents", "Ljava/lang/String;", 0); - R_computeIdenticalMethodID = checkGetMethodID(env, CallRFFIHelperClass, "R_computeIdentical", "(Ljava/lang/Object;Ljava/lang/Object;I)I", 1); - Rf_copyListMatrixMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_copyListMatrix", "(Ljava/lang/Object;Ljava/lang/Object;I)V", 1); - Rf_copyMatrixMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_copyMatrix", "(Ljava/lang/Object;Ljava/lang/Object;I)V", 1); - Rf_nrowsMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_nrows", "(Ljava/lang/Object;)I", 1); - Rf_ncolsMethodID = checkGetMethodID(env, CallRFFIHelperClass, "Rf_ncols", "(Ljava/lang/Object;)I", 1); + R_computeIdenticalMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_computeIdentical", "(Ljava/lang/Object;Ljava/lang/Object;I)I", 0); + Rf_copyListMatrixMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_copyListMatrix", "(Ljava/lang/Object;Ljava/lang/Object;I)V", 0); + Rf_copyMatrixMethodID = checkGetMethodID(env, UpCallsRFFIClass, "Rf_copyMatrix", "(Ljava/lang/Object;Ljava/lang/Object;I)V", 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); - setCompleteMethodID = checkGetMethodID(env, CallRFFIHelperClass, "setComplete", "(Ljava/lang/Object;Z)V", 1); + setCompleteMethodID = checkGetMethodID(env, UpCallsRFFIClass, "setComplete", "(Ljava/lang/Object;Z)V", 0); } static jstring stringFromCharSXP(JNIEnv *thisenv, SEXP charsxp) { @@ -244,7 +244,7 @@ static jstring stringFromCharSXP(JNIEnv *thisenv, SEXP charsxp) { validateRef(thisenv, charsxp, "stringFromCharSXP"); if (!(*thisenv)->IsInstanceOf(thisenv, charsxp, CharSXPWrapperClass)) { - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, logObject_MethodID, charsxp); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, logNotCharSXPWrapperMethodID, charsxp); fatalError("only CharSXPWrapper expected in stringFromCharSXP"); } #endif @@ -254,27 +254,27 @@ static jstring stringFromCharSXP(JNIEnv *thisenv, SEXP charsxp) { SEXP Rf_ScalarInteger(int value) { TRACE(TARGp, value); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_ScalarIntegerMethodID, value); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_ScalarIntegerMethodID, value); return checkRef(thisenv, result); } SEXP Rf_ScalarReal(double value) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_ScalarDoubleMethodID, value); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_ScalarDoubleMethodID, value); return checkRef(thisenv, result); } SEXP Rf_ScalarString(SEXP value) { TRACE(TARGp, value); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_ScalarStringMethodID, value); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_ScalarStringMethodID, value); return checkRef(thisenv, result); } SEXP Rf_ScalarLogical(int value) { TRACE(TARGp, value); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_ScalarLogicalMethodID, value); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_ScalarLogicalMethodID, value); return checkRef(thisenv, result); } @@ -285,14 +285,14 @@ SEXP Rf_allocVector3(SEXPTYPE t, R_xlen_t len, R_allocator_t* allocator) { } TRACE(TARGpd, t, len); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_allocateVectorMethodID, t, len); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_allocateVectorMethodID, t, len); return checkRef(thisenv, result); } SEXP Rf_allocArray(SEXPTYPE t, SEXP dims) { TRACE(TARGppd, t, dims); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_allocateArrayMethodID, t, dims); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_allocateArrayMethodID, t, dims); return checkRef(thisenv, result); } @@ -303,7 +303,7 @@ SEXP Rf_alloc3DArray(SEXPTYPE t, int x, int y, int z) { SEXP Rf_allocMatrix(SEXPTYPE mode, int nrow, int ncol) { TRACE(TARGppd, mode, nrow, ncol); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_allocateMatrixMethodID, mode, nrow, ncol); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_allocateMatrixMethodID, mode, nrow, ncol); return checkRef(thisenv, result); } @@ -319,14 +319,14 @@ SEXP Rf_allocSExp(SEXPTYPE t) { SEXP Rf_cons(SEXP car, SEXP cdr) { TRACE(TARGpp, car, cdr); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_consMethodID, car, cdr); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_consMethodID, car, cdr); return checkRef(thisenv, result); } void Rf_defineVar(SEXP symbol, SEXP value, SEXP rho) { TRACE(TARGppp, symbol, value, rho); JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_defineVarMethodID, symbol, value, rho); + (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_defineVarMethodID, symbol, value, rho); } void Rf_setVar(SEXP x, SEXP y, SEXP z) { @@ -345,63 +345,63 @@ SEXP Rf_eval(SEXP expr, SEXP env) { TRACE(TARGpp, expr, env); JNIEnv *thisenv = getEnv(); updateNativeArrays(thisenv); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_evalMethodID, expr, env); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_evalMethodID, expr, env); return checkRef(thisenv, result); } SEXP Rf_findFun(SEXP symbol, SEXP rho) { TRACE(TARGpp, symbol, rho); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findfunMethodID, symbol, rho); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_findfunMethodID, symbol, rho); return checkRef(thisenv, result); } SEXP Rf_findVar(SEXP sym, SEXP rho) { TRACE(TARGpp, sym, rho); JNIEnv *thisenv = getEnv(); - SEXP result =(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findVarMethodID, sym, rho); + SEXP result =(*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_findVarMethodID, sym, rho); return checkRef(thisenv, result); } SEXP Rf_findVarInFrame(SEXP rho, SEXP sym) { TRACE(TARGpp, rho, sym); JNIEnv *thisenv = getEnv(); - SEXP result =(*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findVarInFrameMethodID, rho, sym); + SEXP result =(*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_findVarInFrameMethodID, rho, sym); return checkRef(thisenv, result); } SEXP Rf_findVarInFrame3(SEXP rho, SEXP sym, Rboolean b) { TRACE(TARGppd, rho, sym, b); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_findVarInFrame3MethodID, rho, sym, b); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_findVarInFrame3MethodID, rho, sym, b); return checkRef(thisenv, result); } SEXP Rf_getAttrib(SEXP vec, SEXP name) { TRACE(TARGpp, vec, name); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_getAttribMethodID, vec, name); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_getAttribMethodID, vec, name); return checkRef(thisenv, result); } SEXP Rf_setAttrib(SEXP vec, SEXP name, SEXP val) { TRACE(TARGppp, vec,name, val); JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, Rf_setAttribMethodID, vec, name, val); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, Rf_setAttribMethodID, vec, name, val); return val; } SEXP Rf_duplicate(SEXP x) { TRACE(TARGp, x); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_duplicateMethodID, x, 1); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, 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); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_duplicateMethodID, x, 0); return checkRef(thisenv, result); } @@ -409,7 +409,7 @@ R_xlen_t Rf_any_duplicated(SEXP x, Rboolean from_last) { TRACE(TARGpd, x, from_last); if (!isVector(x)) error(_("'duplicated' applies only to vectors")); JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_anyDuplicatedMethodID, x, from_last); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, Rf_anyDuplicatedMethodID, x, from_last); } SEXP Rf_duplicated(SEXP x, Rboolean y) { @@ -437,7 +437,7 @@ Rboolean Rf_inherits(SEXP x, const char * klass) { TRACE(TARGps, x, klass); JNIEnv *thisenv = getEnv(); jstring klazz = (*thisenv)->NewStringUTF(thisenv, klass); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_inheritsMethodID, x, klazz); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, Rf_inheritsMethodID, x, klazz); } Rboolean Rf_isReal(SEXP x) { @@ -477,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, CallRFFIHelperClass, Rf_installMethodID, string); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_installMethodID, string); return checkRef(thisenv, result); } @@ -485,18 +485,18 @@ SEXP Rf_installChar(SEXP charsxp) { TRACE(TARGp, charsxp); JNIEnv *thisenv = getEnv(); jstring string = stringFromCharSXP(thisenv, charsxp); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_installMethodID, string); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_installMethodID, string); return checkRef(thisenv, result); } Rboolean Rf_isNull(SEXP s) { JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_isNullMethodID, s); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, Rf_isNullMethodID, s); } Rboolean Rf_isString(SEXP s) { JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_isStringMethodID, s); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, Rf_isStringMethodID, s); } Rboolean R_cycle_detected(SEXP s, SEXP child) { @@ -527,7 +527,7 @@ SEXP Rf_mkCharLenCE(const char *x, int len, cetype_t enc) { JNIEnv *thisenv = getEnv(); jbyteArray bytes = (*thisenv)->NewByteArray(thisenv, len); (*thisenv)->SetByteArrayRegion(thisenv, bytes, 0, len, (const jbyte *) x); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_mkCharLenCEMethodID, bytes, (int) enc); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_mkCharLenCEMethodID, bytes, (int) enc); return checkRef(thisenv, result); } @@ -543,13 +543,13 @@ SEXP Rf_mkString(const char *s) { int Rf_ncols(SEXP x) { TRACE(TARGs, x); JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_ncolsMethodID, x); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, Rf_ncolsMethodID, x); } int Rf_nrows(SEXP x) { TRACE(TARGs, x); JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_nrowsMethodID, x); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, Rf_nrowsMethodID, x); } @@ -591,7 +591,7 @@ void Rf_error(const char *format, ...) { // RError.error does quite a lot of stuff including potentially searching for R condition handlers // and, if it finds any, does not return, but throws a different exception than RError. // We definitely need to exit the FFI call and we certainly cannot return to our caller. - // So we call CallRFFIHelper.Rf_error to throw the RError exception. When the pending + // So we call RFFIUpCallsObject.Rf_error to throw the RError exception. When the pending // exception (whatever it is) is observed by JNI, the call to Rf_error will return where we do a // non-local transfer of control back to the entry point (which will cleanup). char buf[8192]; @@ -602,7 +602,7 @@ void Rf_error(const char *format, ...) { JNIEnv *thisenv = getEnv(); jstring string = (*thisenv)->NewStringUTF(thisenv, buf); // This will set a pending exception - (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_errorMethodID, string); + (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_errorMethodID, string); // just transfer back which will cleanup and exit the entire JNI call longjmp(*getErrorJmpBuf(), 1); @@ -620,7 +620,7 @@ void Rf_warningcall(SEXP x, const char *format, ...) { va_end(ap); JNIEnv *thisenv = getEnv(); jstring string = (*thisenv)->NewStringUTF(thisenv, buf); - (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_warningcallMethodID, x, string); + (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_warningcallMethodID, x, string); } void Rf_warning(const char *format, ...) { @@ -631,7 +631,7 @@ void Rf_warning(const char *format, ...) { va_end(ap); JNIEnv *thisenv = getEnv(); jstring string = (*thisenv)->NewStringUTF(thisenv, buf); - (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_warningMethodID, string); + (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_warningMethodID, string); } void Rprintf(const char *format, ...) { @@ -642,7 +642,7 @@ void Rprintf(const char *format, ...) { va_end(ap); JNIEnv *thisenv = getEnv(); jstring string = (*thisenv)->NewStringUTF(thisenv, buf); - (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, RprintfMethodID, string); + (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, RprintfMethodID, string); } /* @@ -660,7 +660,7 @@ void REprintf(const char *format, ...) va_end(ap); JNIEnv *thisenv = getEnv(); jstring string = (*thisenv)->NewStringUTF(thisenv, buf); - (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, RprintfMethodID, string); + (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, RprintfMethodID, string); } void Rvprintf(const char *format, va_list args) { @@ -681,13 +681,13 @@ void R_ProcessEvents(void) { // Tools package support, not in public API SEXP R_NewHashedEnv(SEXP parent, SEXP size) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_NewHashedEnvMethodID, parent, size); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, R_NewHashedEnvMethodID, parent, size); return checkRef(thisenv, result); } SEXP Rf_classgets(SEXP vec, SEXP klass) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_classgetsMethodID, vec, klass); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_classgetsMethodID, vec, klass); return checkRef(thisenv, result); } @@ -716,7 +716,7 @@ SEXP Rf_lengthgets(SEXP x, R_len_t y) { TRACE(TARGp, x); JNIEnv *thisenv = getEnv(); invalidateNativeArray(thisenv, x); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_lengthgetsMethodID, x, y); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_lengthgetsMethodID, x, y); return checkRef(thisenv, result); } @@ -731,7 +731,7 @@ SEXP R_lsInternal(SEXP env, Rboolean all) { SEXP R_lsInternal3(SEXP env, Rboolean all, Rboolean sorted) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_lsInternal3MethodID, env, all, sorted); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, R_lsInternal3MethodID, env, all, sorted); return checkRef(thisenv, result); } @@ -742,7 +742,7 @@ SEXP Rf_namesgets(SEXP x, SEXP y) { SEXP GetOption1(SEXP tag) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_GetOption1MethodID, tag); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_GetOption1MethodID, tag); return checkRef(thisenv, result); } @@ -803,34 +803,34 @@ Rboolean Rf_GetOptionDeviceAsk(void) void Rf_gsetVar(SEXP symbol, SEXP value, SEXP rho) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_gsetVarMethodID, symbol, value, rho); + (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_gsetVarMethodID, symbol, value, rho); } SEXP TAG(SEXP e) { TRACE(TARGp, e); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, TAG_MethodID, e); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, TAG_MethodID, e); return checkRef(thisenv, result); } SEXP PRINTNAME(SEXP e) { TRACE(TARGp, e); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, PRINTNAME_MethodID, e); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, PRINTNAME_MethodID, e); return checkRef(thisenv, result); } SEXP CAR(SEXP e) { TRACE(TARGp, e); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, CAR_MethodID, e); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, CAR_MethodID, e); return checkRef(thisenv, result); } SEXP CDR(SEXP e) { TRACE(TARGp, e); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, CDR_MethodID, e); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, CDR_MethodID, e); return checkRef(thisenv, result); } @@ -847,14 +847,14 @@ SEXP CDAR(SEXP e) { SEXP CADR(SEXP e) { TRACE(TARGp, e); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, CADR_MethodID, e); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, CADR_MethodID, e); return checkRef(thisenv, result); } SEXP CDDR(SEXP e) { TRACE(TARGp, e); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, CDDR_MethodID, e); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, CDDR_MethodID, e); return checkRef(thisenv, result); } @@ -866,7 +866,7 @@ SEXP CDDDR(SEXP e) { SEXP CADDR(SEXP e) { TRACE(TARGp, e); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, CADDR_MethodID, e); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, CADDR_MethodID, e); return checkRef(thisenv, result); } @@ -892,27 +892,27 @@ void SET_MISSING(SEXP x, int v) { void SET_TAG(SEXP x, SEXP y) { TRACE(TARGpp, x, y); JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, SET_TAG_MethodID, x, y); + (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, SET_TAG_MethodID, x, y); } SEXP SETCAR(SEXP x, SEXP y) { TRACE(TARGpp, x, y); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, SETCAR_MethodID, x, y); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, SETCAR_MethodID, x, y); return checkRef(thisenv, result); } SEXP SETCDR(SEXP x, SEXP y) { TRACE(TARGpp, x, y); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, SETCDR_MethodID, x, y); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, SETCDR_MethodID, x, y); return checkRef(thisenv, result); } SEXP SETCADR(SEXP x, SEXP y) { TRACE(TARGpp, x, y); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, SETCADR_MethodID, x, y); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, SETCADR_MethodID, x, y); return checkRef(thisenv, result); } @@ -945,12 +945,12 @@ SEXP CLOENV(SEXP x) { int RDEBUG(SEXP x) { JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, RDEBUGMethodID, x); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, RDEBUGMethodID, x); } int RSTEP(SEXP x) { JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, RSTEPMethodID, x); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, RSTEPMethodID, x); } int RTRACE(SEXP x) { @@ -960,12 +960,12 @@ int RTRACE(SEXP x) { void SET_RDEBUG(SEXP x, int v) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, SET_RDEBUGMethodID, x, v); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, SET_RDEBUGMethodID, x, v); } void SET_RSTEP(SEXP x, int v) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, SET_RSTEPMethodID, x, v); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, SET_RSTEPMethodID, x, v); } void SET_RTRACE(SEXP x, int v) { @@ -986,7 +986,7 @@ void SET_CLOENV(SEXP x, SEXP v) { SEXP SYMVALUE(SEXP x) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, SYMVALUE_MethodID, x); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, SYMVALUE_MethodID, x); return checkRef(thisenv, result); } @@ -1005,7 +1005,7 @@ void SET_DDVAL(SEXP x, int v) { void SET_SYMVALUE(SEXP x, SEXP v) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, SET_SYMVALUE_MethodID, x, v); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, SET_SYMVALUE_MethodID, x, v); } void SET_INTERNAL(SEXP x, SEXP v) { @@ -1018,7 +1018,7 @@ SEXP FRAME(SEXP x) { SEXP ENCLOS(SEXP x) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, ENCLOSMethodID, x); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, ENCLOSMethodID, x); return checkRef(thisenv, result); } @@ -1059,7 +1059,7 @@ SEXP PRENV(SEXP x) { SEXP PRVALUE(SEXP x) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, PRVALUEMethodID, x); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, PRVALUEMethodID, x); return checkRef(thisenv, result); } @@ -1086,7 +1086,7 @@ void SET_PRCODE(SEXP x, SEXP v) { int LENGTH(SEXP x) { TRACE(TARGp, x); JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, LENGTH_MethodID, x); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, LENGTH_MethodID, x); } int TRUELENGTH(SEXP x){ @@ -1172,7 +1172,7 @@ Rcomplex *COMPLEX(SEXP x){ SEXP STRING_ELT(SEXP x, R_xlen_t i){ TRACE(TARGpd, x, i); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, STRING_ELT_MethodID, x, i); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, STRING_ELT_MethodID, x, i); return checkRef(thisenv, result); } @@ -1180,21 +1180,21 @@ SEXP STRING_ELT(SEXP x, R_xlen_t i){ SEXP VECTOR_ELT(SEXP x, R_xlen_t i){ TRACE(TARGpd, x, i); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, VECTOR_ELT_MethodID, x, i); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, VECTOR_ELT_MethodID, x, i); return checkRef(thisenv, result); } void SET_STRING_ELT(SEXP x, R_xlen_t i, SEXP v){ TRACE("%s(%p, %d, %p)\n", x, i, v); JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, SET_STRING_ELT_MethodID, x, i, v); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, SET_STRING_ELT_MethodID, x, i, v); } SEXP SET_VECTOR_ELT(SEXP x, R_xlen_t i, SEXP v){ TRACE("%s(%p, %d, %p)\n", x, i, v); JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, SET_VECTOR_ELT_MethodID, x, i, v); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, SET_VECTOR_ELT_MethodID, x, i, v); return v; } @@ -1213,14 +1213,14 @@ SEXP *VECTOR_PTR(SEXP x){ SEXP Rf_asChar(SEXP x){ TRACE(TARGp, x); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_asCharMethodID, x); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_asCharMethodID, x); return checkRef(thisenv, result); } SEXP Rf_PairToVectorList(SEXP x){ TRACE(TARGp, x); JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, Rf_PairToVectorListMethodID, x); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, Rf_PairToVectorListMethodID, x); return checkRef(thisenv, result); } @@ -1237,19 +1237,19 @@ SEXP Rf_asCharacterFactor(SEXP x){ int Rf_asLogical(SEXP x){ TRACE(TARGp, x); JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_asLogicalMethodID, x); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, Rf_asLogicalMethodID, x); } int Rf_asInteger(SEXP x) { TRACE(TARGp, x); JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_asIntegerMethodID, x); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, Rf_asIntegerMethodID, x); } //double Rf_asReal(SEXP x) { // TRACE(TARGp, x); // JNIEnv *thisenv = getEnv(); -// return (*thisenv)->CallStaticDoubleMethod(thisenv, CallRFFIHelperClass, Rf_asRealMethodID, x); +// return (*thisenv)->CallDoubleMethod(thisenv, UpCallsRFFIObject, Rf_asRealMethodID, x); //} Rcomplex Rf_asComplex(SEXP x){ @@ -1260,7 +1260,7 @@ Rcomplex Rf_asComplex(SEXP x){ int TYPEOF(SEXP x) { TRACE(TARGp, x); JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, TYPEOF_MethodID, x); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, TYPEOF_MethodID, x); } SEXP ATTRIB(SEXP x){ @@ -1270,7 +1270,7 @@ SEXP ATTRIB(SEXP x){ int OBJECT(SEXP x){ JNIEnv *env = getEnv(); - return (*env)->CallStaticIntMethod(env, CallRFFIHelperClass, OBJECT_MethodID, x); + return (*env)->CallIntMethod(env, UpCallsRFFIObject, OBJECT_MethodID, x); } int MARK(SEXP x){ @@ -1280,7 +1280,7 @@ int MARK(SEXP x){ int NAMED(SEXP x){ JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, NAMED_MethodID, x); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, NAMED_MethodID, x); } int REFCNT(SEXP x){ @@ -1298,7 +1298,7 @@ void SET_TYPEOF(SEXP x, int v){ SEXP SET_TYPEOF_FASTR(SEXP x, int v){ JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, SET_TYPEOF_FASTR_MethodID, x, v); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, SET_TYPEOF_FASTR_MethodID, x, v); return checkRef(thisenv, result); } @@ -1312,7 +1312,7 @@ void SET_ATTRIB(SEXP x, SEXP v){ void DUPLICATE_ATTRIB(SEXP to, SEXP from){ JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, DUPLICATE_ATTRIB_MethodID, to, from); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, DUPLICATE_ATTRIB_MethodID, to, from); } char *dgettext(const char *domainname, const char *msgid) { @@ -1367,7 +1367,7 @@ R_len_t R_BadLongVector(SEXP x, const char *y, int z) { int IS_S4_OBJECT(SEXP x) { JNIEnv *env = getEnv(); - return (*env)->CallStaticIntMethod(env, CallRFFIHelperClass, isS4ObjectMethodID, x); + return (*env)->CallIntMethod(env, UpCallsRFFIObject, isS4ObjectMethodID, x); } void SET_S4_OBJECT(SEXP x) { @@ -1379,9 +1379,9 @@ void UNSET_S4_OBJECT(SEXP x) { Rboolean R_ToplevelExec(void (*fun)(void *), void *data) { JNIEnv *env = getEnv(); - jobject handlerStacks = (*env)->CallStaticObjectMethod(env, CallRFFIHelperClass, resetAndGetHandlerStacksMethodID); + jobject handlerStacks = (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_ToplevelExecMethodID); fun(data); - (*env)->CallStaticVoidMethod(env, CallRFFIHelperClass, restoreHandlerStacksMethodID, handlerStacks); + (*env)->CallVoidMethod(env, UpCallsRFFIObject, restoreHandlerStacksMethodID, handlerStacks); // TODO how do we detect error return TRUE; } @@ -1418,7 +1418,7 @@ SEXP R_NamespaceEnvSpec(SEXP rho) { SEXP R_FindNamespace(SEXP info) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_FindNamespaceMethodID, info); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, R_FindNamespaceMethodID, info); return checkRef(thisenv, result); } @@ -1444,7 +1444,7 @@ void R_MakeActiveBinding(SEXP sym, SEXP fun, SEXP env) { Rboolean R_BindingIsLocked(SEXP sym, SEXP env) { JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, R_BindingIsLockedID, sym, env); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, R_BindingIsLockedID, sym, env); } Rboolean R_BindingIsActive(SEXP sym, SEXP env) { @@ -1467,7 +1467,7 @@ SEXP Rf_asS4(SEXP x, Rboolean b, int i) { static SEXP R_tryEvalInternal(SEXP x, SEXP y, int *ErrorOccurred, jboolean silent) { JNIEnv *thisenv = getEnv(); updateNativeArrays(thisenv); - jobject tryResult = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_tryEvalMethodID, x, y, silent); + jobject tryResult = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, R_tryEvalMethodID, x, y, silent); // If tryResult is NULL, an error occurred if (ErrorOccurred) { *ErrorOccurred = tryResult == NULL; @@ -1507,40 +1507,40 @@ SEXP R_forceAndCall(SEXP e, int n, SEXP rho) { SEXP R_MakeExternalPtr(void *p, SEXP tag, SEXP prot) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_MakeExternalPtrMethodID, (jlong) p, tag, prot); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, R_MakeExternalPtrMethodID, (jlong) p, tag, prot); return checkRef(thisenv, result); } void *R_ExternalPtrAddr(SEXP s) { JNIEnv *thisenv = getEnv(); - return (void *) (*thisenv)->CallStaticLongMethod(thisenv, CallRFFIHelperClass, R_ExternalPtrAddrMethodID, s); + return (void *) (*thisenv)->CallLongMethod(thisenv, UpCallsRFFIObject, R_ExternalPtrAddrMethodID, s); } SEXP R_ExternalPtrTag(SEXP s) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_ExternalPtrTagMethodID, s); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, R_ExternalPtrTagMethodID, s); return checkRef(thisenv, result); } SEXP R_ExternalPtrProt(SEXP s) { JNIEnv *thisenv = getEnv(); - SEXP result = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_ExternalPtrProtMethodID, s); + SEXP result = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, R_ExternalPtrProtMethodID, s); return checkRef(thisenv, result); } void R_SetExternalPtrAddr(SEXP s, void *p) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, R_SetExternalPtrAddrMethodID, s, (jlong) p); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, R_SetExternalPtrAddrMethodID, s, (jlong) p); } void R_SetExternalPtrTag(SEXP s, SEXP tag) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, R_SetExternalPtrTagMethodID, s, tag); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, R_SetExternalPtrTagMethodID, s, tag); } void R_SetExternalPtrProtected(SEXP s, SEXP p) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticVoidMethod(thisenv, CallRFFIHelperClass, R_SetExternalPtrProtMethodID, s, p); + (*thisenv)->CallVoidMethod(thisenv, UpCallsRFFIObject, R_SetExternalPtrProtMethodID, s, p); } void R_ClearExternalPtr(SEXP s) { @@ -1602,7 +1602,7 @@ int R_has_slot(SEXP obj, SEXP name) { SEXP R_do_MAKE_CLASS(const char *what) { JNIEnv *thisenv = getEnv(); jstring string = (*thisenv)->NewStringUTF(thisenv, what); - return (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, R_do_MAKE_CLASS_MethodID, string); + return (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, R_do_MAKE_CLASS_MethodID, string); } SEXP R_getClassDef (const char *what) { @@ -1637,15 +1637,15 @@ void R_dot_Last(void) { Rboolean R_compute_identical(SEXP x, SEXP y, int flags) { JNIEnv *thisenv = getEnv(); - return (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, R_computeIdenticalMethodID, x, y, flags); + return (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, R_computeIdenticalMethodID, x, y, flags); } void Rf_copyListMatrix(SEXP s, SEXP t, Rboolean byrow) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_copyListMatrixMethodID, s, t, byrow); + (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, Rf_copyListMatrixMethodID, s, t, byrow); } void Rf_copyMatrix(SEXP s, SEXP t, Rboolean byrow) { JNIEnv *thisenv = getEnv(); - (*thisenv)->CallStaticIntMethod(thisenv, CallRFFIHelperClass, Rf_copyMatrixMethodID, s, t, byrow); + (*thisenv)->CallIntMethod(thisenv, UpCallsRFFIObject, Rf_copyMatrixMethodID, s, t, byrow); } diff --git a/com.oracle.truffle.r.native/fficall/src/jni/call_rffi.c b/com.oracle.truffle.r.native/fficall/src/jni/call_rffi.c index 7b9a14296c810e03a53a5ac1c6b10329b1006599..eb81606672d73f8a5cfee40801ca109e6ce7e0c0 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/call_rffi.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/call_rffi.c @@ -25,10 +25,11 @@ #include <string.h> #include <setjmp.h> +// The entry point from JNI_Call that initializes the system JNIEXPORT void JNICALL Java_com_oracle_truffle_r_runtime_ffi_jni_JNI_1Call_initialize(JNIEnv *env, jclass c, - jobjectArray initialValues) { - init_utils(env); // must be first + jobject upCallInstance, jobjectArray initialValues) { + init_utils(env, upCallInstance); // must be first init_variables(env, initialValues); init_dynload(env); init_internals(env); 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 0010587bccde3b3ea603407a66e2a05727d9f2f9..69d19f2aec5742fcbc96b2bd11340a324ccf3bcf 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.c @@ -32,11 +32,10 @@ * so we are safe to use static variables. TODO Figure out where to store such state * (portably) for MT use. JNI provides no help. */ -jclass CallRFFIHelperClass; +jclass UpCallsRFFIClass; +jobject UpCallsRFFIObject; jclass CharSXPWrapperClass; -static jmethodID validateMethodID; - static JNIEnv *curenv = NULL; // default for trace output when enabled @@ -87,8 +86,10 @@ static int nativeArrayTableHwmStack[CALLDEPTH_STACK_SIZE]; static jmp_buf* callErrorJmpBufTable[CALLDEPTH_STACK_SIZE]; -void init_utils(JNIEnv *env) { +void init_utils(JNIEnv *env, jobject upCallsInstance) { curenv = env; + UpCallsRFFIClass = (*env)->GetObjectClass(env, upCallsInstance); + UpCallsRFFIObject = (*env)->NewGlobalRef(env, upCallsInstance); if (TRACE_ENABLED && traceFile == NULL) { if (!isEmbedded) { traceFile = stdout; @@ -109,8 +110,6 @@ void init_utils(JNIEnv *env) { setvbuf(traceFile, (char*) NULL, _IONBF, 0); } } - CallRFFIHelperClass = checkFindClass(env, "com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper"); - 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; cachedGlobalRefsHwm = 0; @@ -230,7 +229,7 @@ void *getNativeArray(JNIEnv *thisenv, SEXP x, SEXPTYPE type) { jarray jArray; switch (type) { case INTSXP: { - jintArray intArray = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, INTEGER_MethodID, x); + jintArray intArray = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, INTEGER_MethodID, x); int len = (*thisenv)->GetArrayLength(thisenv, intArray); data = (*thisenv)->GetIntArrayElements(thisenv, intArray, &isCopy); jArray = intArray; @@ -238,7 +237,7 @@ void *getNativeArray(JNIEnv *thisenv, SEXP x, SEXPTYPE type) { } case REALSXP: { - jdoubleArray doubleArray = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, REAL_MethodID, x); + jdoubleArray doubleArray = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, REAL_MethodID, x); int len = (*thisenv)->GetArrayLength(thisenv, doubleArray); data = (*thisenv)->GetDoubleArrayElements(thisenv, doubleArray, &isCopy); jArray = doubleArray; @@ -246,7 +245,7 @@ void *getNativeArray(JNIEnv *thisenv, SEXP x, SEXPTYPE type) { } case RAWSXP: { - jbyteArray byteArray = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, RAW_MethodID, x); + jbyteArray byteArray = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, RAW_MethodID, x); int len = (*thisenv)->GetArrayLength(thisenv, byteArray); data = (*thisenv)->GetByteArrayElements(thisenv, byteArray, &isCopy); jArray = byteArray; @@ -255,7 +254,7 @@ void *getNativeArray(JNIEnv *thisenv, SEXP x, SEXPTYPE type) { case LGLSXP: { // Special treatment becuase R FFI wants int* and FastR represents using byte[] - jbyteArray byteArray = (*thisenv)->CallStaticObjectMethod(thisenv, CallRFFIHelperClass, LOGICAL_MethodID, x); + jbyteArray byteArray = (*thisenv)->CallObjectMethod(thisenv, UpCallsRFFIObject, LOGICAL_MethodID, x); int len = (*thisenv)->GetArrayLength(thisenv, byteArray); jbyte* internalData = (*thisenv)->GetByteArrayElements(thisenv, byteArray, &isCopy); int* idata = malloc(len * sizeof(int)); @@ -333,7 +332,7 @@ static void releaseNativeArray(JNIEnv *env, int i, int freedata) { fatalError("releaseNativeArray type"); } // update complete status - (*env)->CallVoidMethod(env, cv.obj, setCompleteMethodID, cv.obj, complete); + (*env)->CallVoidMethod(env, UpCallsRFFIObject, setCompleteMethodID, cv.obj, complete); if (freedata) { // free up the slot @@ -427,10 +426,6 @@ void validateRef(JNIEnv *env, SEXP x, const char *msg) { } } -void validate(SEXP x) { - (*curenv)->CallStaticObjectMethod(curenv, CallRFFIHelperClass, validateMethodID, x); -} - JNIEnv *getEnv() { // fprintf(traceFile, "getEnv()=%p\n", curenv); return curenv; 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 3a3539579ec0912b64229bbe5709c4c1cab4c719..99732f93766987fdceb40035a84eacce6111d882 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h +++ b/com.oracle.truffle.r.native/fficall/src/jni/rffiutils.h @@ -76,12 +76,12 @@ void updateNativeArrays(JNIEnv *env); SEXP addGlobalRef(JNIEnv *env, SEXP obj, int permanent); +void init_utils(JNIEnv *env, jobject upCallsInstance); void init_rmath(JNIEnv *env); void init_variables(JNIEnv *env, jobjectArray initialValues); void init_dynload(JNIEnv *env); void init_internals(JNIEnv *env); void init_random(JNIEnv *env); -void init_utils(JNIEnv *env); void init_parse(JNIEnv *env); void init_pcre(JNIEnv *env); void init_c(JNIEnv *env); @@ -90,7 +90,8 @@ void setEmbedded(void); void setTempDir(JNIEnv *, jstring tempDir); -extern jclass CallRFFIHelperClass; +extern jclass UpCallsRFFIClass; +extern jobject UpCallsRFFIObject; extern FILE *traceFile; // tracing/debugging support, set to 1 and recompile to enable diff --git a/com.oracle.truffle.r.native/fficall/src/jni/userrng_rffi.c b/com.oracle.truffle.r.native/fficall/src/jni/userrng_rffi.c index a946f23f8b1f9fbcc72322e199a1103afe3649a8..fd510c9e56eaa4985c9067a574bf6a2b092415ed 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/userrng_rffi.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/userrng_rffi.c @@ -29,27 +29,27 @@ typedef int* (*call_nSeed)(void); typedef int* (*call_seeds)(void); JNIEXPORT void JNICALL -Java_com_oracle_truffle_r_runtime_ffi_jni_JNI_1UserRng_init(JNIEnv *env, jclass c, jlong address, jint seed) { +Java_com_oracle_truffle_r_runtime_ffi_jni_JNI_1UserRng_nativeInit(JNIEnv *env, jclass c, jlong address, jint seed) { call_init f = (call_init) address; f(seed); } JNIEXPORT double JNICALL -Java_com_oracle_truffle_r_runtime_ffi_jni_JNI_1UserRng_rand(JNIEnv *env, jclass c, jlong address) { +Java_com_oracle_truffle_r_runtime_ffi_jni_JNI_1UserRng_nativeRand(JNIEnv *env, jclass c, jlong address) { call_rand f = (call_rand) address; double* dp = f(); return *dp; } JNIEXPORT jint JNICALL -Java_com_oracle_truffle_r_runtime_ffi_jni_JNI_1UserRng_nSeed(JNIEnv *env, jclass c, jlong address) { +Java_com_oracle_truffle_r_runtime_ffi_jni_JNI_1UserRng_nativeNSeed(JNIEnv *env, jclass c, jlong address) { call_nSeed f = (call_nSeed) address; int *pn = f(); return *pn; } JNIEXPORT void JNICALL -Java_com_oracle_truffle_r_runtime_ffi_jni_JNI_1UserRng_seeds(JNIEnv *env, jclass c, jlong address, jintArray seedsArray) { +Java_com_oracle_truffle_r_runtime_ffi_jni_JNI_1UserRng_nativeSeeds(JNIEnv *env, jclass c, jlong address, jintArray seedsArray) { call_seeds f = (call_seeds) address; int *pseeds = f(); int seedslen = (*env)->GetArrayLength(env, seedsArray); diff --git a/com.oracle.truffle.r.native/fficall/src/jni/variables.c b/com.oracle.truffle.r.native/fficall/src/jni/variables.c index ca381df5e2e84d8b6568bca259034d09d8227244..aaf00d68fee482eaa1fbae06c1421eb1593b189e 100644 --- a/com.oracle.truffle.r.native/fficall/src/jni/variables.c +++ b/com.oracle.truffle.r.native/fficall/src/jni/variables.c @@ -31,37 +31,37 @@ #include <rffiutils.h> #include <variable_defs.h> -jmethodID getGlobalEnvMethodID; -jmethodID getBaseEnvMethodID; -jmethodID getBaseNamespaceMethodID; -jmethodID getNamespaceRegistryMethodID; +jmethodID R_GlobalEnvMethodID; +jmethodID R_BaseEnvMethodID; +jmethodID R_BaseNamespaceMethodID; +jmethodID R_NamespaceRegistryMethodID; jmethodID isInteractiveMethodID; -jmethodID getGlobalContextMethodID; +jmethodID R_GlobalContextMethodID; // R_GlobalEnv et al are not a variables in FASTR as they are RContext specific SEXP FASTR_GlobalEnv() { JNIEnv *env = getEnv(); - return (*env)->CallStaticObjectMethod(env, CallRFFIHelperClass, getGlobalEnvMethodID); + return (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_GlobalEnvMethodID); } SEXP FASTR_BaseEnv() { JNIEnv *env = getEnv(); - return (*env)->CallStaticObjectMethod(env, CallRFFIHelperClass, getBaseEnvMethodID); + return (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_BaseEnvMethodID); } SEXP FASTR_BaseNamespace() { JNIEnv *env = getEnv(); - return (*env)->CallStaticObjectMethod(env, CallRFFIHelperClass, getBaseNamespaceMethodID); + return (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_BaseNamespaceMethodID); } SEXP FASTR_NamespaceRegistry() { JNIEnv *env = getEnv(); - return (*env)->CallStaticObjectMethod(env, CallRFFIHelperClass, getNamespaceRegistryMethodID); + return (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_NamespaceRegistryMethodID); } CTXT FASTR_GlobalContext() { JNIEnv *env = getEnv(); - CTXT res = (*env)->CallStaticObjectMethod(env, CallRFFIHelperClass, getGlobalContextMethodID); + CTXT res = (*env)->CallObjectMethod(env, UpCallsRFFIObject, R_GlobalContextMethodID); return addGlobalRef(env, res, 0); } @@ -77,12 +77,12 @@ void init_variables(JNIEnv *env, jobjectArray initialValues) { jmethodID doubleValueMethodID = checkGetMethodID(env, doubleClass, "doubleValue", "()D", 0); jmethodID intValueMethodID = checkGetMethodID(env, intClass, "intValue", "()I", 0); - getGlobalEnvMethodID = checkGetMethodID(env, CallRFFIHelperClass, "getGlobalEnv", "()Ljava/lang/Object;", 1); - getBaseEnvMethodID = checkGetMethodID(env, CallRFFIHelperClass, "getBaseEnv", "()Ljava/lang/Object;", 1); - getBaseNamespaceMethodID = checkGetMethodID(env, CallRFFIHelperClass, "getBaseNamespace", "()Ljava/lang/Object;", 1); - getNamespaceRegistryMethodID = checkGetMethodID(env, CallRFFIHelperClass, "getNamespaceRegistry", "()Ljava/lang/Object;", 1); - isInteractiveMethodID = checkGetMethodID(env, CallRFFIHelperClass, "isInteractive", "()I", 1); - getGlobalContextMethodID = checkGetMethodID(env, CallRFFIHelperClass, "getGlobalContext", "()Ljava/lang/Object;", 1); + R_GlobalEnvMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_GlobalEnv", "()Ljava/lang/Object;", 0); + R_BaseEnvMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_BaseEnv", "()Ljava/lang/Object;", 0); + R_BaseNamespaceMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_BaseNamespace", "()Ljava/lang/Object;", 0); + R_NamespaceRegistryMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_NamespaceRegistry", "()Ljava/lang/Object;", 0); + isInteractiveMethodID = checkGetMethodID(env, UpCallsRFFIClass, "isInteractive", "()I", 0); + R_GlobalContextMethodID = checkGetMethodID(env, UpCallsRFFIClass, "R_GlobalContext", "()Ljava/lang/Object;", 0); int length = (*env)->GetArrayLength(env, initialValues); int index; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java index 0550a55c3bdd9628b69680a20f5fda5193ade6b6..535045ab1cba59cf3f21c3d8f60549161d9a1f2c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/RBuiltinPackages.java @@ -38,6 +38,7 @@ import com.oracle.truffle.r.nodes.builtin.base.BaseVariables; import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.REnvVars; import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RSource; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.builtins.RBuiltin; @@ -50,8 +51,6 @@ import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; 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; -import com.oracle.truffle.r.runtime.ffi.DLL.DLLException; /** * Support for loading the base package and also optional overrides for the packages provided with @@ -98,11 +97,10 @@ public final class RBuiltinPackages implements RBuiltinLookup { Utils.rSuicide(String.format("unable to open the base package %s", basePathbase)); } // Load the (stub) DLL for base - try { - DLL.loadPackageDLL(baseDirPath.resolve("libs").resolve("base.so").toString(), true, true); - } catch (DLLException ex) { - Utils.rSuicide(ex.getMessage()); - } + String path = baseDirPath.resolve("libs").resolve("base.so").toString(); + Source loadSource = RSource.fromTextInternal(".Internal(dyn.load(" + RRuntime.quoteString(path, false) + ", TRUE, TRUE, \"\"))", RSource.Internal.R_IMPL); + RContext.getEngine().parseAndEval(loadSource, baseFrame, false); + // Any RBuiltinKind.SUBSTITUTE functions installed above should not be overridden try { RContext.getInstance().setLoadingBase(true); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java index 472fdc3f53b299f573acac83050b028769cddef2..14a7bd1687650116a8d7b22ee82b2c5f6fa1de90 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java @@ -23,13 +23,15 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; @@ -61,10 +63,12 @@ public abstract class APerm extends RBuiltinNode { } @Specialization - protected RAbstractVector aPerm(RAbstractVector vector, @SuppressWarnings("unused") RNull permVector, byte resize) { + protected RAbstractVector aPerm(RAbstractVector vector, @SuppressWarnings("unused") RNull permVector, byte resize, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimNode) { checkErrorConditions(vector); - int[] dim = vector.getDimensions(); + int[] dim = getDimsNode.getDimensions(vector); final int diml = dim.length; RVector<?> result = vector.createEmptySameType(vector.getLength(), vector.isComplete()); @@ -74,9 +78,9 @@ public abstract class APerm extends RBuiltinNode { for (int i = 0; i < diml; i++) { pDim[i] = dim[diml - 1 - i]; } - result.setDimensions(pDim); + setDimNode.setDimensions(result, pDim); } else { - result.setDimensions(dim); + setDimNode.setDimensions(result, dim); } // Move along the old array using stride @@ -101,10 +105,12 @@ public abstract class APerm extends RBuiltinNode { } @Specialization - protected RAbstractVector aPerm(RAbstractVector vector, RAbstractIntVector permVector, byte resize) { + protected RAbstractVector aPerm(RAbstractVector vector, RAbstractIntVector permVector, byte resize, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode) { checkErrorConditions(vector); - int[] dim = vector.getDimensions(); + int[] dim = getDimsNode.getDimensions(vector); int[] perm = getPermute(dim, permVector); int[] posV = new int[dim.length]; @@ -112,7 +118,7 @@ public abstract class APerm extends RBuiltinNode { RVector<?> result = vector.createEmptySameType(vector.getLength(), vector.isComplete()); - result.setDimensions(resize == RRuntime.LOGICAL_TRUE ? pDim : dim); + setDimsNode.setDimensions(result, resize == RRuntime.LOGICAL_TRUE ? pDim : dim); // Move along the old array using stride for (int i = 0; i < result.getLength(); i++) { @@ -126,8 +132,10 @@ public abstract class APerm extends RBuiltinNode { @Specialization protected RAbstractVector aPerm(RAbstractVector vector, RAbstractStringVector permVector, byte resize, - @Cached("create()") RAttributeProfiles dimNamesProfile) { - RList dimNames = vector.getDimNames(dimNamesProfile); + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) { + RList dimNames = getDimNamesNode.getDimNames(vector); if (dimNames == null) { // TODO: this error is reported after IS_OF_WRONG_LENGTH in GnuR errorProfile.enter(); @@ -146,7 +154,7 @@ public abstract class APerm extends RBuiltinNode { } // Note: if this turns out to be slow, we can cache the permutation - return aPerm(vector, RDataFactory.createIntVector(perm, true), resize); + return aPerm(vector, RDataFactory.createIntVector(perm, true), resize, getDimsNode, setDimsNode); } private static int[] getReverse(int[] dim) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abbrev.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abbrev.java index 7f4e8cce164aac257f239c20c70fec86743ec20c..66b265248d07db9cba90963185681d91f64c38a3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abbrev.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Abbrev.java @@ -11,7 +11,8 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; @@ -20,7 +21,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; @@ -29,7 +29,6 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; @RBuiltin(name = "abbreviate", kind = INTERNAL, parameterNames = {"x", "minlength", "use.classes"}, behavior = PURE) public abstract class Abbrev extends RBuiltinNode { private final NACheck naCheck = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Override public void createCasts(CastBuilder casts) { @@ -56,7 +55,7 @@ public abstract class Abbrev extends RBuiltinNode { } } RStringVector result = RDataFactory.createStringVector(data, naCheck.neverSeenNA()); - result.copyAttributesFrom(attrProfiles, x); + result.copyAttributesFrom(x); return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AnyNA.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AnyNA.java index 6a9b1e8f907831b7e9dda078125f62727709a886..57c48da529aacc0ff7572c242cf1506658bf41fb 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AnyNA.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AnyNA.java @@ -54,20 +54,6 @@ public abstract class AnyNA extends RBuiltinNode { private final NACheck naCheck = NACheck.create(); - private final boolean recursionAllowed; - - protected AnyNA(boolean recursionAllowed) { - this.recursionAllowed = recursionAllowed; - } - - protected AnyNA() { - this(true); - } - - protected boolean isRecursionAllowed() { - return recursionAllowed; - } - public abstract byte execute(VirtualFrame frame, Object value, boolean recursive); @Override @@ -161,13 +147,13 @@ public abstract class AnyNA extends RBuiltinNode { return doScalar(false); } - protected AnyNA createRecursive(boolean recursive) { - return AnyNANodeGen.create(recursive); + protected AnyNA createRecursive() { + return AnyNANodeGen.create(); } - @Specialization(guards = "isRecursionAllowed()") + @Specialization(guards = "recursive") protected byte isNA(VirtualFrame frame, RList list, boolean recursive, - @Cached("createRecursive(recursive)") AnyNA recursiveNode, + @Cached("createRecursive()") AnyNA recursiveNode, @Cached("createClassProfile()") ValueProfile elementProfile, @Cached("create()") RLengthNode length) { @@ -183,7 +169,7 @@ public abstract class AnyNA extends RBuiltinNode { return RRuntime.LOGICAL_FALSE; } - @Specialization(guards = "!isRecursionAllowed()") + @Specialization(guards = "!recursive") @SuppressWarnings("unused") protected byte isNA(VirtualFrame frame, RList list, boolean recursive) { return RRuntime.LOGICAL_FALSE; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java index 446875d8fee0449ccf2df866acde5d3cd2edcc2c..cb65b88f22320b3eb45e95941ebca3477833382b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java @@ -30,13 +30,13 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; @@ -50,7 +50,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; public abstract class AsCall extends RBuiltinNode { private final ConditionProfile nullNamesProfile = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Specialization protected RLanguage asCallFunction(RList x) { @@ -89,12 +89,12 @@ public abstract class AsCall extends RBuiltinNode { values[i] = x.getDataAtAsObject(i + 1); } ArgumentsSignature signature; - if (nullNamesProfile.profile(x.getNames(attrProfiles) == null)) { + if (nullNamesProfile.profile(getNamesNode.getNames(x) == null)) { signature = ArgumentsSignature.empty(values.length); } else { String[] names = new String[length]; // extract names, converting "" to null - RStringVector ns = x.getNames(attrProfiles); + RStringVector ns = getNamesNode.getNames(x); for (int i = 0; i < length; i++) { String name = ns.getDataAt(i + 1); if (name != null && !name.isEmpty()) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacterFactor.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacterFactor.java index 1db6100ba110523fc7cfe097d94b81480a216580..aa4fa4aae80e4c3c73d4609f7965677c5bfb9d74 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacterFactor.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacterFactor.java @@ -25,8 +25,9 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import com.oracle.truffle.api.dsl.Specialization; - import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; + +import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNode; import com.oracle.truffle.r.nodes.unary.InheritsNode; @@ -47,6 +48,7 @@ public abstract class AsCharacterFactor extends RBuiltinNode { @Child InheritsNode inheritsNode = InheritsNodeGen.create(); @Child CastToVectorNode castToVectorNode = CastToVectorNode.create(); + @Child private GetFixedAttributeNode getLevelsAttrNode = GetFixedAttributeNode.create(RRuntime.LEVELS_ATTR_KEY); @Specialization protected RStringVector doAsCharacterFactor(Object x) { @@ -57,7 +59,7 @@ public abstract class AsCharacterFactor extends RBuiltinNode { RIntVector xVec = (RIntVector) x; int n = xVec.getLength(); String[] data = new String[n]; - Object levsAttr = xVec.getAttr(RRuntime.LEVELS_ATTR_KEY); + Object levsAttr = getLevelsAttrNode.execute(xVec); Object levs; if (levsAttr == null || !((levs = castToVectorNode.execute(levsAttr)) instanceof RAbstractStringVector)) { throw RError.error(RError.SHOW_CALLER, RError.Message.MALFORMED_FACTOR); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java index c9e2d6aaf5be2238ac970c9e394ab5d1354f4615..10853a996c8aee8f4c672122aeb90f4cee0f4ebd 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attr.java @@ -31,14 +31,15 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; 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.object.DynamicObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode; import com.oracle.truffle.r.nodes.attributes.GetAttributeNode; import com.oracle.truffle.r.nodes.attributes.IterableAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetRowNamesAttributeNode; import com.oracle.truffle.r.nodes.attributes.UpdateSharedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; @@ -62,7 +63,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; public abstract class Attr extends RBuiltinNode { private final ConditionProfile searchPartialProfile = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile errorProfile = BranchProfile.create(); @CompilationFinal private String cachedName = ""; @@ -146,13 +146,14 @@ public abstract class Attr extends RBuiltinNode { } @Specialization(guards = "isRowNamesAttr(name)") - protected Object attrRowNames(RAbstractContainer container, @SuppressWarnings("unused") String name, @SuppressWarnings("unused") boolean exact) { + protected Object attrRowNames(RAbstractContainer container, @SuppressWarnings("unused") String name, @SuppressWarnings("unused") boolean exact, + @Cached("create()") GetRowNamesAttributeNode getRowNamesNode) { // TODO: if exact == false, check for partial match (there is an ignored tests for it) DynamicObject attributes = container.getAttributes(); if (attributes == null) { return RNull.instance; } else { - return getFullRowNames(container.getRowNames(attrProfiles)); + return getFullRowNames(getRowNamesNode.getRowNames(container)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java index d5579cf6151b85e0587b23fa51245d3452b81101..41a244f231512aea273734c48b29acbdf8bb28d7 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Attributes.java @@ -35,6 +35,7 @@ import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; @@ -53,6 +54,7 @@ public abstract class Attributes extends RBuiltinNode { private final BranchProfile rownamesBranch = BranchProfile.create(); @Child private ArrayAttributeNode arrayAttrAccess = ArrayAttributeNode.create(); + @Child private SetNamesAttributeNode setNamesNode = SetNamesAttributeNode.create(); @Specialization protected Object attributesNull(RAbstractContainer container, // @@ -117,11 +119,11 @@ public abstract class Attributes extends RBuiltinNode { } } RList result = RDataFactory.createList(values); - result.setNames(RDataFactory.createStringVector(names, true)); + setNamesNode.setNames(result, RDataFactory.createStringVector(names, true)); return result; } private static boolean hasAttributes(RAttributable attributable) { - return attributable.getAttributes() != null && attributable.getAttributes().size() > 0; + return attributable.getAttributes() != null && !attributable.getAttributes().isEmpty(); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseGammaFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseGammaFunctions.java index effc12dc4a140b4275b8d7822ef084206ac59b97..5b82397a22c02c2e4d0295b89b3b570970691762 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseGammaFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BaseGammaFunctions.java @@ -12,13 +12,13 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.library.stats.StatsUtil.DBLEPSILON; -import static com.oracle.truffle.r.library.stats.StatsUtil.DBL_MANT_DIG; -import static com.oracle.truffle.r.library.stats.StatsUtil.DBL_MAX_EXP; -import static com.oracle.truffle.r.library.stats.StatsUtil.DBL_MIN_EXP; -import static com.oracle.truffle.r.library.stats.StatsUtil.M_LOG10_2; -import static com.oracle.truffle.r.library.stats.StatsUtil.M_PI; -import static com.oracle.truffle.r.library.stats.StatsUtil.fmax2; +import static com.oracle.truffle.r.library.stats.MathConstants.DBL_EPSILON; +import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MANT_DIG; +import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MAX_EXP; +import static com.oracle.truffle.r.library.stats.MathConstants.DBL_MIN_EXP; +import static com.oracle.truffle.r.library.stats.MathConstants.M_LOG10_2; +import static com.oracle.truffle.r.library.stats.MathConstants.M_PI; +import static com.oracle.truffle.r.library.stats.RMath.fmax2; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.complexValue; import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.numericValue; import static com.oracle.truffle.r.runtime.RDispatch.MATH_GROUP_GENERIC; @@ -300,7 +300,7 @@ public class BaseGammaFunctions { // mVal.nz = 0; xln = Math.log(x); if (kode == 1 /* && m == 1 */) { /* the R case --- for very large x: */ - double lrg = 1 / (2. * DBLEPSILON); + double lrg = 1 / (2. * DBL_EPSILON); if (n == 0 && x * xln > lrg) { // ans[0] = -xln; ans = -xln; @@ -316,7 +316,7 @@ public class BaseGammaFunctions { nx = Math.min(-DBL_MIN_EXP, DBL_MAX_EXP); assert (nx == 1021); r1m5 = M_LOG10_2; // Rf_d1mach(5); - r1m4 = DBLEPSILON * 0.5; // Rf_d1mach(4) * 0.5; + r1m4 = DBL_EPSILON * 0.5; // Rf_d1mach(4) * 0.5; wdtol = fmax2(r1m4, 0.5e-18); /* 1.11e-16 */ /* elim = approximate exponential over and underflow limit */ diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java index ce52a7a9c44a63aee2d0e792ec0f4c0203c7665b..c1ccfdd06e08dda7ca09700f1f77d790a2c239fd 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/BasePackage.java @@ -42,10 +42,10 @@ import com.oracle.truffle.r.nodes.builtin.base.fastpaths.MatrixFastPathNodeGen; import com.oracle.truffle.r.nodes.builtin.base.fastpaths.SetDiffFastPathNodeGen; import com.oracle.truffle.r.nodes.builtin.base.fastpaths.VectorFastPathsFactory.DoubleFastPathNodeGen; import com.oracle.truffle.r.nodes.builtin.base.fastpaths.VectorFastPathsFactory.IntegerFastPathNodeGen; -import com.oracle.truffle.r.nodes.builtin.base.foreign.DotC; -import com.oracle.truffle.r.nodes.builtin.base.foreign.DotCNodeGen; -import com.oracle.truffle.r.nodes.builtin.base.foreign.ForeignFunctions; -import com.oracle.truffle.r.nodes.builtin.base.foreign.ForeignFunctionsFactory; +import com.oracle.truffle.r.nodes.builtin.base.foreign.CallAndExternalFunctions; +import com.oracle.truffle.r.nodes.builtin.base.foreign.CallAndExternalFunctionsFactory; +import com.oracle.truffle.r.nodes.builtin.base.foreign.FortranAndCFunctions; +import com.oracle.truffle.r.nodes.builtin.base.foreign.FortranAndCFunctionsFactory; import com.oracle.truffle.r.nodes.builtin.base.infix.AccessField; import com.oracle.truffle.r.nodes.builtin.base.infix.AccessFieldNodeGen; import com.oracle.truffle.r.nodes.builtin.base.infix.AssignBuiltin; @@ -221,6 +221,11 @@ public class BasePackage extends RBuiltinPackage { add(BrowserFunctions.BrowserSetDebug.class, BrowserFunctionsFactory.BrowserSetDebugNodeGen::create); add(BrowserFunctions.BrowserText.class, BrowserFunctionsFactory.BrowserTextNodeGen::create); add(Call.class, CallNodeGen::create); + add(CallAndExternalFunctions.DotCall.class, CallAndExternalFunctionsFactory.DotCallNodeGen::create); + add(CallAndExternalFunctions.DotCallGraphics.class, CallAndExternalFunctionsFactory.DotCallGraphicsNodeGen::create); + add(CallAndExternalFunctions.DotExternal.class, CallAndExternalFunctionsFactory.DotExternalNodeGen::create); + add(CallAndExternalFunctions.DotExternal2.class, CallAndExternalFunctionsFactory.DotExternal2NodeGen::create); + add(CallAndExternalFunctions.DotExternalGraphics.class, CallAndExternalFunctionsFactory.DotExternalGraphicsNodeGen::create); add(Capabilities.class, CapabilitiesNodeGen::create); add(Cat.class, CatNodeGen::create); add(Ceiling.class, CeilingNodeGen::create); @@ -391,17 +396,12 @@ public class BasePackage extends RBuiltinPackage { add(FileFunctions.ListDirs.class, FileFunctionsFactory.ListDirsNodeGen::create); add(FileFunctions.Unlink.class, FileFunctionsFactory.UnlinkNodeGen::create); add(Floor.class, FloorNodeGen::create); - add(DotC.class, DotCNodeGen::create); add(ForceAndCall.class, ForceAndCallNodeGen::create); - add(ForeignFunctions.DotCall.class, ForeignFunctionsFactory.DotCallNodeGen::create); - add(ForeignFunctions.DotCallGraphics.class, ForeignFunctionsFactory.DotCallGraphicsNodeGen::create); - add(ForeignFunctions.DotExternal.class, ForeignFunctionsFactory.DotExternalNodeGen::create); - add(ForeignFunctions.DotExternal2.class, ForeignFunctionsFactory.DotExternal2NodeGen::create); - add(ForeignFunctions.DotExternalGraphics.class, ForeignFunctionsFactory.DotExternalGraphicsNodeGen::create); - add(ForeignFunctions.Fortran.class, ForeignFunctionsFactory.FortranNodeGen::create); add(Formals.class, FormalsNodeGen::create); add(Format.class, FormatNodeGen::create); add(FormatC.class, FormatCNodeGen::create); + add(FortranAndCFunctions.DotC.class, FortranAndCFunctionsFactory.DotCNodeGen::create); + add(FortranAndCFunctions.Fortran.class, FortranAndCFunctionsFactory.FortranNodeGen::create); add(FrameFunctions.MatchCall.class, FrameFunctionsFactory.MatchCallNodeGen::create); add(FrameFunctions.ParentFrame.class, FrameFunctionsFactory.ParentFrameNodeGen::create); add(FrameFunctions.SysCall.class, FrameFunctionsFactory.SysCallNodeGen::create); @@ -511,6 +511,7 @@ public class BasePackage extends RBuiltinPackage { add(MatMult.class, MatMult::create); add(Match.class, MatchNodeGen::create); add(MatchFun.class, MatchFunNodeGen::create); + add(MatchArg.class, MatchArgNodeGen::create); add(Matrix.class, MatrixNodeGen::create); add(Max.class, MaxNodeGen::create); add(Mean.class, MeanNodeGen::create); @@ -556,6 +557,7 @@ public class BasePackage extends RBuiltinPackage { add(RawFunctions.CharToRaw.class, RawFunctionsFactory.CharToRawNodeGen::create); add(RawFunctions.RawToChar.class, RawFunctionsFactory.RawToCharNodeGen::create); add(RawFunctions.RawShift.class, RawFunctionsFactory.RawShiftNodeGen::create); + add(RawToBits.class, RawToBitsNodeGen::create); add(NumericalFunctions.Re.class, NumericalFunctionsFactory.ReNodeGen::create); add(ReadDCF.class, ReadDCFNodeGen::create); add(ReadREnviron.class, ReadREnvironNodeGen::create); @@ -749,7 +751,7 @@ public class BasePackage extends RBuiltinPackage { addFastPath(baseFrame, "cbind", FastPathFactory.FORCED_EAGER_ARGS); addFastPath(baseFrame, "rbind", FastPathFactory.FORCED_EAGER_ARGS); - setContainsDispatch(baseFrame, "sys.function", "match.arg", "eval", "[.data.frame", "[[.data.frame", "[<-.data.frame", "[[<-.data.frame"); + setContainsDispatch(baseFrame, "sys.function", "eval", "[.data.frame", "[[.data.frame", "[<-.data.frame", "[[<-.data.frame"); } private static void setContainsDispatch(MaterializedFrame baseFrame, String... functions) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java index 8fc0691a76e82d5d36fbb142623805bb51e7f335..0a95c508e5ae397f7717df4e96528108cb1d0c27 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java @@ -36,6 +36,11 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.RASTUtils; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode; @@ -61,7 +66,6 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; @@ -95,6 +99,7 @@ public abstract class Bind extends RBaseNode { @Child private CastToVectorNode castVector; @Child private UseMethodInternalNode dcn; @Child private CastLogicalNode castLogical; + @Child private GetDimAttributeNode getDimsNode; private final BindType type; @@ -103,7 +108,6 @@ public abstract class Bind extends RBaseNode { private final ConditionProfile allEmptyVectorProfile = ConditionProfile.createBinaryProfile(); private final BranchProfile nonNullNames = BranchProfile.create(); private final NACheck naCheck = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); protected final ValueProfile resultProfile = ValueProfile.createClassProfile(); protected final ValueProfile vectorProfile = ValueProfile.createClassProfile(); @@ -122,6 +126,14 @@ public abstract class Bind extends RBaseNode { this.type = type; } + protected int[] getVectorDimensions(RAbstractVector v) { + if (getDimsNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimsNode = insert(GetDimAttributeNode.create()); + } + return getDimsNode.getDimensions(v); + } + protected RAbstractVector castVector(Object value) { if (castVector == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -161,7 +173,8 @@ public abstract class Bind extends RBaseNode { } } - private Object bindInternal(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, CastNode castNode, boolean needsVectorCast) { + private Object bindInternal(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, CastNode castNode, boolean needsVectorCast, SetDimAttributeNode setDimNode, + SetDimNamesAttributeNode setDimNamesNode, GetDimNamesAttributeNode getDimNamesNode, GetNamesAttributeNode getNamesNode) { ArgumentsSignature signature = promiseArgs.getSignature(); String[] vecNames = nullNamesProfile.profile(signature.getNonNullCount() == 0) ? null : new String[signature.getLength()]; RAbstractVector[] vectors = new RAbstractVector[args.length]; @@ -217,46 +230,70 @@ public abstract class Bind extends RBaseNode { } } if (type == BindType.cbind) { - return genericCBind(promiseArgs, vectors, complete, vecNames, naCheck.neverSeenNA(), deparseLevel); + return genericCBind(promiseArgs, vectors, complete, vecNames, naCheck.neverSeenNA(), deparseLevel, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } else { - return genericRBind(promiseArgs, vectors, complete, vecNames, naCheck.neverSeenNA(), deparseLevel); + return genericRBind(promiseArgs, vectors, complete, vecNames, naCheck.neverSeenNA(), deparseLevel, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } } @Specialization(guards = {"precedence == LOGICAL_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"}) protected Object allLogical(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastLogicalNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, true); + @Cached("create()") CastLogicalNode cast, + @Cached("create()") SetDimAttributeNode setDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } @Specialization(guards = {"precedence == INT_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"}) protected Object allInt(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastIntegerNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, true); + @Cached("create()") CastIntegerNode cast, + @Cached("create()") SetDimAttributeNode setDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } @Specialization(guards = {"precedence == DOUBLE_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"}) protected Object allDouble(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastDoubleNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, true); + @Cached("create()") CastDoubleNode cast, + @Cached("create()") SetDimAttributeNode setDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } @Specialization(guards = {"precedence == STRING_PRECEDENCE", "args.length> 1", "!isDataFrame(args)"}) protected Object allString(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastStringNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, true); + @Cached("create()") CastStringNode cast, + @Cached("create()") SetDimAttributeNode setDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } @Specialization(guards = {"precedence == COMPLEX_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"}) protected Object allComplex(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastComplexNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, true); + @Cached("create()") CastComplexNode cast, + @Cached("create()") SetDimAttributeNode setDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, true, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } @Specialization(guards = {"precedence == LIST_PRECEDENCE", "args.length > 1", "!isDataFrame(args)"}) protected Object allList(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, // - @Cached("create()") CastListNode cast) { - return bindInternal(deparseLevel, args, promiseArgs, cast, false); + @Cached("create()") CastListNode cast, + @Cached("create()") SetDimAttributeNode setDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return bindInternal(deparseLevel, args, promiseArgs, cast, false, setDimNode, setDimNamesNode, getDimNamesNode, getNamesNode); } /** @@ -267,16 +304,16 @@ public abstract class Bind extends RBaseNode { * @param dimLength * @return dimnames */ - protected Object getDimResultNamesFromElements(RAbstractVector vec, int dimLength, int dimInd) { + protected Object getDimResultNamesFromElements(RAbstractVector vec, int dimLength, int dimInd, GetDimNamesAttributeNode getDimNamesNode, GetNamesAttributeNode getNamesNode) { Object firstDimResultNames = RNull.instance; Object firstDimNames = RNull.instance; if (vec.isMatrix()) { - RList vecDimNames = vec.getDimNames(attrProfiles); + RList vecDimNames = getDimNamesNode.getDimNames(vec); if (vecDimNames != null) { firstDimNames = vecDimNames.getDataAt(dimInd); } - } else if (!vec.isArray() || vec.getDimensions().length == 1) { - RStringVector names = vec.getNames(attrProfiles); + } else if (!vec.isArray() || getVectorDimensions(vec).length == 1) { + RStringVector names = getNamesNode.getNames(vec); firstDimNames = names == null ? RNull.instance : names; } else { RInternalError.unimplemented("binding multi-dimensional arrays is not supported"); @@ -295,11 +332,10 @@ public abstract class Bind extends RBaseNode { * by deparsing. */ protected int getDimResultNamesFromVectors(RArgsValuesAndNames promiseArgs, RAbstractVector vec, String[] argNames, int resDim, int oldInd, int vecInd, int deparseLevel, - String[] dimNamesArray, - int dimNamesInd) { + String[] dimNamesArray, int dimNamesInd, GetDimNamesAttributeNode getDimNamesNode) { int ind = oldInd; if (vec.isMatrix()) { - RList vecDimNames = vec.getDimNames(attrProfiles); + RList vecDimNames = getDimNamesNode.getDimNames(vec); if (vecDimNames != null) { Object resDimNames = vecDimNames.getDataAt(dimNamesInd); if (resDimNames != RNull.instance) { @@ -319,7 +355,7 @@ public abstract class Bind extends RBaseNode { dimNamesArray[ind++] = RRuntime.NAMES_ATTR_EMPTY_VALUE; } return -ind; - } else if (!vec.isArray() || vec.getDimensions().length == 1) { + } else if (!vec.isArray() || getVectorDimensions(vec).length == 1) { if (argNames == null) { if (deparseLevel == 0) { dimNamesArray[ind++] = RRuntime.NAMES_ATTR_EMPTY_VALUE; @@ -377,9 +413,10 @@ public abstract class Bind extends RBaseNode { } protected int[] getDimensions(RAbstractVector vector) { - int[] dimensions = vector.getDimensions(); + RAbstractVector vectorProfiled = vectorProfile.profile(vector); + int[] dimensions = getVectorDimensions(vectorProfiled); if (dimensions == null || dimensions.length != 2) { - return type == BindType.cbind ? new int[]{vector.getLength(), 1} : new int[]{1, vector.getLength()}; + return type == BindType.cbind ? new int[]{vectorProfiled.getLength(), 1} : new int[]{1, vectorProfiled.getLength()}; } else { assert dimensions.length == 2; return dimensions; @@ -444,7 +481,9 @@ public abstract class Bind extends RBaseNode { private final BranchProfile everSeenNotEqualColumns = BranchProfile.create(); @Specialization(guards = {"precedence != NO_PRECEDENCE", "args.length == 1"}) - protected Object allOneElem(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence) { + protected Object allOneElem(int deparseLevel, Object[] args, RArgsValuesAndNames promiseArgs, @SuppressWarnings("unused") int precedence, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { RAbstractVector vec = castVector(args[0]); if (vec.isMatrix()) { return vec; @@ -452,7 +491,10 @@ public abstract class Bind extends RBaseNode { int[] dims = getDimensions(vec); // for cbind dimNamesA is names for the 1st dim and dimNamesB is names for 2nd dim; for // rbind the other way around - Object dimNamesA = vec.getNames(attrProfiles) == null ? RNull.instance : vec.getNames(attrProfiles); + Object dimNamesA = getNamesNode.getNames(vec); + if (dimNamesA == null) { + dimNamesA = RNull.instance; + } Object dimNamesB; ArgumentsSignature signature = promiseArgs.getSignature(); @@ -473,17 +515,19 @@ public abstract class Bind extends RBaseNode { } RVector<?> res = (RVector<?>) vec.copyWithNewDimensions(dims); - res.setDimNames(RDataFactory.createList(type == BindType.cbind ? new Object[]{dimNamesA, dimNamesB} : new Object[]{dimNamesB, dimNamesA})); + setDimNamesNode.execute(res, RDataFactory.createList(type == BindType.cbind ? new Object[]{dimNamesA, dimNamesB} : new Object[]{dimNamesB, dimNamesA})); res.copyRegAttributesFrom(vec); return res; } - public RVector<?> genericCBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel) { + public RVector<?> genericCBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel, + SetDimAttributeNode setDimNode, SetDimNamesAttributeNode setDimNamesNode, GetDimNamesAttributeNode getDimNamesNode, GetNamesAttributeNode getNamesNode) { int[] resultDimensions = new int[2]; int[] secondDims = new int[vectors.length]; boolean notEqualRows = getResultDimensions(vectors, resultDimensions, secondDims); - RVector<?> result = resultProfile.profile(vectors[0].createEmptySameType(resultDimensions[0] * resultDimensions[1], complete)); + RAbstractVector first = vectorProfile.profile(vectors[0]); + RVector<?> result = resultProfile.profile(first.createEmptySameType(resultDimensions[0] * resultDimensions[1], complete)); int ind = 0; Object rowDimResultNames = RNull.instance; @@ -494,11 +538,11 @@ public abstract class Bind extends RBaseNode { RAbstractVector vec = vectorProfile.profile(vectors[i]); if (rowDimResultNames == RNull.instance) { // get the first valid names value - rowDimResultNames = getDimResultNamesFromElements(vec, resultDimensions[0], 0); + rowDimResultNames = getDimResultNamesFromElements(vec, resultDimensions[0], 0, getDimNamesNode, getNamesNode); } // compute dimnames for the second dimension - int newColInd = getDimResultNamesFromVectors(promiseArgs, vec, vecNames, secondDims[i], colInd, i, deparseLevel, colDimNamesArray, 1); + int newColInd = getDimResultNamesFromVectors(promiseArgs, vec, vecNames, secondDims[i], colInd, i, deparseLevel, colDimNamesArray, 1, getDimNamesNode); if (newColInd < 0) { colInd = -newColInd; } else { @@ -528,8 +572,8 @@ public abstract class Bind extends RBaseNode { } Object colDimResultNames = allColDimNamesNull ? RNull.instance : RDataFactory.createStringVector(colDimNamesArray, vecNamesComplete); - result.setDimensions(resultDimensions); - result.setDimNames(RDataFactory.createList(new Object[]{rowDimResultNames, colDimResultNames})); + setDimNode.setDimensions(result, resultDimensions); + setDimNamesNode.setDimNames(result, RDataFactory.createList(new Object[]{rowDimResultNames, colDimResultNames})); return result; } @@ -558,7 +602,8 @@ public abstract class Bind extends RBaseNode { } } - public RVector<?> genericRBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel) { + public RVector<?> genericRBind(RArgsValuesAndNames promiseArgs, RAbstractVector[] vectors, boolean complete, String[] vecNames, boolean vecNamesComplete, int deparseLevel, + SetDimAttributeNode setDimNode, SetDimNamesAttributeNode setDimNamesNode, GetDimNamesAttributeNode getDimNamesNode, GetNamesAttributeNode getNamesNode) { int[] resultDimensions = new int[2]; int[] firstDims = new int[vectors.length]; @@ -574,11 +619,11 @@ public abstract class Bind extends RBaseNode { RAbstractVector vec = vectorProfile.profile(vectors[i]); if (colDimResultNames == RNull.instance) { // get the first valid names value - colDimResultNames = getDimResultNamesFromElements(vec, resultDimensions[1], 1); + colDimResultNames = getDimResultNamesFromElements(vec, resultDimensions[1], 1, getDimNamesNode, getNamesNode); } // compute dimnames for the second dimension - int newRowInd = getDimResultNamesFromVectors(promiseArgs, vec, vecNames, firstDims[i], rowInd, i, deparseLevel, rowDimNamesArray, 0); + int newRowInd = getDimResultNamesFromVectors(promiseArgs, vec, vecNames, firstDims[i], rowInd, i, deparseLevel, rowDimNamesArray, 0, getDimNamesNode); if (newRowInd < 0) { rowInd = -newRowInd; } else { @@ -613,8 +658,8 @@ public abstract class Bind extends RBaseNode { } Object rowDimResultNames = allRowDimNamesNull ? RNull.instance : RDataFactory.createStringVector(rowDimNamesArray, vecNamesComplete); - result.setDimensions(resultDimensions); - result.setDimNames(RDataFactory.createList(new Object[]{rowDimResultNames, colDimResultNames})); + setDimNode.setDimensions(result, resultDimensions); + setDimNamesNode.setDimNames(result, RDataFactory.createList(new Object[]{rowDimResultNames, colDimResultNames})); return result; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java index 431cc73c7dddd20f1860c4fa3b9c862136391f6c..99f09dcce3d563e95b0a3292e91bb7de0395d97e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java @@ -47,7 +47,8 @@ import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; -import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.CombineNodeGen.CombineInputCastNodeGen; @@ -96,7 +97,6 @@ public abstract class Combine extends RBuiltinNode { @Child private CombineInputCast inputCast = CombineInputCastNodeGen.create(null); @Child private CastToVectorNode castVector; - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile naBranch = BranchProfile.create(); private final NACheck naCheck = NACheck.create(); private final ConditionProfile fastNamesMerge = ConditionProfile.createBinaryProfile(); @@ -127,7 +127,8 @@ public abstract class Combine extends RBuiltinNode { @Cached("createCast(cachedPrecedence)") CastNode cast, // @Cached("create()") BranchProfile naNameBranch, // @Cached("create()") NACheck naNameCheck, // - @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile) { + @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile, + @Cached("create()") GetNamesAttributeNode getNamesNode) { CompilerAsserts.partialEvaluationConstant(cachedSignature); CompilerAsserts.partialEvaluationConstant(cachedPrecedence); @@ -142,7 +143,8 @@ public abstract class Combine extends RBuiltinNode { // prepare the names (if there are any) boolean signatureHasNames = signatureHasNames(cachedSignature); CompilerAsserts.partialEvaluationConstant(signatureHasNames); - RStringVector namesVector = hasNamesProfile.profile(signatureHasNames || hasNames(elements)) ? foldNames(naNameBranch, naNameCheck, elements, size, cachedSignature) : null; + RStringVector namesVector = hasNamesProfile.profile(signatureHasNames || hasNames(elements, getNamesNode)) ? foldNames(naNameBranch, naNameCheck, elements, size, cachedSignature, getNamesNode) + : null; // get the actual contents of the result RVector<?> result = foldContents(cachedPrecedence, elements, size, namesVector); @@ -159,8 +161,9 @@ public abstract class Combine extends RBuiltinNode { @Cached("createCast(cachedPrecedence)") CastNode cast, // @Cached("create()") BranchProfile naNameBranch, // @Cached("create()") NACheck naNameCheck, // - @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile) { - return combineCached(args, false, args.getSignature(), cachedPrecedence, cast, naNameBranch, naNameCheck, hasNamesProfile); + @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile, + @Cached("create()") GetNamesAttributeNode getNamesNode) { + return combineCached(args, false, args.getSignature(), cachedPrecedence, cast, naNameBranch, naNameCheck, hasNamesProfile, getNamesNode); } @Specialization(guards = "recursive") @@ -226,7 +229,7 @@ public abstract class Combine extends RBuiltinNode { } @ExplodeLoop - private boolean hasNames(Object[] elements) { + private boolean hasNames(Object[] elements, GetNamesAttributeNode getNamesNode) { for (int i = 0; i < elements.length; i++) { Object element = elements[i]; if (i < argProfiles.length) { @@ -234,7 +237,7 @@ public abstract class Combine extends RBuiltinNode { } if (element instanceof RAbstractVector) { RAbstractVector vector = (RAbstractVector) element; - if (vector.getNames(attrProfiles) != null) { + if (getNamesNode.getNames(vector) != null) { return true; } } @@ -243,7 +246,7 @@ public abstract class Combine extends RBuiltinNode { } @ExplodeLoop - private RStringVector foldNames(BranchProfile naNameBranch, NACheck naNameCheck, Object[] elements, int size, ArgumentsSignature signature) { + private RStringVector foldNames(BranchProfile naNameBranch, NACheck naNameCheck, Object[] elements, int size, ArgumentsSignature signature, GetNamesAttributeNode getNamesNode) { RStringVector result = RDataFactory.createStringVector(new String[size], true); result.incRefCount(); int pos = 0; @@ -252,18 +255,19 @@ public abstract class Combine extends RBuiltinNode { if (i < argProfiles.length) { element = argProfiles[i].profile(element); } - pos += processNamesElement(naNameBranch, naNameCheck, result, pos, element, i, signature); + pos += processNamesElement(naNameBranch, naNameCheck, result, pos, element, i, signature, getNamesNode); } return result; } - private int processNamesElement(BranchProfile naNameBranch, NACheck naNameCheck, RStringVector result, int pos, Object element, int index, ArgumentsSignature signature) { + private int processNamesElement(BranchProfile naNameBranch, NACheck naNameCheck, RStringVector result, int pos, Object element, int index, ArgumentsSignature signature, + GetNamesAttributeNode getNamesNode) { String signatureName = signature.getName(index); if (element instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) element; int length = v.getLength(); - RStringVector newNames = v.getNames(attrProfiles); + RStringVector newNames = getNamesNode.getNames(v); if (signatureName != null && length > 0) { if (fastNamesMerge.profile(length == 1 && newNames == null)) { newNames = RDataFactory.createStringVector(new String[]{signatureName}, true); @@ -455,6 +459,8 @@ public abstract class Combine extends RBuiltinNode { protected abstract static class CombineInputCast extends RNode { private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); public abstract Object execute(Object operand); @@ -474,15 +480,13 @@ public abstract class Combine extends RBuiltinNode { RVector<?> materialized = vector.materialize(); RVector<?> result = materialized.copyDropAttributes(); - RStringVector vecNames = materialized.getInternalNames(); + RStringVector vecNames = getNamesNode.getNames(materialized); if (hasNamesProfile.profile(vecNames != null)) { result.initAttributes(RAttributesLayout.createNames(vecNames)); - result.setInternalNames(vecNames); } else { - RList dimNames = materialized.getInternalDimNames(); + RList dimNames = getDimNamesNode.getDimNames(materialized); if (hasDimNamesProfile.profile(dimNames != null)) { - result.initAttributes(RAttributesLayout.createDimNames(vecNames)); - result.setInternalDimNames(dimNames); + result.initAttributes(RAttributesLayout.createDimNames(dimNames)); } } return result; @@ -494,7 +498,7 @@ public abstract class Combine extends RBuiltinNode { } protected boolean needsCopy(RAbstractVector vector) { - return vector.getAttributes() != null || vector.getNames(attrProfiles) != null || vector.getDimNames(attrProfiles) != null; + return vector.getAttributes() != null || getNamesNode.getNames(vector) != null || getDimNamesNode.getDimNames(vector) != null; } } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java index bd91785573149dbf784c85774719cfbb211c6064..491c440ba79dbbd197522d28fb8ce694809b9ff9 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java @@ -29,7 +29,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -37,12 +36,10 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @RBuiltin(name = "copyDFattr", kind = INTERNAL, parameterNames = {"", ""}, behavior = COMPLEX) public abstract class CopyDFAttr extends RBuiltinNode { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - @Specialization() protected RAttributable copy(RAbstractContainer in, RAbstractVector out) { RVector<?> res = out.materialize(); res.resetAllAttributes(false); - return res.copyAttributesFrom(attrProfiles, in); + return res.copyAttributesFrom(in); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java index 3aefffb5f6b5d7a8e3bc4f27c5d4f058c0e13fd1..9c6e521f08bfa375abdeec6ab6003d53c8d06ab0 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java @@ -27,7 +27,11 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -62,21 +66,29 @@ public abstract class Crossprod extends RBuiltinNode { } @Specialization(guards = {"x.isMatrix()", "y.isMatrix()"}) - protected RDoubleVector crossprod(RAbstractDoubleVector x, RAbstractDoubleVector y) { - int xRows = x.getDimensions()[0]; - int xCols = x.getDimensions()[1]; - int yRows = y.getDimensions()[0]; - int yCols = y.getDimensions()[1]; - return matMult.doubleMatrixMultiply(x, y, xCols, xRows, yRows, yCols, xRows, 1, 1, yRows, false); + protected RDoubleVector crossprod(RAbstractDoubleVector x, RAbstractDoubleVector y, + @Cached("create()") GetDimAttributeNode getXDimsNode, + @Cached("create()") GetDimAttributeNode getYDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + int[] xDims = getXDimsNode.getDimensions(x); + int[] yDims = getYDimsNode.getDimensions(y); + int xRows = xDims[0]; + int xCols = xDims[1]; + int yRows = yDims[0]; + int yCols = yDims[1]; + return matMult.doubleMatrixMultiply(x, y, xCols, xRows, yRows, yCols, xRows, 1, 1, yRows, false, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } - private static RDoubleVector mirror(RDoubleVector result) { + private static RDoubleVector mirror(RDoubleVector result, GetDimAttributeNode getResultDimsNode) { /* * Mirroring the result is not only good for performance, but it is also required to produce * the same result as GNUR. */ - assert result.isMatrix() && result.getDimensions()[0] == result.getDimensions()[1]; - int size = result.getDimensions()[0]; + int[] resultDims = getResultDimsNode.getDimensions(result); + assert result.isMatrix() && resultDims[0] == resultDims[1]; + int size = resultDims[0]; double[] data = result.getDataWithoutCopying(); for (int row = 0; row < size; row++) { int destIndex = row * size + row + 1; @@ -96,10 +108,16 @@ public abstract class Crossprod extends RBuiltinNode { } @Specialization(guards = "x.isMatrix()") - protected RDoubleVector crossprodDoubleMatrix(RAbstractDoubleVector x, @SuppressWarnings("unused") RNull y) { - int xRows = x.getDimensions()[0]; - int xCols = x.getDimensions()[1]; - return mirror(matMult.doubleMatrixMultiply(x, x, xCols, xRows, xRows, xCols, xRows, 1, 1, xRows, true)); + protected RDoubleVector crossprodDoubleMatrix(RAbstractDoubleVector x, @SuppressWarnings("unused") RNull y, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") GetDimAttributeNode getResultDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + int[] xDims = getDimsNode.getDimensions(x); + int xRows = xDims[0]; + int xCols = xDims[1]; + return mirror(matMult.doubleMatrixMultiply(x, x, xCols, xRows, xRows, xCols, xRows, 1, 1, xRows, true, setDimNamesNode, getADimNamesNode, getBDimNamesNode), getResultDimsNode); } @Specialization diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java index edf8441b58c47ee9bad392bd698d4bc1c72247d7..58cf95204c494529cf4eaff9eeb2710b2657b99c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMax.java @@ -24,12 +24,12 @@ import java.util.Arrays; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RIntSequence; @@ -43,7 +43,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class CumMax extends RBuiltinNode { private final NACheck na = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Override protected void createCasts(CastBuilder casts) { @@ -96,7 +96,7 @@ public abstract class CumMax extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(cmaxV, i, cmaxV.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createDoubleVector(cmaxV, na.neverSeenNA(), v.getNames(attrProfiles)); + return RDataFactory.createDoubleVector(cmaxV, na.neverSeenNA(), getNamesNode.getNames(v)); } @Specialization(contains = "cummaxIntSequence") @@ -118,7 +118,7 @@ public abstract class CumMax extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(cmaxV, i, cmaxV.length, RRuntime.INT_NA); } - return RDataFactory.createIntVector(cmaxV, na.neverSeenNA(), v.getNames(attrProfiles)); + return RDataFactory.createIntVector(cmaxV, na.neverSeenNA(), getNamesNode.getNames(v)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java index a1da7b792e40c8abb45fa505b7b76c03946a281f..b99ad15b12cf41a05b9bb5278ef605be97215766 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumMin.java @@ -24,12 +24,12 @@ import java.util.Arrays; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RIntSequence; @@ -43,7 +43,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class CumMin extends RBuiltinNode { private final NACheck na = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Override protected void createCasts(CastBuilder casts) { @@ -96,7 +96,7 @@ public abstract class CumMin extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(cminV, i, cminV.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createDoubleVector(cminV, na.neverSeenNA(), v.getNames(attrProfiles)); + return RDataFactory.createDoubleVector(cminV, na.neverSeenNA(), getNamesNode.getNames(v)); } @Specialization(contains = "cumminIntSequence") @@ -118,7 +118,7 @@ public abstract class CumMin extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(cminV, i, cminV.length, RRuntime.INT_NA); } - return RDataFactory.createIntVector(cminV, na.neverSeenNA(), v.getNames(attrProfiles)); + return RDataFactory.createIntVector(cminV, na.neverSeenNA(), getNamesNode.getNames(v)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java index 56cda98a07fd8f9e13be1f2833356ff00be34526..254eaed5fb718f954495b90339e3955362a6ee0e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumProd.java @@ -24,11 +24,11 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import java.util.Arrays; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -45,7 +45,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class CumProd extends RBuiltinNode { private final NACheck na = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Child private BinaryArithmetic mul = BinaryArithmetic.MULTIPLY.createOperation(); @@ -88,7 +88,7 @@ public abstract class CumProd extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(array, i, array.length, RRuntime.INT_NA); } - return RDataFactory.createIntVector(array, !na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createIntVector(array, !na.neverSeenNA(), getNamesNode.getNames(arg)); } @Specialization @@ -110,7 +110,7 @@ public abstract class CumProd extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(array, i, array.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createDoubleVector(array, !na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createDoubleVector(array, !na.neverSeenNA(), getNamesNode.getNames(arg)); } @Specialization @@ -133,6 +133,6 @@ public abstract class CumProd extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(array, 2 * i, array.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createComplexVector(array, !na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createComplexVector(array, !na.neverSeenNA(), getNamesNode.getNames(arg)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java index 06c1be88b75946797245a613f51c0f5a2578668a..3b6074626f3ab1dc0fc1aedf94739337cd75964d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CumSum.java @@ -36,11 +36,11 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import java.util.Arrays; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -58,7 +58,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; public abstract class CumSum extends RBuiltinNode { private final NACheck na = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Child private BinaryArithmetic add = BinaryArithmetic.ADD.createOperation(); @@ -100,7 +100,7 @@ public abstract class CumSum extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(res, i, res.length, RRuntime.INT_NA); } - return RDataFactory.createIntVector(res, na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createIntVector(res, na.neverSeenNA(), getNamesNode.getNames(arg)); } @Specialization @@ -119,7 +119,7 @@ public abstract class CumSum extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(res, i, res.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createDoubleVector(res, na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createDoubleVector(res, na.neverSeenNA(), getNamesNode.getNames(arg)); } @Specialization @@ -141,7 +141,7 @@ public abstract class CumSum extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(res, i, res.length, RRuntime.INT_NA); } - return RDataFactory.createIntVector(res, na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createIntVector(res, na.neverSeenNA(), getNamesNode.getNames(arg)); } @Specialization @@ -161,6 +161,6 @@ public abstract class CumSum extends RBuiltinNode { if (!na.neverSeenNA()) { Arrays.fill(res, 2 * i, res.length, RRuntime.DOUBLE_NA); } - return RDataFactory.createComplexVector(res, na.neverSeenNA(), arg.getNames(attrProfiles)); + return RDataFactory.createComplexVector(res, na.neverSeenNA(), getNamesNode.getNames(arg)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java index c9a3e2826bcf8d325844e894e04922fb2c9f369a..c45cb05324403c8247e900ca5c64b8162defb836 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DatePOSIXFunctions.java @@ -36,7 +36,10 @@ import java.util.HashMap; import java.util.TimeZone; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RInternalError; @@ -137,6 +140,7 @@ public class DatePOSIXFunctions { public abstract static class Date2POSIXlt extends RBuiltinNode { private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Override protected void createCasts(CastBuilder casts) { @@ -161,7 +165,7 @@ public class DatePOSIXFunctions { } } RList result = builder.finish(); - RStringVector xNames = x.getNames(attrProfiles); + RStringVector xNames = getNamesNode.getNames(x); if (xNames != null) { ((RIntVector) result.getDataAt(5)).copyNamesFrom(attrProfiles, x); } @@ -173,6 +177,7 @@ public class DatePOSIXFunctions { public abstract static class AsPOSIXlt extends RBuiltinNode { private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Override protected void createCasts(CastBuilder casts) { @@ -203,7 +208,7 @@ public class DatePOSIXFunctions { } } RList result = builder.finish(); - RStringVector xNames = x.getNames(attrProfiles); + RStringVector xNames = getNamesNode.getNames(x); if (xNames != null) { ((RIntVector) result.getDataAt(5)).copyNamesFrom(attrProfiles, x); } @@ -280,7 +285,8 @@ public class DatePOSIXFunctions { @Specialization @TruffleBoundary - protected RDoubleVector posix2date(RAbstractListVector x) { + protected RDoubleVector posix2date(RAbstractListVector x, + @Cached("create()") SetClassAttributeNode setClassAttrNode) { RAbstractVector secVector = (RAbstractVector) RRuntime.asAbstractVector(x.getDataAt(0)); RAbstractVector minVector = (RAbstractVector) RRuntime.asAbstractVector(x.getDataAt(1)); RAbstractVector hourVector = (RAbstractVector) RRuntime.asAbstractVector(x.getDataAt(2)); @@ -314,7 +320,7 @@ public class DatePOSIXFunctions { } } RDoubleVector result = RDataFactory.createDoubleVector(data, complete); - result.setClassAttr(CLASS_ATTR); + setClassAttrNode.execute(result, CLASS_ATTR); return result; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java index be4d0db5ec9a83264b3daeaf3390b780184ef2eb..95cb519bd8e14fe633c8a23426a03118a603379e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Dim.java @@ -29,6 +29,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -40,9 +41,11 @@ public abstract class Dim extends RBuiltinNode { @Specialization protected Object dim(RAbstractContainer container, // - @Cached("createBinaryProfile()") ConditionProfile hasDimensionsProfile) { - if (hasDimensionsProfile.profile(container.hasDimensions())) { - return RDataFactory.createIntVector(container.getDimensions(), RDataFactory.COMPLETE_VECTOR); + @Cached("createBinaryProfile()") ConditionProfile hasDimensionsProfile, + @Cached("create()") GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(container); + if (hasDimensionsProfile.profile(dims != null && dims.length > 0)) { + return RDataFactory.createIntVector(dims, RDataFactory.COMPLETE_VECTOR); } else { return RNull.instance; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java index 17661779644a7b819009377f238888db6a8a9fde..6953af8262f8466702d2e38fc0a2a5af330a1b52 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java @@ -26,11 +26,12 @@ import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @@ -38,7 +39,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @RBuiltin(name = "dimnames", kind = PRIMITIVE, parameterNames = {"x"}, dispatch = INTERNAL_GENERIC, behavior = PURE) public abstract class DimNames extends RBuiltinNode { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final ConditionProfile nullProfile = ConditionProfile.createBinaryProfile(); @Specialization(guards = "!isRAbstractContainer(operand)") @@ -47,8 +47,8 @@ public abstract class DimNames extends RBuiltinNode { } @Specialization - protected Object getDimNames(RAbstractContainer container) { - RList names = container.getDimNames(attrProfiles); + protected Object getDimNames(RAbstractContainer container, @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) { + RList names = getDimNamesNode.getDimNames(container); return nullProfile.profile(names == null) ? RNull.instance : names; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java index 7cb11a03f335315d7421134e3bb055a720266eed..dbcf174805a15697847c63c09643e27572a98e02 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java @@ -37,6 +37,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.FrameSlotNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.GetFunctionsFactory.GetNodeGen; @@ -50,7 +51,6 @@ import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RFunction; @@ -72,8 +72,8 @@ public abstract class DoCall extends RBuiltinNode implements InternalRSyntaxNode @Child private GetFunctions.Get getNode; @Child private GetCallerFrameNode getCallerFrame; + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile containsRLanguageProfile = BranchProfile.create(); private final BranchProfile containsRSymbolProfile = BranchProfile.create(); @@ -113,7 +113,7 @@ public abstract class DoCall extends RBuiltinNode implements InternalRSyntaxNode * To re-create the illusion of a normal call, turn the values in argsAsList into promises. */ Object[] argValues = argsAsList.getDataCopy(); - RStringVector n = argsAsList.getNames(attrProfiles); + RStringVector n = getNamesNode.getNames(argsAsList); ArgumentsSignature signature; if (n == null) { signature = ArgumentsSignature.empty(argValues.length); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java index 43cfb6a97d7bde5e346af117e8b0e2762f640d5d..7104921f0dc2c92786597d31e9c707f6fadf5f1c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java @@ -25,9 +25,15 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; +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.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; @@ -47,8 +53,13 @@ public abstract class Drop extends RBuiltinNode { private final ConditionProfile noDimNamesProfile = ConditionProfile.createBinaryProfile(); @Specialization - protected RAbstractVector doDrop(RAbstractVector x) { - int[] dims = x.getDimensions(); + protected RAbstractVector doDrop(RAbstractVector x, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimsNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimsNamesNode, + @Cached("create()") SetNamesAttributeNode setNamesNode) { + int[] dims = getDimsNode.getDimensions(x); if (nullDimensions.profile(dims == null)) { return x; } @@ -67,15 +78,15 @@ public abstract class Drop extends RBuiltinNode { if (resultIsScalarProfile.profile(lastNonOneIndex == -1)) { @SuppressWarnings("unused") RAbstractVector r = x.copy(); - x.setDimensions(null); - x.setDimNames(null); - x.setNames(null); + setDimsNode.setDimensions(x, null); + setDimsNamesNode.setDimNames(x, null); + setNamesNode.setNames(x, null); return x; } // the result is vector if (resultIsVector.profile(newDimsLength <= 1)) { - return toVector(x, lastNonOneIndex); + return toVector(x, lastNonOneIndex, setDimsNode, getDimsNamesNode, setNamesNode); } // else: the result will be a matrix, copy non-1 dimensions @@ -88,10 +99,10 @@ public abstract class Drop extends RBuiltinNode { } RAbstractVector result = x.copy(); - result.setDimensions(newDims); + setDimsNode.setDimensions(result, newDims); // if necessary, copy corresponding dimnames - RList oldDimNames = x.getDimNames(dimNamesAttrProfile); + RList oldDimNames = getDimsNamesNode.getDimNames(x); if (noDimNamesProfile.profile(oldDimNames != null)) { newDimsIdx = 0; Object[] newDimNames = new Object[newDimsLength]; @@ -100,9 +111,9 @@ public abstract class Drop extends RBuiltinNode { newDimNames[newDimsIdx++] = oldDimNames.getDataAt(i); } } - result.setDimNames(RDataFactory.createList(newDimNames)); + setDimsNamesNode.setDimNames(result, RDataFactory.createList(newDimNames)); } else { - result.setDimNames(null); + setDimsNamesNode.setDimNames(result, null); } return result; @@ -112,14 +123,14 @@ public abstract class Drop extends RBuiltinNode { * Handles the case when result is just a vector. The only catch is that we might have to copy * corresponding index from dimnames to names attribute of the new vector. */ - private RAbstractVector toVector(RAbstractVector x, int nonOneIndex) { + private RAbstractVector toVector(RAbstractVector x, int nonOneIndex, SetDimAttributeNode setDimsNode, GetDimNamesAttributeNode getDimNamesNode, SetNamesAttributeNode setNamesNode) { RAbstractVector result = x.copy(); // share? - result.setDimensions(null); + setDimsNode.setDimensions(result, null); // copy dimnames to names if possible - RList dimNames = x.getDimNames(dimNamesAttrProfile); + RList dimNames = getDimNamesNode.getDimNames(x); if (noDimNamesProfile.profile(dimNames != null) && nonOneIndex < dimNames.getLength()) { - result.setNames(ensureStringVector(dimNames.getDataAt(nonOneIndex))); + setNamesNode.setNames(result, ensureStringVector(dimNames.getDataAt(nonOneIndex))); } return result; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java index 9edab7fbd30972db49f6a3a5f47d2996403c446e..943bd6ee74737e7f78df1db20db0fa42b51ab274 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java @@ -22,7 +22,11 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.size; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; import static com.oracle.truffle.r.runtime.RVisibility.OFF; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBehavior.READS_STATE; @@ -32,6 +36,7 @@ import java.util.ArrayList; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -55,6 +60,8 @@ public class DynLoadFunctions { @RBuiltin(name = "dyn.load", visibility = OFF, kind = INTERNAL, parameterNames = {"lib", "local", "now", "unused"}, behavior = COMPLEX) public abstract static class DynLoad extends RBuiltinNode { + @Child private DLL.LoadPackageDLLNode loadPackageDLLNode = DLL.LoadPackageDLLNode.create(); + @Override protected void createCasts(CastBuilder casts) { casts.arg("lib").mustBe(stringValue()).asStringVector().mustBe(size(1), RError.Message.CHAR_ARGUMENT).findFirst(); @@ -67,7 +74,7 @@ public class DynLoadFunctions { @TruffleBoundary protected RList doDynLoad(String lib, boolean local, boolean now, @SuppressWarnings("unused") String unused) { try { - DLLInfo dllInfo = DLL.loadPackageDLL(lib, local, now); + DLLInfo dllInfo = loadPackageDLLNode.loadPackageDLL(lib, local, now); return dllInfo.toRList(); } catch (DLLException ex) { // This is not a recoverable error @@ -100,6 +107,9 @@ public class DynLoadFunctions { @RBuiltin(name = "getLoadedDLLs", kind = INTERNAL, parameterNames = {}, behavior = READS_STATE) public abstract static class GetLoadedDLLs extends RBuiltinNode { + + @Child private SetClassAttributeNode setClassAttrNode = SetClassAttributeNode.create(); + @Specialization @TruffleBoundary protected RList doGetLoadedDLLs() { @@ -113,7 +123,7 @@ public class DynLoadFunctions { data[i] = dllInfo.toRList(); } RList result = RDataFactory.createList(data, RDataFactory.createStringVector(names, RDataFactory.COMPLETE_VECTOR)); - result.setClassAttr(RDataFactory.createStringVectorFromScalar(DLLINFOLIST_CLASS)); + setClassAttrNode.execute(result, RDataFactory.createStringVectorFromScalar(DLLINFOLIST_CLASS)); return result; } } 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 e5ae35b08c784065f46fd10c6b38abd451044f51..d7188cf48b1d06d525c8c64352f9844d7f4d5d0c 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 @@ -49,6 +49,8 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.RRootNode; +import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RList2EnvNode; @@ -172,10 +174,14 @@ public class EnvFunctions { return list2Env.execute(list, env); } + protected GetFixedAttributeNode createGetXDataAttrNode() { + return GetFixedAttributeNode.create(RRuntime.DOT_XDATA); + } + @Specialization - protected Object asEnvironment(RS4Object obj) { + protected Object asEnvironment(RS4Object obj, @Cached("createGetXDataAttrNode()") GetFixedAttributeNode getXDataAttrNode) { // generic dispatch tried already - Object xData = obj.getAttr(RRuntime.DOT_XDATA); + Object xData = getXDataAttrNode.execute(obj); if (xData == null || !(xData instanceof REnvironment)) { throw RError.error(this, RError.Message.S4OBJECT_NX_ENVIRONMENT); } else { @@ -319,8 +325,8 @@ public class EnvFunctions { @RBuiltin(name = "environment", kind = INTERNAL, parameterNames = {"fun"}, behavior = COMPLEX) public abstract static class Environment extends RBuiltinNode { - private static RAttributeProfiles attributeProfile = RAttributeProfiles.create(); private final ConditionProfile attributable = ConditionProfile.createBinaryProfile(); + @Child private GetFixedAttributeNode getEnvAttrNode; @Specialization protected Object environment(VirtualFrame frame, @SuppressWarnings("unused") RNull fun, @@ -352,16 +358,24 @@ public class EnvFunctions { } @Specialization(guards = "isRFormula(formula)") - protected Object environment(RLanguage formula, - @Cached("create()") RAttributeProfiles attrProfiles) { - Object result = formula.getAttr(attrProfiles, RRuntime.DOT_ENVIRONMENT); + protected Object environment(RLanguage formula) { + if (getEnvAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getEnvAttrNode = insert(GetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT)); + } + + Object result = getEnvAttrNode.execute(formula); return result == null ? RNull.instance : result; } @Specialization(guards = {"!isRNull(fun)", "!isRFunction(fun)", "!isRFormula(fun)"}) protected Object environment(Object fun) { if (attributable.profile(fun instanceof RAttributable)) { - Object attr = ((RAttributable) fun).getAttr(attributeProfile, RRuntime.DOT_ENVIRONMENT); + if (getEnvAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getEnvAttrNode = insert(GetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT)); + } + Object attr = getEnvAttrNode.execute(fun); return attr == null ? RNull.instance : attr; } else { // Not an error according to GnuR @@ -401,16 +415,22 @@ public class EnvFunctions { throw RError.error(this, RError.Message.USE_NULL_ENV_DEFUNCT); } + protected SetFixedAttributeNode createSetEnvAttrNode() { + return SetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT); + } + @Specialization @TruffleBoundary - protected static Object updateEnvironment(RAbstractContainer obj, REnvironment env) { - return updateEnvironment((RAttributable) obj, env); + protected static Object updateEnvironment(RAbstractContainer obj, REnvironment env, + @Cached("createSetEnvAttrNode()") SetFixedAttributeNode setEnvAttrNode) { + return updateEnvironment((RAttributable) obj, env, setEnvAttrNode); } @Specialization @TruffleBoundary - protected static Object updateEnvironment(RAttributable obj, REnvironment env) { - obj.setAttr(RRuntime.DOT_ENVIRONMENT, env); + protected static Object updateEnvironment(RAttributable obj, REnvironment env, + @Cached("createSetEnvAttrNode()") SetFixedAttributeNode setEnvAttrNode) { + setEnvAttrNode.execute(obj, env); return obj; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java index 83bade1e3165ab0807caa023896b8a47890d2a4c..63d8b68047883562b4511b147b70663fb83c40ca 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java @@ -57,15 +57,16 @@ import java.util.stream.Stream; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.Utils; -import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.builtins.RBehavior; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.builtins.RBuiltinKind; @@ -266,6 +267,8 @@ public class FileFunctions { private static final RStringVector NAMES_VECTOR = RDataFactory.createStringVector(NAMES, RDataFactory.COMPLETE_VECTOR); private static final RStringVector OCTMODE = RDataFactory.createStringVectorFromScalar("octmode"); + @Child private SetClassAttributeNode setClassAttrNode; + @Override protected void createCasts(CastBuilder casts) { casts.arg("extra_cols").asLogicalVector().findFirst().map(toBoolean()); @@ -400,12 +403,19 @@ public class FileFunctions { // @formatter:on } - private static Object createColumnResult(Column column, Object data, boolean complete) { + private Object createColumnResult(Column column, Object data, boolean complete) { // @formatter:off switch(column) { case size: return RDataFactory.createDoubleVector((double[]) data, complete); case isdir: return RDataFactory.createLogicalVector((byte[]) data, complete); - case mode: RIntVector res = RDataFactory.createIntVector((int[]) data, complete); res.setClassAttr(OCTMODE); return res; + case mode: + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + RIntVector res = RDataFactory.createIntVector((int[]) data, complete); + setClassAttrNode.execute(res, OCTMODE); + return res; case mtime: case ctime: case atime: case uid: case gid: return RDataFactory.createIntVector((int[]) data, complete); case uname: case grname: return RDataFactory.createStringVector((String[]) data, complete); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java index 0ff9871785cb6fb0523d27ae4bae2b6f98f303e7..c69f2dac6af092d2932465d0d8d60fb9974cf2ee 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FormatC.java @@ -15,7 +15,9 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; @@ -51,8 +53,10 @@ public abstract class FormatC extends RBuiltinNode { @SuppressWarnings("unused") @Specialization - RAttributable formatC(RAbstractContainer x, String mode, int width, int digits, String format, String flag, int iStrlen) { + RAttributable formatC(RAbstractContainer x, String mode, int width, int digits, String format, String flag, int iStrlen, + @Cached("create()") SetClassAttributeNode setClassAttrNode) { RStringVector res = castStringVector(x); - return res.setClassAttr(null); + setClassAttrNode.reset(res); + return res; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java index fe7ce64eb662db796aae3d05ae6981247b57ea65..f873109da07b8215fc2cbf199541c0ec6dd8e2df 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java @@ -11,7 +11,8 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.notEmpty; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; @@ -26,6 +27,7 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -63,6 +65,7 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; */ public class GrepFunctions { public abstract static class CommonCodeAdapter extends RBuiltinNode { + @Child protected PCRERFFI.PCRERFFINode pcreRFFINode = RFFIFactory.getRFFI().getPCRERFFI().createPCRERFFINode(); /** * This profile is needed to satisfy API requirements. @@ -205,8 +208,8 @@ public class GrepFunctions { protected PCRERFFI.Result compilePerlPattern(String pattern, boolean ignoreCase) { int cflags = ignoreCase ? PCRERFFI.CASELESS : 0; - long tables = RFFIFactory.getRFFI().getPCRERFFI().maketables(); - PCRERFFI.Result pcre = RFFIFactory.getRFFI().getPCRERFFI().compile(pattern, cflags, tables); + long tables = pcreRFFINode.maketables(); + PCRERFFI.Result pcre = pcreRFFINode.compile(pattern, cflags, tables); if (pcre.result == 0) { // TODO output warning if pcre.errorMessage not NULL throw RError.error(this, RError.Message.INVALID_REGEXP, pattern); @@ -246,7 +249,7 @@ public class GrepFunctions { for (int i = 0; i < len; i++) { String text = vector.getDataAt(i); if (!RRuntime.isNA(text)) { - if (RFFIFactory.getRFFI().getPCRERFFI().exec(pcre.result, 0, text, 0, 0, ovector) >= 0) { + if (pcreRFFINode.exec(pcre.result, 0, text, 0, 0, ovector) >= 0) { matches[i] = true; } } @@ -433,7 +436,7 @@ public class GrepFunctions { int eflag = 0; int lastEnd = -1; StringBuffer sb = new StringBuffer(); - while (RFFIFactory.getRFFI().getPCRERFFI().exec(pcre.result, 0, input, offset, eflag, ovector) >= 0) { + while (pcreRFFINode.exec(pcre.result, 0, input, offset, eflag, ovector) >= 0) { nmatch++; for (int j = offset; j < ovector[0]; j++) { sb.append(input.charAt(j)); @@ -472,7 +475,7 @@ public class GrepFunctions { result[i] = value; } RStringVector ret = RDataFactory.createStringVector(result, vector.isComplete()); - ret.copyAttributesFrom(attrProfiles, vector); + ret.copyAttributesFrom(vector); return ret; } catch (PatternSyntaxException e) { CompilerDirectives.transferToInterpreter(); @@ -663,6 +666,13 @@ public class GrepFunctions { @RBuiltin(name = "regexpr", kind = INTERNAL, parameterNames = {"pattern", "text", "ignore.case", "perl", "fixed", "useBytes"}, behavior = PURE) public abstract static class Regexp extends CommonCodeAdapter { + @Child SetFixedAttributeNode setMatchLengthAttrNode = SetFixedAttributeNode.create("match.length"); + @Child SetFixedAttributeNode setUseBytesAttrNode = SetFixedAttributeNode.create("useBytes"); + @Child SetFixedAttributeNode setCaptureStartAttrNode = SetFixedAttributeNode.create("capture.start"); + @Child SetFixedAttributeNode setCaptureLengthAttrNode = SetFixedAttributeNode.create("capture.length"); + @Child SetFixedAttributeNode setCaptureNamesAttrNode = SetFixedAttributeNode.create("capture.names"); + @Child SetFixedAttributeNode setDimNamesAttrNode = SetFixedAttributeNode.createDimNames(); + @Override protected void createCasts(CastBuilder casts) { castPattern(casts); @@ -754,19 +764,19 @@ public class GrepFunctions { } } RIntVector ret = RDataFactory.createIntVector(result, RDataFactory.COMPLETE_VECTOR); - ret.setAttr("match.length", RDataFactory.createIntVector(matchLength, RDataFactory.COMPLETE_VECTOR)); + setMatchLengthAttrNode.execute(ret, RDataFactory.createIntVector(matchLength, RDataFactory.COMPLETE_VECTOR)); if (useBytes) { - ret.setAttr("useBytes", RRuntime.LOGICAL_TRUE); + setUseBytesAttrNode.execute(ret, RRuntime.LOGICAL_TRUE); } if (hasAnyCapture) { RStringVector captureNamesVec = RDataFactory.createStringVector(captureNames, RDataFactory.COMPLETE_VECTOR); RIntVector captureStartVec = RDataFactory.createIntVector(captureStart, RDataFactory.COMPLETE_VECTOR, new int[]{vector.getLength(), captureNames.length}); - captureStartVec.setAttr(RRuntime.DIMNAMES_ATTR_KEY, RDataFactory.createList(new Object[]{RNull.instance, captureNamesVec.copy()})); - ret.setAttr("capture.start", captureStartVec); + setDimNamesAttrNode.execute(captureStartVec, RDataFactory.createList(new Object[]{RNull.instance, captureNamesVec.copy()})); + setCaptureStartAttrNode.execute(ret, captureStartVec); RIntVector captureLengthVec = RDataFactory.createIntVector(captureLength, RDataFactory.COMPLETE_VECTOR, new int[]{vector.getLength(), captureNames.length}); - captureLengthVec.setAttr(RRuntime.DIMNAMES_ATTR_KEY, RDataFactory.createList(new Object[]{RNull.instance, captureNamesVec.copy()})); - ret.setAttr("capture.length", captureLengthVec); - ret.setAttr("capture.names", captureNamesVec); + setDimNamesAttrNode.execute(captureLengthVec, RDataFactory.createList(new Object[]{RNull.instance, captureNamesVec.copy()})); + setCaptureLengthAttrNode.execute(ret, captureLengthVec); + setCaptureNamesAttrNode.execute(ret, captureNamesVec); } return ret; } @@ -789,13 +799,13 @@ public class GrepFunctions { } } else if (perl) { PCRERFFI.Result pcre = compilePerlPattern(pattern, ignoreCase); - int maxCaptureCount = RFFIFactory.getRFFI().getPCRERFFI().getCaptureCount(pcre.result, 0); + int maxCaptureCount = pcreRFFINode.getCaptureCount(pcre.result, 0); int[] ovector = new int[(maxCaptureCount + 1) * 3]; int offset = 0; while (true) { - int captureCount = RFFIFactory.getRFFI().getPCRERFFI().exec(pcre.result, 0, text, offset, 0, ovector); + int captureCount = pcreRFFINode.exec(pcre.result, 0, text, offset, 0, ovector); if (captureCount >= 0) { - String[] captureNames = RFFIFactory.getRFFI().getPCRERFFI().getCaptureNames(pcre.result, 0, maxCaptureCount); + String[] captureNames = pcreRFFINode.getCaptureNames(pcre.result, 0, maxCaptureCount); for (int i = 0; i < captureNames.length; i++) { if (captureNames[i] == null) { captureNames[i] = ""; @@ -844,6 +854,13 @@ public class GrepFunctions { @RBuiltin(name = "gregexpr", kind = INTERNAL, parameterNames = {"pattern", "text", "ignore.case", "perl", "fixed", "useBytes"}, behavior = PURE) public abstract static class Gregexpr extends Regexp { + @Child SetFixedAttributeNode setMatchLengthAttrNode = SetFixedAttributeNode.create("match.length"); + @Child SetFixedAttributeNode setUseBytesAttrNode = SetFixedAttributeNode.create("useBytes"); + @Child SetFixedAttributeNode setCaptureStartAttrNode = SetFixedAttributeNode.create("capture.start"); + @Child SetFixedAttributeNode setCaptureLengthAttrNode = SetFixedAttributeNode.create("capture.length"); + @Child SetFixedAttributeNode setCaptureNamesAttrNode = SetFixedAttributeNode.create("capture.names"); + @Child SetFixedAttributeNode setDimNamesAttrNode = SetFixedAttributeNode.createDimNames(); + @Override protected void createCasts(CastBuilder casts) { castPattern(casts); @@ -854,19 +871,19 @@ public class GrepFunctions { castUseBytes(casts); } - private static void setNoCaptureAttributes(RIntVector vec, RStringVector captureNames) { + private void setNoCaptureAttributes(RIntVector vec, RStringVector captureNames) { int len = captureNames.getLength(); int[] captureStartData = new int[len]; int[] captureLengthData = new int[len]; Arrays.fill(captureStartData, -1); Arrays.fill(captureLengthData, -1); RIntVector captureStart = RDataFactory.createIntVector(captureStartData, RDataFactory.COMPLETE_VECTOR, new int[]{1, captureNames.getLength()}); - captureStart.setAttr(RRuntime.DIMNAMES_ATTR_KEY, RDataFactory.createList(new Object[]{RNull.instance, captureNames.copy()})); + setDimNamesAttrNode.execute(captureStart, RDataFactory.createList(new Object[]{RNull.instance, captureNames.copy()})); RIntVector captureLength = RDataFactory.createIntVector(captureLengthData, RDataFactory.COMPLETE_VECTOR, new int[]{1, captureNames.getLength()}); - captureLength.setAttr(RRuntime.DIMNAMES_ATTR_KEY, RDataFactory.createList(new Object[]{RNull.instance, captureNames.copy()})); - vec.setAttr("capture.start", captureStart); - vec.setAttr("capture.length", captureLength); - vec.setAttr("capture.names", captureNames); + setDimNamesAttrNode.execute(captureLength, RDataFactory.createList(new Object[]{RNull.instance, captureNames.copy()})); + setCaptureStartAttrNode.execute(vec, captureStart); + setCaptureLengthAttrNode.execute(vec, captureLength); + setCaptureNamesAttrNode.execute(vec, captureNames); } @Specialization @@ -898,16 +915,16 @@ public class GrepFunctions { for (int j = 0; j < txt.length(); j++) { res.setDataAt(res.getDataWithoutCopying(), j, j + 1); } - res.setAttr("match.length", RDataFactory.createIntVector(txt.length())); + setMatchLengthAttrNode.execute(res, RDataFactory.createIntVector(txt.length())); if (useBytes) { - res.setAttr("useBytes", RRuntime.LOGICAL_TRUE); + setUseBytesAttrNode.execute(res, RRuntime.LOGICAL_TRUE); } } else { List<Info> l = getInfo(pattern, vector.getDataAt(i), ignoreCase, perl, fixed); res = toIndexOrSizeVector(l, true); - res.setAttr("match.length", toIndexOrSizeVector(l, false)); + setMatchLengthAttrNode.execute(res, toIndexOrSizeVector(l, false)); if (useBytes) { - res.setAttr("useBytes", RRuntime.LOGICAL_TRUE); + setUseBytesAttrNode.execute(res, RRuntime.LOGICAL_TRUE); } RIntVector captureStart = toCaptureStartOrLength(l, true); if (captureStart != null) { @@ -922,9 +939,9 @@ public class GrepFunctions { } } hasAnyCapture = true; - res.setAttr("capture.start", captureStart); - res.setAttr("capture.length", captureLength); - res.setAttr("capture.names", captureNames); + setCaptureStartAttrNode.execute(res, captureStart); + setCaptureLengthAttrNode.execute(res, captureLength); + setCaptureNamesAttrNode.execute(res, captureNames); } else if (hasAnyCapture) { assert captureNames != null; // it's capture names from previous iteration, so copy @@ -946,7 +963,7 @@ public class GrepFunctions { return RDataFactory.createIntVector(arr, RDataFactory.COMPLETE_VECTOR); } - private static RIntVector toCaptureStartOrLength(List<Info> list, boolean start) { + private RIntVector toCaptureStartOrLength(List<Info> list, boolean start) { assert list.size() > 0; Info firstInfo = list.get(0); if (!firstInfo.hasCapture) { @@ -965,7 +982,7 @@ public class GrepFunctions { } } RIntVector ret = RDataFactory.createIntVector(arr, RDataFactory.COMPLETE_VECTOR, new int[]{list.size(), firstInfo.captureNames.length}); - ret.setAttr(RRuntime.DIMNAMES_ATTR_KEY, RDataFactory.createList(new Object[]{RNull.instance, RDataFactory.createStringVector(firstInfo.captureNames, RDataFactory.COMPLETE_VECTOR)})); + setDimNamesAttrNode.execute(ret, RDataFactory.createList(new Object[]{RNull.instance, RDataFactory.createStringVector(firstInfo.captureNames, RDataFactory.COMPLETE_VECTOR)})); return ret; } @@ -1152,7 +1169,7 @@ public class GrepFunctions { // treat split = NULL as split = "" RAbstractStringVector split = splitArg.getLength() == 0 ? RDataFactory.createStringVectorFromScalar("") : splitArg; String[] splits = new String[split.getLength()]; - long pcreTables = perl ? RFFIFactory.getRFFI().getPCRERFFI().maketables() : 0; + long pcreTables = perl ? pcreRFFINode.maketables() : 0; PCRERFFI.Result[] pcreSplits = perl ? new PCRERFFI.Result[splits.length] : null; na.enable(x); @@ -1161,7 +1178,7 @@ public class GrepFunctions { splits[i] = fixed || perl ? split.getDataAt(i) : RegExp.checkPreDefinedClasses(split.getDataAt(i)); if (perl) { if (!currentSplit.isEmpty()) { - pcreSplits[i] = RFFIFactory.getRFFI().getPCRERFFI().compile(currentSplit, 0, pcreTables); + pcreSplits[i] = pcreRFFINode.compile(currentSplit, 0, pcreTables); if (pcreSplits[i].result == 0) { // TODO output warning if pcre.errorMessage not NULL throw RError.error(this, RError.Message.INVALID_REGEXP, currentSplit); @@ -1231,14 +1248,14 @@ public class GrepFunctions { return RDataFactory.createStringVector(result, true); } - private static RStringVector splitPerl(String data, PCRERFFI.Result pcre) { + private RStringVector splitPerl(String data, PCRERFFI.Result pcre) { ArrayList<String> matches = new ArrayList<>(); int lastEndOffset = 0; int lastEndIndex = 0; int[] ovector = new int[30]; int[] fromByteMapping = getFromByteMapping(data); // non-null if it's necessary - while (RFFIFactory.getRFFI().getPCRERFFI().exec(pcre.result, 0, data, lastEndOffset, 0, ovector) >= 0) { + while (pcreRFFINode.exec(pcre.result, 0, data, lastEndOffset, 0, ovector) >= 0) { // offset == byte position // index == character position int startOffset = ovector[0]; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java index 7b1275c1b1d5ffbe7a3539868b2d97a1a451e9a4..d04b57fd08082c853c5738796cd4fa9a5d2f151a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java @@ -27,6 +27,7 @@ import java.nio.ByteBuffer; import com.oracle.truffle.api.CompilerDirectives; 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.frame.MaterializedFrame; @@ -35,6 +36,7 @@ import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.PromiseHelperNode; @@ -284,7 +286,8 @@ public class HiddenInternalFunctions { @Specialization(guards = "isDLLInfo(externalPtr)") @TruffleBoundary - protected RList getRegisteredRoutines(RExternalPtr externalPtr) { + protected RList getRegisteredRoutines(RExternalPtr externalPtr, + @Cached("create()") SetClassAttributeNode setClassAttrNode) { Object[] data = new Object[NAMES.getLength()]; DLL.DLLInfo dllInfo = (DLLInfo) externalPtr.getExternalObject(); RInternalError.guarantee(dllInfo != null); @@ -301,7 +304,7 @@ public class HiddenInternalFunctions { symbolData[i] = symbolInfo.createRSymbolObject(rnt, true); } RList symbolDataList = RDataFactory.createList(symbolData); - symbolDataList.setClassAttr(NATIVE_ROUTINE_LIST); + setClassAttrNode.execute(symbolDataList, NATIVE_ROUTINE_LIST); data[nst.ordinal()] = symbolDataList; } return RDataFactory.createList(data, NAMES); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java index 984935f3b56ac9def0cdc4c4fcc437aafa1d79a3..4a85c00052164f5c2ea76442cfab799fb2cdf6ea 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java @@ -31,11 +31,14 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 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.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -54,8 +57,11 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; public abstract class IsNA extends RBuiltinNode { @Child private IsNA recursiveIsNA; + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); + @Child private GetDimAttributeNode getDimsNode = GetDimAttributeNode.create(); + @Child private SetDimNamesAttributeNode setDimNamesNode = SetDimNamesAttributeNode.create(); + @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final ConditionProfile nullDimNamesProfile = ConditionProfile.createBinaryProfile(); private Object isNARecursive(Object o) { @@ -194,10 +200,10 @@ public abstract class IsNA extends RBuiltinNode { } private RLogicalVector createResult(byte[] data, RAbstractVector originalVector) { - RLogicalVector result = RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR, originalVector.getDimensions(), originalVector.getNames(attrProfiles)); - RList dimNames = originalVector.getDimNames(attrProfiles); + RLogicalVector result = RDataFactory.createLogicalVector(data, RDataFactory.COMPLETE_VECTOR, getDimsNode.getDimensions(originalVector), getNamesNode.getNames(originalVector)); + RList dimNames = getDimNamesNode.getDimNames(originalVector); if (nullDimNamesProfile.profile(dimNames != null)) { - result.setDimNames(dimNames); + setDimNamesNode.setDimNames(result, dimNames); } return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java index 2e1b049a8896038a9cfd8cd5c5286209590fed69..8d3ca0f3b4ef3d2c4cfe9763960769dca7ff01df 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LaFunctions.java @@ -28,9 +28,16 @@ import java.util.function.Function; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNode; @@ -49,6 +56,7 @@ import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.ffi.LapackRFFI; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.ops.na.NACheck; @@ -61,18 +69,22 @@ import com.oracle.truffle.r.runtime.ops.na.NACheck; */ public class LaFunctions { + protected abstract static class Adapter extends RBuiltinNode { + @Child protected LapackRFFI.LapackRFFINode lapackRFFINode = RFFIFactory.getRFFI().getLapackRFFI().createLapackRFFINode(); + } + @RBuiltin(name = "La_version", kind = INTERNAL, parameterNames = {}, behavior = READS_STATE) - public abstract static class Version extends RBuiltinNode { + public abstract static class Version extends Adapter { @Specialization @TruffleBoundary protected String doVersion() { int[] version = new int[3]; - RFFIFactory.getRFFI().getLapackRFFI().ilaver(version); + lapackRFFINode.ilaver(version); return version[0] + "." + version[1] + "." + version[2]; } } - private abstract static class RsgAdapter extends RBuiltinNode { + private abstract static class RsgAdapter extends Adapter { protected static final String[] NAMES = new String[]{"values", "vectors"}; protected final BranchProfile errorProfile = BranchProfile.create(); @@ -90,8 +102,8 @@ public class LaFunctions { private final ConditionProfile hasComplexValues = ConditionProfile.createBinaryProfile(); @Specialization - protected Object doRg(RDoubleVector matrix, boolean onlyValues) { - int[] dims = matrix.getDimensions(); + protected Object doRg(RDoubleVector matrix, boolean onlyValues, @Cached("create()") GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(matrix); // copy array component of matrix as Lapack destroys it int n = dims[0]; double[] a = matrix.getDataCopy(); @@ -108,7 +120,7 @@ public class LaFunctions { double[] wi = new double[n]; double[] work = new double[1]; // ask for optimal size of work array - int info = RFFIFactory.getRFFI().getLapackRFFI().dgeev(jobVL, jobVR, n, a, n, wr, wi, left, n, right, n, work, -1); + int info = lapackRFFINode.dgeev(jobVL, jobVR, n, a, n, wr, wi, left, n, right, n, work, -1); if (info != 0) { errorProfile.enter(); throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dgeev"); @@ -116,7 +128,7 @@ public class LaFunctions { // now allocate work array and make the actual call int lwork = (int) work[0]; work = new double[lwork]; - info = RFFIFactory.getRFFI().getLapackRFFI().dgeev(jobVL, jobVR, n, a, n, wr, wi, left, n, right, n, work, lwork); + info = lapackRFFINode.dgeev(jobVL, jobVR, n, a, n, wr, wi, left, n, right, n, work, lwork); if (info != 0) { errorProfile.enter(); throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dgeev"); @@ -184,8 +196,8 @@ public class LaFunctions { @RBuiltin(name = "La_rs", kind = INTERNAL, parameterNames = {"matrix", "onlyValues"}, behavior = PURE) public abstract static class Rs extends RsgAdapter { @Specialization - protected Object doRs(RDoubleVector matrix, boolean onlyValues) { - int[] dims = matrix.getDimensions(); + protected Object doRs(RDoubleVector matrix, boolean onlyValues, @Cached("create()") GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(matrix); int n = dims[0]; char jobv = onlyValues ? 'N' : 'V'; char uplo = 'L'; @@ -209,7 +221,7 @@ public class LaFunctions { int[] isuppz = new int[2 * n]; double[] work = new double[1]; int[] iwork = new int[1]; - int info = RFFIFactory.getRFFI().getLapackRFFI().dsyevr(jobv, range, uplo, n, x, n, vl, vu, il, iu, abstol, m, values, z, n, isuppz, work, lwork, iwork, liwork); + int info = lapackRFFINode.dsyevr(jobv, range, uplo, n, x, n, vl, vu, il, iu, abstol, m, values, z, n, isuppz, work, lwork, iwork, liwork); if (info != 0) { errorProfile.enter(); throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dysevr"); @@ -218,7 +230,7 @@ public class LaFunctions { liwork = iwork[0]; work = new double[lwork]; iwork = new int[liwork]; - info = RFFIFactory.getRFFI().getLapackRFFI().dsyevr(jobv, range, uplo, n, x, n, vl, vu, il, iu, abstol, m, values, z, n, isuppz, work, lwork, iwork, liwork); + info = lapackRFFINode.dsyevr(jobv, range, uplo, n, x, n, vl, vu, il, iu, abstol, m, values, z, n, isuppz, work, lwork, iwork, liwork); if (info != 0) { errorProfile.enter(); throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dysevr"); @@ -239,7 +251,7 @@ public class LaFunctions { } @RBuiltin(name = "La_qr", kind = INTERNAL, parameterNames = {"in"}, behavior = PURE) - public abstract static class Qr extends RBuiltinNode { + public abstract static class Qr extends Adapter { @CompilationFinal private static final String[] NAMES = new String[]{"qr", "rank", "qraux", "pivot"}; @@ -251,13 +263,15 @@ public class LaFunctions { } @Specialization - protected RList doQr(RAbstractDoubleVector aIn) { + protected RList doQr(RAbstractDoubleVector aIn, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimAttributeNode setDimsNode) { // This implementation is sufficient for B25 matcal-5. if (!(aIn instanceof RDoubleVector)) { RError.nyi(this, "non-real vectors not supported (yet)"); } RDoubleVector daIn = (RDoubleVector) aIn; - int[] dims = daIn.getDimensions(); + int[] dims = getDimsNode.getDimensions(daIn); // copy array component of matrix as Lapack destroys it int n = dims[0]; int m = dims[1]; @@ -266,14 +280,14 @@ public class LaFunctions { double[] tau = new double[m < n ? m : n]; double[] work = new double[1]; // ask for optimal size of work array - int info = RFFIFactory.getRFFI().getLapackRFFI().dgeqp3(m, n, a, m, jpvt, tau, work, -1); + int info = lapackRFFINode.dgeqp3(m, n, a, m, jpvt, tau, work, -1); if (info < 0) { errorProfile.enter(); throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dgeqp3"); } int lwork = (int) work[0]; work = new double[lwork]; - info = RFFIFactory.getRFFI().getLapackRFFI().dgeqp3(m, n, a, m, jpvt, tau, work, lwork); + info = lapackRFFINode.dgeqp3(m, n, a, m, jpvt, tau, work, lwork); if (info < 0) { errorProfile.enter(); throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dgeqp3"); @@ -282,7 +296,7 @@ public class LaFunctions { // TODO check complete RDoubleVector ra = RDataFactory.createDoubleVector(a, RDataFactory.COMPLETE_VECTOR); // TODO check pivot - ra.setDimensions(dims); + setDimsNode.setDimensions(ra, dims); data[0] = ra; data[1] = m < n ? m : n; data[2] = RDataFactory.createDoubleVector(tau, RDataFactory.COMPLETE_VECTOR); @@ -292,7 +306,7 @@ public class LaFunctions { } @RBuiltin(name = "qr_coef_real", kind = INTERNAL, parameterNames = {"q", "b"}, behavior = PURE) - public abstract static class QrCoefReal extends RBuiltinNode { + public abstract static class QrCoefReal extends Adapter { private final BranchProfile errorProfile = BranchProfile.create(); @@ -306,7 +320,9 @@ public class LaFunctions { } @Specialization - protected RDoubleVector doQrCoefReal(RList qIn, RDoubleVector bIn) { + protected RDoubleVector doQrCoefReal(RList qIn, RDoubleVector bIn, + @Cached("create()") GetDimAttributeNode getBDimsNode, + @Cached("create()") GetDimAttributeNode getQDimsNode) { // If bIn was coerced this extra copy is unnecessary RDoubleVector b = (RDoubleVector) bIn.copy(); @@ -315,8 +331,8 @@ public class LaFunctions { RDoubleVector tau = (RDoubleVector) qIn.getDataAt(2); int k = tau.getLength(); - int[] bDims = bIn.getDimensions(); - int[] qrDims = qr.getDimensions(); + int[] bDims = getBDimsNode.getDimensions(bIn); + int[] qrDims = getQDimsNode.getDimensions(qr); int n = qrDims[0]; if (bDims[0] != n) { errorProfile.enter(); @@ -330,19 +346,19 @@ public class LaFunctions { // we work directly in the internal data of b double[] bData = b.getDataWithoutCopying(); // ask for optimal size of work array - int info = RFFIFactory.getRFFI().getLapackRFFI().dormqr(SIDE, TRANS, n, nrhs, k, qrData, n, tauData, bData, n, work, -1); + int info = lapackRFFINode.dormqr(SIDE, TRANS, n, nrhs, k, qrData, n, tauData, bData, n, work, -1); if (info < 0) { errorProfile.enter(); throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dormqr"); } int lwork = (int) work[0]; work = new double[lwork]; - info = RFFIFactory.getRFFI().getLapackRFFI().dormqr(SIDE, TRANS, n, nrhs, k, qrData, n, tauData, bData, n, work, lwork); + info = lapackRFFINode.dormqr(SIDE, TRANS, n, nrhs, k, qrData, n, tauData, bData, n, work, lwork); if (info < 0) { errorProfile.enter(); throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dormqr"); } - info = RFFIFactory.getRFFI().getLapackRFFI().dtrtrs('U', 'N', 'N', k, nrhs, qrData, n, bData, n); + info = lapackRFFINode.dtrtrs('U', 'N', 'N', k, nrhs, qrData, n, bData, n); if (info < 0) { errorProfile.enter(); throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dtrtrs"); @@ -353,7 +369,7 @@ public class LaFunctions { } @RBuiltin(name = "det_ge_real", kind = INTERNAL, parameterNames = {"a", "uselog"}, behavior = PURE) - public abstract static class DetGeReal extends RBuiltinNode { + public abstract static class DetGeReal extends Adapter { private static final RStringVector NAMES_VECTOR = RDataFactory.createStringVector(new String[]{"modulus", "sign"}, RDataFactory.COMPLETE_VECTOR); private static final RStringVector DET_CLASS = RDataFactory.createStringVector(new String[]{"det"}, RDataFactory.COMPLETE_VECTOR); @@ -363,6 +379,8 @@ public class LaFunctions { private final ConditionProfile doUseLog = ConditionProfile.createBinaryProfile(); private final NACheck naCheck = NACheck.create(); + @Child private SetFixedAttributeNode setLogAttrNode = SetFixedAttributeNode.create("logarithm"); + @Override protected void createCasts(CastBuilder casts) { //@formatter:off @@ -379,14 +397,15 @@ public class LaFunctions { } @Specialization - protected RList doDetGeReal(RDoubleVector aIn, boolean useLog) { + protected RList doDetGeReal(RDoubleVector aIn, boolean useLog, + @Cached("create()") GetDimAttributeNode getDimsNode) { RDoubleVector a = (RDoubleVector) aIn.copy(); - int[] aDims = aIn.getDimensions(); + int[] aDims = getDimsNode.getDimensions(aIn); int n = aDims[0]; int[] ipiv = new int[n]; double modulus = 0; double[] aData = a.getDataWithoutCopying(); - int info = RFFIFactory.getRFFI().getLapackRFFI().dgetrf(n, n, aData, n, ipiv); + int info = lapackRFFINode.dgetrf(n, n, aData, n, ipiv); int sign = 1; if (info < 0) { errorProfile.enter(); @@ -432,7 +451,7 @@ public class LaFunctions { } } RDoubleVector modulusVec = RDataFactory.createDoubleVectorFromScalar(modulus); - modulusVec.setAttr("logarithm", RRuntime.asLogical(useLog)); + setLogAttrNode.execute(modulusVec, RRuntime.asLogical(useLog)); RList result = RDataFactory.createList(new Object[]{modulusVec, sign}, NAMES_VECTOR); RVector.setVectorClassAttr(result, DET_CLASS); return result; @@ -440,11 +459,14 @@ public class LaFunctions { } @RBuiltin(name = "La_chol", kind = INTERNAL, parameterNames = {"a", "pivot", "tol"}, behavior = PURE) - public abstract static class LaChol extends RBuiltinNode { + public abstract static class LaChol extends Adapter { private final BranchProfile errorProfile = BranchProfile.create(); private final ConditionProfile noPivot = ConditionProfile.createBinaryProfile(); + @Child private SetFixedAttributeNode setPivotAttrNode = SetFixedAttributeNode.create("pivot"); + @Child private SetFixedAttributeNode setRankAttrNode = SetFixedAttributeNode.create("rank"); + @Override protected void createCasts(CastBuilder casts) { //@formatter:off @@ -464,9 +486,12 @@ public class LaFunctions { } @Specialization - protected RDoubleVector doDetGeReal(RDoubleVector aIn, boolean piv, double tol) { + protected RDoubleVector doDetGeReal(RDoubleVector aIn, boolean piv, double tol, + @Cached("create()") GetDimAttributeNode getDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode) { RDoubleVector a = (RDoubleVector) aIn.copy(); - int[] aDims = aIn.getDimensions(); + int[] aDims = getDimsNode.getDimensions(aIn); int n = aDims[0]; int m = aDims[1]; double[] aData = a.getDataWithoutCopying(); @@ -478,7 +503,7 @@ public class LaFunctions { } int info; if (noPivot.profile(!piv)) { - info = RFFIFactory.getRFFI().getLapackRFFI().dpotrf('U', m, aData, m); + info = lapackRFFINode.dpotrf('U', m, aData, m); if (info != 0) { errorProfile.enter(); // TODO informative error message (aka GnuR) @@ -488,22 +513,22 @@ public class LaFunctions { int[] ipiv = new int[m]; double[] work = new double[2 * m]; int[] rank = new int[1]; - info = RFFIFactory.getRFFI().getLapackRFFI().dpstrf('U', n, aData, n, ipiv, rank, tol, work); + info = lapackRFFINode.dpstrf('U', n, aData, n, ipiv, rank, tol, work); if (info != 0) { errorProfile.enter(); // TODO informative error message (aka GnuR) throw RError.error(this, RError.Message.LAPACK_ERROR, info, "dpotrf"); } - a.setAttr("pivot", RRuntime.asLogical(piv)); - a.setAttr("rank", rank[0]); - RList dn = a.getDimNames(); + setPivotAttrNode.execute(a, RRuntime.asLogical(piv)); + setRankAttrNode.execute(a, rank[0]); + RList dn = getDimNamesNode.getDimNames(a); if (dn != null && dn.getDataAt(0) != null) { Object[] dn2 = new Object[m]; // need to pivot the colnames for (int i = 0; i < m; i++) { dn2[i] = dn.getDataAt(ipiv[i] - 1); } - a.setDimNames(RDataFactory.createList(dn2)); + setDimNamesNode.setDimNames(a, RDataFactory.createList(dn2)); } } return a; @@ -511,7 +536,7 @@ public class LaFunctions { } @RBuiltin(name = "La_solve", kind = INTERNAL, parameterNames = {"a", "bin", "tolin"}, behavior = PURE) - public abstract static class LaSolve extends RBuiltinNode { + public abstract static class LaSolve extends Adapter { protected final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Child private CastDoubleNode castDouble = CastDoubleNodeGen.create(false, false, false); @@ -535,8 +560,15 @@ public class LaFunctions { } @Specialization - protected RDoubleVector laSolve(RAbstractVector a, RDoubleVector bin, double tol) { - int[] aDims = a.getDimensions(); + protected RDoubleVector laSolve(RAbstractVector a, RDoubleVector bin, double tol, + @Cached("create()") GetDimAttributeNode getADimsNode, + @Cached("create()") GetDimAttributeNode getBinDimsNode, + @Cached("create()") SetDimAttributeNode setBDimsNode, + @Cached("create()") SetDimNamesAttributeNode setBDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBinDimNamesNode, + @Cached("create()") SetNamesAttributeNode setNamesNode) { + int[] aDims = getADimsNode.getDimensions(a); int n = aDims[0]; if (n == 0) { throw RError.error(this, RError.Message.GENERIC, "'a' is 0-diml"); @@ -545,12 +577,12 @@ public class LaFunctions { if (n2 != n) { throw RError.error(this, RError.Message.MUST_BE_SQUARE, "a", n, n2); } - RList aDn = a.getDimNames(attrProfiles); + RList aDn = getADimNamesNode.getDimNames(a); int p; double[] bData; RDoubleVector b; if (bin.isMatrix()) { - int[] bDims = bin.getDimensions(); + int[] bDims = getBinDimsNode.getDimensions(bin); p = bDims[1]; if (p == 0) { throw RError.error(this, RError.Message.GENERIC, "no right-hand side in 'b'"); @@ -561,8 +593,8 @@ public class LaFunctions { } bData = new double[n * p]; b = RDataFactory.createDoubleVector(bData, RDataFactory.COMPLETE_VECTOR); - b.setDimensions(new int[]{n, p}); - RList binDn = bin.getDimNames(); + setBDimsNode.setDimensions(b, new int[]{n, p}); + RList binDn = getBinDimNamesNode.getDimNames(bin); // This is somewhat odd, but Matrix relies on dropping NULL dimnames if (aDn != null || binDn != null) { // rownames(ans) = colnames(A), colnames(ans) = colnames(Bin) @@ -574,7 +606,7 @@ public class LaFunctions { bDnData[1] = binDn.getDataAt(1); } if (bDnData[0] != null || bDnData[1] != null) { - b.setDimNames(RDataFactory.createList(bDnData)); + setBDimNamesNode.setDimNames(b, RDataFactory.createList(bDnData)); } } } else { @@ -585,7 +617,7 @@ public class LaFunctions { bData = new double[n]; b = RDataFactory.createDoubleVector(bData, RDataFactory.COMPLETE_VECTOR); if (aDn != null) { - b.setNames(RDataFactory.createStringVector((String) aDn.getDataAt(1))); + setNamesNode.setNames(b, RDataFactory.createStringVector((String) aDn.getDataAt(1))); } } @@ -601,7 +633,7 @@ public class LaFunctions { assert aDouble != a; avals = aDouble.getInternalStore(); } - int info = RFFIFactory.getRFFI().getLapackRFFI().dgesv(n, p, avals, n, ipiv, bData, n); + int info = lapackRFFINode.dgesv(n, p, avals, n, ipiv, bData, n); if (info < 0) { RError.error(this, RError.Message.LAPACK_INVALID_VALUE, -info, "dgesv"); } @@ -609,10 +641,10 @@ public class LaFunctions { RError.error(this, RError.Message.LAPACK_EXACTLY_SINGULAR, "dgesv", info, info); } if (tol > 0) { - double anorm = RFFIFactory.getRFFI().getLapackRFFI().dlange('1', n, n, avals, n, null); + double anorm = lapackRFFINode.dlange('1', n, n, avals, n, null); double[] work = new double[4 * n]; double[] rcond = new double[1]; - RFFIFactory.getRFFI().getLapackRFFI().dgecon('1', n, avals, n, anorm, rcond, work, ipiv); + lapackRFFINode.dgecon('1', n, avals, n, anorm, rcond, work, ipiv); if (rcond[0] < tol) { RError.error(this, RError.Message.SYSTEM_COMP_SINGULAR, rcond[0]); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java index a75fdbb515e1a6c46e2d4a92aedaf3d6a5d9a70a..54ecf0b6dc9db4eaf3fcfd74062c55e6372bb18c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Lapply.java @@ -33,6 +33,7 @@ import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNodeGen; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.LapplyNodeGen.LapplyInternalNodeGen; @@ -45,7 +46,6 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RSource; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -69,8 +69,6 @@ public abstract class Lapply extends RBuiltinNode { private static final Source CALL_SOURCE = RSource.fromTextInternal("FUN(X[[i]], ...)", RSource.Internal.LAPPLY); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - @Child private LapplyInternalNode lapply = LapplyInternalNodeGen.create(); @Override @@ -83,10 +81,10 @@ public abstract class Lapply extends RBuiltinNode { } @Specialization - protected Object lapply(VirtualFrame frame, RAbstractVector vec, RFunction fun) { + protected Object lapply(VirtualFrame frame, RAbstractVector vec, RFunction fun, @Cached("create()") GetNamesAttributeNode getNamesNode) { Object[] result = lapply.execute(frame, vec, fun); // set here else it gets overridden by the iterator evaluation - return RDataFactory.createList(result, vec.getNames(attrProfiles)); + return RDataFactory.createList(result, getNamesNode.getNames(vec)); } private static final class ExtractElementInternal extends RSourceSectionNode implements RSyntaxCall { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java index 8532659c5be0afa030c0bac1a55a0e52f9406904..457eca9da958eace8975e6ec36c6fb2cd25d90ca 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LogFunctions.java @@ -32,6 +32,8 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.UnaryArithmeticBuiltinNode; @@ -39,7 +41,6 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; @@ -80,7 +81,8 @@ public class LogFunctions { @Specialization protected RDoubleVector log(RAbstractIntVector vector, double base, @Cached("create()") CopyOfRegAttributesNode copyAttrsNode, - @Cached("create()") RAttributeProfiles attrProfiles) { + @Cached("create()") GetNamesAttributeNode getNamesNode, + @Cached("create()") GetDimAttributeNode getDimsNode) { double[] resultVector = new double[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { int inputValue = vector.getDataAt(i); @@ -90,13 +92,14 @@ public class LogFunctions { } resultVector[i] = result; } - return createResult(vector, resultVector, base, copyAttrsNode, attrProfiles); + return createResult(vector, resultVector, base, copyAttrsNode, getNamesNode, getDimsNode); } @Specialization protected RDoubleVector log(RAbstractDoubleVector vector, double base, @Cached("create()") CopyOfRegAttributesNode copyAttrsNode, - @Cached("create()") RAttributeProfiles attrProfiles) { + @Cached("create()") GetNamesAttributeNode getNamesNode, + @Cached("create()") GetDimAttributeNode getDimsNode) { double[] doubleVector = new double[vector.getLength()]; for (int i = 0; i < vector.getLength(); i++) { double value = vector.getDataAt(i); @@ -105,7 +108,7 @@ public class LogFunctions { } doubleVector[i] = value; } - return createResult(vector, doubleVector, base, copyAttrsNode, attrProfiles); + return createResult(vector, doubleVector, base, copyAttrsNode, getNamesNode, getDimsNode); } private double logb(double x, double base) { @@ -121,8 +124,9 @@ public class LogFunctions { return Math.log(x) / Math.log(base); } - private static RDoubleVector createResult(RAbstractVector source, double[] resultData, double base, CopyOfRegAttributesNode copyAttrsNode, RAttributeProfiles attrProfiles) { - RDoubleVector result = RDataFactory.createDoubleVector(resultData, source.isComplete() && !RRuntime.isNA(base), source.getDimensions(), source.getNames(attrProfiles)); + private static RDoubleVector createResult(RAbstractVector source, double[] resultData, double base, CopyOfRegAttributesNode copyAttrsNode, GetNamesAttributeNode getNamesNode, + GetDimAttributeNode getDimsNode) { + RDoubleVector result = RDataFactory.createDoubleVector(resultData, source.isComplete() && !RRuntime.isNA(base), getDimsNode.getDimensions(source), getNamesNode.getNames(source)); copyAttrsNode.execute(source, result); return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java index f363a88b079d661e0154ec885754984e446561d8..372547fa0f8364b32aa5a51ea702a98dcaeaae62 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mapply.java @@ -37,6 +37,7 @@ import com.oracle.truffle.r.nodes.access.FrameSlotNode; import com.oracle.truffle.r.nodes.access.WriteVariableNode; import com.oracle.truffle.r.nodes.access.WriteVariableNode.Mode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.MapplyNodeGen.MapplyInternalNodeGen; @@ -49,7 +50,6 @@ import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLogicalVector; @@ -124,7 +124,7 @@ public abstract class Mapply extends RBuiltinNode { } } - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); public abstract Object[] execute(VirtualFrame frame, RAbstractListVector dots, RFunction function, RAbstractListVector additionalArguments); @@ -215,13 +215,13 @@ public abstract class Mapply extends RBuiltinNode { } Object[] values = new Object[dotsLength + moreArgsLength]; String[] names = new String[dotsLength + moreArgsLength]; - RStringVector dotsNames = dots.getNames(attrProfiles); + RStringVector dotsNames = getNames.getNames(dots); if (dotsNames != null) { for (int listIndex = 0; listIndex < dotsLength; listIndex++) { names[listIndex] = dotsNames.getDataAt(listIndex).isEmpty() ? null : dotsNames.getDataAt(listIndex); } } - RStringVector moreArgsNames = moreArgs.getNames(attrProfiles); + RStringVector moreArgsNames = getNames.getNames(moreArgs); for (int listIndex = dotsLength; listIndex < dotsLength + moreArgsLength; listIndex++) { values[listIndex] = moreArgs.getDataAt(listIndex - dotsLength); names[listIndex] = moreArgsNames == null ? null : (moreArgsNames.getDataAt(listIndex - dotsLength).isEmpty() ? null : moreArgsNames.getDataAt(listIndex - dotsLength)); @@ -260,11 +260,11 @@ public abstract class Mapply extends RBuiltinNode { protected ElementNode[] createElementNodeArray(RAbstractListVector dots, RAbstractListVector moreArgs) { int length = dots.getLength() + moreArgs.getLength(); ElementNode[] elementNodes = new ElementNode[length]; - RStringVector dotsNames = dots.getNames(attrProfiles); + RStringVector dotsNames = getNames.getNames(dots); for (int i = 0; i < dots.getLength(); i++) { elementNodes[i] = insert(new ElementNode(VECTOR_ELEMENT_PREFIX + (i + 1), dotsNames == null ? null : (dotsNames.getDataAt(i).isEmpty() ? null : dotsNames.getDataAt(i)))); } - RStringVector moreArgsNames = moreArgs.getNames(attrProfiles); + RStringVector moreArgsNames = getNames.getNames(moreArgs); for (int i = dots.getLength(); i < dots.getLength() + moreArgs.getLength(); i++) { elementNodes[i] = insert(new ElementNode(VECTOR_ELEMENT_PREFIX + (i + 1), moreArgsNames == null ? null : moreArgsNames.getDataAt(i - dots.getLength()).isEmpty() ? null : moreArgsNames.getDataAt(i - dots.getLength()))); @@ -289,14 +289,17 @@ public abstract class Mapply extends RBuiltinNode { } protected boolean sameNames(RAbstractListVector list, RAbstractListVector cachedList) { - if (list.getNames(attrProfiles) == null && cachedList.getNames(attrProfiles) == null) { + RStringVector listNames = getNames.getNames(list); + RStringVector cachedListNames = getNames.getNames(cachedList); + if (listNames == null && cachedListNames == null) { return true; - } else if (list.getNames(attrProfiles) == null || cachedList.getNames(attrProfiles) == null) { + } else if (listNames == null || cachedListNames == null) { return false; } else { + for (int i = 0; i < list.getLength(); i++) { - String name = list.getNames(attrProfiles).getDataAt(i); - String cachedName = cachedList.getNames(attrProfiles).getDataAt(i); + String name = listNames.getDataAt(i); + String cachedName = cachedListNames.getDataAt(i); if (name == cachedName) { continue; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java index c7a5ea146e47895dba8a926822b61db083c8c696..7bee0fa552fc045332ea15babf8bdaa0daca15f6 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java @@ -34,12 +34,15 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.binary.BinaryMapArithmeticFunctionNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -71,10 +74,12 @@ public abstract class MatMult extends RBuiltinNode { private final ConditionProfile notOneRow = ConditionProfile.createBinaryProfile(); private final ConditionProfile notOneColumn = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles aDimAttributeProfile = RAttributeProfiles.create(); - private final RAttributeProfiles bDimAttributeProfile = RAttributeProfiles.create(); private final ConditionProfile noDimAttributes = ConditionProfile.createBinaryProfile(); + @Child protected GetDimAttributeNode getADimsNode = GetDimAttributeNode.create(); + @Child protected GetDimAttributeNode getBDimsNode = GetDimAttributeNode.create(); + @Child protected SetDimAttributeNode setDimsNode = SetDimAttributeNode.create(); + protected abstract Object executeObject(Object a, Object b); private final NACheck na; @@ -88,24 +93,26 @@ public abstract class MatMult extends RBuiltinNode { return MatMultNodeGen.create(true); } - @Specialization(guards = "bothZeroDim(a, b)") + @Specialization(guards = "bothZeroDim(a, b, getADimsNode, getBDimsNode)") protected RDoubleVector both0Dim(RAbstractDoubleVector a, RAbstractDoubleVector b) { - int r = b.getDimensions()[1]; - int c = a.getDimensions()[0]; + int r = getBDimsNode.getDimensions(b)[1]; + int c = getADimsNode.getDimensions(a)[0]; RDoubleVector result = RDataFactory.createDoubleVector(r * c); - result.setDimensions(new int[]{r, c}); + setDimsNode.setDimensions(result, new int[]{r, c}); return result; } - @Specialization(guards = "hasZeroDim(a)") + @Specialization(guards = "hasZeroDim(a, getADimsNode)") protected RAbstractVector left0Dim(RAbstractVector a, RAbstractVector b) { - int[] dim = a.getDimensions()[0] == 0 ? new int[]{0, b.getDimensions()[1]} : new int[]{b.getDimensions()[0], 0}; + int[] aDim = getADimsNode.getDimensions(a); + int[] dim = aDim[0] == 0 ? new int[]{0, getBDimsNode.getDimensions(b)[1]} : new int[]{getBDimsNode.getDimensions(b)[0], 0}; return a.copyWithNewDimensions(dim); } - @Specialization(guards = "hasZeroDim(b)") + @Specialization(guards = "hasZeroDim(b, getBDimsNode)") protected RAbstractVector right0Dim(RAbstractVector a, RAbstractVector b) { - int[] dim = b.getDimensions()[0] == 0 ? new int[]{0, a.getDimensions()[1]} : new int[]{a.getDimensions()[0], 0}; + int[] bDim = getBDimsNode.getDimensions(b); + int[] dim = bDim[0] == 0 ? new int[]{0, getADimsNode.getDimensions(a)[1]} : new int[]{getADimsNode.getDimensions(a)[0], 0}; return b.copyWithNewDimensions(dim); } @@ -133,8 +140,9 @@ public abstract class MatMult extends RBuiltinNode { private final BranchProfile incompleteProfile = BranchProfile.create(); @CompilationFinal private boolean seenLargeMatrix; - private RDoubleVector doubleMatrixMultiply(RAbstractDoubleVector a, RAbstractDoubleVector b, int aRows, int aCols, int bRows, int bCols) { - return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols, 1, aRows, 1, bRows, false); + private RDoubleVector doubleMatrixMultiply(RAbstractDoubleVector a, RAbstractDoubleVector b, int aRows, int aCols, int bRows, int bCols, SetDimNamesAttributeNode setDimNamesNode, + GetDimNamesAttributeNode getADimNamesNode, GetDimNamesAttributeNode getBDimNamesNode) { + return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols, 1, aRows, 1, bRows, false, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } /** @@ -155,7 +163,7 @@ public abstract class MatMult extends RBuiltinNode { * @return the result vector */ public RDoubleVector doubleMatrixMultiply(RAbstractDoubleVector a, RAbstractDoubleVector b, int aRows, int aCols, int bRows, int bCols, int aRowStride, int aColStride, int bRowStride, - int bColStride, boolean mirrored) { + int bColStride, boolean mirrored, SetDimNamesAttributeNode setDimNamesNode, GetDimNamesAttributeNode getADimNamesNode, GetDimNamesAttributeNode getBDimNamesNode) { if (aCols != bRows) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -207,8 +215,8 @@ public abstract class MatMult extends RBuiltinNode { } RDoubleVector resultVec = RDataFactory.createDoubleVector(result, complete, new int[]{aRows, bCols}); - RList aDimNames = a.getDimNames(aDimAttributeProfile); - RList bDimNames = b.getDimNames(bDimAttributeProfile); + RList aDimNames = getADimNamesNode.getDimNames(a); + RList bDimNames = getBDimNamesNode.getDimNames(b); if (!promoteDimNames || noDimAttributes.profile(aDimNames == null && bDimNames == null)) { return resultVec; } @@ -220,7 +228,7 @@ public abstract class MatMult extends RBuiltinNode { if (bDimNames != null && bDimNames.getLength() > 1) { newDimsNames[1] = bDimNames.getDataAt(1); } - resultVec.setDimNames(RDataFactory.createList(newDimsNames)); + setDimNamesNode.setDimNames(resultVec, RDataFactory.createList(newDimsNames)); return resultVec; } @@ -265,15 +273,19 @@ public abstract class MatMult extends RBuiltinNode { protected RDoubleVector multiply(RAbstractDoubleVector a, RAbstractDoubleVector b, @Cached("createBinaryProfile()") ConditionProfile aIsMatrix, @Cached("createBinaryProfile()") ConditionProfile bIsMatrix, - @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { + @Cached("createBinaryProfile()") ConditionProfile lengthEquals, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { if (aIsMatrix.profile(a.isMatrix())) { if (bIsMatrix.profile(b.isMatrix())) { - int[] aDimensions = a.getDimensions(); - int[] bDimensions = b.getDimensions(); - return doubleMatrixMultiply(a, b, aDimensions[0], aDimensions[1], bDimensions[0], bDimensions[1]); + int[] aDimensions = getADimsNode.getDimensions(a); + int[] bDimensions = getBDimsNode.getDimensions(b); + return doubleMatrixMultiply(a, b, aDimensions[0], aDimensions[1], bDimensions[0], bDimensions[1], setDimNamesNode, getADimNamesNode, getBDimNamesNode); } else { - int aRows = a.getDimensions()[0]; - int aCols = a.getDimensions()[1]; + int[] aDim = getADimsNode.getDimensions(a); + int aRows = aDim[0]; + int aCols = aDim[1]; int bRows; int bCols; if (lengthEquals.profile(aCols == b.getLength())) { @@ -283,12 +295,13 @@ public abstract class MatMult extends RBuiltinNode { bRows = 1; bCols = b.getLength(); } - return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols); + return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } } else { if (bIsMatrix.profile(b.isMatrix())) { - int bRows = b.getDimensions()[0]; - int bCols = b.getDimensions()[1]; + int[] bDim = getBDimsNode.getDimensions(b); + int bRows = bDim[0]; + int bCols = bDim[1]; int aRows; int aCols; if (lengthEquals.profile(bRows == a.getLength())) { @@ -298,7 +311,7 @@ public abstract class MatMult extends RBuiltinNode { aRows = a.getLength(); aCols = 1; } - return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols); + return doubleMatrixMultiply(a, b, aRows, aCols, bRows, bCols, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } else { if (a.getLength() != b.getLength()) { errorProfile.enter(); @@ -328,14 +341,16 @@ public abstract class MatMult extends RBuiltinNode { @Cached("createBinaryProfile()") ConditionProfile bIsMatrix) { if (aIsMatrix.profile(a.isMatrix())) { if (bIsMatrix.profile(b.isMatrix())) { - final int aCols = a.getDimensions()[1]; - final int bRows = b.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + int[] bDim = getBDimsNode.getDimensions(b); + final int aCols = aDim[1]; + final int bRows = bDim[0]; if (aCols != bRows) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); } - final int aRows = a.getDimensions()[0]; - final int bCols = b.getDimensions()[1]; + final int aRows = aDim[0]; + final int bCols = bDim[1]; double[] result = new double[(aRows * bCols) << 1]; na.enable(a); na.enable(b); @@ -353,8 +368,9 @@ public abstract class MatMult extends RBuiltinNode { } return RDataFactory.createComplexVector(result, na.neverSeenNA(), new int[]{aRows, bCols}); } else { - final int aCols = a.getDimensions()[1]; - final int aRows = a.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + final int aCols = aDim[1]; + final int aRows = aDim[0]; if (aCols != 1 && aCols != b.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -388,8 +404,9 @@ public abstract class MatMult extends RBuiltinNode { } } else { if (bIsMatrix.profile(b.isMatrix())) { - final int bRows = b.getDimensions()[0]; - final int bCols = b.getDimensions()[1]; + int[] bDim = getBDimsNode.getDimensions(b); + final int bRows = bDim[0]; + final int bCols = bDim[1]; if (bRows != 1 && bRows != a.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -445,14 +462,16 @@ public abstract class MatMult extends RBuiltinNode { @Cached("createBinaryProfile()") ConditionProfile bIsMatrix) { if (aIsMatrix.profile(a.isMatrix())) { if (bIsMatrix.profile(b.isMatrix())) { - final int aCols = a.getDimensions()[1]; - final int bRows = b.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + int[] bDim = getBDimsNode.getDimensions(b); + final int aCols = aDim[1]; + final int bRows = bDim[0]; if (aCols != bRows) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); } - final int aRows = a.getDimensions()[0]; - final int bCols = b.getDimensions()[1]; + final int aRows = aDim[0]; + final int bCols = bDim[1]; int[] result = new int[aRows * bCols]; na.enable(a); na.enable(b); @@ -468,8 +487,9 @@ public abstract class MatMult extends RBuiltinNode { } return RDataFactory.createIntVector(result, na.neverSeenNA(), new int[]{aRows, bCols}); } else { - final int aCols = a.getDimensions()[1]; - final int aRows = a.getDimensions()[0]; + int[] aDim = getADimsNode.getDimensions(a); + final int aCols = aDim[1]; + final int aRows = aDim[0]; if (aCols != 1 && aCols != b.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -500,9 +520,10 @@ public abstract class MatMult extends RBuiltinNode { } } } else { + int[] bDim = getBDimsNode.getDimensions(b); if (bIsMatrix.profile(b.isMatrix())) { - final int bCols = b.getDimensions()[1]; - final int bRows = b.getDimensions()[0]; + final int bCols = bDim[1]; + final int bRows = bDim[0]; if (bRows != 1 && bRows != a.getLength()) { errorProfile.enter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARGS); @@ -622,32 +643,44 @@ public abstract class MatMult extends RBuiltinNode { protected RDoubleVector multiply(RAbstractIntVector a, RAbstractDoubleVector b, @Cached("createBinaryProfile()") ConditionProfile aIsMatrix, @Cached("createBinaryProfile()") ConditionProfile bIsMatrix, - @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { - return multiply(RClosures.createIntToDoubleVector(a), b, aIsMatrix, bIsMatrix, lengthEquals); + @Cached("createBinaryProfile()") ConditionProfile lengthEquals, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + return multiply(RClosures.createIntToDoubleVector(a), b, aIsMatrix, bIsMatrix, lengthEquals, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } @Specialization protected RDoubleVector multiply(RAbstractDoubleVector a, RAbstractIntVector b, @Cached("createBinaryProfile()") ConditionProfile aIsMatrix, @Cached("createBinaryProfile()") ConditionProfile bIsMatrix, - @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { - return multiply(a, RClosures.createIntToDoubleVector(b), aIsMatrix, bIsMatrix, lengthEquals); + @Cached("createBinaryProfile()") ConditionProfile lengthEquals, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + return multiply(a, RClosures.createIntToDoubleVector(b), aIsMatrix, bIsMatrix, lengthEquals, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } @Specialization protected RDoubleVector multiply(RAbstractLogicalVector a, RAbstractDoubleVector b, @Cached("createBinaryProfile()") ConditionProfile aIsMatrix, @Cached("createBinaryProfile()") ConditionProfile bIsMatrix, - @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { - return multiply(RClosures.createLogicalToDoubleVector(a), b, aIsMatrix, bIsMatrix, lengthEquals); + @Cached("createBinaryProfile()") ConditionProfile lengthEquals, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + return multiply(RClosures.createLogicalToDoubleVector(a), b, aIsMatrix, bIsMatrix, lengthEquals, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } @Specialization protected RDoubleVector multiply(RAbstractDoubleVector a, RAbstractLogicalVector b, @Cached("createBinaryProfile()") ConditionProfile aIsMatrix, @Cached("createBinaryProfile()") ConditionProfile bIsMatrix, - @Cached("createBinaryProfile()") ConditionProfile lengthEquals) { - return multiply(a, RClosures.createLogicalToDoubleVector(b), aIsMatrix, bIsMatrix, lengthEquals); + @Cached("createBinaryProfile()") ConditionProfile lengthEquals, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getADimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getBDimNamesNode) { + return multiply(a, RClosures.createLogicalToDoubleVector(b), aIsMatrix, bIsMatrix, lengthEquals, setDimNamesNode, getADimNamesNode, getBDimNamesNode); } // errors @@ -660,15 +693,16 @@ public abstract class MatMult extends RBuiltinNode { // guards - protected static boolean bothZeroDim(RAbstractVector a, RAbstractVector b) { - return hasZeroDim(a) && hasZeroDim(b); + protected static boolean bothZeroDim(RAbstractVector a, RAbstractVector b, GetDimAttributeNode getADimsNode, GetDimAttributeNode getBDimsNode) { + return hasZeroDim(a, getADimsNode) && hasZeroDim(b, getBDimsNode); } - protected static boolean hasZeroDim(RAbstractVector v) { - if (!v.hasDimensions()) { + protected static boolean hasZeroDim(RAbstractVector v, GetDimAttributeNode getDimsNode) { + int[] dims = getDimsNode.getDimensions(v); + if (dims == null || dims.length == 0) { return false; } - for (int d : v.getDimensions()) { + for (int d : dims) { if (d == 0) { return true; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchArg.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchArg.java new file mode 100644 index 0000000000000000000000000000000000000000..bc6405b87dad17cc3a56e2b301868c6686a84bbc --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/MatchArg.java @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2016, 2016, 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.nodes.builtin.base; + +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.logicalValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.toBoolean; +import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; +import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.SUBSTITUTE; + +import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.CompilerDirectives; +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.dsl.TypeSystemReference; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.RRootNode; +import com.oracle.truffle.r.nodes.builtin.CastBuilder; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.builtin.base.MatchArgNodeGen.MatchArgInternalNodeGen; +import com.oracle.truffle.r.nodes.function.FormalArguments; +import com.oracle.truffle.r.nodes.function.PromiseHelperNode; +import com.oracle.truffle.r.nodes.unary.CastNode; +import com.oracle.truffle.r.runtime.RArguments; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RError.Message; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.builtins.RBuiltin; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RPromise; +import com.oracle.truffle.r.runtime.data.RTypes; +import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; +import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; + +@RBuiltin(name = "match.arg", kind = SUBSTITUTE, parameterNames = {"arg", "choices", "several.ok"}, nonEvalArgs = {0}, behavior = COMPLEX) +public abstract class MatchArg extends RBuiltinNode { + + @Override + public Object[] getDefaultParameterValues() { + return new Object[]{RMissing.instance, RMissing.instance, RRuntime.LOGICAL_FALSE}; + } + + @TypeSystemReference(RTypes.class) + protected abstract static class MatchArgInternal extends Node { + + @Child private PMatch pmatch = PMatchNodeGen.create(); + @Child private Identical identical = IdenticalNodeGen.create(); + + @Children private final CastNode[] casts; + + { + CastBuilder builder = new CastBuilder(); + builder.arg(0).allowNull().asStringVector(); + builder.arg(1).allowMissing().mustBe(stringValue()).asStringVector(); + builder.arg(2).mustBe(logicalValue()).asLogicalVector().findFirst().map(toBoolean()); + this.casts = builder.getCasts(); + } + + public abstract Object execute(Object arg, Object choices, Object severalOK); + + public final Object castAndExecute(Object arg, Object choices, Object severalOK) { + return execute(casts[0].execute(arg), casts[1].execute(choices), casts[2].execute(severalOK)); + } + + @Specialization + protected String matchArgNULL(@SuppressWarnings("unused") RNull arg, RAbstractStringVector choices, @SuppressWarnings("unused") boolean severalOK, + @Cached("createBinaryProfile()") ConditionProfile isEmptyProfile) { + return isEmptyProfile.profile(choices.getLength() == 0) ? RRuntime.STRING_NA : choices.getDataAt(0); + } + + private void checkEmpty(RAbstractStringVector choices, int count) { + if (count == 0) { + CompilerDirectives.transferToInterpreter(); + StringBuilder choicesString = new StringBuilder(); + for (int i = 0; i < choices.getLength(); i++) { + choicesString.append(i == 0 ? "" : ", ").append(RRuntime.quoteString(choices.getDataAt(i), false)); + } + throw RError.error(this, Message.ARG_ONE_OF, "arg", choicesString); + } + } + + private static int count(RIntVector matched) { + int count = 0; + for (int i = 0; i < matched.getLength(); i++) { + if (matched.getDataAt(i) != -1) { + count++; + } + } + return count; + } + + @Specialization(guards = "!severalOK") + protected String matchArg(RAbstractStringVector arg, RAbstractStringVector choices, @SuppressWarnings("unused") boolean severalOK) { + if (identical.executeByte(arg, choices, true, true, true, true, true) == RRuntime.LOGICAL_TRUE) { + return choices.getDataAt(0); + } + if (arg.getLength() != 1) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, Message.MUST_BE_SCALAR, "arg"); + } + RIntVector matched = pmatch.execute(arg, choices, -1, true); + int count = count(matched); + checkEmpty(choices, count); + if (count > 1) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, Message.MORE_THAN_ONE_MATCH, "match.arg"); + } + return choices.getDataAt(matched.getDataAt(0) - 1); + } + + @Specialization(guards = "severalOK") + protected Object matchArgSeveral(RAbstractStringVector arg, RAbstractStringVector choices, @SuppressWarnings("unused") boolean severalOK) { + if (arg.getLength() == 0) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, Message.MUST_BE_GE_ONE, "arg"); + } + RIntVector matched = pmatch.execute(arg, choices, -1, true); + int count = count(matched); + if (count == 1) { + return choices.getDataAt(matched.getDataAt(0) - 1); + } + checkEmpty(choices, count); + String[] result = new String[count]; + for (int i = 0; i < matched.getLength(); i++) { + result[i] = choices.getDataAt(matched.getDataAt(i) - 1); + } + return RDataFactory.createStringVector(result, choices.isComplete()); + } + } + + protected static final class MatchArgChoices extends Node { + + private final CallTarget target; + private final String symbol; + + @Child private RNode value; + + public MatchArgChoices(VirtualFrame frame, RPromise arg) { + CompilerAsserts.neverPartOfCompilation(); + + RFunction function = RArguments.getFunction(frame); + assert function.getRBuiltin() == null; + + this.symbol = arg.getClosure().asSymbol(); + if (symbol == null) { + throw RError.error(this, Message.INVALID_USE, "match.arg"); + } + + RRootNode def = (RRootNode) function.getRootNode(); + this.target = function.getTarget(); + FormalArguments arguments = def.getFormalArguments(); + + for (int i = 0; i < arguments.getLength(); i++) { + assert symbol == arguments.getSignature().getName(i) || !symbol.equals(arguments.getSignature().getName(i)); + if (symbol == arguments.getSignature().getName(i)) { + RNode defaultArg = arguments.getDefaultArgument(i); + if (defaultArg == null) { + this.value = RContext.getASTBuilder().constant(RSyntaxNode.INTERNAL, RDataFactory.createEmptyStringVector()).asRNode(); + } + this.value = RContext.getASTBuilder().process(defaultArg.asRSyntaxNode()).asRNode(); + return; + } + } + throw RError.error(RError.SHOW_CALLER, Message.INVALID_USE, "match.arg"); + } + + public boolean isSupported(VirtualFrame frame, RPromise arg) { + return RArguments.getFunction(frame).getTarget() == target && arg.getClosure().asSymbol() == symbol; + } + + public Object execute(VirtualFrame frame) { + return value.execute(frame); + } + } + + protected static MatchArgInternal createInternal() { + return MatchArgInternalNodeGen.create(); + } + + @Specialization(limit = "3", guards = "choicesValue.isSupported(frame, arg)") + protected Object matchArg(VirtualFrame frame, RPromise arg, @SuppressWarnings("unused") RMissing choices, Object severalOK, + @Cached("new(frame, arg)") MatchArgChoices choicesValue, + @Cached("createInternal()") MatchArgInternal internal, + @Cached("new()") PromiseHelperNode promiseHelper) { + return internal.castAndExecute(promiseHelper.evaluate(frame, arg), choicesValue.execute(frame), severalOK); + } + + protected static boolean isRMissing(Object value) { + return value instanceof RMissing; + } + + @Specialization(guards = "!isRMissing(choices)") + protected Object matchArg(VirtualFrame frame, RPromise arg, Object choices, Object severalOK, + @Cached("createInternal()") MatchArgInternal internal, + @Cached("new()") PromiseHelperNode promiseHelper) { + return internal.castAndExecute(promiseHelper.evaluate(frame, arg), choices, severalOK); + } + + @SuppressWarnings("unused") + @Fallback + protected Object matchArgFallback(Object arg, Object choices, Object severalOK) { + throw RError.error(this, Message.GENERIC, "too many different names in match.arg"); + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java index bec8a180fab423d0887b7139cc7907743180d4a5..0895f7591631e6d7ef4c4630ecd35884c4923457 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Matrix.java @@ -28,8 +28,10 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -75,7 +77,8 @@ public abstract class Matrix extends RBuiltinNode { } @Specialization - protected RAbstractVector matrix(RAbstractVector data, int nrow, int ncol, boolean byrow, Object dimnames, boolean missingNr, boolean missingNc) { + protected RAbstractVector matrix(RAbstractVector data, int nrow, int ncol, boolean byrow, Object dimnames, boolean missingNr, boolean missingNc, + @Cached("create()") SetDimAttributeNode setDimNode) { int[] dim; if (byrowProfile.profile(byrow)) { dim = computeDimByRow(data.getLength(), nrow, ncol, missingNr, missingNc); @@ -99,7 +102,7 @@ public abstract class Matrix extends RBuiltinNode { } } else { res = data.createEmptySameType(0, RDataFactory.COMPLETE_VECTOR); - res.setDimensions(dim); + setDimNode.setDimensions(res, dim); } } else { res = data.copyResizedWithDimensions(dim, false); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java index 1f0a0a0deb44b0cb65f736923ed39858c624ab8f..c2faec1d69a4fca54a7103a68e8e3552c7ac485b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java @@ -33,11 +33,14 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RList; @@ -67,8 +70,11 @@ public abstract class NChar extends RBuiltinNode { @Specialization protected RIntVector ncharInt(RAbstractIntVector vector, String type, boolean allowNA, boolean keepNA, @Cached("createCountingProfile()") LoopConditionProfile loopProfile, - @Cached("create()") RAttributeProfiles attrProfiles, - @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile) { + @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile, + @Cached("create()") GetDimAttributeNode getDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { int len = vector.getLength(); int[] result = new int[len]; loopProfile.profileCounted(len); @@ -80,10 +86,10 @@ public abstract class NChar extends RBuiltinNode { result[i] = (int) (Math.log10(x) + 1); // not the fastest one } } - RIntVector resultVector = RDataFactory.createIntVector(result, true, vector.getDimensions(), vector.getNames(attrProfiles)); - RList dimNames = vector.getDimNames(attrProfiles); + RIntVector resultVector = RDataFactory.createIntVector(result, true, getDimNode.getDimensions(vector), getNamesNode.getNames(vector)); + RList dimNames = getDimNamesNode.getDimNames(vector); if (nullDimNamesProfile.profile(dimNames != null)) { - resultVector.setDimNames(dimNames); + setDimNamesNode.setDimNames(resultVector, dimNames); } return resultVector; } @@ -92,18 +98,21 @@ public abstract class NChar extends RBuiltinNode { @Specialization protected RIntVector nchar(RAbstractStringVector vector, String type, boolean allowNA, boolean keepNA, @Cached("createCountingProfile()") LoopConditionProfile loopProfile, - @Cached("create()") RAttributeProfiles attrProfiles, - @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile) { + @Cached("createBinaryProfile()") ConditionProfile nullDimNamesProfile, + @Cached("create()") GetDimAttributeNode getDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") GetDimNamesAttributeNode getDimNamesNode, + @Cached("create()") GetNamesAttributeNode getNamesNode) { int len = vector.getLength(); int[] result = new int[len]; loopProfile.profileCounted(len); for (int i = 0; loopProfile.inject(i < len); i++) { result[i] = vector.getDataAt(i).length(); } - RIntVector resultVector = RDataFactory.createIntVector(result, true, vector.getDimensions(), vector.getNames(attrProfiles)); - RList dimNames = vector.getDimNames(attrProfiles); + RIntVector resultVector = RDataFactory.createIntVector(result, true, getDimNode.getDimensions(vector), getNamesNode.getNames(vector)); + RList dimNames = getDimNamesNode.getDimNames(vector); if (nullDimNamesProfile.profile(dimNames != null)) { - resultVector.setDimNames(dimNames); + setDimNamesNode.setDimNames(resultVector, dimNames); } return resultVector; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java index 91e6f763bcd36279b045cded3fa328d0a1cdf242..55c50f76361cc2080b1c84120370207135a03ece 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java @@ -30,10 +30,11 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 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.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -41,12 +42,13 @@ import com.oracle.truffle.r.runtime.env.REnvironment; public abstract class Names extends RBuiltinNode { private final ConditionProfile hasNames = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @Specialization protected Object getNames(RAbstractContainer container) { - if (hasNames.profile(container.getNames(attrProfiles) != null)) { - return container.getNames(attrProfiles); + RStringVector names = getNames.getNames(container); + if (hasNames.profile(names != null)) { + return names; } else { return RNull.instance; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NumericalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NumericalFunctions.java index b955f976259a0570876ef29af61ae0c96e28c07f..072c6f76b689b375b95430309b4f2bc7bb0a64d0 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NumericalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NumericalFunctions.java @@ -264,12 +264,12 @@ public class NumericalFunctions { public abstract static class Sign extends UnaryArithmeticBuiltinNode { public Sign() { - super(RType.Logical); + super(RType.Double, RError.Message.NON_NUMERIC_MATH, null); } @Override protected void createCasts(CastBuilder casts) { - casts.arg("x").defaultError(RError.Message.UNIMPLEMENTED_COMPLEX_FUN).mustBe(numericValue()); + casts.arg("x").defaultError(RError.Message.NON_NUMERIC_MATH).mustBe(complexValue().not(), RError.Message.UNIMPLEMENTED_COMPLEX_FUN).mustBe(numericValue()); } @Override diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java index f5487620db0fb63a21abd652f71710e0cf582d99..9486a8a9d9f6bde07fe95e17735384e70462fcb8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/OptionsFunctions.java @@ -22,7 +22,7 @@ */ package com.oracle.truffle.r.nodes.builtin.base; -import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.*; +import static com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef.stringValue; import static com.oracle.truffle.r.runtime.RVisibility.CUSTOM; import static com.oracle.truffle.r.runtime.builtins.RBehavior.MODIFIES_STATE; import static com.oracle.truffle.r.runtime.builtins.RBehavior.READS_STATE; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java index 4f841fb44d50e02358d9a6f652bc4736735e83ee..ad4cbd55f2405b4a34761c15835f1a5b45127e3f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java @@ -43,6 +43,8 @@ public abstract class PMatch extends RBuiltinNode { private final ConditionProfile nomatchNA = ConditionProfile.createBinaryProfile(); + public abstract RIntVector execute(RAbstractStringVector x, RAbstractStringVector table, int nomatch, boolean duplicatesOk); + @Override protected void createCasts(CastBuilder casts) { casts.arg("x").asStringVector(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java index 8ac93354d9a2fdb4f9223c82978ee91a8110bf19..07a3c5f15a5a4458d230723f3b594788c05983c8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java @@ -35,6 +35,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNode; @@ -96,6 +97,10 @@ public abstract class Parse extends RBuiltinNode { @Child private CastStringNode castStringNode; @Child private CastToVectorNode castVectorNode; + @Child private SetFixedAttributeNode setSrcRefAttrNode = SetFixedAttributeNode.create("srcref"); + @Child private SetFixedAttributeNode setWholeSrcRefAttrNode = SetFixedAttributeNode.create("wholeSrcref"); + @Child private SetFixedAttributeNode setSrcFileAttrNode = SetFixedAttributeNode.create("srcfile"); + @Override protected void createCasts(CastBuilder casts) { // Note: string is captured by the R wrapper and transformed to a file, other types not @@ -219,7 +224,7 @@ public abstract class Parse extends RBuiltinNode { } } - private static void addAttributes(RExpression exprs, Source source, REnvironment srcFile) { + private void addAttributes(RExpression exprs, Source source, REnvironment srcFile) { Object[] srcrefData = new Object[exprs.getLength()]; for (int i = 0; i < srcrefData.length; i++) { Object data = exprs.getDataAt(i); @@ -239,7 +244,7 @@ public abstract class Parse extends RBuiltinNode { } } - exprs.setAttr("srcref", RDataFactory.createList(srcrefData)); + setSrcRefAttrNode.execute(exprs, RDataFactory.createList(srcrefData)); int[] wholeSrcrefData = new int[8]; int endOffset = source.getCode().length() - 1; wholeSrcrefData[0] = source.getLineNumber(0); @@ -248,8 +253,8 @@ public abstract class Parse extends RBuiltinNode { wholeSrcrefData[6] = wholeSrcrefData[0]; wholeSrcrefData[6] = wholeSrcrefData[3]; - exprs.setAttr("wholeSrcref", RDataFactory.createIntVector(wholeSrcrefData, RDataFactory.COMPLETE_VECTOR)); - exprs.setAttr("srcfile", srcFile); + setWholeSrcRefAttrNode.execute(exprs, RDataFactory.createIntVector(wholeSrcrefData, RDataFactory.COMPLETE_VECTOR)); + setSrcFileAttrNode.execute(exprs, srcFile); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java index be182b91b23a5b1ef9147f6ae56359df1f2d456c..24496e3ae2d465157530b90cb0d3a2f76122ff08 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ProcTime.java @@ -27,6 +27,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; @@ -44,6 +45,8 @@ public abstract class ProcTime extends RBuiltinNode { private static RStringVector RNAMES; + @Child private SetClassAttributeNode setClassAttrNode = SetClassAttributeNode.create(); + @Specialization @TruffleBoundary protected RDoubleVector procTime() { @@ -65,7 +68,8 @@ public abstract class ProcTime extends RBuiltinNode { RNAMES = RDataFactory.createStringVector(NAMES, RDataFactory.COMPLETE_VECTOR); } RDoubleVector result = RDataFactory.createDoubleVector(data, complete, RNAMES); - result.setClassAttr(PROC_TIME_CLASS); + setClassAttrNode.execute(result, PROC_TIME_CLASS); + return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RawToBits.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RawToBits.java new file mode 100644 index 0000000000000000000000000000000000000000..ec205c198a4bf9870dc143127a22bf4188ece51a --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RawToBits.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, 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.nodes.builtin.base; + +import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; +import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; + +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.builtin.CastBuilder; +import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.builtins.RBuiltin; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; + +@RBuiltin(name = "rawToBits", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE) +public abstract class RawToBits extends RBuiltinNode { + + @Override + protected void createCasts(CastBuilder casts) { + casts.arg("x").mustNotBeNull(RError.SHOW_CALLER, RError.Message.ARGUMENT_MUST_BE_RAW_VECTOR, "x").mustBe(Predef.rawValue(), RError.SHOW_CALLER, + RError.Message.ARGUMENT_MUST_BE_RAW_VECTOR, "x"); + } + + @Specialization + protected RAbstractRawVector rawToBits(RAbstractRawVector x) { + byte[] result = new byte[8 * x.getLength()]; + int pos = 0; + for (int j = 0; j < x.getLength(); j++) { + byte temp = x.getRawDataAt(j); + for (int i = 0; i < 8; i++) { + result[pos++] = (byte) (temp & 1); + temp >>= 1; + } + } + return RDataFactory.createRawVector(result); + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java index 743d510865d5285d571a2fc60fcc33c6765e69e3..e89c2645f46e5482347b24152fbff85318ef7c3a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java @@ -37,14 +37,14 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.InitAttributesNode; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -83,7 +83,7 @@ public abstract class Repeat extends RBuiltinNode { private final BranchProfile errorBranch = BranchProfile.create(); private final ConditionProfile oneTimeGiven = ConditionProfile.createBinaryProfile(); private final ConditionProfile replicateOnce = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @Override public Object[] getDefaultParameterValues() { @@ -106,7 +106,7 @@ public abstract class Repeat extends RBuiltinNode { } protected boolean hasNames(RAbstractVector x) { - return x.getNames(attrProfiles) != null; + return getNames.getNames(x) != null; } private RError invalidTimes() { @@ -158,7 +158,7 @@ public abstract class Repeat extends RBuiltinNode { throw invalidTimes(); } RAbstractVector input = handleEach(x, each); - RStringVector names = (RStringVector) handleEach(x.getNames(attrProfiles), each); + RStringVector names = (RStringVector) handleEach(getNames.getNames(x), each); RVector<?> r; if (lengthOutOrTimes.profile(!RRuntime.isNA(lengthOut))) { names = (RStringVector) handleLengthOut(names, lengthOut, false); @@ -168,7 +168,6 @@ public abstract class Repeat extends RBuiltinNode { r = handleTimes(input, times, false); } putNames.execute(initAttributes.execute(r), names); - r.setInternalNames(names); return r; } @@ -179,14 +178,13 @@ public abstract class Repeat extends RBuiltinNode { RStringVector names; RVector<?> r; if (lengthOutOrTimes.profile(!RRuntime.isNA(lengthOut))) { - names = (RStringVector) handleLengthOut(x.getNames(attrProfiles), lengthOut, true); + names = (RStringVector) handleLengthOut(getNames.getNames(x), lengthOut, true); r = handleLengthOut(x, lengthOut, true); } else { - names = (RStringVector) handleTimes(x.getNames(attrProfiles), times, true); + names = (RStringVector) handleTimes(getNames.getNames(x), times, true); r = handleTimes(x, times, true); } putNames.execute(initAttributes.execute(r), names); - r.setInternalNames(names); return r; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Return.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Return.java index 7bd403ca3263119f4d7bf6c49f089da2d93b4ca8..d2407dfe625f4cda14649e91c61417c594371646 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Return.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Return.java @@ -25,60 +25,35 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.function.PromiseHelperNode; +import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.ReturnException; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPromise; /** - * In the normal case, we are returning from the currently executing function, but in the case where - * "return" was passed as an argument (promise) (e.g. in tryCatch) to a function, we will be - * evaluating that in the context of a PromiseEvalFrame and the frame we need to return to is that - * given by the PromiseEvalFrame. + * Return a value from the currently executing function, which is identified by the + * {@link RArguments#getCall(com.oracle.truffle.api.frame.Frame) call}. The return value will be + * delivered via a {@link ReturnException}, which is subsequently caught in the + * {@link FunctionDefinitionNode}. */ -@RBuiltin(name = "return", kind = PRIMITIVE, parameterNames = {"value"}, nonEvalArgs = {0}, behavior = COMPLEX) +@RBuiltin(name = "return", kind = PRIMITIVE, parameterNames = {"value"}, behavior = COMPLEX) public abstract class Return extends RBuiltinNode { private final BranchProfile isPromiseEvalProfile = BranchProfile.create(); - @Child private PromiseHelperNode promiseHelper; - - private PromiseHelperNode initPromiseHelper() { - if (promiseHelper == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - promiseHelper = insert(new PromiseHelperNode()); - } - return promiseHelper; - } - @Override public Object[] getDefaultParameterValues() { return new Object[]{RNull.instance}; } @Specialization - protected Object returnFunction(VirtualFrame frame, @SuppressWarnings("unused") RMissing arg) { - throw new ReturnException(RNull.instance, RArguments.getCall(frame)); - } - - @Specialization - protected Object returnFunction(VirtualFrame frame, RNull arg) { - throw new ReturnException(arg, RArguments.getCall(frame)); - } - - @Specialization - protected Object returnFunction(VirtualFrame frame, RPromise expr) { - // Evaluate the result - Object value = initPromiseHelper().evaluate(frame, expr); + protected Object returnFunction(VirtualFrame frame, Object value) { RCaller call = RArguments.getCall(frame); while (call.isPromise()) { isPromiseEvalProfile.enter(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java index e6bce9fd7f17f5cd0f3016bc0a853fa078a1aa93..8a5488c18d78944eeb4a906301b760a75846ef0b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Round.java @@ -32,7 +32,6 @@ import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -55,7 +54,6 @@ public abstract class Round extends RBuiltinNode { @Child private RoundArithmetic roundOp = new RoundArithmetic(); private final NACheck check = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @Override public Object[] getDefaultParameterValues() { @@ -124,7 +122,7 @@ public abstract class Round extends RBuiltinNode { result[i] = check.check(value) ? RRuntime.DOUBLE_NA : round(value, digits); } RDoubleVector ret = RDataFactory.createDoubleVector(result, check.neverSeenNA()); - ret.copyAttributesFrom(attrProfiles, x); + ret.copyAttributesFrom(x); return ret; } @@ -137,7 +135,7 @@ public abstract class Round extends RBuiltinNode { result[i] = check.check(value) ? RRuntime.DOUBLE_NA : roundDigits(value, digits); } RDoubleVector ret = RDataFactory.createDoubleVector(result, check.neverSeenNA()); - ret.copyAttributesFrom(attrProfiles, x); + ret.copyAttributesFrom(x); return ret; } @@ -165,7 +163,7 @@ public abstract class Round extends RBuiltinNode { check.check(r); } RComplexVector ret = RDataFactory.createComplexVector(result, check.neverSeenNA()); - ret.copyAttributesFrom(attrProfiles, x); + ret.copyAttributesFrom(x); return ret; } @@ -181,7 +179,7 @@ public abstract class Round extends RBuiltinNode { check.check(r); } RComplexVector ret = RDataFactory.createComplexVector(result, check.neverSeenNA()); - ret.copyAttributesFrom(attrProfiles, x); + ret.copyAttributesFrom(x); return ret; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java index 6a4d2b0e3a599bbb0089d72d2dd6ae6b81277597..d9396a717a28d8f3084ab5a169a2ab44bc4fa0ac 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Scan.java @@ -31,18 +31,18 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.conn.RConnection; import com.oracle.truffle.r.runtime.conn.StdConnections; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDouble; @@ -67,7 +67,7 @@ public abstract class Scan extends RBuiltinNode { private final NACheck naCheck = NACheck.create(); private final BranchProfile errorProfile = BranchProfile.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @Child private CastToVectorNode castVector; @@ -338,7 +338,7 @@ public abstract class Scan extends RBuiltinNode { list.updateDataAt(i, vec.createEmptySameType(blockSize, RDataFactory.COMPLETE_VECTOR), null); } } - list.setNames(what.getNames(attrProfiles)); + list.setNames(getNames.getNames(what)); naCheck.enable(true); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java index e318c352f9a7e3ded51e0bd78d06cfb50c9d1501..17a035de4a7ff78c82f6ecf809bc11439af6a064 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java @@ -31,12 +31,12 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.IntValueProfile; import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetRowNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -46,10 +46,11 @@ import com.oracle.truffle.r.runtime.env.REnvironment; public abstract class ShortRowNames extends RBuiltinNode { private final BranchProfile naValueMet = BranchProfile.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile errorProfile = BranchProfile.create(); private final ValueProfile operandTypeProfile = ValueProfile.createClassProfile(); + @Child private GetRowNamesAttributeNode getRowNamesNode = GetRowNamesAttributeNode.create(); + @Override protected void createCasts(CastBuilder casts) { casts.arg("type").asIntegerVector().findFirst().mustBe(gte0().and(lte(2))); @@ -62,9 +63,9 @@ public abstract class ShortRowNames extends RBuiltinNode { Object operand = operandTypeProfile.profile(originalOperand); Object rowNames; if (operand instanceof RAbstractContainer) { - rowNames = ((RAbstractContainer) operand).getRowNames(attrProfiles); + rowNames = getRowNamesNode.getRowNames((RAbstractContainer) operand); } else if (operand instanceof REnvironment) { - rowNames = ((REnvironment) operand).getAttr(attrProfiles, RRuntime.ROWNAMES_ATTR_KEY); + rowNames = getRowNamesNode.execute(operand); } else { // for any other type GnuR returns 0 return 0; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/StandardGeneric.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/StandardGeneric.java index 08c9e57b8c1930c4216ba587f5665ef4a229bbc6..2a590e3749181816039b058a24c41352711c8f37 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/StandardGeneric.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/StandardGeneric.java @@ -53,7 +53,8 @@ import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; -// transcribed from src/main/objects.c +// transcribed from /src/library/methods/src/methods_list_dispatch.c (R_dispatch_generic function) + @RBuiltin(name = "standardGeneric", visibility = CUSTOM, kind = PRIMITIVE, parameterNames = {"f", "fdef"}, behavior = COMPLEX) public abstract class StandardGeneric extends RBuiltinNode { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java index 0313cad4b98aec16177b01b33fe7021ffa3fa6ee..31023607abacfbcd6dffea008880f47efebf75ec 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java @@ -33,12 +33,13 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNodeGen; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; @@ -52,9 +53,10 @@ public abstract class ToLowerOrUpper { private final VectorLengthProfile lengthProfile = VectorLengthProfile.create(); private final LoopConditionProfile loopProfile = LoopConditionProfile.createCountingProfile(); private final NACheck na = NACheck.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @Child private CopyOfRegAttributesNode copyAttributes = CopyOfRegAttributesNodeGen.create(); + @Child private GetDimAttributeNode getDimNode = GetDimAttributeNode.create(); private StringMapNode() { // nothing to do @@ -82,7 +84,7 @@ public abstract class ToLowerOrUpper { String value = vector.getDataAt(i); stringVector[i] = elementFunction(value, i, function); } - RStringVector result = RDataFactory.createStringVector(stringVector, vector.isComplete(), vector.getDimensions(), vector.getNames(attrProfiles)); + RStringVector result = RDataFactory.createStringVector(stringVector, vector.isComplete(), getDimNode.getDimensions(vector), getNames.getNames(vector)); copyAttributes.execute(vector, result); return result; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java index ec945bb76c07a474ac8f40471b3ab7473c12b4d1..db8fcf308280a90a6933d6a4afd755b6a69584b6 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Transpose.java @@ -25,14 +25,14 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode; import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNodeGen; -import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.InitAttributesNode; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; @@ -50,7 +50,6 @@ import com.oracle.truffle.r.runtime.nodes.RNode; @RBuiltin(name = "t.default", kind = INTERNAL, parameterNames = {"x"}, behavior = PURE) public abstract class Transpose extends RBuiltinNode { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final BranchProfile hasDimNamesProfile = BranchProfile.create(); private final ConditionProfile isMatrixProfile = ConditionProfile.createBinaryProfile(); @@ -61,6 +60,7 @@ public abstract class Transpose extends RBuiltinNode { @Child private InitAttributesNode initAttributes = InitAttributesNode.create(); @Child private SetFixedAttributeNode putDimensions = SetFixedAttributeNode.createDim(); @Child private SetFixedAttributeNode putDimNames = SetFixedAttributeNode.createDimNames(); + @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); public abstract Object execute(RAbstractVector o); @@ -96,15 +96,13 @@ public abstract class Transpose extends RBuiltinNode { copyRegAttributes.execute(vector, r); // set new dimensions int[] newDim = new int[]{secondDim, firstDim}; - r.setInternalDimensions(newDim); putDimensions.execute(initAttributes.execute(r), RDataFactory.createIntVector(newDim, RDataFactory.COMPLETE_VECTOR)); // set new dim names - RList dimNames = vector.getDimNames(attrProfiles); + RList dimNames = getDimNamesNode.getDimNames(vector); if (dimNames != null) { hasDimNamesProfile.enter(); assert dimNames.getLength() == 2; RList newDimNames = RDataFactory.createList(new Object[]{dimNames.getDataAt(1), dimNames.getDataAt(0)}); - r.setInternalDimNames(newDimNames); putDimNames.execute(r.getAttributes(), newDimNames); } return r; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java index 03cf59487b7a937e378b58662b29d18458f38740..8558fef08d71acb5d113e9d833217db0c34a7f97 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java @@ -22,6 +22,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.UnlistNodeGen.RecursiveLengthNodeGen; @@ -31,7 +32,6 @@ import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; @@ -57,8 +57,7 @@ public abstract class Unlist extends RBuiltinNode { @Child private PrecedenceNode precedenceNode = PrecedenceNodeGen.create(); @Child private Length lengthNode; @Child private RecursiveLength recursiveLengthNode; - - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNames = GetNamesAttributeNode.create(); @TypeSystemReference(RTypes.class) protected abstract static class RecursiveLength extends Node { @@ -189,7 +188,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.RAW_PRECEDENCE: { byte[] result = new byte[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -204,7 +204,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.LOGICAL_PRECEDENCE: { byte[] result = new byte[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -220,7 +221,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.INT_PRECEDENCE: { int[] result = new int[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -236,7 +238,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.DOUBLE_PRECEDENCE: { double[] result = new double[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -252,7 +255,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.COMPLEX_PRECEDENCE: { double[] result = new double[totalSize << 1]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -268,7 +272,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.STRING_PRECEDENCE: { String[] result = new String[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -285,7 +290,8 @@ public abstract class Unlist extends RBuiltinNode { case PrecedenceNode.EXPRESSION_PRECEDENCE: { Object[] result = new Object[totalSize]; if (!recursive) { - RStringVector listNames = useNames && list.getNames(attrProfiles) != null ? list.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(list); + RStringVector listNames = useNames && ln != null ? ln : null; int position = 0; for (int i = 0; i < list.getLength(); i++) { if (list.getDataAt(i) != RNull.instance) { @@ -337,7 +343,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -373,7 +380,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -409,7 +417,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -445,7 +454,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -481,7 +491,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -522,7 +533,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); @@ -558,7 +570,8 @@ public abstract class Unlist extends RBuiltinNode { if (o instanceof RAbstractVector) { RAbstractVector v = (RAbstractVector) o; - RStringVector listNames = useNames && v.getNames(attrProfiles) != null ? v.getNames(attrProfiles) : null; + RStringVector ln = getNames.getNames(v); + RStringVector listNames = useNames && ln != null ? ln : null; for (int i = 0; i < v.getLength(); i++) { String name = itemName(listNames, i); Object cur = v.getDataAtAsObject(i); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java index 11bc95e938d5a7b6c2e3a9127e07b22fb9b2d582..34c1d680f8290eead7dfaabaed28894cabb35bd4 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java @@ -34,6 +34,10 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetRowNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNode; @@ -66,6 +70,10 @@ public abstract class UpdateAttr extends RBuiltinNode { @Child private CastIntegerNode castInteger; @Child private CastToVectorNode castVector; @Child private CastListNode castList; + @Child private SetClassAttributeNode setClassAttrNode; + @Child private SetRowNamesAttributeNode setRowNamesAttrNode; + @Child private SetAttributeNode setGenAttrNode; + @Child private SetDimAttributeNode setDimNode; @CompilationFinal private String cachedName = ""; @CompilationFinal private String cachedInternedName = ""; @@ -138,15 +146,28 @@ public abstract class UpdateAttr extends RBuiltinNode { RAbstractContainer result = (RAbstractContainer) container.getNonShared(); // the name is interned, so identity comparison is sufficient if (internedName == RRuntime.DIM_ATTR_KEY) { - result.setDimensions(null); + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + setDimNode.setDimensions(result, null); } else if (internedName == RRuntime.NAMES_ATTR_KEY) { return updateNames(result, value); } else if (internedName == RRuntime.DIMNAMES_ATTR_KEY) { return updateDimNames(result, value); } else if (internedName == RRuntime.CLASS_ATTR_KEY) { - return (RAbstractContainer) result.setClassAttr(null); + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + setClassAttrNode.reset(result); + return result; } else if (internedName == RRuntime.ROWNAMES_ATTR_KEY) { - result.setRowNames(null); + if (setRowNamesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setRowNamesAttrNode = insert(SetRowNamesAttributeNode.create()); + } + setRowNamesAttrNode.setRowNames(result, null); } else if (result.getAttributes() != null) { result.removeAttr(attrProfiles, internedName); } @@ -175,18 +196,35 @@ public abstract class UpdateAttr extends RBuiltinNode { errorProfile.enter(); throw RError.error(this, RError.Message.LENGTH_ZERO_DIM_INVALID); } - result.setDimensions(dimsVector.materialize().getDataCopy()); + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + setDimNode.setDimensions(result, dimsVector.materialize().getDataCopy()); } else if (internedName == RRuntime.NAMES_ATTR_KEY) { return updateNames(result, value); } else if (internedName == RRuntime.DIMNAMES_ATTR_KEY) { return updateDimNames(result, value); } else if (internedName == RRuntime.CLASS_ATTR_KEY) { - return (RAbstractContainer) result.setClassAttr(convertClassAttrFromObject(value)); + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + setClassAttrNode.execute(result, convertClassAttrFromObject(value)); + return result; } else if (internedName == RRuntime.ROWNAMES_ATTR_KEY) { - result.setRowNames(castVector(value)); + if (setRowNamesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setRowNamesAttrNode = insert(SetRowNamesAttributeNode.create()); + } + setRowNamesAttrNode.setRowNames(result, castVector(value)); } else { // generic attribute - result.setAttr(internedName, value); + if (setGenAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setGenAttrNode = insert(SetAttributeNode.create()); + } + setGenAttrNode.execute(result, internedName, value); } return result; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java index 31ce0f85a414a66a52bc6d3757e9398960508d74..4e0c99102cbac929b1bff3705111ca5f2e9f4f43 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java @@ -31,6 +31,10 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetRowNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNode; @@ -55,11 +59,15 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; public abstract class UpdateAttributes extends RBuiltinNode { private final ConditionProfile numAttributesProfile = ConditionProfile.createBinaryProfile(); private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Child private UpdateNames updateNames; @Child private UpdateDimNames updateDimNames; @Child private CastIntegerNode castInteger; @Child private CastToVectorNode castVector; + @Child private SetAttributeNode setAttrNode; + @Child private SetDimAttributeNode setDimNode; + @Child private SetRowNamesAttributeNode setRowNamesNode; @Override protected void createCasts(CastBuilder casts) { @@ -113,7 +121,7 @@ public abstract class UpdateAttributes extends RBuiltinNode { @Specialization protected RAbstractContainer updateAttributes(RAbstractContainer container, RList list) { - Object listNamesObject = list.getNames(attrProfiles); + Object listNamesObject = getNamesNode.getNames(list); if (listNamesObject == null || listNamesObject == RNull.instance) { throw RError.error(this, RError.Message.ATTRIBUTES_NAMED); } @@ -154,28 +162,34 @@ public abstract class UpdateAttributes extends RBuiltinNode { } private void setDimAttribute(RAbstractContainer result, RList sourceList) { - RStringVector listNames = sourceList.getNames(attrProfiles); + RStringVector listNames = getNamesNode.getNames(sourceList); int length = sourceList.getLength(); assert length > 0 : "Length should be > 0 for ExplodeLoop"; for (int i = 0; i < sourceList.getLength(); i++) { Object value = sourceList.getDataAt(i); String attrName = listNames.getDataAt(i); if (attrName.equals(RRuntime.DIM_ATTR_KEY)) { + + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + if (value == RNull.instance) { - result.setDimensions(null); + setDimNode.setDimensions(result, null); } else { RAbstractIntVector dimsVector = castInteger(castVector(value)); if (dimsVector.getLength() == 0) { throw RError.error(this, RError.Message.LENGTH_ZERO_DIM_INVALID); } - result.setDimensions(dimsVector.materialize().getDataCopy()); + setDimNode.setDimensions(result, dimsVector.materialize().getDataCopy()); } } } } private RAbstractContainer setRemainingAttributes(RAbstractContainer result, RList sourceList) { - RStringVector listNames = sourceList.getNames(attrProfiles); + RStringVector listNames = getNamesNode.getNames(sourceList); int length = sourceList.getLength(); assert length > 0 : "Length should be > 0 for ExplodeLoop"; RAbstractContainer res = result; @@ -190,17 +204,26 @@ public abstract class UpdateAttributes extends RBuiltinNode { res = updateDimNames(res, value); } else if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) { if (value == RNull.instance) { - res = (RAbstractContainer) result.setClassAttr(null); + res.setClassAttr(null); } else { - res = (RAbstractContainer) result.setClassAttr(UpdateAttr.convertClassAttrFromObject(value)); + res.setClassAttr(UpdateAttr.convertClassAttrFromObject(value)); } + res = result; } else if (attrName.equals(RRuntime.ROWNAMES_ATTR_KEY)) { - res.setRowNames(castVector(value)); + if (setRowNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setRowNamesNode = insert(SetRowNamesAttributeNode.create()); + } + setRowNamesNode.setRowNames(res, castVector(value)); } else { if (value == RNull.instance) { res.removeAttr(attrProfiles, attrName); } else { - res.setAttr(attrName.intern(), value); + if (setAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setAttrNode = insert(SetAttributeNode.create()); + } + setAttrNode.execute(res, attrName.intern(), value); } } } @@ -251,6 +274,7 @@ public abstract class UpdateAttributes extends RBuiltinNode { if (attrValue == null) { throw RError.error(this, RError.Message.SET_INVALID_CLASS_ATTR); } + attrObj.setClassAttr(UpdateAttr.convertClassAttrFromObject(attrValue)); } else { attrObj.setAttr(attrName.intern(), operand.getDataAt(i)); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java index 62799507ade961086ec2c43d64c72aa344899b69..094f7fb3b8b052cc251da25e495c326f181a1cf3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java @@ -18,6 +18,8 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.attributes.TypeFromModeNode; import com.oracle.truffle.r.nodes.binary.CastTypeNode; import com.oracle.truffle.r.nodes.binary.CastTypeNodeGen; @@ -48,6 +50,7 @@ public abstract class UpdateClass extends RBuiltinNode { @Child private CastTypeNode castTypeNode; @Child private TypeofNode typeof; + @Child private SetClassAttributeNode setClassAttrNode = SetClassAttributeNode.create(); private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @@ -61,7 +64,8 @@ public abstract class UpdateClass extends RBuiltinNode { @TruffleBoundary protected Object setClass(RAbstractContainer arg, @SuppressWarnings("unused") RNull className) { RAbstractContainer result = reuseNonShared(arg); - return result.setClassAttr(null); + setClassAttrNode.reset(result); + return result; } @Specialization(limit = "CACHE_LIMIT", guards = "cachedClassName == className") @@ -94,6 +98,7 @@ public abstract class UpdateClass extends RBuiltinNode { return setClass((RAbstractVector) result, RNull.instance); } } + RAbstractContainer result = reuseNonShared(arg); if (result instanceof RAbstractVector) { RAbstractVector resultVector = (RAbstractVector) result; @@ -114,73 +119,75 @@ public abstract class UpdateClass extends RBuiltinNode { } } - return result.setClassAttr(RDataFactory.createStringVector(className)); + setClassAttrNode.execute(result, RDataFactory.createStringVector(className)); + return result; } @Specialization @TruffleBoundary protected Object setClass(RAbstractContainer arg, RStringVector className) { RAbstractContainer result = reuseNonShared(arg); - return result.setClassAttr(className); + setClassAttrNode.execute(result, className); + return result; } @Specialization protected Object setClass(RFunction arg, RAbstractStringVector className) { - arg.setClassAttr(className.materialize()); + setClassAttrNode.execute(arg, className.materialize()); return arg; } @Specialization protected Object setClass(RFunction arg, @SuppressWarnings("unused") RNull className) { - arg.setClassAttr(null); + setClassAttrNode.reset(arg); return arg; } @Specialization protected Object setClass(REnvironment arg, RAbstractStringVector className) { - arg.setClassAttr(className.materialize()); + setClassAttrNode.execute(arg, className.materialize()); return arg; } @Specialization protected Object setClass(REnvironment arg, @SuppressWarnings("unused") RNull className) { - arg.setClassAttr(null); + setClassAttrNode.reset(arg); return arg; } @Specialization protected Object setClass(RSymbol arg, RAbstractStringVector className) { - arg.setClassAttr(className.materialize()); + setClassAttrNode.execute(arg, className.materialize()); return arg; } @Specialization protected Object setClass(RSymbol arg, @SuppressWarnings("unused") RNull className) { - arg.setClassAttr(null); + setClassAttrNode.reset(arg); return arg; } @Specialization protected Object setClass(RExternalPtr arg, RAbstractStringVector className) { - arg.setClassAttr(className.materialize()); + setClassAttrNode.execute(arg, className.materialize()); return arg; } @Specialization protected Object setClass(RExternalPtr arg, @SuppressWarnings("unused") RNull className) { - arg.setClassAttr(null); + setClassAttrNode.reset(arg); return arg; } @Specialization protected Object setClass(RS4Object arg, RAbstractStringVector className) { - arg.setClassAttr(className.materialize()); + setClassAttrNode.execute(arg, className.materialize()); return arg; } @Specialization protected Object setClass(RS4Object arg, @SuppressWarnings("unused") RNull className) { - arg.setClassAttr(null); + setClassAttrNode.reset(arg); return arg; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java index 0b7c49004d52e746b872d503f89b2e7fa32376aa..d30e638139ad629645041ed73dab870e8b043753 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java @@ -31,14 +31,12 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.r.nodes.attributes.InitAttributesNode; +import com.oracle.truffle.r.nodes.attributes.RemoveFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.opt.ReuseNonSharedNode; -import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeStorage; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RNull; @@ -67,14 +65,13 @@ public abstract class UpdateDim extends RBuiltinNode { @Specialization protected RAbstractVector updateDim(RAbstractVector vector, RAbstractIntVector dimensions, @Cached("createBinaryProfile()") ConditionProfile initAttrProfile, - @Cached("createDim()") SetFixedAttributeNode putDimensions) { + @Cached("createDim()") SetFixedAttributeNode putDimensions, + @Cached("createNames()") RemoveFixedAttributeNode removeNames) { RIntVector dimensionsMaterialized = dimensions.materialize(); int[] dimsData = dimensionsMaterialized.getDataCopy(); RVector.verifyDimensions(vector.getLength(), dimsData, this); RVector<?> result = ((RAbstractVector) reuse.execute(vector)).materialize(); - result.setInternalDimensions(dimsData); - result.setInternalNames(null); - result.setInternalDimNames(null); + removeNames.execute(result); DynamicObject attrs = result.getAttributes(); if (initAttrProfile.profile(attrs == null)) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java index b5ee7967ce49f2b74af6722eca32380187520043..35adf33049ff8328091ce27e59d1947407474c8e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java @@ -31,7 +31,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.attributes.RemoveFixedAttributeNode; -import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; @@ -40,11 +40,8 @@ import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -54,7 +51,6 @@ public abstract class UpdateDimNames extends RBuiltinNode { protected static final String DIMNAMES_ATTR_KEY = RRuntime.DIMNAMES_ATTR_KEY; private final ConditionProfile shareListProfile = ConditionProfile.createBinaryProfile(); - private final ConditionProfile isRVectorProfile = ConditionProfile.createBinaryProfile(); @Child private CastStringNode castStringNode; @Child private CastToVectorNode castVectorNode; @@ -96,15 +92,7 @@ public abstract class UpdateDimNames extends RBuiltinNode { protected RAbstractContainer updateDimnamesNull(RAbstractContainer container, @SuppressWarnings("unused") RNull list, // @Cached("createDimNames()") RemoveFixedAttributeNode remove) { RAbstractContainer result = (RAbstractContainer) container.getNonShared(); - if (isRVectorProfile.profile(container instanceof RVector)) { - RVector<?> vector = (RVector<?>) result; - if (vector.getInternalDimNames() != null) { - vector.setInternalDimNames(null); - remove.execute(vector.getAttributes()); - } - } else { - result.setDimNames(null); - } + remove.execute(result); return result; } @@ -116,9 +104,9 @@ public abstract class UpdateDimNames extends RBuiltinNode { @Specialization(guards = "list.getLength() > 0") protected RAbstractContainer updateDimnames(RAbstractContainer container, RList list, // - @Cached("createDimNames()") SetFixedAttributeNode attrSetter) { + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode) { RAbstractContainer result = (RAbstractContainer) container.getNonShared(); - setDimNames(result, convertToListOfStrings(list), attrSetter); + setDimNamesNode.setDimNames(result, convertToListOfStrings(list)); return result; } @@ -128,58 +116,4 @@ public abstract class UpdateDimNames extends RBuiltinNode { throw RError.error(this, RError.Message.DIMNAMES_LIST); } - private void setDimNames(RAbstractContainer container, RList newDimNames, SetFixedAttributeNode attrSetter) { - assert newDimNames != null; - if (isRVectorProfile.profile(container instanceof RVector)) { - RVector<?> vector = (RVector<?>) container; - int[] dimensions = vector.getDimensions(); - if (dimensions == null) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(this, RError.Message.DIMNAMES_NONARRAY); - } - int newDimNamesLength = newDimNames.getLength(); - if (newDimNamesLength > dimensions.length) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_DIMS, newDimNamesLength, dimensions.length); - } - for (int i = 0; i < newDimNamesLength; i++) { - Object dimObject = newDimNames.getDataAt(i); - if (dimObject != RNull.instance) { - if (dimObject instanceof String) { - if (dimensions[i] != 1) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_EXTENT, i + 1); - } - } else { - RStringVector dimVector = (RStringVector) dimObject; - if (dimVector == null || dimVector.getLength() == 0) { - newDimNames.updateDataAt(i, RNull.instance, null); - } else if (dimVector.getLength() != dimensions[i]) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_EXTENT, i + 1); - } - } - } - } - - RList resDimNames = newDimNames; - if (newDimNamesLength < dimensions.length) { - // resize the array and fill the missing entries with NULL-s - resDimNames = (RList) resDimNames.copyResized(dimensions.length, true); - resDimNames.setAttributes(newDimNames); - for (int i = newDimNamesLength; i < dimensions.length; i++) { - resDimNames.updateDataAt(i, RNull.instance, null); - } - } - if (vector.getAttributes() == null) { - vector.initAttributes(RAttributesLayout.createDimNames(resDimNames)); - } else { - attrSetter.execute(vector.getAttributes(), resDimNames); - } - resDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; - vector.setInternalDimNames(resDimNames); - } else { - container.setDimNames(newDimNames); - } - } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java index b9f41698d5966fe4c557badf8f03da94e0b95225..329730c362cfc6ee005247514fa33506811d928e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java @@ -15,7 +15,9 @@ import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; @@ -44,10 +46,15 @@ public abstract class UpdateLevels extends RBuiltinNode { return v; } + protected SetFixedAttributeNode createSetLevelsAttrNode() { + return SetFixedAttributeNode.create(RRuntime.LEVELS_ATTR_KEY); + } + @Specialization(guards = "!isRNull(levels)") - protected RAbstractVector updateLevels(RAbstractVector vector, Object levels) { + protected RAbstractVector updateLevels(RAbstractVector vector, Object levels, + @Cached("createSetLevelsAttrNode()") SetFixedAttributeNode setLevelsAttrNode) { RVector<?> v = (RVector<?>) vector.getNonShared(); - v.setAttr(RRuntime.LEVELS_ATTR_KEY, levels); + setLevelsAttrNode.execute(v, levels); return v; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java index f05261a585f42113af69f41576f5a2897eddc6df..02c1ab3e723189351e01281fc7714e35326c9270 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java @@ -29,6 +29,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; @@ -45,6 +46,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; public abstract class UpdateOldClass extends RBuiltinNode { @Child private CastStringNode castStringNode; + @Child private SetClassAttributeNode setClassAttributeNode = SetClassAttributeNode.create(); @Specialization(guards = "!isStringVector(className)") protected Object setOldClass(RAbstractContainer arg, RAbstractVector className) { @@ -73,14 +75,16 @@ public abstract class UpdateOldClass extends RBuiltinNode { @TruffleBoundary protected Object setOldClass(RAbstractContainer arg, RStringVector className) { RAbstractContainer result = (RAbstractContainer) arg.getNonShared(); - return result.setClassAttr(className); + setClassAttributeNode.execute(result, className); + return result; } @Specialization @TruffleBoundary protected Object setOldClass(RAbstractContainer arg, @SuppressWarnings("unused") RNull className) { RAbstractContainer result = (RAbstractContainer) arg.getNonShared(); - return result.setClassAttr(null); + setClassAttributeNode.reset(result); + return result; } protected boolean isStringVector(RAbstractVector className) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java index a2b8ddcf234c55e836d8af7397a79d7e2ea40423..804b73b66704a390fa5dee5d937b25a7c650b76d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java @@ -20,6 +20,8 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.attributes.TypeFromModeNode; import com.oracle.truffle.r.nodes.attributes.TypeFromModeNodeGen; import com.oracle.truffle.r.nodes.binary.CastTypeNode; @@ -35,9 +37,7 @@ import com.oracle.truffle.r.runtime.Utils; 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.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @RBuiltin(name = "storage.mode<-", kind = PRIMITIVE, parameterNames = {"x", "value"}, behavior = PURE) @@ -47,11 +47,14 @@ public abstract class UpdateStorageMode extends RBuiltinNode { @Child private TypeofNode typeof; @Child private CastTypeNode castTypeNode; @Child private IsFactorNode isFactor; + @Child private SetClassAttributeNode setClassAttrNode; private final BranchProfile errorProfile = BranchProfile.create(); @Specialization - protected Object update(Object x, String value, @Cached("create()") ArrayAttributeNode attrAttrAccess) { + protected Object update(Object x, String value, + @Cached("create()") ArrayAttributeNode attrAttrAccess, + @Cached("create()") SetAttributeNode setAttrNode) { RType mode = typeFromMode.execute(value); if (mode == RType.DefunctReal || mode == RType.DefunctSingle) { errorProfile.enter(); @@ -80,13 +83,19 @@ public abstract class UpdateStorageMode extends RBuiltinNode { String attrName = attr.getName(); Object v = attr.getValue(); if (attrName.equals(RRuntime.CLASS_ATTR_KEY)) { + + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + if (v == RNull.instance) { - rresult = (RAbstractContainer) rresult.setClassAttr(null); + setClassAttrNode.reset(rresult); } else { - rresult = (RAbstractContainer) rresult.setClassAttr((RStringVector) v); + setClassAttrNode.execute(rresult, v); } } else { - rresult.setAttr(Utils.intern(attrName), v); + setAttrNode.execute(rresult, Utils.intern(attrName), v); } } return rresult; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java index 2fdba2452bbd296c15841f87e7aead60fb576a88..83f99a9513a2e09bb32b33e7d754e008d0e4af4a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/VApply.java @@ -32,6 +32,9 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.Lapply.LapplyInternalNode; @@ -50,7 +53,6 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; @@ -80,7 +82,6 @@ public abstract class VApply extends RBuiltinNode { private final ConditionProfile useNamesProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile dimsProfile = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final NACheck naCheck = NACheck.create(); @Child private LapplyInternalNode doApply = LapplyInternalNodeGen.create(); @@ -90,6 +91,9 @@ public abstract class VApply extends RBuiltinNode { @Child private CastIntegerNode castInteger; @Child private CastLogicalNode castLogical; @Child private CastStringNode castString; + @Child private SetDimAttributeNode setDimNode; + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); + @Child private SetNamesAttributeNode setNamesNode = SetNamesAttributeNode.create(); @Override protected void createCasts(CastBuilder casts) { @@ -186,12 +190,16 @@ public abstract class VApply extends RBuiltinNode { } if (dimsProfile.profile(funValueVecLen > 1)) { - result.setDimensions(new int[]{funValueVecLen, applyResult.length}); + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + setDimNode.setDimensions(result, new int[]{funValueVecLen, applyResult.length}); } // TODO: handle names in case of matrices if (useNamesProfile.profile(RRuntime.fromLogical(useNames))) { - RStringVector names = vecMat.getNames(attrProfiles); + RStringVector names = getNamesNode.getNames(vecMat); RStringVector newNames = null; if (names != null) { newNames = names; @@ -199,7 +207,7 @@ public abstract class VApply extends RBuiltinNode { newNames = (RStringVector) vecMat.copy(); } if (newNames != null) { - result.setNames(newNames); + setNamesNode.setNames(result, newNames); } } return result; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java index ec76dd55c89e32226ef5eafac0317d653103d41b..14614074f986b56a2698b9eccd9b6a13189b4b8d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java @@ -30,6 +30,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.WhichFunctionsFactory.WhichMaxNodeGen; @@ -37,7 +38,6 @@ import com.oracle.truffle.r.nodes.builtin.base.WhichFunctionsFactory.WhichMinNod import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RNull; @@ -64,7 +64,7 @@ public class WhichFunctions { @Cached("create()") VectorLengthProfile lengthProfile, @Cached("createCountingProfile()") LoopConditionProfile loopProfile, @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile, - @Cached("create()") RAttributeProfiles attrProfiles, + @Cached("create()") GetNamesAttributeNode getNamesNode, @Cached("create()") NACheck naCheck) { int length = lengthProfile.profile(x.getLength()); loopProfile.profileCounted(length); @@ -83,7 +83,7 @@ public class WhichFunctions { result[pos++] = i + 1; } } - RStringVector names = x.getNames(attrProfiles); + RStringVector names = getNamesNode.getNames(x); if (hasNamesProfile.profile(names != null)) { // collect result names String[] resultNames = new String[resultLength]; @@ -122,7 +122,7 @@ public class WhichFunctions { @Cached("createCountingProfile()") LoopConditionProfile loopProfile, @Cached("createBinaryProfile()") ConditionProfile isNaNProfile, @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile, - @Cached("create()") RAttributeProfiles attrProfiles) { + @Cached("create()") GetNamesAttributeNode getNamesNode) { int length = lengthProfile.profile(x.getLength()); loopProfile.profileCounted(length); double extreme = Double.NaN; @@ -138,7 +138,7 @@ public class WhichFunctions { if (isNaNProfile.profile(extremeIndex == -1)) { return RDataFactory.createEmptyIntVector(); } - RStringVector names = x.getNames(attrProfiles); + RStringVector names = getNamesNode.getNames(x); if (hasNamesProfile.profile(names != null)) { // collect result names RStringVector resultNames = RDataFactory.createStringVectorFromScalar(names.getDataAt(extremeIndex)); 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/CallAndExternalFunctions.java similarity index 68% rename from com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java rename to com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java index 59786926cd8806b63b998768c62575be03c53fb2..279790c9b7f5c15e33802be3b956aefe106a481d 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/CallAndExternalFunctions.java @@ -15,7 +15,6 @@ import static com.oracle.truffle.r.runtime.RVisibility.CUSTOM; import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; -import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -41,24 +40,43 @@ import com.oracle.truffle.r.library.methods.SlotFactory.R_getSlotNodeGen; import com.oracle.truffle.r.library.methods.SlotFactory.R_setSlotNodeGen; import com.oracle.truffle.r.library.methods.SubstituteDirectNodeGen; import com.oracle.truffle.r.library.parallel.ParallelFunctionsFactory.MCIsChildNodeGen; +import com.oracle.truffle.r.library.stats.Cauchy; +import com.oracle.truffle.r.library.stats.Cauchy.DCauchy; +import com.oracle.truffle.r.library.stats.Cauchy.PCauchy; +import com.oracle.truffle.r.library.stats.Cauchy.RCauchy; import com.oracle.truffle.r.library.stats.CdistNodeGen; +import com.oracle.truffle.r.library.stats.Chisq; 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.DBeta; +import com.oracle.truffle.r.library.stats.DPois; import com.oracle.truffle.r.library.stats.Dbinom; +import com.oracle.truffle.r.library.stats.Df; import com.oracle.truffle.r.library.stats.DoubleCentreNodeGen; +import com.oracle.truffle.r.library.stats.Dt; +import com.oracle.truffle.r.library.stats.Exp.DExp; +import com.oracle.truffle.r.library.stats.Exp.PExp; +import com.oracle.truffle.r.library.stats.Exp.QExp; +import com.oracle.truffle.r.library.stats.Exp.RExp; +import com.oracle.truffle.r.library.stats.GammaFunctions.DGamma; import com.oracle.truffle.r.library.stats.GammaFunctions.QgammaFunc; +import com.oracle.truffle.r.library.stats.Geom; +import com.oracle.truffle.r.library.stats.Geom.DGeom; +import com.oracle.truffle.r.library.stats.Geom.RGeom; +import com.oracle.truffle.r.library.stats.LogNormal; +import com.oracle.truffle.r.library.stats.LogNormal.DLNorm; +import com.oracle.truffle.r.library.stats.LogNormal.PLNorm; +import com.oracle.truffle.r.library.stats.LogNormal.QLNorm; +import com.oracle.truffle.r.library.stats.Pbeta; import com.oracle.truffle.r.library.stats.Pbinom; import com.oracle.truffle.r.library.stats.Pf; import com.oracle.truffle.r.library.stats.Pnorm; import com.oracle.truffle.r.library.stats.Qbinom; import com.oracle.truffle.r.library.stats.Qnorm; import com.oracle.truffle.r.library.stats.RBeta; -import com.oracle.truffle.r.library.stats.RCauchy; import com.oracle.truffle.r.library.stats.RChisq; -import com.oracle.truffle.r.library.stats.RExp; import com.oracle.truffle.r.library.stats.RGamma; -import com.oracle.truffle.r.library.stats.RGeom; import com.oracle.truffle.r.library.stats.RHyper; import com.oracle.truffle.r.library.stats.RLogis; import com.oracle.truffle.r.library.stats.RMultinomNodeGen; @@ -66,6 +84,7 @@ import com.oracle.truffle.r.library.stats.RNbinomMu; import com.oracle.truffle.r.library.stats.RNchisq; import com.oracle.truffle.r.library.stats.RPois; import com.oracle.truffle.r.library.stats.RWeibull; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions; import com.oracle.truffle.r.library.stats.RandGenerationFunctionsFactory; import com.oracle.truffle.r.library.stats.Rbinom; import com.oracle.truffle.r.library.stats.Rf; @@ -76,7 +95,6 @@ import com.oracle.truffle.r.library.stats.Signrank.RSignrank; import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineCoefNodeGen; import com.oracle.truffle.r.library.stats.SplineFunctionsFactory.SplineEvalNodeGen; import com.oracle.truffle.r.library.stats.StatsFunctionsFactory; -import com.oracle.truffle.r.library.stats.StatsUtil; import com.oracle.truffle.r.library.stats.Wilcox.RWilcox; import com.oracle.truffle.r.library.tools.C_ParseRdNodeGen; import com.oracle.truffle.r.library.tools.DirChmodNodeGen; @@ -91,7 +109,6 @@ import com.oracle.truffle.r.library.utils.ObjectSizeNodeGen; import com.oracle.truffle.r.library.utils.RprofNodeGen; import com.oracle.truffle.r.library.utils.RprofmemNodeGen; import com.oracle.truffle.r.library.utils.TypeConvertNodeGen; -import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RInternalCodeBuiltinNode; import com.oracle.truffle.r.nodes.objects.GetPrimNameNodeGen; @@ -99,8 +116,6 @@ import com.oracle.truffle.r.nodes.objects.NewObjectNodeGen; import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalCode; -import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; @@ -108,21 +123,21 @@ import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; +import com.oracle.truffle.r.runtime.ffi.CallRFFI; import com.oracle.truffle.r.runtime.ffi.DLL; -import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; +import com.oracle.truffle.r.runtime.ffi.RFFIFactory; /** - * {@code .Call} {@code .Fortran}, {@code .External}, {@code .External2}, {@code External.graphics} - * functions. + * {@code .Call}, {@code .Call.graphics}, {@code .External}, {@code .External2}, + * {@code External.graphics} functions, which share a common signature. * * TODO Completeness (more types, more error checks), Performance (copying). Especially all the * subtleties around copying. * * See <a href="https://stat.ethz.ch/R-manual/R-devel/library/base/html/Foreign.html">here</a>. */ -public class ForeignFunctions { +public class CallAndExternalFunctions { @TruffleBoundary protected static Object encodeArgumentPairList(RArgsValuesAndNames args, String symbolName) { @@ -135,158 +150,28 @@ public class ForeignFunctions { return list; } - /** - * Locator for "builtin" package function implementations. The "builtin" packages contain many - * functions that are called from R code via the FFI, e.g. {@code .Call}, but implemented - * internally in GnuR, and not necessarily following the FFI API. The value passed to - * {@code .Call} etc., is a symbol, created when the package is loaded and stored in the - * namespace environment of the package, that is a list-valued object. Evidently these - * "builtins" are somewhat similar to the {@code .Primitive} and {@code .Internal} builtins and, - * similarly, most of these are re-implemented in Java in FastR. The - * {@link #lookupBuiltin(RList)} method checks the name in the list object and returns the - * {@link RExternalBuiltinNode} that implements the function, or {@code null}. A {@code null} - * result implies that the builtin is not implemented in Java, but called directly via the FFI - * interface, which is only possible for functions that use the FFI in a way that FastR can - * handle. - */ - protected abstract static class LookupAdapter extends RBuiltinNode { - protected static class UnimplementedExternal extends RExternalBuiltinNode { - private final String name; - - public UnimplementedExternal(String name) { - this.name = name; - } - - @Override - public final Object call(RArgsValuesAndNames args) { - throw RInternalError.unimplemented("unimplemented external builtin: " + name); - } - } - - protected abstract RExternalBuiltinNode lookupBuiltin(RList f); - - private static final String UNKNOWN_EXTERNAL_BUILTIN = "UNKNOWN_EXTERNAL_BUILTIN"; - - protected static String lookupName(RList f) { - CompilerAsserts.neverPartOfCompilation(); - if (f.getNames() != null) { - RAbstractStringVector names = f.getNames(); - for (int i = 0; i < names.getLength(); i++) { - if (names.getDataAt(i).equals("name")) { - String name = RRuntime.asString(f.getDataAt(i)); - return name != null ? name : UNKNOWN_EXTERNAL_BUILTIN; - } - } - } - return UNKNOWN_EXTERNAL_BUILTIN; - } - - @TruffleBoundary - protected RuntimeException fallback(Object fobj) { - String name = null; - if (fobj instanceof RList) { - name = lookupName((RList) fobj); - name = name == UNKNOWN_EXTERNAL_BUILTIN ? null : name; - if (name != null && lookupBuiltin((RList) fobj) != null) { - /* - * if we reach this point, then the cache saw a different value for f. the lists - * that contain the information about native calls are never expected to change. - */ - throw RInternalError.shouldNotReachHere("fallback reached for " + getRBuiltin().name() + " " + name); - } - } - throw RError.nyi(this, getRBuiltin().name() + " specialization failure: " + (name == null ? "<unknown>" : name)); - } - - @Child private ExtractNativeCallInfoNode extractSymbolInfoNode = ExtractNativeCallInfoNodeGen.create(); - - protected NativeCallInfo extractSymbolInfo(VirtualFrame frame, RList symbol) { - return (NativeCallInfo) extractSymbolInfoNode.execute(frame, symbol); - } - - protected String checkPackageArg(Object rPackage, BranchProfile errorProfile) { - String libName = null; - if (!(rPackage instanceof RMissing)) { - libName = RRuntime.asString(rPackage); - if (libName == null) { - errorProfile.enter(); - throw RError.error(this, RError.Message.ARGUMENT_MUST_BE_STRING, "PACKAGE"); - } - } - return libName; - } - - protected static RExternalBuiltinNode getExternalModelBuiltinNode(String name) { - return new RInternalCodeBuiltinNode(RContext.getInstance(), "stats", RInternalCode.loadSourceRelativeTo(StatsUtil.class, "model.R"), name); - } - } - - /** - * Interface to .Fortran native functions. Some functions have explicit implementations in - * FastR, otherwise the .Fortran interface uses the machinery that implements the .C interface. - */ - @RBuiltin(name = ".Fortran", kind = PRIMITIVE, parameterNames = {".NAME", "...", "NAOK", "DUP", "PACKAGE", "ENCODING"}, behavior = COMPLEX) - public abstract static class Fortran extends LookupAdapter { - - @Override - public Object[] getDefaultParameterValues() { - return new Object[]{RMissing.instance, RArgsValuesAndNames.EMPTY, RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_FALSE, RMissing.instance, RMissing.instance}; - } - - @Override - @TruffleBoundary - protected RExternalBuiltinNode lookupBuiltin(RList f) { - switch (lookupName(f)) { - case "dqrdc2": - return new Dqrdc2(); - case "dqrcf": - return new Dqrcf(); - default: - return null; - } - } - - @SuppressWarnings("unused") - @Specialization(limit = "1", guards = {"cached == f", "builtin != null"}) - protected Object doExternal(VirtualFrame frame, RList f, RArgsValuesAndNames args, byte naok, byte dup, Object rPackage, RMissing encoding, // - @Cached("f") RList cached, // - @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { - return builtin.call(frame, args); - } - - @Specialization(guards = "lookupBuiltin(symbol) == null") - protected RList c(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, byte naok, byte dup, @SuppressWarnings("unused") Object rPackage, - @SuppressWarnings("unused") RMissing encoding) { - NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); - return DotC.dispatch(this, nativeCallInfo, naok, dup, args); - } - - @Specialization - protected RList c(RAbstractStringVector f, RArgsValuesAndNames args, byte naok, byte dup, Object rPackage, @SuppressWarnings("unused") RMissing encoding, // - @Cached("create()") BranchProfile errorProfile) { - String libName = checkPackageArg(rPackage, errorProfile); - DLL.RegisteredNativeSymbol rns = new DLL.RegisteredNativeSymbol(DLL.NativeSymbolType.Fortran, null, null); - DLL.SymbolHandle func = DLL.findSymbol(f.getDataAt(0), libName, rns); - if (func == DLL.SYMBOL_NOT_FOUND) { - errorProfile.enter(); - throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, f); - } - return DotC.dispatch(this, new NativeCallInfo(f.getDataAt(0), func, rns.getDllInfo()), naok, dup, args); - } - - @SuppressWarnings("unused") - @Fallback - protected Object fallback(Object f, Object args, Object naok, Object dup, Object rPackage, Object encoding) { - throw fallback(f); - } + protected abstract static class CallRFFIAdapter extends LookupAdapter { + @Child protected CallRFFI.CallRFFINode callRFFINode = RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode(); } /** * Handles the generic case, but also many special case functions that are called from the * default packages. + * + * The native function to be called can be specified in two ways: + * <ol> + * <li>as an object of R class {@code NativeSymbolInfo} (passed as an {@link RList}. In this + * case {@code .PACKAGE} is ignored even if provided.</li> + * <li>as a character string. If {@code .PACKAGE} is provided the search is restricted to that + * package, else the symbol is searched in all loaded packages (evidently dangerous as the + * symbol could be duplicated)</li> + * </ol> + * Many of the functions in the builtin packages have been translated to Java which is handled + * by specializations that {@link #lookupBuiltin(RList)}. N.N. In principle such a function + * could be invoked by a string but experimentally that situation has never been encountered. */ @RBuiltin(name = ".Call", kind = PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}, behavior = COMPLEX) - public abstract static class DotCall extends LookupAdapter { + public abstract static class DotCall extends CallRFFIAdapter { private final BranchProfile errorProfile = BranchProfile.create(); @@ -297,8 +182,8 @@ public class ForeignFunctions { @Override @TruffleBoundary - protected RExternalBuiltinNode lookupBuiltin(RList f) { - String name = lookupName(f); + protected RExternalBuiltinNode lookupBuiltin(RList symbol) { + String name = lookupName(symbol); switch (name) { // methods case "R_initMethodDispatch": @@ -409,8 +294,48 @@ public class ForeignFunctions { return RandGenerationFunctionsFactory.Function2_IntNodeGen.create(new Rbinom()); case "pbinom": return StatsFunctionsFactory.Function3_2NodeGen.create(new Pbinom()); + case "pbeta": + return StatsFunctionsFactory.Function3_2NodeGen.create(new Pbeta()); + case "dcauchy": + return StatsFunctionsFactory.Function3_1NodeGen.create(new DCauchy()); + case "pcauchy": + return StatsFunctionsFactory.Function3_2NodeGen.create(new PCauchy()); + case "qcauchy": + return StatsFunctionsFactory.Function3_2NodeGen.create(new Cauchy.QCauchy()); case "pf": return StatsFunctionsFactory.Function3_2NodeGen.create(new Pf()); + case "df": + return StatsFunctionsFactory.Function3_1NodeGen.create(new Df()); + case "dgamma": + return StatsFunctionsFactory.Function3_1NodeGen.create(new DGamma()); + case "dchisq": + return StatsFunctionsFactory.Function2_1NodeGen.create(new Chisq.DChisq()); + case "qgeom": + return StatsFunctionsFactory.Function2_2NodeGen.create(new Geom.QGeom()); + case "pchisq": + return StatsFunctionsFactory.Function2_2NodeGen.create(new Chisq.PChisq()); + case "dexp": + return StatsFunctionsFactory.Function2_1NodeGen.create(new DExp()); + case "pexp": + return StatsFunctionsFactory.Function2_2NodeGen.create(new PExp()); + case "qexp": + return StatsFunctionsFactory.Function2_2NodeGen.create(new QExp()); + case "dgeom": + return StatsFunctionsFactory.Function2_1NodeGen.create(new DGeom()); + case "dpois": + return StatsFunctionsFactory.Function2_1NodeGen.create(new DPois()); + case "dbeta": + return StatsFunctionsFactory.Function3_1NodeGen.create(new DBeta()); + case "dt": + return StatsFunctionsFactory.Function2_1NodeGen.create(new Dt()); + case "rlnorm": + return RandGenerationFunctionsFactory.Function2_DoubleNodeGen.create(new LogNormal.RLNorm()); + case "dlnorm": + return StatsFunctionsFactory.Function3_1NodeGen.create(new DLNorm()); + case "qlnorm": + return StatsFunctionsFactory.Function3_2NodeGen.create(new QLNorm()); + case "plnorm": + return StatsFunctionsFactory.Function3_2NodeGen.create(new PLNorm()); case "rmultinom": return RMultinomNodeGen.create(); case "Approx": @@ -501,7 +426,7 @@ public class ForeignFunctions { return getExternalModelBuiltinNode("updateform"); case "Cdqrls": - return new RInternalCodeBuiltinNode(RContext.getInstance(), "stats", RInternalCode.loadSourceRelativeTo(StatsUtil.class, "lm.R"), "Cdqrls"); + return new RInternalCodeBuiltinNode(RContext.getInstance(), "stats", RInternalCode.loadSourceRelativeTo(RandGenerationFunctions.class, "lm.R"), "Cdqrls"); case "dnorm": return StatsFunctionsFactory.Function3_1NodeGen.create(new Dnorm4()); @@ -568,44 +493,67 @@ public class ForeignFunctions { } } + /** + * {@code .NAME = NativeSymbolInfo} implemented as a builtin. + */ @SuppressWarnings("unused") - @Specialization(limit = "1", guards = {"cached == f", "builtin != null"}) - protected Object doExternal(VirtualFrame frame, RList f, RArgsValuesAndNames args, RMissing packageName, // - @Cached("f") RList cached, // - @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { + @Specialization(limit = "1", guards = {"cached == symbol", "builtin != null"}) + protected Object doExternal(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, Object packageName, // + @Cached("symbol") RList cached, // + @Cached("lookupBuiltin(symbol)") RExternalBuiltinNode builtin) { return builtin.call(frame, args); } - @Specialization - protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { - NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(nativeCallInfo, args.getArguments()); + /** + * {@code .NAME = NativeSymbolInfo} implementation remains in native code (e.g. non-builtin + * package) + */ + @SuppressWarnings("unused") + @Specialization(limit = "1", guards = {"cached == symbol"}) + protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, Object packageName, // + @Cached("symbol") RList cached, // + @Cached("extractSymbolInfo(frame, symbol)") NativeCallInfo nativeCallInfo) { + return callRFFINode.invokeCall(nativeCallInfo, args.getArguments()); } + /** + * {@code .NAME = string}, no package specified. + */ @Specialization - protected Object callNamedFunction(String name, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - return callNamedFunctionWithPackage(name, args, null); + protected Object callNamedFunction(String symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName, // + @Cached("createRegisteredNativeSymbol(CallNST)") DLL.RegisteredNativeSymbol rns) { + return callNamedFunctionWithPackage(symbol, args, null, rns); } + /** + * {@code .NAME = string, .PACKAGE = package}. An error if package provided and it does not + * define that symbol. + */ @Specialization - protected Object callNamedFunctionWithPackage(String name, RArgsValuesAndNames args, String packageName) { - DLL.RegisteredNativeSymbol rns = new DLL.RegisteredNativeSymbol(DLL.NativeSymbolType.Call, null, null); - DLL.SymbolHandle func = DLL.findSymbol(name, packageName, rns); + protected Object callNamedFunctionWithPackage(String symbol, RArgsValuesAndNames args, String packageName, // + @Cached("createRegisteredNativeSymbol(CallNST)") DLL.RegisteredNativeSymbol rns) { + DLL.SymbolHandle func = DLL.findSymbol(symbol, packageName, rns); if (func == DLL.SYMBOL_NOT_FOUND) { errorProfile.enter(); - throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name); + throw RError.error(this, RError.Message.SYMBOL_NOT_IN_TABLE, symbol, "Call", packageName); } - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), args.getArguments()); + return callRFFINode.invokeCall(new NativeCallInfo(symbol, func, rns.getDllInfo()), args.getArguments()); } + @SuppressWarnings("unused") @Fallback - protected Object dotCallFallback(Object fobj, @SuppressWarnings("unused") Object args, @SuppressWarnings("unused") Object packageName) { - throw fallback(fobj); + protected Object dotCallFallback(Object symbol, Object args, Object packageName) { + throw fallback(symbol); } + } + /** + * The interpretation of the {@code .NAME} and {code .PACKAGE} arguments as are for + * {@link DotCall}. + */ @RBuiltin(name = ".External", kind = PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}, behavior = COMPLEX) - public abstract static class DotExternal extends LookupAdapter { + public abstract static class DotExternal extends CallRFFIAdapter { private final BranchProfile errorProfile = BranchProfile.create(); @@ -655,35 +603,38 @@ public class ForeignFunctions { } @SuppressWarnings("unused") - @Specialization(limit = "1", guards = {"cached == f", "builtin != null"}) - protected Object doExternal(VirtualFrame frame, RList f, RArgsValuesAndNames args, RMissing packageName, // - @Cached("f") RList cached, // - @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { + @Specialization(limit = "1", guards = {"cached == symbol", "builtin != null"}) + protected Object doExternal(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, Object packageName, // + @Cached("symbol") RList cached, // + @Cached("lookupBuiltin(symbol)") RExternalBuiltinNode builtin) { return builtin.call(frame, args); } - @Specialization - protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { - NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); + @SuppressWarnings("unused") + @Specialization(limit = "1", guards = {"cached == symbol"}) + protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, Object packageName, // + @Cached("symbol") RList cached, // + @Cached("extractSymbolInfo(frame, symbol)") NativeCallInfo nativeCallInfo) { Object list = encodeArgumentPairList(args, nativeCallInfo.name); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(nativeCallInfo, new Object[]{list}); + return callRFFINode.invokeCall(nativeCallInfo, new Object[]{list}); } @Specialization - protected Object callNamedFunction(String name, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - return callNamedFunctionWithPackage(name, args, null); + protected Object callNamedFunction(String symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName, // ) + @Cached("createRegisteredNativeSymbol(ExternalNST)") DLL.RegisteredNativeSymbol rns) { + return callNamedFunctionWithPackage(symbol, args, null, rns); } @Specialization - protected Object callNamedFunctionWithPackage(String name, RArgsValuesAndNames args, String packageName) { - DLL.RegisteredNativeSymbol rns = new DLL.RegisteredNativeSymbol(DLL.NativeSymbolType.External, null, null); - DLL.SymbolHandle func = DLL.findSymbol(name, packageName, rns); + protected Object callNamedFunctionWithPackage(String symbol, RArgsValuesAndNames args, String packageName, // + @Cached("createRegisteredNativeSymbol(ExternalNST)") DLL.RegisteredNativeSymbol rns) { + DLL.SymbolHandle func = DLL.findSymbol(symbol, packageName, rns); if (func == DLL.SYMBOL_NOT_FOUND) { errorProfile.enter(); - throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name); + throw RError.error(this, RError.Message.SYMBOL_NOT_IN_TABLE, symbol, "External", packageName); } - Object list = encodeArgumentPairList(args, name); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), new Object[]{list}); + Object list = encodeArgumentPairList(args, symbol); + return callRFFINode.invokeCall(new NativeCallInfo(symbol, func, rns.getDllInfo()), new Object[]{list}); } @Fallback @@ -693,7 +644,7 @@ public class ForeignFunctions { } @RBuiltin(name = ".External2", visibility = CUSTOM, kind = PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}, behavior = COMPLEX) - public abstract static class DotExternal2 extends LookupAdapter { + public abstract static class DotExternal2 extends CallRFFIAdapter { private static final Object CALL = "call"; private static final Object OP = "op"; private static final Object RHO = "rho"; @@ -702,14 +653,14 @@ public class ForeignFunctions { @Override @TruffleBoundary - protected RExternalBuiltinNode lookupBuiltin(RList f) { + protected RExternalBuiltinNode lookupBuiltin(RList symbol) { if (FastROptions.UseInternalGraphics.getBooleanValue()) { - switch (lookupName(f)) { + switch (lookupName(symbol)) { case "C_par": return new C_Par(); } } - String name = lookupName(f); + String name = lookupName(symbol); switch (name) { // tools case "writetable": @@ -727,37 +678,40 @@ public class ForeignFunctions { } @SuppressWarnings("unused") - @Specialization(limit = "1", guards = {"cached == f", "builtin != null"}) - protected Object doExternal(VirtualFrame frame, RList f, RArgsValuesAndNames args, RMissing packageName, // - @Cached("f") RList cached, // - @Cached("lookupBuiltin(f)") RExternalBuiltinNode builtin) { + @Specialization(limit = "1", guards = {"cached == symbol", "builtin != null"}) + protected Object doExternal(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, Object packageName, // + @Cached("symbol") RList cached, // + @Cached("lookupBuiltin(symbol)") RExternalBuiltinNode builtin) { return builtin.call(frame, args); } - @Specialization - protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { - NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); + @SuppressWarnings("unused") + @Specialization(limit = "1", guards = {"cached == symbol"}) + protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, Object packageName, // + @Cached("symbol") RList cached, // + @Cached("extractSymbolInfo(frame, symbol)") NativeCallInfo nativeCallInfo) { Object list = encodeArgumentPairList(args, nativeCallInfo.name); // TODO: provide proper values for the CALL, OP and RHO parameters - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(nativeCallInfo, new Object[]{CALL, OP, list, RHO}); + return callRFFINode.invokeCall(nativeCallInfo, new Object[]{CALL, OP, list, RHO}); } @Specialization - protected Object callNamedFunction(String name, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName) { - return callNamedFunctionWithPackage(name, args, null); + protected Object callNamedFunction(String symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") RMissing packageName, // ) + @Cached("createRegisteredNativeSymbol(ExternalNST)") DLL.RegisteredNativeSymbol rns) { + return callNamedFunctionWithPackage(symbol, args, null, rns); } @Specialization - protected Object callNamedFunctionWithPackage(String name, RArgsValuesAndNames args, String packageName) { - DLL.RegisteredNativeSymbol rns = new DLL.RegisteredNativeSymbol(DLL.NativeSymbolType.External, null, null); - DLL.SymbolHandle func = DLL.findSymbol(name, packageName, rns); + protected Object callNamedFunctionWithPackage(String symbol, RArgsValuesAndNames args, String packageName, // + @Cached("createRegisteredNativeSymbol(ExternalNST)") DLL.RegisteredNativeSymbol rns) { + DLL.SymbolHandle func = DLL.findSymbol(symbol, packageName, rns); if (func == DLL.SYMBOL_NOT_FOUND) { errorProfile.enter(); - throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name); + throw RError.error(this, RError.Message.SYMBOL_NOT_IN_TABLE, symbol, "External2", packageName); } - Object list = encodeArgumentPairList(args, name); + Object list = encodeArgumentPairList(args, symbol); // TODO: provide proper values for the CALL, OP and RHO parameters - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), new Object[]{CALL, OP, list, RHO}); + return callRFFINode.invokeCall(new NativeCallInfo(symbol, func, rns.getDllInfo()), new Object[]{CALL, OP, list, RHO}); } @Fallback @@ -767,7 +721,7 @@ public class ForeignFunctions { } @RBuiltin(name = ".External.graphics", kind = PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}, behavior = COMPLEX) - public abstract static class DotExternalGraphics extends LookupAdapter { + public abstract static class DotExternalGraphics extends CallRFFIAdapter { private final BranchProfile errorProfile = BranchProfile.create(); @@ -797,7 +751,7 @@ public class ForeignFunctions { protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); Object list = encodeArgumentPairList(args, nativeCallInfo.name); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(nativeCallInfo, new Object[]{list}); + return callRFFINode.invokeCall(nativeCallInfo, new Object[]{list}); } @Specialization @@ -814,7 +768,7 @@ public class ForeignFunctions { throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name); } Object list = encodeArgumentPairList(args, name); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), new Object[]{list}); + return callRFFINode.invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), new Object[]{list}); } @Fallback @@ -824,7 +778,7 @@ public class ForeignFunctions { } @RBuiltin(name = ".Call.graphics", kind = PRIMITIVE, parameterNames = {".NAME", "...", "PACKAGE"}, behavior = COMPLEX) - public abstract static class DotCallGraphics extends LookupAdapter { + public abstract static class DotCallGraphics extends CallRFFIAdapter { private final BranchProfile errorProfile = BranchProfile.create(); @@ -853,7 +807,7 @@ public class ForeignFunctions { @Specialization protected Object callNamedFunction(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, @SuppressWarnings("unused") Object packageName) { NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(nativeCallInfo, args.getArguments()); + return callRFFINode.invokeCall(nativeCallInfo, args.getArguments()); } @Specialization @@ -870,7 +824,7 @@ public class ForeignFunctions { errorProfile.enter(); throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, name); } - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), args.getArguments()); + return callRFFINode.invokeCall(new NativeCallInfo(name, func, rns.getDllInfo()), args.getArguments()); } @Fallback 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 deleted file mode 100644 index 8009ea798359a524bc8b59bd25bdd0408fbe1d0e..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * 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-2012, The R Core Team - * Copyright (c) 2003, The R Foundation - * Copyright (c) 2015, 2016, Oracle and/or its affiliates - * - * All rights reserved. - */ -package com.oracle.truffle.r.nodes.builtin.base.foreign; - -import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; -import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; - -import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.profiles.BranchProfile; -import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.runtime.ArgumentsSignature; -import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.ffi.DLL; -import com.oracle.truffle.r.runtime.ffi.RFFIFactory; -import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; - -/** - * {@code .C} functions. - * - * TODO Completeness (more types, more error checks), Performance (copying). Especially all the - * subtleties around copying. - * - * See <a href="https://stat.ethz.ch/R-manual/R-devel/library/base/html/Foreign.html">here</a>. - */ -@RBuiltin(name = ".C", kind = PRIMITIVE, parameterNames = {".NAME", "...", "NAOK", "DUP", "PACKAGE", "ENCODING"}, behavior = COMPLEX) -public abstract class DotC extends RBuiltinNode { - - private static final int SCALAR_DOUBLE = 0; - private static final int SCALAR_INT = 1; - private static final int SCALAR_LOGICAL = 2; - @SuppressWarnings("unused") private static final int SCALAR_STRING = 3; - private static final int VECTOR_DOUBLE = 10; - private static final int VECTOR_INT = 11; - private static final int VECTOR_LOGICAL = 12; - @SuppressWarnings("unused") private static final int VECTOR_STRING = 12; - - @Child private ExtractNativeCallInfoNode extractSymbolInfoNode = ExtractNativeCallInfoNodeGen.create(); - - protected NativeCallInfo extractSymbolInfo(VirtualFrame frame, RList symbol) { - return (NativeCallInfo) extractSymbolInfoNode.execute(frame, symbol); - } - - @Override - public Object[] getDefaultParameterValues() { - return new Object[]{RMissing.instance, RArgsValuesAndNames.EMPTY, RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_FALSE, RMissing.instance, RMissing.instance}; - } - - @SuppressWarnings("unused") - @Specialization - protected RList c(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, byte naok, byte dup, Object rPackage, RMissing encoding) { - NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); - return dispatch(this, nativeCallInfo, naok, dup, args); - } - - @SuppressWarnings("unused") - @Specialization - protected RList c(RAbstractStringVector f, RArgsValuesAndNames args, byte naok, byte dup, Object rPackage, RMissing encoding, // - @Cached("create()") BranchProfile errorProfile) { - String libName = null; - if (!(rPackage instanceof RMissing)) { - libName = RRuntime.asString(rPackage); - if (libName == null) { - errorProfile.enter(); - throw RError.error(this, RError.Message.ARGUMENT_MUST_BE_STRING, "PACKAGE"); - } - } - DLL.RegisteredNativeSymbol rns = new DLL.RegisteredNativeSymbol(DLL.NativeSymbolType.C, null, null); - DLL.SymbolHandle func = DLL.findSymbol(f.getDataAt(0), libName, rns); - if (func == DLL.SYMBOL_NOT_FOUND) { - errorProfile.enter(); - throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, f); - } - return dispatch(this, new NativeCallInfo(f.getDataAt(0), func, rns.getDllInfo()), naok, dup, args); - } - - private static int[] checkNAs(RBuiltinNode node, int argIndex, int[] data) { - CompilerAsserts.neverPartOfCompilation(); - for (int i = 0; i < data.length; i++) { - if (RRuntime.isNA(data[i])) { - throw RError.error(node, RError.Message.NA_IN_FOREIGN_FUNCTION_CALL, argIndex); - } - } - return data; - } - - private static double[] checkNAs(RBuiltinNode node, int argIndex, double[] data) { - CompilerAsserts.neverPartOfCompilation(); - for (int i = 0; i < data.length; i++) { - if (!RRuntime.isFinite(data[i])) { - throw RError.error(node, RError.Message.NA_NAN_INF_IN_FOREIGN_FUNCTION_CALL, argIndex); - } - } - return data; - } - - private static RStringVector validateArgNames(int argsLength, ArgumentsSignature signature) { - String[] listArgNames = new String[argsLength]; - for (int i = 0; i < argsLength; i++) { - String name = signature.getName(i); - if (name == null) { - name = RRuntime.NAMES_ATTR_EMPTY_VALUE; - } - listArgNames[i] = name; - } - return RDataFactory.createStringVector(listArgNames, RDataFactory.COMPLETE_VECTOR); - } - - @TruffleBoundary - protected static RList dispatch(RBuiltinNode node, NativeCallInfo nativeCallInfo, byte naok, byte dup, RArgsValuesAndNames args) { - @SuppressWarnings("unused") - boolean dupArgs = RRuntime.fromLogical(dup); - @SuppressWarnings("unused") - boolean checkNA = RRuntime.fromLogical(naok); - // Analyze the args, making copies (ignoring dup for now) - Object[] array = args.getArguments(); - int[] argTypes = new int[array.length]; - Object[] nativeArgs = new Object[array.length]; - for (int i = 0; i < array.length; i++) { - Object arg = array[i]; - if (arg instanceof RAbstractDoubleVector) { - argTypes[i] = VECTOR_DOUBLE; - nativeArgs[i] = checkNAs(node, i + 1, ((RAbstractDoubleVector) arg).materialize().getDataCopy()); - } else if (arg instanceof RAbstractIntVector) { - argTypes[i] = VECTOR_INT; - nativeArgs[i] = checkNAs(node, i + 1, ((RAbstractIntVector) arg).materialize().getDataCopy()); - } else if (arg instanceof RAbstractLogicalVector) { - argTypes[i] = VECTOR_LOGICAL; - // passed as int[] - byte[] data = ((RAbstractLogicalVector) arg).materialize().getDataWithoutCopying(); - int[] dataAsInt = new int[data.length]; - for (int j = 0; j < data.length; j++) { - // An NA is an error but the error handling happens in checkNAs - dataAsInt[j] = RRuntime.isNA(data[j]) ? RRuntime.INT_NA : data[j]; - } - nativeArgs[i] = checkNAs(node, i + 1, dataAsInt); - } else if (arg instanceof Double) { - argTypes[i] = SCALAR_DOUBLE; - nativeArgs[i] = checkNAs(node, i + 1, new double[]{(double) arg}); - } else if (arg instanceof Integer) { - argTypes[i] = SCALAR_INT; - nativeArgs[i] = checkNAs(node, i + 1, new int[]{(int) arg}); - } else if (arg instanceof Byte) { - argTypes[i] = SCALAR_LOGICAL; - nativeArgs[i] = checkNAs(node, i + 1, new int[]{RRuntime.isNA((byte) arg) ? RRuntime.INT_NA : (byte) arg}); - } else { - throw RError.error(node, RError.Message.UNIMPLEMENTED_ARG_TYPE, i + 1); - } - } - RFFIFactory.getRFFI().getCRFFI().invoke(nativeCallInfo, nativeArgs); - // we have to assume that the native method updated everything - RStringVector listNames = validateArgNames(array.length, args.getSignature()); - Object[] results = new Object[array.length]; - for (int i = 0; i < array.length; i++) { - switch (argTypes[i]) { - case SCALAR_DOUBLE: - results[i] = RDataFactory.createDoubleVector((double[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); - break; - case SCALAR_INT: - results[i] = RDataFactory.createIntVector((int[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); - break; - case SCALAR_LOGICAL: - // 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]); - break; - case VECTOR_INT: - results[i] = ((RAbstractIntVector) array[i]).materialize().copyResetData((int[]) nativeArgs[i]); - break; - case VECTOR_LOGICAL: { - int[] intData = (int[]) nativeArgs[i]; - byte[] byteData = new byte[intData.length]; - for (int j = 0; j < intData.length; j++) { - byteData[j] = RRuntime.isNA(intData[j]) ? RRuntime.LOGICAL_NA : RRuntime.asLogical(intData[j] != 0); - } - results[i] = ((RAbstractLogicalVector) array[i]).materialize().copyResetData(byteData); - break; - } - } - } - return RDataFactory.createList(results, listNames); - } - -} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java index b8dfa18b98a9656c6d2df0059a5589ebf7deda57..3ca0f0c97d0173a30490c3c5cdd8b0bf225426ec 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java @@ -21,9 +21,11 @@ import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +import com.oracle.truffle.r.runtime.ffi.RApplRFFI; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; public final class Dqrcf extends RExternalBuiltinNode { + @Child private RApplRFFI.RApplRFFINode rApplRFFINode = RFFIFactory.getRFFI().getRApplRFFI().createRApplRFFINode(); private static final String E = RRuntime.NAMES_ATTR_EMPTY_VALUE; private static final RStringVector DQRCF_NAMES = RDataFactory.createStringVector(new String[]{E, E, E, E, E, E, "coef", "info"}, RDataFactory.COMPLETE_VECTOR); @@ -45,9 +47,9 @@ public final class Dqrcf extends RExternalBuiltinNode { double[] y = yVec.materialize().getDataTemp(); double[] b = bVec.materialize().getDataTemp(); int[] info = infoVec.materialize().getDataTemp(); - RFFIFactory.getRFFI().getRApplRFFI().dqrcf(x, n, k.getDataAt(0), qraux, y, ny, b, info); + rApplRFFINode.dqrcf(x, n, k.getDataAt(0), qraux, y, ny, b, info); RDoubleVector coef = RDataFactory.createDoubleVector(b, RDataFactory.COMPLETE_VECTOR); - coef.copyAttributesFrom(attrProfiles, bVec); + coef.copyAttributesFrom(bVec); // @formatter:off Object[] data = new Object[]{ RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR), diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java index fb842d465d81c176cdc1f5aeadaab8f3d07326c0..e63b42dd1195018bf6b83324ff0ca72ef2dcdfb1 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java @@ -11,6 +11,7 @@ */ package com.oracle.truffle.r.nodes.builtin.base.foreign; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; @@ -20,13 +21,17 @@ import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +import com.oracle.truffle.r.runtime.ffi.RApplRFFI; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; public final class Dqrdc2 extends RExternalBuiltinNode { + @Child private RApplRFFI.RApplRFFINode rApplRFFINode = RFFIFactory.getRFFI().getRApplRFFI().createRApplRFFINode(); private static final String E = RRuntime.NAMES_ATTR_EMPTY_VALUE; private static final RStringVector DQRDC2_NAMES = RDataFactory.createStringVector(new String[]{"qr", E, E, E, E, "rank", "qraux", "pivot", E}, RDataFactory.COMPLETE_VECTOR); + @Child private GetDimAttributeNode getDimNode = GetDimAttributeNode.create(); + @Override public RList call(RArgsValuesAndNames args) { Object[] argValues = args.getArguments(); @@ -44,10 +49,10 @@ public final class Dqrdc2 extends RExternalBuiltinNode { int[] rank = rankVec.materialize().getDataTemp(); double[] qraux = qrauxVec.materialize().getDataTemp(); int[] pivot = pivotVec.materialize().getDataTemp(); - RFFIFactory.getRFFI().getRApplRFFI().dqrdc2(x, ldx, n, p, tol, rank, qraux, pivot, workVec.materialize().getDataCopy()); + rApplRFFINode.dqrdc2(x, ldx, n, p, tol, rank, qraux, pivot, workVec.materialize().getDataCopy()); // @formatter:off Object[] data = new Object[]{ - RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR, xVec.getDimensions()), + RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR, getDimNode.getDimensions(xVec)), argValues[1], argValues[2], argValues[3], argValues[4], RDataFactory.createIntVector(rank, RDataFactory.COMPLETE_VECTOR), RDataFactory.createDoubleVector(qraux, RDataFactory.COMPLETE_VECTOR), diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ExtractNativeCallInfoNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ExtractNativeCallInfoNode.java deleted file mode 100644 index 47d1f4a19c04070de6ce485cc2b780ee8f2bca86..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ExtractNativeCallInfoNode.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2016, 2016, 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.nodes.builtin.base.foreign; - -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; -import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RExternalPtr; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RLogical; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; -import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; -import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; - -/** - * Extracts the salient information needed for a native call from the {@link RList} value provided - * from R. - */ -public abstract class ExtractNativeCallInfoNode extends Node { - @Child private ExtractVectorNode nameExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); - @Child private ExtractVectorNode addressExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); - @Child private ExtractVectorNode packageExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); - @Child private ExtractVectorNode infoExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); - - protected abstract Object execute(VirtualFrame frame, RList symbol); - - @Specialization - protected Object extractNativeCallInfo(VirtualFrame frame, RList symbol) { - if (nameExtract == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - nameExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); - } - if (addressExtract == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - addressExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); - } - if (packageExtract == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - packageExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); - } - String name = RRuntime.asString(nameExtract.applyAccessField(frame, symbol, "name")); - SymbolHandle address = ((RExternalPtr) addressExtract.applyAccessField(frame, symbol, "address")).getAddr(); - // field name may be "package" or "dll", but always at (R) index 3 - RList packageList = (RList) packageExtract.apply(frame, symbol, new Object[]{3}, RLogical.valueOf(false), RMissing.instance); - DLLInfo dllInfo = (DLLInfo) ((RExternalPtr) addressExtract.applyAccessField(frame, packageList, "info")).getExternalObject(); - return new NativeCallInfo(name, address, dllInfo); - - } - -} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java index c15e41e81848edfec4ae9ad06f1ebbac9a6a7850..b4bf5517d216c83e638f04f7e139142fa7278a16 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java @@ -11,8 +11,10 @@ */ package com.oracle.truffle.r.nodes.builtin.base.foreign; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; @@ -20,11 +22,13 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; +import com.oracle.truffle.r.runtime.ffi.StatsRFFI; public abstract class Fft extends RExternalBuiltinNode.Arg2 { private final ConditionProfile zVecLgt1 = ConditionProfile.createBinaryProfile(); private final ConditionProfile noDims = ConditionProfile.createBinaryProfile(); + @Child private StatsRFFI.FFTNode fftNode = RFFIFactory.getRFFI().getStatsRFFI().createFFTNode(); @Override protected void createCasts(CastBuilder casts) { @@ -34,33 +38,33 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { // TODO: handle more argument types (this is sufficient to run the b25 benchmarks) @Specialization - public Object execute(RAbstractComplexVector zVec, boolean inverse) { + public Object execute(RAbstractComplexVector zVec, boolean inverse, @Cached("create()") GetDimAttributeNode getDimNode) { double[] z = zVec.materialize().getDataTemp(); int inv = inverse ? 2 : -2; + int[] d = getDimNode.getDimensions(zVec); @SuppressWarnings("unused") int retCode = 7; if (zVecLgt1.profile(zVec.getLength() > 1)) { int[] maxf = new int[1]; int[] maxp = new int[1]; - if (noDims.profile(zVec.getDimensions() == null)) { + if (noDims.profile(d == null)) { int n = zVec.getLength(); - RFFIFactory.getRFFI().getStatsRFFI().fft_factor(n, maxf, maxp); + fftNode.executeFactor(n, maxf, maxp); if (maxf[0] == 0) { errorProfile.enter(); throw RError.error(this, RError.Message.FFT_FACTORIZATION); } double[] work = new double[4 * maxf[0]]; int[] iwork = new int[maxp[0]]; - retCode = RFFIFactory.getRFFI().getStatsRFFI().fft_work(z, 1, n, 1, inv, work, iwork); + retCode = fftNode.executeWork(z, 1, n, 1, inv, work, iwork); } else { int maxmaxf = 1; int maxmaxp = 1; - int[] d = zVec.getDimensions(); int ndims = d.length; /* do whole loop just for error checking and maxmax[fp] .. */ for (int i = 0; i < ndims; i++) { if (d[i] > 1) { - RFFIFactory.getRFFI().getStatsRFFI().fft_factor(d[i], maxf, maxp); + fftNode.executeFactor(d[i], maxf, maxp); if (maxf[0] == 0) { errorProfile.enter(); throw RError.error(this, RError.Message.FFT_FACTORIZATION); @@ -83,12 +87,12 @@ public abstract class Fft extends RExternalBuiltinNode.Arg2 { nspn *= n; n = d[i]; nseg /= n; - RFFIFactory.getRFFI().getStatsRFFI().fft_factor(n, maxf, maxp); - RFFIFactory.getRFFI().getStatsRFFI().fft_work(z, nseg, n, nspn, inv, work, iwork); + fftNode.executeFactor(n, maxf, maxp); + fftNode.executeWork(z, nseg, n, nspn, inv, work, iwork); } } } } - return RDataFactory.createComplexVector(z, zVec.isComplete(), zVec.getDimensions()); + return RDataFactory.createComplexVector(z, zVec.isComplete(), d); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java new file mode 100644 index 0000000000000000000000000000000000000000..abf14d088d7d3deceb19912bb0298050b8343eb5 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java @@ -0,0 +1,282 @@ +/* + * 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-2012, The R Core Team + * Copyright (c) 2003, The R Foundation + * Copyright (c) 2015, 2016, Oracle and/or its affiliates + * + * All rights reserved. + */ +package com.oracle.truffle.r.nodes.builtin.base.foreign; + +import static com.oracle.truffle.r.runtime.builtins.RBehavior.COMPLEX; +import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; + +import com.oracle.truffle.api.CompilerAsserts; +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.frame.VirtualFrame; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.runtime.ArgumentsSignature; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.builtins.RBuiltin; +import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; +import com.oracle.truffle.r.runtime.ffi.CRFFI; +import com.oracle.truffle.r.runtime.ffi.DLL; +import com.oracle.truffle.r.runtime.ffi.RFFIFactory; +import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; + +/** + * {@code .C} and {@code .Fortran} functions, which share a common signature. + * + * TODO Completeness (more types, more error checks), Performance (copying). Especially all the + * subtleties around copying. + * + * See <a href="https://stat.ethz.ch/R-manual/R-devel/library/base/html/Foreign.html">here</a>. + */ +public class FortranAndCFunctions { + + protected abstract static class CRFFIAdapter extends LookupAdapter { + private static final int SCALAR_DOUBLE = 0; + private static final int SCALAR_INT = 1; + private static final int SCALAR_LOGICAL = 2; + @SuppressWarnings("unused") private static final int SCALAR_STRING = 3; + private static final int VECTOR_DOUBLE = 10; + private static final int VECTOR_INT = 11; + private static final int VECTOR_LOGICAL = 12; + @SuppressWarnings("unused") private static final int VECTOR_STRING = 12; + + @Child private CRFFI.CRFFINode cRFFINode = RFFIFactory.getRFFI().getCRFFI().createCRFFINode(); + + @Override + public Object[] getDefaultParameterValues() { + return new Object[]{RMissing.instance, RArgsValuesAndNames.EMPTY, RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_FALSE, RMissing.instance, RMissing.instance}; + } + + @TruffleBoundary + protected RList dispatch(RBuiltinNode node, NativeCallInfo nativeCallInfo, byte naok, byte dup, RArgsValuesAndNames args) { + @SuppressWarnings("unused") + boolean dupArgs = RRuntime.fromLogical(dup); + @SuppressWarnings("unused") + boolean checkNA = RRuntime.fromLogical(naok); + // Analyze the args, making copies (ignoring dup for now) + Object[] array = args.getArguments(); + int[] argTypes = new int[array.length]; + Object[] nativeArgs = new Object[array.length]; + for (int i = 0; i < array.length; i++) { + Object arg = array[i]; + if (arg instanceof RAbstractDoubleVector) { + argTypes[i] = VECTOR_DOUBLE; + nativeArgs[i] = checkNAs(node, i + 1, ((RAbstractDoubleVector) arg).materialize().getDataCopy()); + } else if (arg instanceof RAbstractIntVector) { + argTypes[i] = VECTOR_INT; + nativeArgs[i] = checkNAs(node, i + 1, ((RAbstractIntVector) arg).materialize().getDataCopy()); + } else if (arg instanceof RAbstractLogicalVector) { + argTypes[i] = VECTOR_LOGICAL; + // passed as int[] + byte[] data = ((RAbstractLogicalVector) arg).materialize().getDataWithoutCopying(); + int[] dataAsInt = new int[data.length]; + for (int j = 0; j < data.length; j++) { + // An NA is an error but the error handling happens in checkNAs + dataAsInt[j] = RRuntime.isNA(data[j]) ? RRuntime.INT_NA : data[j]; + } + nativeArgs[i] = checkNAs(node, i + 1, dataAsInt); + } else if (arg instanceof Double) { + argTypes[i] = SCALAR_DOUBLE; + nativeArgs[i] = checkNAs(node, i + 1, new double[]{(double) arg}); + } else if (arg instanceof Integer) { + argTypes[i] = SCALAR_INT; + nativeArgs[i] = checkNAs(node, i + 1, new int[]{(int) arg}); + } else if (arg instanceof Byte) { + argTypes[i] = SCALAR_LOGICAL; + nativeArgs[i] = checkNAs(node, i + 1, new int[]{RRuntime.isNA((byte) arg) ? RRuntime.INT_NA : (byte) arg}); + } else { + throw RError.error(node, RError.Message.UNIMPLEMENTED_ARG_TYPE, i + 1); + } + } + cRFFINode.invoke(nativeCallInfo, nativeArgs); + // we have to assume that the native method updated everything + RStringVector listNames = validateArgNames(array.length, args.getSignature()); + Object[] results = new Object[array.length]; + for (int i = 0; i < array.length; i++) { + switch (argTypes[i]) { + case SCALAR_DOUBLE: + results[i] = RDataFactory.createDoubleVector((double[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); + break; + case SCALAR_INT: + results[i] = RDataFactory.createIntVector((int[]) nativeArgs[i], RDataFactory.COMPLETE_VECTOR); + break; + case SCALAR_LOGICAL: + // 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]); + break; + case VECTOR_INT: + results[i] = ((RAbstractIntVector) array[i]).materialize().copyResetData((int[]) nativeArgs[i]); + break; + case VECTOR_LOGICAL: { + int[] intData = (int[]) nativeArgs[i]; + byte[] byteData = new byte[intData.length]; + for (int j = 0; j < intData.length; j++) { + byteData[j] = RRuntime.isNA(intData[j]) ? RRuntime.LOGICAL_NA : RRuntime.asLogical(intData[j] != 0); + } + results[i] = ((RAbstractLogicalVector) array[i]).materialize().copyResetData(byteData); + break; + } + } + } + return RDataFactory.createList(results, listNames); + } + + private static int[] checkNAs(RBuiltinNode node, int argIndex, int[] data) { + CompilerAsserts.neverPartOfCompilation(); + for (int i = 0; i < data.length; i++) { + if (RRuntime.isNA(data[i])) { + throw RError.error(node, RError.Message.NA_IN_FOREIGN_FUNCTION_CALL, argIndex); + } + } + return data; + } + + private static double[] checkNAs(RBuiltinNode node, int argIndex, double[] data) { + CompilerAsserts.neverPartOfCompilation(); + for (int i = 0; i < data.length; i++) { + if (!RRuntime.isFinite(data[i])) { + throw RError.error(node, RError.Message.NA_NAN_INF_IN_FOREIGN_FUNCTION_CALL, argIndex); + } + } + return data; + } + + private static RStringVector validateArgNames(int argsLength, ArgumentsSignature signature) { + String[] listArgNames = new String[argsLength]; + for (int i = 0; i < argsLength; i++) { + String name = signature.getName(i); + if (name == null) { + name = RRuntime.NAMES_ATTR_EMPTY_VALUE; + } + listArgNames[i] = name; + } + return RDataFactory.createStringVector(listArgNames, RDataFactory.COMPLETE_VECTOR); + } + + } + + /** + * Interface to .Fortran native functions. Some functions have explicit implementations in + * FastR, otherwise the .Fortran interface uses the machinery that implements the .C interface. + */ + @RBuiltin(name = ".Fortran", kind = PRIMITIVE, parameterNames = {".NAME", "...", "NAOK", "DUP", "PACKAGE", "ENCODING"}, behavior = COMPLEX) + public abstract static class Fortran extends CRFFIAdapter { + + @Override + @TruffleBoundary + protected RExternalBuiltinNode lookupBuiltin(RList symbol) { + switch (lookupName(symbol)) { + case "dqrdc2": + return new Dqrdc2(); + case "dqrcf": + return new Dqrcf(); + default: + return null; + } + } + + @SuppressWarnings("unused") + @Specialization(limit = "1", guards = {"cached == symbol", "builtin != null"}) + protected Object doExternal(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, byte naok, byte dup, Object rPackage, RMissing encoding, // + @Cached("symbol") RList cached, // + @Cached("lookupBuiltin(symbol)") RExternalBuiltinNode builtin) { + return builtin.call(frame, args); + } + + @Specialization(guards = "lookupBuiltin(symbol) == null") + protected RList c(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, byte naok, byte dup, @SuppressWarnings("unused") Object rPackage, + @SuppressWarnings("unused") RMissing encoding) { + NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); + return dispatch(this, nativeCallInfo, naok, dup, args); + } + + @Specialization + protected RList c(RAbstractStringVector symbol, RArgsValuesAndNames args, byte naok, byte dup, Object rPackage, @SuppressWarnings("unused") RMissing encoding, // + @Cached("create()") BranchProfile errorProfile) { + String libName = checkPackageArg(rPackage, errorProfile); + DLL.RegisteredNativeSymbol rns = new DLL.RegisteredNativeSymbol(DLL.NativeSymbolType.Fortran, null, null); + DLL.SymbolHandle func = DLL.findSymbol(symbol.getDataAt(0), libName, rns); + if (func == DLL.SYMBOL_NOT_FOUND) { + errorProfile.enter(); + throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, symbol); + } + return dispatch(this, new NativeCallInfo(symbol.getDataAt(0), func, rns.getDllInfo()), naok, dup, args); + } + + @SuppressWarnings("unused") + @Fallback + protected Object fallback(Object symbol, Object args, Object naok, Object dup, Object rPackage, Object encoding) { + throw fallback(symbol); + } + } + + @RBuiltin(name = ".C", kind = PRIMITIVE, parameterNames = {".NAME", "...", "NAOK", "DUP", "PACKAGE", "ENCODING"}, behavior = COMPLEX) + public abstract static class DotC extends CRFFIAdapter { + + @Override + @TruffleBoundary + protected RExternalBuiltinNode lookupBuiltin(RList symbol) { + throw RInternalError.shouldNotReachHere(); + } + + @SuppressWarnings("unused") + @Specialization + protected RList c(VirtualFrame frame, RList symbol, RArgsValuesAndNames args, byte naok, byte dup, Object rPackage, RMissing encoding) { + NativeCallInfo nativeCallInfo = extractSymbolInfo(frame, symbol); + return dispatch(this, nativeCallInfo, naok, dup, args); + } + + @SuppressWarnings("unused") + @Specialization + protected RList c(RAbstractStringVector symbol, RArgsValuesAndNames args, byte naok, byte dup, Object rPackage, RMissing encoding, // + @Cached("create()") BranchProfile errorProfile) { + String libName = null; + if (!(rPackage instanceof RMissing)) { + libName = RRuntime.asString(rPackage); + if (libName == null) { + errorProfile.enter(); + throw RError.error(this, RError.Message.ARGUMENT_MUST_BE_STRING, "PACKAGE"); + } + } + DLL.RegisteredNativeSymbol rns = new DLL.RegisteredNativeSymbol(DLL.NativeSymbolType.C, null, null); + DLL.SymbolHandle func = DLL.findSymbol(symbol.getDataAt(0), libName, rns); + if (func == DLL.SYMBOL_NOT_FOUND) { + errorProfile.enter(); + throw RError.error(this, RError.Message.C_SYMBOL_NOT_IN_TABLE, symbol); + } + return dispatch(this, new NativeCallInfo(symbol.getDataAt(0), func, rns.getDllInfo()), naok, dup, args); + } + + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/LookupAdapter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/LookupAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..5da46c93311b5d2f68f85a60ba0b085c4b3539c8 --- /dev/null +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/LookupAdapter.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2015, 2016, 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.nodes.builtin.base.foreign; + +import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.library.stats.RandGenerationFunctions; +import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; +import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; +import com.oracle.truffle.r.nodes.builtin.RInternalCodeBuiltinNode; +import com.oracle.truffle.r.nodes.builtin.base.foreign.LookupAdapterFactory.ExtractNativeCallInfoNodeGen; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RInternalCode; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; +import com.oracle.truffle.r.runtime.data.RExternalPtr; +import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RLogical; +import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; +import com.oracle.truffle.r.runtime.ffi.DLL; +import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; +import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; +import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; + +/** + * Locator for "builtin" package function implementations. The "builtin" packages contain many + * functions that are called from R code via the FFI, e.g. {@code .Call}, but implemented internally + * in GnuR, and not necessarily following the FFI API. The value passed to {@code .Call} etc., is a + * symbol, created when the package is loaded and stored in the namespace environment of the + * package, that is a list-valued object. Evidently these "builtins" are somewhat similar to the + * {@code .Primitive} and {@code .Internal} builtins and, similarly, most of these are + * re-implemented in Java in FastR. The {@link #lookupBuiltin(RList)} method checks the name in the + * list object and returns the {@link RExternalBuiltinNode} that implements the function, or + * {@code null}. A {@code null} result implies that the builtin is not implemented in Java, but + * called directly via the FFI interface, which is only possible for functions that use the FFI in a + * way that FastR can handle. + * + * This class also handles the "lookup" of the {@link NativeCallInfo} data for builtins that are + * still implemented by native code. + */ +abstract class LookupAdapter extends RBuiltinNode { + @Child private ExtractNativeCallInfoNode extractSymbolInfoNode = ExtractNativeCallInfoNodeGen.create(); + + protected static class UnimplementedExternal extends RExternalBuiltinNode { + private final String name; + + public UnimplementedExternal(String name) { + this.name = name; + } + + @Override + public final Object call(RArgsValuesAndNames args) { + throw RInternalError.unimplemented("unimplemented external builtin: " + name); + } + } + + protected abstract RExternalBuiltinNode lookupBuiltin(RList symbol); + + private static final String UNKNOWN_EXTERNAL_BUILTIN = "UNKNOWN_EXTERNAL_BUILTIN"; + + protected static String lookupName(RList symbol) { + CompilerAsserts.neverPartOfCompilation(); + if (symbol.getNames() != null) { + RAbstractStringVector names = symbol.getNames(); + for (int i = 0; i < names.getLength(); i++) { + if (names.getDataAt(i).equals("name")) { + String name = RRuntime.asString(symbol.getDataAt(i)); + return name != null ? name : UNKNOWN_EXTERNAL_BUILTIN; + } + } + } + return UNKNOWN_EXTERNAL_BUILTIN; + } + + @TruffleBoundary + protected RuntimeException fallback(Object symbol) { + String name = null; + if (symbol instanceof RList) { + name = lookupName((RList) symbol); + name = name == UNKNOWN_EXTERNAL_BUILTIN ? null : name; + if (name != null && lookupBuiltin((RList) symbol) != null) { + /* + * if we reach this point, then the cache saw a different value for f. the lists + * that contain the information about native calls are never expected to change. + */ + throw RInternalError.shouldNotReachHere("fallback reached for " + getRBuiltin().name() + " " + name); + } + } + throw RError.nyi(this, getRBuiltin().name() + " specialization failure: " + (name == null ? "<unknown>" : name)); + } + + protected NativeCallInfo extractSymbolInfo(VirtualFrame frame, RList symbol) { + return (NativeCallInfo) extractSymbolInfoNode.execute(frame, symbol); + } + + protected String checkPackageArg(Object rPackage, BranchProfile errorProfile) { + String libName = null; + if (!(rPackage instanceof RMissing)) { + libName = RRuntime.asString(rPackage); + if (libName == null) { + errorProfile.enter(); + throw RError.error(this, RError.Message.ARGUMENT_MUST_BE_STRING, "PACKAGE"); + } + } + return libName; + } + + /** + * Extracts the salient information needed for a native call from the {@link RList} value + * provided from R. + */ + public abstract static class ExtractNativeCallInfoNode extends Node { + @Child private ExtractVectorNode nameExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); + @Child private ExtractVectorNode addressExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); + @Child private ExtractVectorNode packageExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); + @Child private ExtractVectorNode infoExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); + + protected abstract Object execute(VirtualFrame frame, RList symbol); + + @Specialization + protected Object extractNativeCallInfo(VirtualFrame frame, RList symbol) { + if (nameExtract == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + nameExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); + } + if (addressExtract == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + addressExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); + } + if (packageExtract == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + packageExtract = ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true); + } + String name = RRuntime.asString(nameExtract.applyAccessField(frame, symbol, "name")); + SymbolHandle address = ((RExternalPtr) addressExtract.applyAccessField(frame, symbol, "address")).getAddr(); + // field name may be "package" or "dll", but always at (R) index 3 + RList packageList = (RList) packageExtract.apply(frame, symbol, new Object[]{3}, RLogical.valueOf(false), RMissing.instance); + DLLInfo dllInfo = (DLLInfo) ((RExternalPtr) addressExtract.applyAccessField(frame, packageList, "info")).getExternalObject(); + return new NativeCallInfo(name, address, dllInfo); + + } + } + + protected static RExternalBuiltinNode getExternalModelBuiltinNode(String name) { + return new RInternalCodeBuiltinNode(RContext.getInstance(), "stats", RInternalCode.loadSourceRelativeTo(RandGenerationFunctions.class, "model.R"), name); + } + + protected static final int CallNST = DLL.NativeSymbolType.Call.ordinal(); + protected static final int ExternalNST = DLL.NativeSymbolType.External.ordinal(); + + public static DLL.RegisteredNativeSymbol createRegisteredNativeSymbol(int nstOrd) { + // DSL cannot resolve DLL.DLL.NativeSymbolType + DLL.NativeSymbolType nst = DLL.NativeSymbolType.values()[nstOrd]; + return new DLL.RegisteredNativeSymbol(nst, null, null); + } +} diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java index 36866074464c2b3f440152f76350d05a393b6dbc..9f848c51562ad640a6ac5c7331ebdd9be1c13c2b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java @@ -39,6 +39,7 @@ import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout; import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; import com.oracle.truffle.r.nodes.access.vector.ExtractListElement; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; @@ -69,8 +70,8 @@ abstract class AccessFieldSpecial extends SpecialsUtils.ListFieldSpecialBase { } @Specialization(contains = "doList", guards = {"isSimpleList(list)", "list.getNames() != null"}) - public Object doListDynamic(RList list, String field) { - return doList(list, field, getIndex(list.getNames(), field)); + public Object doListDynamic(RList list, String field, @Cached("create()") GetNamesAttributeNode getNamesNode) { + return doList(list, field, getIndex(getNamesNode.getNames(list), field)); } @Fallback diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java index a72d60cf059516649d731875c9f2352777135446..793d882e1a8121d8e29bcbdbcd993e9b78bbe6d3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/SpecialsUtils.java @@ -26,6 +26,7 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.data.RList; @@ -84,12 +85,13 @@ class SpecialsUtils { @CompilationFinal private String cachedField; @CompilationFinal private RStringVector cachedNames; @Child private ClassHierarchyNode hierarchyNode = ClassHierarchyNode.create(); + @Child protected GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); protected final void updateCache(RList list, String field) { if (cachedField == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); cachedField = field; - cachedNames = list.getNames(); + cachedNames = getNamesNode.getNames(list); } } @@ -98,7 +100,7 @@ class SpecialsUtils { } protected final boolean isCached(RList list, String field) { - return cachedField == null || (cachedField == field && list.getNames() == cachedNames); + return cachedField == null || (cachedField == field && getNamesNode.getNames(list) == cachedNames); } protected static int getIndex(RStringVector names, String field) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java index 4b3166024df80800419b87a3ec2843f9f62f46b7..9d693de22845ef0dba043d41824103eeda08015e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Subset.java @@ -34,12 +34,12 @@ import com.oracle.truffle.r.nodes.EmptyTypeSystemFlatLayout; import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; import com.oracle.truffle.r.nodes.access.vector.ExtractListElement; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RLogical; @@ -55,12 +55,12 @@ import com.oracle.truffle.r.runtime.nodes.RNode; @TypeSystemReference(EmptyTypeSystemFlatLayout.class) abstract class SubsetSpecial extends SubscriptSpecialBase { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); @Override protected boolean simpleVector(RAbstractVector vector) { vector = vectorClassProfile.profile(vector); - return super.simpleVector(vector) && vector.getNames(attrProfiles) == null; + return super.simpleVector(vector) && getNamesNode.getNames(vector) == null; } @Override diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java index 771bc4bd590e1e2d170aacb2159ceca8c77d16c5..1918c7c7447a23370355b722e6bcf4ba139faeb0 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java @@ -25,8 +25,11 @@ package com.oracle.truffle.r.nodes.builtin.base.infix; import static com.oracle.truffle.r.runtime.builtins.RBehavior.READS_FRAME; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.RCallNode; import com.oracle.truffle.r.runtime.RRuntime; @@ -49,18 +52,25 @@ public abstract class Tilde extends RBuiltinNode { private static final RStringVector FORMULA_CLASS = RDataFactory.createStringVectorFromScalar(RRuntime.FORMULA_CLASS); + @Child private SetClassAttributeNode setClassAttrNode = SetClassAttributeNode.create(); + @Override public Object[] getDefaultParameterValues() { return new Object[]{RMissing.instance, RMissing.instance}; } + protected SetFixedAttributeNode createSetEnvAttrNode() { + return SetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT); + } + @Specialization - protected RLanguage tilde(VirtualFrame frame, @SuppressWarnings("unused") Object response, @SuppressWarnings("unused") Object model) { + protected RLanguage tilde(VirtualFrame frame, @SuppressWarnings("unused") Object response, @SuppressWarnings("unused") Object model, + @Cached("createSetEnvAttrNode()") SetFixedAttributeNode setEnvAttrNode) { RCallNode call = (RCallNode) ((RBaseNode) getParent()).asRSyntaxNode(); RLanguage lang = RDataFactory.createLanguage(call); - lang.setClassAttr(FORMULA_CLASS); + setClassAttrNode.execute(lang, FORMULA_CLASS); REnvironment env = REnvironment.frameToEnvironment(frame.materialize()); - lang.setAttr(RRuntime.DOT_ENVIRONMENT, env); + setEnvAttrNode.execute(lang, env); return lang; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java index da44b6344da226739efbb89c77cbb9067773ccbe..ebbd01a056c1e63bb5e0436186690bb062b07a2c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/UpdateField.java @@ -83,7 +83,7 @@ abstract class UpdateFieldSpecial extends SpecialsUtils.ListFieldSpecialBase { @Specialization(contains = "doList", guards = {"isSimpleList(list)", "!list.isShared()", "list.getNames() != null", "isNotRNullRList(value)"}) public RList doListDynamic(RList list, String field, Object value) { - return doList(list, field, value, getIndex(list.getNames(), field)); + return doList(list, field, value, getIndex(getNamesNode.getNames(list), field)); } @SuppressWarnings("unused") diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java index d8fcdd5d2926f7fbae17bbc8913cc2097940d3e5..6bbd827d0354c7ff5428f5c4a1bc7a1fbb82a087 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ExpressionPrinter.java @@ -26,8 +26,6 @@ import java.io.IOException; import java.io.PrintWriter; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -39,8 +37,6 @@ final class ExpressionPrinter extends AbstractValuePrinter<RExpression> { // singleton } - private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); - @Override @TruffleBoundary protected void printValue(RExpression expr, PrintContext printCtx) throws IOException { @@ -49,7 +45,7 @@ final class ExpressionPrinter extends AbstractValuePrinter<RExpression> { valPrintCtx.parameters().setSuppressIndexLabels(true); out.print("expression("); - RStringVector names = (RStringVector) expr.getAttr(dummyAttrProfiles, RRuntime.NAMES_ATTR_KEY); + RStringVector names = expr.getNames(); for (int i = 0; i < expr.getLength(); i++) { if (i != 0) { out.print(", "); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java index ffc0c1db1b5e9877d742687455e746f049aa7cb3..62a994e753e86d30a52158f32994a1dbba4891ae 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java @@ -44,20 +44,19 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { static final ListPrinter INSTANCE = new ListPrinter(); + private static final RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); private ListPrinter() { // singleton } - private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); - private static int TAGBUFLEN = 256; @Override @TruffleBoundary protected void printValue(RAbstractListVector s, PrintContext printCtx) throws IOException { RAbstractIntVector dims = Utils.<RAbstractIntVector> castTo( - s.getAttr(dummyAttrProfiles, RRuntime.DIM_ATTR_KEY)); + s.getAttr(RRuntime.DIM_ATTR_KEY)); if (dims != null && dims.getLength() > 1) { printDimList(s, printCtx); @@ -151,7 +150,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { } RStringVector tt = RDataFactory.createStringVector(t, true, s.getDimensions()); - Object dimNames = s.getAttr(dummyAttrProfiles, RRuntime.DIMNAMES_ATTR_KEY); + Object dimNames = s.getAttr(RRuntime.DIMNAMES_ATTR_KEY); tt.setAttr(RRuntime.DIMNAMES_ATTR_KEY, dimNames); PrintContext cc = printCtx.cloneContext(); @@ -171,7 +170,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { int ns = s.getLength(); RAbstractStringVector names; - names = Utils.castTo(RRuntime.asAbstractVector(s.getAttr(dummyAttrProfiles, RRuntime.NAMES_ATTR_KEY))); + names = Utils.castTo(RRuntime.asAbstractVector(s.getNames(dummyAttrProfiles))); if (ns > 0) { int npr = (ns <= pp.getMax() + 1) ? ns : pp.getMax(); @@ -216,7 +215,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { out.println(tagbuf); Object si = s.getDataAtAsObject(i); - if (si instanceof RAttributable && ((RAttributable) si).isObject(dummyAttrProfiles)) { + if (si instanceof RAttributable && ((RAttributable) si).isObject()) { RContext.getEngine().printResult(si); } else { ValuePrinters.INSTANCE.print(si, printCtx); @@ -236,7 +235,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { /* Formal classes are represented as empty lists */ String className = null; if (printCtx.printerNode().isObject(s) && printCtx.printerNode().isMethodDispatchOn()) { - RAbstractStringVector klass = Utils.castTo(RRuntime.asAbstractVector(s.getAttr(dummyAttrProfiles, RRuntime.CLASS_ATTR_KEY))); + RAbstractStringVector klass = Utils.castTo(RRuntime.asAbstractVector(s.getAttr(RRuntime.CLASS_ATTR_KEY))); if (klass != null && klass.getLength() == 1) { String ss = klass.getDataAt(0); String str = snprintf(200, ".__C__%s", ss); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java index 9dabad114d57463555f70c483b5dbc381a9abc9b..5927ddf98ec477d3b0d8c3dc191785040e0831f2 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java @@ -17,7 +17,6 @@ import java.io.IOException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RNull; @@ -42,13 +41,11 @@ final class PairListPrinter extends AbstractValuePrinter<RPairList> { // singleton } - private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); - @Override @TruffleBoundary protected void printValue(RPairList s, PrintContext printCtx) throws IOException { final RAbstractIntVector dims = Utils.<RAbstractIntVector> castTo( - s.getAttr(dummyAttrProfiles, RRuntime.DIM_ATTR_KEY)); + s.getAttr(RRuntime.DIM_ATTR_KEY)); final int ns = s.getLength(); @@ -82,7 +79,7 @@ final class PairListPrinter extends AbstractValuePrinter<RPairList> { t[i] = pbuf; RStringVector tt = RDataFactory.createStringVector(t, true, s.getDimensions()); - Object dimNames = s.getAttr(dummyAttrProfiles, RRuntime.DIMNAMES_ATTR_KEY); + Object dimNames = s.getAttr(RRuntime.DIMNAMES_ATTR_KEY); tt.setAttr(RRuntime.DIMNAMES_ATTR_KEY, dimNames); PrintContext cc = printCtx.cloneContext(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java index cbcb5e2af91c4a3884b2f87f57ca61a10498684b..7448ebc7516c8ea623afd1c3ca912f86528212e5 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinterNode.java @@ -542,7 +542,7 @@ public final class ValuePrinterNode extends RBaseNode { } @Override - public void setNames(RStringVector newNames) { + public final void setNames(RStringVector newNames) { throw RInternalError.shouldNotReachHere(); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java index dcbc682204eda47037bf0d17c584f364f162973f..5577dd7c283cd4f934d3edcdee26c1a71687af24 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/VectorPrinter.java @@ -19,7 +19,6 @@ import java.io.PrintWriter; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; @@ -29,8 +28,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePrinter<T> { - private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); - @Override protected void printValue(T vector, PrintContext printCtx) throws IOException { printVector(vector, 1, printCtx); @@ -77,13 +74,13 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri MatrixDimNames mdn = null; - Object dimAttr = vector.getAttr(dummyAttrProfiles, RRuntime.DIM_ATTR_KEY); + Object dimAttr = vector.getAttr(RRuntime.DIM_ATTR_KEY); if (dimAttr instanceof RAbstractIntVector) { dims = (RAbstractIntVector) dimAttr; if (dims.getLength() == 1) { - RList t = Utils.<RList> castTo(vector.getAttr(dummyAttrProfiles, RRuntime.DIMNAMES_ATTR_KEY)); + RList t = Utils.<RList> castTo(vector.getAttr(RRuntime.DIMNAMES_ATTR_KEY)); if (t != null && t.getDataAt(0) != null) { - RAbstractStringVector nn = Utils.castTo(RRuntime.asAbstractVector(t.getAttr(dummyAttrProfiles, RRuntime.NAMES_ATTR_KEY))); + RAbstractStringVector nn = Utils.castTo(RRuntime.asAbstractVector(t.getNames())); if (nn != null) { title = nn.getDataAt(0); @@ -111,7 +108,7 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri } } else { dims = null; - Object namesAttr = Utils.castTo(vector.getAttr(dummyAttrProfiles, RRuntime.NAMES_ATTR_KEY)); + Object namesAttr = Utils.castTo(vector.getAttr(RRuntime.NAMES_ATTR_KEY)); if (namesAttr != null) { if (vector.getLength() > 0) { names = Utils.castTo(RRuntime.asAbstractVector(namesAttr)); @@ -676,7 +673,7 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri final RAbstractStringVector axisNames; MatrixDimNames(RAbstractVector x) { - dimnames = Utils.<RList> castTo(x.getAttr(dummyAttrProfiles, RRuntime.DIMNAMES_ATTR_KEY)); + dimnames = Utils.<RList> castTo(x.getAttr(RRuntime.DIMNAMES_ATTR_KEY)); if (dimnames == null) { rl = null; @@ -688,7 +685,7 @@ abstract class VectorPrinter<T extends RAbstractVector> extends AbstractValuePri } else { rl = getDimNamesAt(0); cl = getDimNamesAt(1); - axisNames = Utils.<RAbstractStringVector> castTo(dimnames.getAttr(dummyAttrProfiles, RRuntime.NAMES_ATTR_KEY)); + axisNames = Utils.<RAbstractStringVector> castTo(dimnames.getNames()); if (axisNames == null) { rn = null; cn = null; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRContext.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRContext.java index 4a6ededba9b6103720b5e7d49202ec778b612c6e..dd68c15f3a66753ccf27bed53273331db337bcf7 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRContext.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRContext.java @@ -192,7 +192,11 @@ public class FastRContext { if (pc == 1) { ContextInfo info = createContextInfo(contextKind); PolyglotEngine vm = info.createVM(); - results[0] = RContext.EvalThread.run(vm, info, RSource.fromTextInternal(exprs.getDataAt(0), RSource.Internal.CONTEXT_EVAL)); + try { + results[0] = RContext.EvalThread.run(vm, info, RSource.fromTextInternal(exprs.getDataAt(0), RSource.Internal.CONTEXT_EVAL)); + } finally { + vm.dispose(); + } } else { // separate threads that run in parallel; invoking thread waits for completion RContext.EvalThread[] threads = new RContext.EvalThread[pc]; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java index 071ef08d2a93304f80ef7f32d0c3661722fef431..315f1f2c0aad2161732c7d25cb6d09620e3a958d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTry.java @@ -33,6 +33,7 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.function.RCallBaseNode; import com.oracle.truffle.r.nodes.function.RCallNode; import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RFunction; @@ -55,7 +56,7 @@ public abstract class FastRTry extends RBuiltinNode { frame.setObject(frameSlot, RArgsValuesAndNames.EMPTY); call.execute(frame, func); } catch (Throwable ex) { - return String.format("Exception %s, message: %s", ex.getClass().getSimpleName(), ex.getMessage()); + return Utils.stringFormat("Exception %s, message: %s", ex.getClass().getSimpleName(), ex.getMessage()); } finally { frame.setObject(frameSlot, null); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java index 07719a305b4ca2937b7dbd2d4a5cb64eddebc9b0..714e8c2a381a8dd49dd583944e2439d4e5d3ef7d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastrDqrls.java @@ -23,13 +23,13 @@ import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNode; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.ffi.RApplRFFI; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; /** @@ -38,14 +38,11 @@ import com.oracle.truffle.r.runtime.ffi.RFFIFactory; */ @RBuiltin(name = ".fastr.dqrls", visibility = OFF, kind = PRIMITIVE, parameterNames = {"x", "n", "p", "y", "ny", "tol", "coeff"}, behavior = PURE) public abstract class FastrDqrls extends RBuiltinNode { + @Child private RApplRFFI.RApplRFFINode rApplRFFINode = RFFIFactory.getRFFI().getRApplRFFI().createRApplRFFINode(); private static final String[] NAMES = new String[]{"qr", "coefficients", "residuals", "effects", "rank", "pivot", "qraux", "tol", "pivoted"}; private static RStringVector namesVector = null; - private final RAttributeProfiles coeffAttributeProfiles = RAttributeProfiles.create(); - private final RAttributeProfiles xAttributeProfiles = RAttributeProfiles.create(); - private final RAttributeProfiles residualsAttributesProfiles = RAttributeProfiles.create(); - @Override protected void createCasts(CastBuilder casts) { casts.arg("x").asDoubleVector(true, true, true); @@ -82,16 +79,16 @@ public abstract class FastrDqrls extends RBuiltinNode { pivot[i] = i + 1; } - RFFIFactory.getRFFI().getRApplRFFI().dqrls(x, n, p, y, ny, tol, coeff, residuals, effects, rank, pivot, qraux, work); + rApplRFFINode.dqrls(x, n, p, y, ny, tol, coeff, residuals, effects, rank, pivot, qraux, work); RDoubleVector resultCoeffVect = RDataFactory.createDoubleVector(coeff, RDataFactory.COMPLETE_VECTOR); - resultCoeffVect.copyAttributesFrom(coeffAttributeProfiles, coeffVec); + resultCoeffVect.copyAttributesFrom(coeffVec); RDoubleVector resultX = RDataFactory.createDoubleVector(x, RDataFactory.COMPLETE_VECTOR); - resultX.copyAttributesFrom(xAttributeProfiles, originalXVec); + resultX.copyAttributesFrom(originalXVec); RDoubleVector resultResiduals = RDataFactory.createDoubleVector(residuals, RDataFactory.COMPLETE_VECTOR); - resultResiduals.copyAttributesFrom(residualsAttributesProfiles, originalYVec); + resultResiduals.copyAttributesFrom(originalYVec); Object[] data = new Object[]{ resultX, diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java index 044773513f6598af456b3be185fda9108d69737c..78c4fd48204f108f6fb44bc9d9ff2eaa70ff7f1c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java @@ -27,6 +27,7 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; import com.oracle.truffle.r.runtime.JumpToTopLevelException; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RCaller; @@ -69,6 +70,9 @@ public abstract class BrowserInteractNode extends RNode { public static final int CONTINUE = 2; public static final int FINISH = 3; + @Child private GetFixedAttributeNode getSrcRefAttrNode; + @Child private GetFixedAttributeNode getSrcFileAttrNode; + @Specialization protected int interact(VirtualFrame frame) { CompilerDirectives.transferToInterpreter(); @@ -179,11 +183,20 @@ public abstract class BrowserInteractNode extends RNode { return RCaller.create(null, currentCaller, builder.call(RSyntaxNode.INTERNAL, builder.lookup(RSyntaxNode.INTERNAL, "browser", true))); } - private static String getSrcinfo(RStringVector element) { - Object srcref = element.getAttr(RRuntime.R_SRCREF); + private String getSrcinfo(RStringVector element) { + if (getSrcRefAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getSrcRefAttrNode = insert(GetFixedAttributeNode.create(RRuntime.R_SRCREF)); + } + + Object srcref = getSrcRefAttrNode.execute(element); if (srcref != null) { + if (getSrcFileAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getSrcFileAttrNode = insert(GetFixedAttributeNode.create(RRuntime.R_SRCFILE)); + } RIntVector lloc = (RIntVector) srcref; - Object srcfile = lloc.getAttr(RRuntime.R_SRCFILE); + Object srcfile = getSrcFileAttrNode.execute(lloc); if (srcfile != null) { REnvironment env = (REnvironment) srcfile; return " at " + RRuntime.asString(env.get(RSrcref.SrcrefFields.filename.name())) + "#" + lloc.getDataAt(0); diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java index d17626bd61f79b6c3f08b544914cebc5fdca54c1..b0e55a5d0192eea5ba7efba7987f15b82d589f6f 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java @@ -64,7 +64,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import java.util.function.Consumer; import java.util.function.Function; import org.junit.After; @@ -75,7 +74,6 @@ import org.junit.Test; import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef; import com.oracle.truffle.r.nodes.builtin.casts.PipelineConfig; import com.oracle.truffle.r.nodes.builtin.casts.fluent.InitialPhaseBuilder; -import com.oracle.truffle.r.nodes.builtin.casts.fluent.PipelineConfigBuilder; import com.oracle.truffle.r.nodes.builtin.casts.fluent.PreinitialPhaseBuilder; import com.oracle.truffle.r.nodes.casts.CastNodeSampler; import com.oracle.truffle.r.nodes.casts.FilterSamplerFactory; diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java index 668afbfc228cf49e199438f87a448f9b7ef0b88f..ce538982b09d76218ae36524e3cb873e9f26cc20 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java @@ -67,7 +67,6 @@ import com.oracle.truffle.r.nodes.binary.BinaryArithmeticNode; import com.oracle.truffle.r.nodes.test.TestUtilities.NodeHandle; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RScalarVector; diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java index d231d368106ff91a044eb2fe90e2f943d1213b0c..5a7ef2b6e1eeb41b379c803ec9e26d2326f66b67 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java @@ -56,7 +56,6 @@ import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNode; import com.oracle.truffle.r.nodes.unary.UnaryArithmeticNodeGen; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RScalarVector; import com.oracle.truffle.r.runtime.data.RSequence; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java index 50b84824a122ebfa9b012e38dfe7807e58e57518..e5307e12f2b19f3d435dc30d25e7b497556d3231 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessSlotNode.java @@ -21,7 +21,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.attributes.GetAttributeNode; -import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.InitAttributesNode; import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen; @@ -42,6 +41,8 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RNode; +// Transcribed from src/main/attrib.c file (R_do_slot function) + /** * Perform a slot access. This node represents the {@code @} operator in R. */ diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/UpdateSlotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/UpdateSlotNode.java index c0b37f806041ee648bfecb8dccf76df73f04f3ec..22972c305937af31631bec8b43d876dadfb1b80f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/UpdateSlotNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/UpdateSlotNode.java @@ -18,7 +18,6 @@ import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.NodeChildren; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.RASTUtils; -import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.InitAttributesNode; import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; import com.oracle.truffle.r.runtime.RCaller; @@ -31,6 +30,8 @@ import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RNode; +// Transcribed from src/main/attrib.c file (R_do_slot_assign function) + @NodeChildren({@NodeChild(value = "object", type = RNode.class), @NodeChild(value = "name", type = RNode.class), @NodeChild(value = "value", type = RNode.class)}) public abstract class UpdateSlotNode extends RNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java index 9013ee971727f511d890c57a113796f664921721..589acd316b992ddc87812d2e6fb7306c88c4562d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java @@ -33,7 +33,10 @@ import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.access.vector.CachedExtractVectorNodeFactory.SetNamesNodeGen; import com.oracle.truffle.r.nodes.access.vector.PositionsCheckNode.PositionProfile; import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; -import com.oracle.truffle.r.nodes.attributes.SetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.nodes.profile.AlwaysOnBranchProfile; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; @@ -69,11 +72,15 @@ final class CachedExtractVectorNode extends CachedVectorNode { private final boolean dropDimensions; private final VectorLengthProfile vectorLengthProfile = VectorLengthProfile.create(); - private final RAttributeProfiles vectorNamesProfile = RAttributeProfiles.create(); @Child private WriteIndexedVectorNode writeVectorNode; @Child private PositionsCheckNode positionsCheckNode; @Child private SetNamesNode setNamesNode; + @Child private SetDimAttributeNode setDimNode; + @Child private SetDimNamesAttributeNode setDimNamesNode; + @Child private GetDimNamesAttributeNode getDimNamesNode; + @Child private GetNamesAttributeNode getNamesNode; + @Child private GetNamesAttributeNode getNamesFromDimNamesNode; @Children private final CachedExtractVectorNode[] extractNames; @Children private final CachedExtractVectorNode[] extractNamesAlternative; @@ -185,7 +192,11 @@ final class CachedExtractVectorNode extends CachedVectorNode { } if (oneDimensionProfile.profile(numberOfDimensions == 1)) { // names only need to be considered for single dimensional accesses - RStringVector originalNames = vector.getNames(vectorNamesProfile); + if (getNamesNode == null) { + CompilerDirectives.transferToInterpreter(); + getNamesNode = insert(GetNamesAttributeNode.create()); + } + RStringVector originalNames = getNamesNode.getNames(vector); if (originalNames != null) { metadataApplied.enter(); setNames(extractedVector, extractNames(originalNames, positions, positionProfiles, 0, originalExact, originalDropDimensions)); @@ -274,7 +285,6 @@ final class CachedExtractVectorNode extends CachedVectorNode { } private final ConditionProfile dimNamesNull = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles dimnamesNamesProfile = RAttributeProfiles.create(); private final ValueProfile foundDimNamesProfile = ValueProfile.createClassProfile(); private final ConditionProfile selectPositionsProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile originalDimNamesPRofile = ConditionProfile.createBinaryProfile(); @@ -285,8 +295,13 @@ final class CachedExtractVectorNode extends CachedVectorNode { // TODO speculate on the number of counted dimensions int dimCount = countDimensions(positionProfile); + if (getDimNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimNamesNode = insert(GetDimNamesAttributeNode.create()); + } + int[] newDimensions = new int[dimCount]; - RList originalDimNames = originalTarget.getDimNames(null); + RList originalDimNames = getDimNamesNode.getDimNames(originalTarget); RStringVector originalDimNamesNames; Object[] newDimNames; String[] newDimNamesNames; @@ -295,8 +310,12 @@ final class CachedExtractVectorNode extends CachedVectorNode { originalDimNamesNames = null; newDimNamesNames = null; } else { + if (getNamesFromDimNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getNamesFromDimNamesNode = insert(GetNamesAttributeNode.create()); + } newDimNames = new Object[dimCount]; - originalDimNamesNames = originalDimNames.getNames(dimnamesNamesProfile); + originalDimNamesNames = getNamesFromDimNamesNode.getNames(originalDimNames); newDimNamesNames = originalDimNamesNames == null ? null : new String[dimCount]; } @@ -326,9 +345,20 @@ final class CachedExtractVectorNode extends CachedVectorNode { if (resultHasDimensions.profile(dimCount > 1)) { metadataApplied.enter(); - extractedTarget.setDimensions(newDimensions); + + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + + setDimNode.setDimensions(extractedTarget, newDimensions); if (newDimNames != null) { - extractedTarget.setDimNames(RDataFactory.createList(newDimNames, newDimNamesNames == null ? null : RDataFactory.createStringVector(newDimNamesNames, originalDimNames.isComplete()))); + if (setDimNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNamesNode = insert(SetDimNamesAttributeNode.create()); + } + setDimNamesNode.setDimNames(extractedTarget, + RDataFactory.createList(newDimNames, newDimNamesNames == null ? null : RDataFactory.createStringVector(newDimNamesNames, originalDimNames.isComplete()))); } } else if (newDimNames != null && originalDimNamesPRofile.profile(originalDimNames.getLength() > 0)) { RAbstractStringVector foundNames = translateDimNamesToNames(positionProfile, originalDimNames, extractedTargetLength, positions); @@ -445,7 +475,6 @@ final class CachedExtractVectorNode extends CachedVectorNode { if (container.getAttributes() == null) { // usual case container.initAttributes(RAttributesLayout.createNames(newNames1)); - container.setInternalNames(newNames1); } else { // from an RLanguage extraction that set a name RStringVector oldNames = (RStringVector) namesAttrGetter.execute(container.getAttributes()); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java index e951c3c9927316606423f3d313152a0bc252a6c4..2113155262a366925b79e1963772fda9a23f2806 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java @@ -40,6 +40,8 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.access.vector.CachedReplaceVectorNodeFactory.ValueProfileNodeGen; import com.oracle.truffle.r.nodes.access.vector.PositionsCheckNode.PositionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.nodes.binary.CastTypeNode; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.nodes.unary.CastListNodeGen; @@ -79,7 +81,6 @@ final class CachedReplaceVectorNode extends CachedVectorNode { private final VectorLengthProfile valueLengthProfile = VectorLengthProfile.create(); private final BranchProfile warningBranch = BranchProfile.create(); private final RAttributeProfiles vectorNamesProfile = RAttributeProfiles.create(); - private final RAttributeProfiles positionNamesProfile = RAttributeProfiles.create(); private final ConditionProfile valueIsNA = ConditionProfile.createBinaryProfile(); private final BranchProfile resizeProfile = BranchProfile.create(); private final BranchProfile sharedProfile = BranchProfile.create(); @@ -100,6 +101,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { @Child private CastNode castVectorNode; @Child private CachedReplaceVectorNode copyPositionNames; @Child private DeleteElementsNode deleteElementsNode; + @Child private SetNamesAttributeNode setNamesNode; CachedReplaceVectorNode(ElementAccessMode mode, RTypedValue vector, Object[] positions, RTypedValue value, boolean updatePositionNames, boolean recursive) { super(mode, vector, positions, recursive); @@ -438,6 +440,8 @@ final class CachedReplaceVectorNode extends CachedVectorNode { } private final ValueProfile positionCastProfile = ValueProfile.createClassProfile(); + @Child private GetNamesAttributeNode getNamesNode; + @Child private GetNamesAttributeNode getResultNamesNode; private void updateVectorWithPositionNames(RAbstractVector vector, Object[] positions) { Object position = positionCastProfile.profile(positions[0]); @@ -446,7 +450,11 @@ final class CachedReplaceVectorNode extends CachedVectorNode { if (position instanceof RMissing) { positionNames = null; } else { - positionNames = ((RAbstractVector) position).getNames(positionNamesProfile); + if (getNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getNamesNode = insert(GetNamesAttributeNode.create()); + } + positionNames = getNamesNode.getNames(position); } if (positionNames != null && positionNames.getLength() > 0) { updatePositionNames(vector, positionNames, positions); @@ -537,7 +545,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { RStringVector oldNames = vector.getNames(vectorNamesProfile); RVector<?> res = vector.copyResized(size, true).materialize(); if (vector instanceof RVector) { - res.copyAttributesFrom(positionNamesProfile, vector); + res.copyAttributesFrom(vector); } res.setDimensionsNoCheck(null); res.setDimNamesNoCheck(null); @@ -551,7 +559,11 @@ final class CachedReplaceVectorNode extends CachedVectorNode { private final ConditionProfile updateNamesProfile = ConditionProfile.createBinaryProfile(); private void updatePositionNames(RAbstractVector resultVector, RAbstractStringVector positionNames, Object[] positions) { - RTypedValue originalNames = resultVector.getNames(positionNamesProfile); + if (getResultNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getResultNamesNode = insert(GetNamesAttributeNode.create()); + } + RTypedValue originalNames = getResultNamesNode.getNames(resultVector); RTypedValue names = originalNames; if (names == null) { String[] emptyVector = new String[resultVector.getLength()]; @@ -565,7 +577,11 @@ final class CachedReplaceVectorNode extends CachedVectorNode { assert copyPositionNames.isSupported(names, positions, positionNames); RAbstractStringVector newNames = (RAbstractStringVector) copyPositionNames.apply(names, positions, positionNames); if (updateNamesProfile.profile(newNames != originalNames)) { - resultVector.setNames(newNames.materialize()); + if (setNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setNamesNode = insert(SetNamesAttributeNode.create()); + } + setNamesNode.setNames(resultVector, newNames.materialize()); } } @@ -580,7 +596,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { */ @CompilationFinal private int previousResultLength = PREVIOUS_RESULT_UNINITIALIZED; - private final RAttributeProfiles vectorNamesProfile = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); public RAbstractVector deleteElements(RAbstractVector vector, int vectorLength) { // we can speculate here that we delete always the same number of elements @@ -596,7 +612,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { } Object[] data = new Object[resultLength]; - RStringVector names = vector.getNames(vectorNamesProfile); + RStringVector names = getNamesNode.getNames(vector); boolean hasNames = names != null; String[] newNames = null; if (hasNames) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java index 2622dfc83ebb23d9920416d187264533e4ce06fe..ddd61957c7c5e09b7df428161eff08cd00e3ace4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java @@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.access.vector; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; @@ -60,6 +61,8 @@ abstract class CachedVectorNode extends RBaseNode { // if this is non-null, the node needs to throw the error whenever it is executed @CompilationFinal protected Runnable error; + @Child private GetDimAttributeNode getDimNode = GetDimAttributeNode.create(); + CachedVectorNode(ElementAccessMode mode, RTypedValue vector, Object[] positions, boolean recursive) { this.mode = mode; this.vectorType = vector.getRType(); @@ -151,14 +154,13 @@ abstract class CachedVectorNode extends RBaseNode { } } - @SuppressWarnings("static-method") protected final int[] loadVectorDimensions(RAbstractContainer vector) { // N.B. (stepan) this method used to be instance method and have special handling for // RDataFrame, which was removed and any test case, which would require this special // handling was not found (see TestBuiltin_extract_dataframe for tests used and further // explanation). This method and note will remain here for a while in case this behavior // crops up somewhere - return vector.getDimensions(); + return getDimNode.getDimensions(vector); } public ElementAccessMode getMode() { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCharacterLookupNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCharacterLookupNode.java index e437eef25787fc36433b988c3109a99dcd04ba6b..70e086e85722e0917405de4db7f6f82244cd5526 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCharacterLookupNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCharacterLookupNode.java @@ -24,9 +24,10 @@ package com.oracle.truffle.r.nodes.access.vector; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; @@ -38,12 +39,13 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; final class PositionCharacterLookupNode extends Node { private final ElementAccessMode mode; - private final RAttributeProfiles attributeProfiles = RAttributeProfiles.create(); private final int numDimensions; private final int dimensionIndex; private final BranchProfile emptyProfile = BranchProfile.create(); @Child private SearchFirstStringNode searchNode; + @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); PositionCharacterLookupNode(ElementAccessMode mode, int numDimensions, int dimensionIndex, boolean useNAForNotFound, boolean exact) { this.numDimensions = numDimensions; @@ -56,14 +58,14 @@ final class PositionCharacterLookupNode extends Node { // lookup names for single dimension case RAbstractIntVector result; if (numDimensions <= 1) { - RStringVector names = target.getNames(attributeProfiles); + RStringVector names = getNamesNode.getNames(target); if (names == null) { emptyProfile.enter(); names = RDataFactory.createEmptyStringVector(); } result = searchNode.apply(names, position, notFoundStartIndex, position.materialize()); } else { - RList dimNames = target.getDimNames(attributeProfiles); + RList dimNames = getDimNamesNode.getDimNames(target); if (dimNames != null) { Object dataAt = dimNames.getDataAt(dimensionIndex); if (dataAt != RNull.instance) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java index 5ec428e5feefa3341125319e430de02631d25336..9dffa7e5111fdd7459b8c5f77352b2daa85eed54 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckNode.java @@ -30,6 +30,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.access.vector.PositionCheckNodeFactory.Mat2indsubNodeGen; import com.oracle.truffle.r.nodes.access.vector.PositionsCheckNode.PositionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.control.RLengthNode; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; @@ -110,6 +111,8 @@ abstract class PositionCheckNode extends Node { } @Child private Mat2indsubNode mat2indsub; + @Child private GetDimAttributeNode getVectorDimsNode; + @Child private GetDimAttributeNode getVectorPosDimsNode; public final Object execute(PositionProfile profile, RAbstractContainer vector, int[] vectorDimensions, int vectorLength, Object position) { Object castPosition = castNode.execute(positionClass.cast(position)); @@ -124,12 +127,20 @@ abstract class PositionCheckNode extends Node { } if (mode.isSubset() && numDimensions == 1) { - int[] vectorDim = vector.getDimensions(); + if (getVectorDimsNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getVectorDimsNode = insert(GetDimAttributeNode.create()); + } + int[] vectorDim = getVectorDimsNode.getDimensions(vector); if (nullDimensionsProfile.profile(vectorDim != null) && vectorDim.length == 2) { if (vector instanceof RAbstractVector && ((RAbstractVector) vector).isArray()) { if (castPosition instanceof RAbstractVector) { + if (getVectorPosDimsNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getVectorPosDimsNode = insert(GetDimAttributeNode.create()); + } RAbstractVector vectorPosition = (RAbstractVector) castPosition; - int[] posDim = vectorPosition.getDimensions(); + int[] posDim = getVectorPosDimsNode.getDimensions(vectorPosition); if (posDim != null && posDim.length == 2 && posDim[1] == vectorDim.length) { if (castPosition instanceof RAbstractIntVector || castPosition instanceof RAbstractDoubleVector) { if (mat2indsub == null) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java index 43486bf76a3b037d6e5eaf5ab11043ceba180ece..6aa4578656348d2c47e4ea9f19d82418716a06af 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubscriptNode.java @@ -22,9 +22,11 @@ */ package com.oracle.truffle.r.nodes.access.vector; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.access.vector.PositionsCheckNode.PositionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RRuntime; @@ -61,7 +63,8 @@ abstract class PositionCheckSubscriptNode extends PositionCheckNode { } @Specialization - protected RAbstractVector doLogical(PositionProfile statistics, int dimSize, RAbstractLogicalVector position, int positionLength) { + protected RAbstractVector doLogical(PositionProfile statistics, int dimSize, RAbstractLogicalVector position, int positionLength, + @Cached("create()") GetNamesAttributeNode getNamesNode) { positionNACheck.enable(position); byte value = position.getDataAt(0); if (positionLength != 1) { @@ -77,11 +80,12 @@ abstract class PositionCheckSubscriptNode extends PositionCheckNode { } } - return doIntegerImpl(statistics, dimSize, positionNACheck.convertLogicalToInt(value), position); + return doIntegerImpl(statistics, dimSize, positionNACheck.convertLogicalToInt(value), position, getNamesNode); } @Specialization - protected RAbstractVector doInteger(PositionProfile profile, int dimSize, RAbstractIntVector position, int positionLength) { + protected RAbstractVector doInteger(PositionProfile profile, int dimSize, RAbstractIntVector position, int positionLength, + @Cached("create()") GetNamesAttributeNode getNamesNode) { if (positionLength != 1) { error.enter(); Message message; @@ -99,12 +103,12 @@ abstract class PositionCheckSubscriptNode extends PositionCheckNode { } assert positionLength == 1; positionNACheck.enable(position); - RAbstractVector result = doIntegerImpl(profile, dimSize, position.getDataAt(0), position); + RAbstractVector result = doIntegerImpl(profile, dimSize, position.getDataAt(0), position, getNamesNode); return result; } - private RAbstractVector doIntegerImpl(PositionProfile profile, int dimSize, int value, RAbstractVector originalVector) { + private RAbstractVector doIntegerImpl(PositionProfile profile, int dimSize, int value, RAbstractVector originalVector, GetNamesAttributeNode getNamesNode) { int result; if (greaterZero.profile(value > 0)) { // fast path @@ -121,7 +125,7 @@ abstract class PositionCheckSubscriptNode extends PositionCheckNode { } profile.selectedPositionsCount = 1; - RStringVector names = originalVector.getNames(attributeProfile); + RStringVector names = getNamesNode.getNames(originalVector); if (names != null) { return RDataFactory.createIntVector(new int[]{result}, !profile.containsNA, names); } else { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java index bc29b18d2a136d3ebb10508126a66727b3b771a0..99ad2b78cab1e9f3630e33e9a8c1345da56e6735 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCheckSubsetNode.java @@ -31,12 +31,13 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.access.vector.PositionsCheckNode.PositionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.runtime.NullProfile; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.Utils; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RInteger; import com.oracle.truffle.r.runtime.data.RMissing; @@ -128,8 +129,6 @@ abstract class PositionCheckSubsetNode extends PositionCheckNode { return position; } - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - @Specialization(/* contains = "doSequence" */) protected RAbstractVector doDouble(PositionProfile profile, int dimensionLength, RAbstractDoubleVector position, int positionLength, // @Cached("create()") BranchProfile seenZeroProfile, // @@ -137,13 +136,15 @@ abstract class PositionCheckSubsetNode extends PositionCheckNode { @Cached("create()") BranchProfile seenNegativeProfile, // @Cached("create()") BranchProfile seenOutOfBounds, // @Cached("create()") NullProfile hasNamesProfile, // - @Cached("createCountingProfile()") LoopConditionProfile lengthProfile) { + @Cached("createCountingProfile()") LoopConditionProfile lengthProfile, + @Cached("create()") GetNamesAttributeNode getNamesNode, + @Cached("create()") SetNamesAttributeNode setNamesNode) { RAbstractIntVector intPosition = RDataFactory.createIntVector(positionLength); intPosition.setComplete(position.isComplete()); // requires names preservation - RStringVector names = hasNamesProfile.profile(position.getNames(attrProfiles)); + RStringVector names = hasNamesProfile.profile(getNamesNode.getNames(position)); if (names != null) { - intPosition.setNames(names); + setNamesNode.setNames(intPosition, names); } Object convertedStore = intPosition.getInternalStore(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java index e1f30141ef54d7abc96f2dc4f0f5a5133c81f677..78faca3c4d6bfe0b214b34a5ee689421b0ccad47 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyAttributesNode.java @@ -28,8 +28,11 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -47,8 +50,9 @@ public abstract class CopyAttributesNode extends RBaseNode { private final boolean copyAllAttributes; - protected final RAttributeProfiles attrLeftProfiles = RAttributeProfiles.create(); - protected final RAttributeProfiles attrRightProfiles = RAttributeProfiles.create(); + @Child protected HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim(); + @Child protected GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); + @Child protected GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); protected CopyAttributesNode(boolean copyAllAttributes) { this.copyAllAttributes = copyAllAttributes; @@ -60,9 +64,9 @@ public abstract class CopyAttributesNode extends RBaseNode { public abstract RAbstractVector execute(RAbstractVector target, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength); - protected boolean containsMetadata(RAbstractVector vector, RAttributeProfiles attrProfiles) { - return vector instanceof RVector && vector.hasDimensions() || (copyAllAttributes && vector.getAttributes() != null) || vector.getDimNames(attrProfiles) != null || - vector.getNames(attrProfiles) != null; + protected boolean containsMetadata(RAbstractVector vector) { + return vector instanceof RVector && hasDimNode.execute(vector) || (copyAllAttributes && vector.getAttributes() != null) || getDimNamesNode.getDimNames(vector) != null || + getNamesNode.getNames(vector) != null; } private static int countNo; @@ -98,7 +102,7 @@ public abstract class CopyAttributesNode extends RBaseNode { } @SuppressWarnings("unused") - @Specialization(guards = {"!containsMetadata(left, attrLeftProfiles)", "!containsMetadata(right, attrRightProfiles)"}) + @Specialization(guards = {"!containsMetadata(left)", "!containsMetadata(right)"}) protected RAbstractVector copyNoMetadata(RAbstractVector target, RAbstractVector left, int leftLength, RAbstractVector right, int rightLength) { if (LOG) { log("copyAttributes: no"); @@ -107,7 +111,7 @@ public abstract class CopyAttributesNode extends RBaseNode { return target; } - @Specialization(guards = {"leftLength == rightLength", "containsMetadata(left, attrLeftProfiles) || containsMetadata(right, attrRightProfiles)"}) + @Specialization(guards = {"leftLength == rightLength", "containsMetadata(left) || containsMetadata(right)"}) protected RAbstractVector copySameLength(RAbstractVector target, RAbstractVector left, @SuppressWarnings("unused") int leftLength, RAbstractVector right, @SuppressWarnings("unused") int rightLength, @Cached("create()") CopyOfRegAttributesNode copyOfRegLeft, @@ -124,7 +128,10 @@ public abstract class CopyAttributesNode extends RBaseNode { @Cached("create()") BranchProfile noDimensions, @Cached("createBinaryProfile()") ConditionProfile hasNamesLeft, @Cached("createBinaryProfile()") ConditionProfile hasNamesRight, - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getLeftDimsNode, + @Cached("create()") GetDimAttributeNode getRightDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode) { if (LOG) { log("copyAttributes: =="); countEquals++; @@ -139,32 +146,28 @@ public abstract class CopyAttributesNode extends RBaseNode { } } - int[] newDimensions = left.getDimensions(); + int[] newDimensions = getLeftDimsNode.getDimensions(left); if (newDimensions == null) { - newDimensions = right.getDimensions(); + newDimensions = getRightDimsNode.getDimensions(right); if (newDimensions == null) { noDimensions.enter(); DynamicObject attributes = result.getAttributes(); if (hasAttributes.profile(attributes != null)) { removeDim.execute(attributes); removeDimNames.execute(attributes); - result.setInternalDimNames(null); } - result.setInternalDimensions(null); - RStringVector vecNames = left.getNames(attrLeftProfiles); + RStringVector vecNames = getNamesNode.getNames(left); if (hasNamesLeft.profile(vecNames != null)) { if (result != left) { putNames.execute(initAttributes.execute(result), vecNames); - result.setInternalNames(vecNames); } return result; } if (result != right) { - vecNames = right.getNames(attrRightProfiles); + vecNames = getNamesNode.getNames(right); if (hasNamesRight.profile(vecNames != null)) { putNames.execute(initAttributes.execute(result), vecNames); - result.setInternalNames(vecNames); } } return result; @@ -176,28 +179,26 @@ public abstract class CopyAttributesNode extends RBaseNode { } putDim.execute(initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); - result.setInternalDimensions(newDimensions); if (result != left) { - RList newDimNames = left.getDimNames(attrLeftProfiles); + RList newDimNames = getDimNamesNode.getDimNames(left); if (hasDimNames.profile(newDimNames != null)) { putDimNames.execute(result.getAttributes(), newDimNames); newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; - result.setInternalDimNames(newDimNames); return result; } if (result != right) { - newDimNames = right.getDimNames(attrRightProfiles); + newDimNames = getDimNamesNode.getDimNames(right); if (hasDimNames.profile(newDimNames != null)) { - result.setDimNames(newDimNames); + setDimNamesNode.setDimNames(result, newDimNames); } } } return result; } - @Specialization(guards = {"leftLength < rightLength", "containsMetadata(left, attrLeftProfiles) || containsMetadata(right, attrRightProfiles)"}) + @Specialization(guards = {"leftLength < rightLength", "containsMetadata(left) || containsMetadata(right)"}) protected RAbstractVector copyShorter(RAbstractVector target, RAbstractVector left, @SuppressWarnings("unused") int leftLength, RAbstractVector right, @SuppressWarnings("unused") int rightLength, // @Cached("create()") CopyOfRegAttributesNode copyOfReg, // @Cached("createBinaryProfile()") ConditionProfile rightNotResultProfile, // @@ -208,7 +209,10 @@ public abstract class CopyAttributesNode extends RBaseNode { @Cached("createDim()") SetFixedAttributeNode putDim, // @Cached("create()") InitAttributesNode initAttributes, // @Cached("createBinaryProfile()") ConditionProfile hasNames, // - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getLeftDimsNode, + @Cached("create()") GetDimAttributeNode getRightDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode) { if (LOG) { log("copyAttributes: <"); countSmaller++; @@ -219,18 +223,17 @@ public abstract class CopyAttributesNode extends RBaseNode { copyOfReg.execute(right, result); } - int[] newDimensions = left.getDimensions(); + int[] newDimensions = getLeftDimsNode.getDimensions(left); if (newDimensions == null || (newDimensions.length == 2 && newDimensions[0] == 1 && newDimensions[1] == 1)) { // 1-element matrix should be treated as 1-element vector - newDimensions = right.getDimensions(); + newDimensions = getRightDimsNode.getDimensions(right); if (newDimensions == null || (newDimensions.length == 2 && newDimensions[0] == 1 && newDimensions[1] == 1)) { // 1-element matrix should be treated as 1-element vector noDimensions.enter(); if (rightNotResult) { - RStringVector vecNames = right.getNames(attrRightProfiles); + RStringVector vecNames = getNamesNode.getNames(right); if (hasNames.profile(vecNames != null)) { putNames.execute(initAttributes.execute(result), vecNames); - result.setInternalNames(vecNames); } } return result; @@ -243,17 +246,16 @@ public abstract class CopyAttributesNode extends RBaseNode { RVector.verifyDimensions(result.getLength(), newDimensions, this); putDim.execute(initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); - result.setInternalDimensions(newDimensions); if (rightNotResult) { - RList newDimNames = right.getDimNames(attrRightProfiles); + RList newDimNames = getDimNamesNode.getDimNames(right); if (hasDimNames.profile(newDimNames != null)) { - result.setDimNames(newDimNames); + setDimNamesNode.setDimNames(result, newDimNames); } } return result; } - @Specialization(guards = {"leftLength > rightLength", "containsMetadata(left, attrLeftProfiles) || containsMetadata(right, attrRightProfiles)"}) + @Specialization(guards = {"leftLength > rightLength", "containsMetadata(left) || containsMetadata(right)"}) protected RAbstractVector copyLonger(RAbstractVector target, RAbstractVector left, @SuppressWarnings("unused") int leftLength, RAbstractVector right, @SuppressWarnings("unused") int rightLength, // @Cached("create()") CopyOfRegAttributesNode copyOfReg, // @Cached("create()") BranchProfile leftHasDimensions, // @@ -263,7 +265,10 @@ public abstract class CopyAttributesNode extends RBaseNode { @Cached("createDim()") SetFixedAttributeNode putDim, // @Cached("create()") InitAttributesNode initAttributes, // @Cached("createBinaryProfile()") ConditionProfile hasNames, // - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getLeftDimsNode, + @Cached("create()") GetDimAttributeNode getRightDimsNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode) { if (LOG) { log("copyAttributes: >"); countLarger++; @@ -272,16 +277,15 @@ public abstract class CopyAttributesNode extends RBaseNode { if (copyAllAttributes && result != left) { copyOfReg.execute(left, result); } - int[] newDimensions = left.getDimensions(); + int[] newDimensions = getLeftDimsNode.getDimensions(left); if (newDimensions == null) { - newDimensions = right.getDimensions(); + newDimensions = getRightDimsNode.getDimensions(right); if (newDimensions == null) { noDimensions.enter(); if (left != result) { - RStringVector vecNames = left.getNames(attrLeftProfiles); + RStringVector vecNames = getNamesNode.getNames(left); if (hasNames.profile(vecNames != null)) { putNames.execute(initAttributes.execute(result), vecNames); - result.setInternalNames(vecNames); } } return result; @@ -292,11 +296,10 @@ public abstract class CopyAttributesNode extends RBaseNode { leftHasDimensions.enter(); } putDim.execute(initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); - result.setInternalDimensions(newDimensions); if (left != result) { - RList newDimNames = left.getDimNames(attrLeftProfiles); + RList newDimNames = getDimNamesNode.getDimNames(left); if (hasDimNames.profile(newDimNames != null)) { - result.setDimNames(newDimNames); + setDimNamesNode.setDimNames(result, newDimNames); } } return result; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java index 7b6897b18b8ecdd0cc42a7c8aff3085a9b3c0a1e..d1422eebc32fb87cfcdb041b1b411aae9a1a2c35 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/CopyOfRegAttributesNode.java @@ -22,7 +22,6 @@ */ package com.oracle.truffle.r.nodes.attributes; -import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.object.Property; @@ -30,7 +29,6 @@ import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @@ -112,20 +110,14 @@ public abstract class CopyOfRegAttributesNode extends RBaseNode { protected void copyGeneric(RAbstractVector source, RVector<?> target) { DynamicObject orgAttributes = source.getAttributes(); if (orgAttributes != null) { - Object newRowNames = null; - Shape shape = orgAttributes.getShape(); for (Property p : shape.getProperties()) { String name = (String) p.getKey(); if (name != RRuntime.DIM_ATTR_KEY && name != RRuntime.DIMNAMES_ATTR_KEY && name != RRuntime.NAMES_ATTR_KEY) { Object val = p.get(orgAttributes, shape); target.initAttributes().define(name, val); - if (name == RRuntime.ROWNAMES_ATTR_KEY) { - newRowNames = val; - } } } - target.setInternalRowNames(newRowNames == null ? RNull.instance : newRowNames); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java index 0a28d002af32b82684ecf48e4f815256e363c859..858530667ff7dc7246205f084dd710e3e0b2d631 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributeNode.java @@ -22,16 +22,29 @@ */ package com.oracle.truffle.r.nodes.attributes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.object.Location; import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; +/** + * This node is responsible for retrieving a value from an arbitrary attribute. It accepts both + * {@link DynamicObject} and {@link RAttributable} instances as the first argument. If the first + * argument is {@link RAttributable} and its attributes are initialized, the recursive instance of + * this class is used to get the attribute value from the attributes. + */ public abstract class GetAttributeNode extends AttributeAccessNode { + @Child private GetAttributeNode recursive; + protected GetAttributeNode() { } @@ -39,7 +52,7 @@ public abstract class GetAttributeNode extends AttributeAccessNode { return GetAttributeNodeGen.create(); } - public abstract Object execute(DynamicObject attrs, String name); + public abstract Object execute(Object attrs, String name); @Specialization(limit = "3", // guards = {"cachedName.equals(name)", "shapeCheck(shape, attrs)"}, // @@ -58,4 +71,30 @@ public abstract class GetAttributeNode extends AttributeAccessNode { return attrs.get(name); } + @Specialization + protected Object getAttrFromAttributable(RAttributable x, String name, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); + } else { + attributes = xTypeProfile.profile(x).getAttributes(); + } + + if (attributes == null) { + attrNullProfile.enter(); + return null; + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create()); + } + + return recursive.execute(attributes, name); + } + } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java index 35b79c0d788b2e5f0ac8b45900b880778437d283..5b1b1963faebb517b9f6156dad202f17cfa632b8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetFixedAttributeNode.java @@ -22,38 +22,57 @@ */ package com.oracle.truffle.r.nodes.attributes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.object.Location; import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetClassAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; +/** + * This node is responsible for retrieving a value from the predefined (fixed) attribute. It accepts + * both {@link DynamicObject} and {@link RAttributable} instances as the first argument. If the + * first argument is {@link RAttributable} and its attributes are initialized, the recursive + * instance of this class is used to get the attribute value from the attributes. + */ public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode { + @Child private GetFixedAttributeNode recursive; + protected GetFixedAttributeNode(String name) { super(name); } public static GetFixedAttributeNode create(String name) { - return GetFixedAttributeNodeGen.create(name); + if (SpecialAttributesFunctions.IsSpecialAttributeNode.isSpecialAttribute(name)) { + return SpecialAttributesFunctions.createGetSpecialAttributeNode(name); + } else { + return GetFixedAttributeNodeGen.create(name); + } } public static GetFixedAttributeNode createNames() { - return GetFixedAttributeNode.create(RRuntime.NAMES_ATTR_KEY); + return GetNamesAttributeNode.create(); } - public static GetFixedAttributeNode createDim() { - return GetFixedAttributeNode.create(RRuntime.DIM_ATTR_KEY); + public static GetDimAttributeNode createDim() { + return GetDimAttributeNode.create(); } - public static GetFixedAttributeNode createClass() { - return GetFixedAttributeNode.create(RRuntime.CLASS_ATTR_KEY); + public static GetClassAttributeNode createClass() { + return GetClassAttributeNode.create(); } - public abstract Object execute(DynamicObject attrs); + public abstract Object execute(Object attr); protected boolean hasProperty(Shape shape) { return shape.hasProperty(name); @@ -74,4 +93,31 @@ public abstract class GetFixedAttributeNode extends FixedAttributeAccessNode { protected Object getAttrFallback(DynamicObject attrs) { return attrs.get(name); } + + @Specialization + protected Object getAttrFromAttributable(RAttributable x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); + } else { + attributes = xTypeProfile.profile(x).getAttributes(); + } + + if (attributes == null) { + attrNullProfile.enter(); + return null; + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create(name)); + } + + return recursive.execute(attributes); + } + } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/HasFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/HasFixedAttributeNode.java new file mode 100644 index 0000000000000000000000000000000000000000..fdff7b2c0f7c3418a2847f03020d043e0473e74f --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/HasFixedAttributeNode.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016, 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.nodes.attributes; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.object.DynamicObject; +import com.oracle.truffle.api.object.Location; +import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; + +/** + * This node is responsible for determining the existence of the predefined (fixed) attribute. It + * accepts both {@link DynamicObject} and {@link RAttributable} instances as the first argument. If + * the first argument is {@link RAttributable} and its attributes are initialized, the recursive + * instance of this class is used to determine the existence from the attributes. + */ +public abstract class HasFixedAttributeNode extends FixedAttributeAccessNode { + + @Child private HasFixedAttributeNode recursive; + + protected HasFixedAttributeNode(String name) { + super(name); + } + + public static HasFixedAttributeNode create(String name) { + return HasFixedAttributeNodeGen.create(name); + } + + public static HasFixedAttributeNode createDim() { + return HasFixedAttributeNodeGen.create(RRuntime.DIM_ATTR_KEY); + } + + public abstract boolean execute(Object attr); + + protected boolean hasProperty(Shape shape) { + return shape.hasProperty(name); + } + + @Specialization(limit = "3", // + guards = {"shapeCheck(shape, attrs)"}, // + assumptions = {"shape.getValidAssumption()"}) + @SuppressWarnings("unused") + protected boolean hasAttrCached(DynamicObject attrs, + @Cached("lookupShape(attrs)") Shape shape, + @Cached("lookupLocation(shape, name)") Location location) { + return location != null; + } + + @Specialization(contains = "hasAttrCached") + @TruffleBoundary + protected boolean hasAttrFallback(DynamicObject attrs) { + return attrs.containsKey(name); + } + + @Specialization + protected boolean hasAttrFromAttributable(RAttributable x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); + } else { + attributes = xTypeProfile.profile(x).getAttributes(); + } + + if (attributes == null) { + attrNullProfile.enter(); + return false; + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create(name)); + } + + return recursive.execute(attributes); + } + +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java index 5d41dae1dbc3861f24152719abd03b86707050e0..b9c737057e670e1ed1d3938bbedabf588c48c737 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/RemoveFixedAttributeNode.java @@ -26,10 +26,17 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; -import com.oracle.truffle.api.object.Property; +import com.oracle.truffle.api.object.Location; import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.profiles.BranchProfile; -import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.RemoveClassAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.RemoveDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.RemoveDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.RemoveNamesAttributeNode; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; public abstract class RemoveFixedAttributeNode extends FixedAttributeAccessNode { @@ -38,42 +45,64 @@ public abstract class RemoveFixedAttributeNode extends FixedAttributeAccessNode } public static RemoveFixedAttributeNode create(String name) { - return RemoveFixedAttributeNodeGen.create(name); + if (SpecialAttributesFunctions.IsSpecialAttributeNode.isSpecialAttribute(name)) { + return SpecialAttributesFunctions.createRemoveSpecialAttributeNode(name); + } else { + return RemoveFixedAttributeNodeGen.create(name); + } } public static RemoveFixedAttributeNode createNames() { - return RemoveFixedAttributeNode.create(RRuntime.NAMES_ATTR_KEY); + return RemoveNamesAttributeNode.create(); } public static RemoveFixedAttributeNode createDim() { - return RemoveFixedAttributeNode.create(RRuntime.DIM_ATTR_KEY); + return RemoveDimAttributeNode.create(); } public static RemoveFixedAttributeNode createDimNames() { - return RemoveFixedAttributeNode.create(RRuntime.DIMNAMES_ATTR_KEY); + return RemoveDimNamesAttributeNode.create(); } public static RemoveFixedAttributeNode createClass() { - return RemoveFixedAttributeNode.create(RRuntime.CLASS_ATTR_KEY); + return RemoveClassAttributeNode.create(); } - public abstract void execute(DynamicObject attrs); + public abstract void execute(Object attrs); @Specialization(limit = "3", // - guards = {"shapeCheck(shape, attrs)"}, // + guards = {"shapeCheck(shape, attrs)", "location == null"}, // assumptions = {"shape.getValidAssumption()"}) - protected void removeAttrCached(DynamicObject attrs, - @Cached("lookupShape(attrs)") Shape shape, - @Cached("lookupProperty(shape, name)") Property property) { - if (property != null) { - Shape newShape = attrs.getShape().removeProperty(property); - attrs.setShapeAndResize(shape, newShape); - } + protected void removeNonExistantAttr(@SuppressWarnings("unused") DynamicObject attrs, + @SuppressWarnings("unused") @Cached("lookupShape(attrs)") Shape shape, + @SuppressWarnings("unused") @Cached("lookupLocation(shape, name)") Location location) { + // do nothing } - @Specialization(contains = "removeAttrCached") + @Specialization @TruffleBoundary protected void removeAttrFallback(DynamicObject attrs) { attrs.delete(this.name); } + + @Specialization + protected void removeAttrFromAttributable(RAttributable x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); + } else { + attributes = xTypeProfile.profile(x).getAttributes(); + } + + if (attributes == null) { + attrNullProfile.enter(); + return; + } + + removeAttrFallback(attributes); + } + } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java index b669fa8b59fdef3af23f82a6455888e6c742d45e..aecd9e3c0fc95b1f2f6cdb3c2bb80e3c5ff862da 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetAttributeNode.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.nodes.attributes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; @@ -30,10 +31,27 @@ import com.oracle.truffle.api.object.FinalLocationException; import com.oracle.truffle.api.object.IncompatibleLocationException; import com.oracle.truffle.api.object.Location; import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; +/** + * This node is responsible for setting a value to an arbitrary attribute. It accepts both + * {@link DynamicObject} and {@link RAttributable} instances as the first argument. If the first + * argument is {@link RAttributable} and the attribute is a special one (i.e. names, dims, dimnames, + * rownames), a corresponding node defined in the {@link SpecialAttributesFunctions} class is + * created and the processing is delegated to it. If the first argument is {@link RAttributable} and + * the attribute is not a special one, it is made sure that the attributes in the first argument are + * initialized. Then the recursive instance of this class is used to set the attribute value to the + * attributes. + */ public abstract class SetAttributeNode extends AttributeAccessNode { + @Child SetAttributeNode recursive; + protected SetAttributeNode() { } @@ -41,7 +59,7 @@ public abstract class SetAttributeNode extends AttributeAccessNode { return SetAttributeNodeGen.create(); } - public abstract void execute(DynamicObject attrs, String name, Object value); + public abstract void execute(Object attrs, String name, Object value); @Specialization(limit = "3", // guards = { @@ -100,6 +118,57 @@ public abstract class SetAttributeNode extends AttributeAccessNode { receiver.define(name, value); } + protected static SpecialAttributesFunctions.SetSpecialAttributeNode createSpecAttrNode(String name) { + return SpecialAttributesFunctions.createSetSpecialAttributeNode(name); + } + + @Specialization(limit = "3", // + guards = { + "isSpecialAttributeNode.execute(name)", + "cachedName.equals(name)" + }) + @SuppressWarnings("unused") + protected void setSpecAttrInAttributable(RAttributable x, String name, Object value, + @Cached("create()") SpecialAttributesFunctions.IsSpecialAttributeNode isSpecialAttributeNode, + @Cached("name") String cachedName, + @Cached("createSpecAttrNode(cachedName)") SpecialAttributesFunctions.SetSpecialAttributeNode setSpecAttrNode) { + setSpecAttrNode.execute(x, value); + } + + @Specialization(contains = "setSpecAttrInAttributable", // + guards = "isSpecialAttributeNode.execute(name)") + @SuppressWarnings("unused") + protected void setSpecAttrInAttributable(RAttributable x, String name, Object value, + @Cached("create()") SpecialAttributesFunctions.IsSpecialAttributeNode isSpecialAttributeNode, + @Cached("create()") SpecialAttributesFunctions.GenericSpecialAttributeNode genericSpecialAttrNode) { + genericSpecialAttrNode.execute(x, name, value); + } + + @Specialization + protected void setAttrInAttributable(RAttributable x, String name, Object value, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); + } else { + attributes = xTypeProfile.profile(x).getAttributes(); + } + + if (attributes == null) { + attrNullProfile.enter(); + attributes = x.initAttributes(); + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create()); + } + + recursive.execute(attributes, name, value); + } + /** * Try to find the given property in the shape. Also returns null when the value cannot be store * into the location. diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java index 3f6b8b6bebd444f5cc1fd567b60b71d6cda3b159..fd79ede63e6e57041d801f7eecbd7355ca1f50e6 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SetFixedAttributeNode.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.nodes.attributes; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; @@ -30,36 +31,58 @@ import com.oracle.truffle.api.object.FinalLocationException; import com.oracle.truffle.api.object.IncompatibleLocationException; import com.oracle.truffle.api.object.Location; import com.oracle.truffle.api.object.Shape; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetSpecialAttributeNode; import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeStorage; +/** + * This node is responsible for setting a value to the predefined (fixed) attribute. It accepts both + * {@link DynamicObject} and {@link RAttributable} instances as the first argument. If the first + * argument is {@link RAttributable} and the attribute is a special one (i.e. names, dims, dimnames, + * rownames), a corresponding node defined in the {@link SpecialAttributesFunctions} class is + * created and the processing is delegated to it. If the first argument is {@link RAttributable} and + * the attribute is not a special one, it is made sure that the attributes in the first argument are + * initialized. Then the recursive instance of this class is used to set the attribute value to the + * attributes. + */ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode { + @Child private SetFixedAttributeNode recursive; + @Child private SetSpecialAttributeNode setSpecialAttrNode; + protected SetFixedAttributeNode(String name) { super(name); } public static SetFixedAttributeNode create(String name) { - return SetFixedAttributeNodeGen.create(name); + if (SpecialAttributesFunctions.IsSpecialAttributeNode.isSpecialAttribute(name)) { + return SpecialAttributesFunctions.createSetSpecialAttributeNode(name); + } else { + return SetFixedAttributeNodeGen.create(name); + } } public static SetFixedAttributeNode createNames() { - return SetFixedAttributeNode.create(RRuntime.NAMES_ATTR_KEY); + return SpecialAttributesFunctions.SetNamesAttributeNode.create(); } public static SetFixedAttributeNode createDim() { - return SetFixedAttributeNode.create(RRuntime.DIM_ATTR_KEY); + return SpecialAttributesFunctions.SetDimAttributeNode.create(); } public static SetFixedAttributeNode createDimNames() { - return SetFixedAttributeNode.create(RRuntime.DIMNAMES_ATTR_KEY); + return SpecialAttributesFunctions.SetDimNamesAttributeNode.create(); } public static SetFixedAttributeNode createClass() { - return SetFixedAttributeNode.create(RRuntime.CLASS_ATTR_KEY); + return SpecialAttributesFunctions.SetClassAttributeNode.create(); } - public abstract void execute(DynamicObject attrs, Object value); + public abstract void execute(Object attr, Object value); @Specialization(limit = "3", // guards = {"shapeCheck(shape, attrs)", "location != null"}, // @@ -74,10 +97,54 @@ public abstract class SetFixedAttributeNode extends FixedAttributeAccessNode { } } + @Specialization(limit = "3", // + guards = {"shapeCheck(oldShape, attrs)", "oldLocation == null"}, // + assumptions = {"oldShape.getValidAssumption()", "newShape.getValidAssumption()"}) + protected static void setNewAttrCached(DynamicObject attrs, Object value, + @Cached("lookupShape(attrs)") Shape oldShape, + @SuppressWarnings("unused") @Cached("lookupLocation(oldShape, name)") Location oldLocation, + @Cached("defineProperty(oldShape, name, value)") Shape newShape, + @Cached("lookupLocation(newShape, name)") Location newLocation) { + try { + newLocation.set(attrs, value, oldShape, newShape); + } catch (IncompatibleLocationException ex) { + RInternalError.reportError(ex); + } + } + + protected static Shape defineProperty(Shape oldShape, Object name, Object value) { + return oldShape.defineProperty(name, value, 0); + } + @Specialization(contains = "setAttrCached") @TruffleBoundary protected void setFallback(DynamicObject attrs, Object value) { attrs.define(name, value); } + @Specialization + protected void setAttrInAttributable(RAttributable x, Object value, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + DynamicObject attributes; + if (attrStorageProfile.profile(x instanceof RAttributeStorage)) { + attributes = ((RAttributeStorage) x).getAttributes(); + } else { + attributes = xTypeProfile.profile(x).getAttributes(); + } + + if (attributes == null) { + attrNullProfile.enter(); + attributes = x.initAttributes(); + } + + if (recursive == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursive = insert(create(name)); + } + + recursive.execute(attributes, value); + } + } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java new file mode 100644 index 0000000000000000000000000000000000000000..e596ca4f5b734b8f433cb47a4b912ab49de67e0a --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java @@ -0,0 +1,1045 @@ +/* + * Copyright (c) 2016, 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.nodes.attributes; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.object.DynamicObject; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.LoopConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctionsFactory.GetDimAttributeNodeGen; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributeProfiles; +import com.oracle.truffle.r.runtime.data.RAttributesLayout; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RInteger; +import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.data.RScalarVector; +import com.oracle.truffle.r.runtime.data.RSequence; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.nodes.RBaseNode; + +/** + * This class defines a number of nodes used to handle the special attributes, such as names, dims, + * dimnames and rownames. + */ +public final class SpecialAttributesFunctions { + + /** + * A node used in guards, for example, to determine whether an attribute is a special one. + */ + public static final class IsSpecialAttributeNode extends RBaseNode { + + private final BranchProfile namesProfile = BranchProfile.create(); + private final BranchProfile dimProfile = BranchProfile.create(); + private final BranchProfile dimNamesProfile = BranchProfile.create(); + private final BranchProfile rowNamesProfile = BranchProfile.create(); + private final BranchProfile classProfile = BranchProfile.create(); + + public static IsSpecialAttributeNode create() { + return new IsSpecialAttributeNode(); + } + + /** + * The fast-path method. + */ + public boolean execute(String name) { + assert name.intern() == name; + if (name == RRuntime.NAMES_ATTR_KEY) { + namesProfile.enter(); + return true; + } else if (name == RRuntime.DIM_ATTR_KEY) { + dimProfile.enter(); + return true; + } else if (name == RRuntime.DIMNAMES_ATTR_KEY) { + dimNamesProfile.enter(); + return true; + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + rowNamesProfile.enter(); + return true; + } else if (name == RRuntime.CLASS_ATTR_KEY) { + classProfile.enter(); + return false; + } + return false; + } + + /** + * The slow-path method. + */ + public static boolean isSpecialAttribute(String name) { + assert name.intern() == name; + return name == RRuntime.NAMES_ATTR_KEY || + name == RRuntime.DIM_ATTR_KEY || + name == RRuntime.DIMNAMES_ATTR_KEY || + name == RRuntime.ROWNAMES_ATTR_KEY || + name == RRuntime.CLASS_ATTR_KEY; + + } + } + + /** + * A node for setting a value to any special attribute. + */ + public static final class GenericSpecialAttributeNode extends RBaseNode { + + private final BranchProfile namesProfile = BranchProfile.create(); + private final BranchProfile dimProfile = BranchProfile.create(); + private final BranchProfile dimNamesProfile = BranchProfile.create(); + private final BranchProfile rowNamesProfile = BranchProfile.create(); + + @Child private SetNamesAttributeNode namesAttrNode; + @Child private SetDimAttributeNode dimAttrNode; + @Child private SetDimNamesAttributeNode dimNamesAttrNode; + @Child private SetRowNamesAttributeNode rowNamesAttrNode; + + public static GenericSpecialAttributeNode create() { + return new GenericSpecialAttributeNode(); + } + + public void execute(RAttributable x, String name, Object value) { + assert name.intern() == name; + if (name == RRuntime.NAMES_ATTR_KEY) { + namesProfile.enter(); + if (namesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + namesAttrNode = insert(SetNamesAttributeNode.create()); + } + namesAttrNode.execute(x, value); + } else if (name == RRuntime.DIM_ATTR_KEY) { + dimProfile.enter(); + if (dimAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + dimAttrNode = insert(SetDimAttributeNode.create()); + } + dimAttrNode.execute(x, value); + } else if (name == RRuntime.DIMNAMES_ATTR_KEY) { + dimNamesProfile.enter(); + if (dimNamesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + dimNamesAttrNode = insert(SetDimNamesAttributeNode.create()); + } + dimNamesAttrNode.execute(x, value); + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + rowNamesProfile.enter(); + if (rowNamesAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + rowNamesAttrNode = insert(SetRowNamesAttributeNode.create()); + } + rowNamesAttrNode.execute(x, value); + } else if (name == RRuntime.CLASS_ATTR_KEY) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw RInternalError.unimplemented("The \"class\" attribute should be set using a separate method"); + } else { + CompilerDirectives.transferToInterpreterAndInvalidate(); + throw RInternalError.shouldNotReachHere(); + } + } + } + + /** + * A factory method for creating a node setting the given special attribute. + * + * @param name the special attribute name + * @return the node + */ + public static SetSpecialAttributeNode createSetSpecialAttributeNode(String name) { + assert name.intern() == name; + if (name == RRuntime.NAMES_ATTR_KEY) { + return SetNamesAttributeNode.create(); + } else if (name == RRuntime.DIM_ATTR_KEY) { + return SetDimAttributeNode.create(); + } else if (name == RRuntime.DIMNAMES_ATTR_KEY) { + return SetDimNamesAttributeNode.create(); + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + return SetRowNamesAttributeNode.create(); + } else if (name == RRuntime.CLASS_ATTR_KEY) { + return SetClassAttributeNode.create(); + } else { + throw RInternalError.shouldNotReachHere(); + } + } + + /** + * A factory method for creating a node removing the given special attribute. + * + * @param name the special attribute name + * @return the node + */ + public static RemoveSpecialAttributeNode createRemoveSpecialAttributeNode(String name) { + assert name.intern() == name; + if (name == RRuntime.NAMES_ATTR_KEY) { + return RemoveNamesAttributeNode.create(); + } else if (name == RRuntime.DIM_ATTR_KEY) { + return RemoveDimAttributeNode.create(); + } else if (name == RRuntime.DIMNAMES_ATTR_KEY) { + return RemoveDimNamesAttributeNode.create(); + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + return RemoveRowNamesAttributeNode.create(); + } else if (name == RRuntime.CLASS_ATTR_KEY) { + return RemoveClassAttributeNode.create(); + } else { + throw RInternalError.shouldNotReachHere(); + } + } + + /** + * A factory method for creating a node retrieving the given special attribute. + * + * @param name the special attribute name + * @return the node + */ + public static GetFixedAttributeNode createGetSpecialAttributeNode(String name) { + assert name.intern() == name; + if (name == RRuntime.NAMES_ATTR_KEY) { + return GetNamesAttributeNode.create(); + } else if (name == RRuntime.DIM_ATTR_KEY) { + return GetDimAttributeNode.create(); + } else if (name == RRuntime.DIMNAMES_ATTR_KEY) { + return GetDimNamesAttributeNode.create(); + } else if (name == RRuntime.ROWNAMES_ATTR_KEY) { + return GetRowNamesAttributeNode.create(); + } else if (name == RRuntime.CLASS_ATTR_KEY) { + return GetClassAttributeNode.create(); + } else { + throw RInternalError.shouldNotReachHere(); + } + } + + /** + * The base class for the nodes setting values to special attributes. + */ + public abstract static class SetSpecialAttributeNode extends SetFixedAttributeNode { + + protected SetSpecialAttributeNode(String name) { + super(name); + } + + public abstract void execute(RAttributable x, Object attrValue); + + } + + /** + * The base class for the nodes removing values from special attributes. + */ + public abstract static class RemoveSpecialAttributeNode extends RemoveFixedAttributeNode { + + protected RemoveSpecialAttributeNode(String name) { + super(name); + } + + public abstract void execute(RAttributable x); + + @Specialization(insertBefore = "removeAttrFromAttributable") + protected void removeAttrFromVector(RVector<?> x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("create()") BranchProfile attrEmptyProfile) { + DynamicObject attributes = x.getAttributes(); + if (attributes == null) { + attrNullProfile.enter(); + return; + } + + attributes.delete(name); + + if (attributes.isEmpty()) { + attrEmptyProfile.enter(); + x.initAttributes(null); + } + } + + } + + public abstract static class SetNamesAttributeNode extends SetSpecialAttributeNode { + + private final ConditionProfile nullDimNamesProfile = ConditionProfile.createBinaryProfile(); + + protected SetNamesAttributeNode() { + super(RRuntime.NAMES_ATTR_KEY); + } + + public static SetNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetNamesAttributeNodeGen.create(); + } + + public void setNames(RAbstractContainer x, RStringVector newNames) { + if (nullDimNamesProfile.profile(newNames == null)) { + execute(x, RNull.instance); + } else { + execute(x, newNames); + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void resetDimNames(RAbstractContainer x, @SuppressWarnings("unused") RNull rnull, + @Cached("create()") RemoveNamesAttributeNode removeNamesAttrNode) { + removeNamesAttrNode.execute(x); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setNamesInVector(RVector<?> x, RStringVector newNames, + @Cached("create()") BranchProfile namesTooLongProfile, + @Cached("createBinaryProfile()") ConditionProfile useDimNamesProfile, + @Cached("create()") GetDimAttributeNode getDimNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + RVector<?> xProfiled = xTypeProfile.profile(x); + if (newNames.getLength() > xProfiled.getLength()) { + namesTooLongProfile.enter(); + throw RError.error(this, RError.Message.ATTRIBUTE_VECTOR_SAME_LENGTH, RRuntime.NAMES_ATTR_KEY, newNames.getLength(), xProfiled.getLength()); + } + + int[] dimensions = getDimNode.getDimensions(x); + if (useDimNamesProfile.profile(dimensions != null && dimensions.length == 1)) { + // for one dimensional array, "names" is really "dimnames[[1]]" (see R + // documentation for "names" function) + RList newDimNames = RDataFactory.createList(new Object[]{newNames}); + newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; + setDimNamesNode.setDimNames(xProfiled, newDimNames); + } else { + assert newNames != xProfiled; + DynamicObject attrs = xProfiled.getAttributes(); + if (attrs == null) { + attrNullProfile.enter(); + attrs = RAttributesLayout.createNames(newNames); + xProfiled.initAttributes(attrs); + return; + } + + super.setAttrInAttributable(xProfiled, newNames, attrNullProfile, attrStorageProfile, xTypeProfile); + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setNamesInContainer(RAbstractContainer x, RStringVector newNames, + @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setNames(newNames); + } + } + + public abstract static class RemoveNamesAttributeNode extends RemoveSpecialAttributeNode { + + protected RemoveNamesAttributeNode() { + super(RRuntime.NAMES_ATTR_KEY); + } + + @Override + @Specialization + protected void removeAttrFallback(DynamicObject attrs) { + super.removeAttrFallback(attrs); + } + + public static RemoveNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.RemoveNamesAttributeNodeGen.create(); + } + } + + public abstract static class GetNamesAttributeNode extends GetFixedAttributeNode { + + protected GetNamesAttributeNode() { + super(RRuntime.NAMES_ATTR_KEY); + } + + public static GetNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.GetNamesAttributeNodeGen.create(); + } + + public final RStringVector getNames(Object x) { + return (RStringVector) execute(x); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorNames(RVector<?> x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("create()") BranchProfile namesNullProfile, + @Cached("create()") BranchProfile dimNamesAvlProfile, + @Cached("create()") GetDimNamesAttributeNode getDimNames) { + RStringVector names = (RStringVector) super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); + if (names == null) { + namesNullProfile.enter(); + RList dimNames = getDimNames.getDimNames(x); + if (dimNames != null && dimNames.getLength() == 1) { + dimNamesAvlProfile.enter(); + return dimNames.getDataAt(0); + } + return null; + } + + return names; + + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorNames(RAbstractContainer x, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("create()") RAttributeProfiles attrProfiles) { + return xTypeProfile.profile(x).getNames(attrProfiles); + } + } + + public abstract static class SetDimAttributeNode extends SetSpecialAttributeNode { + + private final ConditionProfile nullDimProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile naDimProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile negativeDimProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile dimNotMatchLengthProfile = ConditionProfile.createBinaryProfile(); + private final ValueProfile contArgClassProfile = ValueProfile.createClassProfile(); + private final ValueProfile dimArgClassProfile = ValueProfile.createClassProfile(); + private final LoopConditionProfile verifyLoopProfile = LoopConditionProfile.createCountingProfile(); + + protected SetDimAttributeNode() { + super(RRuntime.DIM_ATTR_KEY); + } + + public static SetDimAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetDimAttributeNodeGen.create(); + } + + public void setDimensions(RAbstractContainer x, int[] dims) { + if (nullDimProfile.profile(dims == null)) { + execute(x, RNull.instance); + } else { + execute(x, RDataFactory.createIntVector(dims, RDataFactory.COMPLETE_VECTOR)); + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void resetDims(RAbstractContainer x, @SuppressWarnings("unused") RNull rnull, + @Cached("create()") RemoveDimAttributeNode removeDimAttrNode, + @Cached("create()") SetDimNamesAttributeNode setDimNamesNode) { + removeDimAttrNode.execute(x); + setDimNamesNode.setDimNames(x, null); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setOneDimInVector(RVector<?> x, int dim, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + RAbstractContainer xProfiled = contArgClassProfile.profile(x); + + int[] dims = new int[]{dim}; + verifyOneDimensions(xProfiled.getLength(), dim); + + RIntVector dimVec = RDataFactory.createIntVector(dims, RDataFactory.COMPLETE_VECTOR); + + DynamicObject attrs = xProfiled.getAttributes(); + if (attrs == null) { + attrNullProfile.enter(); + attrs = RAttributesLayout.createDim(dimVec); + xProfiled.initAttributes(attrs); + return; + } + + super.setAttrInAttributable(x, dimVec, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setDimsInVector(RVector<?> x, RAbstractIntVector dims, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + RAbstractContainer xProfiled = contArgClassProfile.profile(x); + verifyDimensions(xProfiled.getLength(), dims); + + DynamicObject attrs = xProfiled.getAttributes(); + if (attrs == null) { + attrNullProfile.enter(); + attrs = RAttributesLayout.createDim(dims); + xProfiled.initAttributes(attrs); + return; + } + + super.setAttrInAttributable(x, dims, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setDimsInContainerFallback(RAbstractContainer x, RAbstractIntVector dims, + @Cached("create()") SetDimAttributeNode setDimNode) { + int[] dimsArr = dims.materialize().getDataCopy(); + setDimNode.setDimensions(x, dimsArr); + } + + private void verifyOneDimensions(int vectorLength, int dim) { + int length = dim; + if (naDimProfile.profile(RRuntime.isNA(dim))) { + throw RError.error(this, RError.Message.DIMS_CONTAIN_NA); + } else if (negativeDimProfile.profile(dim < 0)) { + throw RError.error(this, RError.Message.DIMS_CONTAIN_NEGATIVE_VALUES); + } + if (dimNotMatchLengthProfile.profile(length != vectorLength && vectorLength > 0)) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, RError.Message.DIMS_DONT_MATCH_LENGTH, length, vectorLength); + } + } + + public void verifyDimensions(int vectorLength, RAbstractIntVector dims) { + RAbstractIntVector dimsProfiled = dimArgClassProfile.profile(dims); + int dimLen = dims.getLength(); + verifyLoopProfile.profileCounted(dimLen); + int length = 1; + for (int i = 0; i < dimLen; i++) { + int dim = dimsProfiled.getDataAt(i); + if (naDimProfile.profile(RRuntime.isNA(dim))) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, RError.Message.DIMS_CONTAIN_NA); + } else if (negativeDimProfile.profile(dim < 0)) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, RError.Message.DIMS_CONTAIN_NEGATIVE_VALUES); + } + length *= dim; + } + if (length != vectorLength && vectorLength > 0) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(this, RError.Message.DIMS_DONT_MATCH_LENGTH, length, vectorLength); + } + } + + } + + public abstract static class RemoveDimAttributeNode extends RemoveSpecialAttributeNode { + + protected RemoveDimAttributeNode() { + super(RRuntime.DIM_ATTR_KEY); + } + + public static RemoveDimAttributeNode create() { + return SpecialAttributesFunctionsFactory.RemoveDimAttributeNodeGen.create(); + } + + @Override + @Specialization + protected void removeAttrFallback(DynamicObject attrs) { + super.removeAttrFallback(attrs); + } + + } + + public abstract static class GetDimAttributeNode extends GetFixedAttributeNode { + + private final BranchProfile isLanguageProfile = BranchProfile.create(); + private final BranchProfile isPairListProfile = BranchProfile.create(); + private final ConditionProfile nullDimsProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile nonEmptyDimsProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile twoDimsOrMoreProfile = ConditionProfile.createBinaryProfile(); + private final ConditionProfile isContainerProfile = ConditionProfile.createBinaryProfile(); + + protected GetDimAttributeNode() { + super(RRuntime.DIM_ATTR_KEY); + } + + public static GetDimAttributeNode create() { + return GetDimAttributeNodeGen.create(); + } + + public final int[] getDimensions(Object x) { + // Let's handle the following two types directly so as to avoid wrapping and unwrapping + // RIntVector. The getContainerDims spec would be invoked otherwise. + if (x instanceof RLanguage) { + isLanguageProfile.enter(); + return ((RLanguage) x).getDimensions(); + } + if (x instanceof RPairList) { + isPairListProfile.enter(); + return ((RPairList) x).getDimensions(); + } + RIntVector dims = (RIntVector) execute(x); + return nullDimsProfile.profile(dims == null) ? null : dims.getInternalStore(); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getScalarVectorDims(@SuppressWarnings("unused") RScalarVector x) { + return null; + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getScalarVectorDims(@SuppressWarnings("unused") RSequence x) { + return null; + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorDims(RAbstractVector x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + return super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getContainerDims(RAbstractContainer x, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("createBinaryProfile()") ConditionProfile nullResultProfile) { + int[] res = xTypeProfile.profile(x).getDimensions(); + return nullResultProfile.profile(res == null) ? null : RDataFactory.createIntVector(res, true); + } + + public int nrows(Object x) { + if (isContainerProfile.profile(x instanceof RAbstractContainer)) { + RAbstractContainer xa = (RAbstractContainer) x; + int[] dims = getDimensions(xa); + if (nonEmptyDimsProfile.profile(dims != null && dims.length > 0)) { + return dims[0]; + } else { + return xa.getLength(); + } + } else { + throw RError.error(RError.SHOW_CALLER2, RError.Message.OBJECT_NOT_MATRIX); + } + } + + public int ncols(Object x) { + if (isContainerProfile.profile(x instanceof RAbstractContainer)) { + RAbstractContainer xa = (RAbstractContainer) x; + int[] dims = getDimensions(xa); + if (nonEmptyDimsProfile.profile(dims != null && dims.length > 0)) { + if (twoDimsOrMoreProfile.profile(dims.length >= 2)) { + return dims[1]; + } else { + return 1; + } + } else { + return 1; + } + } else { + throw RError.error(RError.SHOW_CALLER2, RError.Message.OBJECT_NOT_MATRIX); + } + } + + } + + public abstract static class SetDimNamesAttributeNode extends SetSpecialAttributeNode { + + private final ConditionProfile nullDimNamesProfile = ConditionProfile.createBinaryProfile(); + + protected SetDimNamesAttributeNode() { + super(RRuntime.DIMNAMES_ATTR_KEY); + } + + public static SetDimNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetDimNamesAttributeNodeGen.create(); + } + + public void setDimNames(RAbstractContainer x, RList dimNames) { + if (nullDimNamesProfile.profile(dimNames == null)) { + execute(x, RNull.instance); + } else { + execute(x, dimNames); + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void resetDimNames(RAbstractContainer x, @SuppressWarnings("unused") RNull rnull, + @Cached("create()") RemoveDimNamesAttributeNode removeDimNamesAttrNode) { + removeDimNamesAttrNode.execute(x); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setDimNamesInVector(RVector<?> x, RList newDimNames, + @Cached("create()") GetDimAttributeNode getDimNode, + @Cached("create()") BranchProfile nullDimsProfile, + @Cached("create()") BranchProfile dimsLengthProfile, + @Cached("createCountingProfile()") LoopConditionProfile loopProfile, + @Cached("create()") BranchProfile invalidDimProfile, + @Cached("create()") BranchProfile nullDimProfile, + @Cached("create()") BranchProfile resizeDimsProfile, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + int[] dimensions = getDimNode.getDimensions(x); + if (dimensions == null) { + nullDimsProfile.enter(); + throw RError.error(this, RError.Message.DIMNAMES_NONARRAY); + } + int newDimNamesLength = newDimNames.getLength(); + if (newDimNamesLength > dimensions.length) { + dimsLengthProfile.enter(); + throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_DIMS, newDimNamesLength, + dimensions.length); + } + + loopProfile.profileCounted(newDimNamesLength); + for (int i = 0; loopProfile.inject(i < newDimNamesLength); i++) { + Object dimObject = newDimNames.getDataAt(i); + + if ((dimObject instanceof String && dimensions[i] != 1) || + (dimObject instanceof RStringVector && !isValidDimLength((RStringVector) dimObject, dimensions[i]))) { + invalidDimProfile.enter(); + throw RError.error(this, RError.Message.DIMNAMES_DONT_MATCH_EXTENT, i + 1); + } + + if (dimObject == null || (dimObject instanceof RStringVector && ((RStringVector) dimObject).getLength() == 0)) { + nullDimProfile.enter(); + newDimNames.updateDataAt(i, RNull.instance, null); + } + } + + RList resDimNames = newDimNames; + if (newDimNamesLength < dimensions.length) { + resizeDimsProfile.enter(); + // resize the array and fill the missing entries with NULL-s + resDimNames = (RList) resDimNames.copyResized(dimensions.length, true); + resDimNames.setAttributes(newDimNames); + for (int i = newDimNamesLength; i < dimensions.length; i++) { + resDimNames.updateDataAt(i, RNull.instance, null); + } + } + resDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; + + if (x.getAttributes() == null) { + attrNullProfile.enter(); + x.initAttributes(RAttributesLayout.createDimNames(resDimNames)); + return; + } + + super.setAttrInAttributable(x, resDimNames, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + private static boolean isValidDimLength(RStringVector x, int expectedDim) { + int len = x.getLength(); + return len == 0 || len == expectedDim; + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setDimNamesInContainer(RAbstractContainer x, RList dimNames, @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setDimNames(dimNames); + } + + } + + public abstract static class RemoveDimNamesAttributeNode extends RemoveSpecialAttributeNode { + + protected RemoveDimNamesAttributeNode() { + super(RRuntime.DIMNAMES_ATTR_KEY); + } + + @Override + @Specialization + protected void removeAttrFallback(DynamicObject attrs) { + super.removeAttrFallback(attrs); + } + + public static RemoveDimNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.RemoveDimNamesAttributeNodeGen.create(); + } + } + + public abstract static class GetDimNamesAttributeNode extends GetFixedAttributeNode { + + protected GetDimNamesAttributeNode() { + super(RRuntime.DIMNAMES_ATTR_KEY); + } + + public static GetDimNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.GetDimNamesAttributeNodeGen.create(); + } + + public final RList getDimNames(Object x) { + return (RList) execute(x); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorDimNames(RVector<?> x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + return super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorDimNames(RAbstractContainer x, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("create()") RAttributeProfiles attrProfiles) { + return xTypeProfile.profile(x).getDimNames(attrProfiles); + } + + } + + public abstract static class SetRowNamesAttributeNode extends SetSpecialAttributeNode { + + private final ConditionProfile nullRowNamesProfile = ConditionProfile.createBinaryProfile(); + + protected SetRowNamesAttributeNode() { + super(RRuntime.ROWNAMES_ATTR_KEY); + } + + public static SetRowNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetRowNamesAttributeNodeGen.create(); + } + + public void setRowNames(RAbstractContainer x, RAbstractVector rowNames) { + if (nullRowNamesProfile.profile(rowNames == null)) { + execute(x, RNull.instance); + } else { + execute(x, rowNames); + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void resetRowNames(RVector<?> x, @SuppressWarnings("unused") RNull rnull, + @Cached("create()") RemoveRowNamesAttributeNode removeRowNamesAttrNode) { + removeRowNamesAttrNode.execute(x); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setRowNamesInVector(RVector<?> x, RAbstractVector newRowNames, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + if (x.getAttributes() == null) { + attrNullProfile.enter(); + x.initAttributes(RAttributesLayout.createRowNames(newRowNames)); + return; + } + setAttrInAttributable(x, newRowNames, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void setRowNamesInContainer(RAbstractContainer x, RAbstractVector rowNames, @Cached("createClassProfile()") ValueProfile contClassProfile) { + RAbstractContainer xProfiled = contClassProfile.profile(x); + xProfiled.setRowNames(rowNames); + } + + } + + public abstract static class RemoveRowNamesAttributeNode extends RemoveSpecialAttributeNode { + + protected RemoveRowNamesAttributeNode() { + super(RRuntime.DIMNAMES_ATTR_KEY); + } + + public static RemoveRowNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.RemoveRowNamesAttributeNodeGen.create(); + } + + @Override + @Specialization + protected void removeAttrFallback(DynamicObject attrs) { + super.removeAttrFallback(attrs); + } + } + + public abstract static class GetRowNamesAttributeNode extends GetFixedAttributeNode { + + protected GetRowNamesAttributeNode() { + super(RRuntime.ROWNAMES_ATTR_KEY); + } + + public static GetRowNamesAttributeNode create() { + return SpecialAttributesFunctionsFactory.GetRowNamesAttributeNodeGen.create(); + } + + public Object getRowNames(RAbstractContainer x) { + return execute(x); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getScalarVectorRowNames(@SuppressWarnings("unused") RScalarVector x) { + return RNull.instance; + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getScalarVectorRowNames(@SuppressWarnings("unused") RSequence x) { + return RNull.class; + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorRowNames(RAbstractVector x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("createBinaryProfile()") ConditionProfile nullRowNamesProfile) { + Object res = super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); + return nullRowNamesProfile.profile(res == null) ? RNull.instance : res; + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorRowNames(RAbstractContainer x, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("create()") RAttributeProfiles attrProfiles) { + return xTypeProfile.profile(x).getRowNames(attrProfiles); + } + + } + + public abstract static class SetClassAttributeNode extends SetSpecialAttributeNode { + + protected SetClassAttributeNode() { + super(RRuntime.CLASS_ATTR_KEY); + } + + public static SetClassAttributeNode create() { + return SpecialAttributesFunctionsFactory.SetClassAttributeNodeGen.create(); + } + + public void reset(RAttributable x) { + execute(x, RNull.instance); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected <T> void handleVectorNullClass(RVector<T> vector, @SuppressWarnings("unused") RNull classAttr, + @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode, + @Cached("createBinaryProfile()") ConditionProfile initAttrProfile, + @Cached("create()") BranchProfile nullAttrProfile, + @Cached("createBinaryProfile()") ConditionProfile nullClassProfile, + @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + handleVector(vector, null, removeClassAttrNode, initAttrProfile, nullAttrProfile, nullClassProfile, notNullClassProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected <T> void handleVector(RVector<T> vector, RStringVector classAttr, + @Cached("createClass()") RemoveFixedAttributeNode removeClassAttrNode, + @Cached("createBinaryProfile()") ConditionProfile initAttrProfile, + @Cached("create()") BranchProfile nullAttrProfile, + @Cached("createBinaryProfile()") ConditionProfile nullClassProfile, + @Cached("createBinaryProfile()") ConditionProfile notNullClassProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + + DynamicObject attrs = vector.getAttributes(); + boolean initializeAttrs = initAttrProfile.profile(attrs == null && classAttr != null && classAttr.getLength() != 0); + if (initializeAttrs) { + nullAttrProfile.enter(); + attrs = RAttributesLayout.createClass(classAttr); + vector.initAttributes(attrs); + } + if (nullClassProfile.profile(attrs != null && (classAttr == null || classAttr.getLength() == 0))) { + removeAttributeMapping(vector, attrs, removeClassAttrNode); + } else if (notNullClassProfile.profile(classAttr != null && classAttr.getLength() != 0)) { + for (int i = 0; i < classAttr.getLength(); i++) { + String attr = classAttr.getDataAt(i); + if (RRuntime.CLASS_FACTOR.equals(attr)) { + // TODO: Isn't this redundant when the same operation is done after the + // loop? + if (!initializeAttrs) { + super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile); + } + // setClassAttrNode.execute(attrs, classAttr); + if (vector.getElementClass() != RInteger.class) { + // N.B. there used to be conversion to integer under certain + // circumstances. + // However, it seems that it was dead/obsolete code so it was removed. + // Notes: this can only happen if the class is set by hand to some + // non-integral vector, i.e. attr(doubles, 'class') <- 'factor'. GnuR + // also + // does not update the 'class' attr with other, possibly + // valid classes when it reaches this error. + throw RError.error(RError.SHOW_CALLER2, RError.Message.ADDING_INVALID_CLASS, "factor"); + } + } + } + + if (!initializeAttrs) { + super.setAttrInAttributable(vector, classAttr, nullAttrProfile, attrStorageProfile, xTypeProfile); + } + } + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void handleAttributable(RAttributable x, @SuppressWarnings("unused") RNull classAttr) { + x.setClassAttr(null); + } + + @Specialization(insertBefore = "setAttrInAttributable") + protected void handleAttributable(RAttributable x, RStringVector classAttr) { + x.setClassAttr(classAttr); + } + + private static void removeAttributeMapping(RAttributable x, DynamicObject attrs, RemoveFixedAttributeNode removeClassAttrNode) { + if (attrs != null) { + removeClassAttrNode.execute(attrs); + if (attrs.isEmpty()) { + x.initAttributes(null); + } + } + } + + } + + public abstract static class RemoveClassAttributeNode extends RemoveSpecialAttributeNode { + + protected RemoveClassAttributeNode() { + super(RRuntime.CLASS_ATTR_KEY); + } + + public static RemoveClassAttributeNode create() { + return SpecialAttributesFunctionsFactory.RemoveClassAttributeNodeGen.create(); + } + + @Override + @Specialization + protected void removeAttrFallback(DynamicObject attrs) { + super.removeAttrFallback(attrs); + } + + } + + public abstract static class GetClassAttributeNode extends GetFixedAttributeNode { + + protected GetClassAttributeNode() { + super(RRuntime.CLASS_ATTR_KEY); + } + + public static GetClassAttributeNode create() { + return SpecialAttributesFunctionsFactory.GetClassAttributeNodeGen.create(); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorClass(RVector<?> x, + @Cached("create()") BranchProfile attrNullProfile, + @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, + @Cached("createClassProfile()") ValueProfile xTypeProfile) { + return super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); + } + + @Specialization(insertBefore = "getAttrFromAttributable") + protected Object getVectorClass(RAbstractContainer x, + @Cached("createClassProfile()") ValueProfile xTypeProfile, + @Cached("create()") RAttributeProfiles attrProfiles) { + return xTypeProfile.profile(x).getClassAttr(attrProfiles); + } + + } + +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java index 16ae928994e5501164d6c035d71ee336d91c4284..c31cd1da74a52ee0c2792e5dba579aafb2a7be56 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/UnaryCopyAttributesNode.java @@ -26,8 +26,10 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -47,7 +49,9 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { protected final boolean copyAllAttributes; - protected final RAttributeProfiles attrSourceProfiles = RAttributeProfiles.create(); + @Child protected HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim(); + @Child protected GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); + @Child protected GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); protected UnaryCopyAttributesNode(boolean copyAllAttributes) { this.copyAllAttributes = copyAllAttributes; @@ -59,13 +63,13 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { public abstract RAbstractVector execute(RAbstractVector target, RAbstractVector left); - protected boolean containsMetadata(RAbstractVector vector, RAttributeProfiles attrProfiles) { - return vector instanceof RVector && vector.hasDimensions() || (copyAllAttributes && vector.getAttributes() != null) || vector.getNames(attrProfiles) != null || - vector.getDimNames(attrProfiles) != null; + protected boolean containsMetadata(RAbstractVector vector) { + return vector instanceof RVector && hasDimNode.execute(vector) || (copyAllAttributes && vector.getAttributes() != null) || getNamesNode.getNames(vector) != null || + getDimNamesNode.getDimNames(vector) != null; } @SuppressWarnings("unused") - @Specialization(guards = "!containsMetadata(source, attrSourceProfiles)") + @Specialization(guards = "!containsMetadata(source)") protected RAbstractVector copyNoMetadata(RAbstractVector target, RAbstractVector source) { return target; } @@ -76,7 +80,7 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { return target; } - @Specialization(guards = {"!copyAllAttributes || target != source", "containsMetadata(source, attrSourceProfiles)"}) + @Specialization(guards = {"!copyAllAttributes || target != source", "containsMetadata(source)"}) protected RAbstractVector copySameLength(RAbstractVector target, RAbstractVector source, // @Cached("create()") CopyOfRegAttributesNode copyOfReg, // @Cached("createDim()") RemoveFixedAttributeNode removeDim, // @@ -87,40 +91,36 @@ public abstract class UnaryCopyAttributesNode extends RBaseNode { @Cached("createDimNames()") SetFixedAttributeNode putDimNames, // @Cached("createBinaryProfile()") ConditionProfile noDimensions, // @Cached("createBinaryProfile()") ConditionProfile hasNamesSource, // - @Cached("createBinaryProfile()") ConditionProfile hasDimNames) { + @Cached("createBinaryProfile()") ConditionProfile hasDimNames, + @Cached("create()") GetDimAttributeNode getDimsNode) { RVector<?> result = target.materialize(); if (copyAllAttributes) { copyOfReg.execute(source, result); } - int[] newDimensions = source.getDimensions(); + int[] newDimensions = getDimsNode.getDimensions(source); if (noDimensions.profile(newDimensions == null)) { DynamicObject attributes = result.getAttributes(); if (attributes != null) { removeDim.execute(attributes); removeDimNames.execute(attributes); - result.setInternalDimNames(null); } - result.setInternalDimensions(null); - RStringVector vecNames = source.getNames(attrSourceProfiles); + RStringVector vecNames = getNamesNode.getNames(source); if (hasNamesSource.profile(vecNames != null)) { putNames.execute(initAttributes.execute(result), vecNames); - result.setInternalNames(vecNames); return result; } return result; } putDim.execute(initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); - result.setInternalDimensions(newDimensions); - RList newDimNames = source.getDimNames(attrSourceProfiles); + RList newDimNames = getDimNamesNode.getDimNames(source); if (hasDimNames.profile(newDimNames != null)) { putDimNames.execute(result.getAttributes(), newDimNames); newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; - result.setInternalDimNames(newDimNames); return result; } return result; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RExternalBuiltinNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RExternalBuiltinNode.java index d535ea92bc02fa1d2c8c9afeac907fcbb0c97534..7d7294095202e7f5ee95e789e947a12832a2e9c4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RExternalBuiltinNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/RExternalBuiltinNode.java @@ -38,7 +38,6 @@ import com.oracle.truffle.r.nodes.unary.CastToVectorNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RTypes; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -74,7 +73,6 @@ public abstract class RExternalBuiltinNode extends RBaseNode { @Child private CastToVectorNode castVector; @Children private final CastNode[] argumentCasts; - protected final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); protected final BranchProfile errorProfile = BranchProfile.create(); public RExternalBuiltinNode() { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/CollectGenericArgumentsNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/CollectGenericArgumentsNode.java index 9c9ffffb388f84c5819887d65e8721dc07ed7048..3acb958ef9701fc0229a07e17fafe3d69a94c9f3 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/CollectGenericArgumentsNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/CollectGenericArgumentsNode.java @@ -45,6 +45,8 @@ import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.nodes.RBaseNode; +// transcribed from /src/library/methods/src/methods_list_dispatch.c (R_dispatch_generic function) + /* * Used to collect arguments of the generic function for S4 method dispatch. Modeled after {@link CollectArgumentsNode}. */ diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/DispatchGeneric.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/DispatchGeneric.java index 733648fbaea8f503607b1b735e07275a000315ab..ea03075c9a6fe23cf2c4ba80440876339b94c4c8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/DispatchGeneric.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/DispatchGeneric.java @@ -30,6 +30,7 @@ import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RBaseNode; +// transcribed from /src/library/methods/src/methods_list_dispatch.c (R_dispatch_generic function) public abstract class DispatchGeneric extends RBaseNode { public abstract Object executeObject(VirtualFrame frame, REnvironment mtable, RStringVector classes, RFunction fdef, String fname); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetPrimName.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetPrimName.java index 1e450fd0305ce0255954e667cf2816950dfce822..84229b57ef0d5313013909ec59ce9d622496bc0c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetPrimName.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetPrimName.java @@ -17,7 +17,7 @@ import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.data.RFunction; -// transcribed from src/library/methods/utils.c +// transcribed from src/library/methods/src/utils.c public abstract class GetPrimName extends RExternalBuiltinNode.Arg1 { @Specialization(guards = "f.isBuiltin()") diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetS4DataSlot.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetS4DataSlot.java index 3b7dc03d2d930df8d37386cc0fd332e510823f56..8dc96975ebadf202edc586ede634c365eb3475df 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetS4DataSlot.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/GetS4DataSlot.java @@ -19,6 +19,7 @@ import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; import com.oracle.truffle.r.nodes.attributes.RemoveFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNode; import com.oracle.truffle.r.nodes.unary.TypeofNode; import com.oracle.truffle.r.nodes.unary.TypeofNodeGen; @@ -28,7 +29,6 @@ import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RS4Object; import com.oracle.truffle.r.runtime.data.RShareable; -import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RTypedValue; // transcribed from src/main/attrib.c @@ -42,6 +42,7 @@ public abstract class GetS4DataSlot extends Node { @Child private GetFixedAttributeNode dotDataAttrAccess; @Child private GetFixedAttributeNode dotXDataAttrAccess; @Child private TypeofNode typeOf = TypeofNodeGen.create(); + @Child private SetClassAttributeNode setClassAttrNode; private final BranchProfile shareable = BranchProfile.create(); @@ -72,6 +73,12 @@ public abstract class GetS4DataSlot extends Node { shareable.enter(); obj = (RAttributable) ((RShareable) obj).copy(); } + + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + if (s3Class != null) { if (s3ClassAttrRemove == null) { assert castToVector == null; @@ -81,9 +88,9 @@ public abstract class GetS4DataSlot extends Node { } s3ClassAttrRemove.execute(obj.initAttributes()); - obj = obj.setClassAttr((RStringVector) castToVector.execute(s3Class)); + setClassAttrNode.execute(obj, castToVector.execute(s3Class)); } else { - obj = obj.setClassAttr(null); + setClassAttrNode.reset(obj); } obj.unsetS4(); if (type == RType.S4Object) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java index 71ae3eef2b2593978101505c6d1e786b381b4e53..4be981a574ff0db8c4c8bfb736f99a60452b1748 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/LoadMethod.java @@ -39,6 +39,7 @@ import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; +// transcribed from /src/library/methods/src/methods_list_dispatch.c (R_loadMethod function) abstract class LoadMethod extends RBaseNode { private static final ArgumentsSignature SIGNATURE = ArgumentsSignature.get("method", "fname", "envir"); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/NewObject.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/NewObject.java index b02d46ea7312a68103d2a0488edad5a155c4bc29..025378e9745a42cfa016d1f36041b5e97e88b84b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/NewObject.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/objects/NewObject.java @@ -12,10 +12,12 @@ */ package com.oracle.truffle.r.nodes.objects; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.access.AccessSlotNode; import com.oracle.truffle.r.nodes.access.AccessSlotNodeGen; import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastNode; @@ -26,7 +28,6 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RStringVector; // transcribed from src/main/objects.c public abstract class NewObject extends RExternalBuiltinNode.Arg1 { @@ -36,6 +37,7 @@ public abstract class NewObject extends RExternalBuiltinNode.Arg1 { @Child private AccessSlotNode accessSlotPrototypeName = AccessSlotNodeGen.create(true, null, null); @Child private DuplicateNode duplicate = DuplicateNodeGen.create(true); @Child private GetFixedAttributeNode pckgAttrAccess = GetFixedAttributeNode.create(RRuntime.PCKG_ATTR_KEY); + @Child private SetClassAttributeNode setClassAttrNode; @Child private CastNode castStringScalar; @Child private CastNode castLogicalScalar; @@ -62,7 +64,13 @@ public abstract class NewObject extends RExternalBuiltinNode.Arg1 { RAttributable valueAttr = (RAttributable) value; if (valueAttr instanceof RS4Object || (e instanceof RAttributable && ((RAttributable) e).getAttributes() != null && pckgAttrAccess.execute(((RAttributable) e).getAttributes()) != null)) { - valueAttr = valueAttr.setClassAttr((RStringVector) e); + + if (setClassAttrNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setClassAttrNode = insert(SetClassAttributeNode.create()); + } + + setClassAttrNode.execute(valueAttr, e); valueAttr.setS4(); } return value; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java index bb33f7c87e692865c85bb056adbd3b6cb32987b2..a720fcbc354a2185eb2dfda7551dedf61aa7cce1 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/BinaryMapNode.java @@ -29,6 +29,8 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; import com.oracle.truffle.r.nodes.attributes.CopyAttributesNode; import com.oracle.truffle.r.nodes.attributes.CopyAttributesNodeGen; +import com.oracle.truffle.r.nodes.attributes.HasFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; import com.oracle.truffle.r.nodes.primitive.BinaryMapNodeFactory.VectorMapBinaryInternalNodeGen; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RError; @@ -63,6 +65,10 @@ public final class BinaryMapNode extends RBaseNode { @Child private VectorMapBinaryInternalNode vectorNode; @Child private BinaryMapFunctionNode function; @Child private CopyAttributesNode copyAttributes; + @Child private GetDimAttributeNode getLeftDimNode = GetDimAttributeNode.create(); + @Child private GetDimAttributeNode getRightDimNode = GetDimAttributeNode.create(); + @Child private HasFixedAttributeNode hasLeftDimNode = HasFixedAttributeNode.createDim(); + @Child private HasFixedAttributeNode hasRightDimNode = HasFixedAttributeNode.createDim(); // profiles private final Class<? extends RAbstractVector> leftClass; @@ -142,9 +148,9 @@ public final class BinaryMapNode extends RBaseNode { } } - private static boolean differentDimensions(RAbstractVector left, RAbstractVector right) { - int[] leftDimensions = left.getDimensions(); - int[] rightDimensions = right.getDimensions(); + private boolean differentDimensions(RAbstractVector left, RAbstractVector right) { + int[] leftDimensions = getLeftDimNode.getDimensions(left); + int[] rightDimensions = getRightDimNode.getDimensions(right); int leftLength = leftDimensions.length; int rightLength = rightDimensions.length; if (leftLength != rightLength) { @@ -227,7 +233,7 @@ public final class BinaryMapNode extends RBaseNode { } private Object applyVectorized(RAbstractVector left, RAbstractVector leftCast, int leftLength, RAbstractVector right, RAbstractVector rightCast, int rightLength) { - if (mayContainMetadata && (dimensionsProfile.profile(left.hasDimensions() && right.hasDimensions()))) { + if (mayContainMetadata && (dimensionsProfile.profile(hasLeftDimNode.execute(left) && hasRightDimNode.execute(right)))) { if (differentDimensions(left, right)) { CompilerDirectives.transferToInterpreter(); throw RError.error(this, RError.Message.NON_CONFORMABLE_ARRAYS); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java index bb49fe7f101598457022b1d5854d3b0901d8de16..e0b9d614cae4b1e9d6a0fff7d469b945ce70213c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/primitive/UnaryMapNode.java @@ -22,12 +22,18 @@ */ package com.oracle.truffle.r.nodes.primitive; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.LoopConditionProfile; +import com.oracle.truffle.r.nodes.attributes.HasFixedAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimAttributeNode; import com.oracle.truffle.r.nodes.primitive.UnaryMapNodeFactory.MapUnaryVectorInternalNodeGen; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RInternalError; @@ -50,6 +56,9 @@ public final class UnaryMapNode extends RBaseNode { @Child private UnaryMapFunctionNode scalarNode; @Child private MapUnaryVectorInternalNode vectorNode; + @Child private GetDimAttributeNode getDimNode; + @Child private SetDimAttributeNode setDimNode; + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); // profiles private final Class<? extends RAbstractVector> operandClass; @@ -170,6 +179,19 @@ public final class UnaryMapNode extends RBaseNode { if (containsMetadata(operand) && operand != target) { hasAttributesProfile.enter(); result = result.materialize(); + + if (getDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimNode = insert(GetDimAttributeNode.create()); + } + + if (setDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNode = insert(SetDimAttributeNode.create()); + } + + setDimNode.setDimensions(result, getDimNode.getDimensions(operand)); + copyAttributesInternal((RVector<?>) result, operand); } return result; @@ -178,16 +200,18 @@ public final class UnaryMapNode extends RBaseNode { private final ConditionProfile hasDimensionsProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile hasNamesProfile = ConditionProfile.createBinaryProfile(); + @Child private HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim(); + @Child private GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); + private boolean containsMetadata(RAbstractVector vector) { return vector instanceof RVector && - (hasDimensionsProfile.profile(vector.hasDimensions()) || vector.getAttributes() != null || hasNamesProfile.profile(vector.getNames(attrProfiles) != null) || - vector.getDimNames(attrProfiles) != null); + (hasDimensionsProfile.profile(hasDimNode.execute(vector)) || vector.getAttributes() != null || hasNamesProfile.profile(getNamesNode.getNames(vector) != null) || + getDimNamesNode.getDimNames(vector) != null); } @TruffleBoundary private void copyAttributesInternal(RVector<?> result, RAbstractVector attributeSource) { result.copyRegAttributesFrom(attributeSource); - result.setDimensions(attributeSource.getDimensions()); result.copyNamesFrom(attrProfiles, attributeSource); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java index e9b89627095e03cd06329d0eee7a0082a7ea2ab5..860e6461885dec3ed983f115cc5e3e2b81ca9abe 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java @@ -22,17 +22,21 @@ */ package com.oracle.truffle.r.nodes.unary; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetDimNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.runtime.NullProfile; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RTypedValue; @@ -46,7 +50,10 @@ public abstract class CastBaseNode extends CastNode { private final ConditionProfile hasDimNamesProfile = ConditionProfile.createBinaryProfile(); private final NullProfile hasDimensionsProfile = NullProfile.create(); private final NullProfile hasNamesProfile = NullProfile.create(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); + @Child private GetDimAttributeNode getDimNode; + @Child private SetDimNamesAttributeNode setDimNamesNode; + @Child private GetDimNamesAttributeNode getDimNamesNode; private final boolean preserveNames; private final boolean preserveDimensions; @@ -56,13 +63,16 @@ public abstract class CastBaseNode extends CastNode { this.preserveNames = preserveNames; this.preserveDimensions = preserveDimensions; this.preserveAttributes = preserveAttributes; + if (preserveDimensions) { + getDimNamesNode = GetDimNamesAttributeNode.create(); + } } public boolean preserveNames() { return preserveNames; } - public boolean preserveDimensions() { + public final boolean preserveDimensions() { return preserveDimensions; } @@ -79,7 +89,11 @@ public abstract class CastBaseNode extends CastNode { protected int[] getPreservedDimensions(RAbstractContainer operand) { if (preserveDimensions()) { - return hasDimensionsProfile.profile(operand.getDimensions()); + if (getDimNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getDimNode = insert(GetDimAttributeNode.create()); + } + return hasDimensionsProfile.profile(getDimNode.getDimensions(operand)); } else { return null; } @@ -87,7 +101,7 @@ public abstract class CastBaseNode extends CastNode { protected RStringVector getPreservedNames(RAbstractContainer operand) { if (preserveNames()) { - return hasNamesProfile.profile(operand.getNames(attrProfiles)); + return hasNamesProfile.profile(getNamesNode.getNames(operand)); } else { return null; } @@ -95,9 +109,13 @@ public abstract class CastBaseNode extends CastNode { protected void preserveDimensionNames(RAbstractContainer operand, RVector<?> ret) { if (preserveDimensions()) { - RList dimNames = operand.getDimNames(attrProfiles); + RList dimNames = getDimNamesNode.getDimNames(operand); if (hasDimNamesProfile.profile(dimNames != null)) { - ret.setDimNames((RList) dimNames.copy()); + if (setDimNamesNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + setDimNamesNode = insert(SetDimNamesAttributeNode.create()); + } + setDimNamesNode.setDimNames(ret, (RList) dimNames.copy()); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java index 60f816057c901fbe6863f0c7cc5460d7c54c4cf1..1178f3762ee7743577fe611918c14242c8f9592d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java @@ -22,10 +22,11 @@ */ package com.oracle.truffle.r.nodes.unary; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; @@ -36,8 +37,6 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; public abstract class CastExpressionNode extends CastBaseNode { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - public abstract Object executeExpression(Object o); protected CastExpressionNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { @@ -85,7 +84,8 @@ public abstract class CastExpressionNode extends CastBaseNode { } @Specialization - protected RExpression doAbstractContainer(RAbstractContainer obj) { + protected RExpression doAbstractContainer(RAbstractContainer obj, + @Cached("create()") GetNamesAttributeNode getNamesNode) { int len = obj.getLength(); Object[] data = new Object[len]; for (int i = 0; i < len; i++) { @@ -94,7 +94,7 @@ public abstract class CastExpressionNode extends CastBaseNode { if (obj instanceof RList) { RList list = (RList) obj; // TODO other attributes - return RDataFactory.createExpression(data, list.getNames(attrProfiles)); + return RDataFactory.createExpression(data, getNamesNode.getNames(list)); } else { return RDataFactory.createExpression(data); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java index 9d53e8623b97de1e410dd4ae8b0619e7fae4f224..14ea322f9f4f9e49447990349ea395b987d9f135 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java @@ -22,11 +22,14 @@ */ package com.oracle.truffle.r.nodes.unary; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; +import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.context.RContext; @@ -38,13 +41,14 @@ import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RStringVector; 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; public abstract class CastListNode extends CastBaseNode { + @Child private SetClassAttributeNode setClassAttrNode; + public abstract RList executeList(Object o); protected CastListNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { @@ -86,16 +90,24 @@ public abstract class CastListNode extends CastBaseNode { } @Specialization - protected RList doLanguage(RLanguage operand, @Cached("create()") ArrayAttributeNode attrAttrAccess) { + protected RList doLanguage(RLanguage operand, + @Cached("create()") ArrayAttributeNode attrAttrAccess, + @Cached("create()") SetAttributeNode setAttrNode) { RList result = RContext.getRRuntimeASTAccess().asList(operand); DynamicObject operandAttrs = operand.getAttributes(); if (operandAttrs != null) { // result may already have names, so can't call RVector.copyAttributesFrom for (RAttributesLayout.RAttribute attr : attrAttrAccess.execute(operandAttrs)) { if (attr.getName().equals(RRuntime.CLASS_ATTR_KEY)) { - result.setClassAttr((RStringVector) attr.getValue()); + + if (setClassAttrNode == null) { + setClassAttrNode = insert(SetClassAttributeNode.create()); + CompilerDirectives.transferToInterpreterAndInvalidate(); + } + + setClassAttrNode.execute(result, attr.getValue()); } else { - result.setAttr(attr.getName(), attr.getValue()); + setAttrNode.execute(result, attr.getName(), attr.getValue()); } } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java index 084a71a45255baab8f18c0adbdc809882a9ba399..f6c14178278012d0d955b85109470e9667a1a166 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java @@ -207,6 +207,7 @@ public abstract class ToStringNode extends RBaseNode { @SuppressWarnings("unused") @Specialization + @TruffleBoundary protected String toString(REnvironment env, boolean quotes, String separator) { return env.toString(); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java index f46b860eaa0bb01f6161abce902c1a7bd32ae362..11fc0d9c9361611a2cf8e797fdf7282527963218 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java @@ -110,7 +110,7 @@ public abstract class UnaryNotNode extends RBuiltinNode { } } RLogicalVector resultVector = RDataFactory.createLogicalVector(result, na.neverSeenNA()); - resultVector.copyAttributesFrom(attrProfiles, vector); + resultVector.copyAttributesFrom(vector); return resultVector; } @@ -184,7 +184,7 @@ public abstract class UnaryNotNode extends RBuiltinNode { } } RRawVector resultVector = RDataFactory.createRawVector(result); - resultVector.copyAttributesFrom(attrProfiles, vector); + resultVector.copyAttributesFrom(vector); return resultVector; } 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/JavaUpCallsRFFI.java similarity index 66% rename from com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/CallRFFIHelper.java rename to com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFI.java index fa73127bcec10decf22135b9317a62cbf70d5ce1..d51986b5013153204a5c9b511534bd21d37f4de5 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/JavaUpCallsRFFI.java @@ -20,12 +20,11 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.runtime.ffi.jni; +package com.oracle.truffle.r.runtime.ffi; import java.nio.charset.StandardCharsets; import java.util.function.Function; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.object.DynamicObject; @@ -79,17 +78,16 @@ 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.ffi.ParseResult.ParseStatus; +import com.oracle.truffle.r.runtime.ffi.jni.TraceUpCallsAdapter; 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; /** - * This class provides methods that match the functionality of the macro/function definitions in the - * 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. + * This class provides a simple Java-based implementation of {@link UpCallsRFFI}, using no Truffle + * mechanisms. * * 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 @@ -98,37 +96,16 @@ import com.oracle.truffle.r.runtime.rng.RRNG; * 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 { +public class JavaUpCallsRFFI implements UpCallsRFFI { - /** - * 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; - - CharSXPWrapper(String contents) { - this.contents = contents; - } - - public String getContents() { - return contents; - } + private TraceUpCallsAdapter tracer; - @Override - public String toString() { - return "CHARSXP(" + contents + ")"; + public JavaUpCallsRFFI() { + if (RFFIUtils.traceEnabled()) { + tracer = new TraceUpCallsAdapter(); } } - public static Object createCharSXP(String contents) { - return new CharSXPWrapper(contents); - } - private static RuntimeException unimplemented() { return unimplemented(""); } @@ -169,38 +146,43 @@ public class CallRFFIHelper { // Checkstyle: stop method name check - public static RIntVector Rf_ScalarInteger(int value) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_ScalarInteger", value); + @Override + public RIntVector Rf_ScalarInteger(int value) { + if (tracer != null) { + tracer.Rf_ScalarInteger(value); } return RDataFactory.createIntVectorFromScalar(value); } - public static RLogicalVector Rf_ScalarLogical(int value) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_ScalarLogical", value); + @Override + public RLogicalVector Rf_ScalarLogical(int value) { + if (tracer != null) { + tracer.Rf_ScalarLogical(value); } return RDataFactory.createLogicalVectorFromScalar(value != 0); } - public static RDoubleVector Rf_ScalarDouble(double value) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_ScalarDouble", value); + @Override + public RDoubleVector Rf_ScalarDouble(double value) { + if (tracer != null) { + tracer.Rf_ScalarDouble(value); } return RDataFactory.createDoubleVectorFromScalar(value); } - public static RStringVector Rf_ScalarString(Object value) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_ScalarString", value); + @Override + public RStringVector Rf_ScalarString(Object value) { + if (tracer != null) { + tracer.Rf_ScalarString(value); } CharSXPWrapper chars = guaranteeInstanceOf(value, CharSXPWrapper.class); return RDataFactory.createStringVectorFromScalar(chars.getContents()); } - public static int Rf_asInteger(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_asInteger", x); + @Override + public int Rf_asInteger(Object x) { + if (tracer != null) { + tracer.Rf_asInteger(x); } // TODO this is quite incomplete and really should be implemented with CastIntegerNode if (x instanceof Integer) { @@ -217,9 +199,10 @@ public class CallRFFIHelper { } } - public static double Rf_asReal(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_asReal", x); + @Override + public double Rf_asReal(Object x) { + if (tracer != null) { + tracer.Rf_asReal(x); } if (x instanceof Double) { return ((Double) x).doubleValue(); @@ -231,9 +214,10 @@ public class CallRFFIHelper { } } - public static int Rf_asLogical(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_asLogical", x); + @Override + public int Rf_asLogical(Object x) { + if (tracer != null) { + tracer.Rf_asLogical(x); } if (x instanceof Byte) { return ((Byte) x).intValue(); @@ -243,14 +227,15 @@ public class CallRFFIHelper { } } - public static Object Rf_asChar(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_asChar", x); + @Override + public Object Rf_asChar(Object x) { + if (tracer != null) { + tracer.Rf_asChar(x); } if (x instanceof CharSXPWrapper) { return x; } else if (x instanceof RSymbol) { - return new CharSXPWrapper(((RSymbol) x).getName()); + return CharSXPWrapper.create(((RSymbol) x).getName()); } Object obj = RRuntime.asAbstractVector(x); @@ -258,34 +243,37 @@ public class CallRFFIHelper { RAbstractVector vector = (RAbstractVector) obj; if (vector.getLength() > 0) { if (vector instanceof RAbstractStringVector) { - return new CharSXPWrapper(((RAbstractStringVector) vector).getDataAt(0)); + return CharSXPWrapper.create(((RAbstractStringVector) vector).getDataAt(0)); } else { unimplemented("asChar type " + x.getClass()); } } } - return new CharSXPWrapper(RRuntime.STRING_NA); + return CharSXPWrapper.create(RRuntime.STRING_NA); } - public static Object Rf_mkCharLenCE(byte[] bytes, @SuppressWarnings("unused") int encoding) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_mkCharLenCE", bytes); + @Override + public Object Rf_mkCharLenCE(byte[] bytes, int encoding) { + if (tracer != null) { + tracer.Rf_mkCharLenCE(bytes, encoding); } // TODO: handle encoding properly - return new CharSXPWrapper(new String(bytes, StandardCharsets.UTF_8)); + return CharSXPWrapper.create(new String(bytes, StandardCharsets.UTF_8)); } - public static Object Rf_cons(Object car, Object cdr) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_cons", car, cdr); + @Override + public Object Rf_cons(Object car, Object cdr) { + if (tracer != null) { + tracer.Rf_cons(car, cdr); } return RDataFactory.createPairList(car, cdr); } - public static void Rf_defineVar(Object symbolArg, Object value, Object envArg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_defineVar", symbolArg, value, envArg); + @Override + public void Rf_defineVar(Object symbolArg, Object value, Object envArg) { + if (tracer != null) { + tracer.Rf_defineVar(symbolArg, value, envArg); } REnvironment env = (REnvironment) envArg; RSymbol name = (RSymbol) symbolArg; @@ -296,33 +284,39 @@ public class CallRFFIHelper { } } - public static Object R_do_MAKE_CLASS(String clazz) { + @Override + public Object R_do_MAKE_CLASS(String clazz) { + if (tracer != null) { + tracer.R_do_MAKE_CLASS(clazz); + } String name = "getClass"; RFunction getClass = (RFunction) RContext.getRRuntimeASTAccess().forcePromise(name, REnvironment.getRegisteredNamespace("methods").get(name)); return RContext.getEngine().evalFunction(getClass, null, RCaller.createInvalid(null), null, clazz); } - public static Object Rf_findVar(Object symbolArg, Object envArg) { - // WARNING: argument order reversed from Rf_findVarInFrame! - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_findVar", symbolArg, envArg); + @Override + public Object Rf_findVar(Object symbolArg, Object envArg) { + if (tracer != null) { + tracer.Rf_findVar(symbolArg, envArg); } return findVarInFrameHelper(envArg, symbolArg, true); } - public static Object Rf_findVarInFrame(Object envArg, Object symbolArg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_findVarInFrame", envArg, symbolArg); + @Override + public Object Rf_findVarInFrame(Object envArg, Object symbolArg) { + if (tracer != null) { + tracer.Rf_findVarInFrame(envArg, symbolArg); } return findVarInFrameHelper(envArg, symbolArg, false); } - public static Object Rf_findVarInFrame3(Object envArg, Object symbolArg, @SuppressWarnings("unused") int doGet) { + @Override + public Object Rf_findVarInFrame3(Object envArg, Object symbolArg, int doGet) { + if (tracer != null) { + tracer.Rf_findVarInFrame3(envArg, symbolArg, doGet); + } // GNU R has code for IS_USER_DATBASE that uses doGet // This is a lookup in the single environment (envArg) only, i.e. inherits=false - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_findVarInFrame3", envArg, symbolArg); - } return findVarInFrameHelper(envArg, symbolArg, false); } @@ -349,9 +343,10 @@ public class CallRFFIHelper { return RUnboundValue.instance; } - public static Object Rf_getAttrib(Object obj, Object name) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_getAttrib", obj, name); + @Override + public Object Rf_getAttrib(Object obj, Object name) { + if (tracer != null) { + tracer.Rf_getAttrib(obj, name); } Object result = RNull.instance; if (obj instanceof RAttributable) { @@ -368,9 +363,10 @@ public class CallRFFIHelper { return result; } - public static void Rf_setAttrib(Object obj, Object name, Object val) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_setAttrib", obj, name, val); + @Override + public void Rf_setAttrib(Object obj, Object name, Object val) { + if (tracer != null) { + tracer.Rf_setAttrib(obj, name, val); } if (obj instanceof RAttributable) { RAttributable attrObj = (RAttributable) obj; @@ -415,9 +411,10 @@ public class CallRFFIHelper { return result; } - public static int Rf_inherits(Object x, String clazz) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_inherits", x, clazz); + @Override + public int Rf_inherits(Object x, String clazz) { + if (tracer != null) { + tracer.Rf_inherits(x, clazz); } int result = 0; RStringVector hierarchy = getClassHr(x); @@ -429,38 +426,43 @@ public class CallRFFIHelper { return result; } - public static Object Rf_install(String name) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_install", name); + @Override + public Object Rf_install(String name) { + if (tracer != null) { + tracer.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); + @Override + public Object Rf_lengthgets(Object x, int newSize) { + if (tracer != null) { + tracer.Rf_lengthgets(x, newSize); } RAbstractVector vec = (RAbstractVector) RRuntime.asAbstractVector(x); return vec.resize(newSize); } - public static int Rf_isString(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_isString", x); + @Override + public int Rf_isString(Object x) { + if (tracer != null) { + tracer.Rf_isString(x); } return RRuntime.checkType(x, RType.Character) ? 1 : 0; } - public static int Rf_isNull(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_isNull", x); + @Override + public int Rf_isNull(Object x) { + if (tracer != null) { + tracer.Rf_isNull(x); } return x == RNull.instance ? 1 : 0; } - public static Object Rf_PairToVectorList(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_PairToVectorList", x); + @Override + public Object Rf_PairToVectorList(Object x) { + if (tracer != null) { + tracer.Rf_PairToVectorList(x); } if (x == RNull.instance) { return RDataFactory.createList(); @@ -469,30 +471,34 @@ public class CallRFFIHelper { return pl.toRList(); } - public static void Rf_error(String msg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_error", msg); + @Override + public void Rf_error(String msg) { + if (tracer != null) { + tracer.Rf_error(msg); } throw RError.error(RError.SHOW_CALLER2, RError.Message.GENERIC, msg); } - public static void Rf_warning(String msg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_warning", msg); + @Override + public void Rf_warning(String msg) { + if (tracer != null) { + tracer.Rf_warning(msg); } RError.warning(RError.SHOW_CALLER2, RError.Message.GENERIC, msg); } - public static void Rf_warningcall(Object call, String msg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_warningcall", call, msg); + @Override + public void Rf_warningcall(Object call, String msg) { + if (tracer != null) { + tracer.Rf_warningcall(call, msg); } RErrorHandling.warningcallRFFI(call, msg); } - public static Object Rf_allocateVector(int mode, int n) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_allocateVector", mode, n); + @Override + public Object Rf_allocateVector(int mode, int n) { + if (tracer != null) { + tracer.Rf_allocateVector(mode, n); } SEXPTYPE type = SEXPTYPE.mapInt(mode); if (n < 0) { @@ -521,9 +527,10 @@ public class CallRFFIHelper { } } - public static Object Rf_allocateArray(int mode, Object dimsObj) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_allocateArray", mode, dimsObj); + @Override + public Object Rf_allocateArray(int mode, Object dimsObj) { + if (tracer != null) { + tracer.Rf_allocateArray(mode, dimsObj); } RIntVector dims = (RIntVector) dimsObj; int n = 1; @@ -539,9 +546,10 @@ public class CallRFFIHelper { } - public static Object Rf_allocateMatrix(int mode, int nrow, int ncol) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_allocateMatrix", mode, ncol, nrow); + @Override + public Object Rf_allocateMatrix(int mode, int nrow, int ncol) { + if (tracer != null) { + tracer.Rf_allocateMatrix(mode, ncol, nrow); } SEXPTYPE type = SEXPTYPE.mapInt(mode); if (nrow < 0 || ncol < 0) { @@ -565,23 +573,26 @@ public class CallRFFIHelper { } } - public static int Rf_nrows(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_nrows", x); + @Override + public int Rf_nrows(Object x) { + if (tracer != null) { + tracer.Rf_nrows(x); } return RRuntime.nrows(x); } - public static int Rf_ncols(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_ncols", x); + @Override + public int Rf_ncols(Object x) { + if (tracer != null) { + tracer.Rf_ncols(x); } return RRuntime.ncols(x); } - public static int LENGTH(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("LENGTH", x); + @Override + public int LENGTH(Object x) { + if (tracer != null) { + tracer.LENGTH(x); } if (x instanceof RAbstractContainer) { return ((RAbstractContainer) x).getLength(); @@ -596,26 +607,29 @@ public class CallRFFIHelper { } } - public static void SET_STRING_ELT(Object x, int i, Object v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_STRING_ELT", x, i, v); + @Override + public void SET_STRING_ELT(Object x, int i, Object v) { + if (tracer != null) { + tracer.SET_STRING_ELT(x, i, v); } RStringVector vector = guaranteeInstanceOf(x, RStringVector.class); CharSXPWrapper element = guaranteeInstanceOf(v, CharSXPWrapper.class); vector.setElement(i, element.getContents()); } - public static void SET_VECTOR_ELT(Object x, int i, Object v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_VECTOR_ELT", i, v); + @Override + public void SET_VECTOR_ELT(Object x, int i, Object v) { + if (tracer != null) { + tracer.SET_VECTOR_ELT(x, i, v); } RList list = guaranteeInstanceOf(x, RList.class); list.setElement(i, v); } - public static byte[] RAW(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("RAW", x); + @Override + public Object RAW(Object x) { + if (tracer != null) { + tracer.RAW(x); } if (x instanceof RRawVector) { return ((RRawVector) x).getDataWithoutCopying(); @@ -626,9 +640,10 @@ public class CallRFFIHelper { } } - public static byte[] LOGICAL(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("LOGICAL", x); + @Override + public Object LOGICAL(Object x) { + if (tracer != null) { + tracer.LOGICAL(x); } if (x instanceof RLogicalVector) { return ((RLogicalVector) x).getDataWithoutCopying(); @@ -639,9 +654,10 @@ public class CallRFFIHelper { } } - public static int[] INTEGER(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("INTEGER", x); + @Override + public Object INTEGER(Object x) { + if (tracer != null) { + tracer.INTEGER(x); } if (x instanceof RIntVector) { return ((RIntVector) x).getDataWithoutCopying(); @@ -662,9 +678,10 @@ public class CallRFFIHelper { } } - public static double[] REAL(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("REAL", x); + @Override + public Object REAL(Object x) { + if (tracer != null) { + tracer.REAL(x); } if (x instanceof RDoubleVector) { return ((RDoubleVector) x).getDataWithoutCopying(); @@ -676,33 +693,19 @@ public class CallRFFIHelper { } } - /** - * Called to possibly update the "complete" status on {@code x}. N.B. {@code x} may not be an - * object with a concrete {@code setComplete} method, e.g. see {@link #INTEGER(Object)}. - */ - public static void setComplete(Object x, boolean complete) { - // only care about concrete vectors - if (x instanceof RVector) { - ((RVector<?>) x).setComplete(complete); - } - } - - public static void logObject(Object x) { - System.out.println("object " + x); - System.out.println("class " + x.getClass()); - } - - public static Object STRING_ELT(Object x, int i) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("STRING_ELT", x, i); + @Override + public Object STRING_ELT(Object x, int i) { + if (tracer != null) { + tracer.STRING_ELT(x, i); } RAbstractStringVector vector = guaranteeInstanceOf(RRuntime.asAbstractVector(x), RAbstractStringVector.class); - return new CharSXPWrapper(vector.getDataAt(i)); + return CharSXPWrapper.create(vector.getDataAt(i)); } - public static Object VECTOR_ELT(Object x, int i) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("VECTOR_ELT", x, i); + @Override + public Object VECTOR_ELT(Object x, int i) { + if (tracer != null) { + tracer.VECTOR_ELT(x, i); } Object vec = x; if (vec instanceof RExpression) { @@ -712,9 +715,10 @@ public class CallRFFIHelper { return list.getDataAt(i); } - public static int NAMED(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("NAMED", x); + @Override + public int NAMED(Object x) { + if (tracer != null) { + tracer.NAMED(x); } if (x instanceof RShareable) { return ((RShareable) x).isShared() ? 1 : 0; @@ -723,9 +727,10 @@ public class CallRFFIHelper { } } - public static Object SET_TYPEOF_FASTR(Object x, int v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_TYPEOF_FASTR", x, v); + @Override + public Object SET_TYPEOF_FASTR(Object x, int v) { + if (tracer != null) { + tracer.SET_TYPEOF_FASTR(x, v); } int code = SEXPTYPE.gnuRCodeForObject(x); if (code == SEXPTYPE.LISTSXP.code && v == SEXPTYPE.LANGSXP.code) { @@ -735,9 +740,10 @@ public class CallRFFIHelper { } } - public static int TYPEOF(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("TYPEOF", x); + @Override + public int TYPEOF(Object x) { + if (tracer != null) { + tracer.TYPEOF(x); } if (x instanceof CharSXPWrapper) { return SEXPTYPE.CHARSXP.code; @@ -746,9 +752,10 @@ public class CallRFFIHelper { } } - public static int OBJECT(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("OBJECT", x); + @Override + public int OBJECT(Object x) { + if (tracer != null) { + tracer.OBJECT(x); } if (x instanceof RAttributable) { return ((RAttributable) x).getAttr(RRuntime.CLASS_ATTR_KEY) == null ? 0 : 1; @@ -757,9 +764,10 @@ public class CallRFFIHelper { } } - public static Object Rf_duplicate(Object x, int deep) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_duplicate", x, deep); + @Override + public Object Rf_duplicate(Object x, int deep) { + if (tracer != null) { + tracer.Rf_duplicate(x, deep); } guarantee(x != null, "unexpected type: null instead of " + x.getClass().getSimpleName()); guarantee(x instanceof RShareable || x instanceof RIntSequence || x instanceof RExternalPtr, @@ -773,9 +781,10 @@ public class CallRFFIHelper { } } - public static int Rf_anyDuplicated(Object x, int fromLast) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_anyDuplicated", x, fromLast); + @Override + public int Rf_anyDuplicated(Object x, int fromLast) { + if (tracer != null) { + tracer.Rf_anyDuplicated(x, fromLast); } RAbstractVector vec = (RAbstractVector) x; if (vec.getLength() == 0) { @@ -785,17 +794,19 @@ public class CallRFFIHelper { } } - public static Object PRINTNAME(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("PRINTNAME", x); + @Override + public Object PRINTNAME(Object x) { + if (tracer != null) { + tracer.PRINTNAME(x); } guaranteeInstanceOf(x, RSymbol.class); - return new CharSXPWrapper(((RSymbol) x).getName()); + return CharSXPWrapper.create(((RSymbol) x).getName()); } - public static Object TAG(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("TAG", e); + @Override + public Object TAG(Object e) { + if (tracer != null) { + tracer.TAG(e); } if (e instanceof RPairList) { return ((RPairList) e).getTag(); @@ -806,9 +817,10 @@ public class CallRFFIHelper { } } - public static Object CAR(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("CAR", e); + @Override + public Object CAR(Object e) { + if (tracer != null) { + tracer.CAR(e); } guarantee(e != null && (RPairList.class.isInstance(e) || RLanguage.class.isInstance(e)), "CAR only works on pair lists and language objects"); if (e instanceof RPairList) { @@ -818,9 +830,10 @@ public class CallRFFIHelper { } } - public static Object CDR(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("CDR", e); + @Override + public Object CDR(Object e) { + if (tracer != null) { + tracer.CDR(e); } if (e instanceof RLanguage) { RLanguage lang = (RLanguage) e; @@ -832,9 +845,10 @@ public class CallRFFIHelper { } } - public static Object CADR(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("CADR", e); + @Override + public Object CADR(Object e) { + if (tracer != null) { + tracer.CADR(e); } guarantee(e != null && (RPairList.class.isInstance(e) || RLanguage.class.isInstance(e)), "CADR only works on pair lists and language objects"); if (e instanceof RPairList) { @@ -844,9 +858,10 @@ public class CallRFFIHelper { } } - public static Object CADDR(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("CADDR", e); + @Override + public Object CADDR(Object e) { + if (tracer != null) { + tracer.CADDR(e); } guarantee(e != null && (RPairList.class.isInstance(e) || RLanguage.class.isInstance(e)), "CADDR only works on pair lists and language objects"); if (e instanceof RPairList) { @@ -856,9 +871,10 @@ public class CallRFFIHelper { } } - public static Object CDDR(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("CDDR", e); + @Override + public Object CDDR(Object e) { + if (tracer != null) { + tracer.CDDR(e); } if (e instanceof RLanguage) { RLanguage lang = (RLanguage) e; @@ -870,9 +886,10 @@ public class CallRFFIHelper { } } - public static Object SET_TAG(Object x, Object y) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_TAG", x, y); + @Override + public Object SET_TAG(Object x, Object y) { + if (tracer != null) { + tracer.SET_TAG(x, y); } if (x instanceof RPairList) { ((RPairList) x).setTag(y); @@ -884,32 +901,39 @@ public class CallRFFIHelper { return y; } - public static Object SETCAR(Object x, Object y) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SETCAR", x, y); + @Override + public Object SETCAR(Object x, Object y) { + if (tracer != null) { + tracer.SETCAR(x, y); } guaranteeInstanceOf(x, RPairList.class); ((RPairList) x).setCar(y); return y; } - public static Object SETCDR(Object x, Object y) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SETCDR", x, y); + @Override + public Object SETCDR(Object x, Object y) { + if (tracer != null) { + tracer.SETCDR(x, y); } guaranteeInstanceOf(x, RPairList.class); ((RPairList) x).setCdr(y); return y; } - public static Object SETCADR(Object x, Object y) { + @Override + public Object SETCADR(Object x, Object y) { + if (tracer != null) { + tracer.SETCADR(x, y); + } SETCAR(CDR(x), y); return y; } - public static Object SYMVALUE(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SYMVALUE", x); + @Override + public Object SYMVALUE(Object x) { + if (tracer != null) { + tracer.SYMVALUE(x); } if (!(x instanceof RSymbol)) { throw RInternalError.shouldNotReachHere(); @@ -922,9 +946,10 @@ public class CallRFFIHelper { } } - public static void SET_SYMVALUE(Object x, Object v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_SYMVALUE", x, v); + @Override + public void SET_SYMVALUE(Object x, Object v) { + if (tracer != null) { + tracer.SET_SYMVALUE(x, v); } if (!(x instanceof RSymbol)) { throw RInternalError.shouldNotReachHere(); @@ -932,27 +957,29 @@ public class CallRFFIHelper { REnvironment.baseEnv().safePut(((RSymbol) x).getName(), v); } - public static int R_BindingIsLocked(Object sym, Object env) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_BindingIsLocked", sym, env); + @Override + public int R_BindingIsLocked(Object sym, Object env) { + if (tracer != null) { + tracer.R_BindingIsLocked(sym, env); } guaranteeInstanceOf(sym, RSymbol.class); guaranteeInstanceOf(env, REnvironment.class); return ((REnvironment) env).bindingIsLocked(((RSymbol) sym).getName()) ? 1 : 0; } - public static Object R_FindNamespace(Object name) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_FindNamespace", name); + @Override + public Object R_FindNamespace(Object name) { + if (tracer != null) { + tracer.R_FindNamespace(name); } Object result = RContext.getInstance().stateREnvironment.getNamespaceRegistry().get(RRuntime.asString(name)); return result; } - @TruffleBoundary - public static Object Rf_eval(Object expr, Object env) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_eval", expr, env); + @Override + public Object Rf_eval(Object expr, Object env) { + if (tracer != null) { + tracer.Rf_eval(expr, env); } guarantee(env instanceof REnvironment); Object result; @@ -981,9 +1008,10 @@ public class CallRFFIHelper { return result; } - public static Object Rf_findfun(Object symbolObj, Object envObj) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_findfun", symbolObj, envObj); + @Override + public Object Rf_findfun(Object symbolObj, Object envObj) { + if (tracer != null) { + tracer.Rf_findfun(symbolObj, envObj); } guarantee(envObj instanceof REnvironment); REnvironment env = (REnvironment) envObj; @@ -999,18 +1027,20 @@ public class CallRFFIHelper { } } - public static Object Rf_GetOption1(Object tag) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_GetOption1", tag); + @Override + public Object Rf_GetOption1(Object tag) { + if (tracer != null) { + tracer.Rf_GetOption1(tag); } guarantee(tag instanceof RSymbol); Object result = RContext.getInstance().stateROptions.getValue(((RSymbol) tag).getName()); return result; } - public static void Rf_gsetVar(Object symbol, Object value, Object rho) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_gsetVar", symbol, value, rho); + @Override + public void Rf_gsetVar(Object symbol, Object value, Object rho) { + if (tracer != null) { + tracer.Rf_gsetVar(symbol, value, rho); } guarantee(symbol instanceof RSymbol); REnvironment baseEnv = RContext.getInstance().stateREnvironment.getBaseEnv(); @@ -1022,9 +1052,10 @@ public class CallRFFIHelper { } } - public static void DUPLICATE_ATTRIB(Object to, Object from) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("DUPLICATE_ATTRIB", to, from); + @Override + public void DUPLICATE_ATTRIB(Object to, Object from) { + if (tracer != null) { + tracer.DUPLICATE_ATTRIB(to, from); } if (from instanceof RAttributable) { guaranteeInstanceOf(to, RAttributable.class); @@ -1034,9 +1065,10 @@ public class CallRFFIHelper { // TODO: copy OBJECT? and S4 attributes } - public static int R_computeIdentical(Object x, Object y, int flags) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_computeIdentical", x, y, flags); + @Override + public int R_computeIdentical(Object x, Object y, int flags) { + if (tracer != null) { + tracer.R_computeIdentical(x, y, flags); } RFunction indenticalBuiltin = RContext.lookupBuiltin("identical"); Object res = RContext.getEngine().evalFunction(indenticalBuiltin, null, null, null, x, y, RRuntime.asLogical((!((flags & 1) == 0))), @@ -1044,25 +1076,26 @@ public class CallRFFIHelper { return (int) res; } - @SuppressWarnings("unused") - public static void Rf_copyListMatrix(Object s, Object t, int byrow) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_copyListMatrix", t, byrow); + @Override + public void Rf_copyListMatrix(Object s, Object t, int byrow) { + if (tracer != null) { + tracer.Rf_copyListMatrix(s, t, byrow); } throw unimplemented(); } - @SuppressWarnings("unused") - public static void Rf_copyMatrix(Object s, Object t, int byrow) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_copyMatrix", t, byrow); + @Override + public void Rf_copyMatrix(Object s, Object t, int byrow) { + if (tracer != null) { + tracer.Rf_copyMatrix(s, t, byrow); } throw unimplemented(); } - public static Object R_tryEval(Object expr, Object env, boolean silent) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_tryEval", expr, env, silent); + @Override + public Object R_tryEval(Object expr, Object env, boolean silent) { + if (tracer != null) { + tracer.R_tryEval(expr, env, silent); } Object handlerStack = RErrorHandling.getHandlerStack(); Object restartStack = RErrorHandling.getRestartStack(); @@ -1083,25 +1116,27 @@ public class CallRFFIHelper { * 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"); + @Override + public Object R_ToplevelExec() { + if (tracer != null) { + tracer.R_ToplevelExec(); } return RErrorHandling.resetAndGetHandlerStacks(); } /** - * Helper function for {@code R_TopLevelExec}, see {@link #resetAndGetErrorHandlerStacks()}, - * called after C function returns. + * Helper function for {@code R_TopLevelExec}, see {@link #R_ToplevelExec()}, called after C + * function returns. */ - public static void restoreErrorHandlerStacks(Object stacks) { + public void R_ToplevelExecRestoreErrorHandlerStacks(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); + @Override + public int RDEBUG(Object x) { + if (tracer != null) { + tracer.RDEBUG(x); } REnvironment env = guaranteeInstanceOf(x, REnvironment.class); if (env instanceof REnvironment.Function) { @@ -1113,9 +1148,10 @@ public class CallRFFIHelper { } } - public static void SET_RDEBUG(Object x, int v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_RDEBUG", x, v); + @Override + public void SET_RDEBUG(Object x, int v) { + if (tracer != null) { + tracer.SET_RDEBUG(x, v); } REnvironment env = guaranteeInstanceOf(x, REnvironment.class); if (env instanceof REnvironment.Function) { @@ -1129,27 +1165,30 @@ public class CallRFFIHelper { } } - public static int RSTEP(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("RSTEP", x); + @Override + public int RSTEP(Object x) { + if (tracer != null) { + tracer.RSTEP(x); } @SuppressWarnings("unused") REnvironment env = guaranteeInstanceOf(x, REnvironment.class); throw RInternalError.unimplemented("RSTEP"); } - public static void SET_RSTEP(Object x, int v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_RSTEP", x, v); + @Override + public void SET_RSTEP(Object x, int v) { + if (tracer != null) { + tracer.SET_RSTEP(x, v); } @SuppressWarnings("unused") REnvironment env = guaranteeInstanceOf(x, REnvironment.class); throw RInternalError.unimplemented("SET_RSTEP"); } - public static Object ENCLOS(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("ENCLOS", x); + @Override + public Object ENCLOS(Object x) { + if (tracer != null) { + tracer.ENCLOS(x); } REnvironment env = guaranteeInstanceOf(x, REnvironment.class); Object result = env.getParent(); @@ -1159,35 +1198,19 @@ public class CallRFFIHelper { return result; } - public static Object PRVALUE(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("PRVALUE", x); + @Override + public Object PRVALUE(Object x) { + if (tracer != null) { + tracer.PRVALUE(x); } RPromise p = guaranteeInstanceOf(x, RPromise.class); return p.isEvaluated() ? p.getValue() : RUnboundValue.instance; } - private enum ParseStatus { - PARSE_NULL, - PARSE_OK, - PARSE_INCOMPLETE, - PARSE_ERROR, - PARSE_EOF - } - - private static class ParseResult { - @SuppressWarnings("unused") private final int parseStatus; - @SuppressWarnings("unused") private final Object expr; - - private ParseResult(int parseStatus, Object expr) { - this.parseStatus = parseStatus; - this.expr = expr; - } - } - - public static Object R_ParseVector(Object text, int n, Object srcFile) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_ParseVector", text, n, srcFile); + @Override + public Object R_ParseVector(Object text, int n, Object srcFile) { + if (tracer != null) { + tracer.R_ParseVector(text, n, srcFile); } // TODO general case assert n == 1; @@ -1206,9 +1229,10 @@ public class CallRFFIHelper { } - public static Object R_lsInternal3(Object envArg, int allArg, int sortedArg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_lsInternal3", envArg, allArg, sortedArg); + @Override + public Object R_lsInternal3(Object envArg, int allArg, int sortedArg) { + if (tracer != null) { + tracer.R_lsInternal3(envArg, allArg, sortedArg); } boolean sorted = sortedArg != 0; boolean all = allArg != 0; @@ -1216,29 +1240,28 @@ public class CallRFFIHelper { return env.ls(all, null, sorted); } - public static String R_HomeDir() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_HomeDir"); + @Override + public String R_HomeDir() { + if (tracer != null) { + tracer.R_HomeDir(); } return REnvVars.rHome(); } - @SuppressWarnings("unused") - private static void R_CleanUp(int sa, int status, int runlast) { + @Override + public void R_CleanUp(int sa, int status, int runlast) { + if (tracer != null) { + tracer.R_CleanUp(sa, status, runlast); + } RCleanUp.stdCleanUp(SA_TYPE.values()[sa], status, runlast != 0); } - // Checkstyle: resume method name check - - public static Object validate(Object x) { - return x; - } - - public static Object getGlobalContext() { - Utils.warn("Potential memory leak (global context object)"); - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getGlobalContext"); + @Override + public Object R_GlobalContext() { + if (tracer != null) { + tracer.R_GlobalContext(); } + Utils.warn("Potential memory leak (global context object)"); Frame frame = Utils.getActualCurrentFrame(); if (frame == null) { return RCaller.topLevel; @@ -1250,80 +1273,94 @@ public class CallRFFIHelper { return rCaller == null ? RCaller.topLevel : rCaller; } - public static Object getGlobalEnv() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getGlobalEnv"); + @Override + public Object R_GlobalEnv() { + if (tracer != null) { + tracer.R_GlobalEnv(); } return RContext.getInstance().stateREnvironment.getGlobalEnv(); } - public static Object getBaseEnv() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getBaseEnv"); + @Override + public Object R_BaseEnv() { + if (tracer != null) { + tracer.R_BaseEnv(); } return RContext.getInstance().stateREnvironment.getBaseEnv(); } - public static Object getBaseNamespace() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getBaseNamespace"); + @Override + public Object R_BaseNamespace() { + if (tracer != null) { + tracer.R_BaseNamespace(); } return RContext.getInstance().stateREnvironment.getBaseNamespace(); } - public static Object getNamespaceRegistry() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getNamespaceRegistry"); + @Override + public Object R_NamespaceRegistry() { + if (tracer != null) { + tracer.R_NamespaceRegistry(); } return RContext.getInstance().stateREnvironment.getNamespaceRegistry(); } - public static int isInteractive() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("isInteractive"); + @Override + public int isInteractive() { + if (tracer != null) { + tracer.isInteractive(); } return RContext.getInstance().isInteractive() ? 1 : 0; } - public static int isS4Object(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("isS4Object"); + @Override + public int isS4Object(Object x) { + if (tracer != null) { + tracer.isS4Object(x); } return x instanceof RS4Object ? 1 : 0; } - public static void printf(String message) { + @Override + public void Rprintf(String message) { + if (tracer != null) { + tracer.Rprintf(message); + } RContext.getInstance().getConsoleHandler().print(message); } - public static void getRNGstate() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getRNGstate"); + @Override + public void GetRNGstate() { + if (tracer != null) { + tracer.GetRNGstate(); } RRNG.getRNGState(); } - public static void putRNGstate() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("putRNGstate"); + @Override + public void PutRNGstate() { + if (tracer != null) { + tracer.PutRNGstate(); } RRNG.putRNGState(); } - public static double unifRand() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("unifRand"); + @Override + public double unif_rand() { + if (tracer != null) { + tracer.unif_rand(); } return RRNG.unifRand(); } // Checkstyle: stop method name check - public static Object R_getGlobalFunctionContext() { - Utils.warn("Potential memory leak (global function context object)"); - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getGlobalFunctionContext"); + @Override + public Object R_getGlobalFunctionContext() { + if (tracer != null) { + tracer.R_getGlobalFunctionContext(); } + Utils.warn("Potential memory leak (global function context object)"); Frame frame = Utils.getActualCurrentFrame(); if (frame == null) { return RNull.instance; @@ -1338,11 +1375,12 @@ public class CallRFFIHelper { return currentCaller == null || currentCaller == RCaller.topLevel ? RNull.instance : currentCaller; } - public static Object R_getParentFunctionContext(Object c) { - Utils.warn("Potential memory leak (parent function context object)"); - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getParentFunctionContext"); + @Override + public Object R_getParentFunctionContext(Object c) { + if (tracer != null) { + tracer.R_getParentFunctionContext(c); } + Utils.warn("Potential memory leak (parent function context object)"); RCaller currentCaller = guaranteeInstanceOf(c, RCaller.class); while (true) { currentCaller = currentCaller.getParent(); @@ -1354,9 +1392,10 @@ public class CallRFFIHelper { return currentCaller == null || currentCaller == RCaller.topLevel ? RNull.instance : currentCaller; } - public static Object R_getContextEnv(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getContextEnv", c); + @Override + public Object R_getContextEnv(Object c) { + if (tracer != null) { + tracer.R_getContextEnv(c); } RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); if (rCaller == RCaller.topLevel) { @@ -1382,9 +1421,10 @@ public class CallRFFIHelper { } } - public static Object R_getContextFun(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getContextEnv", c); + @Override + public Object R_getContextFun(Object c) { + if (tracer != null) { + tracer.R_getContextFun(c); } RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); if (rCaller == RCaller.topLevel) { @@ -1410,9 +1450,10 @@ public class CallRFFIHelper { } } - public static Object R_getContextCall(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getContextEnv", c); + @Override + public Object R_getContextCall(Object c) { + if (tracer != null) { + tracer.R_getContextCall(c); } RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); if (rCaller == RCaller.topLevel) { @@ -1421,9 +1462,10 @@ public class CallRFFIHelper { return RContext.getRRuntimeASTAccess().getSyntaxCaller(rCaller); } - public static Object R_getContextSrcRef(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("getContextSrcRef", c); + @Override + public Object R_getContextSrcRef(Object c) { + if (tracer != null) { + tracer.R_getContextSrcRef(c); } Object o = R_getContextFun(c); if (!(o instanceof RFunction)) { @@ -1438,94 +1480,133 @@ public class CallRFFIHelper { } - public static int R_insideBrowser() { + @Override + public int R_insideBrowser() { + if (tracer != null) { + tracer.R_insideBrowser(); + } return RContext.getInstance().stateInstrumentation.getBrowserState().inBrowser() ? 1 : 0; } - public static int R_isGlobal(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("isGlobal", c); + @Override + public int R_isGlobal(Object c) { + if (tracer != null) { + tracer.R_isGlobal(c); } RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); return rCaller == RCaller.topLevel ? 1 : 0; } - public static int R_isEqual(Object x, Object y) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("isEqual", x, y); + @Override + public int R_isEqual(Object x, Object y) { + if (tracer != null) { + tracer.R_isEqual(x, y); } return x == y ? 1 : 0; } - public static Object Rf_classgets(Object x, Object y) { + @Override + public Object Rf_classgets(Object x, Object y) { + if (tracer != null) { + tracer.Rf_classgets(x, y); + } RAbstractVector vector = guaranteeInstanceOf(x, RAbstractVector.class); vector.setClassAttr(guaranteeInstanceOf(y, RStringVector.class)); return RNull.instance; } - public static RExternalPtr R_MakeExternalPtr(long addr, Object tag, Object prot) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_MakeExternalPtr", addr, tag, prot); + @Override + public RExternalPtr R_MakeExternalPtr(long addr, Object tag, Object prot) { + if (tracer != null) { + tracer.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); + @Override + public long R_ExternalPtrAddr(Object x) { + if (tracer != null) { + tracer.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); + @Override + public Object R_ExternalPtrTag(Object x) { + if (tracer != null) { + tracer.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); + @Override + public Object R_ExternalPtrProt(Object x) { + if (tracer != null) { + tracer.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); + @Override + public void R_SetExternalPtrAddr(Object x, long addr) { + if (tracer != null) { + tracer.R_SetExternalPtrAddr(x, addr); } 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); + @Override + public void R_SetExternalPtrTag(Object x, Object tag) { + if (tracer != null) { + tracer.R_SetExternalPtrTag(x, tag); } 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); + @Override + public void R_SetExternalPtrProt(Object x, Object prot) { + if (tracer != null) { + tracer.R_SetExternalPtrProt(x, prot); } 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); + @Override + public REnvironment R_NewHashedEnv(REnvironment parent, String name, boolean hashed, int initialSize) { + if (tracer != null) { + tracer.R_NewHashedEnv(parent, name, hashed, initialSize); } REnvironment env = RDataFactory.createNewEnv(name, hashed, initialSize); RArguments.initializeEnclosingFrame(env.getFrame(), parent.getFrame()); return env; } + // Implementation specific support + + /** + * Called to possibly update the "complete" status on {@code x}. N.B. {@code x} may not be an + * object with a concrete {@code setComplete} method, e.g. see {@link #INTEGER(Object)}. + */ + public void setComplete(Object x, boolean complete) { + // only care about concrete vectors + if (x instanceof RVector) { + ((RVector<?>) x).setComplete(complete); + } + } + + /** + * Called when a {@link CharSXPWrapper} is expected and not found. + */ + public void logNotCharSXPWrapper(Object x) { + System.out.println("object " + x); + System.out.println("class " + x.getClass()); + } + } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFIFactory.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFIFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..d9666616f0199f060d9b5b5e9372722362f4d63a --- /dev/null +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/JavaUpCallsRFFIFactory.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014, 2016, 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.runtime.ffi; + +public class JavaUpCallsRFFIFactory extends UpCallsRFFIFactory { + + @Override + public UpCallsRFFI getUpcallsRFFI() { + return new JavaUpCallsRFFI(); + } + +} diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java index 0695d46b3a50b64b9664e158c287d9e44c03bafc..77628a0b8d8b06eba9a99ed0144e89924e0f12a6 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/RFFIVariables.java @@ -29,7 +29,6 @@ import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RUnboundValue; import com.oracle.truffle.r.runtime.env.REnvironment; -import com.oracle.truffle.r.runtime.ffi.jni.CallRFFIHelper; public enum RFFIVariables { R_Home(REnvVars.rHome()), @@ -71,7 +70,7 @@ public enum RFFIVariables { R_dot_target(RDataFactory.createSymbol(".target")), R_SrcrefSymbol(RDataFactory.createSymbol("srcref")), R_SrcfileSymbol(RDataFactory.createSymbol("srcfile")), - R_NaString(CallRFFIHelper.createCharSXP(RRuntime.STRING_NA)), + R_NaString(CharSXPWrapper.create(RRuntime.STRING_NA)), R_NaN(Double.NaN), R_PosInf(Double.POSITIVE_INFINITY), R_NegInf(Double.NEGATIVE_INFINITY), diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java index 4b79d033cce8889333b8b758dd31c16793a9f3a2..6161b0e4e724a3d1ddf555a888b9a41cf75a3858 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Grid.java @@ -24,6 +24,7 @@ package com.oracle.truffle.r.runtime.ffi.generic; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.ffi.CallRFFI; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.GridRFFI; @@ -32,46 +33,55 @@ import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; public class Generic_Grid implements GridRFFI { - private static final class GridProvider { - private static GridProvider grid; - private static DLL.SymbolHandle initGrid; - private static DLL.SymbolHandle killGrid; + private static class Generic_GridRFFINode extends GridRFFINode { + @Child private CallRFFI.CallRFFINode callRFFINode = RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode(); - @TruffleBoundary - private GridProvider() { - System.load(LibPaths.getPackageLibPath("grid")); - initGrid = DLL.findSymbol("L_initGrid", "grid", DLL.RegisteredNativeSymbol.any()); - killGrid = DLL.findSymbol("L_killGrid", "grid", DLL.RegisteredNativeSymbol.any()); - assert initGrid != DLL.SYMBOL_NOT_FOUND && killGrid != DLL.SYMBOL_NOT_FOUND; - } + private static final class GridProvider { + private static GridProvider grid; + private static DLL.SymbolHandle initGrid; + private static DLL.SymbolHandle killGrid; - static GridProvider gridProvider() { - if (grid == null) { - grid = new GridProvider(); + @TruffleBoundary + private GridProvider() { + System.load(LibPaths.getPackageLibPath("grid")); + initGrid = DLL.findSymbol("L_initGrid", "grid", DLL.RegisteredNativeSymbol.any()); + killGrid = DLL.findSymbol("L_killGrid", "grid", DLL.RegisteredNativeSymbol.any()); + assert initGrid != DLL.SYMBOL_NOT_FOUND && killGrid != DLL.SYMBOL_NOT_FOUND; + } + + static GridProvider gridProvider() { + if (grid == null) { + grid = new GridProvider(); + } + return grid; + } + + @SuppressWarnings("static-method") + long getInitGrid() { + return initGrid.asAddress(); } - return grid; - } - @SuppressWarnings("static-method") - long getInitGrid() { - return initGrid.asAddress(); + @SuppressWarnings("static-method") + long getKillGrid() { + return killGrid.asAddress(); + } } - @SuppressWarnings("static-method") - long getKillGrid() { - return killGrid.asAddress(); + @Override + public Object initGrid(REnvironment gridEvalEnv) { + long initGrid = GridProvider.gridProvider().getInitGrid(); + return callRFFINode.invokeCall(new NativeCallInfo("L_initGrid", new SymbolHandle(initGrid), DLL.findLibrary("grid")), new Object[]{gridEvalEnv}); } - } - @Override - public Object initGrid(REnvironment gridEvalEnv) { - long initGrid = GridProvider.gridProvider().getInitGrid(); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo("L_initGrid", new SymbolHandle(initGrid), DLL.findLibrary("grid")), new Object[]{gridEvalEnv}); + @Override + public Object killGrid() { + long killGrid = GridProvider.gridProvider().getKillGrid(); + return callRFFINode.invokeCall(new NativeCallInfo("L_killGrid", new SymbolHandle(killGrid), DLL.findLibrary("grid")), new Object[0]); + } } @Override - public Object killGrid() { - long killGrid = GridProvider.gridProvider().getKillGrid(); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo("L_killGrid", new SymbolHandle(killGrid), DLL.findLibrary("grid")), new Object[0]); + public GridRFFINode createGridRFFINode() { + return new Generic_GridRFFINode(); } } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java index fedd559f04c17749c46c8744e7379ad5b360870e..6b8a93ca053a86a81ca62bbd16f8e73368633144 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/generic/Generic_Tools.java @@ -30,6 +30,7 @@ import com.oracle.truffle.r.runtime.conn.RConnection; import com.oracle.truffle.r.runtime.data.RLogicalVector; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.ffi.CallRFFI; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.LibPaths; @@ -38,46 +39,59 @@ import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.ffi.ToolsRFFI; public class Generic_Tools implements ToolsRFFI { - private static final class ToolsProvider { - private static final String C_PARSE_RD = "C_parseRd"; - private static ToolsProvider tools; - private static DLL.SymbolHandle parseRd; + private static class Generic_ToolsRFFINode extends ToolsRFFINode { + @Child private CallRFFI.CallRFFINode callRFFINode = RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode(); - @TruffleBoundary - private ToolsProvider() { - System.load(LibPaths.getPackageLibPath("tools")); - parseRd = DLL.findSymbol(C_PARSE_RD, "tools", DLL.RegisteredNativeSymbol.any()); - assert parseRd != DLL.SYMBOL_NOT_FOUND; - } + private static final class ToolsProvider { + private static final String C_PARSE_RD = "C_parseRd"; + private static ToolsProvider tools; + private static DLL.SymbolHandle parseRd; + + @TruffleBoundary + private ToolsProvider() { + System.load(LibPaths.getPackageLibPath("tools")); + parseRd = DLL.findSymbol(C_PARSE_RD, "tools", DLL.RegisteredNativeSymbol.any()); + assert parseRd != DLL.SYMBOL_NOT_FOUND; + } + + static ToolsProvider toolsProvider() { + if (tools == null) { + tools = new ToolsProvider(); + } + return tools; + } - static ToolsProvider toolsProvider() { - if (tools == null) { - tools = new ToolsProvider(); + @SuppressWarnings("static-method") + long getParseRd() { + return parseRd.asAddress(); } - return tools; } - @SuppressWarnings("static-method") - long getParseRd() { - return parseRd.asAddress(); + private static final Semaphore parseRdCritical = new Semaphore(1, false); + private NativeCallInfo nativeCallInfo; + + @Override + public Object parseRd(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros, + RLogicalVector warndups) { + // The C code is not thread safe. + try { + parseRdCritical.acquire(); + long parseRd = ToolsProvider.toolsProvider().getParseRd(); + if (nativeCallInfo == null) { + nativeCallInfo = new NativeCallInfo("parseRd", new SymbolHandle(parseRd), DLL.findLibrary("tools")); + } + return callRFFINode.invokeCall(nativeCallInfo, + new Object[]{con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups}); + } catch (Throwable ex) { + throw RInternalError.shouldNotReachHere(ex, "error during Rd parsing"); + } finally { + parseRdCritical.release(); + } } } - private static final Semaphore parseRdCritical = new Semaphore(1, false); - @Override - public Object parseRd(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros, - RLogicalVector warndups) { - // The C code is not thread safe. - try { - parseRdCritical.acquire(); - long parseRd = ToolsProvider.toolsProvider().getParseRd(); - return RFFIFactory.getRFFI().getCallRFFI().invokeCall(new NativeCallInfo("parseRd", new SymbolHandle(parseRd), DLL.findLibrary("tools")), - new Object[]{con, srcfile, verbose, fragment, basename, warningCalls, macros, warndups}); - } catch (Throwable ex) { - throw RInternalError.shouldNotReachHere(ex, "error during Rd parsing"); - } finally { - parseRdCritical.release(); - } + public ToolsRFFINode createToolsRFFINode() { + return new Generic_ToolsRFFINode(); } } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java index 1928c09f73d4053f518cb777a1c8257b78451ae6..2e7a4c3d7aef66bdb52e71eaafcc12f347d7858e 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_C.java @@ -30,21 +30,27 @@ import com.oracle.truffle.r.runtime.ffi.CRFFI; import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; public class JNI_C implements CRFFI { - - /** - * This is rather similar to {@link JNI_Call}, except the objects are guaranteed to be native - * array types, no upcalls are possible, and no result is returned. However, the receiving - * function expects actual native arrays (not SEXPs), so these have to be handled on the JNI - * side. - */ - @Override - @TruffleBoundary - public synchronized void invoke(NativeCallInfo nativeCallInfo, Object[] args) { - if (traceEnabled()) { - traceDownCall(nativeCallInfo.name, args); + private static class JNI_CRFFINode extends CRFFINode { + /** + * This is rather similar to {@link JNI_Call}, except the objects are guaranteed to be + * native array types, no upcalls are possible, and no result is returned. However, the + * receiving function expects actual native arrays (not SEXPs), so these have to be handled + * on the JNI side. + */ + @Override + @TruffleBoundary + public synchronized void invoke(NativeCallInfo nativeCallInfo, Object[] args) { + if (traceEnabled()) { + traceDownCall(nativeCallInfo.name, args); + } + c(nativeCallInfo.address.asAddress(), args); } - c(nativeCallInfo.address.asAddress(), args); } private static native void c(long address, Object[] args); + + @Override + public CRFFINode createCRFFINode() { + return new JNI_CRFFINode(); + } } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java index 8ea6fac033712f9b115c3e191aef0d82a5b8b606..ee4a044a1f19a7438b001314ff4bc6c0a47718fc 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java @@ -36,6 +36,8 @@ import com.oracle.truffle.r.runtime.ffi.LibPaths; import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; import com.oracle.truffle.r.runtime.ffi.RFFIUtils; import com.oracle.truffle.r.runtime.ffi.RFFIVariables; +import com.oracle.truffle.r.runtime.ffi.UpCallsRFFI; +import com.oracle.truffle.r.runtime.ffi.UpCallsRFFIFactory; /** * The only variety in the signatures for {@code .Call} is the number of arguments. GnuR supports a @@ -47,12 +49,97 @@ import com.oracle.truffle.r.runtime.ffi.RFFIVariables; */ public class JNI_Call implements CallRFFI { - protected JNI_Call() { - loadLibrary(); + public static class JNI_CallRFFINode extends CallRFFINode { + + @Override + @TruffleBoundary + public synchronized Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args) { + long address = nativeCallInfo.address.asAddress(); + Object result = null; + if (traceEnabled()) { + traceDownCall(nativeCallInfo.name, args); + } + try { + switch (args.length) { + // @formatter:off + case 0: result = call0(address); break; + case 1: result = call1(address, args[0]); break; + case 2: result = call2(address, args[0], args[1]); break; + case 3: result = call3(address, args[0], args[1], args[2]); break; + case 4: result = call4(address, args[0], args[1], args[2], args[3]); break; + case 5: result = call5(address, args[0], args[1], args[2], args[3], args[4]); break; + case 6: result = call6(address, args[0], args[1], args[2], args[3], args[4], args[5]); break; + case 7: result = call7(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); break; + case 8: result = call8(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); break; + case 9: result = call9(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); break; + default: + result = call(address, args); break; + // @formatter:on + } + return result; + } finally { + if (traceEnabled()) { + traceDownCallReturn(nativeCallInfo.name, result); + } + } + } + + @Override + @TruffleBoundary + public synchronized void invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args) { + if (traceEnabled()) { + traceDownCall(nativeCallInfo.name, args); + } + long address = nativeCallInfo.address.asAddress(); + try { + switch (args.length) { + case 0: + callVoid0(address); + break; + case 1: + callVoid1(address, args[0]); + break; + default: + throw RInternalError.shouldNotReachHere(); + } + } finally { + if (traceEnabled()) { + traceDownCallReturn(nativeCallInfo.name, null); + } + } + } + + @Override + public synchronized void setTempDir(String tempDir) { + if (traceEnabled()) { + traceDownCall("setTempDir", tempDir); + } + RFFIVariables.setTempDir(tempDir); + nativeSetTempDir(tempDir); + if (traceEnabled()) { + traceDownCallReturn("setTempDir", null); + } + } + + @Override + public synchronized void setInteractive(boolean interactive) { + if (traceEnabled()) { + traceDownCall("setInteractive", interactive); + } + nativeSetInteractive(interactive); + if (traceEnabled()) { + traceDownCallReturn("setInteractive", null); + } + } + } private static final boolean ForceRTLDGlobal = false; + public JNI_Call() { + loadLibRLibrary(); + } + /** * Load the {@code libR} library. N.B. this library defines some non-JNI global symbols that are * referenced by C code in R packages. Unfortunately, {@link System#load(String)} uses @@ -64,13 +151,13 @@ public class JNI_Call implements CallRFFI { * {@link DLLRFFI#dlopen} is called by {@link DLL#load} which uses JNI! */ @TruffleBoundary - private static void loadLibrary() { + private static void loadLibRLibrary() { String libjnibootPath = LibPaths.getBuiltinLibPath("jniboot"); System.load(libjnibootPath); String librffiPath = LibPaths.getBuiltinLibPath("R"); try { - DLL.load(librffiPath, ForceRTLDGlobal, false); + DLL.loadLibR(librffiPath, ForceRTLDGlobal, false); } catch (DLLException ex) { throw new RInternalError(ex, "error while loading " + librffiPath); } @@ -80,7 +167,7 @@ public class JNI_Call implements CallRFFI { traceDownCall("initialize"); } try { - initialize(RFFIVariables.values()); + initialize(UpCallsRFFIFactory.getInstance().getUpcallsRFFI(), RFFIVariables.values()); } finally { if (traceEnabled()) { traceDownCallReturn("initialize", null); @@ -89,40 +176,7 @@ public class JNI_Call implements CallRFFI { } } - @Override - @TruffleBoundary - public synchronized Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args) { - long address = nativeCallInfo.address.asAddress(); - Object result = null; - if (traceEnabled()) { - traceDownCall(nativeCallInfo.name, args); - } - try { - switch (args.length) { - // @formatter:off - case 0: result = call0(address); break; - case 1: result = call1(address, args[0]); break; - case 2: result = call2(address, args[0], args[1]); break; - case 3: result = call3(address, args[0], args[1], args[2]); break; - case 4: result = call4(address, args[0], args[1], args[2], args[3]); break; - case 5: result = call5(address, args[0], args[1], args[2], args[3], args[4]); break; - case 6: result = call6(address, args[0], args[1], args[2], args[3], args[4], args[5]); break; - case 7: result = call7(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6]); break; - case 8: result = call8(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); break; - case 9: result = call9(address, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); break; - default: - result = call(address, args); break; - // @formatter:on - } - return result; - } finally { - if (traceEnabled()) { - traceDownCallReturn(nativeCallInfo.name, result); - } - } - } - - private static native void initialize(RFFIVariables[] variables); + private static native void initialize(UpCallsRFFI upCallRFFI, RFFIVariables[] variables); private static native void nativeSetTempDir(String tempDir); @@ -150,56 +204,13 @@ public class JNI_Call implements CallRFFI { private static native Object call9(long address, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, Object arg8, Object arg9); - @Override - @TruffleBoundary - public synchronized void invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args) { - if (traceEnabled()) { - traceDownCall(nativeCallInfo.name, args); - } - long address = nativeCallInfo.address.asAddress(); - try { - switch (args.length) { - case 0: - callVoid0(address); - break; - case 1: - callVoid1(address, args[0]); - break; - default: - throw RInternalError.shouldNotReachHere(); - } - } finally { - if (traceEnabled()) { - traceDownCallReturn(nativeCallInfo.name, null); - } - } - } - private static native void callVoid0(long address); private static native void callVoid1(long address, Object arg1); @Override - public synchronized void setTempDir(String tempDir) { - if (traceEnabled()) { - traceDownCall("setTempDir", tempDir); - } - RFFIVariables.setTempDir(tempDir); - nativeSetTempDir(tempDir); - if (traceEnabled()) { - traceDownCallReturn("setTempDir", null); - } - } - - @Override - public synchronized void setInteractive(boolean interactive) { - if (traceEnabled()) { - traceDownCall("setInteractive", interactive); - } - nativeSetInteractive(interactive); - if (traceEnabled()) { - traceDownCallReturn("setInteractive", null); - } + public CallRFFINode createCallRFFINode() { + return new JNI_CallRFFINode(); } } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Lapack.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Lapack.java index e6d37de0f1f956b90a964530f09c98c501ab724e..7b0a29a0be58fd01a27701d12c1644b9c192da9e 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Lapack.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Lapack.java @@ -26,77 +26,85 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.ffi.LapackRFFI; public class JNI_Lapack implements LapackRFFI { - @Override - @TruffleBoundary - public void ilaver(int[] version) { - native_ilaver(version); - } - - @Override - @TruffleBoundary - public int dgeev(char jobVL, char jobVR, int n, double[] a, int lda, double[] wr, double[] wi, double[] vl, int ldvl, double[] vr, int ldvr, double[] work, int lwork) { - return native_dgeev(jobVL, jobVR, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork); - } - - @Override - @TruffleBoundary - public int dgeqp3(int m, int n, double[] a, int lda, int[] jpvt, double[] tau, double[] work, int lwork) { - return native_dgeqp3(m, n, a, lda, jpvt, tau, work, lwork); - } - - @Override - @TruffleBoundary - public int dormqr(char side, char trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork) { - return native_dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork); - } - - @Override - @TruffleBoundary - public int dtrtrs(char uplo, char trans, char diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb) { - return native_dtrtrs(uplo, trans, diag, n, nrhs, a, lda, b, ldb); - } - - @Override - @TruffleBoundary - public int dgetrf(int m, int n, double[] a, int lda, int[] ipiv) { - return native_dgetrf(m, n, a, lda, ipiv); - } - - @Override - @TruffleBoundary - public int dpotrf(char uplo, int n, double[] a, int lda) { - return native_dpotrf(uplo, n, a, lda); + private static class JNI_LapackRFFINode extends LapackRFFINode { + @Override + @TruffleBoundary + public void ilaver(int[] version) { + native_ilaver(version); + } + + @Override + @TruffleBoundary + public int dgeev(char jobVL, char jobVR, int n, double[] a, int lda, double[] wr, double[] wi, double[] vl, int ldvl, double[] vr, int ldvr, double[] work, int lwork) { + return native_dgeev(jobVL, jobVR, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, work, lwork); + } + + @Override + @TruffleBoundary + public int dgeqp3(int m, int n, double[] a, int lda, int[] jpvt, double[] tau, double[] work, int lwork) { + return native_dgeqp3(m, n, a, lda, jpvt, tau, work, lwork); + } + + @Override + @TruffleBoundary + public int dormqr(char side, char trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork) { + return native_dormqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork); + } + + @Override + @TruffleBoundary + public int dtrtrs(char uplo, char trans, char diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb) { + return native_dtrtrs(uplo, trans, diag, n, nrhs, a, lda, b, ldb); + } + + @Override + @TruffleBoundary + public int dgetrf(int m, int n, double[] a, int lda, int[] ipiv) { + return native_dgetrf(m, n, a, lda, ipiv); + } + + @Override + @TruffleBoundary + public int dpotrf(char uplo, int n, double[] a, int lda) { + return native_dpotrf(uplo, n, a, lda); + } + + @Override + @TruffleBoundary + public int dpstrf(char uplo, int n, double[] a, int lda, int[] piv, int[] rank, double tol, double[] work) { + return native_dpstrf(uplo, n, a, lda, piv, rank, tol, work); + } + + @Override + @TruffleBoundary + public int dgesv(int n, int nrhs, double[] a, int lda, int[] ipiv, double[] b, int ldb) { + return native_dgesv(n, nrhs, a, lda, ipiv, b, ldb); + } + + @Override + @TruffleBoundary + public double dlange(char norm, int m, int n, double[] a, int lda, double[] work) { + return native_dlange(norm, m, n, a, lda, work); + } + + @Override + @TruffleBoundary + public int dgecon(char norm, int n, double[] a, int lda, double anorm, double[] rcond, double[] work, int[] iwork) { + return native_dgecon(norm, n, a, lda, anorm, rcond, work, iwork); + } + + @Override + public int dsyevr(char jobz, char range, char uplo, int n, double[] a, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, + double[] w, double[] z, int ldz, int[] isuppz, double[] work, int lwork, int[] iwork, int liwork) { + return native_dsyevr(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, isuppz, work, lwork, iwork, liwork); + } } @Override - @TruffleBoundary - public int dpstrf(char uplo, int n, double[] a, int lda, int[] piv, int[] rank, double tol, double[] work) { - return native_dpstrf(uplo, n, a, lda, piv, rank, tol, work); + public LapackRFFINode createLapackRFFINode() { + return new JNI_LapackRFFINode(); } - @Override - @TruffleBoundary - public int dgesv(int n, int nrhs, double[] a, int lda, int[] ipiv, double[] b, int ldb) { - return native_dgesv(n, nrhs, a, lda, ipiv, b, ldb); - } - - @Override - @TruffleBoundary - public double dlange(char norm, int m, int n, double[] a, int lda, double[] work) { - return native_dlange(norm, m, n, a, lda, work); - } - - @Override - @TruffleBoundary - public int dgecon(char norm, int n, double[] a, int lda, double anorm, double[] rcond, double[] work, int[] iwork) { - return native_dgecon(norm, n, a, lda, anorm, rcond, work, iwork); - } - - @Override - public int dsyevr(char jobz, char range, char uplo, int n, double[] a, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, - double[] w, double[] z, int ldz, int[] isuppz, double[] work, int lwork, int[] iwork, int liwork) { - return native_dsyevr(jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol, m, w, z, ldz, isuppz, work, lwork, iwork, liwork); - } // Checkstyle: stop method name private static native void native_ilaver(int[] version); diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_PCRE.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_PCRE.java index dda34a3c1896e369eb8799ffdd981cb4129d8688..7ddfbc4b4367672b27f892e18660395cfce4bac6 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_PCRE.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_PCRE.java @@ -28,45 +28,47 @@ import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.ffi.PCRERFFI; public class JNI_PCRE implements PCRERFFI { - @Override - public long maketables() { - return nativeMaketables(); - } + private static class JNI_PCRERFFINode extends PCRERFFINode { + @Override + public long maketables() { + return nativeMaketables(); + } - @Override - public Result compile(String pattern, int options, long tables) { - return nativeCompile(pattern, options, tables); - } + @Override + public Result compile(String pattern, int options, long tables) { + return nativeCompile(pattern, options, tables); + } - @Override - public int getCaptureCount(long code, long extra) { - int res = nativeGetCaptureCount(code, extra); - if (res < 0) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(RError.NO_CALLER, RError.Message.WRONG_PCRE_INFO, res); + @Override + public int getCaptureCount(long code, long extra) { + int res = nativeGetCaptureCount(code, extra); + if (res < 0) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(RError.NO_CALLER, RError.Message.WRONG_PCRE_INFO, res); + } + return res; } - return res; - } - @Override - public String[] getCaptureNames(long code, long extra, int captureCount) { - String[] ret = new String[captureCount]; - int res = nativeGetCaptureNames(code, extra, ret); - if (res < 0) { - CompilerDirectives.transferToInterpreter(); - throw RError.error(RError.NO_CALLER, RError.Message.WRONG_PCRE_INFO, res); + @Override + public String[] getCaptureNames(long code, long extra, int captureCount) { + String[] ret = new String[captureCount]; + int res = nativeGetCaptureNames(code, extra, ret); + if (res < 0) { + CompilerDirectives.transferToInterpreter(); + throw RError.error(RError.NO_CALLER, RError.Message.WRONG_PCRE_INFO, res); + } + return ret; } - return ret; - } - @Override - public Result study(long code, int options) { - throw RInternalError.unimplemented("pcre_study"); - } + @Override + public Result study(long code, int options) { + throw RInternalError.unimplemented("pcre_study"); + } - @Override - public int exec(long code, long extra, String subject, int offset, int options, int[] ovector) { - return nativeExec(code, extra, subject, offset, options, ovector, ovector.length); + @Override + public int exec(long code, long extra, String subject, int offset, int options, int[] ovector) { + return nativeExec(code, extra, subject, offset, options, ovector, ovector.length); + } } private static native long nativeMaketables(); @@ -80,4 +82,9 @@ public class JNI_PCRE implements PCRERFFI { private static native int nativeExec(long code, long extra, String subject, int offset, int options, int[] ovector, int ovectorLen); + @Override + public PCRERFFINode createPCRERFFINode() { + return new JNI_PCRERFFINode(); + } + } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_RAppl.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_RAppl.java index b48a2fa9c113c12f68a2632ee147f1b3c55c4287..995c4d0914be9d4c7a26355f15cf063fcc3a1cfe 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_RAppl.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_RAppl.java @@ -26,24 +26,30 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.ffi.RApplRFFI; public class JNI_RAppl implements RApplRFFI { - @Override - @TruffleBoundary - public void dqrdc2(double[] x, int ldx, int n, int p, double tol, int[] rank, double[] qraux, int[] pivot, double[] work) { - native_dqrdc2(x, ldx, n, p, tol, rank, qraux, pivot, work); + private static class JNI_RApplRFFINode extends RApplRFFINode { + @Override + @TruffleBoundary + public void dqrdc2(double[] x, int ldx, int n, int p, double tol, int[] rank, double[] qraux, int[] pivot, double[] work) { + native_dqrdc2(x, ldx, n, p, tol, rank, qraux, pivot, work); + } + + @Override + @TruffleBoundary + public void dqrcf(double[] x, int n, int k, double[] qraux, double[] y, int ny, double[] b, int[] info) { + native_dqrcf(x, n, k, qraux, y, ny, b, info); + } + + @Override + @TruffleBoundary + public void dqrls(double[] x, int n, int p, double[] y, int ny, double tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work) { + native_dqrls(x, n, p, y, ny, tol, b, rsd, qty, k, jpvt, qraux, work); + } } @Override - @TruffleBoundary - public void dqrcf(double[] x, int n, int k, double[] qraux, double[] y, int ny, double[] b, int[] info) { - native_dqrcf(x, n, k, qraux, y, ny, b, info); + public RApplRFFINode createRApplRFFINode() { + return new JNI_RApplRFFINode(); } - - @Override - @TruffleBoundary - public void dqrls(double[] x, int n, int p, double[] y, int ny, double tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work) { - native_dqrls(x, n, p, y, ny, tol, b, rsd, qty, k, jpvt, qraux, work); - } - // Checkstyle: stop method name private static native void native_dqrdc2(double[] x, int ldx, int n, int p, double tol, int[] rank, double[] qraux, int[] pivot, double[] work); diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Stats.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Stats.java index 1f0564d90b37b8bb5442bd516e71499ca3157545..0905a092aa7460837a4c2a5129f538687ba18e59 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Stats.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Stats.java @@ -29,42 +29,52 @@ import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; import com.oracle.truffle.r.runtime.ffi.StatsRFFI; -// Checkstyle: stop method name public class JNI_Stats implements StatsRFFI { - @Override - @TruffleBoundary - public void fft_factor(int n, int[] pmaxf, int[] pmaxp) { - native_fft_factor(fft_factor_address().asAddress(), n, pmaxf, pmaxp); - } - @Override - @TruffleBoundary - public int fft_work(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork) { - return native_fft_work(fft_work_address().asAddress(), a, nseg, n, nspn, isn, work, iwork); - } + public static class JNI_FFTNode extends FFTNode { + private SymbolHandle fftWorkAddress; + private SymbolHandle fftFactorAddress; - private SymbolHandle fft_factor_address; - private SymbolHandle fft_work_address; + @Override + @TruffleBoundary + public int executeWork(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork) { + initialize(); + return native_fft_work(fftWorkAddress.asAddress(), a, nseg, n, nspn, isn, work, iwork); + } + + @Override + @TruffleBoundary + public void executeFactor(int n, int[] pmaxf, int[] pmaxp) { + initialize(); + native_fft_factor(fftFactorAddress.asAddress(), n, pmaxf, pmaxp); - private SymbolHandle fft_factor_address() { - if (fft_factor_address == null) { - DLLInfo dllInfo = DLL.findLibrary("stats"); - fft_factor_address = RFFIFactory.getRFFI().getDLLRFFI().dlsym(dllInfo.handle, "fft_factor"); - assert fft_factor_address != DLL.SYMBOL_NOT_FOUND; } - return fft_factor_address; - } - private SymbolHandle fft_work_address() { - if (fft_work_address == null) { + private void initialize() { + if (fftWorkAddress == null) { + fftWorkAddress = fftAddress("fft_work"); + fftFactorAddress = fftAddress("fft_factor"); + } + } + + private static SymbolHandle fftAddress(String symbol) { + SymbolHandle fftAddress; DLLInfo dllInfo = DLL.findLibrary("stats"); - fft_work_address = RFFIFactory.getRFFI().getDLLRFFI().dlsym(dllInfo.handle, "fft_work"); - assert fft_work_address != DLL.SYMBOL_NOT_FOUND; + fftAddress = RFFIFactory.getRFFI().getDLLRFFI().dlsym(dllInfo.handle, symbol); + assert fftAddress != DLL.SYMBOL_NOT_FOUND; + return fftAddress; } - return fft_work_address; + } + @Override + public FFTNode createFFTNode() { + return new JNI_FFTNode(); + } + + // Checkstyle: stop method name private static native void native_fft_factor(long address, int n, int[] pmaxf, int[] pmaxp); private static native int native_fft_work(long address, double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork); + } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_UserRng.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_UserRng.java index 1387cb869aaaa5c1a8f649187c2aa27cf7d4a24d..e6e374a7981eb37e4eaba2cb5cc281b4a18d3185 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_UserRng.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_UserRng.java @@ -27,36 +27,44 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.ffi.UserRngRFFI; public class JNI_UserRng implements UserRngRFFI { - @Override - @TruffleBoundary - public void init(int seed) { - init(Function.Init.getSymbolHandle().asAddress(), seed); + private static class JNI_UserRngRFFINode extends UserRngRFFINode { + @Override + @TruffleBoundary + public void init(int seed) { + nativeInit(Function.Init.getSymbolHandle().asAddress(), seed); - } + } - @Override - @TruffleBoundary - public double rand() { - return rand(Function.Rand.getSymbolHandle().asAddress()); - } + @Override + @TruffleBoundary + public double rand() { + return nativeRand(Function.Rand.getSymbolHandle().asAddress()); + } - @Override - @TruffleBoundary - public int nSeed() { - return nSeed(Function.NSeed.getSymbolHandle().asAddress()); + @Override + @TruffleBoundary + public int nSeed() { + return nativeNSeed(Function.NSeed.getSymbolHandle().asAddress()); + } + + @Override + @TruffleBoundary + public void seeds(int[] n) { + nativeSeeds(Function.Seedloc.getSymbolHandle().asAddress(), n); + } } @Override - @TruffleBoundary - public void seeds(int[] n) { - seeds(Function.Seedloc.getSymbolHandle().asAddress(), n); + public UserRngRFFINode createUserRngRFFINode() { + return new JNI_UserRngRFFINode(); } - private static native void init(long address, int seed); + private static native void nativeInit(long address, int seed); + + private static native double nativeRand(long address); - private static native double rand(long address); + private static native int nativeNSeed(long address); - private static native int nSeed(long address); + private static native void nativeSeeds(long address, int[] n); - private static native void seeds(long address, int[] n); } diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/TraceUpCallsAdapter.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/TraceUpCallsAdapter.java new file mode 100644 index 0000000000000000000000000000000000000000..1b6d8aab816bc180e5a361d2e3311c02d40e3749 --- /dev/null +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/TraceUpCallsAdapter.java @@ -0,0 +1,893 @@ +/* + * Copyright (c) 2016, 2016, 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.runtime.ffi.jni; + +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RExternalPtr; +import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RLogicalVector; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.ffi.RFFIUtils; +import com.oracle.truffle.r.runtime.ffi.UpCallsRFFI; + +public class TraceUpCallsAdapter implements UpCallsRFFI { + @Override + public RIntVector Rf_ScalarInteger(int value) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_ScalarInteger", value); + } + return null; + } + + @Override + public RLogicalVector Rf_ScalarLogical(int value) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_ScalarLogical", value); + } + return null; + } + + @Override + public RDoubleVector Rf_ScalarDouble(double value) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_ScalarDouble", value); + } + return null; + } + + @Override + public RStringVector Rf_ScalarString(Object value) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_ScalarString", value); + } + return null; + } + + @Override + public int Rf_asInteger(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_asInteger", x); + } + return 0; + } + + @Override + public double Rf_asReal(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_asReal", x); + } + return 0; + } + + @Override + public int Rf_asLogical(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_asLogical", x); + } + return 0; + } + + @Override + public Object Rf_asChar(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_asChar", x); + } + return null; + } + + @Override + public Object Rf_mkCharLenCE(byte[] bytes, int encoding) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_mkCharLenCE", bytes); + } + return null; + } + + @Override + public Object Rf_cons(Object car, Object cdr) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_cons", car, cdr); + } + return null; + } + + @Override + public void Rf_defineVar(Object symbolArg, Object value, Object envArg) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_defineVar", symbolArg, value, envArg); + } + } + + @Override + public Object R_do_MAKE_CLASS(String clazz) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_do_MAKE_CLASS", clazz); + } + return null; + } + + @Override + public Object Rf_findVar(Object symbolArg, Object envArg) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_findVar", symbolArg, envArg); + } + return null; + } + + @Override + public Object Rf_findVarInFrame(Object envArg, Object symbolArg) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_findVarInFrame", envArg, symbolArg); + } + return null; + } + + @Override + public Object Rf_findVarInFrame3(Object envArg, Object symbolArg, int doGet) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_findVarInFrame3", envArg, symbolArg); + } + return null; + } + + @Override + public Object Rf_getAttrib(Object obj, Object name) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_getAttrib", obj, name); + } + return null; + } + + @Override + public void Rf_setAttrib(Object obj, Object name, Object val) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_setAttrib", obj, name, val); + } + } + + @Override + public int Rf_inherits(Object x, String clazz) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_inherits", x, clazz); + } + return 0; + } + + @Override + public Object Rf_install(String name) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_install", name); + } + return null; + } + + @Override + public Object Rf_lengthgets(Object x, int newSize) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_lengthgets", x, newSize); + } + return null; + } + + @Override + public int Rf_isString(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_isString", x); + } + return 0; + } + + @Override + public int Rf_isNull(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_isNull", x); + } + return 0; + } + + @Override + public Object Rf_PairToVectorList(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_PairToVectorList", x); + } + return null; + } + + @Override + public void Rf_error(String msg) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_error", msg); + } + } + + @Override + public void Rf_warning(String msg) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_warning", msg); + } + } + + @Override + public void Rf_warningcall(Object call, String msg) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_warningcall", call, msg); + } + } + + @Override + public Object Rf_allocateVector(int mode, int n) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_allocateVector", mode, n); + } + return null; + } + + @Override + public Object Rf_allocateArray(int mode, Object dimsObj) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_allocateArray", mode, dimsObj); + } + return null; + } + + @Override + public Object Rf_allocateMatrix(int mode, int nrow, int ncol) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_allocateMatrix", mode, ncol, nrow); + } + return null; + } + + @Override + public int Rf_nrows(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_nrows", x); + } + return 0; + } + + @Override + public int Rf_ncols(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_ncols", x); + } + return 0; + } + + @Override + public int LENGTH(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("LENGTH", x); + } + return 0; + } + + @Override + public void SET_STRING_ELT(Object x, int i, Object v) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SET_STRING_ELT", x, i, v); + } + } + + @Override + public void SET_VECTOR_ELT(Object x, int i, Object v) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SET_VECTOR_ELT", i, v); + } + } + + @Override + public Object RAW(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("RAW", x); + } + return null; + } + + @Override + public Object LOGICAL(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("LOGICAL", x); + } + return null; + } + + @Override + public Object INTEGER(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("INTEGER", x); + } + return null; + } + + @Override + public Object REAL(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("REAL", x); + } + return null; + } + + @Override + public Object STRING_ELT(Object x, int i) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("STRING_ELT", x, i); + } + return null; + } + + @Override + public Object VECTOR_ELT(Object x, int i) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("VECTOR_ELT", x, i); + } + return null; + } + + @Override + public int NAMED(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("NAMED", x); + } + return 0; + } + + @Override + public Object SET_TYPEOF_FASTR(Object x, int v) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SET_TYPEOF_FASTR", x, v); + } + return null; + } + + @Override + public int TYPEOF(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("TYPEOF", x); + } + return 0; + } + + @Override + public int OBJECT(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("OBJECT", x); + } + return 0; + } + + @Override + public Object Rf_duplicate(Object x, int deep) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_duplicate", x, deep); + } + return null; + } + + @Override + public int Rf_anyDuplicated(Object x, int fromLast) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_anyDuplicated", x, fromLast); + } + return 0; + } + + @Override + public Object PRINTNAME(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("PRINTNAME", x); + } + return null; + } + + @Override + public Object TAG(Object e) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("TAG", e); + } + return null; + } + + @Override + public Object CAR(Object e) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("CAR", e); + } + return null; + } + + @Override + public Object CDR(Object e) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("CDR", e); + } + return null; + } + + @Override + public Object CADR(Object e) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("CADR", e); + } + return null; + } + + @Override + public Object CADDR(Object e) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("CADDR", e); + } + return null; + } + + @Override + public Object CDDR(Object e) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("CDDR", e); + } + return null; + } + + @Override + public Object SET_TAG(Object x, Object y) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SET_TAG", x, y); + } + return null; + } + + @Override + public Object SETCAR(Object x, Object y) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SETCAR", x, y); + } + return null; + } + + @Override + public Object SETCDR(Object x, Object y) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SETCDR", x, y); + } + return null; + } + + @Override + public Object SETCADR(Object x, Object y) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SETCADR", x); + } + return null; + } + + @Override + public Object SYMVALUE(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SYMVALUE", x); + } + return null; + } + + @Override + public void SET_SYMVALUE(Object x, Object v) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SET_SYMVALUE", x, v); + } + } + + @Override + public int R_BindingIsLocked(Object sym, Object env) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_BindingIsLocked", sym, env); + } + return 0; + } + + @Override + public Object R_FindNamespace(Object name) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_FindNamespace", name); + } + return null; + } + + @Override + public Object Rf_eval(Object expr, Object env) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_eval", expr, env); + } + return null; + } + + @Override + public Object Rf_findfun(Object symbolObj, Object envObj) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_findfun", symbolObj, envObj); + } + return null; + } + + @Override + public Object Rf_GetOption1(Object tag) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_GetOption1", tag); + } + return null; + } + + @Override + public void Rf_gsetVar(Object symbol, Object value, Object rho) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_gsetVar", symbol, value, rho); + } + } + + @Override + public void DUPLICATE_ATTRIB(Object to, Object from) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("DUPLICATE_ATTRIB", to, from); + } + } + + @Override + public int R_computeIdentical(Object x, Object y, int flags) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_computeIdentical", x, y, flags); + } + return 0; + } + + @Override + public void Rf_copyListMatrix(Object s, Object t, int byrow) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_copyListMatrix", t, byrow); + } + } + + @Override + public void Rf_copyMatrix(Object s, Object t, int byrow) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_copyMatrix", t, byrow); + } + } + + @Override + public Object R_tryEval(Object expr, Object env, boolean silent) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_tryEval", expr, env, silent); + } + return null; + } + + @Override + public Object R_ToplevelExec() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_TopLevelExec"); + } + return null; + } + + @Override + public int RDEBUG(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("RDEBUG", x); + } + return 0; + } + + @Override + public void SET_RDEBUG(Object x, int v) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SET_RDEBUG", x, v); + } + } + + @Override + public int RSTEP(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("RSTEP", x); + } + return 0; + } + + @Override + public void SET_RSTEP(Object x, int v) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("SET_RSTEP", x, v); + } + } + + @Override + public Object ENCLOS(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("ENCLOS", x); + } + return null; + } + + @Override + public Object PRVALUE(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("PRVALUE", x); + } + return null; + } + + @Override + public Object R_ParseVector(Object text, int n, Object srcFile) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_ParseVector", text, n, srcFile); + } + return null; + } + + @Override + public Object R_lsInternal3(Object envArg, int allArg, int sortedArg) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_lsInternal3", envArg, allArg, sortedArg); + } + return null; + } + + @Override + public String R_HomeDir() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_HomeDir"); + } + return null; + } + + @Override + public void R_CleanUp(int sa, int status, int runlast) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_Cleanup", sa, status, runlast); + } + } + + @Override + public Object R_GlobalContext() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_GlobalContext"); + } + return null; + } + + @Override + public Object R_GlobalEnv() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_GlobalEnv"); + } + return null; + } + + @Override + public Object R_BaseEnv() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_BaseEnv"); + } + return null; + } + + @Override + public Object R_BaseNamespace() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_BaseNamespace"); + } + return null; + } + + @Override + public Object R_NamespaceRegistry() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_NamespaceRegistry"); + } + return null; + } + + @Override + public int isInteractive() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("isInteractive"); + } + return 0; + } + + @Override + public int isS4Object(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("isS4Object"); + } + return 0; + } + + @Override + public void Rprintf(String message) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rprintf", message); + } + } + + @Override + public void GetRNGstate() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("GetRNGstate"); + } + } + + @Override + public void PutRNGstate() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("PutRNGstate"); + } + } + + @Override + public double unif_rand() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("unif_rand"); + } + return 0; + } + + @Override + public Object R_getGlobalFunctionContext() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_getGlobalFunctionContext"); + } + return null; + } + + @Override + public Object R_getParentFunctionContext(Object c) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_getParentFunctionContext"); + } + return null; + } + + @Override + public Object R_getContextEnv(Object c) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_getContextEnv", c); + } + return null; + } + + @Override + public Object R_getContextFun(Object c) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_getContextFun", c); + } + return null; + } + + @Override + public Object R_getContextCall(Object c) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_getContextCall", c); + } + return null; + } + + @Override + public Object R_getContextSrcRef(Object c) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_getContextSrcRef", c); + } + return null; + } + + @Override + public int R_insideBrowser() { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_insideBrowser"); + } + return 0; + } + + @Override + public int R_isGlobal(Object c) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_isGlobal", c); + } + return 0; + } + + @Override + public int R_isEqual(Object x, Object y) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("isEqual", x, y); + } + return 0; + } + + @Override + public Object Rf_classgets(Object x, Object y) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("Rf_classgets", x, y); + } + return null; + } + + @Override + public RExternalPtr R_MakeExternalPtr(long addr, Object tag, Object prot) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_MakeExternalPtr", addr, tag, prot); + } + return null; + } + + @Override + public long R_ExternalPtrAddr(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_ExternalPtrAddr", x); + } + return 0; + } + + @Override + public Object R_ExternalPtrTag(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_ExternalPtrTag", x); + } + return null; + } + + @Override + public Object R_ExternalPtrProt(Object x) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_ExternalPtrProt", x); + } + return null; + } + + @Override + public void R_SetExternalPtrAddr(Object x, long addr) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_SetExternalPtrAddr", x); + } + } + + @Override + public void R_SetExternalPtrTag(Object x, Object tag) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_SetExternalPtrTag", x); + } + } + + @Override + public void R_SetExternalPtrProt(Object x, Object prot) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_ExternalPtrProt", x); + } + } + + @Override + public REnvironment R_NewHashedEnv(REnvironment parent, String name, boolean hashed, int initialSize) { + if (RFFIUtils.traceEnabled()) { + RFFIUtils.traceUpCall("R_NewHashedEnv", parent, name, hashed, initialSize); + } + return null; + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java index f5a84fb5c59a96e77b0457446cf562667c2ac246..13475477da4af40a519467e8e5d31948d45e7923 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java @@ -35,7 +35,6 @@ import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributeStorage; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java index 60e498c60ee86bacb2f327409f5b0dc46f36c249..9337e810d8a898aa8f6c1257525fdbbbdce62cdb 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java @@ -594,6 +594,7 @@ public final class RError extends RuntimeException { UNIMPLEMENTED_ARG_TYPE("unimplemented argument type (arg %d)"), C_SYMBOL_NOT_IN_TABLE("C symbol name \"%s\" not in load table"), FORTRAN_SYMBOL_NOT_IN_TABLE("Fortran symbol name \"%s\" not in load table"), + SYMBOL_NOT_IN_TABLE("\"%s\" not available for .%s() for package \"%s\""), NOT_THAT_MANY_FRAMES("not that many frames on the stack"), UNIMPLEMENTED_ARGUMENT_TYPE("unimplemented argument type"), MUST_BE_SQUARE_NUMERIC("'%s' must be a square numeric matrix"), @@ -760,7 +761,9 @@ public final class RError extends RuntimeException { GAP_MUST_BE_NON_NEGATIVE("'gap' must be non-negative integer"), WRONG_PCRE_INFO("'pcre_fullinfo' returned '%d' "), BAD_FUNCTION_EXPR("badly formed function expression"), - FIRST_ELEMENT_ONLY("only first element of '%s' argument used"); + FIRST_ELEMENT_ONLY("only first element of '%s' argument used"), + MUST_BE_GE_ONE("'%s' must be of length >= 1"), + MORE_THAN_ONE_MATCH("there is more than one match in '%s'"); public final String message; final boolean hasArgs; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java index 7a4a01cd501f6eca13e219621a21fff3466dc094..835b3d36e23b921d01ad2515f07ee8173188d363 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime; +import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.r.runtime.context.Engine; @@ -90,6 +91,12 @@ public interface RRuntimeASTAccess { */ RLanguage getSyntaxCaller(RCaller rl); + /** + * Gets {@code TruffleRLanguage} avoiding project circularity. + */ + @SuppressWarnings("rawtypes") + Class<? extends TruffleLanguage> getTruffleRLanguage(); + /** * Returns a string for a call as represented by {@code rl}, returned originally by * {@link #getSyntaxCaller}. 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 ff6d84758b526a9a736b6bb7afe2e83c2be3fafd..88c9bc23ee170a940db7ad22673a263e0f771b9d 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 @@ -41,7 +41,6 @@ import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDataFactory; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java index fe0a57bac502c4d7f5fb31cd1a4cfe03f82e17c7..9ee98c9d78bcde430d2e58bc088703ab50ada1bf 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java @@ -44,7 +44,7 @@ public enum RType { DefunctReal("real", -1), DefunctSingle("single", -1), ExternalPtr("externalptr", -1), - S4Object("s4object", -1), + S4Object("S4", -1), Connection("connection", -1), Dots("...", -1); @@ -160,7 +160,7 @@ public enum RType { return DefunctSingle; case "externalptr": return ExternalPtr; - case "s4object": + case "S4": return S4Object; case "connection": return Connection; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java index 050047c15b04f035d312d4198db3e90ed37d70d7..fcc8f9710fb7126add02d5490531426fe29d5974 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/TempPathName.java @@ -68,7 +68,7 @@ public class TempPathName { } else { Utils.rSuicide("cannot create 'R_TempDir'"); } - RFFIFactory.getRFFI().getCallRFFI().setTempDir(tempDirPath); + RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode().setTempDir(tempDirPath); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java index a0f6d36b867504ad6a268ad5117452ca4f91f07a..b699372ccaae032d19a0777b141c5d47ba662ce7 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/conn/RConnection.java @@ -30,7 +30,6 @@ import java.util.LinkedList; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.object.DynamicObject; -import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.conn.ConnectionSupport.BaseRConnection; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributesLayout; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java index ee4a98fe34d52fe214e9782ea9bbce56594ea2f5..068f49fbdfadf00ed3caae3e9556fd2ae9680bfb 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java @@ -76,6 +76,7 @@ import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.RFFIContextStateFactory; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; import com.oracle.truffle.r.runtime.instrument.InstrumentationState; @@ -447,6 +448,7 @@ public final class RContext extends ExecutionContext implements TruffleObject { public final LazyDBCache.ContextStateImpl stateLazyDBCache; public final InstrumentationState stateInstrumentation; public final ContextStateImpl stateInternalCode; + public final DLL.ContextStateImpl stateDLL; /** * RFFI implementation state. Cannot be final as choice of FFI implementation is not made at the * time the constructor is called. @@ -457,7 +459,7 @@ public final class RContext extends ExecutionContext implements TruffleObject { private ContextState[] contextStates() { return new ContextState[]{stateREnvVars, stateRProfile, stateROptions, stateREnvironment, stateRErrorHandling, stateRConnection, stateStdConnections, stateRNG, stateRFFI, stateRSerialize, - stateLazyDBCache, stateInstrumentation}; + stateLazyDBCache, stateInstrumentation, stateDLL}; } public static void setEmbedded() { @@ -501,8 +503,8 @@ public final class RContext extends ExecutionContext implements TruffleObject { this.stateLazyDBCache = LazyDBCache.ContextStateImpl.newContextState(); this.stateInstrumentation = InstrumentationState.newContextState(instrumenter); this.stateInternalCode = ContextStateImpl.newContextState(); + this.stateDLL = DLL.ContextStateImpl.newContextState(); this.engine = RContext.getRRuntimeASTAccess().createEngine(this); - state.add(State.CONSTRUCTED); } @@ -559,13 +561,14 @@ public final class RContext extends ExecutionContext implements TruffleObject { stateRConnection.initialize(this); stateStdConnections.initialize(this); stateRNG.initialize(this); - this.stateRFFI = RFFIContextStateFactory.newContextState().initialize(this); - + stateRFFI = RFFIContextStateFactory.newContextState(); + // separate in case initialize calls getStateRFFI()! stateRFFI.initialize(this); stateRSerialize.initialize(this); stateLazyDBCache.initialize(this); stateInstrumentation.initialize(this); stateInternalCode.initialize(this); + stateDLL.initialize(this); state.add(State.INITIALIZED); if (!embedded) { @@ -584,7 +587,7 @@ public final class RContext extends ExecutionContext implements TruffleObject { this.methodTableDispatchOn = info.getParent().methodTableDispatchOn; } if (initial && !embedded) { - RFFIFactory.getRFFI().getCallRFFI().setInteractive(isInteractive()); + RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode().setInteractive(isInteractive()); initialContextInitialized = true; } return this; @@ -824,6 +827,11 @@ public final class RContext extends ExecutionContext implements TruffleObject { return RContext.getInstance().engine; } + public ContextState getStateRFFI() { + assert stateRFFI != null; + return stateRFFI; + } + public PolyglotEngine getVM() { return info.getVM(); } @@ -844,6 +852,10 @@ public final class RContext extends ExecutionContext implements TruffleObject { return exportedSymbols; } + public void addExportedSymbol(String name, TruffleObject obj) { + exportedSymbols.put(name, obj); + } + public TimeZone getSystemTimeZone() { return info.getSystemTimeZone(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RForeignAccessFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RForeignAccessFactory.java index d05f96d5ec35693c48cbf238b01fdffe6f34d930..d5732acff89aa0c8213f3b1c59fe3220f4b677f3 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RForeignAccessFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RForeignAccessFactory.java @@ -28,7 +28,13 @@ import com.oracle.truffle.r.runtime.data.RTruffleObject; public interface RForeignAccessFactory { - ForeignAccess getForeignAccess(RTruffleObject value); + /** + * Return the appropriate {@link ForeignAccess} instance for {@code obj}. + */ + ForeignAccess getForeignAccess(RTruffleObject obj); + /** + * Return the {@link TruffleLanguage} instance for R. (Project circularity workaround). + */ Class<? extends TruffleLanguage<RContext>> getTruffleLanguage(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java index 6d1ed9e4e3e8da595a2591307208691b93364e0a..2fcc8fee9eb0465109998dde9517ad8123ffda69 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java @@ -142,7 +142,7 @@ public interface RAttributable extends RTypedValue { * initialized and will be just cleared, unless nullify is {@code true}. * * @param nullify Some implementations can force nullifying attributes instance if this flag is - * set to {@code true}. Nullifying is not guaranteed for al implementations. + * set to {@code true}. Nullifying is not guaranteed for all implementations. */ default void resetAllAttributes(boolean nullify) { DynamicObject attributes = getAttributes(); @@ -164,6 +164,10 @@ public interface RAttributable extends RTypedValue { return (RStringVector) getAttr(profiles, RRuntime.CLASS_ATTR_KEY); } + default RStringVector getClassAttr() { + return (RStringVector) getAttr(RRuntime.CLASS_ATTR_KEY); + } + /** * Returns {@code true} if and only if the value has a {@code class} attribute added explicitly. * When {@code true}, it is possible to call {@link RAttributable#getClassHierarchy()}. @@ -172,6 +176,10 @@ public interface RAttributable extends RTypedValue { return getClassAttr(profiles) != null ? true : false; } + default boolean isObject() { + return getClassAttr() != null ? true : false; + } + static void copyAttributes(RAttributable obj, DynamicObject attrs) { if (attrs == null) { return; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java index 70c54ef9df0bf9ac8ab717578d672f8fc221402a..8f35974969087a286e79230a3b7af3788e483ff2 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributesLayout.java @@ -27,7 +27,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.object.DynamicObject; @@ -59,12 +58,13 @@ public final class RAttributesLayout { private static final AttrsLayout NAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.NAMES_ATTR_KEY); private static final AttrsLayout DIM_ATTRS_LAYOUT = new AttrsLayout(RRuntime.DIM_ATTR_KEY); private static final AttrsLayout DIMNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.DIMNAMES_ATTR_KEY); + private static final AttrsLayout ROWNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.ROWNAMES_ATTR_KEY); private static final AttrsLayout NAMES_AND_DIM_ATTRS_LAYOUT = new AttrsLayout(RRuntime.NAMES_ATTR_KEY, RRuntime.DIM_ATTR_KEY); private static final AttrsLayout DIM_AND_DIMNAMES_ATTRS_LAYOUT = new AttrsLayout(RRuntime.DIM_ATTR_KEY, RRuntime.DIMNAMES_ATTR_KEY); private static final AttrsLayout CLASS_AND_CONNID_ATTRS_LAYOUT = new AttrsLayout(RRuntime.CLASS_ATTR_KEY, RRuntime.CONN_ID_ATTR_KEY); - public static final AttrsLayout[] LAYOUTS = {EMPTY_ATTRS_LAYOUT, CLASS_ATTRS_LAYOUT, NAMES_ATTRS_LAYOUT, DIM_ATTRS_LAYOUT, DIMNAMES_ATTRS_LAYOUT, NAMES_AND_DIM_ATTRS_LAYOUT, - DIM_AND_DIMNAMES_ATTRS_LAYOUT}; + public static final AttrsLayout[] LAYOUTS = {EMPTY_ATTRS_LAYOUT, CLASS_ATTRS_LAYOUT, NAMES_ATTRS_LAYOUT, DIM_ATTRS_LAYOUT, DIMNAMES_ATTRS_LAYOUT, ROWNAMES_ATTRS_LAYOUT, + NAMES_AND_DIM_ATTRS_LAYOUT, DIM_AND_DIMNAMES_ATTRS_LAYOUT}; private static final Map<String, ConstantShapesAndProperties> constantShapesAndLocationsForAttribute = new HashMap<>(); @@ -114,6 +114,13 @@ public final class RAttributesLayout { new Property[]{ CLASS_AND_CONNID_ATTRS_LAYOUT.properties[0] })); + constantShapesAndLocationsForAttribute.put(RRuntime.ROWNAMES_ATTR_KEY, new ConstantShapesAndProperties( + new Shape[]{ + ROWNAMES_ATTRS_LAYOUT.shape + }, + new Property[]{ + ROWNAMES_ATTRS_LAYOUT.properties[0] + })); } @@ -147,6 +154,10 @@ public final class RAttributesLayout { return DIMNAMES_ATTRS_LAYOUT.factory.newInstance(dimNames); } + public static DynamicObject createRowNames(Object rowNames) { + return ROWNAMES_ATTRS_LAYOUT.factory.newInstance(rowNames); + } + public static DynamicObject createNamesAndDim(Object names, Object dim) { return NAMES_AND_DIM_ATTRS_LAYOUT.factory.newInstance(names, dim); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java index 94d1d71fb49c3ac82b4b3f74a69a2f5fa3e18356..65d16aef9b115d138c0defe6e90f03ab43125e2b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java @@ -47,14 +47,14 @@ public class RExpression extends RListBase implements RAbstractVector { @Override protected RExpression internalCopy() { - return new RExpression(Arrays.copyOf(data, data.length), dimensions, null); + return new RExpression(Arrays.copyOf(data, data.length), getDimensions(), null); } @Override protected RExpression internalDeepCopy() { // TOOD: only used for nested list updates, but still could be made faster (through a // separate AST node?) - RExpression listCopy = new RExpression(Arrays.copyOf(data, data.length), dimensions, null); + RExpression listCopy = new RExpression(Arrays.copyOf(data, data.length), getDimensions(), null); for (int i = 0; i < listCopy.getLength(); i++) { Object el = listCopy.getDataAt(i); if (el instanceof RVector) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java index dd1d78c81978adf1ae7cd562a1042a5c9c0e90e1..cd52a76a925b0dc067d7554f1c8ea060c24942f1 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java @@ -196,7 +196,7 @@ public class RLanguage extends RSharingAttributeStorage implements RAbstractCont } @Override - public void setNames(RStringVector newNames) { + public final void setNames(RStringVector newNames) { if (list == null) { /* See getNames */ RContext.getRRuntimeASTAccess().setNames(this, newNames); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java index dd97f6ea0d42c018c7089d82c5b38b1a1609dddd..8632d8f56dbb440bf7ed0b0722ea33c34bc0a5cd 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RList.java @@ -44,14 +44,14 @@ public final class RList extends RListBase implements RAbstractListVector { @Override protected RList internalCopy() { - return new RList(Arrays.copyOf(data, data.length), dimensions, null); + return new RList(Arrays.copyOf(data, data.length), getDimensions(), null); } @Override protected RList internalDeepCopy() { // TOOD: only used for nested list updates, but still could be made faster (through a // separate AST node?) - RList listCopy = new RList(Arrays.copyOf(data, data.length), dimensions, null); + RList listCopy = new RList(Arrays.copyOf(data, data.length), getDimensions(), null); for (int i = 0; i < listCopy.getLength(); i++) { Object el = listCopy.getDataAt(i); if (el instanceof RVector) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java index 4ed316e9098910dadca1a832ced61ce207fdfee0..537d54d73051c4026054cb467d2661f4b271bf06 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RListBase.java @@ -146,6 +146,7 @@ public abstract class RListBase extends RVector<Object[]> implements RAbstractLi @TruffleBoundary public final Object getNameAt(int index) { + RStringVector names = getNamesFromAttrs(); if (names != null && names != null) { String name = names.getDataAt(index); if (name == RRuntime.STRING_NA) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java index fabe9e5c925816dc58e278f0f2cd4aef95f55b2b..4b514edb83a7774ebb4e417fa35b4ab3373beb86 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java @@ -329,7 +329,7 @@ public class RPairList extends RSharingAttributeStorage implements RAbstractCont } @Override - public void setNames(RStringVector newNames) { + public final void setNames(RStringVector newNames) { Object p = this; for (int i = 0; i < newNames.getLength() && !isNull(p); i++) { RPairList pList = (RPairList) p; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRaw.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRaw.java index a18f274d43736e0c7e9936de1eaa8d6adf0aa544..138c53d05712073d0e6941b8a566ef0c2db40e20 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRaw.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RRaw.java @@ -22,10 +22,10 @@ */ package com.oracle.truffle.r.runtime.data; -import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.data.closures.RClosures; import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -100,8 +100,7 @@ public final class RRaw extends RScalarVector implements RAbstractRawVector { @Override public String toString() { - CompilerAsserts.neverPartOfCompilation(); - return String.format("%02x", value); + return Utils.stringFormat("%02x", value); } public static RRaw valueOf(byte value) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java index 4d9c43afdf1371f48b3e288e73d3c4bd153d17de..310bde8f45d7ac97bb6a82e9f6275a0cf11847a2 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java @@ -33,7 +33,6 @@ import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.SuppressFBWarnings; -import com.oracle.truffle.r.runtime.data.RAttributesLayout.RAttribute; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -60,18 +59,10 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement private static final RStringVector implicitClassHeaderMatrix = RDataFactory.createStringVector(new String[]{RType.Matrix.getName()}, true); protected boolean complete; // "complete" means: does not contain NAs - protected int[] dimensions; - protected RStringVector names; - private RList dimNames; - // cache rownames for data frames as they are accessed at every data frame access - private Object rowNames; protected RVector(boolean complete, int length, int[] dimensions, RStringVector names) { this.complete = complete; - this.dimensions = dimensions; assert names != this; - this.names = names; - this.rowNames = RNull.instance; if (names != null) { // since this constructor is for internal use only, the assertion shouldn't fail assert names.getLength() == length : "size mismatch: " + names.getLength() + " vs. " + length; @@ -85,7 +76,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement // one-dimensional arrays do not have names, only dimnames with one value RList newDimNames = RDataFactory.createList(new Object[]{names}); initAttributes(RAttributesLayout.createDimAndDimNames(dimensionsVector, newDimNames)); - this.dimNames = newDimNames; } } } else { @@ -95,6 +85,39 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } } + private int[] getDimensionsFromAttrs() { + if (attributes == null) { + return null; + } else { + RIntVector dims = (RIntVector) attributes.get(RRuntime.DIM_ATTR_KEY); + return dims == null ? null : dims.getInternalStore(); + } + } + + private RList getDimNamesFromAttrs() { + if (attributes == null) { + return null; + } else { + return (RList) attributes.get(RRuntime.DIMNAMES_ATTR_KEY); + } + } + + private Object getRowNamesFromAttrs() { + if (attributes == null) { + return null; + } else { + return attributes.get(RRuntime.ROWNAMES_ATTR_KEY); + } + } + + protected final RStringVector getNamesFromAttrs() { + if (attributes == null) { + return null; + } else { + return (RStringVector) attributes.get(RRuntime.NAMES_ATTR_KEY); + } + } + /** * Intended for external calls where a mutable copy is needed. */ @@ -127,36 +150,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final int[] getInternalDimensions() { - return dimensions; - } - - public final void setInternalDimensions(int[] newDimensions) { - dimensions = newDimensions; - } - - public final RStringVector getInternalNames() { - return names; - } - - public final void setInternalNames(RStringVector newNames) { - assert newNames != this; - names = newNames; - } - - public final RList getInternalDimNames() { - return dimNames; - } - - public final void setInternalDimNames(RList newDimNames) { - dimNames = newDimNames; - } - - public final Object getInternalRowNames() { - return rowNames; - } - - public final void setInternalRowNames(Object newRowNames) { - rowNames = newRowNames; + return getDimensionsFromAttrs(); } @Override @@ -179,7 +173,9 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement if (attrProfiles.attrNullProfile(attributes == null)) { return null; } else { + RStringVector names = getNamesFromAttrs(); if (attrProfiles.attrNullNamesProfile(names == null)) { + RList dimNames = getDimNames(); if (dimNames != null && dimNames.getLength() == 1) { return (RStringVector) dimNames.getDataAt(0); } else { @@ -196,7 +192,9 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement * performance-critical) */ public final RStringVector getNames() { + RStringVector names = getNamesFromAttrs(); if (names == null) { + RList dimNames = getDimNames(); if (dimNames != null && dimNames.getLength() == 1) { return (RStringVector) dimNames.getDataAt(0); } else { @@ -212,6 +210,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement if (getNames(attrProfiles) == null) { return -1; } + RStringVector names = getNamesFromAttrs(); for (int i = 0; i < names.getLength(); i++) { if (names.getDataAt(i).equals(name)) { return i; @@ -232,6 +231,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } boolean oneMatch = false; int match = -1; + RStringVector names = getNamesFromAttrs(); for (int i = 0; i < names.getLength(); i++) { if (names.getDataAt(i).startsWith(name)) { if (oneMatch) { @@ -339,7 +339,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement putAttribute(RRuntime.NAMES_ATTR_KEY, newNames); } assert newNames != this; - this.names = newNames; } @Override @@ -354,22 +353,20 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement // whether it's one dimensional array or not, assigning null always removes the "names" // attribute removeAttributeMapping(RRuntime.NAMES_ATTR_KEY); - this.names = null; } else if (newNames != null) { if (newNames.getLength() > this.getLength()) { throw RError.error(invokingNode, RError.Message.ATTRIBUTE_VECTOR_SAME_LENGTH, RRuntime.NAMES_ATTR_KEY, newNames.getLength(), this.getLength()); } - if (this.dimensions != null && dimensions.length == 1) { + int[] dimensions = getDimensionsFromAttrs(); + if (dimensions != null && dimensions.length == 1) { // for one dimensional array, "names" is really "dimnames[[1]]" (see R documentation // for "names" function) RList newDimNames = RDataFactory.createList(new Object[]{newNames}); newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; putAttribute(RRuntime.DIMNAMES_ATTR_KEY, newDimNames); - this.dimNames = newDimNames; } else { putAttribute(RRuntime.NAMES_ATTR_KEY, newNames); assert newNames != this; - this.names = newNames; } } } @@ -380,7 +377,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final RList getDimNames() { - return dimNames; + return getDimNamesFromAttrs(); } /** @@ -394,7 +391,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } else { putAttribute(RRuntime.DIMNAMES_ATTR_KEY, newDimNames); } - this.dimNames = newDimNames; } @Override @@ -407,8 +403,8 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement private void setDimNames(RList newDimNames, RBaseNode invokingNode) { if (attributes != null && newDimNames == null) { removeAttributeMapping(RRuntime.DIMNAMES_ATTR_KEY); - this.dimNames = null; } else if (newDimNames != null) { + int[] dimensions = getDimensionsFromAttrs(); if (dimensions == null) { throw RError.error(invokingNode, RError.Message.DIMNAMES_NONARRAY); } @@ -445,7 +441,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } putAttribute(RRuntime.DIMNAMES_ATTR_KEY, resDimNames); resDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; - this.dimNames = resDimNames; } } @@ -455,17 +450,16 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final Object getRowNames() { - return rowNames; + Object rn = getRowNamesFromAttrs(); + return rn == null ? RNull.instance : rn; } @Override public final void setRowNames(RAbstractVector newRowNames) { if (newRowNames == null) { removeAttributeMapping(RRuntime.ROWNAMES_ATTR_KEY); - this.rowNames = RNull.instance; } else { putAttribute(RRuntime.ROWNAMES_ATTR_KEY, newRowNames); - this.rowNames = newRowNames; } } @@ -476,22 +470,36 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement @Override public final boolean hasDimensions() { - return dimensions != null; + return attributes == null ? false : attributes.containsKey(RRuntime.DIM_ATTR_KEY); + } + + public final boolean hasDimNames() { + return attributes == null ? false : attributes.containsKey(RRuntime.DIMNAMES_ATTR_KEY); + } + + public final boolean hasRowNames() { + return attributes == null ? false : attributes.containsKey(RRuntime.ROWNAMES_ATTR_KEY); + } + + public final boolean hasNames() { + return attributes == null ? false : attributes.containsKey(RRuntime.NAMES_ATTR_KEY); } @Override public final boolean isMatrix() { + int[] dimensions = getDimensionsFromAttrs(); return dimensions != null && dimensions.length == 2; } @Override public final boolean isArray() { + int[] dimensions = getDimensionsFromAttrs(); return dimensions != null && dimensions.length > 0; } @Override public final int[] getDimensions() { - return dimensions; + return getDimensionsFromAttrs(); } /** @@ -505,7 +513,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } else { putAttribute(RRuntime.DIM_ATTR_KEY, RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); } - this.dimensions = newDimensions; } @Override @@ -521,7 +528,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement verifyDimensions(getLength(), newDimensions, invokingNode); putAttribute(RRuntime.DIM_ATTR_KEY, RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); } - this.dimensions = newDimensions; } @Override @@ -533,6 +539,10 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement return setClassAttrInternal(vector, classAttr); } + public abstract class CNode extends RBaseNode { + + } + private static RAbstractContainer setClassAttrInternal(RVector<?> vector, RStringVector classAttr) { if (vector.attributes == null && classAttr != null && classAttr.getLength() != 0) { vector.initAttributes(); @@ -562,10 +572,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final void setAttributes(RVector<?> result) { - result.names = this.names; - result.dimNames = this.dimNames; - result.rowNames = this.rowNames; - result.dimensions = this.dimensions; if (this.attributes != null) { result.initAttributes(RAttributesLayout.copy(this.attributes)); } @@ -659,21 +665,13 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement public abstract void transferElementSameType(int toIndex, RAbstractVector fromVector, int fromIndex); - public final RAttributable copyAttributesFrom(RAttributeProfiles attrProfiles, RAbstractContainer vector) { + public final RAttributable copyAttributesFrom(RAbstractContainer vector) { // it's meant to be used on a "fresh" vector with only dimensions potentially set - assert (this.names == null); - assert (this.dimNames == null); - assert (this.rowNames == RNull.instance); - assert (this.dimensions == null); + assert (!hasNames()); + assert (!hasDimNames()); + assert (!hasRowNames()); + assert (!hasDimensions()); assert (this.attributes == null || this.attributes.size() == 0) : this.attributes.size(); - if (vector.getDimensions() == null || vector.getDimensions().length != 1) { - // only assign name attribute if it's not represented as dimnames (as is the case for - // one-dimensional array) - this.names = vector.getNames(attrProfiles); - } - this.dimNames = vector.getDimNames(attrProfiles); - this.rowNames = vector.getRowNames(attrProfiles); - this.dimensions = vector.getDimensions(); DynamicObject vecAttributes = vector.getAttributes(); if (vecAttributes != null) { initAttributes(RAttributesLayout.copy(vecAttributes)); @@ -687,13 +685,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement * Internal version without profiles used in a rare (and already slow) case of double-to-int * vector conversion when setting class attribute */ - protected final RAttributable copyAttributesFrom(RVector<?> vector) { - if (vector.getDimensions() == null || vector.getDimensions().length != 1) { - this.names = vector.getNames(); - } - this.dimNames = vector.getDimNames(); - this.rowNames = vector.getRowNames(); - this.dimensions = vector.getDimensions(); + protected final RAttributable copyAttributesFromVector(RVector<?> vector) { DynamicObject vecAttributes = vector.getAttributes(); if (vecAttributes != null) { initAttributes(RAttributesLayout.copy(vecAttributes)); @@ -705,9 +697,9 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement public final void copyNamesDimsDimNamesFrom(RAttributeProfiles attrProfiles, RAbstractVector vector, RBaseNode invokingNode) { // it's meant to be used on a "fresh" vector with only dimensions potentially set - assert (this.names == null); - assert (this.dimNames == null); - assert (this.dimensions == null); + assert (!hasDimNames()); + assert (!hasDimNames()); + assert (!hasDimensions()); assert (this.attributes == null); // for some reason, names is copied first, then dims, then dimnames if (vector.getDimensions() == null || vector.getDimensions().length != 1) { @@ -720,7 +712,8 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement } public final boolean copyNamesFrom(RAttributeProfiles attrProfiles, RAbstractVector vector) { - if (this.dimensions == null) { + int[] dimensions = getDimensionsFromAttrs(); + if (dimensions == null) { RStringVector vecNames = vector.getNames(attrProfiles); if (vecNames != null) { this.setNames(vecNames); @@ -742,18 +735,13 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement public final RVector<ArrayT> copyRegAttributesFrom(RAbstractContainer vector) { DynamicObject orgAttributes = vector.getAttributes(); if (orgAttributes != null) { - Object newRowNames = null; for (RAttributesLayout.RAttribute e : RAttributesLayout.asIterable(orgAttributes)) { String name = e.getName(); if (name != RRuntime.DIM_ATTR_KEY && name != RRuntime.DIMNAMES_ATTR_KEY && name != RRuntime.NAMES_ATTR_KEY) { Object val = e.getValue(); putAttribute(name, val); - if (name == RRuntime.ROWNAMES_ATTR_KEY) { - newRowNames = val; - } } } - this.rowNames = newRowNames == null ? RNull.instance : newRowNames; } return this; } @@ -766,7 +754,7 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement private RVector<ArrayT> resize(int size, boolean resetAll) { this.complete &= getLength() >= size; RVector<ArrayT> res = this; - RStringVector oldNames = res.names; + RStringVector oldNames = res.getNamesFromAttrs(); res = copyResized(size, true); if (this.isShared()) { assert res.isTemporary(); @@ -775,14 +763,13 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement if (resetAll) { resetAllAttributes(oldNames == null); } else { - res.copyAttributesFrom(this); + res.copyAttributesFromVector(this); res.setDimensionsNoCheck(null); res.setDimNamesNoCheck(null); } if (oldNames != null) { oldNames = oldNames.resizeWithEmpty(size); res.putAttribute(RRuntime.NAMES_ATTR_KEY, oldNames); - res.names = oldNames; } return res; } @@ -790,13 +777,10 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement @TruffleBoundary public final void resetDimensions(int[] newDimensions) { // reset all attributes other than dimensions; - this.dimensions = newDimensions; // whether we nullify dimensions or re-set them to a different value, names and dimNames // must be reset - this.names = null; - this.dimNames = null; - if (this.dimensions != null) { - putAttribute(RRuntime.DIM_ATTR_KEY, RDataFactory.createIntVector(this.dimensions, true)); + if (newDimensions != null) { + putAttribute(RRuntime.DIM_ATTR_KEY, RDataFactory.createIntVector(newDimensions, true)); } else { // nullifying dimensions does not reset regular attributes if (this.attributes != null) { @@ -809,10 +793,6 @@ public abstract class RVector<ArrayT> extends RSharingAttributeStorage implement @Override public final void resetAllAttributes(boolean nullify) { - this.dimensions = null; - this.names = null; - this.dimNames = null; - this.rowNames = RNull.instance; if (nullify) { this.attributes = null; } else { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java index 24cdcd702ad4a17447951e0f3aff6fbf9f5267fc..e8f6e117dc99f28a7193e8c03c849a5072386021 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CRFFI.java @@ -22,14 +22,20 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; + /** * Support for the {.C} and {.Fortran} calls. */ public interface CRFFI { - /** - * Invoke the native method identified by {@code symbolInfo} passing it the arguments in - * {@code args}. The values in {@code args} should be native types,e.g., {@code double[]} not - * {@code RDoubleVector}. - */ - void invoke(NativeCallInfo nativeCallInfo, Object[] args); + abstract class CRFFINode extends Node { + /** + * Invoke the native method identified by {@code symbolInfo} passing it the arguments in + * {@code args}. The values in {@code args} should be native types,e.g., {@code double[]} + * not {@code RDoubleVector}. + */ + public abstract void invoke(NativeCallInfo nativeCallInfo, Object[] args); + } + + CRFFINode createCRFFINode(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java index 3029ffce07e33bfd27552919f3916437fb3a93d3..8620608493e7cdee94b262335f988a7db60b54f5 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CallRFFI.java @@ -22,32 +22,38 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; + /** * Support for the {.Call} and {.External} calls. */ public interface CallRFFI { - /** - * Invoke the native function identified by {@code symbolInfo} passing it the arguments in - * {@code args}. The values in {@code args} can be any of the types used to represent {@code R} - * values in the implementation. - */ - Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args); + abstract class CallRFFINode extends Node { + /** + * Invoke the native function identified by {@code symbolInfo} passing it the arguments in + * {@code args}. The values in {@code args} can be any of the types used to represent + * {@code R} values in the implementation. + */ + public abstract Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args); + + /** + * Variant that does not return a result (primarily for library "init" methods). + */ + public abstract void invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args); - /** - * Variant that does not return a result (primarily for library "init" methods). - */ - void invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args); + /** + * This interface is instantiated very early and sets the FFI global variables as part of + * that process. However, at that stage {@code tempDir} is not established so this call + * exists to set the value later. + */ + public abstract void setTempDir(String tempDir); - /** - * This interface is instantiated very early and sets the FFI global variables as part of that - * process. However, at that stage {@code tempDir} is not established so this call exists to set - * the value later. - */ - void setTempDir(String tempDir); + /** + * Sets the {@code R_Interactive} FFI variable. Similar rationale to {#link setTmpDir}. + */ + public abstract void setInteractive(boolean interactive); + } - /** - * Sets the {@code R_Interactive} FFI variable. Similar rationale to {#link setTmpDir}. - */ - void setInteractive(boolean interactive); + CallRFFINode createCallRFFINode(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CharSXPWrapper.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CharSXPWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..f7e83255eb8c99e1c347db8bc76d5f03fadcf6c2 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CharSXPWrapper.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, 2016, 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.runtime.ffi; + +/** + * 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. + * + * N.B. Use limited to RFFI implementations. + * + */ +public final class CharSXPWrapper { + private final String contents; + + private CharSXPWrapper(String contents) { + this.contents = contents; + } + + public String getContents() { + return contents; + } + + @Override + public String toString() { + return "CHARSXP(" + contents + ")"; + } + + public static Object create(String contents) { + return new CharSXPWrapper(contents); + } + +} 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 bceaacfbd4e212370d6dd05252803756e897201e..181da4cc9d31082accd86f6a2728539eb311a475 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 @@ -13,13 +13,12 @@ package com.oracle.truffle.r.runtime.ffi; import java.io.File; import java.util.ArrayList; -import java.util.Deque; -import java.util.concurrent.ConcurrentLinkedDeque; import java.util.concurrent.atomic.AtomicInteger; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.RErrorException; import com.oracle.truffle.r.runtime.RInternalError; @@ -27,6 +26,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.ContextState; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RList; @@ -34,6 +34,7 @@ import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTruffleObject; +import com.oracle.truffle.r.runtime.ffi.CallRFFI.CallRFFINode; /** * Support for Dynamically Loaded Libraries. @@ -46,34 +47,63 @@ import com.oracle.truffle.r.runtime.data.RTruffleObject; * <li>support native code of dynamically loaded user packages</li> * </ol> * - * In general, unloading a DLL may not be possible, so the set of DLLs have to be considered VM - * wide, in the sense of multiple {@link RContext}s. TODO what about mutable state in native code? - * So in the case of multiple {@link RContext}s package shared libraries may be registered multiple - * times and we must take care not to duplicate them in the meta-data here ({@link #list}). - * * Logic derived from Rdynload.c. For the most part we use the same type/function names as GnuR, * e.g. {@link NativeSymbolType}. + * + * Abstractly every {@link RContext} has its own unique list of loaded libraries, stored in the + * {@link ContextStateImpl} class. Concretely, an implementation of the {@link DLLRFFI} may or may + * not maintain separate instances. + * + * The {@code libR} library is a special case, as it is an implementation artifact and not visible + * at the R level. However, it is convenient to manage it in a similar way in this code. It is + * always stored in slot 0 of the list, and is hidden from R code. It is loaded by the + * {@link RFFIFactory} early in the startup, before the initial {@link RContext} is created, by + * {@link #loadLibR}. This should only be called once. */ public class DLL { + public static class ContextStateImpl implements RContext.ContextState { + private ArrayList<DLLInfo> list; + private RContext context; + + public static ContextStateImpl newContextState() { + return new ContextStateImpl(); + } + + @Override + public ContextState initialize(RContext contextArg) { + this.context = contextArg; + if (context.getKind() == RContext.ContextKind.SHARE_PARENT_RW) { + list = context.getParent().stateDLL.list; + } else { + list = new ArrayList<>(); + list.add(libRDLLInfo); + } + return this; + } + + @Override + public void beforeDestroy(RContext contextArg) { + if (context.getKind() != RContext.ContextKind.SHARE_PARENT_RW) { + for (int i = 1; i < list.size(); i++) { + DLLInfo dllInfo = list.get(i); + RFFIFactory.getRFFI().getDLLRFFI().dlclose(dllInfo.handle); + } + } + list = null; + } + + } + /** * The list of loaded DLLs. */ - private static Deque<DLLInfo> list = new ConcurrentLinkedDeque<>(); /** * Uniquely identifies the DLL (for use in an {@code externalptr}). */ private static final AtomicInteger ID = new AtomicInteger(); - public static Deque<DLLInfo> getList() { - return list; - } - - public static void addDLL(DLLInfo dllInfo) { - list.add(dllInfo); - } - public enum NativeSymbolType { C, Call, @@ -144,9 +174,12 @@ public class DLL { this.handle = handle; } - private static synchronized DLLInfo create(String name, String path, boolean dynamicLookup, Object handle) { + private static DLLInfo create(String name, String path, boolean dynamicLookup, Object handle, boolean addToList) { DLLInfo result = new DLLInfo(name, path, dynamicLookup, handle); - list.add(result); + if (addToList) { + ContextStateImpl contextState = getContextState(); + contextState.list.add(result); + } return result; } @@ -289,6 +322,10 @@ public class DLL { public static final SymbolHandle SYMBOL_NOT_FOUND = null; + private static ContextStateImpl getContextState() { + return RContext.getInstance().stateDLL; + } + public static boolean isDLLInfo(RExternalPtr info) { RSymbol tag = (RSymbol) info.getTag(); return tag.getName().equals(DLLInfo.DLL_INFO_REFERENCE); @@ -309,53 +346,87 @@ public class DLL { } } - /* - * There is no sense in throwing an RError if we fail to load/init a (default) package during - * initial context initialization, as it is essentially fatal for any of the standard packages - * and indicates a bug in the RFFI implementation. So we call Utils.fatalError instead. When the - * system is stable, we can undo this, so that errors loading (user) packages added to - * R_DEFAULT_PACKAGES do throw RErrors. + /** + * A temporary stash until such time as the initial context is initialized. + */ + private static DLLInfo libRDLLInfo; + + /** + * Loads a the {@code libR} library. This is an implementation specific library N.B., when this + * is called for the first time, there is no {@link RContext} available, so we stash the result + * until {@link ContextStateImpl#initialize} is called. */ + public static void loadLibR(String path, boolean local, boolean now) throws DLLException { + assert libRDLLInfo == null; + libRDLLInfo = doLoad(path, local, now, false); + } @TruffleBoundary - public static synchronized DLLInfo load(String path, boolean local, boolean now) throws DLLException { + public static DLLInfo load(String path, boolean local, boolean now) throws DLLException { String absPath = Utils.tildeExpand(path); - for (DLLInfo dllInfo : list) { + ContextStateImpl contextState = getContextState(); + for (DLLInfo dllInfo : contextState.list) { if (dllInfo.path.equals(absPath)) { // already loaded return dllInfo; } } - File file = new File(absPath); - Object handle = RFFIFactory.getRFFI().getDLLRFFI().dlopen(path, local, now); + return doLoad(absPath, local, now, true); + } + + /* + * There is no sense in throwing an RError if we fail to load/init a (default) package during + * initial context initialization, as it is essentially fatal for any of the standard packages + * and indicates a bug in the RFFI implementation. So we call Utils.fatalError instead. When the + * system is stable, we can undo this, so that errors loading (user) packages added to + * R_DEFAULT_PACKAGES do throw RErrors. + */ + + private static DLLInfo doLoad(String absPath, boolean local, boolean now, boolean addToList) throws DLLException { + Object handle = RFFIFactory.getRFFI().getDLLRFFI().dlopen(absPath, local, now); if (handle == null) { String dlError = RFFIFactory.getRFFI().getDLLRFFI().dlerror(); if (RContext.isInitialContextInitialized()) { - throw new DLLException(RError.Message.DLL_LOAD_ERROR, path, dlError); + throw new DLLException(RError.Message.DLL_LOAD_ERROR, absPath, dlError); } else { - throw Utils.rSuicide("error loading default package: " + path + "\n" + dlError); + throw Utils.rSuicide("error loading default package: " + absPath + "\n" + dlError); } } + DLLInfo dllInfo = DLLInfo.create(libName(absPath), absPath, true, handle, addToList); + return dllInfo; + } + + private static String libName(String absPath) { + File file = new File(absPath); String name = file.getName(); int dx = name.lastIndexOf('.'); if (dx > 0) { name = name.substring(0, dx); } - return DLLInfo.create(name, absPath, true, handle); + return name; } - private static final String R_INIT_PREFIX = "R_init_"; + public static final String R_INIT_PREFIX = "R_init_"; - @TruffleBoundary - public static DLLInfo loadPackageDLL(String path, boolean local, boolean now) throws DLLException { - DLLInfo dllInfo = load(path, local, now); - // Search for init method - String pkgInit = R_INIT_PREFIX + dllInfo.name; - SymbolHandle initFunc = RFFIFactory.getRFFI().getDLLRFFI().dlsym(dllInfo.handle, pkgInit); - if (initFunc != SYMBOL_NOT_FOUND) { - synchronized (DLL.class) { + public static class LoadPackageDLLNode extends Node { + @Child private CallRFFINode callRFFINode; + + public static LoadPackageDLLNode create() { + return new LoadPackageDLLNode(); + } + + @TruffleBoundary + public DLLInfo loadPackageDLL(String path, boolean local, boolean now) throws DLLException { + DLLInfo dllInfo = load(path, local, now); + // Search for init method + String pkgInit = R_INIT_PREFIX + dllInfo.name; + SymbolHandle initFunc = RFFIFactory.getRFFI().getDLLRFFI().dlsym(dllInfo.handle, pkgInit); + if (initFunc != SYMBOL_NOT_FOUND) { try { - RFFIFactory.getRFFI().getCallRFFI().invokeVoidCall(new NativeCallInfo(pkgInit, initFunc, dllInfo), new Object[]{dllInfo}); + if (callRFFINode == null) { + callRFFINode = insert(RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode()); + } + callRFFINode.invokeVoidCall(new NativeCallInfo(pkgInit, initFunc, dllInfo), new Object[]{dllInfo}); } catch (ReturnException ex) { // An error call can, due to condition handling, throw this which we must // propogate @@ -368,28 +439,33 @@ public class DLL { } } } + return dllInfo; } - return dllInfo; } @TruffleBoundary - public static synchronized void unload(String path) throws DLLException { + public static void unload(String path) throws DLLException { String absPath = Utils.tildeExpand(path); - for (DLLInfo info : list) { + ContextStateImpl contextState = getContextState(); + for (DLLInfo info : contextState.list) { if (info.path.equals(absPath)) { int rc = RFFIFactory.getRFFI().getDLLRFFI().dlclose(info.handle); if (rc != 0) { throw new DLLException(RError.Message.DLL_LOAD_ERROR, path, ""); } + contextState.list.remove(info); return; } } throw new DLLException(RError.Message.DLL_NOT_LOADED, path); } - public static synchronized ArrayList<DLLInfo> getLoadedDLLs() { + public static ArrayList<DLLInfo> getLoadedDLLs() { ArrayList<DLLInfo> result = new ArrayList<>(); - for (DLLInfo dllInfo : list) { + ContextStateImpl contextState = getContextState(); + // skip first entry (libR) + for (int i = 1; i < contextState.list.size(); i++) { + DLLInfo dllInfo = contextState.list.get(i); result.add(dllInfo); } return result; @@ -465,9 +541,10 @@ public class DLL { * {@code null}) */ @TruffleBoundary - public static synchronized SymbolHandle findSymbol(String name, String libName, RegisteredNativeSymbol rns) { + public static SymbolHandle findSymbol(String name, String libName, RegisteredNativeSymbol rns) { boolean all = libName == null || libName.length() == 0; - for (DLLInfo dllInfo : list) { + ContextStateImpl contextState = getContextState(); + for (DLLInfo dllInfo : contextState.list) { if (dllInfo.forceSymbols) { continue; } @@ -487,8 +564,9 @@ public class DLL { return SYMBOL_NOT_FOUND; } - public static synchronized DLLInfo findLibrary(String name) { - for (DLLInfo dllInfo : list) { + public static DLLInfo findLibrary(String name) { + ContextStateImpl contextState = getContextState(); + for (DLLInfo dllInfo : contextState.list) { if (dllInfo.name.equals(name)) { return dllInfo; } @@ -529,7 +607,7 @@ public class DLL { public static DLLInfo getEmbeddingDLLInfo() { DLLInfo result = findLibrary(EMBEDDING); if (result == null) { - result = DLLInfo.create(EMBEDDING, EMBEDDING, false, null); + result = DLLInfo.create(EMBEDDING, EMBEDDING, false, null, true); } return result; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/FFIRootNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/FFIRootNode.java new file mode 100644 index 0000000000000000000000000000000000000000..00c8ed1b5f521e25244303b467ad901847642534 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/FFIRootNode.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, 2016, 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.runtime.ffi; + +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.RootNode; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.data.RNull; + +public final class FFIRootNode extends RootNode { + @Child private CallRFFI.CallRFFINode callRFFINode = RFFIFactory.getRFFI().getCallRFFI().createCallRFFINode(); + + public FFIRootNode() { + super(RContext.getRRuntimeASTAccess().getTruffleRLanguage(), null, new FrameDescriptor()); + + } + + @Override + public Object execute(VirtualFrame frame) { + Object[] args = frame.getArguments(); + NativeCallInfo nativeCallInfo = (NativeCallInfo) args[0]; + boolean isVoidCall = (boolean) args[1]; + Object[] callArgs = (Object[]) args[2]; + if (isVoidCall) { + callRFFINode.invokeVoidCall(nativeCallInfo, callArgs); + return RNull.instance; + } else { + return callRFFINode.invokeCall(nativeCallInfo, callArgs); + } + } + + public static RootCallTarget createCallTarget() { + return Truffle.getRuntime().createCallTarget(new FFIRootNode()); + } + +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/GridRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/GridRFFI.java index 561ba671024c66baf1db51eacd3776bc0b218778..9d410b1054b72fa146627a30012e09c103dbdcc8 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/GridRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/GridRFFI.java @@ -22,10 +22,15 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.env.REnvironment; public interface GridRFFI { - Object initGrid(REnvironment gridEvalEnv); + abstract class GridRFFINode extends Node { + public abstract Object initGrid(REnvironment gridEvalEnv); - Object killGrid(); + public abstract Object killGrid(); + } + + GridRFFINode createGridRFFINode(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LapackRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LapackRFFI.java index 9d537ec5006221e9796736eaf19bc85e645631c0..a8f3622fa426a6c5a8d5070705abf8a160e4ed08 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LapackRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/LapackRFFI.java @@ -22,67 +22,73 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; + /** * Collection of statically typed Lapack methods that are used in the {@code base} package. The * signatures match the Fortran definition with the exception that the "info" value is returned as * the result of the call. */ public interface LapackRFFI { - /** - * Return version info, mjor, minor, patch, in {@code version}. - */ - void ilaver(int[] version); + abstract class LapackRFFINode extends Node { + /** + * Return version info, mjor, minor, patch, in {@code version}. + */ + public abstract void ilaver(int[] version); + + /** + * See <a href="http://www.netlib.org/lapack/explore-html/d9/d28/dgeev_8f.html">spec</a>. + */ + public abstract int dgeev(char jobVL, char jobVR, int n, double[] a, int lda, double[] wr, double[] wi, double[] vl, int ldvl, double[] vr, int ldvr, double[] work, int lwork); - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d9/d28/dgeev_8f.html">spec</a>. - */ - int dgeev(char jobVL, char jobVR, int n, double[] a, int lda, double[] wr, double[] wi, double[] vl, int ldvl, double[] vr, int ldvr, double[] work, int lwork); + /** + * See <a href="http://www.netlib.org/lapack/explore-html/db/de5/dgeqp3_8f.html">spec</a>. + */ + public abstract int dgeqp3(int m, int n, double[] a, int lda, int[] jpvt, double[] tau, double[] work, int lwork); - /** - * See <a href="http://www.netlib.org/lapack/explore-html/db/de5/dgeqp3_8f.html">spec</a>. - */ - int dgeqp3(int m, int n, double[] a, int lda, int[] jpvt, double[] tau, double[] work, int lwork); + /** + * See <a href="http://www.netlib.org/lapack/explore-html/da/d82/dormqr_8f.html">spec</a>. + */ + public abstract int dormqr(char side, char trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork); - /** - * See <a href="http://www.netlib.org/lapack/explore-html/da/d82/dormqr_8f.html">spec</a>. - */ - int dormqr(char side, char trans, int m, int n, int k, double[] a, int lda, double[] tau, double[] c, int ldc, double[] work, int lwork); + /** + * See <a href="http://www.netlib.org/lapack/explore-html/d6/d6f/dtrtrs_8f.html">spec</a>. + */ + public abstract int dtrtrs(char uplo, char trans, char diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb); - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d6/d6f/dtrtrs_8f.html">spec</a>. - */ - int dtrtrs(char uplo, char trans, char diag, int n, int nrhs, double[] a, int lda, double[] b, int ldb); + /** + * See <a href="http://www.netlib.org/lapack/explore-html/d3/d6a/dgetrf_8f.html">spec</a>. + */ + public abstract int dgetrf(int m, int n, double[] a, int lda, int[] ipiv); - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d3/d6a/dgetrf_8f.html">spec</a>. - */ - int dgetrf(int m, int n, double[] a, int lda, int[] ipiv); + /** + * See <a href="http://www.netlib.org/lapack/explore-html/d0/d8a/dpotrf_8f.html">spec</a>. + */ + public abstract int dpotrf(char uplo, int n, double[] a, int lda); - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d0/d8a/dpotrf_8f.html">spec</a>. - */ - int dpotrf(char uplo, int n, double[] a, int lda); + /** + * See <a href="http://www.netlib.org/lapack/explore-html/dd/dad/dpstrf_8f.html">spec</a>. + */ + public abstract int dpstrf(char uplo, int n, double[] a, int lda, int[] piv, int[] rank, double tol, double[] work); - /** - * See <a href="http://www.netlib.org/lapack/explore-html/dd/dad/dpstrf_8f.html">spec</a>. - */ - int dpstrf(char uplo, int n, double[] a, int lda, int[] piv, int[] rank, double tol, double[] work); + /** + * See <a href="http://www.netlib.org/lapack/explore-html/d8/d72/dgesv_8f.html">spec</a>. + */ + public abstract int dgesv(int n, int nrhs, double[] a, int lda, int[] ipiv, double[] b, int ldb); - /** - * See <a href="http://www.netlib.org/lapack/explore-html/d8/d72/dgesv_8f.html">spec</a>. - */ - int dgesv(int n, int nrhs, double[] a, int lda, int[] ipiv, double[] b, int ldb); + /** + * See <a href="http://www.netlib.org/lapack/explore-html/dc/d09/dlange_8f.html">spec</a>. + */ + public abstract double dlange(char norm, int m, int n, double[] a, int lda, double[] work); - /** - * See <a href="http://www.netlib.org/lapack/explore-html/dc/d09/dlange_8f.html">spec</a>. - */ - double dlange(char norm, int m, int n, double[] a, int lda, double[] work); + /** + * See <a href="http://www.netlib.org/lapack/explore-html/db/de4/dgecon_8f.html">spec</a>. + */ + public abstract int dgecon(char norm, int n, double[] a, int lda, double anorm, double[] rcond, double[] work, int[] iwork); - /** - * See <a href="http://www.netlib.org/lapack/explore-html/db/de4/dgecon_8f.html">spec</a>. - */ - int dgecon(char norm, int n, double[] a, int lda, double anorm, double[] rcond, double[] work, int[] iwork); + public abstract int dsyevr(char jobz, char range, char uplo, int n, double[] a, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, double[] w, + double[] z, int ldz, int[] isuppz, double[] work, int lwork, int[] iwork, int liwork); + } - int dsyevr(char jobz, char range, char uplo, int n, double[] a, int lda, double vl, double vu, int il, int iu, double abstol, int[] m, double[] w, - double[] z, int ldz, int[] isuppz, double[] work, int lwork, int[] iwork, int liwork); + LapackRFFINode createLapackRFFINode(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeCallInfo.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeCallInfo.java index b2559c719ee30f9e3880a1016448c05b851d2f01..c904948ab6afcacfcb6f7fe3a54dec1fadccc220 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeCallInfo.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/NativeCallInfo.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; @@ -42,4 +43,10 @@ public final class NativeCallInfo { this.address = address; this.dllInfo = dllInfo; } + + @Override + public String toString() { + CompilerAsserts.neverPartOfCompilation(); + return String.format("dll: %s, name: %s", dllInfo.name, name); + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/PCRERFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/PCRERFFI.java index 1825446c61a5d71aa069c44c0460febb2b902922..cff6aadebf60cdce9f6b0f3aa44fd5789218a020 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/PCRERFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/PCRERFFI.java @@ -22,6 +22,8 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; + /** * An interface to the <a href="http://www.pcre.org/original/doc/html/index.html">PCRE</a> library * for Perl regular expressions. @@ -47,16 +49,21 @@ public interface PCRERFFI { } } - long maketables(); + abstract class PCRERFFINode extends Node { + + public abstract long maketables(); - Result compile(String pattern, int options, long tables); + public abstract Result compile(String pattern, int options, long tables); - int getCaptureCount(long code, long extra); + public abstract int getCaptureCount(long code, long extra); - String[] getCaptureNames(long code, long extra, int captureCount); + public abstract String[] getCaptureNames(long code, long extra, int captureCount); - Result study(long code, int options); + public abstract Result study(long code, int options); + + public abstract int exec(long code, long extra, String subject, int offset, int options, int[] ovector); + } - int exec(long code, long extra, String subject, int offset, int options, int[] ovector); + PCRERFFINode createPCRERFFINode(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ParseResult.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ParseResult.java new file mode 100644 index 0000000000000000000000000000000000000000..d4c71e01bd9db7b54b821bdeec2afda8ea9589b6 --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ParseResult.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014, 2016, 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.runtime.ffi; + +/** + * Used in implementation of {@link UpCallsRFFI#R_ParseVector(Object, int, Object)}. + */ +public class ParseResult { + public enum ParseStatus { + PARSE_NULL, + PARSE_OK, + PARSE_INCOMPLETE, + PARSE_ERROR, + PARSE_EOF + } + + @SuppressWarnings("unused") private final int parseStatus; + @SuppressWarnings("unused") private final Object expr; + + ParseResult(int parseStatus, Object expr) { + this.parseStatus = parseStatus; + this.expr = expr; + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RApplRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RApplRFFI.java index 4f20c85d9b914cd51b4ae9ef42aa7da45a300317..189f88165c856c4296e52f25bdb2be52f43ec268 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RApplRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RApplRFFI.java @@ -22,17 +22,23 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; + /** * Collection of statically typed methods (from Linpack and elsewhere) that are built in to a GnuR * implementation and factored out into a separate library in FastR. This corresponds to the * {@code libappl} library in GnuR. */ public interface RApplRFFI { - // Linpack - void dqrdc2(double[] x, int ldx, int n, int p, double tol, int[] rank, double[] qraux, int[] pivot, double[] work); + abstract class RApplRFFINode extends Node { + // Linpack + public abstract void dqrdc2(double[] x, int ldx, int n, int p, double tol, int[] rank, double[] qraux, int[] pivot, double[] work); + + public abstract void dqrcf(double[] x, int n, int k, double[] qraux, double[] y, int ny, double[] b, int[] info); - void dqrcf(double[] x, int n, int k, double[] qraux, double[] y, int ny, double[] b, int[] info); + public abstract void dqrls(double[] x, int n, int p, double[] y, int ny, double tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work); + } - void dqrls(double[] x, int n, int p, double[] y, int ny, double tol, double[] b, double[] rsd, double[] qty, int[] k, int[] jpvt, double[] qraux, double[] work); + RApplRFFINode createRApplRFFINode(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java index 99378fa1afaf28b7dc52b531356a846330d4edd2..ccc6224ba183630e07ad2a4ca7dce1ccb2c14766 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/RFFI.java @@ -42,6 +42,9 @@ package com.oracle.truffle.r.runtime.ffi; * <li>{@link DLLRFFI}: interface to dll functions, e.g., {@code dlopen}</li> * <li>{@link REmbedRFFI}: interface to embedded support</li> * <li>{@link MiscRFFI}: interface to miscellaneous native functions</li> + * <li>{@link UpCallsRFFI}: interface that defines the set of upcalls from native code (resulting + * from {@link CallRFFI}). There is no public access to this interface as it should never be called + * from FastR Java code and is always implemented by a specific FFI factory. * </ul> * * These interfaces may be implemented by one or more providers, specified either when the FastR diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java index a796d4fb612f4ae24a80ab1d21b5929199e38f48..67adab0639211e28786f15af9be6578e12abcdb6 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/StatsRFFI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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,13 +22,20 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; + /** - * Interface to native (C) methods provided by the {@code stats} package. + * Interface to native (C) methods provided by the {@code stats} package that are used to implement + * {@code.Call(C_fft)}. The implementation is split into a Java part which calls the + * {@code fft_factor} and {@code fft_work}. functions from the GNU R C code. */ public interface StatsRFFI { - // Checkstyle: stop method name - void fft_factor(int n, int[] pmaxf, int[] pmaxp); + abstract class FFTNode extends Node { + public abstract void executeFactor(int n, int[] pmaxf, int[] pmaxp); + + public abstract int executeWork(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork); + } - int fft_work(double[] a, int nseg, int n, int nspn, int isn, double[] work, int[] iwork); + FFTNode createFFTNode(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ToolsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ToolsRFFI.java index 04bc7e21a310117776602427c0dee389e3154b6b..290daad5f02a030ce1c177c3b461f7332fb3fae4 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ToolsRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/ToolsRFFI.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.conn.RConnection; import com.oracle.truffle.r.runtime.data.RLogicalVector; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -31,14 +32,18 @@ import com.oracle.truffle.r.runtime.env.REnvironment; * Interface to native (C) methods provided by the {@code tools} package. */ public interface ToolsRFFI { - /** - * This invokes the Rd parser, written in C, and part of GnuR, that does its work using the R - * FFI interface. The R code initially invokes this via {@code .External2(C_parseRd, ...)}, - * which has a custom specialization in the implementation of the {@code .External2} builtin. - * That does some work in Java, and then calls this method to invoke the actual C code. We can't - * go straight to the GnuR C entry point as that makes GnuR-specific assumptions about, for - * example, how connections are implemented. - */ - Object parseRd(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros, - RLogicalVector warndups); + abstract class ToolsRFFINode extends Node { + /** + * This invokes the Rd parser, written in C, and part of GnuR, that does its work using the + * R FFI interface. The R code initially invokes this via {@code .External2(C_parseRd, ...)} + * , which has a custom specialization in the implementation of the {@code .External2} + * builtin. That does some work in Java, and then calls this method to invoke the actual C + * code. We can't go straight to the GnuR C entry point as that makes GnuR-specific + * assumptions about, for example, how connections are implemented. + */ + public abstract Object parseRd(RConnection con, REnvironment srcfile, RLogicalVector verbose, RLogicalVector fragment, RStringVector basename, RLogicalVector warningCalls, Object macros, + RLogicalVector warndups); + } + + ToolsRFFINode createToolsRFFINode(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UpCallsRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UpCallsRFFI.java new file mode 100644 index 0000000000000000000000000000000000000000..ccfb5fa901804eb5d13cc1f0858d736fe1c0cc4d --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UpCallsRFFI.java @@ -0,0 +1,279 @@ +/* + * Copyright (c) 2014, 2016, 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.runtime.ffi; + +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RExternalPtr; +import com.oracle.truffle.r.runtime.data.RIntVector; +import com.oracle.truffle.r.runtime.data.RLogicalVector; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.env.REnvironment; + +/** + * This class defines methods that match the functionality of the macro/function definitions in the + * R header files, e.g. {@code Rinternals.h} that are used by C/C++ code to call into the R + * implementation. For ease of identification, we use method names that match the names in the R + * header files. These methods should never be called from normal FastR code. + * + * The set is incomplete; these are the functions that have been found to be used to at this time of + * writing. From the GNU R perspective all {@code Object} parameters are {@code SEXP} instances. + * Some of the functions are typed with a specific return type but, again, this is a {@code SEXP} in + * GNU R terms. The native side does not require a specific Java type. + * + */ +public interface UpCallsRFFI { + + // Checkstyle: stop method name check + + RIntVector Rf_ScalarInteger(int value); + + RLogicalVector Rf_ScalarLogical(int value); + + RDoubleVector Rf_ScalarDouble(double value); + + RStringVector Rf_ScalarString(Object value); + + int Rf_asInteger(Object x); + + double Rf_asReal(Object x); + + int Rf_asLogical(Object x); + + Object Rf_asChar(Object x); + + Object Rf_mkCharLenCE(byte[] bytes, int encoding); + + Object Rf_cons(Object car, Object cdr); + + void Rf_defineVar(Object symbolArg, Object value, Object envArg); + + Object R_do_MAKE_CLASS(String clazz); + + /** + * WARNING: argument order reversed from Rf_findVarInFrame! + */ + Object Rf_findVar(Object symbolArg, Object envArg); + + Object Rf_findVarInFrame(Object envArg, Object symbolArg); + + Object Rf_findVarInFrame3(Object envArg, Object symbolArg, int doGet); + + Object Rf_getAttrib(Object obj, Object name); + + void Rf_setAttrib(Object obj, Object name, Object val); + + int Rf_inherits(Object x, String clazz); + + Object Rf_install(String name); + + Object Rf_lengthgets(Object x, int newSize); + + int Rf_isString(Object x); + + int Rf_isNull(Object x); + + Object Rf_PairToVectorList(Object x); + + void Rf_error(String msg); + + void Rf_warning(String msg); + + void Rf_warningcall(Object call, String msg); + + Object Rf_allocateVector(int mode, int n); + + Object Rf_allocateArray(int mode, Object dimsObj); + + Object Rf_allocateMatrix(int mode, int nrow, int ncol); + + int Rf_nrows(Object x); + + int Rf_ncols(Object x); + + int LENGTH(Object x); + + void SET_STRING_ELT(Object x, int i, Object v); + + void SET_VECTOR_ELT(Object x, int i, Object v); + + Object RAW(Object x); + + Object LOGICAL(Object x); + + Object INTEGER(Object x); + + Object REAL(Object x); + + Object STRING_ELT(Object x, int i); + + Object VECTOR_ELT(Object x, int i); + + int NAMED(Object x); + + Object SET_TYPEOF_FASTR(Object x, int v); + + int TYPEOF(Object x); + + int OBJECT(Object x); + + Object Rf_duplicate(Object x, int deep); + + int Rf_anyDuplicated(Object x, int fromLast); + + Object PRINTNAME(Object x); + + Object TAG(Object e); + + Object CAR(Object e); + + Object CDR(Object e); + + Object CADR(Object e); + + Object CADDR(Object e); + + Object CDDR(Object e); + + Object SET_TAG(Object x, Object y); + + Object SETCAR(Object x, Object y); + + Object SETCDR(Object x, Object y); + + Object SETCADR(Object x, Object y); + + Object SYMVALUE(Object x); + + void SET_SYMVALUE(Object x, Object v); + + int R_BindingIsLocked(Object sym, Object env); + + Object R_FindNamespace(Object name); + + Object Rf_eval(Object expr, Object env); + + Object Rf_findfun(Object symbolObj, Object envObj); + + Object Rf_GetOption1(Object tag); + + void Rf_gsetVar(Object symbol, Object value, Object rho); + + void DUPLICATE_ATTRIB(Object to, Object from); + + int R_computeIdentical(Object x, Object y, int flags); + + void Rf_copyListMatrix(Object s, Object t, int byrow); + + void Rf_copyMatrix(Object s, Object t, int byrow); + + Object R_tryEval(Object expr, Object env, boolean silent); + + Object R_ToplevelExec(); + + int RDEBUG(Object x); + + void SET_RDEBUG(Object x, int v); + + int RSTEP(Object x); + + void SET_RSTEP(Object x, int v); + + Object ENCLOS(Object x); + + Object PRVALUE(Object x); + + Object R_ParseVector(Object text, int n, Object srcFile); + + Object R_lsInternal3(Object envArg, int allArg, int sortedArg); + + String R_HomeDir(); + + int isInteractive(); + + int isS4Object(Object x); + + void Rprintf(String message); + + void GetRNGstate(); + + void PutRNGstate(); + + double unif_rand(); + + Object Rf_classgets(Object x, Object y); + + RExternalPtr R_MakeExternalPtr(long addr, Object tag, Object prot); + + long R_ExternalPtrAddr(Object x); + + Object R_ExternalPtrTag(Object x); + + Object R_ExternalPtrProt(Object x); + + void R_SetExternalPtrAddr(Object x, long addr); + + void R_SetExternalPtrTag(Object x, Object tag); + + void R_SetExternalPtrProt(Object x, Object prot); + + void R_CleanUp(int sa, int status, int runlast); + + REnvironment R_NewHashedEnv(REnvironment parent, String name, boolean hashed, int initialSize); + + /* + * The following functions are global variables in the standard R FFI. However, owing to the + * support for virtual R sessions (see .fastr.context) in FastR they are remapped as functions. + */ + Object R_GlobalContext(); + + Object R_GlobalEnv(); + + Object R_BaseEnv(); + + Object R_BaseNamespace(); + + Object R_NamespaceRegistry(); + + /* + * The following functions are FastR extensions to support RStudio + */ + + Object R_getGlobalFunctionContext(); + + Object R_getParentFunctionContext(Object c); + + Object R_getContextEnv(Object c); + + Object R_getContextFun(Object c); + + Object R_getContextCall(Object c); + + Object R_getContextSrcRef(Object c); + + int R_insideBrowser(); + + int R_isGlobal(Object c); + + int R_isEqual(Object x, Object y); + +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UpCallsRFFIFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UpCallsRFFIFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..ad90095e5d43c62b89736d67dc05c0a60d035c1a --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UpCallsRFFIFactory.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016, 2016, 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.runtime.ffi; + +public abstract class UpCallsRFFIFactory { + static { + final String prop = System.getProperty("fastr.upcalls.factory.class", "com.oracle.truffle.r.runtime.ffi.JavaUpCallsRFFIFactory"); + try { + theInstance = (UpCallsRFFIFactory) Class.forName(prop).newInstance(); + } catch (Exception ex) { + // CheckStyle: stop system..print check + System.err.println("Failed to instantiate class: " + prop); + } + } + + private static UpCallsRFFIFactory theInstance; + + public static UpCallsRFFIFactory getInstance() { + return theInstance; + } + + public abstract UpCallsRFFI getUpcallsRFFI(); + +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UserRngRFFI.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UserRngRFFI.java index dc692727fcfe6b46100e854a859d63ec0abaa700..64059decbdafae4071c9165e91a345da6c2f313d 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UserRngRFFI.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/UserRngRFFI.java @@ -22,17 +22,23 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.api.nodes.Node; + /** * Explicit statically typed interface to user-supplied random number generators. */ public interface UserRngRFFI { + abstract class UserRngRFFINode extends Node { + + public abstract void init(int seed); - void init(int seed); + public abstract double rand(); - double rand(); + public abstract int nSeed(); - int nSeed(); + public abstract void seeds(int[] n); + } - void seeds(int[] n); + UserRngRFFINode createUserRngRFFINode(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java index c3538fa9a79e69624a844b784275b7a3b2dd0d40..fa6e33017ba7329a1d9810df5051c8da746174dc 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java @@ -110,7 +110,8 @@ public abstract class BinaryArithmetic extends Operation { public abstract String op(String left, String right); public static double fmod(double a, double b) { - // LICENSE: transcribed code from GNU R, which is licensed under GPL + // TODO: this is duplicated in RMath, once RMath is moved to runtime, this should be + // replaced double q = a / b; if (b != 0) { double tmp = a - Math.floor(q) * b; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java index 84187071f92296f69c96bec987616bcefd1d0270..b8490dfaae54f03a4c1fae79f647be644b5ce418 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/rng/user/UserRNG.java @@ -23,7 +23,15 @@ package com.oracle.truffle.r.runtime.rng.user; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; import com.oracle.truffle.r.runtime.ffi.RFFIFactory; @@ -66,28 +74,67 @@ public final class UserRNG implements RandomNumberGenerator { } - private UserRngRFFI userRngRFFI; private int nSeeds = 0; + private abstract static class UserRNGRootNodeAdapter extends RootNode { + @Child protected UserRngRFFI.UserRngRFFINode userRngRFFINode = RFFIFactory.getRFFI().getUserRngRFFI().createUserRngRFFINode(); + + protected UserRNGRootNodeAdapter() { + super(RContext.getRRuntimeASTAccess().getTruffleRLanguage(), null, new FrameDescriptor()); + } + } + + private static final class GenericUserRNGRootNode extends UserRNGRootNodeAdapter { + @Override + public Object execute(VirtualFrame frame) { + Object[] args = frame.getArguments(); + Function function = (Function) args[0]; + switch (function) { + case Init: + userRngRFFINode.init((int) args[1]); + return RNull.instance; + case NSeed: + return userRngRFFINode.nSeed(); + case Seedloc: + userRngRFFINode.seeds((int[]) args[1]); + return RNull.instance; + default: + throw RInternalError.shouldNotReachHere(); + } + } + } + + private static final class RandUserRNGRootNode extends UserRNGRootNodeAdapter { + + @Override + public Object execute(VirtualFrame frame) { + return userRngRFFINode.rand(); + } + + } + + private RootCallTarget callGeneric; + private RootCallTarget callRand; + @Override @TruffleBoundary public void init(int seed) { DLLInfo dllInfo = DLL.findLibraryContainingSymbol(Function.Rand.symbol); + callGeneric = Truffle.getRuntime().createCallTarget(new GenericUserRNGRootNode()); if (dllInfo == null) { throw RError.error(RError.NO_CALLER, RError.Message.RNG_SYMBOL, Function.Rand.symbol); } for (Function f : Function.values()) { f.setSymbolHandle(dllInfo); } - userRngRFFI = RFFIFactory.getRFFI().getUserRngRFFI(); if (Function.Init.isDefined()) { - userRngRFFI.init(seed); + callGeneric.call(Function.Init, seed); } if (Function.Seedloc.isDefined() && !Function.NSeed.isDefined()) { RError.warning(RError.NO_CALLER, RError.Message.RNG_READ_SEEDS); } if (Function.NSeed.isDefined()) { - int ns = userRngRFFI.nSeed(); + int ns = (int) callGeneric.call(Function.NSeed); if (ns < 0 || ns > 625) { RError.warning(RError.NO_CALLER, RError.Message.GENERIC, "seed length must be in 0...625; ignored"); } else { @@ -98,6 +145,7 @@ public final class UserRNG implements RandomNumberGenerator { */ } } + callRand = Truffle.getRuntime().createCallTarget(new RandUserRNGRootNode()); } private static DLL.SymbolHandle findSymbol(String symbol, DLLInfo dllInfo, boolean optional) { @@ -125,7 +173,7 @@ public final class UserRNG implements RandomNumberGenerator { return null; } int[] seeds = new int[nSeeds]; - userRngRFFI.seeds(seeds); + callGeneric.call(Function.Seedloc, seeds); int[] result = new int[nSeeds + 1]; System.arraycopy(seeds, 0, result, 1, seeds.length); return result; @@ -133,7 +181,7 @@ public final class UserRNG implements RandomNumberGenerator { @Override public double genrandDouble() { - return userRngRFFI.rand(); + return (double) callRand.call(); } @Override diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/NAMESPACE b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/NAMESPACE index e8d3772855c8cf98879a21dea3dcfd271e657c79..d4740fb354292dca72ba1633e4f2446b6d0858f4 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/NAMESPACE +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/NAMESPACE @@ -1,5 +1,5 @@ ## package has a dynamic library -useDynLib(testrffi) +useDynLib(testrffi, .registration = TRUE, .fixes = "C_") ## and exported functions exportPattern("rffi\\..*") diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R index 6f53923b5377add006be17e501fd321463e2ffff..54c5c79209d12d65cbee830a6d24a19af28e9fc4 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/testrffi.R @@ -1,3 +1,6 @@ +.onUnload <- function(libpath) + library.dynam.unload("testrffi", libpath) + rffi.dotCModifiedArguments <- function(data) { .C("dotCModifiedArguments", length(data), as.integer(data), as.double(data), as.logical(data)) } @@ -83,10 +86,6 @@ rffi.mkStringFromBytes <- function() { .Call("mkStringFromBytes", PACKAGE = "testrffi") } -rffi.null <- function() { - .Call("null", PACKAGE = "testrffi") -} - rffi.iterate_iarray <- function(x) { .Call("iterate_iarray", x, PACKAGE = "testrffi") } @@ -110,3 +109,16 @@ rffi.findvar <- function(x, env) { .Call("findvar", x, env, PACKAGE = "testrffi") } +rffi.null <- function() { + .Call("null", PACKAGE = "testrffi") +} + +rffi.null.E <- function() { + .Call("null", PACKAGE = "foo") +} + +rffi.null.C <- function() { + .Call(C_null) +} + + diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c index f46e8f1d2cf1125e443674261b0ef62f4c0caae6..5af8e6bb9f7b8298be0b5a6ee5a99fafd51ffe25 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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,47 @@ */ #include <R.h> #include <Rinternals.h> - #include <R_ext/Rdynload.h> +#include "testrffi.h" + +static const R_CMethodDef CEntries[] = { + {"dotCModifiedArguments", (DL_FUNC) &dotCModifiedArguments, 4}, + {NULL, NULL, 0} +}; + +#define CALLDEF(name, n) {#name, (DL_FUNC) &name, n} + +static const R_CallMethodDef CallEntries[] = { + CALLDEF(addInt, 2), + CALLDEF(addDouble, 2), + CALLDEF(populateIntVector, 1), + CALLDEF(populateLogicalVector, 1), + CALLDEF(createExternalPtr, 3), + CALLDEF(getExternalPtrAddr, 1), + CALLDEF(invoke_TYPEOF, 1), + CALLDEF(invoke_error, 1), + CALLDEF(dot_external_access_args, 1), + CALLDEF(invoke_isString, 1), + CALLDEF(invoke12, 12), + CALLDEF(interactive, 0), + CALLDEF(tryEval, 2), + CALLDEF(rHomeDir, 0), + CALLDEF(nestedCall1, 2), + CALLDEF(nestedCall2, 1), + CALLDEF(r_home, 0), + CALLDEF(mkStringFromChar, 0), + CALLDEF(mkStringFromBytes, 0), + CALLDEF(null, 0), + CALLDEF(iterate_iarray, 1), + CALLDEF(iterate_iptr, 1), + CALLDEF(preserve_object, 0), + CALLDEF(release_object, 1), + CALLDEF(findvar, 2), + {NULL, NULL, 0} +}; void R_init_testrffi(DllInfo *dll) { - R_registerRoutines(dll, NULL, NULL, NULL, NULL); + R_registerRoutines(dll, CEntries, CallEntries, NULL, NULL); } diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c index 61f4862f88ee9e9ae9ea2f93e8c919517571f6c5..771587f95b8d1c384aa93b646a37563a6f0d1d04 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.c @@ -28,6 +28,7 @@ #include <Rinterface.h> #include <Rinternals.h> #include <Rinterface.h> +#include "testrffi.h" void dotCModifiedArguments(int* len, int* idata, double* rdata, int* ldata) { for (int i = 0; i < len[0]; i++) { diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h new file mode 100644 index 0000000000000000000000000000000000000000..44de64f3dacf7f6b4dcda78ca61fe0ab4b58eff2 --- /dev/null +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/testrffi.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016, 2016, 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. + */ +extern void dotCModifiedArguments(int* len, int* idata, double* rdata, int* ldata); + +extern SEXP addInt(SEXP a, SEXP b); + +extern SEXP addDouble(SEXP a, SEXP b); + +extern SEXP populateIntVector(SEXP n); + +extern SEXP populateLogicalVector(SEXP n); + +extern SEXP createExternalPtr(SEXP addr, SEXP tag, SEXP prot); + +extern SEXP getExternalPtrAddr(SEXP eptr); + +extern SEXP invoke_TYPEOF(SEXP x); + +extern SEXP invoke_error(SEXP msg); + +extern SEXP dot_external_access_args(SEXP args); + +extern SEXP invoke_isString(SEXP s); + +extern SEXP invoke12(SEXP a1, SEXP a2, SEXP a3, SEXP a4, SEXP a5, SEXP a6, SEXP a7, SEXP a8, SEXP a9, SEXP a10, SEXP a11, SEXP a12); + +extern SEXP interactive(void); + +extern SEXP tryEval(SEXP expr, SEXP env); + +extern SEXP rHomeDir(); + +extern SEXP nestedCall1(SEXP upcall, SEXP env); + +extern SEXP nestedCall2(SEXP v); + +extern SEXP r_home(void); + +extern SEXP mkStringFromChar(void); + +extern SEXP mkStringFromBytes(void); + +extern SEXP null(void); + +extern SEXP iterate_iarray(SEXP x); + +extern SEXP iterate_iptr(SEXP x); + +extern SEXP preserve_object(void); + +extern SEXP release_object(SEXP x); + +extern SEXP findvar(SEXP x, SEXP env); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index 411da557d81edc47a44d8cbd349fda7e8e3d329f..8fef252e8753cf9ccc3ec41ebc0250fcd584ecfe 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -120,6 +120,10 @@ Slot "j": [1] 42 +##com.oracle.truffle.r.test.S4.TestS4.testAllocation# +#{ setClass("foo", representation(j="numeric")); typeof(new("foo", j=42)) } +[1] "S4" + ##com.oracle.truffle.r.test.S4.TestS4.testClassCreation# #{ setClass("foo"); setClass("bar", representation(j = "numeric"), contains = "foo"); is.null(getClass("foo")@prototype) } [1] FALSE @@ -2717,6 +2721,34 @@ In anyDuplicated.default(c(1L, 2L, 1L, 1L, 3L, 2L), incomparables = "cat") : #anyNA(list(list(c(NA)),c(1)), recursive=c(FALSE,TRUE)) [1] FALSE +##com.oracle.truffle.r.test.builtins.TestBuiltin_anyNA.testanyNA3# +#anyNA(c(1, 2, 3)) +[1] FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_anyNA.testanyNA3# +#anyNA(c(1, NA, 3)) +[1] TRUE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_anyNA.testanyNA3# +#anyNA(c(1, NA, 3), recursive = TRUE) +[1] TRUE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_anyNA.testanyNA3# +#anyNA(list(a = c(1, 2, 3), b = 'a')) +[1] FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_anyNA.testanyNA3# +#anyNA(list(a = c(1, 2, 3), b = 'a'), recursive = TRUE) +[1] FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_anyNA.testanyNA3# +#anyNA(list(a = c(1, NA, 3), b = 'a')) +[1] FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_anyNA.testanyNA3# +#anyNA(list(a = c(1, NA, 3), b = 'a'), recursive = TRUE) +[1] TRUE + ##com.oracle.truffle.r.test.builtins.TestBuiltin_aperm.testAperm# #{ a = array(1:24,c(2,3,4)); b = aperm(a); c(dim(b)[1],dim(b)[2],dim(b)[3]) } [1] 4 3 2 @@ -5370,7 +5402,7 @@ character(0) #{ as.character(list(c(2L, 3L))) } [1] "2:3" -##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testAsCharacter#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testAsCharacter# #{ as.character(list(c(2L, 3L, 5L))) } [1] "c(2, 3, 5)" @@ -5562,7 +5594,7 @@ character(0) #argv <- list(c(-4, 4, 3.99, -1, -3.01));as.character(argv[[1]]); [1] "-4" "4" "3.99" "-1" "-3.01" -##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testascharacter36#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_ascharacter.testascharacter36# #argv <- list(list(exit.code = 0L, send = NULL));as.character(argv[[1]]); [1] "0" "NULL" @@ -16373,7 +16405,7 @@ invalid 'cutoff' value for 'deparse', using default #{ det(matrix(c(1,-3,4,-5),nrow=2)) } [1] 7 -##com.oracle.truffle.r.test.builtins.TestBuiltin_det.testDet#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_det.testDet# #{ det(matrix(c(1,0,4,NA),nrow=2)) } [1] NA @@ -17916,6 +17948,10 @@ NULL [,1] [1,] NA +##com.oracle.truffle.r.test.builtins.TestBuiltin_dimassign.testdimassign12# +#b <- c(a=1+2i,b=3+4i);dim(b) <- c(2,1);attributes(x) +Error: object 'x' not found + ##com.oracle.truffle.r.test.builtins.TestBuiltin_dimassign.testdimassign2# #argv <- list(structure(logical(0), .Dim = c(0L, 0L)), value = c(0L, 0L));`dim<-`(argv[[1]],argv[[2]]); <0 x 0 matrix> @@ -22493,7 +22529,7 @@ attr(,"Rd_tag") #argv <- list(structure(c(NA, 2, NA, 1, NA, 0), .Dim = 2:3), structure(c(NA, 2, NA, 1, NA, 0), .Dim = 2:3), TRUE, TRUE, TRUE, TRUE, FALSE); .Internal(identical(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]])) [1] TRUE -##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testidentical20#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testidentical20# #argv <- list(NaN, NaN, TRUE, TRUE, TRUE, TRUE, FALSE); .Internal(identical(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]])) [1] TRUE @@ -22561,7 +22597,7 @@ attr(,"Rd_tag") #argv <- structure(list(x = structure(list(X1.4 = 1:4), .Names = 'X1.4', row.names = c(NA, -4L), class = 'data.frame'), y = structure(list(X1.4 = 1:4), .Names = 'X1.4', row.names = c('1', '2', '3', '4'), class = 'data.frame')), .Names = c('x', 'y'));do.call('identical', argv) [1] FALSE -##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testidentical37#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testidentical37# #argv <- structure(list(x = structure(list(a = NA, b = NA_integer_, c = NA_real_, d = NA_complex_, e = 1, f = 1L, g = 1:3, h = c(NA, 1L, 2L, 3L), i = NA_character_, j = c('foo', NA, 'bar')), .Names = c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')), y = structure(list(a = NA, b = NA_integer_, c = NA_real_, d = NA_complex_, e = 1, f = 1L, g = 1:3, h = c(NA, 1L, 2L, 3L), i = NA_character_, j = c('foo', NA, 'bar')), .Names = c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'))), .Names = c('x', 'y'));do.call('identical', argv) [1] TRUE @@ -29260,7 +29296,7 @@ Error in lockEnvironment("foo", TRUE) : not an environment [1,] 0.00000 0.47712 [2,] 0.30103 0.60206 -##com.oracle.truffle.r.test.builtins.TestBuiltin_log10.testLog10#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_log10.testLog10# #{ x <- c(a=1, b=10) ; round( c(log(x), log10(x), log2(x)), digits=5 ) } a b a b a b 0.00000 2.30259 0.00000 1.00000 0.00000 3.32193 @@ -39362,7 +39398,7 @@ complex(0) #argv <- list(c(1, 8, 28, 56, 70, 56, 28, 8, 1)); .Internal(polyroot(argv[[1]])) [1] -1-0i -1+0i -1+0i -1-0i -1-0i -1-0i -1-0i -1-0i -##com.oracle.truffle.r.test.builtins.TestBuiltin_pretty.testpretty1#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_pretty.testpretty1# #argv <- list(0L, 3L, 5, 1, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]])) $l [1] 0 @@ -39374,7 +39410,7 @@ $n [1] 6 -##com.oracle.truffle.r.test.builtins.TestBuiltin_pretty.testpretty2#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_pretty.testpretty2# #argv <- list(-0.03, 1.11, 5, 1, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]])) $l [1] -0.2 @@ -39386,7 +39422,7 @@ $n [1] 7 -##com.oracle.truffle.r.test.builtins.TestBuiltin_pretty.testpretty3#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_pretty.testpretty3# #argv <- list(-6.64448090063514e-06, 6.64454021993011e-06, 1, 0, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]])) $l [1] -1e-05 @@ -39398,7 +39434,7 @@ $n [1] 2 -##com.oracle.truffle.r.test.builtins.TestBuiltin_pretty.testpretty4#Ignored.Unknown# +##com.oracle.truffle.r.test.builtins.TestBuiltin_pretty.testpretty4# #argv <- list(1.234e+100, 1.234e+100, 5, 1, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]])) $l [1] 1.2e+100 @@ -41158,6 +41194,186 @@ Error in rawShift(x = as.raw(c(0x00, 0x01, 0x20, 0x7f, 0x80, 0xff, 0x7b : Error in rawShift(x = as.raw(c(0x00, 0x01, 0x20, 0x7f, 0x80, 0xff, 0x7b : argument 'shift' must be a small integer +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits('a') +Error in rawToBits("a") : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(01) +Error in rawToBits(1) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(0:255) +Error in rawToBits(0:255) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(NA) +Error in rawToBits(NA) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(NULL) +Error in rawToBits(NULL) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(as.raw(0)) +[1] 00 00 00 00 00 00 00 00 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(as.raw(0:255)) + [1] 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 + [25] 01 01 00 00 00 00 00 00 00 00 01 00 00 00 00 00 01 00 01 00 00 00 00 00 + [49] 00 01 01 00 00 00 00 00 01 01 01 00 00 00 00 00 00 00 00 01 00 00 00 00 + [73] 01 00 00 01 00 00 00 00 00 01 00 01 00 00 00 00 01 01 00 01 00 00 00 00 + [97] 00 00 01 01 00 00 00 00 01 00 01 01 00 00 00 00 00 01 01 01 00 00 00 00 + [121] 01 01 01 01 00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00 + [145] 00 01 00 00 01 00 00 00 01 01 00 00 01 00 00 00 00 00 01 00 01 00 00 00 + [169] 01 00 01 00 01 00 00 00 00 01 01 00 01 00 00 00 01 01 01 00 01 00 00 00 + [193] 00 00 00 01 01 00 00 00 01 00 00 01 01 00 00 00 00 01 00 01 01 00 00 00 + [217] 01 01 00 01 01 00 00 00 00 00 01 01 01 00 00 00 01 00 01 01 01 00 00 00 + [241] 00 01 01 01 01 00 00 00 01 01 01 01 01 00 00 00 00 00 00 00 00 01 00 00 + [265] 01 00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 01 01 00 00 00 01 00 00 + [289] 00 00 01 00 00 01 00 00 01 00 01 00 00 01 00 00 00 01 01 00 00 01 00 00 + [313] 01 01 01 00 00 01 00 00 00 00 00 01 00 01 00 00 01 00 00 01 00 01 00 00 + [337] 00 01 00 01 00 01 00 00 01 01 00 01 00 01 00 00 00 00 01 01 00 01 00 00 + [361] 01 00 01 01 00 01 00 00 00 01 01 01 00 01 00 00 01 01 01 01 00 01 00 00 + [385] 00 00 00 00 01 01 00 00 01 00 00 00 01 01 00 00 00 01 00 00 01 01 00 00 + [409] 01 01 00 00 01 01 00 00 00 00 01 00 01 01 00 00 01 00 01 00 01 01 00 00 + [433] 00 01 01 00 01 01 00 00 01 01 01 00 01 01 00 00 00 00 00 01 01 01 00 00 + [457] 01 00 00 01 01 01 00 00 00 01 00 01 01 01 00 00 01 01 00 01 01 01 00 00 + [481] 00 00 01 01 01 01 00 00 01 00 01 01 01 01 00 00 00 01 01 01 01 01 00 00 + [505] 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 01 00 + [529] 00 01 00 00 00 00 01 00 01 01 00 00 00 00 01 00 00 00 01 00 00 00 01 00 + [553] 01 00 01 00 00 00 01 00 00 01 01 00 00 00 01 00 01 01 01 00 00 00 01 00 + [577] 00 00 00 01 00 00 01 00 01 00 00 01 00 00 01 00 00 01 00 01 00 00 01 00 + [601] 01 01 00 01 00 00 01 00 00 00 01 01 00 00 01 00 01 00 01 01 00 00 01 00 + [625] 00 01 01 01 00 00 01 00 01 01 01 01 00 00 01 00 00 00 00 00 01 00 01 00 + [649] 01 00 00 00 01 00 01 00 00 01 00 00 01 00 01 00 01 01 00 00 01 00 01 00 + [673] 00 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 00 01 01 00 01 00 01 00 + [697] 01 01 01 00 01 00 01 00 00 00 00 01 01 00 01 00 01 00 00 01 01 00 01 00 + [721] 00 01 00 01 01 00 01 00 01 01 00 01 01 00 01 00 00 00 01 01 01 00 01 00 + [745] 01 00 01 01 01 00 01 00 00 01 01 01 01 00 01 00 01 01 01 01 01 00 01 00 + [769] 00 00 00 00 00 01 01 00 01 00 00 00 00 01 01 00 00 01 00 00 00 01 01 00 + [793] 01 01 00 00 00 01 01 00 00 00 01 00 00 01 01 00 01 00 01 00 00 01 01 00 + [817] 00 01 01 00 00 01 01 00 01 01 01 00 00 01 01 00 00 00 00 01 00 01 01 00 + [841] 01 00 00 01 00 01 01 00 00 01 00 01 00 01 01 00 01 01 00 01 00 01 01 00 + [865] 00 00 01 01 00 01 01 00 01 00 01 01 00 01 01 00 00 01 01 01 00 01 01 00 + [889] 01 01 01 01 00 01 01 00 00 00 00 00 01 01 01 00 01 00 00 00 01 01 01 00 + [913] 00 01 00 00 01 01 01 00 01 01 00 00 01 01 01 00 00 00 01 00 01 01 01 00 + [937] 01 00 01 00 01 01 01 00 00 01 01 00 01 01 01 00 01 01 01 00 01 01 01 00 + [961] 00 00 00 01 01 01 01 00 01 00 00 01 01 01 01 00 00 01 00 01 01 01 01 00 + [985] 01 01 00 01 01 01 01 00 00 00 01 01 01 01 01 00 01 00 01 01 01 01 01 00 +[1009] 00 01 01 01 01 01 01 00 01 01 01 01 01 01 01 00 00 00 00 00 00 00 00 01 +[1033] 01 00 00 00 00 00 00 01 00 01 00 00 00 00 00 01 01 01 00 00 00 00 00 01 +[1057] 00 00 01 00 00 00 00 01 01 00 01 00 00 00 00 01 00 01 01 00 00 00 00 01 +[1081] 01 01 01 00 00 00 00 01 00 00 00 01 00 00 00 01 01 00 00 01 00 00 00 01 +[1105] 00 01 00 01 00 00 00 01 01 01 00 01 00 00 00 01 00 00 01 01 00 00 00 01 +[1129] 01 00 01 01 00 00 00 01 00 01 01 01 00 00 00 01 01 01 01 01 00 00 00 01 +[1153] 00 00 00 00 01 00 00 01 01 00 00 00 01 00 00 01 00 01 00 00 01 00 00 01 +[1177] 01 01 00 00 01 00 00 01 00 00 01 00 01 00 00 01 01 00 01 00 01 00 00 01 +[1201] 00 01 01 00 01 00 00 01 01 01 01 00 01 00 00 01 00 00 00 01 01 00 00 01 +[1225] 01 00 00 01 01 00 00 01 00 01 00 01 01 00 00 01 01 01 00 01 01 00 00 01 +[1249] 00 00 01 01 01 00 00 01 01 00 01 01 01 00 00 01 00 01 01 01 01 00 00 01 +[1273] 01 01 01 01 01 00 00 01 00 00 00 00 00 01 00 01 01 00 00 00 00 01 00 01 +[1297] 00 01 00 00 00 01 00 01 01 01 00 00 00 01 00 01 00 00 01 00 00 01 00 01 +[1321] 01 00 01 00 00 01 00 01 00 01 01 00 00 01 00 01 01 01 01 00 00 01 00 01 +[1345] 00 00 00 01 00 01 00 01 01 00 00 01 00 01 00 01 00 01 00 01 00 01 00 01 +[1369] 01 01 00 01 00 01 00 01 00 00 01 01 00 01 00 01 01 00 01 01 00 01 00 01 +[1393] 00 01 01 01 00 01 00 01 01 01 01 01 00 01 00 01 00 00 00 00 01 01 00 01 +[1417] 01 00 00 00 01 01 00 01 00 01 00 00 01 01 00 01 01 01 00 00 01 01 00 01 +[1441] 00 00 01 00 01 01 00 01 01 00 01 00 01 01 00 01 00 01 01 00 01 01 00 01 +[1465] 01 01 01 00 01 01 00 01 00 00 00 01 01 01 00 01 01 00 00 01 01 01 00 01 +[1489] 00 01 00 01 01 01 00 01 01 01 00 01 01 01 00 01 00 00 01 01 01 01 00 01 +[1513] 01 00 01 01 01 01 00 01 00 01 01 01 01 01 00 01 01 01 01 01 01 01 00 01 +[1537] 00 00 00 00 00 00 01 01 01 00 00 00 00 00 01 01 00 01 00 00 00 00 01 01 +[1561] 01 01 00 00 00 00 01 01 00 00 01 00 00 00 01 01 01 00 01 00 00 00 01 01 +[1585] 00 01 01 00 00 00 01 01 01 01 01 00 00 00 01 01 00 00 00 01 00 00 01 01 +[1609] 01 00 00 01 00 00 01 01 00 01 00 01 00 00 01 01 01 01 00 01 00 00 01 01 +[1633] 00 00 01 01 00 00 01 01 01 00 01 01 00 00 01 01 00 01 01 01 00 00 01 01 +[1657] 01 01 01 01 00 00 01 01 00 00 00 00 01 00 01 01 01 00 00 00 01 00 01 01 +[1681] 00 01 00 00 01 00 01 01 01 01 00 00 01 00 01 01 00 00 01 00 01 00 01 01 +[1705] 01 00 01 00 01 00 01 01 00 01 01 00 01 00 01 01 01 01 01 00 01 00 01 01 +[1729] 00 00 00 01 01 00 01 01 01 00 00 01 01 00 01 01 00 01 00 01 01 00 01 01 +[1753] 01 01 00 01 01 00 01 01 00 00 01 01 01 00 01 01 01 00 01 01 01 00 01 01 +[1777] 00 01 01 01 01 00 01 01 01 01 01 01 01 00 01 01 00 00 00 00 00 01 01 01 +[1801] 01 00 00 00 00 01 01 01 00 01 00 00 00 01 01 01 01 01 00 00 00 01 01 01 +[1825] 00 00 01 00 00 01 01 01 01 00 01 00 00 01 01 01 00 01 01 00 00 01 01 01 +[1849] 01 01 01 00 00 01 01 01 00 00 00 01 00 01 01 01 01 00 00 01 00 01 01 01 +[1873] 00 01 00 01 00 01 01 01 01 01 00 01 00 01 01 01 00 00 01 01 00 01 01 01 +[1897] 01 00 01 01 00 01 01 01 00 01 01 01 00 01 01 01 01 01 01 01 00 01 01 01 +[1921] 00 00 00 00 01 01 01 01 01 00 00 00 01 01 01 01 00 01 00 00 01 01 01 01 +[1945] 01 01 00 00 01 01 01 01 00 00 01 00 01 01 01 01 01 00 01 00 01 01 01 01 +[1969] 00 01 01 00 01 01 01 01 01 01 01 00 01 01 01 01 00 00 00 01 01 01 01 01 +[1993] 01 00 00 01 01 01 01 01 00 01 00 01 01 01 01 01 01 01 00 01 01 01 01 01 +[2017] 00 00 01 01 01 01 01 01 01 00 01 01 01 01 01 01 00 01 01 01 01 01 01 01 +[2041] 01 01 01 01 01 01 01 01 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(as.raw(1)) +[1] 01 00 00 00 00 00 00 00 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(as.raw(1)[1]) +[1] 01 00 00 00 00 00 00 00 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(as.raw(255)) +[1] 01 01 01 01 01 01 01 01 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(as.raw(c(0,1,255))) + [1] 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 01 01 01 01 01 01 01 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(c(NULL)) +Error in rawToBits(c(NULL)) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(c(as.raw(1), as.raw(255))) + [1] 01 00 00 00 00 00 00 00 01 01 01 01 01 01 01 01 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(double(0)) +Error in rawToBits(double(0)) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(environment) +Error in rawToBits(environment) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(integer(0)) +Error in rawToBits(integer(0)) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(list(NULL)) +Error in rawToBits(list(NULL)) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(list(list())) +Error in rawToBits(list(list())) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(new.env()) +Error in rawToBits(new.env()) : argument 'x' must be a raw vector + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(raw(0)) +raw(0) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(raw(0), raw(1)) +Error in rawToBits(raw(0), raw(1)) : unused argument (raw(1)) + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(raw(10)) + [1] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[26] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[51] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +[76] 00 00 00 00 00 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToBits.testRawToBits# +#rawToBits(stdout()) +Error in rawToBits(stdout()) : argument 'x' must be a raw vector + ##com.oracle.truffle.r.test.builtins.TestBuiltin_rawToChar.testrawToChar1# #argv <- structure(list(x = as.raw(c(115, 116, 114, 105, 110, 103))), .Names = 'x');do.call('rawToChar', argv) [1] "string" @@ -45739,6 +45955,54 @@ integer(0) #argv <- list(29);sign(argv[[1]]); [1] 1 +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign('1') +Error in sign("1") : non-numeric argument to mathematical function + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign('1L') +Error in sign("1L") : non-numeric argument to mathematical function + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign('a') +Error in sign("a") : non-numeric argument to mathematical function + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign(1i) +Error in sign(0+1i) : unimplemented complex function + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign(NA_real_) +[1] NA + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign(NULL) +Error in sign(NULL) : non-numeric argument to mathematical function + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign(NaN) +[1] NaN + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign(c(1, -1, FALSE)) +[1] 1 -1 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign(c(1, -1, FALSE, 1i)) +Error in sign(c(1, -1, FALSE, 0+1i)) : unimplemented complex function + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign(c(FALSE)) +[1] 0 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign(c(FALSE, TRUE)) +[1] 0 1 + +##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign10# +#sign(list(c(1, -1, FALSE))[[1]]) +[1] 1 -1 0 + ##com.oracle.truffle.r.test.builtins.TestBuiltin_sign.testsign2# #argv <- list(-29);sign(argv[[1]]); [1] -1 @@ -113686,6 +113950,38 @@ Warning message: In rgamma(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, : NAs produced +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace# +#set.seed(1); rlnorm(10, 10, 10) + [1] 4.190738e+01 1.381967e+05 5.174351e+00 1.867073e+11 5.942633e+05 + [6] 6.021378e+00 2.882852e+06 3.543629e+07 6.974795e+06 1.039106e+03 + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace# +#set.seed(1); rlnorm(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) + [1] NaN 1.0000000 1.1472349 8.7170336 1.6374074 NaN + [7] 148.4131591 0.4315068 1.3452192 0.1042040 NaN 20.0855369 +[13] 57.3253483 288.4414833 2.0695766 NaN 1.2214028 7.1668137 +[19] 78.3043417 175.8321258 +Warning message: +In rlnorm(20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)) : NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace# +#set.seed(1); rlnorm(24, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1)) + [1] 1.0246925 1.0001456 1.0000000 Inf Inf 1.0674792 NaN + [8] 0.9478333 Inf Inf Inf 0.0000000 1.0000000 NaN +[15] Inf 1.0675304 1.0001230 0.0000000 Inf Inf NaN +[22] 0.9971928 0.9999980 Inf +Warning message: +In rlnorm(24, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653, : + NAs produced + +##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace# +#set.seed(1); rlnorm(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0)) + [1] NaN NaN NaN Inf NaN NaN NaN NaN NaN 0 NaN NaN NaN NaN NaN NaN NaN NaN NaN +[20] NaN NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN +Warning message: +In rlnorm(30, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, : + NAs produced + ##com.oracle.truffle.r.test.library.stats.TestRandGenerationFunctions.testFunctions2#Output.IgnoreWhitespace# #set.seed(1); rlogis(10, 10, 10) [1] -0.1753073 4.7688401 12.9350241 32.9194576 -3.7581524 31.7945887 @@ -113954,6 +114250,1707 @@ B 5 8 4 7 6 2 6 [2,] 2 0 0 1 0 [3,] 1 2 3 2 3 +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dchisq(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE) +[1] Inf Inf Inf 0 0 Inf NaN +Warning message: +In dchisq(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dchisq(10, 10, log=TRUE) +[1] -2.433449 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dchisq(3, 3, log=FALSE) +[1] 0.1541803 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=FALSE) + [1] NaN Inf 0.207096473 0.093458828 0.000000000 NaN + [7] 0.000000000 0.009447299 0.000000000 0.000000000 NaN 0.000000000 +[13] 0.000000000 Inf 0.161434226 NaN 0.000000000 Inf +[19] 0.815615297 0.207553749 +Warning message: +In dchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=TRUE) + [1] NaN Inf -1.5745705 -2.3702343 -Inf NaN + [7] -Inf -4.6620264 -Inf -Inf NaN -Inf +[13] -Inf Inf -1.8236575 NaN -Inf Inf +[19] -0.2038125 -1.5723649 +Warning message: +In dchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dchisq(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log=FALSE) + [1] NA Inf NaN 0 0 NA Inf NaN 0 0 NA Inf NaN 0 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE) +[1] 6.530e-02 1.230e-04 3.200e-79 8.833e+03 7.900e+71 0.000e+00 NaN +Warning message: +In dexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), log = FALSE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dexp(10, 10, log=TRUE) +[1] -97.69741 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dexp(3, 3, log=FALSE) +[1] 0.0003702294 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=FALSE) + [1] NaN 0.000000000 0.098019867 0.148768999 0.000000000 NaN + [7] 0.000000000 0.081873075 0.000000000 3.000000000 NaN 0.000000000 +[13] 0.000000000 0.900000000 1.646434908 NaN 0.000000000 0.100000000 +[19] 0.751743190 0.007436257 +Warning message: +In dexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=TRUE) + [1] NaN -Inf -2.3225851 -1.9053605 -Inf NaN + [7] -Inf -2.5025851 -Inf 1.0986123 NaN -Inf +[13] -Inf -0.1053605 0.4986123 NaN -Inf -2.3025851 +[19] -0.2853605 -4.9013877 +Warning message: +In dexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log=FALSE) + [1] NA 0.0 NaN 0.0 0.0 NA 1.0 NaN 0.0 0.0 NA 0.1 NaN NaN 0.0 +Warning message: +In dexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log = FALSE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dgeom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE) +[1] 6.53e-02 1.23e-04 3.20e-79 NaN NaN NaN NaN +Warning message: +In dgeom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dgeom(10, 10, log=TRUE) +[1] NaN +Warning message: +In dgeom(10, 10, log = TRUE) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dgeom(3, 3, log=FALSE) +[1] NaN +Warning message: +In dgeom(3, 3, log = FALSE) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=FALSE) + [1] NaN NaN 0.000 0.009 NaN NaN NaN 0.081 0.000 NaN NaN NaN +[13] 0.000 0.900 NaN NaN NaN 0.100 0.000 NaN +Warning messages: +1: In dgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + non-integer x = 0.200000 +2: In dgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + non-integer x = 0.200000 +3: In dgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=TRUE) + [1] NaN NaN -Inf -4.7105307 NaN NaN + [7] NaN -2.5133061 -Inf NaN NaN NaN +[13] -Inf -0.1053605 NaN NaN NaN -2.3025851 +[19] -Inf NaN +Warning messages: +1: In dgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + non-integer x = 0.200000 +2: In dgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + non-integer x = 0.200000 +3: In dgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dgeom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log=FALSE) + [1] NA NaN NaN 0.0 NaN NA 1.0 NaN 0.0 0.0 NA 0.1 NaN NaN 0.0 +Warning message: +In dgeom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log = FALSE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dpois(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE) +[1] 0.9367864 0.9998770 1.0000000 0.0000000 0.0000000 1.0000000 NaN +Warning message: +In dpois(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dpois(10, 10, log=TRUE) +[1] -2.078562 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dpois(3, 3, log=FALSE) +[1] 0.2240418 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=FALSE) + [1] NaN 1.000000000 0.000000000 0.164660712 0.000000000 NaN + [7] 0.000000000 0.004524187 0.000000000 0.049787068 NaN 0.000000000 +[13] 0.000000000 0.406569660 0.000000000 NaN 0.000000000 0.904837418 +[19] 0.000000000 0.224041808 +Warning messages: +1: In dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + non-integer x = 0.200000 +2: In dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + non-integer x = 0.200000 +3: In dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + non-integer x = 0.200000 +4: In dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + non-integer x = 0.200000 +5: In dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=TRUE) + [1] NaN 0.000000 -Inf -1.803868 -Inf NaN -Inf + [8] -5.398317 -Inf -3.000000 NaN -Inf -Inf -0.900000 +[15] -Inf NaN -Inf -0.100000 -Inf -1.495923 +Warning messages: +1: In dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + non-integer x = 0.200000 +2: In dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + non-integer x = 0.200000 +3: In dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + non-integer x = 0.200000 +4: In dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + non-integer x = 0.200000 +5: In dpois(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dpois(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log=FALSE) + [1] NA 1.0000000 NaN 0.0000000 0.0000000 NA 0.3678794 + [8] NaN 0.0000000 0.0000000 NA 0.9048374 NaN 0.0000000 +[15] 0.0000000 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dt(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE) +[1] 1.223197e-01 5.544796e-03 2.828427e-40 3.989310e-01 3.989423e-01 +[6] NaN NaN +Warning message: +In dt(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), log = FALSE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dt(10, 10, log=TRUE) +[1] -14.13232 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dt(3, 3, log=FALSE) +[1] 0.02297204 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=FALSE) + [1] NaN NaN 0.12307265 0.06230778 0.20674834 NaN + [7] NaN 0.01920883 0.15325430 0.36755260 NaN NaN +[13] 0.03960646 0.31167229 0.35794379 NaN NaN 0.14809212 +[19] 0.29905916 0.06750966 +Warning message: +In dt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = FALSE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=TRUE) + [1] NaN NaN -2.094980 -2.775669 -1.576253 NaN NaN + [8] -3.952385 -1.875657 -1.000889 NaN NaN -3.228763 -1.165803 +[15] -1.027379 NaN NaN -1.909921 -1.207114 -2.695485 +Warning message: +In dt(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log = TRUE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions21#Output.IgnoreWhitespace# +#set.seed(1); dt(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log=FALSE) + [1] NA NaN NaN 0.0000000 NaN NA 0.3183099 + [8] NaN 0.0000000 0.0000000 NA 0.1480921 NaN NaN +[15] 0.0000000 +Warning message: +In dt(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log = FALSE) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(0, 10, lower.tail=FALSE, log.p=FALSE) +[1] 1 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(0, 10, lower.tail=FALSE, log.p=TRUE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(0, 10, lower.tail=TRUE, log.p=FALSE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(0, 10, lower.tail=TRUE, log.p=TRUE) +[1] -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE) +[1] 1 1 1 1 1 1 NaN +Warning message: +In pchisq(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE) +[1] 0 0 0 0 0 0 NaN +Warning message: +In pchisq(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE) +[1] 0 0 0 0 0 0 NaN +Warning message: +In pchisq(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE) +[1] -Inf -Inf -Inf -Inf -Inf -Inf NaN +Warning message: +In pchisq(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE) + [1] NaN 1.00000000 0.08874237 0.13808560 1.00000000 NaN + [7] 0.00000000 0.01152365 1.00000000 1.00000000 NaN 0.00000000 +[13] 1.00000000 1.00000000 0.97758930 NaN 1.00000000 1.00000000 +[19] 0.61145396 0.57240670 +Warning message: +In pchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE) + [1] NaN 0.00000000 -2.42201777 -1.97988153 0.00000000 NaN + [7] -Inf -4.46335358 0.00000000 0.00000000 NaN -Inf +[13] 0.00000000 0.00000000 -0.02266564 NaN 0.00000000 0.00000000 +[19] -0.49191562 -0.55790552 +Warning message: +In pchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE) + [1] NaN 0.0000000 0.9112576 0.8619144 0.0000000 NaN 1.0000000 + [8] 0.9884763 0.0000000 0.0000000 NaN 1.0000000 0.0000000 0.0000000 +[15] 0.0224107 NaN 0.0000000 0.0000000 0.3885460 0.4275933 +Warning message: +In pchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE) + [1] NaN -Inf -0.09292963 -0.14859931 -Inf NaN + [7] 0.00000000 -0.01159056 -Inf -Inf NaN 0.00000000 +[13] -Inf -Inf -3.79821666 NaN -Inf -Inf +[19] -0.94534361 -0.84958278 +Warning message: +In pchisq(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) + [1] NA 0 NaN 1 0 NA 0 NaN 1 0 NA 0 NaN 1 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pchisq(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) + [1] NA 0 NaN NaN NaN NA 1 NaN NaN NaN NA 1 NaN 0 NaN +Warning messages: +1: In pchisq(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : + value out of range in 'lgamma' +2: In pchisq(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : + value out of range in 'lgamma' +3: In pchisq(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(0, 10, lower.tail=FALSE, log.p=FALSE) +[1] 1 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(0, 10, lower.tail=FALSE, log.p=TRUE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(0, 10, lower.tail=TRUE, log.p=FALSE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(0, 10, lower.tail=TRUE, log.p=TRUE) +[1] -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE) +[1] 1 1 1 1 1 1 NaN +Warning message: +In pexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE) +[1] 0 0 0 0 0 0 NaN +Warning message: +In pexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE) +[1] 0 0 0 0 0 0 NaN +Warning message: +In pexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE) +[1] -Inf -Inf -Inf -Inf -Inf -Inf NaN +Warning message: +In pexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE) + [1] NaN 1.000000000 0.980198673 0.165298888 1.000000000 NaN + [7] 1.000000000 0.818730753 1.000000000 1.000000000 NaN 1.000000000 +[13] 1.000000000 1.000000000 0.548811636 NaN 1.000000000 1.000000000 +[19] 0.835270211 0.002478752 +Warning message: +In pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE) + [1] NaN 0.00 -0.02 -1.80 0.00 NaN 0.00 -0.20 0.00 0.00 NaN 0.00 +[13] 0.00 0.00 -0.60 NaN 0.00 0.00 -0.18 -6.00 +Warning message: +In pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE) + [1] NaN 0.00000000 0.01980133 0.83470111 0.00000000 NaN + [7] 0.00000000 0.18126925 0.00000000 0.00000000 NaN 0.00000000 +[13] 0.00000000 0.00000000 0.45118836 NaN 0.00000000 0.00000000 +[19] 0.16472979 0.99752125 +Warning message: +In pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE) + [1] NaN -Inf -3.922006339 -0.180681568 -Inf + [6] NaN -Inf -1.707771801 -Inf -Inf +[11] NaN -Inf -Inf -Inf -0.795870368 +[16] NaN -Inf -Inf -1.803448792 -0.002481829 +Warning message: +In pexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) + [1] NA 0 NaN 1 0 NA 0 NaN 1 0 NA 0 NaN NaN 0 +Warning message: +In pexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); pexp(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) + [1] NA 0 NaN 1 0 NA 0 NaN 1 -Inf NA 0 NaN 0 -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(0, 10, lower.tail=FALSE, log.p=FALSE) +[1] Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(0, 10, lower.tail=FALSE, log.p=TRUE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(0, 10, lower.tail=TRUE, log.p=FALSE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(0, 10, lower.tail=TRUE, log.p=TRUE) +[1] Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE) +[1] Inf Inf Inf Inf Inf Inf NaN +Warning message: +In qexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE) +[1] 0 0 0 0 0 0 NaN +Warning message: +In qexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE) +[1] 0 0 0 0 0 0 NaN +Warning message: +In qexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE) +[1] Inf Inf Inf Inf Inf Inf NaN +Warning message: +In qexp(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE) + [1] NaN Inf 16.0943791 NaN NaN NaN + [7] Inf NaN NaN Inf NaN NaN +[13] NaN Inf 0.5364793 NaN NaN Inf +[19] 1.7882643 NaN +Warning message: +In qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE) + [1] NaN 0.0000000 NaN NaN 0.3333333 NaN + [7] NaN NaN 1.1111111 0.0000000 NaN NaN +[13] 10.0000000 0.0000000 NaN NaN Inf 0.0000000 +[19] NaN NaN +Warning message: +In qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE) + [1] NaN 0.00000000 2.23143551 NaN NaN NaN + [7] Inf NaN NaN 0.00000000 NaN NaN +[13] NaN 0.00000000 0.07438118 NaN NaN 0.00000000 +[19] 0.24793728 NaN +Warning message: +In qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE) + [1] NaN Inf NaN NaN 0.1528917 NaN NaN + [8] NaN 0.5096391 Inf NaN NaN 4.5867515 Inf +[15] NaN NaN Inf Inf NaN NaN +Warning message: +In qexp(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) + [1] NA 0 NaN NaN NaN NA 0 NaN NaN NaN NA 0 NaN NaN NaN +Warning message: +In qexp(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qexp(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) + [1] NA 0 NaN NaN 0 NA Inf NaN 0 NaN NA Inf NaN 0 0 +Warning message: +In qexp(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(0, 10, lower.tail=FALSE, log.p=FALSE) +[1] NaN +Warning message: +In qgeom(0, 10, lower.tail = FALSE, log.p = FALSE) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(0, 10, lower.tail=FALSE, log.p=TRUE) +[1] NaN +Warning message: +In qgeom(0, 10, lower.tail = FALSE, log.p = TRUE) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(0, 10, lower.tail=TRUE, log.p=FALSE) +[1] NaN +Warning message: +In qgeom(0, 10, lower.tail = TRUE, log.p = FALSE) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(0, 10, lower.tail=TRUE, log.p=TRUE) +[1] NaN +Warning message: +In qgeom(0, 10, lower.tail = TRUE, log.p = TRUE) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=FALSE) +[1] Inf Inf Inf NaN NaN NaN NaN +Warning message: +In qgeom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=FALSE, log.p=TRUE) +[1] 0 0 0 NaN NaN NaN NaN +Warning message: +In qgeom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=FALSE) +[1] 0 0 0 NaN NaN NaN NaN +Warning message: +In qgeom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), lower.tail=TRUE, log.p=TRUE) +[1] Inf Inf Inf NaN NaN NaN NaN +Warning message: +In qgeom(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=FALSE) + [1] NaN NaN 15 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN Inf NaN NaN NaN Inf 0 +[20] NaN +Warning message: +In qgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=FALSE, log.p=TRUE) + [1] NaN NaN NaN NaN NaN NaN NaN NaN 0 NaN NaN NaN 9 0 NaN NaN NaN 0 NaN +[20] NaN +Warning message: +In qgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = FALSE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=FALSE) + [1] NaN NaN 2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0 NaN NaN NaN 0 0 +[20] NaN +Warning message: +In qgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail=TRUE, log.p=TRUE) + [1] NaN NaN NaN NaN NaN NaN NaN NaN 0 NaN NaN NaN 4 Inf NaN NaN NaN Inf NaN +[20] NaN +Warning message: +In qgeom(c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), lower.tail = TRUE, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) + [1] NA NaN NaN NaN NaN NA 0 NaN NaN NaN NA 0 NaN NaN NaN +Warning message: +In qgeom(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions22#Output.IgnoreWhitespace# +#set.seed(1); qgeom(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) + [1] NA NaN NaN NaN NaN NA NaN NaN NaN NaN NA NaN NaN NaN NaN +Warning message: +In qgeom(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) : NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dbeta(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE) +[1] Inf Inf Inf 0 0 0 NaN +Warning message: +In dbeta(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dbeta(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE) +[1] NA NaN NA 0 NaN NA +Warning message: +In dbeta(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dbeta(10, 10, 10, log=TRUE) +[1] -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dbeta(3, 3, 3, log=FALSE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dbeta(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE) + [1] NaN Inf Inf 0 0 NaN 0 NaN 0 0 NaN Inf 0 0 NaN NaN 0 Inf 0 +[20] 0 NaN NaN Inf Inf 0 NaN Inf 0 NaN 0 NaN 0 Inf 0 0 NaN 0 Inf +[39] Inf 0 NaN Inf NaN Inf 0 NaN 0 Inf 0 NaN NaN 0 0 Inf 0 NaN NaN +[58] 0 Inf 0 +Warning message: +In dbeta(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dbeta(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE) + [1] NaN Inf Inf -Inf -Inf NaN -Inf NaN -Inf -Inf NaN Inf -Inf -Inf NaN +[16] NaN -Inf Inf -Inf -Inf NaN NaN Inf Inf -Inf NaN Inf -Inf NaN -Inf +[31] NaN -Inf Inf -Inf -Inf NaN -Inf Inf Inf -Inf NaN Inf NaN Inf -Inf +[46] NaN -Inf Inf -Inf NaN NaN -Inf -Inf Inf -Inf NaN NaN -Inf Inf -Inf +Warning message: +In dbeta(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dbeta(c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE) +[1] NA NaN 0 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE) +[1] 2.437289e+00 1.293943e+03 4.973592e+77 1.801822e-05 2.014620e-73 +[6] NaN NaN +Warning message: +In dcauchy(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dcauchy(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE) +[1] NA NaN NA NaN NaN NA +Warning message: +In dcauchy(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dcauchy(10, 10, 10, log=TRUE) +[1] -3.447315 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dcauchy(3, 3, 3, log=FALSE) +[1] 0.1061033 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dcauchy(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE) + [1] NaN NaN 0.0489707517 0.0292027419 0.0530516477 + [6] NaN NaN 0.0315158303 0.1582756340 0.0914683581 +[11] NaN NaN 0.0012727305 0.0110995311 0.0734561276 +[16] NaN NaN 0.0315158303 0.0170421712 0.0381971863 +[21] NaN NaN 3.1830988618 0.1975716535 0.0530516477 +[26] NaN NaN 0.0008839486 0.1582756340 0.0954929659 +[31] NaN NaN 0.0079379024 0.0110995311 0.0280861664 +[36] NaN NaN 0.6366197724 0.1582756340 0.0381971863 +[41] NaN NaN 3.1830988618 0.3536776513 0.0990590932 +[46] NaN NaN 0.0035328511 0.0077826378 0.0954929659 +[51] NaN NaN 0.0079379024 0.0595590224 0.0280861664 +[56] NaN NaN 0.0315158303 0.3370339971 0.0954929659 +Warning message: +In dcauchy(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dcauchy(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE) + [1] NaN NaN -3.0165321 -3.5334927 -2.9364894 NaN + [7] NaN -3.4572653 -1.8434172 -2.3917622 NaN NaN +[13] -6.6665907 -4.5008524 -2.6110670 NaN NaN -3.4572653 +[19] -4.0720643 -3.2649934 NaN NaN 1.1578552 -1.6216540 +[25] -2.9364894 NaN NaN -7.0311117 -1.8434172 -2.3487027 +[31] NaN NaN -4.8361062 -4.5008524 -3.5724781 NaN +[37] NaN -0.4515827 -1.8434172 -3.2649934 NaN NaN +[43] 1.1578552 -1.0393694 -2.3120387 NaN NaN -5.6456501 +[49] -4.8558599 -2.3487027 NaN NaN -4.8361062 -2.8207875 +[55] -3.5724781 NaN NaN -3.4572653 -1.0875715 -2.3487027 +Warning message: +In dcauchy(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dcauchy(c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE) +[1] NA NaN 0 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dgamma(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE) +[1] Inf Inf Inf 0 0 Inf NaN +Warning message: +In dgamma(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dgamma(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE) +[1] NA NaN NA 0 NaN NA +Warning message: +In dgamma(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dgamma(10, 10, 10, log=TRUE) +[1] -69.05271 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dgamma(3, 3, 3, log=FALSE) +[1] 0.01499429 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dgamma(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE) + [1] NaN Inf 1.243592e-01 0.000000e+00 0.000000e+00 + [6] NaN 0.000000e+00 NaN 0.000000e+00 0.000000e+00 +[11] NaN 0.000000e+00 0.000000e+00 0.000000e+00 NaN +[16] NaN Inf 9.048374e-03 0.000000e+00 0.000000e+00 +[21] NaN NaN Inf 8.671435e-02 0.000000e+00 +[26] NaN 0.000000e+00 0.000000e+00 NaN 0.000000e+00 +[31] NaN 0.000000e+00 4.524187e-04 0.000000e+00 0.000000e+00 +[36] NaN 0.000000e+00 Inf 3.293214e-01 0.000000e+00 +[41] NaN 0.000000e+00 NaN Inf 1.350978e-02 +[46] NaN 0.000000e+00 1.508062e-05 0.000000e+00 NaN +[51] NaN 0.000000e+00 0.000000e+00 1.481946e-01 0.000000e+00 +[56] NaN NaN 0.000000e+00 Inf 4.480836e-01 +Warning message: +In dgamma(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dgamma(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE) + [1] NaN Inf -2.0845808 -Inf -Inf NaN + [7] -Inf NaN -Inf -Inf NaN -Inf +[13] -Inf -Inf NaN NaN Inf -4.7051702 +[19] -Inf -Inf NaN NaN Inf -2.4451359 +[25] -Inf NaN -Inf -Inf NaN -Inf +[31] NaN -Inf -7.7009025 -Inf -Inf NaN +[37] -Inf Inf -1.1107210 -Inf NaN -Inf +[43] NaN Inf -4.3043414 NaN -Inf -11.1020998 +[49] -Inf NaN NaN -Inf -Inf -1.9092287 +[55] -Inf NaN NaN -Inf Inf -0.8027754 +Warning message: +In dgamma(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dgamma(c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE) +[1] NA NaN 0 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE) +[1] 0 0 0 0 0 0 NaN +Warning message: +In dlnorm(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71), c(0.0653, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dlnorm(0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE) +[1] NA NaN NA 0 0 NA + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dlnorm(10, 10, 10, log=TRUE) +[1] -5.82036 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dlnorm(3, 3, 3, log=FALSE) +[1] 0.03626103 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE) + [1] NaN 0.000000e+00 5.399097e-01 0.000000e+00 0.000000e+00 + [6] NaN 0.000000e+00 0.000000e+00 4.432692e-01 0.000000e+00 +[11] NaN 0.000000e+00 0.000000e+00 0.000000e+00 1.257944e-01 +[16] NaN 0.000000e+00 5.520948e-87 0.000000e+00 0.000000e+00 +[21] NaN 0.000000e+00 0.000000e+00 4.324583e-01 0.000000e+00 +[26] NaN 0.000000e+00 0.000000e+00 0.000000e+00 1.329808e-01 +[31] NaN 0.000000e+00 1.473646e-195 0.000000e+00 0.000000e+00 +[36] NaN 0.000000e+00 0.000000e+00 3.752628e-02 0.000000e+00 +[41] NaN 0.000000e+00 0.000000e+00 0.000000e+00 1.326856e-01 +[46] NaN 0.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00 +[51] NaN 0.000000e+00 0.000000e+00 1.713643e-03 0.000000e+00 +[56] NaN 0.000000e+00 0.000000e+00 0.000000e+00 1.064827e-01 +Warning message: +In dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE) + [1] NaN -Inf -0.6163534 -Inf -Inf + [6] NaN -Inf -Inf -0.8135780 -Inf +[11] NaN -Inf -Inf -Inf -2.0731064 +[16] NaN -Inf -198.6163534 -Inf -Inf +[21] NaN -Inf -Inf -0.8382694 -Inf +[26] NaN -Inf -Inf -Inf -2.0175508 +[31] NaN -Inf -448.6163534 -Inf -Inf +[36] NaN -Inf -Inf -3.2827138 -Inf +[41] NaN -Inf -Inf -Inf -2.0197730 +[46] NaN -Inf -798.6163534 -Inf -Inf +[51] NaN -Inf -Inf -6.3691336 -Inf +[56] NaN -Inf -Inf -Inf -2.2397730 +Warning message: +In dlnorm(c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions31#Output.IgnoreWhitespace# +#set.seed(1); dlnorm(c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE) +[1] NA NaN 0 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(0, 10, 10, lower.tail=FALSE, log.p=FALSE) +[1] 1 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(0, 10, 10, lower.tail=FALSE, log.p=TRUE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(0, 10, 10, lower.tail=TRUE, log.p=FALSE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(0, 10, 10, lower.tail=TRUE, log.p=TRUE) +[1] -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE) + [1] 1 1 1 1 1 1 NaN 1 1 1 1 1 1 NaN 1 1 1 1 1 +[20] 1 NaN 1 1 1 1 1 1 NaN 1 1 1 1 1 1 NaN +Warning message: +In pbeta(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE) + [1] 0 0 0 0 0 0 NaN 0 0 0 0 0 0 NaN 0 0 0 0 0 +[20] 0 NaN 0 0 0 0 0 0 NaN 0 0 0 0 0 0 NaN +Warning message: +In pbeta(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE) + [1] 0 0 0 0 0 0 NaN 0 0 0 0 0 0 NaN 0 0 0 0 0 +[20] 0 NaN 0 0 0 0 0 0 NaN 0 0 0 0 0 0 NaN +Warning message: +In pbeta(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE) + [1] -Inf -Inf -Inf -Inf -Inf -Inf NaN -Inf -Inf -Inf -Inf -Inf -Inf NaN -Inf +[16] -Inf -Inf -Inf -Inf -Inf NaN -Inf -Inf -Inf -Inf -Inf -Inf NaN -Inf -Inf +[31] -Inf -Inf -Inf -Inf NaN +Warning message: +In pbeta(0, c(0.0653, 0.000123, 3.2e-79, 8833, 7.9e+71, 0, -1), : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE) + [1] NaN 1.0000000 0.1486601 0.0000000 NaN NaN NaN + [8] 0.0000000 1.0000000 1.0000000 NaN 0.0000000 NaN 1.0000000 + [15] 0.9920000 NaN NaN 1.0000000 NaN 0.0000000 NaN + [22] 1.0000000 NaN 0.0000000 NaN NaN 0.0000000 0.0000000 + [29] NaN 1.0000000 NaN 0.0000000 1.0000000 1.0000000 NaN + [36] NaN NaN 1.0000000 0.7650762 0.0000000 NaN 1.0000000 + [43] NaN 0.0000000 1.0000000 NaN NaN 0.0000000 NaN + [50] 1.0000000 NaN 0.0000000 NaN 1.0000000 NaN NaN + [57] 1.0000000 1.0000000 NaN 0.0000000 NaN 1.0000000 0.1486601 + [64] 0.0000000 NaN NaN NaN 0.0000000 1.0000000 1.0000000 + [71] NaN 0.0000000 NaN 1.0000000 0.9920000 NaN NaN + [78] 1.0000000 NaN 0.0000000 NaN 1.0000000 NaN 0.0000000 + [85] NaN NaN 0.0000000 0.0000000 NaN 1.0000000 NaN + [92] 0.0000000 1.0000000 1.0000000 NaN NaN NaN 1.0000000 + [99] 0.7650762 0.0000000 NaN 1.0000000 NaN 0.0000000 1.0000000 +[106] NaN NaN 0.0000000 NaN 1.0000000 NaN 0.0000000 +[113] NaN 1.0000000 NaN NaN 1.0000000 1.0000000 NaN +[120] 0.0000000 +Warning message: +In pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE) + [1] NaN 0.000000000 -1.906092939 -Inf NaN + [6] NaN NaN -Inf 0.000000000 0.000000000 + [11] NaN -Inf NaN 0.000000000 -0.008032172 + [16] NaN NaN 0.000000000 NaN -Inf + [21] NaN 0.000000000 NaN -Inf NaN + [26] NaN -Inf -Inf NaN 0.000000000 + [31] NaN -Inf 0.000000000 0.000000000 NaN + [36] NaN NaN 0.000000000 -0.267779827 -Inf + [41] NaN 0.000000000 NaN -Inf 0.000000000 + [46] NaN NaN -Inf NaN 0.000000000 + [51] NaN -Inf NaN 0.000000000 NaN + [56] NaN 0.000000000 0.000000000 NaN -Inf + [61] NaN 0.000000000 -1.906092939 -Inf NaN + [66] NaN NaN -Inf 0.000000000 0.000000000 + [71] NaN -Inf NaN 0.000000000 -0.008032172 + [76] NaN NaN 0.000000000 NaN -Inf + [81] NaN 0.000000000 NaN -Inf NaN + [86] NaN -Inf -Inf NaN 0.000000000 + [91] NaN -Inf 0.000000000 0.000000000 NaN + [96] NaN NaN 0.000000000 -0.267779827 -Inf +[101] NaN 0.000000000 NaN -Inf 0.000000000 +[106] NaN NaN -Inf NaN 0.000000000 +[111] NaN -Inf NaN 0.000000000 NaN +[116] NaN 0.000000000 0.000000000 NaN -Inf +Warning message: +In pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE) + [1] NaN 0.0000000 0.8513399 1.0000000 NaN NaN NaN + [8] 1.0000000 0.0000000 0.0000000 NaN 1.0000000 NaN 0.0000000 + [15] 0.0080000 NaN NaN 0.0000000 NaN 1.0000000 NaN + [22] 0.0000000 NaN 1.0000000 NaN NaN 1.0000000 1.0000000 + [29] NaN 0.0000000 NaN 1.0000000 0.0000000 0.0000000 NaN + [36] NaN NaN 0.0000000 0.2349238 1.0000000 NaN 0.0000000 + [43] NaN 1.0000000 0.0000000 NaN NaN 1.0000000 NaN + [50] 0.0000000 NaN 1.0000000 NaN 0.0000000 NaN NaN + [57] 0.0000000 0.0000000 NaN 1.0000000 NaN 0.0000000 0.8513399 + [64] 1.0000000 NaN NaN NaN 1.0000000 0.0000000 0.0000000 + [71] NaN 1.0000000 NaN 0.0000000 0.0080000 NaN NaN + [78] 0.0000000 NaN 1.0000000 NaN 0.0000000 NaN 1.0000000 + [85] NaN NaN 1.0000000 1.0000000 NaN 0.0000000 NaN + [92] 1.0000000 0.0000000 0.0000000 NaN NaN NaN 0.0000000 + [99] 0.2349238 1.0000000 NaN 0.0000000 NaN 1.0000000 0.0000000 +[106] NaN NaN 1.0000000 NaN 0.0000000 NaN 1.0000000 +[113] NaN 0.0000000 NaN NaN 0.0000000 0.0000000 NaN +[120] 1.0000000 +Warning message: +In pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE) + [1] NaN -Inf -0.1609438 0.0000000 NaN NaN + [7] NaN 0.0000000 -Inf -Inf NaN 0.0000000 + [13] NaN -Inf -4.8283137 NaN NaN -Inf + [19] NaN 0.0000000 NaN -Inf NaN 0.0000000 + [25] NaN NaN 0.0000000 0.0000000 NaN -Inf + [31] NaN 0.0000000 -Inf -Inf NaN NaN + [37] NaN -Inf -1.4484941 0.0000000 NaN -Inf + [43] NaN 0.0000000 -Inf NaN NaN 0.0000000 + [49] NaN -Inf NaN 0.0000000 NaN -Inf + [55] NaN NaN -Inf -Inf NaN 0.0000000 + [61] NaN -Inf -0.1609438 0.0000000 NaN NaN + [67] NaN 0.0000000 -Inf -Inf NaN 0.0000000 + [73] NaN -Inf -4.8283137 NaN NaN -Inf + [79] NaN 0.0000000 NaN -Inf NaN 0.0000000 + [85] NaN NaN 0.0000000 0.0000000 NaN -Inf + [91] NaN 0.0000000 -Inf -Inf NaN NaN + [97] NaN -Inf -1.4484941 0.0000000 NaN -Inf +[103] NaN 0.0000000 -Inf NaN NaN 0.0000000 +[109] NaN -Inf NaN 0.0000000 NaN -Inf +[115] NaN NaN -Inf -Inf NaN 0.0000000 +Warning message: +In pbeta(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext# +#set.seed(1); pbeta(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5)) + [1] NA 0 NaN 1 0 NA 0 NaN 1 0 NA 0 NaN 1 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext# +#set.seed(1); pbeta(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) + [1] NA 0 NaN 1 NaN NA 1 NaN 0 NaN NA 1 NaN 0 NaN +Warning message: +In pbeta(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pbeta(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) + [1] NA 0 NaN 1 NaN NA 1 NaN 1 NaN NA 0 NaN 0 NaN +Warning message: +In pbeta(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(0, 10, 10, lower.tail=FALSE, log.p=FALSE) +[1] 0.75 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(0, 10, 10, lower.tail=FALSE, log.p=TRUE) +[1] -0.2876821 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(0, 10, 10, lower.tail=TRUE, log.p=FALSE) +[1] 0.25 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(0, 10, 10, lower.tail=TRUE, log.p=TRUE) +[1] -1.386294 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE) + [1] 7.500000e-01 7.500000e-01 7.500000e-01 7.500000e-01 7.500000e-01 + [6] 5.000000e-01 3.915212e-05 1.000000e+00 5.000000e-01 5.000000e-01 +[11] 9.999976e-01 1.000000e+00 5.000000e-01 4.999640e-01 5.000000e-01 +[16] 5.005996e-01 5.000000e-01 1.000000e+00 1.000000e+00 5.000000e-01 +[21] 2.075617e-02 9.994004e-01 1.000000e+00 5.000000e-01 5.000000e-01 +[26] 1.000000e+00 5.000000e-01 1.018592e-79 5.000024e-01 5.000000e-01 +[31] 5.000000e-01 1.000000e+00 1.000000e+00 5.000000e-01 5.000000e-01 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE) + [1] -2.876821e-01 -2.876821e-01 -2.876821e-01 -2.876821e-01 -2.876821e-01 + [6] -6.931472e-01 -1.014806e+01 -1.559865e-78 -6.931472e-01 -6.931472e-01 +[11] -2.353182e-06 -4.955964e-77 -6.931472e-01 -6.932193e-01 -6.931472e-01 +[16] -6.919488e-01 -6.931472e-01 -1.153166e-83 -3.559027e-69 -6.931472e-01 +[21] -3.874912e+00 -5.997521e-04 -8.281233e-76 -6.931472e-01 -6.931472e-01 +[26] -2.631093e-74 -6.931472e-01 -1.818858e+02 -6.931425e-01 -6.931472e-01 +[31] -6.931472e-01 -4.432482e-09 -1.289357e-151 -6.931472e-01 -6.931472e-01 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE) + [1] 2.500000e-01 2.500000e-01 2.500000e-01 2.500000e-01 2.500000e-01 + [6] 5.000000e-01 9.999608e-01 1.559865e-78 5.000000e-01 5.000000e-01 +[11] 2.353180e-06 4.955964e-77 5.000000e-01 5.000360e-01 5.000000e-01 +[16] 4.994004e-01 5.000000e-01 1.153166e-83 3.559027e-69 5.000000e-01 +[21] 9.792438e-01 5.995723e-04 8.281233e-76 5.000000e-01 5.000000e-01 +[26] 2.631093e-74 5.000000e-01 1.000000e+00 4.999976e-01 5.000000e-01 +[31] 5.000000e-01 4.432482e-09 1.289357e-151 5.000000e-01 5.000000e-01 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE) + [1] -1.386294e+00 -1.386294e+00 -1.386294e+00 -1.386294e+00 -1.386294e+00 + [6] -6.931472e-01 -3.915288e-05 -1.791570e+02 -6.931472e-01 -6.931472e-01 +[11] -1.295974e+01 -1.756985e+02 -6.931472e-01 -6.930751e-01 -6.931472e-01 +[16] -6.943470e-01 -6.931472e-01 -1.909721e+02 -1.576089e+02 -6.931472e-01 +[21] -2.097460e-02 -7.419294e+00 -1.728825e+02 -6.931472e-01 -6.931472e-01 +[26] -1.694239e+02 -6.931472e-01 -1.018592e-79 -6.931519e-01 -6.931472e-01 +[31] -6.931472e-01 -1.923431e+01 -3.474362e+02 -6.931472e-01 -6.931472e-01 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE) + [1] NaN NaN 4.682745e-01 2.885794e-02 NaN + [6] 3.183099e-05 NaN NaN 8.457859e-01 9.893936e-01 + [11] NaN 1.591549e-05 NaN NaN 8.908121e-01 + [16] 1.060640e-02 NaN 9.996817e-01 NaN NaN + [21] 5.000000e-01 5.000000e-01 NaN 2.893726e-05 NaN + [26] NaN 4.371670e-01 1.673771e-02 NaN 9.999894e-01 + [31] NaN NaN 7.651462e-01 9.647767e-01 NaN + [36] 1.061033e-05 NaN NaN 6.944001e-01 9.682745e-01 + [41] NaN 5.000000e-01 NaN NaN 9.220209e-01 + [46] 3.172552e-02 NaN 1.675315e-05 NaN NaN + [51] 2.211421e-01 1.590225e-02 NaN 9.999646e-01 NaN + [56] NaN 7.500000e-01 7.500000e-01 NaN 9.999682e-01 + [61] NaN NaN 4.682745e-01 2.885794e-02 NaN + [66] 3.183099e-05 NaN NaN 8.457859e-01 9.893936e-01 + [71] NaN 1.591549e-05 NaN NaN 8.908121e-01 + [76] 1.060640e-02 NaN 9.996817e-01 NaN NaN + [81] 5.000000e-01 5.000000e-01 NaN 2.893726e-05 NaN + [86] NaN 4.371670e-01 1.673771e-02 NaN 9.999894e-01 + [91] NaN NaN 7.651462e-01 9.647767e-01 NaN + [96] 1.061033e-05 NaN NaN 6.944001e-01 9.682745e-01 +[101] NaN 5.000000e-01 NaN NaN 9.220209e-01 +[106] 3.172552e-02 NaN 1.675315e-05 NaN NaN +[111] 2.211421e-01 1.590225e-02 NaN 9.999646e-01 NaN +[116] NaN 7.500000e-01 7.500000e-01 NaN 9.999682e-01 +Warning message: +In pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE) + [1] NaN NaN -7.587007e-01 -3.545370e+00 NaN + [6] -1.035507e+01 NaN NaN -1.674890e-01 -1.066305e-02 + [11] NaN -1.104822e+01 NaN NaN -1.156218e-01 + [16] -4.546297e+00 NaN -3.183605e-04 NaN NaN + [21] -6.931472e-01 -6.931472e-01 NaN -1.045038e+01 NaN + [26] NaN -8.274399e-01 -4.090091e+00 NaN -1.061039e-05 + [31] NaN NaN -2.676884e-01 -3.585859e-02 NaN + [36] -1.145368e+01 NaN NaN -3.647070e-01 -3.223968e-02 + [41] NaN -6.931472e-01 NaN NaN -8.118742e-02 + [46] -3.450634e+00 NaN -1.099692e+01 NaN NaN + [51] -1.508950e+00 -4.141295e+00 NaN -3.536839e-05 NaN + [56] NaN -2.876821e-01 -2.876821e-01 NaN -3.183150e-05 + [61] NaN NaN -7.587007e-01 -3.545370e+00 NaN + [66] -1.035507e+01 NaN NaN -1.674890e-01 -1.066305e-02 + [71] NaN -1.104822e+01 NaN NaN -1.156218e-01 + [76] -4.546297e+00 NaN -3.183605e-04 NaN NaN + [81] -6.931472e-01 -6.931472e-01 NaN -1.045038e+01 NaN + [86] NaN -8.274399e-01 -4.090091e+00 NaN -1.061039e-05 + [91] NaN NaN -2.676884e-01 -3.585859e-02 NaN + [96] -1.145368e+01 NaN NaN -3.647070e-01 -3.223968e-02 +[101] NaN -6.931472e-01 NaN NaN -8.118742e-02 +[106] -3.450634e+00 NaN -1.099692e+01 NaN NaN +[111] -1.508950e+00 -4.141295e+00 NaN -3.536839e-05 NaN +[116] NaN -2.876821e-01 -2.876821e-01 NaN -3.183150e-05 +Warning message: +In pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE) + [1] NaN NaN 5.317255e-01 9.711421e-01 NaN + [6] 9.999682e-01 NaN NaN 1.542141e-01 1.060640e-02 + [11] NaN 9.999841e-01 NaN NaN 1.091879e-01 + [16] 9.893936e-01 NaN 3.183098e-04 NaN NaN + [21] 5.000000e-01 5.000000e-01 NaN 9.999711e-01 NaN + [26] NaN 5.628330e-01 9.832623e-01 NaN 1.061033e-05 + [31] NaN NaN 2.348538e-01 3.522329e-02 NaN + [36] 9.999894e-01 NaN NaN 3.055999e-01 3.172552e-02 + [41] NaN 5.000000e-01 NaN NaN 7.797913e-02 + [46] 9.682745e-01 NaN 9.999832e-01 NaN NaN + [51] 7.788579e-01 9.840977e-01 NaN 3.536776e-05 NaN + [56] NaN 2.500000e-01 2.500000e-01 NaN 3.183099e-05 + [61] NaN NaN 5.317255e-01 9.711421e-01 NaN + [66] 9.999682e-01 NaN NaN 1.542141e-01 1.060640e-02 + [71] NaN 9.999841e-01 NaN NaN 1.091879e-01 + [76] 9.893936e-01 NaN 3.183098e-04 NaN NaN + [81] 5.000000e-01 5.000000e-01 NaN 9.999711e-01 NaN + [86] NaN 5.628330e-01 9.832623e-01 NaN 1.061033e-05 + [91] NaN NaN 2.348538e-01 3.522329e-02 NaN + [96] 9.999894e-01 NaN NaN 3.055999e-01 3.172552e-02 +[101] NaN 5.000000e-01 NaN NaN 7.797913e-02 +[106] 9.682745e-01 NaN 9.999832e-01 NaN NaN +[111] 7.788579e-01 9.840977e-01 NaN 3.536776e-05 NaN +[116] NaN 2.500000e-01 2.500000e-01 NaN 3.183099e-05 +Warning message: +In pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE) + [1] NaN NaN -6.316279e-01 -2.928252e-02 NaN + [6] -3.183150e-05 NaN NaN -1.869413e+00 -4.546297e+00 + [11] NaN -1.591562e-05 NaN NaN -2.214685e+00 + [16] -1.066305e-02 NaN -8.052485e+00 NaN NaN + [21] -6.931472e-01 -6.931472e-01 NaN -2.893768e-05 NaN + [26] NaN -5.747724e-01 -1.687937e-02 NaN -1.145368e+01 + [31] NaN NaN -1.448792e+00 -3.346048e+00 NaN + [36] -1.061039e-05 NaN NaN -1.185479e+00 -3.450634e+00 + [41] NaN -6.931472e-01 NaN NaN -2.551314e+00 + [46] -3.223968e-02 NaN -1.675329e-05 NaN NaN + [51] -2.499266e-01 -1.603005e-02 NaN -1.024971e+01 NaN + [56] NaN -1.386294e+00 -1.386294e+00 NaN -1.035507e+01 + [61] NaN NaN -6.316279e-01 -2.928252e-02 NaN + [66] -3.183150e-05 NaN NaN -1.869413e+00 -4.546297e+00 + [71] NaN -1.591562e-05 NaN NaN -2.214685e+00 + [76] -1.066305e-02 NaN -8.052485e+00 NaN NaN + [81] -6.931472e-01 -6.931472e-01 NaN -2.893768e-05 NaN + [86] NaN -5.747724e-01 -1.687937e-02 NaN -1.145368e+01 + [91] NaN NaN -1.448792e+00 -3.346048e+00 NaN + [96] -1.061039e-05 NaN NaN -1.185479e+00 -3.450634e+00 +[101] NaN -6.931472e-01 NaN NaN -2.551314e+00 +[106] -3.223968e-02 NaN -1.675329e-05 NaN NaN +[111] -2.499266e-01 -1.603005e-02 NaN -1.024971e+01 NaN +[116] NaN -1.386294e+00 -1.386294e+00 NaN -1.035507e+01 +Warning message: +In pcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext# +#set.seed(1); pcauchy(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5)) + [1] NA NaN NaN 1.00 NaN NA 0.25 NaN 1.00 0.00 NA 0.25 NaN NaN 0.00 +Warning message: +In pcauchy(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext# +#set.seed(1); pcauchy(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) + [1] NA NaN NaN 0.00 NaN NA 0.75 NaN 0.00 1.00 NA 0.75 NaN NaN 1.00 +Warning message: +In pcauchy(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); pcauchy(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) + [1] NA NaN NaN 0.5 NaN NA NaN NaN 0.5 NaN NA NaN NaN 0.5 NaN +Warning message: +In pcauchy(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(0, 10, 10, lower.tail=FALSE, log.p=FALSE) +[1] 1 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(0, 10, 10, lower.tail=FALSE, log.p=TRUE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(0, 10, 10, lower.tail=TRUE, log.p=FALSE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(0, 10, 10, lower.tail=TRUE, log.p=TRUE) +[1] -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE) + [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE) + [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE) + [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE) + [1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf +[16] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf +[31] -Inf -Inf -Inf -Inf -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE) + [1] NaN 1.000000e+00 9.563151e-01 9.807048e-01 NaN + [6] 1.000000e+00 NaN 0.000000e+00 1.000000e+00 1.000000e+00 + [11] NaN 0.000000e+00 NaN 1.000000e+00 9.999980e-01 + [16] 1.318515e-64 NaN 1.000000e+00 NaN 1.000000e+00 + [21] 1.000000e+00 1.000000e+00 NaN 1.000000e+00 NaN + [26] 1.000000e+00 9.462397e-01 1.501156e-09 NaN 1.000000e+00 + [31] NaN 0.000000e+00 1.000000e+00 1.000000e+00 NaN + [36] 0.000000e+00 NaN 1.000000e+00 9.939538e-01 1.000000e+00 + [41] NaN 1.000000e+00 NaN 1.000000e+00 1.000000e+00 + [46] 1.000000e+00 NaN 0.000000e+00 NaN 1.000000e+00 + [51] 7.288829e-01 2.082422e-12 NaN 1.000000e+00 NaN + [56] 0.000000e+00 1.000000e+00 1.000000e+00 NaN 1.000000e+00 + [61] NaN 1.000000e+00 9.563151e-01 9.807048e-01 NaN + [66] 1.000000e+00 NaN 0.000000e+00 1.000000e+00 1.000000e+00 + [71] NaN 0.000000e+00 NaN 1.000000e+00 9.999980e-01 + [76] 1.318515e-64 NaN 1.000000e+00 NaN 1.000000e+00 + [81] 1.000000e+00 1.000000e+00 NaN 1.000000e+00 NaN + [86] 1.000000e+00 9.462397e-01 1.501156e-09 NaN 1.000000e+00 + [91] NaN 0.000000e+00 1.000000e+00 1.000000e+00 NaN + [96] 0.000000e+00 NaN 1.000000e+00 9.939538e-01 1.000000e+00 +[101] NaN 1.000000e+00 NaN 1.000000e+00 1.000000e+00 +[106] 1.000000e+00 NaN 0.000000e+00 NaN 1.000000e+00 +[111] 7.288829e-01 2.082422e-12 NaN 1.000000e+00 NaN +[116] 0.000000e+00 1.000000e+00 1.000000e+00 NaN 1.000000e+00 +Warning message: +In plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE) + [1] NaN 0.000000e+00 -4.466785e-02 -1.948377e-02 NaN + [6] 0.000000e+00 NaN -Inf 0.000000e+00 0.000000e+00 + [11] NaN -2.402266e+07 NaN 0.000000e+00 -2.018797e-06 + [16] -1.470889e+02 NaN 0.000000e+00 NaN 0.000000e+00 + [21] 0.000000e+00 0.000000e+00 NaN 0.000000e+00 NaN + [26] 0.000000e+00 -5.525937e-02 -2.031703e+01 NaN 0.000000e+00 + [31] NaN -Inf 0.000000e+00 0.000000e+00 NaN + [36] -1.433374e+08 NaN 0.000000e+00 -6.064526e-03 -4.793526e-118 + [41] NaN 0.000000e+00 NaN 0.000000e+00 0.000000e+00 + [46] 0.000000e+00 NaN -1.759119e+07 NaN 0.000000e+00 + [51] -3.162422e-01 -2.689749e+01 NaN 0.000000e+00 NaN + [56] -Inf 0.000000e+00 0.000000e+00 NaN 0.000000e+00 + [61] NaN 0.000000e+00 -4.466785e-02 -1.948377e-02 NaN + [66] 0.000000e+00 NaN -Inf 0.000000e+00 0.000000e+00 + [71] NaN -2.402266e+07 NaN 0.000000e+00 -2.018797e-06 + [76] -1.470889e+02 NaN 0.000000e+00 NaN 0.000000e+00 + [81] 0.000000e+00 0.000000e+00 NaN 0.000000e+00 NaN + [86] 0.000000e+00 -5.525937e-02 -2.031703e+01 NaN 0.000000e+00 + [91] NaN -Inf 0.000000e+00 0.000000e+00 NaN + [96] -1.433374e+08 NaN 0.000000e+00 -6.064526e-03 -4.793526e-118 +[101] NaN 0.000000e+00 NaN 0.000000e+00 0.000000e+00 +[106] 0.000000e+00 NaN -1.759119e+07 NaN 0.000000e+00 +[111] -3.162422e-01 -2.689749e+01 NaN 0.000000e+00 NaN +[116] -Inf 0.000000e+00 0.000000e+00 NaN 0.000000e+00 +Warning message: +In plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE) + [1] NaN 0.000000e+00 4.368493e-02 1.929519e-02 NaN + [6] 0.000000e+00 NaN 1.000000e+00 0.000000e+00 0.000000e+00 + [11] NaN 1.000000e+00 NaN 0.000000e+00 2.018795e-06 + [16] 1.000000e+00 NaN 0.000000e+00 NaN 0.000000e+00 + [21] 0.000000e+00 0.000000e+00 NaN 0.000000e+00 NaN + [26] 0.000000e+00 5.376031e-02 1.000000e+00 NaN 0.000000e+00 + [31] NaN 1.000000e+00 0.000000e+00 0.000000e+00 NaN + [36] 1.000000e+00 NaN 0.000000e+00 6.046174e-03 4.793526e-118 + [41] NaN 0.000000e+00 NaN 0.000000e+00 0.000000e+00 + [46] 0.000000e+00 NaN 1.000000e+00 NaN 0.000000e+00 + [51] 2.711171e-01 1.000000e+00 NaN 0.000000e+00 NaN + [56] 1.000000e+00 0.000000e+00 0.000000e+00 NaN 0.000000e+00 + [61] NaN 0.000000e+00 4.368493e-02 1.929519e-02 NaN + [66] 0.000000e+00 NaN 1.000000e+00 0.000000e+00 0.000000e+00 + [71] NaN 1.000000e+00 NaN 0.000000e+00 2.018795e-06 + [76] 1.000000e+00 NaN 0.000000e+00 NaN 0.000000e+00 + [81] 0.000000e+00 0.000000e+00 NaN 0.000000e+00 NaN + [86] 0.000000e+00 5.376031e-02 1.000000e+00 NaN 0.000000e+00 + [91] NaN 1.000000e+00 0.000000e+00 0.000000e+00 NaN + [96] 1.000000e+00 NaN 0.000000e+00 6.046174e-03 4.793526e-118 +[101] NaN 0.000000e+00 NaN 0.000000e+00 0.000000e+00 +[106] 0.000000e+00 NaN 1.000000e+00 NaN 0.000000e+00 +[111] 2.711171e-01 1.000000e+00 NaN 0.000000e+00 NaN +[116] 1.000000e+00 0.000000e+00 0.000000e+00 NaN 0.000000e+00 +Warning message: +In plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE) + [1] NaN -Inf -3.130752e+00 -3.947899e+00 NaN + [6] -Inf NaN 0.000000e+00 -Inf -Inf + [11] NaN 0.000000e+00 NaN -Inf -1.311301e+01 + [16] -1.318515e-64 NaN -Inf NaN -Inf + [21] -Inf -Inf NaN -2.139413e+06 NaN + [26] -Inf -2.923220e+00 -1.501156e-09 NaN -Inf + [31] NaN 0.000000e+00 -Inf -Inf NaN + [36] 0.000000e+00 NaN -Inf -5.108330e+00 -2.701378e+02 + [41] NaN -Inf NaN -Inf -Inf + [46] -Inf NaN 0.000000e+00 NaN -Inf + [51] -1.305204e+00 -2.082422e-12 NaN -Inf NaN + [56] 0.000000e+00 -Inf -Inf NaN -2.660785e+08 + [61] NaN -Inf -3.130752e+00 -3.947899e+00 NaN + [66] -Inf NaN 0.000000e+00 -Inf -Inf + [71] NaN 0.000000e+00 NaN -Inf -1.311301e+01 + [76] -1.318515e-64 NaN -Inf NaN -Inf + [81] -Inf -Inf NaN -2.139413e+06 NaN + [86] -Inf -2.923220e+00 -1.501156e-09 NaN -Inf + [91] NaN 0.000000e+00 -Inf -Inf NaN + [96] 0.000000e+00 NaN -Inf -5.108330e+00 -2.701378e+02 +[101] NaN -Inf NaN -Inf -Inf +[106] -Inf NaN 0.000000e+00 NaN -Inf +[111] -1.305204e+00 -2.082422e-12 NaN -Inf NaN +[116] 0.000000e+00 -Inf -Inf NaN -2.660785e+08 +Warning message: +In plnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext# +#set.seed(1); plnorm(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5)) + [1] NA 0 NaN 1 0 NA 0 NaN 1 0 NA 0 NaN 1 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext# +#set.seed(1); plnorm(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) + [1] NA 0.000000e+00 NaN 0.000000e+00 0.000000e+00 + [6] NA 5.000000e-01 NaN 0.000000e+00 1.000000e+00 +[11] NA 1.284176e-117 NaN 0.000000e+00 1.000000e+00 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); plnorm(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) + [1] NA 0.0 NaN 0.5 NaN NA 0.0 NaN 0.5 NaN NA 0.0 NaN 0.0 NaN +Warning message: +In plnorm(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(0, 10, 10, lower.tail=FALSE, log.p=FALSE) +[1] Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(0, 10, 10, lower.tail=FALSE, log.p=TRUE) +[1] -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(0, 10, 10, lower.tail=TRUE, log.p=FALSE) +[1] -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(0, 10, 10, lower.tail=TRUE, log.p=TRUE) +[1] Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE) + [1] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf +[20] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE) + [1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf +[16] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf +[31] -Inf -Inf -Inf -Inf -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE) + [1] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf +[16] -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf +[31] -Inf -Inf -Inf -Inf -Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE) + [1] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf +[20] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE) + [1] NaN 0.0000000 1.4763819 NaN NaN Inf + [7] NaN NaN NaN Inf NaN NaN + [13] NaN 0.9000000 4.3763819 NaN NaN Inf + [19] NaN NaN NaN Inf NaN NaN + [25] NaN -1.0000000 1.3763819 NaN NaN Inf + [31] NaN NaN NaN Inf NaN NaN + [37] NaN 0.1000000 2.2763819 NaN NaN Inf + [43] NaN NaN NaN Inf NaN NaN + [49] NaN 3.0000000 0.3763819 NaN NaN Inf + [55] NaN NaN NaN Inf NaN NaN + [61] NaN 0.0000000 1.4763819 NaN NaN Inf + [67] NaN NaN NaN Inf NaN NaN + [73] NaN 0.9000000 4.3763819 NaN NaN Inf + [79] NaN NaN NaN Inf NaN NaN + [85] NaN -1.0000000 1.3763819 NaN NaN Inf + [91] NaN NaN NaN Inf NaN NaN + [97] NaN 0.1000000 2.2763819 NaN NaN Inf +[103] NaN NaN NaN Inf NaN NaN +[109] NaN 3.0000000 0.3763819 NaN NaN Inf +[115] NaN NaN NaN Inf NaN NaN +Warning message: +In qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE) + [1] NaN 0.0000000 NaN NaN NaN -Inf + [7] NaN NaN 1.3406711 -Inf NaN NaN + [13] NaN 0.9000000 NaN NaN NaN -Inf + [19] NaN NaN -0.5593289 -Inf NaN NaN + [25] NaN -1.0000000 NaN NaN NaN -Inf + [31] NaN NaN 0.5406711 -Inf NaN NaN + [37] NaN 0.1000000 NaN NaN NaN -Inf + [43] NaN NaN 3.4406711 -Inf NaN NaN + [49] NaN 3.0000000 NaN NaN NaN -Inf + [55] NaN NaN 0.4406711 -Inf NaN NaN + [61] NaN 0.0000000 NaN NaN NaN -Inf + [67] NaN NaN 1.3406711 -Inf NaN NaN + [73] NaN 0.9000000 NaN NaN NaN -Inf + [79] NaN NaN -0.5593289 -Inf NaN NaN + [85] NaN -1.0000000 NaN NaN NaN -Inf + [91] NaN NaN 0.5406711 -Inf NaN NaN + [97] NaN 0.1000000 NaN NaN NaN -Inf +[103] NaN NaN 3.4406711 -Inf NaN NaN +[109] NaN 3.0000000 NaN NaN NaN -Inf +[115] NaN NaN 0.4406711 -Inf NaN NaN +Warning message: +In qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE) + [1] NaN 0.0000000 -1.2763819 NaN NaN -Inf + [7] NaN NaN NaN -Inf NaN NaN + [13] NaN 0.9000000 1.6236181 NaN NaN -Inf + [19] NaN NaN NaN -Inf NaN NaN + [25] NaN -1.0000000 -1.3763819 NaN NaN -Inf + [31] NaN NaN NaN -Inf NaN NaN + [37] NaN 0.1000000 -0.4763819 NaN NaN -Inf + [43] NaN NaN NaN -Inf NaN NaN + [49] NaN 3.0000000 -2.3763819 NaN NaN -Inf + [55] NaN NaN NaN -Inf NaN NaN + [61] NaN 0.0000000 -1.2763819 NaN NaN -Inf + [67] NaN NaN NaN -Inf NaN NaN + [73] NaN 0.9000000 1.6236181 NaN NaN -Inf + [79] NaN NaN NaN -Inf NaN NaN + [85] NaN -1.0000000 -1.3763819 NaN NaN -Inf + [91] NaN NaN NaN -Inf NaN NaN + [97] NaN 0.1000000 -0.4763819 NaN NaN -Inf +[103] NaN NaN NaN -Inf NaN NaN +[109] NaN 3.0000000 -2.3763819 NaN NaN -Inf +[115] NaN NaN NaN -Inf NaN NaN +Warning message: +In qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE) + [1] NaN 0.0000000 NaN NaN NaN Inf + [7] NaN NaN 0.4593289 Inf NaN NaN + [13] NaN 0.9000000 NaN NaN NaN Inf + [19] NaN NaN -1.4406711 Inf NaN NaN + [25] NaN -1.0000000 NaN NaN NaN Inf + [31] NaN NaN -0.3406711 Inf NaN NaN + [37] NaN 0.1000000 NaN NaN NaN Inf + [43] NaN NaN 2.5593289 Inf NaN NaN + [49] NaN 3.0000000 NaN NaN NaN Inf + [55] NaN NaN -0.4406711 Inf NaN NaN + [61] NaN 0.0000000 NaN NaN NaN Inf + [67] NaN NaN 0.4593289 Inf NaN NaN + [73] NaN 0.9000000 NaN NaN NaN Inf + [79] NaN NaN -1.4406711 Inf NaN NaN + [85] NaN -1.0000000 NaN NaN NaN Inf + [91] NaN NaN -0.3406711 Inf NaN NaN + [97] NaN 0.1000000 NaN NaN NaN Inf +[103] NaN NaN 2.5593289 Inf NaN NaN +[109] NaN 3.0000000 NaN NaN NaN Inf +[115] NaN NaN -0.4406711 Inf NaN NaN +Warning message: +In qcauchy(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext# +#set.seed(1); qcauchy(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5)) + [1] NA 0 NaN NaN NaN NA -Inf NaN NaN NaN NA -Inf NaN NaN NaN +Warning message: +In qcauchy(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext# +#set.seed(1); qcauchy(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) + [1] NA 0.0000000 NaN Inf -Inf NA + [7] Inf NaN Inf NaN NA -0.3077684 +[13] NaN Inf -Inf +Warning message: +In qcauchy(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qcauchy(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) + [1] NA 0.0 NaN NaN NaN NA 1.0 NaN NaN NaN NA 0.1 NaN NaN NaN +Warning message: +In qcauchy(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(0, 10, 10, lower.tail=FALSE, log.p=FALSE) +[1] Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(0, 10, 10, lower.tail=FALSE, log.p=TRUE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(0, 10, 10, lower.tail=TRUE, log.p=FALSE) +[1] 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(0, 10, 10, lower.tail=TRUE, log.p=TRUE) +[1] Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=FALSE) + [1] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf +[20] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=FALSE, log.p=TRUE) + [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=FALSE) + [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7), lower.tail=TRUE, log.p=TRUE) + [1] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf +[20] Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf Inf + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=FALSE) + [1] NaN Inf 2.5641351 NaN NaN Inf + [7] NaN NaN NaN Inf NaN NaN + [13] NaN Inf 46.6009643 NaN NaN Inf + [19] NaN NaN NaN Inf NaN NaN + [25] NaN Inf 2.3201254 NaN NaN Inf + [31] NaN NaN NaN Inf NaN NaN + [37] NaN Inf 5.7065876 NaN NaN Inf + [43] NaN NaN NaN Inf NaN NaN + [49] NaN Inf 0.8535264 NaN NaN Inf + [55] NaN NaN NaN Inf NaN NaN + [61] NaN Inf 2.5641351 NaN NaN Inf + [67] NaN NaN NaN Inf NaN NaN + [73] NaN Inf 46.6009643 NaN NaN Inf + [79] NaN NaN NaN Inf NaN NaN + [85] NaN Inf 2.3201254 NaN NaN Inf + [91] NaN NaN NaN Inf NaN NaN + [97] NaN Inf 5.7065876 NaN NaN Inf +[103] NaN NaN NaN Inf NaN NaN +[109] NaN Inf 0.8535264 NaN NaN Inf +[115] NaN NaN NaN Inf NaN NaN +Warning message: +In qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=FALSE, log.p=TRUE) + [1] NaN 0.0000000 NaN NaN NaN 0.0000000 + [7] NaN NaN 3.4468989 0.0000000 NaN NaN + [13] NaN 0.0000000 NaN NaN NaN 0.0000000 + [19] NaN NaN 0.5155479 0.0000000 NaN NaN + [25] NaN 0.0000000 NaN NaN NaN 0.0000000 + [31] NaN NaN 1.5487915 0.0000000 NaN NaN + [37] NaN 0.0000000 NaN NaN NaN 0.0000000 + [43] NaN NaN 28.1479623 0.0000000 NaN NaN + [49] NaN 0.0000000 NaN NaN NaN 0.0000000 + [55] NaN NaN 1.4014045 0.0000000 NaN NaN + [61] NaN 0.0000000 NaN NaN NaN 0.0000000 + [67] NaN NaN 3.4468989 0.0000000 NaN NaN + [73] NaN 0.0000000 NaN NaN NaN 0.0000000 + [79] NaN NaN 0.5155479 0.0000000 NaN NaN + [85] NaN 0.0000000 NaN NaN NaN 0.0000000 + [91] NaN NaN 1.5487915 0.0000000 NaN NaN + [97] NaN 0.0000000 NaN NaN NaN 0.0000000 +[103] NaN NaN 28.1479623 0.0000000 NaN NaN +[109] NaN 0.0000000 NaN NaN NaN 0.0000000 +[115] NaN NaN 1.4014045 0.0000000 NaN NaN +Warning message: +In qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=FALSE) + [1] NaN 0.0000000 0.4763410 NaN NaN 0.0000000 NaN + [8] NaN NaN 0.0000000 NaN NaN NaN 0.0000000 + [15] 8.6570911 NaN NaN 0.0000000 NaN NaN NaN + [22] 0.0000000 NaN NaN NaN 0.0000000 0.4310112 NaN + [29] NaN 0.0000000 NaN NaN NaN 0.0000000 NaN + [36] NaN NaN 0.0000000 1.0601165 NaN NaN 0.0000000 + [43] NaN NaN NaN 0.0000000 NaN NaN NaN + [50] 0.0000000 0.1585602 NaN NaN 0.0000000 NaN NaN + [57] NaN 0.0000000 NaN NaN NaN 0.0000000 0.4763410 + [64] NaN NaN 0.0000000 NaN NaN NaN 0.0000000 + [71] NaN NaN NaN 0.0000000 8.6570911 NaN NaN + [78] 0.0000000 NaN NaN NaN 0.0000000 NaN NaN + [85] NaN 0.0000000 0.4310112 NaN NaN 0.0000000 NaN + [92] NaN NaN 0.0000000 NaN NaN NaN 0.0000000 + [99] 1.0601165 NaN NaN 0.0000000 NaN NaN NaN +[106] 0.0000000 NaN NaN NaN 0.0000000 0.1585602 NaN +[113] NaN 0.0000000 NaN NaN NaN 0.0000000 NaN +[120] NaN +Warning message: +In qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20), lower.tail=TRUE, log.p=TRUE) + [1] NaN Inf NaN NaN NaN Inf + [7] NaN NaN 1.7550986 Inf NaN NaN + [13] NaN Inf NaN NaN NaN Inf + [19] NaN NaN 0.2625077 Inf NaN NaN + [25] NaN Inf NaN NaN NaN Inf + [31] NaN NaN 0.7886166 Inf NaN NaN + [37] NaN Inf NaN NaN NaN Inf + [43] NaN NaN 14.3324334 Inf NaN NaN + [49] NaN Inf NaN NaN NaN Inf + [55] NaN NaN 0.7135698 Inf NaN NaN + [61] NaN Inf NaN NaN NaN Inf + [67] NaN NaN 1.7550986 Inf NaN NaN + [73] NaN Inf NaN NaN NaN Inf + [79] NaN NaN 0.2625077 Inf NaN NaN + [85] NaN Inf NaN NaN NaN Inf + [91] NaN NaN 0.7886166 Inf NaN NaN + [97] NaN Inf NaN NaN NaN Inf +[103] NaN NaN 14.3324334 Inf NaN NaN +[109] NaN Inf NaN NaN NaN Inf +[115] NaN NaN 0.7135698 Inf NaN NaN +Warning message: +In qlnorm(c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext# +#set.seed(1); qlnorm(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5)) + [1] NA 0 NaN NaN NaN NA 0 NaN NaN NaN NA 0 NaN NaN NaN +Warning message: +In qlnorm(c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, : + NaNs produced + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWarningContext# +#set.seed(1); qlnorm(rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)) + [1] NA 0.0000000 NaN Inf 0.0000000 NA Inf + [8] NaN Inf Inf NA 0.8797169 NaN 0.0000000 +[15] 0.0000000 + +##com.oracle.truffle.r.test.library.stats.TestStatFunctions.testFunctions32#Output.IgnoreWhitespace# +#set.seed(1); qlnorm(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)) + [1] NA 0.000000 NaN Inf 0.000000 NA Inf NaN + [9] 0.000000 Inf NA 1.105171 NaN 0.000000 NaN +Warning message: +In qlnorm(rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, : + NaNs produced + ##com.oracle.truffle.r.test.library.stats.TestStats.testCor# #{ as.integer(cor(c(1,2,3),c(1,2,5))*10000000) } [1] 9607689 @@ -114564,6 +116561,34 @@ In qnorm(c(0.1, 0.9, 0.5, 1.00001, 0.99999), 100, c(20, 1)) : NaNs produced #{ set.seed(7); round( rbinom(3,3,0.9), digits = 5 ) } [1] 1 3 3 +##com.oracle.truffle.r.test.library.stats.TestStats.testRandom# +#{ set.seed(7); round( rcauchy(3), digits = 5 ) } +[1] -0.03486 3.00509 0.38038 + +##com.oracle.truffle.r.test.library.stats.TestStats.testRandom# +#{ set.seed(7); round( rcauchy(3, scale=4, location=1:3), digits = 5 ) } +[1] 0.86057 14.02037 4.52150 + +##com.oracle.truffle.r.test.library.stats.TestStats.testRandom# +#{ set.seed(7); round( rgamma(3,0.5,rate=1:3), digits = 5 ) } +[1] 3.63965 0.00938 0.02776 + +##com.oracle.truffle.r.test.library.stats.TestStats.testRandom# +#{ set.seed(7); round( rgamma(3,0.5,scale=1:3), digits = 5 ) } +[1] 3.63965 0.03753 0.24984 + +##com.oracle.truffle.r.test.library.stats.TestStats.testRandom# +#{ set.seed(7); round( rgamma(3,1), digits = 5 ) } +[1] 3.42520 0.95263 2.76594 + +##com.oracle.truffle.r.test.library.stats.TestStats.testRandom# +#{ set.seed(7); round( rlnorm(3), digits = 5 ) } +[1] 9.84779 0.30217 0.49943 + +##com.oracle.truffle.r.test.library.stats.TestStats.testRandom# +#{ set.seed(7); round( rlnorm(3,sdlog=c(10,3,0.5)), digits = 5 ) } +[1] 8.578043e+09 2.759000e-02 7.067000e-01 + ##com.oracle.truffle.r.test.library.stats.TestStats.testRandom# #{ set.seed(7); round( rnorm(3,c(1000,2,3),c(10,11)), digits = 5 ) } [1] 1022.87247 -11.16449 -3.94293 @@ -114576,6 +116601,10 @@ In qnorm(c(0.1, 0.9, 0.5, 1.00001, 0.99999), 100, c(20, 1)) : NaNs produced #{ set.seed(7); round( runif(3,1,10), digits = 5 ) } [1] 9.90018 4.57971 2.04128 +##com.oracle.truffle.r.test.library.stats.TestStats.testRandom# +#{ set.seed(7); round( runif(3,1:3,3:2), digits = 5 ) } +[1] 2.97782 2.00000 3.00000 + ##com.oracle.truffle.r.test.library.stats.TestStats.testRandom# #{ set.seed(7); runif(10) } [1] 0.98890930 0.39774545 0.11569778 0.06974868 0.24374939 0.79201043 @@ -114713,38 +116742,6 @@ In qnorm(c(0.1, 0.9, 0.5, 1.00001, 0.99999), 100, c(20, 1)) : NaNs produced #{ set.seed(9567, "Marsaglia-Multicarry"); sum(runif(100)) } [1] 52.92218 -##com.oracle.truffle.r.test.library.stats.TestStats.testRandomIgnore#Ignored.Unknown# -#{ set.seed(7); round( rcauchy(3), digits = 5 ) } -[1] -0.03486 3.00509 0.38038 - -##com.oracle.truffle.r.test.library.stats.TestStats.testRandomIgnore#Ignored.Unknown# -#{ set.seed(7); round( rcauchy(3, scale=4, location=1:3), digits = 5 ) } -[1] 0.86057 14.02037 4.52150 - -##com.oracle.truffle.r.test.library.stats.TestStats.testRandomIgnore#Ignored.Unknown# -#{ set.seed(7); round( rgamma(3,0.5,rate=1:3), digits = 5 ) } -[1] 3.63965 0.00938 0.02776 - -##com.oracle.truffle.r.test.library.stats.TestStats.testRandomIgnore#Ignored.Unknown# -#{ set.seed(7); round( rgamma(3,0.5,scale=1:3), digits = 5 ) } -[1] 3.63965 0.03753 0.24984 - -##com.oracle.truffle.r.test.library.stats.TestStats.testRandomIgnore#Ignored.Unknown# -#{ set.seed(7); round( rgamma(3,1), digits = 5 ) } -[1] 3.42520 0.95263 2.76594 - -##com.oracle.truffle.r.test.library.stats.TestStats.testRandomIgnore#Ignored.Unknown# -#{ set.seed(7); round( rlnorm(3), digits = 5 ) } -[1] 9.84779 0.30217 0.49943 - -##com.oracle.truffle.r.test.library.stats.TestStats.testRandomIgnore#Ignored.Unknown# -#{ set.seed(7); round( rlnorm(3,sdlog=c(10,3,0.5)), digits = 5 ) } -[1] 8.578043e+09 2.759000e-02 7.067000e-01 - -##com.oracle.truffle.r.test.library.stats.TestStats.testRandomIgnore#Ignored.Unknown# -#{ set.seed(7); round( runif(3,1:3,3:2), digits = 5 ) } -[1] 2.97782 2.00000 3.00000 - ##com.oracle.truffle.r.test.library.stats.TestStats.testRbinom# #set.seed(123); rbinom(1,20,c(0.3,0.2)) [1] 5 @@ -115168,15 +117165,15 @@ Error: unexpected '*' in: [1] TRUE ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI1# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.addInt(2L, 3L); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.addInt(2L, 3L); detach("package:testrffi", unload=T); x } [1] 5 ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI10# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); a <- c(1L,2L,3L); x <- rffi.iterate_iptr(a); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); a <- c(1L,2L,3L); x <- rffi.iterate_iptr(a); detach("package:testrffi", unload=T); x } [1] 1 2 3 ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI11# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.dotCModifiedArguments(c(0,1,2,3)); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.dotCModifiedArguments(c(0,1,2,3)); detach("package:testrffi", unload=T); x } [[1]] [1] 4 @@ -115191,7 +117188,7 @@ Error: unexpected '*' in: ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI12# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.dotExternalAccessArgs(1L, 3, c(1,2,3), c('a', 'b'), 'b', TRUE, as.raw(12)); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.dotExternalAccessArgs(1L, 3, c(1,2,3), c('a', 'b'), 'b', TRUE, as.raw(12)); detach("package:testrffi", unload=T); x } [[1]] [[1]][[1]] NULL @@ -115250,7 +117247,7 @@ NULL ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI13# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.dotExternalAccessArgs(x=1L, 3, c(1,2,3), y=c('a', 'b'), 'b', TRUE, as.raw(12)); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.dotExternalAccessArgs(x=1L, 3, c(1,2,3), y=c('a', 'b'), 'b', TRUE, as.raw(12)); detach("package:testrffi", unload=T); x } [[1]] [[1]][[1]] x @@ -115309,59 +117306,68 @@ NULL ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI14# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.invoke12(); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.invoke12(); detach("package:testrffi", unload=T); x } [1] 12 ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI15# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.TYPEOF(3L); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.TYPEOF(3L); detach("package:testrffi", unload=T); x } [1] 13 ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI16# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.isRString("hello"); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.isRString("hello"); detach("package:testrffi", unload=T); x } [1] TRUE ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI17# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.isRString(NULL); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.isRString(NULL); detach("package:testrffi", unload=T); x } [1] FALSE ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI18# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.interactive(); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.interactive(); detach("package:testrffi", unload=T); x } [1] FALSE ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI19# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- 1; x <- rffi.findVar(x, globalenv()); detach("package:testrffi"); x } -Error: could not find function "rffi.findVar" +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- 1; x <- rffi.findvar("x", globalenv()); detach("package:testrffi", unload=T); x } +[1] 1 ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI2# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.addDouble(2, 3); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.addDouble(2, 3); detach("package:testrffi", unload=T); x } [1] 5 ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI3# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.populateIntVector(5); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.populateIntVector(5); detach("package:testrffi", unload=T); x } [1] 0 1 2 3 4 ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI4# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.populateLogicalVector(5); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.populateLogicalVector(5); detach("package:testrffi", unload=T); x } [1] TRUE NA FALSE FALSE FALSE ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI5# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.mkStringFromChar(); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.mkStringFromChar(); detach("package:testrffi", unload=T); x } [1] "hello" ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI6# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.mkStringFromBytes(); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.mkStringFromBytes(); detach("package:testrffi", unload=T); x } [1] "hello" ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI7# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.null(); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.null(); detach("package:testrffi", unload=T); x } NULL +##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI7C# +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.null.C(); detach("package:testrffi", unload=T); x } +NULL + +##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI7E# +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.null.E(); detach("package:testrffi", unload=T); x } +Error in .Call("null", PACKAGE = "foo") : + "null" not available for .Call() for package "foo" + ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI8# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.isRString(character(0)); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); x <- rffi.isRString(character(0)); detach("package:testrffi", unload=T); x } [1] TRUE ##com.oracle.truffle.r.test.rffi.TestRFFIPackage.testRFFI9# -#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); a <- c(1L,2L,3L); x <- rffi.iterate_iarray(a); detach("package:testrffi"); x } +#{ library("testrffi", lib.loc = "tmptest/com.oracle.truffle.r.test.rpackages"); a <- c(1L,2L,3L); x <- rffi.iterate_iarray(a); detach("package:testrffi", unload=T); x } [1] 1 2 3 ##com.oracle.truffle.r.test.rffi.TestUserRNG.testUserRNG# diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java index 41a29e7c30c60c0d76f902975ed2a4fa92aba4e6..30a6d6d91d5452eaf144a3e67ac8336438ae1ee9 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java @@ -85,7 +85,7 @@ public class TestS4 extends TestRBase { public void testAllocation() { assertEval("{ new(\"numeric\") }"); assertEval("{ setClass(\"foo\", representation(j=\"numeric\")); new(\"foo\", j=42) }"); - + assertEval("{ setClass(\"foo\", representation(j=\"numeric\")); typeof(new(\"foo\", j=42)) }"); } @Test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_anyNA.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_anyNA.java index cea95545ce24d229ee5943fa53220345c2d9141b..4b36de5ed4b3ff0531c106d3a2e6413b7d2274db 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_anyNA.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_anyNA.java @@ -31,4 +31,15 @@ public class TestBuiltin_anyNA extends TestBase { assertEval("anyNA(list(list(4,5,NA), 3), recursive=TRUE)"); } + @Test + public void testanyNA3() { + assertEval("anyNA(c(1, 2, 3))"); + assertEval("anyNA(c(1, NA, 3))"); + assertEval("anyNA(c(1, NA, 3), recursive = TRUE)"); + assertEval("anyNA(list(a = c(1, 2, 3), b = 'a'))"); + assertEval("anyNA(list(a = c(1, NA, 3), b = 'a'))"); + assertEval("anyNA(list(a = c(1, 2, 3), b = 'a'), recursive = TRUE)"); + assertEval("anyNA(list(a = c(1, NA, 3), b = 'a'), recursive = TRUE)"); + } + } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascharacter.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascharacter.java index 6deb046c20253c0a5cfe6b6d718e071506d28b21..41bcaeff061282aa915931433bb3373631865486 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascharacter.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascharacter.java @@ -197,7 +197,7 @@ public class TestBuiltin_ascharacter extends TestBase { @Test public void testascharacter36() { - assertEval(Ignored.Unknown, "argv <- list(list(exit.code = 0L, send = NULL));as.character(argv[[1]]);"); + assertEval("argv <- list(list(exit.code = 0L, send = NULL));as.character(argv[[1]]);"); } @Test @@ -262,7 +262,7 @@ public class TestBuiltin_ascharacter extends TestBase { assertEval("{ as.character(list(c(\"hello\", \"hi\"))) }"); assertEval("{ as.character(list(list(c(\"hello\", \"hi\")))) }"); assertEval("{ as.character(list(c(2L, 3L))) }"); - assertEval(Ignored.Unknown, "{ as.character(list(c(2L, 3L, 5L))) }"); // GnuR prints no L + assertEval("{ as.character(list(c(2L, 3L, 5L))) }"); assertEval("{ x<-as.character(Sys.time()) }"); assertEval("{ f<-function(x) { sys.call() }; as.character(f(7)) }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_det.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_det.java index 03c916578780d4c15100169745c7226f424c5881..bc9640f6a04b95851c0127e2cc03d9de885e18ca 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_det.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_det.java @@ -41,6 +41,6 @@ public class TestBuiltin_det extends TestBase { public void testDet() { assertEval("{ det(matrix(c(1,2,4,5),nrow=2)) }"); assertEval("{ det(matrix(c(1,-3,4,-5),nrow=2)) }"); - assertEval(Ignored.Unknown, "{ det(matrix(c(1,0,4,NA),nrow=2)) }"); + assertEval("{ det(matrix(c(1,0,4,NA),nrow=2)) }"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimassign.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimassign.java index da6bda1e0cb7cc2ebe39516bfc246518da3e8a63..f76298ead2b14bf7a33e0e1fee0011b14932c8af 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimassign.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_dimassign.java @@ -71,4 +71,10 @@ public class TestBuiltin_dimassign extends TestBase { public void testdimassign11() { assertEval("argv <- list(structure(NA, .Dim = c(1L, 1L)), value = c(1L, 1L));`dim<-`(argv[[1]],argv[[2]]);"); } + + @Test + public void testdimassign12() { + assertEval("b <- c(a=1+2i,b=3+4i);dim(b) <- c(2,1);attributes(x)"); + } + } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java index 6811de383289d6f4fd895805930c125ee5e77f33..d2fdc75685a637c5ee7d4bb80484fef5a580ecc2 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java @@ -114,7 +114,7 @@ public class TestBuiltin_identical extends TestBase { @Test public void testidentical20() { - assertEval(Ignored.Unknown, "argv <- list(NaN, NaN, TRUE, TRUE, TRUE, TRUE, FALSE); .Internal(identical(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))"); + assertEval("argv <- list(NaN, NaN, TRUE, TRUE, TRUE, TRUE, FALSE); .Internal(identical(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))"); } @Test @@ -196,9 +196,8 @@ public class TestBuiltin_identical extends TestBase { @Test public void testidentical37() { - assertEval(Ignored.Unknown, - "argv <- structure(list(x = structure(list(a = NA, b = NA_integer_, c = NA_real_, d = NA_complex_, e = 1, f = 1L, g = 1:3, h = c(NA, 1L, 2L, 3L), i = NA_character_, j = c('foo', NA, 'bar')), .Names = c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')), y = structure(list(a = NA, b = NA_integer_, c = NA_real_, d = NA_complex_, e = 1, f = 1L, g = 1:3, h = c(NA, 1L, 2L, 3L), i = NA_character_, j = c('foo', NA, 'bar')), .Names = c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'))), .Names = c('x', 'y'));" + - "do.call('identical', argv)"); + assertEval("argv <- structure(list(x = structure(list(a = NA, b = NA_integer_, c = NA_real_, d = NA_complex_, e = 1, f = 1L, g = 1:3, h = c(NA, 1L, 2L, 3L), i = NA_character_, j = c('foo', NA, 'bar')), .Names = c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j')), y = structure(list(a = NA, b = NA_integer_, c = NA_real_, d = NA_complex_, e = 1, f = 1L, g = 1:3, h = c(NA, 1L, 2L, 3L), i = NA_character_, j = c('foo', NA, 'bar')), .Names = c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'))), .Names = c('x', 'y'));" + + "do.call('identical', argv)"); } @Test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log10.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log10.java index 11f19dd5403a7f4c9364119db2c3be4f59bb5790..a7cf88d1a1eacf5fd0e1e9d05c139a66f037154b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log10.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_log10.java @@ -63,7 +63,7 @@ public class TestBuiltin_log10 extends TestBase { assertEval("{ as.integer(log10(200)*100000) } "); assertEval("{ m <- matrix(1:4, nrow=2) ; round( log10(m), digits=5 ) }"); - assertEval(Ignored.Unknown, "{ x <- c(a=1, b=10) ; round( c(log(x), log10(x), log2(x)), digits=5 ) }"); + assertEval("{ x <- c(a=1, b=10) ; round( c(log(x), log10(x), log2(x)), digits=5 ) }"); assertEval("{ log10(c(1+1i, -1-1i)) }"); } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pretty.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pretty.java index 5151c51755823f045cc95948e1b2794b79dbeba0..e539220c8de8c727fd2174d91f79b4ca406baabe 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pretty.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_pretty.java @@ -19,23 +19,21 @@ public class TestBuiltin_pretty extends TestBase { @Test public void testpretty1() { - assertEval(Ignored.Unknown, "argv <- list(0L, 3L, 5, 1, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))"); + assertEval("argv <- list(0L, 3L, 5, 1, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))"); } @Test public void testpretty2() { - assertEval(Ignored.Unknown, "argv <- list(-0.03, 1.11, 5, 1, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))"); + assertEval("argv <- list(-0.03, 1.11, 5, 1, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))"); } @Test public void testpretty3() { - assertEval(Ignored.Unknown, - "argv <- list(-6.64448090063514e-06, 6.64454021993011e-06, 1, 0, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))"); + assertEval("argv <- list(-6.64448090063514e-06, 6.64454021993011e-06, 1, 0, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))"); } @Test public void testpretty4() { - assertEval(Ignored.Unknown, - "argv <- list(1.234e+100, 1.234e+100, 5, 1, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))"); + assertEval("argv <- list(1.234e+100, 1.234e+100, 5, 1, 0.75, c(1.5, 2.75), 0); .Internal(pretty(argv[[1]], argv[[2]], argv[[3]], argv[[4]], argv[[5]], argv[[6]], argv[[7]]))"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rawToBits.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rawToBits.java new file mode 100644 index 0000000000000000000000000000000000000000..c8f0a4c56f73c0e74f542fcc942964bbbe25d610 --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_rawToBits.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2016, 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.test.builtins; + +import org.junit.Test; + +import com.oracle.truffle.r.test.TestBase; + +// Checkstyle: stop line length check +public class TestBuiltin_rawToBits extends TestBase { + + @Test + public void testRawToBits() { + assertEval("rawToBits(raw(0))"); + assertEval("rawToBits(raw(10))"); + assertEval("rawToBits(as.raw(0))"); + assertEval("rawToBits(as.raw(1))"); + assertEval("rawToBits(as.raw(255))"); + assertEval("rawToBits(c(as.raw(1), as.raw(255)))"); + assertEval("rawToBits(raw(0), raw(1))"); + assertEval("rawToBits(as.raw(0:255))"); + assertEval("rawToBits(as.raw(c(0,1,255)))"); + + assertEval("rawToBits(as.raw(1)[1])"); + + assertEval("rawToBits(0:255)"); + assertEval("rawToBits(NA)"); + assertEval("rawToBits(NULL)"); + assertEval("rawToBits(list(list()))"); + assertEval("rawToBits(list(NULL))"); + assertEval("rawToBits(c(NULL))"); + + assertEval("rawToBits(integer(0))"); + assertEval("rawToBits(double(0))"); + + assertEval("rawToBits(01)"); + assertEval("rawToBits('a')"); + + assertEval("rawToBits(new.env())"); + assertEval("rawToBits(environment)"); + assertEval("rawToBits(stdout())"); + } +} diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sign.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sign.java index 11d3565ddd47e8c2ea4c83f23dc23b2a5a512354..c116a18a6446c801c66d22aa5853e87a88a00f93 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sign.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_sign.java @@ -61,4 +61,20 @@ public class TestBuiltin_sign extends TestBase { public void testsign9() { assertEval("argv <- list(numeric(0));sign(argv[[1]]);"); } + + @Test + public void testsign10() { + assertEval("sign(c(FALSE))"); + assertEval("sign(c(FALSE, TRUE))"); + assertEval("sign(c(1, -1, FALSE))"); + assertEval("sign(list(c(1, -1, FALSE))[[1]])"); + assertEval("sign(1i)"); + assertEval("sign(c(1, -1, FALSE, 1i))"); + assertEval("sign('a')"); + assertEval("sign('1')"); + assertEval("sign('1L')"); + assertEval("sign(NULL)"); + assertEval("sign(NaN)"); + assertEval("sign(NA_real_)"); + } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java index 11898e61ca3b04ff4c2f6eedc78dda28b32b5ab6..6a6b175ea891e7be107607c82849195514ea49d5 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestRandGenerationFunctions.java @@ -31,7 +31,7 @@ import com.oracle.truffle.r.test.TestBase; * tests for its specific corner cases if those are not covered here. */ public class TestRandGenerationFunctions extends TestBase { - private static final String[] FUNCTION2_NAMES = {"rnorm", "runif", "rgamma", "rbeta", "rcauchy", "rf", "rlogis", "rweibull", "rchisq", "rwilcox"}; + private static final String[] FUNCTION2_NAMES = {"rnorm", "runif", "rgamma", "rbeta", "rcauchy", "rf", "rlogis", "rweibull", "rchisq", "rwilcox", "rlnorm"}; private static final String[] FUNCTION2_PARAMS = { "10, 10, 10", "20, c(-1, 0, 0.2, 2:5), c(-1, 0, 0.1, 0.9, 3)", diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStatFunctions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStatFunctions.java new file mode 100644 index 0000000000000000000000000000000000000000..d15b49dd4f2a0250212fd7abd5e035e24cb85ffc --- /dev/null +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStatFunctions.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2014, 2016, 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.test.library.stats; + +import org.junit.Test; + +import com.oracle.truffle.r.test.TestBase; + +/** + * Common tests for functions implemented using {@code StatsFunctions} infrastructure. + */ +public class TestStatFunctions extends TestBase { + private static final String[] FUNCTION3_1_NAMES = {"dgamma", "dbeta", "dcauchy", "dlnorm"}; + private static final String[] FUNCTION3_1_PARAMS = { + "10, 10, 10, log=TRUE", + "3, 3, 3, log=FALSE", + "c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=TRUE", + "c(-1, 0, 1), c(-1, 0, 0.2, 2:5), rep(c(-1, 0, 0.1, 0.9, 3), 12), log=FALSE", + "0, c(NA, 0, NaN, 1/0, -1/0), c(NaN, NaN, NA, 0, 1/0, -1/0), log=FALSE", + "0, c(0.0653, 0.000123, 32e-80, 8833, 79e70), c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE", + "c(NA, NaN, 1/0, -1/0), 2, 2, log=FALSE" + }; + + @Test + public void testFunctions31() { + assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1)", FUNCTION3_1_NAMES, FUNCTION3_1_PARAMS)); + } + + private static final String[] FUNCTION2_1_NAMES = {"dchisq", "dexp", "dgeom", "dpois", "dt"}; + private static final String[] FUNCTION2_1_PARAMS = { + "10, 10, log=TRUE", + "3, 3, log=FALSE", + "c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=TRUE", + "c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4), log=FALSE", + "c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), log=FALSE", + "0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), log=FALSE" + }; + + @Test + public void testFunctions21() { + assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1)", FUNCTION2_1_NAMES, FUNCTION2_1_PARAMS)); + } + + private static final String[] FUNCTION2_2_NAMES = {"pchisq", "pexp", "qexp", "qgeom"}; + private static final String[] FUNCTION2_2_PARAMS = { + "0, 10", + "c(-1, 0, 0.2, 2), rep(c(-1, 0, 0.1, 0.9, 3), 4)", + "0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1)" + }; + + @Test + public void testFunctions22() { + // first: the "normal params" with all the combinations of log.p and lower.tail + assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1, %2, %3)", + FUNCTION2_2_NAMES, FUNCTION2_2_PARAMS, new String[]{"lower.tail=TRUE", "lower.tail=FALSE"}, new String[]{"log.p=TRUE", "log.p=FALSE"})); + // the error cases (where log.p nor lower.tail should make no difference) + // first parameter wrong + assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1)", FUNCTION2_2_NAMES, new String[]{"c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)"})); + // second parameter wrong + assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1)", FUNCTION2_2_NAMES, new String[]{"rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)"})); + } + + private static final String[] FUNCTION3_2_NAMES = {"pbeta", "pcauchy", "qcauchy", "qlnorm", "plnorm"}; + private static final String[] FUNCTION3_2_PARAMS = { + "0, 10, 10", + "c(-1, 0, 0.2, 2), c(-1, 0, 0.1, 0.9, 3), rep(c(-1, 0, 1, 0.1, -0.1, 0.0001), 20)", + "0, c(0.0653, 0.000123, 32e-80, 8833, 79e70, 0, -1), rep(c(0.0653, 0.000123, 32e-80, 8833, 79e70), 7)" + }; + + @Test + public void testFunctions32() { + // first: the "normal params" with all the combinations of log.p and lower.tail + assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1, %2, %3)", + FUNCTION3_2_NAMES, FUNCTION3_2_PARAMS, new String[]{"lower.tail=TRUE", "lower.tail=FALSE"}, new String[]{"log.p=TRUE", "log.p=FALSE"})); + // the error cases (where log.p nor lower.tail should make no difference) + // first parameter wrong + assertEval(Output.IgnoreWarningContext, + template("set.seed(1); %0(%1)", FUNCTION3_2_NAMES, new String[]{"c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5)"})); + // second parameter wrong + assertEval(Output.IgnoreWarningContext, + template("set.seed(1); %0(%1)", FUNCTION3_2_NAMES, new String[]{"rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0), rep(c(1, 0, 0.1), 5)"})); + // third parameter wrong + assertEval(Output.IgnoreWhitespace, template("set.seed(1); %0(%1)", FUNCTION3_2_NAMES, new String[]{"rep(c(1, 0, 0.1), 5), rep(c(1, 0, 0.1), 5), c(NA, 0, NaN, 1/0, -1/0)"})); + } +} diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStats.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStats.java index 3ab6478a9f128b4f225e287d530217da3861d220..13121b775e0e31a4c03bf5a724f14a9283b2760a 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStats.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/stats/TestStats.java @@ -143,25 +143,21 @@ public class TestStats extends TestBase { assertEval("{ set.seed(7); round( runif(3), digits = 5 ) }"); assertEval("{ set.seed(7); round( runif(3,1,10), digits = 5 ) }"); + assertEval("{ set.seed(7); round( runif(3,1:3,3:2), digits = 5 ) }"); assertEval("{ set.seed(7); round( rnorm(3,c(1000,2,3),c(10,11)), digits = 5 ) }"); assertEval("{ set.seed(7); round( rbinom(3,3,0.9), digits = 5 ) }"); assertEval("{ set.seed(7); round( rbinom(3,10,(1:5)/5), digits = 5 ) }"); - } - - @Test - public void testRandomIgnore() { - assertEval(Ignored.Unknown, "{ set.seed(7); round( runif(3,1:3,3:2), digits = 5 ) }"); - assertEval(Ignored.Unknown, "{ set.seed(7); round( rgamma(3,1), digits = 5 ) }"); - assertEval(Ignored.Unknown, "{ set.seed(7); round( rgamma(3,0.5,scale=1:3), digits = 5 ) }"); - assertEval(Ignored.Unknown, "{ set.seed(7); round( rgamma(3,0.5,rate=1:3), digits = 5 ) }"); + assertEval("{ set.seed(7); round( rgamma(3,1), digits = 5 ) }"); + assertEval("{ set.seed(7); round( rgamma(3,0.5,scale=1:3), digits = 5 ) }"); + assertEval("{ set.seed(7); round( rgamma(3,0.5,rate=1:3), digits = 5 ) }"); - assertEval(Ignored.Unknown, "{ set.seed(7); round( rlnorm(3), digits = 5 ) }"); - assertEval(Ignored.Unknown, "{ set.seed(7); round( rlnorm(3,sdlog=c(10,3,0.5)), digits = 5 ) }"); + assertEval("{ set.seed(7); round( rcauchy(3), digits = 5 ) }"); + assertEval("{ set.seed(7); round( rcauchy(3, scale=4, location=1:3), digits = 5 ) }"); - assertEval(Ignored.Unknown, "{ set.seed(7); round( rcauchy(3), digits = 5 ) }"); - assertEval(Ignored.Unknown, "{ set.seed(7); round( rcauchy(3, scale=4, location=1:3), digits = 5 ) }"); + assertEval("{ set.seed(7); round( rlnorm(3), digits = 5 ) }"); + assertEval("{ set.seed(7); round( rlnorm(3,sdlog=c(10,3,0.5)), digits = 5 ) }"); } @Test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackage.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackage.java index 1b8cd192ef964076af0a275b3de0b31ace62002a..40270c5de51f4b35661184065b85a52780d0e742 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackage.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/rffi/TestRFFIPackage.java @@ -43,8 +43,13 @@ public class TestRFFIPackage extends TestRPackages { tearDownUninstallTestPackages(TEST_PACKAGES); } + /** + * This is somewhat expensive to do per test, but the only alternative is to put all the + * micro-tests in one big test. It might be that this should be switched to an R file-based + * approach as the number of tests increase. + */ private void assertEvalWithLibWithSetup(String setup, String test) { - assertEval(TestBase.template("{ library(\"testrffi\", lib.loc = \"%0\"); " + setup + "x <- " + test + "; detach(\"package:testrffi\"); x }", new String[]{TestRPackages.libLoc()})); + assertEval(TestBase.template("{ library(\"testrffi\", lib.loc = \"%0\"); " + setup + "x <- " + test + "; detach(\"package:testrffi\", unload=T); x }", new String[]{TestRPackages.libLoc()})); } private void assertEvalWithLib(String test) { @@ -86,6 +91,16 @@ public class TestRFFIPackage extends TestRPackages { assertEvalWithLib("rffi.null()"); } + @Test + public void testRFFI7E() { + assertEvalWithLib("rffi.null.E()"); + } + + @Test + public void testRFFI7C() { + assertEvalWithLib("rffi.null.C()"); + } + @Test public void testRFFI8() { assertEvalWithLib("rffi.isRString(character(0))"); @@ -143,6 +158,6 @@ public class TestRFFIPackage extends TestRPackages { @Test public void testRFFI19() { - assertEvalWithLibWithSetup("x <- 1; ", "rffi.findVar(x, globalenv())"); + assertEvalWithLibWithSetup("x <- 1; ", "rffi.findvar(\"x\", globalenv())"); } } diff --git a/mx.fastr/copyrights/overrides b/mx.fastr/copyrights/overrides index 34b4bca629f2ceea3857c3c258899c620e4673e9..0467373d319614885a7468b7ad3c4ddd3c190853 100644 --- a/mx.fastr/copyrights/overrides +++ b/mx.fastr/copyrights/overrides @@ -31,7 +31,7 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/Slot.java, com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Arithmetic.java,gnu_r_gentleman_ihaka.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RBeta.java,gnu_r_gentleman_ihaka.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMultinom.java,gnu_r_gentleman_ihaka.copyright -com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RCauchy.java,gnu_r_ihaka_core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cauchy.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Cdist.java,gnu_r_gentleman_ihaka.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/CompleteCases.java,gnu_r_gentleman_ihaka2.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Covcor.java,gnu_r.copyright @@ -42,7 +42,6 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DoubleCentre com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPQ.java,gnu_r.core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rt.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/GammaFunctions.java,gnu_r_qgamma.copyright -com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/QHyper.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RHyper.java,gnu_r_ihaka.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathInit.java,gnu_r.core.copyright @@ -57,10 +56,13 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Random2.java com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RPois.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rbinom.java,gnu_r_ihaka.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rnorm.java,gnu_r.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Chisq.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SplineFunctions.java,gnu_r_splines.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsFunctions.java,gnu_r_gentleman_ihaka.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RandGenerationFunctions.java,gnu_r_gentleman_ihaka.copyright -com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/StatsUtil.java,gnu_r_ihaka.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RMath.java,gnu_r_ihaka.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/LogNormal.java,gnu_r_ihaka.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/MathConstants.java,gnu_r_ihaka.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/TOMS708.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SNorm.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/SExp.java,gnu_r_ihaka_core.copyright @@ -69,8 +71,12 @@ com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNbinomMu.ja com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RLogis.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Rf.java,gnu_r_ihaka_core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RChisq.java,gnu_r_ihaka_core.copyright -com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RExp.java,gnu_r_ihaka_core.copyright -com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RGeom.java,gnu_r_ihaka_core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Exp.java,gnu_r_ihaka_core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Geom.java,gnu_r_ihaka_core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Dt.java,gnu_r.core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Df.java,gnu_r.core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DBeta.java,gnu_r.core.copyright +com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/DPois.java,gnu_r.core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RNchisq.java,gnu_r.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/Wilcox.java,gnu_r.core.copyright com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/RWeibull.java,gnu_r_ihaka_core.copyright @@ -149,12 +155,12 @@ com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/D com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EncodeString.java,purdue.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CairoProps.java,gnu_r.copyright -com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/DotC.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Fft.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Flushconsole.java,gnu_r.copyright -com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ForeignFunctions.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/FortranAndCFunctions.java,gnu_r.copyright +com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/CallAndExternalFunctions.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/MakeQuartzDefault.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/ReadTableHead.java,gnu_r.copyright com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dnorm4.java,gnu_r.copyright diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py index 2166292810b8b4f6b8c48aad1d718472f0ef01f9..4003efe2cde967c8fb499814c73639ad8a24837c 100644 --- a/mx.fastr/suite.py +++ b/mx.fastr/suite.py @@ -28,7 +28,7 @@ suite = { "suites" : [ { "name" : "truffle", - "version" : "f0c06d466056ad23e05aa3d21b98405cd72f117b", + "version" : "13641c9f68eefccd0099d283ca25d6bb44b3349a", "urls" : [ {"url" : "https://github.com/graalvm/truffle", "kind" : "git"}, {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},