diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index 5245ffc126395a7b4409feddcc38e9dae9dd2f4c..8798c06e6976de8811a41bef02f894a70457e50d 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -40,6 +40,7 @@ import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.interop.java.JavaInterop; import com.oracle.truffle.api.nodes.DirectCallNode; import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.Node; @@ -142,8 +143,7 @@ final class REngine implements Engine, Engine.Timings { } static REngine create(RContext context) { - REngine engine = new REngine(context); - return engine; + return new REngine(context); } @Override @@ -294,8 +294,21 @@ final class REngine implements Engine, Engine.Timings { @Override public CallTarget parseToCallTarget(Source source, MaterializedFrame executionFrame) throws ParseException { - List<RSyntaxNode> statements = parseImpl(source); - return Truffle.getRuntime().createCallTarget(new PolyglotEngineRootNode(statements, createSourceSection(source, statements), executionFrame)); + if (source == Engine.GET_CONTEXT) { + /* + * The "get context" operations should be executed with as little influence on the + * actual engine as possible, therefore this special case takes care of it explicitly. + */ + return Truffle.getRuntime().createCallTarget(new RootNode(TruffleRLanguage.class, source.createUnavailableSection(), new FrameDescriptor()) { + @Override + public Object execute(VirtualFrame frame) { + return JavaInterop.asTruffleValue(context); + } + }); + } else { + List<RSyntaxNode> statements = parseImpl(source); + return Truffle.getRuntime().createCallTarget(new PolyglotEngineRootNode(statements, createSourceSection(source, statements), executionFrame)); + } } private static SourceSection createSourceSection(Source source, List<RSyntaxNode> statements) { diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/nfi/TruffleNFI_DLL.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/nfi/TruffleNFI_DLL.java index 21ca2496f3858240a1faf422f477d976fd7a83a1..36cfaaa2d30743e96f318b91c81d3f5d1203fc87 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/nfi/TruffleNFI_DLL.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/nfi/TruffleNFI_DLL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 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 @@ -23,6 +23,7 @@ package com.oracle.truffle.r.engine.interop.ffi.nfi; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.Message; @@ -30,7 +31,6 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.ffi.DLL; @@ -54,8 +54,8 @@ public class TruffleNFI_DLL implements DLLRFFI { @Override public Object execute(String path, boolean local, boolean now) { String libName = DLL.libName(path); - PolyglotEngine engine = RContext.getInstance().getVM(); - TruffleObject libHandle = engine.eval(Source.newBuilder(prepareLibraryOpen(path, local, now)).name(path).mimeType("application/x-native").build()).as(TruffleObject.class); + Env env = RContext.getInstance().getEnv(); + TruffleObject libHandle = (TruffleObject) env.parse(Source.newBuilder(prepareLibraryOpen(path, local, now)).name(path).mimeType("application/x-native").build()).call(); return new NFIHandle(libName, libHandle); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/nfi/TruffleNFI_Utils.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/nfi/TruffleNFI_Utils.java index df1edddf964d9ec2510fab9921b5ae1445d698bc..92a0e6dcb43f4931571047721eaa3d5e74c3c4f2 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/nfi/TruffleNFI_Utils.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/nfi/TruffleNFI_Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -24,13 +24,13 @@ package com.oracle.truffle.r.engine.interop.ffi.nfi; import java.nio.charset.StandardCharsets; +import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.engine.interop.UnsafeAdapter; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.context.RContext; @@ -59,8 +59,8 @@ public class TruffleNFI_Utils { private static void initDefaultLibrary() { if (defaultLibrary == null) { - PolyglotEngine engine = RContext.getInstance().getVM(); - defaultLibrary = engine.eval(Source.newBuilder("default").name("(load default)").mimeType("application/x-native").build()).as(TruffleObject.class); + Env env = RContext.getInstance().getEnv(); + defaultLibrary = (TruffleObject) env.parse(Source.newBuilder("default").name("(load default)").mimeType("application/x-native").build()).call(); } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RCommand.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RCommand.java index 53d4271bb1e0900510967b3f85d286e3599641cb..805e959e9a08a6edfdb723155e04f798c151bc3e 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RCommand.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/RCommand.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -53,6 +53,7 @@ import com.oracle.truffle.r.runtime.Utils.DebugExitException; import com.oracle.truffle.r.runtime.context.ConsoleHandler; import com.oracle.truffle.r.runtime.context.ContextInfo; import com.oracle.truffle.r.runtime.context.DefaultConsoleHandler; +import com.oracle.truffle.r.runtime.context.Engine; import com.oracle.truffle.r.runtime.context.Engine.IncompleteSourceException; import com.oracle.truffle.r.runtime.context.Engine.ParseException; import com.oracle.truffle.r.runtime.context.RContext; @@ -203,8 +204,8 @@ public class RCommand { */ static int readEvalPrint(PolyglotEngine vm) { int lastStatus = 0; - ContextInfo contextInfo = ContextInfo.getContextInfo(vm); - ConsoleHandler consoleHandler = contextInfo.getConsoleHandler(); + RContext context = vm.eval(Engine.GET_CONTEXT).as(RContext.class); + ConsoleHandler consoleHandler = context.getConsoleHandler(); try { // console.println("initialize time: " + (System.currentTimeMillis() - start)); REPL: for (;;) { @@ -261,7 +262,7 @@ public class RCommand { } catch (ExitException e) { // usually from quit int status = e.getStatus(); - if (contextInfo.getParent() == null) { + if (context.getParent() == null) { vm.dispose(); Utils.systemExit(status); } else { @@ -287,7 +288,7 @@ public class RCommand { Utils.systemExit(0); } catch (ExitException e) { // normal quit, but with exit code based on lastStatus - if (contextInfo.getParent() == null) { + if (context.getParent() == null) { Utils.systemExit(lastStatus); } else { return lastStatus; diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/REmbedded.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/REmbedded.java index d0031dd9f6d0c394ef56f41ec992a90c4ae36d50..9a6d8d94903577442904ccfc77149c8272231f6a 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/REmbedded.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/shell/REmbedded.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -31,6 +31,7 @@ import com.oracle.truffle.r.runtime.RSource.Internal; import com.oracle.truffle.r.runtime.RStartParams; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.context.ContextInfo; +import com.oracle.truffle.r.runtime.context.Engine; import com.oracle.truffle.r.runtime.context.RContext; /** @@ -105,7 +106,7 @@ public class REmbedded { */ public static void main(String[] args) { PolyglotEngine vm = initializeR(args); - RStartParams startParams = ContextInfo.getContextInfo(vm).getStartParams(); + RStartParams startParams = vm.eval(Engine.GET_CONTEXT).as(RContext.class).getStartParams(); startParams.setEmbedded(); startParams.setLoadInitFile(false); startParams.setNoRenviron(true); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/ContextInfo.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/ContextInfo.java index d048d228286590d1bedb946e5ebe84c5ccaab5c7..c1d39f9b1e21dc4bb76377f176aa8afb31bb60a6 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/ContextInfo.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/ContextInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,7 +25,6 @@ package com.oracle.truffle.r.runtime.context; import java.util.TimeZone; import java.util.concurrent.atomic.AtomicInteger; -import com.oracle.truffle.api.interop.java.JavaInterop; import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.RCmdOptions; import com.oracle.truffle.r.runtime.RCmdOptions.Client; @@ -39,7 +38,7 @@ import com.oracle.truffle.r.runtime.context.RContext.ContextKind; * instance (it will be stored in the "fastrContextInfo" global symbol). */ public final class ContextInfo { - public static final String GLOBAL_SYMBOL = "fastrContextInfo"; + static final String CONFIG_KEY = "fastrContextInfo"; private static final AtomicInteger contextInfoIds = new AtomicInteger(); @@ -68,13 +67,13 @@ public final class ContextInfo { } public PolyglotEngine createVM() { - PolyglotEngine newVM = PolyglotEngine.newBuilder().globalSymbol(GLOBAL_SYMBOL, JavaInterop.asTruffleObject(this)).build(); + PolyglotEngine newVM = PolyglotEngine.newBuilder().config("application/x-r", CONFIG_KEY, this).build(); this.vm = newVM; return newVM; } public PolyglotEngine createVM(PolyglotEngine.Builder builder) { - PolyglotEngine newVM = builder.globalSymbol(GLOBAL_SYMBOL, JavaInterop.asTruffleObject(this)).build(); + PolyglotEngine newVM = builder.config("application/x-r", CONFIG_KEY, this).build(); this.vm = newVM; return newVM; } @@ -114,10 +113,6 @@ public final class ContextInfo { return create(params, env, kind, parent, consoleHandler); } - public static ContextInfo getContextInfo(PolyglotEngine vm) { - return vm.findGlobalSymbol(ContextInfo.GLOBAL_SYMBOL).as(ContextInfo.class); - } - public RStartParams getStartParams() { return startParams; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java index ac6079435a58436bed6d286fe3e30f23d5048c51..6c7f7f692cc73dc2134594d4f5c71f4bc65dd99d 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java @@ -30,6 +30,7 @@ import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RSource; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; @@ -39,6 +40,8 @@ import com.oracle.truffle.r.runtime.nodes.RNode; public interface Engine { + Source GET_CONTEXT = RSource.fromTextInternal("<<<get_context>>>", RSource.Internal.GET_CONTEXT); + class ParseException extends RuntimeException { private static final long serialVersionUID = 1L; 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 3e7f4875fca710868853b0e95dc44d72ef3d538b..64339a2fc5dac568b8b2845d39e1f517da5c5210 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -40,7 +40,6 @@ import com.oracle.truffle.api.TruffleLanguage; import com.oracle.truffle.api.TruffleLanguage.Env; import com.oracle.truffle.api.instrumentation.Instrumenter; import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.java.JavaInterop; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.ExitException; @@ -58,7 +57,6 @@ import com.oracle.truffle.r.runtime.RProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RRuntimeASTAccess; import com.oracle.truffle.r.runtime.RSerialize; -import com.oracle.truffle.r.runtime.RSource; import com.oracle.truffle.r.runtime.RStartParams; import com.oracle.truffle.r.runtime.TempPathName; import com.oracle.truffle.r.runtime.Utils; @@ -71,6 +69,7 @@ import com.oracle.truffle.r.runtime.context.Engine.ParseException; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; 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.env.REnvironment; import com.oracle.truffle.r.runtime.ffi.DLL; @@ -215,8 +214,6 @@ public final class RContext extends ExecutionContext { */ public static class EvalThread extends ContextThread { - private static final Source GET_CONTEXT = RSource.fromTextInternal("invisible(.fastr.context.get())", RSource.Internal.GET_CONTEXT); - private final Source source; private final ContextInfo info; private RList evalResult; @@ -232,9 +229,9 @@ public final class RContext extends ExecutionContext { @Override public void run() { - PolyglotEngine vm = info.createVM(); + PolyglotEngine vm = info.createVM(PolyglotEngine.newBuilder()); try { - setContext(vm.eval(GET_CONTEXT).as(RContext.class)); + setContext(vm.eval(Engine.GET_CONTEXT).as(RContext.class)); } catch (Throwable t) { throw new RInternalError(t, "error while initializing eval thread"); } @@ -260,6 +257,9 @@ public final class RContext extends ExecutionContext { } catch (ExitException e) { // termination, treat this as "success" evalResult = RDataFactory.createList(new Object[]{e.getStatus()}); + } catch (RError e) { + // nothing to do + evalResult = RDataFactory.createList(new Object[]{RNull.instance}); } catch (Throwable t) { // some internal error RInternalError.reportErrorAndConsoleLog(t, info.getConsoleHandler(), info.getId()); @@ -445,7 +445,7 @@ public final class RContext extends ExecutionContext { * @param isInitial {@code true} if this is the initial (primordial) context. */ private RContext(Env env, Instrumenter instrumenter, boolean isInitial) { - Object initialInfo = env.importSymbol(ContextInfo.GLOBAL_SYMBOL); + Object initialInfo = env.getConfig().get(ContextInfo.CONFIG_KEY); if (initialInfo == null) { /* * This implies that FastR is being invoked initially from another Truffle language and @@ -455,7 +455,7 @@ public final class RContext extends ExecutionContext { this.info = ContextInfo.create(new RStartParams(RCmdOptions.parseArguments(Client.R, new String[]{"--no-restore"}, false), false), null, ContextKind.SHARE_NOTHING, null, new DefaultConsoleHandler(env.in(), env.out())); } else { - this.info = JavaInterop.asJavaObject(ContextInfo.class, (TruffleObject) initialInfo); + this.info = (ContextInfo) initialInfo; } this.initial = isInitial; diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRTckTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRTckTest.java index 1d79ee857fc804394e83d3bd71097fbca34f8cbd..48193aea07c9e1b9520caabde5ebb6c4d6cff012 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRTckTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRTckTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, 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 @@ -40,8 +40,7 @@ import com.oracle.truffle.tck.TruffleTCK; public class FastRTckTest extends TruffleTCK { @Test public void testVerifyPresence() { - PolyglotEngine vm = PolyglotEngine.newBuilder().globalSymbol(ContextInfo.GLOBAL_SYMBOL, - null).build(); + PolyglotEngine vm = PolyglotEngine.newBuilder().build(); assertTrue("Our language is present", vm.getLanguages().containsKey("text/x-r")); }