# HG changeset patch # User Jaroslav Tulach # Date 1445540823 -7200 # Node ID 096e2c0fd2dc2378364d09b76ec752c261e37778 # Parent 7c396c4f46f5203dff16d48669060cad56e83341 Cannot pass VirtualFrame into a Runnable. Either invoke the call directly or materialize the frame diff -r 7c396c4f46f5 -r 096e2c0fd2dc truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java --- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java Thu Oct 22 19:59:02 2015 +0200 +++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java Thu Oct 22 21:07:03 2015 +0200 @@ -51,6 +51,7 @@ import java.util.logging.Logger; import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleLanguage.Env; @@ -58,6 +59,7 @@ import com.oracle.truffle.api.debug.Debugger; import com.oracle.truffle.api.debug.ExecutionEvent; import com.oracle.truffle.api.debug.SuspendedEvent; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.impl.Accessor; import com.oracle.truffle.api.instrument.Instrumenter; @@ -106,6 +108,12 @@ @SuppressWarnings("rawtypes") public class PolyglotEngine { static final boolean JAVA_INTEROP_ENABLED = !Boolean.getBoolean("com.oracle.truffle.aot"); + private static final Executor DIRECT_EXECUTOR = new Executor() { + @Override + public void execute(Runnable command) { + command.run(); + } + }; static final Logger LOG = Logger.getLogger(PolyglotEngine.class.getName()); private static final SPIAccessor SPI = new SPIAccessor(); @@ -349,12 +357,7 @@ if (in == null) { in = System.in; } - Executor nonNullExecutor = executor != null ? executor : new Executor() { - @Override - public void execute(Runnable command) { - command.run(); - } - }; + Executor nonNullExecutor = executor != null ? executor : DIRECT_EXECUTOR; return new PolyglotEngine(nonNullExecutor, globals, out, err, in, handlers.toArray(new EventConsumer[0])); } } @@ -526,22 +529,37 @@ } @SuppressWarnings("try") - final Object invokeForeign(final Node foreignNode, final VirtualFrame frame, final TruffleObject receiver) throws IOException { + final Object invokeForeign(final Node foreignNode, VirtualFrame frame, final TruffleObject receiver) throws IOException { final Object[] res = {null, null}; + if (executor == DIRECT_EXECUTOR) { + try (final Closeable c = SPI.executionStart(PolyglotEngine.this, -1, debugger, null)) { + final Object[] args = ForeignAccess.getArguments(frame).toArray(); + res[0] = ForeignAccess.execute(foreignNode, frame, receiver, args); + } + } else { + invokeForeignOnExecutor(foreignNode, frame, receiver, res); + } + exceptionCheck(res); + if (res[0] instanceof TruffleObject) { + return new EngineTruffleObject(this, (TruffleObject) res[0]); + } else { + return res[0]; + } + } + + @TruffleBoundary + private void invokeForeignOnExecutor(final Node foreignNode, VirtualFrame frame, final TruffleObject receiver, final Object[] res) throws IOException { + final MaterializedFrame materialized = frame.materialize(); final CountDownLatch computed = new CountDownLatch(1); - final Thread caller = Thread.currentThread(); executor.execute(new Runnable() { + @SuppressWarnings("try") @Override public void run() { try (final Closeable c = SPI.executionStart(PolyglotEngine.this, -1, debugger, null)) { - final Object[] args = ForeignAccess.getArguments(frame).toArray(); - if (caller != Thread.currentThread()) { - RootNode node = SymbolInvokerImpl.createTemporaryRoot(TruffleLanguage.class, foreignNode, receiver, args.length); - final CallTarget target = Truffle.getRuntime().createCallTarget(node); - res[0] = target.call(args); - } else { - res[0] = ForeignAccess.execute(foreignNode, frame, receiver, args); - } + final Object[] args = ForeignAccess.getArguments(materialized).toArray(); + RootNode node = SymbolInvokerImpl.createTemporaryRoot(TruffleLanguage.class, foreignNode, receiver, args.length); + final CallTarget target = Truffle.getRuntime().createCallTarget(node); + res[0] = target.call(args); } catch (Exception ex) { res[1] = ex; } finally { @@ -554,12 +572,6 @@ } catch (InterruptedException ex) { throw new InterruptedIOException(ex.getMessage()); } - exceptionCheck(res); - if (res[0] instanceof TruffleObject) { - return new EngineTruffleObject(this, (TruffleObject) res[0]); - } else { - return res[0]; - } } /** diff -r 7c396c4f46f5 -r 096e2c0fd2dc truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Thu Oct 22 19:59:02 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Thu Oct 22 21:07:03 2015 +0200 @@ -33,6 +33,7 @@ import com.oracle.truffle.api.Assumption; import com.oracle.truffle.api.CallTarget; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleLanguage.Env; @@ -267,6 +268,7 @@ private static Reference previousVM = new WeakReference<>(null); private static Assumption oneVM = Truffle.getRuntime().createAssumption(); + @TruffleBoundary @SuppressWarnings("unused") protected Closeable executionStart(Object vm, int currentDepth, Debugger debugger, Source s) { vm.getClass(); @@ -280,6 +282,7 @@ } CURRENT_VM.set(vm); class ContextCloseable implements Closeable { + @TruffleBoundary @Override public void close() throws IOException { CURRENT_VM.set(prev);