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/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.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 1f60bc3c9a673dbfc2c6f9fd50be439b9d18ac06..025fd11d7fdf7709d0c9bd88d687a2a8d839ed86 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 @@ -465,7 +465,6 @@ public final class RContext extends ExecutionContext implements TruffleObject { this.stateInstrumentation = InstrumentationState.newContextState(instrumenter); this.stateInternalCode = ContextStateImpl.newContextState(); this.engine = RContext.getRRuntimeASTAccess().createEngine(this); - state.add(State.CONSTRUCTED); } @@ -523,8 +522,6 @@ public final class RContext extends ExecutionContext implements TruffleObject { stateStdConnections.initialize(this); stateRNG.initialize(this); this.stateRFFI = RFFIContextStateFactory.newContextState().initialize(this); - - stateRFFI.initialize(this); stateRSerialize.initialize(this); stateLazyDBCache.initialize(this); stateInstrumentation.initialize(this); @@ -787,6 +784,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(); } 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(); }