changeset 22174:0bcfe8c6088f

The central API to invoke various programs is now PolyglotEngine - a polyglot-ready enhancement of JDK's ScriptEngine
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Tue, 22 Sep 2015 11:22:26 +0200
parents 0480c4873a4a (current diff) dcb70d90c11d (diff)
children 5d2a12c9aae1
files truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/TruffleVMSingleThreadedTest.java truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/TruffleVM.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java
diffstat 30 files changed, 1254 insertions(+), 1045 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG.md	Mon Sep 21 13:11:41 2015 +0200
+++ b/CHANGELOG.md	Tue Sep 22 11:22:26 2015 +0200
@@ -11,8 +11,8 @@
 17-Jul-2015, [Repository Revision](http://lafo.ssw.uni-linz.ac.at/hg/truffle/shortlog/graal-0.8)
 ### Truffle
 * The Truffle repository no longer contains Graal
-* TruffleVM is an entrypoint for creating, building and running multi language Truffle systems
-* Implement TruffleLanguage and use @Registration to register your language into the TruffleVM system
+* PolyglotEngine is an entrypoint for creating, building and running multi language Truffle systems
+* Implement TruffleLanguage and use @Registration to register your language into the Truffle polyglot system
 * Include Truffle TCK (test compatibility kit) into your test cases to verify your language implementation is compliant enough
 * Interoperability API polished
 * Cleanup of Source related API
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/AccessorTest.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/AccessorTest.java	Tue Sep 22 11:22:26 2015 +0200
@@ -27,7 +27,7 @@
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.ExportImportLanguage1;
 import static com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.L1;
-import com.oracle.truffle.api.vm.TruffleVM;
+import com.oracle.truffle.api.vm.PolyglotEngine;
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -50,8 +50,8 @@
 
     @Test
     public void canGetAccessToOwnLanguageInstance() throws Exception {
-        TruffleVM vm = TruffleVM.newVM().executor(Executors.newSingleThreadExecutor()).build();
-        TruffleVM.Language language = vm.getLanguages().get(L1);
+        PolyglotEngine vm = PolyglotEngine.buildNew().executor(Executors.newSingleThreadExecutor()).build();
+        PolyglotEngine.Language language = vm.getLanguages().get(L1);
         assertNotNull("L1 language is defined", language);
 
         Source s = Source.fromText("return nothing", "nothing").withMimeType(L1);
@@ -63,7 +63,7 @@
         assertTrue("Right instance: " + afterInitialization, afterInitialization instanceof ExportImportLanguage1);
     }
 
-    Object findLanguageByClass(TruffleVM vm) throws IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
+    Object findLanguageByClass(PolyglotEngine vm) throws IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
         Method find = Accessor.class.getDeclaredMethod("findLanguage", Object.class, Class.class);
         find.setAccessible(true);
         TruffleLanguage.Env env = (TruffleLanguage.Env) find.invoke(API, vm, ExportImportLanguage1.class);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/EngineSingleThreadedTest.java	Tue Sep 22 11:22:26 2015 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, 2015, 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.api.test.vm;
+
+import com.oracle.truffle.api.source.Source;
+import com.oracle.truffle.api.vm.PolyglotEngine;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URI;
+import java.net.URISyntaxException;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EngineSingleThreadedTest {
+    PolyglotEngine tvm;
+
+    @Before
+    public void initInDifferentThread() throws InterruptedException {
+        final PolyglotEngine.Builder b = PolyglotEngine.buildNew();
+        Thread t = new Thread("Initializer") {
+            @Override
+            public void run() {
+                tvm = b.build();
+            }
+        };
+        t.start();
+        t.join();
+    }
+
+    @SuppressWarnings("deprecation")
+    @Test(expected = IllegalStateException.class)
+    public void evalURI() throws IOException, URISyntaxException {
+        tvm.eval(new URI("http://unknown.js"));
+    }
+
+    @SuppressWarnings("deprecation")
+    @Test(expected = IllegalStateException.class)
+    public void evalString() throws IOException {
+        tvm.eval("text/javascript", "1 + 1");
+    }
+
+    @SuppressWarnings("deprecation")
+    @Test(expected = IllegalStateException.class)
+    public void evalReader() throws IOException {
+        try (StringReader sr = new StringReader("1 + 1")) {
+            tvm.eval("text/javascript", sr);
+        }
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void evalSource() throws IOException {
+        tvm.eval(Source.fromText("", "Empty"));
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void findGlobalSymbol() {
+        tvm.findGlobalSymbol("doesNotExists");
+    }
+}
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ExceptionDuringParsingTest.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ExceptionDuringParsingTest.java	Tue Sep 22 11:22:26 2015 +0200
@@ -25,7 +25,7 @@
 import com.oracle.truffle.api.impl.Accessor;
 import com.oracle.truffle.api.source.Source;
 import static com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.L1;
-import com.oracle.truffle.api.vm.TruffleVM;
+import com.oracle.truffle.api.vm.PolyglotEngine;
 import java.io.IOException;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
@@ -37,8 +37,8 @@
 
     @Test
     public void canGetAccessToOwnLanguageInstance() throws Exception {
-        TruffleVM vm = TruffleVM.newVM().build();
-        TruffleVM.Language language = vm.getLanguages().get(L1);
+        PolyglotEngine vm = PolyglotEngine.buildNew().build();
+        PolyglotEngine.Language language = vm.getLanguages().get(L1);
         assertNotNull("L1 language is defined", language);
 
         try {
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolTest.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/GlobalSymbolTest.java	Tue Sep 22 11:22:26 2015 +0200
@@ -24,7 +24,7 @@
 
 import com.oracle.truffle.api.source.Source;
 import static com.oracle.truffle.api.test.vm.ImplicitExplicitExportTest.L3;
-import com.oracle.truffle.api.vm.TruffleVM;
+import com.oracle.truffle.api.vm.PolyglotEngine;
 import java.io.IOException;
 import java.util.concurrent.Executors;
 import static org.junit.Assert.assertEquals;
@@ -34,7 +34,7 @@
 public class GlobalSymbolTest {
     @Test
     public void globalSymbolFoundByLanguage() throws IOException {
-        TruffleVM vm = TruffleVM.newVM().globalSymbol("ahoj", "42").executor(Executors.newSingleThreadExecutor()).build();
+        PolyglotEngine vm = PolyglotEngine.buildNew().globalSymbol("ahoj", "42").executor(Executors.newSingleThreadExecutor()).build();
         // @formatter:off
         Object ret = vm.eval(
             Source.fromText("return=ahoj", "Return").withMimeType(L3)
@@ -45,8 +45,8 @@
 
     @Test
     public void globalSymbolFoundByVMUser() throws IOException {
-        TruffleVM vm = TruffleVM.newVM().globalSymbol("ahoj", "42").build();
-        TruffleVM.Symbol ret = vm.findGlobalSymbol("ahoj");
+        PolyglotEngine vm = PolyglotEngine.buildNew().globalSymbol("ahoj", "42").build();
+        PolyglotEngine.Value ret = vm.findGlobalSymbol("ahoj");
         assertNotNull("Symbol found", ret);
         assertEquals("42", ret.get());
     }
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java	Tue Sep 22 11:22:26 2015 +0200
@@ -31,7 +31,7 @@
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.RootNode;
 import com.oracle.truffle.api.source.Source;
-import com.oracle.truffle.api.vm.TruffleVM;
+import com.oracle.truffle.api.vm.PolyglotEngine;
 import java.io.IOException;
 import java.io.Reader;
 import java.util.Enumeration;
@@ -48,12 +48,12 @@
 
 public class ImplicitExplicitExportTest {
     private static Thread mainThread;
-    private TruffleVM vm;
+    private PolyglotEngine vm;
 
     @Before
     public void initializeVM() {
         mainThread = Thread.currentThread();
-        vm = TruffleVM.newVM().executor(Executors.newSingleThreadExecutor()).build();
+        vm = PolyglotEngine.buildNew().executor(Executors.newSingleThreadExecutor()).build();
         assertTrue("Found " + L1 + " language", vm.getLanguages().containsKey(L1));
         assertTrue("Found " + L2 + " language", vm.getLanguages().containsKey(L2));
         assertTrue("Found " + L3 + " language", vm.getLanguages().containsKey(L3));
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/InitializationTest.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/InitializationTest.java	Tue Sep 22 11:22:26 2015 +0200
@@ -46,7 +46,7 @@
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.api.vm.EventConsumer;
-import com.oracle.truffle.api.vm.TruffleVM;
+import com.oracle.truffle.api.vm.PolyglotEngine;
 import java.io.IOException;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
@@ -68,7 +68,7 @@
     @Test
     public void accessProbeForAbstractLanguage() throws IOException {
         final Debugger[] arr = {null};
-        TruffleVM vm = TruffleVM.newVM().onEvent(new EventConsumer<ExecutionEvent>(ExecutionEvent.class) {
+        PolyglotEngine vm = PolyglotEngine.buildNew().onEvent(new EventConsumer<ExecutionEvent>(ExecutionEvent.class) {
             @Override
             protected void on(ExecutionEvent event) {
                 arr[0] = event.getDebugger();
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/TruffleVMSingleThreadedTest.java	Mon Sep 21 13:11:41 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2012, 2015, 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.api.test.vm;
-
-import com.oracle.truffle.api.source.Source;
-import com.oracle.truffle.api.vm.TruffleVM;
-import java.io.IOException;
-import java.io.StringReader;
-import java.net.URI;
-import java.net.URISyntaxException;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TruffleVMSingleThreadedTest {
-    TruffleVM tvm;
-
-    @Before
-    public void initInDifferentThread() throws InterruptedException {
-        final TruffleVM.Builder b = TruffleVM.newVM();
-        Thread t = new Thread("Initializer") {
-            @Override
-            public void run() {
-                tvm = b.build();
-            }
-        };
-        t.start();
-        t.join();
-    }
-
-    @SuppressWarnings("deprecation")
-    @Test(expected = IllegalStateException.class)
-    public void evalURI() throws IOException, URISyntaxException {
-        tvm.eval(new URI("http://unknown.js"));
-    }
-
-    @SuppressWarnings("deprecation")
-    @Test(expected = IllegalStateException.class)
-    public void evalString() throws IOException {
-        tvm.eval("text/javascript", "1 + 1");
-    }
-
-    @SuppressWarnings("deprecation")
-    @Test(expected = IllegalStateException.class)
-    public void evalReader() throws IOException {
-        try (StringReader sr = new StringReader("1 + 1")) {
-            tvm.eval("text/javascript", sr);
-        }
-    }
-
-    @Test(expected = IllegalStateException.class)
-    public void evalSource() throws IOException {
-        tvm.eval(Source.fromText("", "Empty"));
-    }
-
-    @Test(expected = IllegalStateException.class)
-    public void findGlobalSymbol() {
-        tvm.findGlobalSymbol("doesNotExists");
-    }
-}
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/EventConsumer.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/EventConsumer.java	Tue Sep 22 11:22:26 2015 +0200
@@ -29,9 +29,9 @@
 import com.oracle.truffle.api.debug.SuspendedEvent;
 
 /**
- * {@link TruffleVM} generates various events and delivers them to
- * {@link TruffleVM.Builder#onEvent(com.oracle.truffle.api.vm.EventConsumer) registered} handlers.
- * Each handler is registered for a particular type of event. Examples of events include
+ * {@link PolyglotEngine} generates various events and delivers them to
+ * {@link PolyglotEngine.Builder#onEvent(com.oracle.truffle.api.vm.EventConsumer) registered}
+ * handlers. Each handler is registered for a particular type of event. Examples of events include
  * {@link ExecutionEvent} or {@link SuspendedEvent} useful when debugging {@link TruffleLanguage
  * Truffle language}s.
  *
@@ -50,7 +50,7 @@
     }
 
     /**
-     * Called by the {@link TruffleVM} when event of requested type appears.
+     * Called by the {@link PolyglotEngine} when event of requested type appears.
      *
      * @param event the instance of an event of the request type
      */
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/JavaWrapper.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/JavaWrapper.java	Tue Sep 22 11:22:26 2015 +0200
@@ -29,17 +29,17 @@
 import java.lang.reflect.Proxy;
 
 final class JavaWrapper implements InvocationHandler {
-    private final TruffleVM.Symbol value;
+    private final PolyglotEngine.Value value;
     private final Object wrapper;
     private final InvocationHandler chain;
 
-    public JavaWrapper(TruffleVM.Symbol value, Object wrapper, InvocationHandler chain) {
+    public JavaWrapper(PolyglotEngine.Value value, Object wrapper, InvocationHandler chain) {
         this.value = value;
         this.chain = chain;
         this.wrapper = wrapper;
     }
 
-    static <T> T create(Class<T> representation, Object wrapper, TruffleVM.Symbol value) {
+    static <T> T create(Class<T> representation, Object wrapper, PolyglotEngine.Value value) {
         InvocationHandler chain = Proxy.getInvocationHandler(wrapper);
         Object instance = Proxy.newProxyInstance(representation.getClassLoader(), new Class<?>[]{representation}, new JavaWrapper(value, wrapper, chain));
         return representation.cast(instance);
@@ -50,7 +50,7 @@
         if (method.getDeclaringClass() == Object.class) {
             return method.invoke(this, args);
         }
-        TruffleVM.Symbol retValue = value.invokeProxy(chain, wrapper, method, args);
+        PolyglotEngine.Value retValue = value.invokeProxy(chain, wrapper, method, args);
         if (method.getReturnType() == void.class) {
             return null;
         } else {
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/LanguageCache.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/LanguageCache.java	Tue Sep 22 11:22:26 2015 +0200
@@ -25,7 +25,7 @@
 package com.oracle.truffle.api.vm;
 
 import com.oracle.truffle.api.TruffleLanguage;
-import static com.oracle.truffle.api.vm.TruffleVM.LOG;
+import static com.oracle.truffle.api.vm.PolyglotEngine.LOG;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
@@ -80,7 +80,7 @@
     }
 
     private static ClassLoader loader() {
-        ClassLoader l = TruffleVM.class.getClassLoader();
+        ClassLoader l = PolyglotEngine.class.getClassLoader();
         if (l == null) {
             l = ClassLoader.getSystemClassLoader();
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java	Tue Sep 22 11:22:26 2015 +0200
@@ -0,0 +1,954 @@
+/*
+ * Copyright (c) 2014, 2015, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.api.vm;
+
+import com.oracle.truffle.api.CallTarget;
+import com.oracle.truffle.api.TruffleLanguage;
+import com.oracle.truffle.api.TruffleLanguage.Env;
+import com.oracle.truffle.api.TruffleLanguage.Registration;
+import com.oracle.truffle.api.debug.DebugSupportProvider;
+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.impl.Accessor;
+import com.oracle.truffle.api.instrument.Probe;
+import com.oracle.truffle.api.instrument.ToolSupportProvider;
+import com.oracle.truffle.api.interop.TruffleObject;
+import com.oracle.truffle.api.interop.java.JavaInterop;
+import com.oracle.truffle.api.source.Source;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Gate way into the world of {@link TruffleLanguage Truffle languages}. {@link #buildNew()
+ * Instantiate} your own portal into the isolated, multi language system with all the registered
+ * languages ready for your use. A {@link PolyglotEngine} runs inside of a <em>JVM</em>, there can
+ * however be multiple instances (some would say tenants) of {@link PolyglotEngine} running next to
+ * each other in a single <em>JVM</em> with a complete mutual isolation. There is 1:N mapping
+ * between <em>JVM</em> and {@link PolyglotEngine}.
+ * <p>
+ * It would not be correct to think of a {@link PolyglotEngine} as a runtime for a single
+ * {@link TruffleLanguage Truffle language} (Ruby, Python, R, C, JavaScript, etc.) either.
+ * {@link PolyglotEngine} can host as many of Truffle languages as {@link Registration registered on
+ * a class path} of your <em>JVM</em> application. {@link PolyglotEngine} orchestrates these
+ * languages, manages exchange of objects and calls among them. While it may happen that there is
+ * just one activated language inside of a {@link PolyglotEngine}, the greatest strength of
+ * {@link PolyglotEngine} is in inter-operability between all Truffle languages. There is 1:N
+ * mapping between {@link PolyglotEngine} and {@link TruffleLanguage Truffle language
+ * implementations}.
+ * <p>
+ * Use {@link #buildNew()} to create new isolated portal ready for execution of various languages.
+ * All the languages in a single portal see each other exported global symbols and can cooperate.
+ * Use {@link #buildNew()} multiple times to create different, isolated portal environment
+ * completely separated from each other.
+ * <p>
+ * Once instantiated use {@link #eval(java.net.URI)} with a reference to a file or URL or directly
+ * pass code snippet into the virtual machine via {@link #eval(java.lang.String, java.lang.String)}.
+ * Support for individual languages is initialized on demand - e.g. once a file of certain MIME type
+ * is about to be processed, its appropriate engine (if found), is initialized. Once an engine gets
+ * initialized, it remains so, until the virtual machine isn't garbage collected.
+ * <p>
+ * The engine is single-threaded and tries to enforce that. It records the thread it has been
+ * {@link Builder#build() created} by and checks that all subsequent calls are coming from the same
+ * thread. There is 1:1 mapping between {@link PolyglotEngine} and a thread that can tell it what to
+ * do.
+ */
+@SuppressWarnings("rawtypes")
+public class PolyglotEngine {
+    static final Logger LOG = Logger.getLogger(PolyglotEngine.class.getName());
+    private static final SPIAccessor SPI = new SPIAccessor();
+    private final Thread initThread;
+    private final Executor executor;
+    private final Map<String, Language> langs;
+    private final InputStream in;
+    private final OutputStream err;
+    private final OutputStream out;
+    private final EventConsumer<?>[] handlers;
+    private final Map<String, Object> globals;
+    private Debugger debugger;
+
+    /**
+     * Private & temporary only constructor.
+     */
+    PolyglotEngine() {
+        this.initThread = null;
+        this.in = null;
+        this.err = null;
+        this.out = null;
+        this.langs = null;
+        this.handlers = null;
+        this.globals = null;
+        this.executor = null;
+    }
+
+    /**
+     * Real constructor used from the builder.
+     */
+    PolyglotEngine(Executor executor, Map<String, Object> globals, OutputStream out, OutputStream err, InputStream in, EventConsumer<?>[] handlers) {
+        this.executor = executor;
+        this.out = out;
+        this.err = err;
+        this.in = in;
+        this.handlers = handlers;
+        this.initThread = Thread.currentThread();
+        this.globals = new HashMap<>(globals);
+        Map<String, Language> map = new HashMap<>();
+        for (Map.Entry<String, LanguageCache> en : LanguageCache.languages().entrySet()) {
+            map.put(en.getKey(), createLanguage(en));
+        }
+        this.langs = map;
+    }
+
+    /**
+     * Creation of new Truffle virtual machine. Use the {@link Builder} methods to configure your
+     * virtual machine and then create one using {@link Builder#build()}:
+     *
+     * <pre>
+     * {@link PolyglotEngine} vm = {@link PolyglotEngine}.{@link PolyglotEngine#buildNew() buildNew()}
+     *     .{@link Builder#setOut(java.io.OutputStream) setOut}({@link OutputStream yourOutput})
+     *     .{@link Builder#setErr(java.io.OutputStream) setrr}({@link OutputStream yourOutput})
+     *     .{@link Builder#setIn(java.io.InputStream) setIn}({@link InputStream yourInput})
+     *     .{@link Builder#build() build()};
+     * </pre>
+     *
+     * It searches for {@link Registration languages registered} in the system class loader and
+     * makes them available for later evaluation via
+     * {@link #eval(java.lang.String, java.lang.String)} methods.
+     *
+     * @return new, isolated virtual machine with pre-registered languages
+     */
+    public static PolyglotEngine.Builder buildNew() {
+        // making Builder non-static inner class is a
+        // nasty trick to avoid the Builder class to appear
+        // in Javadoc next to PolyglotEngine class
+        PolyglotEngine vm = new PolyglotEngine();
+        return vm.new Builder();
+    }
+
+    /**
+     * Builder for a new {@link PolyglotEngine}. Call various configuration methods in a chain and
+     * at the end create new {@link PolyglotEngine virtual machine}:
+     *
+     * <pre>
+     * {@link PolyglotEngine} vm = {@link PolyglotEngine}.{@link PolyglotEngine#buildNew() buildNew()}
+     *     .{@link Builder#setOut(java.io.OutputStream) setOut}({@link OutputStream yourOutput})
+     *     .{@link Builder#setErr(java.io.OutputStream) setrr}({@link OutputStream yourOutput})
+     *     .{@link Builder#setIn(java.io.InputStream) setIn}({@link InputStream yourInput})
+     *     .{@link Builder#build() build()};
+     * </pre>
+     */
+    public class Builder {
+        private OutputStream out;
+        private OutputStream err;
+        private InputStream in;
+        private final List<EventConsumer<?>> handlers = new ArrayList<>();
+        private final Map<String, Object> globals = new HashMap<>();
+        private Executor executor;
+
+        Builder() {
+        }
+
+        /**
+         * Changes the default output for languages running in <em>to be created</em>
+         * {@link PolyglotEngine virtual machine}. The default is to use {@link System#out}.
+         *
+         * @param os the stream to use as output
+         * @return instance of this builder
+         */
+        public Builder setOut(OutputStream os) {
+            out = os;
+            return this;
+        }
+
+        /**
+         * @deprecated does nothing
+         */
+        @Deprecated
+        @SuppressWarnings("unused")
+        public Builder stdOut(Writer w) {
+            return this;
+        }
+
+        /**
+         * Changes the error output for languages running in <em>to be created</em>
+         * {@link PolyglotEngine virtual machine}. The default is to use {@link System#err}.
+         *
+         * @param os the stream to use as output
+         * @return instance of this builder
+         */
+        public Builder setErr(OutputStream os) {
+            err = os;
+            return this;
+        }
+
+        /**
+         * @deprecated does nothing
+         */
+        @Deprecated
+        @SuppressWarnings("unused")
+        public Builder stdErr(Writer w) {
+            return this;
+        }
+
+        /**
+         * Changes the default input for languages running in <em>to be created</em>
+         * {@link PolyglotEngine virtual machine}. The default is to use {@link System#in}.
+         *
+         * @param is the stream to use as input
+         * @return instance of this builder
+         */
+        public Builder setIn(InputStream is) {
+            in = is;
+            return this;
+        }
+
+        /**
+         * @deprecated does nothing
+         */
+        @Deprecated
+        @SuppressWarnings("unused")
+        public Builder stdIn(Reader r) {
+            return this;
+        }
+
+        /**
+         * Registers another instance of {@link EventConsumer} into the to be created
+         * {@link PolyglotEngine}.
+         *
+         * @param handler the handler to register
+         * @return instance of this builder
+         */
+        public Builder onEvent(EventConsumer<?> handler) {
+            handler.getClass();
+            handlers.add(handler);
+            return this;
+        }
+
+        /**
+         * Adds global named symbol into the configuration of to-be-built {@link PolyglotEngine}.
+         * This symbol will be accessible to all languages via
+         * {@link Env#importSymbol(java.lang.String)} and will take precedence over
+         * {@link TruffleLanguage#findExportedSymbol symbols exported by languages itself}. Repeated
+         * use of <code>globalSymbol</code> is possible; later definition of the same name overrides
+         * the previous one.
+         *
+         * @param name name of the symbol to register
+         * @param obj value of the object - expected to be primitive wrapper, {@link String} or
+         *            <code>TruffleObject</code> for mutual inter-operability
+         * @return instance of this builder
+         * @see PolyglotEngine#findGlobalSymbol(java.lang.String)
+         */
+        public Builder globalSymbol(String name, Object obj) {
+            globals.put(name, obj);
+            return this;
+        }
+
+        /**
+         * Provides own executor for running {@link PolyglotEngine} scripts. By default
+         * {@link PolyglotEngine#eval(com.oracle.truffle.api.source.Source)} and
+         * {@link Value#invoke(java.lang.Object, java.lang.Object[])} are executed synchronously in
+         * the calling thread. Sometimes, however it is more beneficial to run them asynchronously -
+         * the easiest way to do so is to provide own executor when configuring the {
+         * {@link #executor(java.util.concurrent.Executor) the builder}. The executor is expected to
+         * execute all {@link Runnable runnables} passed into its
+         * {@link Executor#execute(java.lang.Runnable)} method in the order they arrive and in a
+         * single (yet arbitrary) thread.
+         *
+         * @param executor the executor to use for internal execution inside the {@link #build() to
+         *            be created} {@link PolyglotEngine}
+         * @return instance of this builder
+         */
+        @SuppressWarnings("hiding")
+        public Builder executor(Executor executor) {
+            this.executor = executor;
+            return this;
+        }
+
+        /**
+         * Creates the {@link PolyglotEngine Truffle virtual machine}. The configuration is taken
+         * from values passed into configuration methods in this class.
+         *
+         * @return new, isolated virtual machine with pre-registered languages
+         */
+        @SuppressWarnings("deprecation")
+        public PolyglotEngine build() {
+            if (out == null) {
+                out = System.out;
+            }
+            if (err == null) {
+                err = System.err;
+            }
+            if (in == null) {
+                in = System.in;
+            }
+            Executor nonNullExecutor = executor != null ? executor : new Executor() {
+                @Override
+                public void execute(Runnable command) {
+                    command.run();
+                }
+            };
+            return new TruffleVM(nonNullExecutor, globals, out, err, in, handlers.toArray(new EventConsumer[0]));
+        }
+    }
+
+    /**
+     * Descriptions of languages supported in this Truffle virtual machine.
+     *
+     * @return an immutable map with keys being MIME types and values the {@link Language
+     *         descriptions} of associated languages
+     */
+    public Map<String, ? extends Language> getLanguages() {
+        return Collections.unmodifiableMap(langs);
+    }
+
+    /**
+     * Evaluates file located on a given URL. Is equivalent to loading the content of a file and
+     * executing it via {@link #eval(java.lang.String, java.lang.String)} with a MIME type guess
+     * based on the file's extension and/or content.
+     *
+     * @param location the location of a file to execute
+     * @return result of a processing the file, possibly <code>null</code>
+     * @throws IOException exception to signal I/O problems or problems with processing the file's
+     *             content
+     * @deprecated use {@link #eval(com.oracle.truffle.api.source.Source)}
+     */
+    @Deprecated
+    public Object eval(URI location) throws IOException {
+        checkThread();
+        Source s;
+        String mimeType;
+        if (location.getScheme().equals("file")) {
+            File file = new File(location);
+            s = Source.fromFileName(file.getPath(), true);
+            if (file.getName().endsWith(".c")) {
+                mimeType = "text/x-c";
+            } else if (file.getName().endsWith(".sl")) {
+                mimeType = "application/x-sl";
+            } else if (file.getName().endsWith(".R") || file.getName().endsWith(".r")) {
+                mimeType = "application/x-r";
+            } else {
+                mimeType = Files.probeContentType(file.toPath());
+            }
+        } else {
+            URL url = location.toURL();
+            s = Source.fromURL(url, location.toString());
+            URLConnection conn = url.openConnection();
+            mimeType = conn.getContentType();
+        }
+        Language l = langs.get(mimeType);
+        if (l == null) {
+            throw new IOException("No language for " + location + " with MIME type " + mimeType + " found. Supported types: " + langs.keySet());
+        }
+        return eval(l, s).get();
+    }
+
+    /**
+     * Evaluates code snippet. Chooses a language registered for a given MIME type (throws
+     * {@link IOException} if there is none). And passes the specified code to it for execution.
+     *
+     * @param mimeType MIME type of the code snippet - chooses the right language
+     * @param reader the source of code snippet to execute
+     * @return result of an execution, possibly <code>null</code>
+     * @throws IOException thrown to signal errors while processing the code
+     * @deprecated use {@link #eval(com.oracle.truffle.api.source.Source)}
+     */
+    @Deprecated
+    public Object eval(String mimeType, Reader reader) throws IOException {
+        checkThread();
+        Language l = langs.get(mimeType);
+        if (l == null) {
+            throw new IOException("No language for MIME type " + mimeType + " found. Supported types: " + langs.keySet());
+        }
+        return eval(l, Source.fromReader(reader, mimeType)).get();
+    }
+
+    /**
+     * Evaluates code snippet. Chooses a language registered for a given MIME type (throws
+     * {@link IOException} if there is none). And passes the specified code to it for execution.
+     *
+     * @param mimeType MIME type of the code snippet - chooses the right language
+     * @param code the code snippet to execute
+     * @return result of an execution, possibly <code>null</code>
+     * @throws IOException thrown to signal errors while processing the code
+     * @deprecated use {@link #eval(com.oracle.truffle.api.source.Source)}
+     */
+    @Deprecated
+    public Object eval(String mimeType, String code) throws IOException {
+        checkThread();
+        Language l = langs.get(mimeType);
+        if (l == null) {
+            throw new IOException("No language for MIME type " + mimeType + " found. Supported types: " + langs.keySet());
+        }
+        return eval(l, Source.fromText(code, mimeType)).get();
+    }
+
+    /**
+     * Evaluates provided source. Chooses language registered for a particular
+     * {@link Source#getMimeType() MIME type} (throws {@link IOException} if there is none). The
+     * language is then allowed to parse and execute the source.
+     *
+     * @param source code snippet to execute
+     * @return a {@link Value} object that holds result of an execution, never <code>null</code>
+     * @throws IOException thrown to signal errors while processing the code
+     */
+    public Value eval(Source source) throws IOException {
+        String mimeType = source.getMimeType();
+        checkThread();
+        Language l = langs.get(mimeType);
+        if (l == null) {
+            throw new IOException("No language for MIME type " + mimeType + " found. Supported types: " + langs.keySet());
+        }
+        return eval(l, source);
+    }
+
+    private Value eval(final Language l, final Source s) throws IOException {
+        final Debugger[] fillIn = {debugger};
+        final Object[] result = {null, null};
+        final CountDownLatch ready = new CountDownLatch(1);
+        final TruffleLanguage[] lang = {null};
+        executor.execute(new Runnable() {
+            @Override
+            public void run() {
+                evalImpl(fillIn, lang, s, result, l, ready);
+            }
+        });
+        exceptionCheck(result);
+        return createValue(lang[0], result, ready);
+    }
+
+    Value createValue(TruffleLanguage lang, Object[] result, CountDownLatch ready) {
+        return new Value(lang, result, ready);
+    }
+
+    Language createLanguage(Map.Entry<String, LanguageCache> en) {
+        return new Language(en.getValue());
+    }
+
+    @SuppressWarnings("try")
+    private void evalImpl(Debugger[] fillIn, TruffleLanguage<?>[] fillLang, Source s, Object[] result, Language l, CountDownLatch ready) {
+        try (Closeable d = SPI.executionStart(this, fillIn, s)) {
+            TruffleLanguage<?> langImpl = l.getImpl(true);
+            fillLang[0] = langImpl;
+            PolyglotEngine.findDebuggerSupport(langImpl);
+            if (debugger == null) {
+                debugger = fillIn[0];
+            }
+            result[0] = SPI.eval(langImpl, s);
+        } catch (IOException ex) {
+            result[1] = ex;
+        } finally {
+            ready.countDown();
+        }
+    }
+
+    /**
+     * Looks global symbol provided by one of initialized languages up. First of all execute your
+     * program via one of your {@link #eval(java.lang.String, java.lang.String)} and then look
+     * expected symbol up using this method.
+     * <p>
+     * The names of the symbols are language dependent, but for example the Java language bindings
+     * follow the specification for method references:
+     * <ul>
+     * <li>"java.lang.Exception::new" is a reference to constructor of {@link Exception}
+     * <li>"java.lang.Integer::valueOf" is a reference to static method in {@link Integer} class
+     * </ul>
+     * Once an symbol is obtained, it remembers values for fast access and is ready for being
+     * invoked.
+     *
+     * @param globalName the name of the symbol to find
+     * @return found symbol or <code>null</code> if it has not been found
+     */
+    public Value findGlobalSymbol(final String globalName) {
+        checkThread();
+        final TruffleLanguage<?>[] lang = {null};
+        final Object[] obj = {globals.get(globalName), null};
+        final CountDownLatch ready = new CountDownLatch(1);
+        if (obj[0] == null) {
+            executor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    findGlobalSymbolImpl(obj, globalName, lang, ready);
+                }
+            });
+            try {
+                ready.await();
+            } catch (InterruptedException ex) {
+                LOG.log(Level.SEVERE, null, ex);
+            }
+        } else {
+            ready.countDown();
+        }
+        return obj[0] == null ? null : createValue(lang[0], obj, ready);
+    }
+
+    private void findGlobalSymbolImpl(Object[] obj, String globalName, TruffleLanguage<?>[] lang, CountDownLatch ready) {
+        if (obj[0] == null) {
+            for (Language dl : langs.values()) {
+                TruffleLanguage.Env env = dl.getEnv(false);
+                if (env == null) {
+                    continue;
+                }
+                obj[0] = SPI.findExportedSymbol(env, globalName, true);
+                if (obj[0] != null) {
+                    lang[0] = dl.getImpl(true);
+                    break;
+                }
+            }
+        }
+        if (obj[0] == null) {
+            for (Language dl : langs.values()) {
+                TruffleLanguage.Env env = dl.getEnv(false);
+                if (env == null) {
+                    continue;
+                }
+                obj[0] = SPI.findExportedSymbol(env, globalName, true);
+                if (obj[0] != null) {
+                    lang[0] = dl.getImpl(true);
+                    break;
+                }
+            }
+        }
+        ready.countDown();
+    }
+
+    private void checkThread() {
+        if (initThread != Thread.currentThread()) {
+            throw new IllegalStateException("PolyglotEngine created on " + initThread.getName() + " but used on " + Thread.currentThread().getName());
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    void dispatch(Object ev) {
+        Class type = ev.getClass();
+        if (type == SuspendedEvent.class) {
+            dispatchSuspendedEvent((SuspendedEvent) ev);
+        }
+        if (type == ExecutionEvent.class) {
+            dispatchExecutionEvent((ExecutionEvent) ev);
+        }
+        dispatch(type, ev);
+    }
+
+    @SuppressWarnings("unused")
+    void dispatchSuspendedEvent(SuspendedEvent event) {
+    }
+
+    @SuppressWarnings("unused")
+    void dispatchExecutionEvent(ExecutionEvent event) {
+    }
+
+    @SuppressWarnings("unchecked")
+    <Event> void dispatch(Class<Event> type, Event event) {
+        for (EventConsumer handler : handlers) {
+            if (handler.type == type) {
+                handler.on(event);
+            }
+        }
+    }
+
+    static void exceptionCheck(Object[] result) throws RuntimeException, IOException {
+        if (result[1] instanceof IOException) {
+            throw (IOException) result[1];
+        }
+        if (result[1] instanceof RuntimeException) {
+            throw (RuntimeException) result[1];
+        }
+    }
+
+    /**
+     * A future value wrapper. A user level wrapper around values returned by evaluation of various
+     * {@link PolyglotEngine} functions like
+     * {@link PolyglotEngine#findGlobalSymbol(java.lang.String)} and
+     * {@link PolyglotEngine#eval(com.oracle.truffle.api.source.Source)} or value returned by
+     * {@link #invoke(java.lang.Object, java.lang.Object...) sbbsequent of execution}. In case the
+     * {@link PolyglotEngine} has been initialized for
+     * {@link Builder#executor(java.util.concurrent.Executor) asynchronous excution}, the
+     * {@link Value} represents a future - e.g. it is returned immediately, leaving the execution
+     * running on behind.
+     */
+    public class Value {
+        private final TruffleLanguage<?> language;
+        private final Object[] result;
+        private final CountDownLatch ready;
+        private CallTarget target;
+
+        Value(TruffleLanguage<?> language, Object[] result, CountDownLatch ready) {
+            this.language = language;
+            this.result = result;
+            this.ready = ready;
+        }
+
+        /**
+         * Obtains the object represented by this symbol. The <em>raw</em> object can either be a
+         * wrapper about primitive type (e.g. {@link Number}, {@link String}, {@link Character},
+         * {@link Boolean}) or a <em>TruffleObject</em> representing more complex object from a
+         * language. The method can return <code>null</code>.
+         *
+         * @return the object or <code>null</code>
+         * @throws IOException in case it is not possible to obtain the value of the object
+         */
+        public Object get() throws IOException {
+            waitForSymbol();
+            exceptionCheck(result);
+            return result[0];
+        }
+
+        /**
+         * Obtains Java view of the object represented by this symbol. The method basically
+         * delegates to
+         * {@link JavaInterop#asJavaObject(java.lang.Class, com.oracle.truffle.api.interop.TruffleObject)}
+         * just handles primitive types as well.
+         * 
+         * @param <T> the type of the view one wants to obtain
+         * @param representation the class of the view interface (it has to be an interface)
+         * @return instance of the view wrapping the object of this symbol
+         * @throws IOException in case it is not possible to obtain the value of the object
+         * @throws ClassCastException if the value cannot be converted to desired view
+         */
+        public <T> T as(Class<T> representation) throws IOException {
+            Object obj = get();
+            if (representation.isInstance(obj)) {
+                return representation.cast(obj);
+            }
+            T wrapper = JavaInterop.asJavaObject(representation, (TruffleObject) obj);
+            return JavaWrapper.create(representation, wrapper, this);
+        }
+
+        /**
+         * Invokes the symbol. If the symbol represents a function, then it should be invoked with
+         * provided arguments. If the symbol represents a field, then first argument (if provided)
+         * should set the value to the field; the return value should be the actual value of the
+         * field when the <code>invoke</code> method returns.
+         *
+         * @param thiz this/self in language that support such concept; use <code>null</code> to let
+         *            the language use default this/self or ignore the value
+         * @param args arguments to pass when invoking the symbol
+         * @return symbol wrapper around the value returned by invoking the symbol, never
+         *         <code>null</code>
+         * @throws IOException signals problem during execution
+         */
+        public Value invoke(final Object thiz, final Object... args) throws IOException {
+            get();
+            final Debugger[] fillIn = {debugger};
+            final CountDownLatch done = new CountDownLatch(1);
+            final Object[] res = {null, null};
+            executor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    invokeImpl(fillIn, thiz, args, res, done);
+                }
+            });
+            exceptionCheck(res);
+            return createValue(language, res, done);
+        }
+
+        @SuppressWarnings("try")
+        final Value invokeProxy(final InvocationHandler chain, final Object wrapper, final Method method, final Object[] args) throws IOException {
+            final Debugger[] fillIn = {debugger};
+            final CountDownLatch done = new CountDownLatch(1);
+            final Object[] res = {null, null};
+            executor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    try (final Closeable c = SPI.executionStart(PolyglotEngine.this, fillIn, null)) {
+                        if (debugger == null) {
+                            debugger = fillIn[0];
+                        }
+                        res[0] = chain.invoke(wrapper, method, args);
+                    } catch (IOException ex) {
+                        res[1] = ex;
+                    } catch (Throwable ex) {
+                        res[1] = ex;
+                    } finally {
+                        done.countDown();
+                    }
+                }
+            });
+            exceptionCheck(res);
+            return new Value(language, res, done);
+        }
+
+        @SuppressWarnings("try")
+        private void invokeImpl(Debugger[] fillIn, Object thiz, Object[] args, Object[] res, CountDownLatch done) {
+            try (final Closeable c = SPI.executionStart(PolyglotEngine.this, fillIn, null)) {
+                if (debugger == null) {
+                    debugger = fillIn[0];
+                }
+                List<Object> arr = new ArrayList<>();
+                if (thiz == null && language != null) {
+                    Object global = SPI.languageGlobal(SPI.findLanguage(PolyglotEngine.this, language.getClass()));
+                    if (global != null) {
+                        arr.add(global);
+                    }
+                } else {
+                    arr.add(thiz);
+                }
+                arr.addAll(Arrays.asList(args));
+                for (;;) {
+                    try {
+                        if (target == null) {
+                            target = SymbolInvokerImpl.createCallTarget(language, result[0], arr.toArray());
+                        }
+                        res[0] = target.call(arr.toArray());
+                        break;
+                    } catch (ArgumentsMishmashException ex) {
+                        target = null;
+                    }
+                }
+            } catch (IOException ex) {
+                res[1] = ex;
+            } catch (RuntimeException ex) {
+                res[1] = ex;
+            } finally {
+                done.countDown();
+            }
+        }
+
+        private void waitForSymbol() throws InterruptedIOException {
+            checkThread();
+            try {
+                ready.await();
+            } catch (InterruptedException ex) {
+                throw (InterruptedIOException) new InterruptedIOException(ex.getMessage()).initCause(ex);
+            }
+        }
+    }
+
+    /**
+     * Description of a language registered in {@link PolyglotEngine Truffle virtual machine}.
+     * Languages are registered by {@link Registration} annotation which stores necessary
+     * information into a descriptor inside of the language's JAR file. When a new
+     * {@link PolyglotEngine} is created, it reads all available descriptors and creates
+     * {@link Language} objects to represent them. One can obtain a {@link #getName() name} or list
+     * of supported {@link #getMimeTypes() MIME types} for each language. The actual language
+     * implementation is not initialized until
+     * {@link PolyglotEngine#eval(java.lang.String, java.lang.String) a code is evaluated} in it.
+     */
+    public class Language {
+        private final LanguageCache info;
+        private TruffleLanguage.Env env;
+
+        Language(LanguageCache info) {
+            this.info = info;
+        }
+
+        /**
+         * MIME types recognized by the language.
+         *
+         * @return returns immutable set of recognized MIME types
+         */
+        public Set<String> getMimeTypes() {
+            return info.getMimeTypes();
+        }
+
+        /**
+         * Human readable name of the language. Think of C, Ruby, JS, etc.
+         *
+         * @return string giving the language a name
+         */
+        public String getName() {
+            return info.getName();
+        }
+
+        /**
+         * Name of the language version.
+         *
+         * @return string specifying the language version
+         */
+        public String getVersion() {
+            return info.getVersion();
+        }
+
+        /**
+         * Human readable string that identifies the language and version.
+         *
+         * @return string describing the specific language version
+         */
+        public String getShortName() {
+            return getName() + "(" + getVersion() + ")";
+        }
+
+        TruffleLanguage<?> getImpl(boolean create) {
+            getEnv(create);
+            return info.getImpl(false);
+        }
+
+        TruffleLanguage.Env getEnv(boolean create) {
+            if (env == null && create) {
+                env = SPI.attachEnv(PolyglotEngine.this, info.getImpl(true), out, err, in);
+            }
+            return env;
+        }
+
+        @Override
+        public String toString() {
+            return "[" + getShortName() + " for " + getMimeTypes() + "]";
+        }
+    } // end of Language
+
+    //
+    // Accessor helper methods
+    //
+
+    TruffleLanguage<?> findLanguage(Probe probe) {
+        Class<? extends TruffleLanguage> languageClazz = SPI.findLanguage(probe);
+        for (Map.Entry<String, Language> entrySet : langs.entrySet()) {
+            Language languageDescription = entrySet.getValue();
+            final TruffleLanguage<?> impl = languageDescription.getImpl(false);
+            if (languageClazz.isInstance(impl)) {
+                return impl;
+            }
+        }
+        throw new IllegalStateException("Cannot find language " + languageClazz + " among " + langs);
+    }
+
+    Env findEnv(Class<? extends TruffleLanguage> languageClazz) {
+        for (Map.Entry<String, Language> entrySet : langs.entrySet()) {
+            Language languageDescription = entrySet.getValue();
+            Env env = languageDescription.getEnv(false);
+            if (env != null && languageClazz.isInstance(languageDescription.getImpl(false))) {
+                return env;
+            }
+        }
+        throw new IllegalStateException("Cannot find language " + languageClazz + " among " + langs);
+    }
+
+    static DebugSupportProvider findDebuggerSupport(TruffleLanguage<?> l) {
+        return SPI.getDebugSupport(l);
+    }
+
+    private static class SPIAccessor extends Accessor {
+        @Override
+        public Object importSymbol(Object vmObj, TruffleLanguage<?> ownLang, String globalName) {
+            PolyglotEngine vm = (PolyglotEngine) vmObj;
+            Object g = vm.globals.get(globalName);
+            if (g != null) {
+                return g;
+            }
+            Set<Language> uniqueLang = new LinkedHashSet<>(vm.langs.values());
+            for (Language dl : uniqueLang) {
+                TruffleLanguage<?> l = dl.getImpl(false);
+                TruffleLanguage.Env env = dl.getEnv(false);
+                if (l == ownLang || l == null || env == null) {
+                    continue;
+                }
+                Object obj = SPI.findExportedSymbol(env, globalName, true);
+                if (obj != null) {
+                    return obj;
+                }
+            }
+            for (Language dl : uniqueLang) {
+                TruffleLanguage<?> l = dl.getImpl(false);
+                TruffleLanguage.Env env = dl.getEnv(false);
+                if (l == ownLang || l == null || env == null) {
+                    continue;
+                }
+                Object obj = SPI.findExportedSymbol(env, globalName, false);
+                if (obj != null) {
+                    return obj;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        protected Env attachEnv(Object obj, TruffleLanguage<?> language, OutputStream stdOut, OutputStream stdErr, InputStream stdIn) {
+            PolyglotEngine vm = (PolyglotEngine) obj;
+            return super.attachEnv(vm, language, stdOut, stdErr, stdIn);
+        }
+
+        @Override
+        public Object eval(TruffleLanguage<?> l, Source s) throws IOException {
+            return super.eval(l, s);
+        }
+
+        @Override
+        public Object findExportedSymbol(TruffleLanguage.Env env, String globalName, boolean onlyExplicit) {
+            return super.findExportedSymbol(env, globalName, onlyExplicit);
+        }
+
+        @Override
+        protected Object languageGlobal(TruffleLanguage.Env env) {
+            return super.languageGlobal(env);
+        }
+
+        @Override
+        public ToolSupportProvider getToolSupport(TruffleLanguage<?> l) {
+            return super.getToolSupport(l);
+        }
+
+        @Override
+        public DebugSupportProvider getDebugSupport(TruffleLanguage<?> l) {
+            return super.getDebugSupport(l);
+        }
+
+        @Override
+        protected Class<? extends TruffleLanguage> findLanguage(Probe probe) {
+            return super.findLanguage(probe);
+        }
+
+        @Override
+        protected Env findLanguage(Object obj, Class<? extends TruffleLanguage> languageClass) {
+            PolyglotEngine vm = (PolyglotEngine) obj;
+            return vm.findEnv(languageClass);
+        }
+
+        @Override
+        protected Closeable executionStart(Object obj, Debugger[] fillIn, Source s) {
+            PolyglotEngine vm = (PolyglotEngine) obj;
+            return super.executionStart(vm, fillIn, s);
+        }
+
+        @Override
+        protected void dispatchEvent(Object obj, Object event) {
+            PolyglotEngine vm = (PolyglotEngine) obj;
+            vm.dispatch(event);
+        }
+    } // end of SPIAccessor
+}
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/TruffleVM.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/TruffleVM.java	Tue Sep 22 11:22:26 2015 +0200
@@ -24,143 +24,37 @@
  */
 package com.oracle.truffle.api.vm;
 
-import com.oracle.truffle.api.CallTarget;
 import com.oracle.truffle.api.TruffleLanguage;
-import com.oracle.truffle.api.TruffleLanguage.Env;
-import com.oracle.truffle.api.TruffleLanguage.Registration;
-import com.oracle.truffle.api.debug.DebugSupportProvider;
-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.impl.Accessor;
-import com.oracle.truffle.api.instrument.Probe;
-import com.oracle.truffle.api.instrument.ToolSupportProvider;
-import com.oracle.truffle.api.interop.TruffleObject;
-import com.oracle.truffle.api.interop.java.JavaInterop;
 import com.oracle.truffle.api.source.Source;
-import java.io.Closeable;
-import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InterruptedIOException;
 import java.io.OutputStream;
 import java.io.Reader;
 import java.io.Writer;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.net.URI;
-import java.net.URL;
-import java.net.URLConnection;
-import java.nio.file.Files;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 /**
- * <em>Virtual machine</em> for Truffle based languages. Term virtual machine is a bit overloaded,
- * so don't think of <em>Java virtual machine</em> here - while we are running and using
- * {@link TruffleVM} inside of a <em>JVM</em> there can be multiple instances (some would say
- * tenants) of {@link TruffleVM} running next to each other in a single <em>JVM</em> with a complete
- * mutual isolation. There is 1:N mapping between <em>JVM</em> and {@link TruffleVM}.
- * <p>
- * It would not be correct to think of a {@link TruffleVM} as a runtime for a single Truffle
- * language (Ruby, Python, R, C, JavaScript, etc.) either. {@link TruffleVM} can host as many of
- * Truffle languages as {@link Registration registered on a class path} of your <em>JVM</em>
- * application. {@link TruffleVM} orchestrates these languages, manages exchange of objects and
- * calls among them. While it may happen that there is just one activated language inside of a
- * {@link TruffleVM}, the greatest strength of {@link TruffleVM} is in interoperability between all
- * Truffle languages. There is 1:N mapping between {@link TruffleVM} and {@link TruffleLanguage
- * Truffle language implementations}.
- * <p>
- * Use {@link #newVM()} to create new isolated virtual machine ready for execution of various
- * languages. All the languages in a single virtual machine see each other exported global symbols
- * and can cooperate. Use {@link #newVM()} multiple times to create different, isolated virtual
- * machines completely separated from each other.
- * <p>
- * Once instantiated use {@link #eval(java.net.URI)} with a reference to a file or URL or directly
- * pass code snippet into the virtual machine via {@link #eval(java.lang.String, java.lang.String)}.
- * Support for individual languages is initialized on demand - e.g. once a file of certain MIME type
- * is about to be processed, its appropriate engine (if found), is initialized. Once an engine gets
- * initialized, it remains so, until the virtual machine isn't garbage collected.
- * <p>
- * The <code>TruffleVM</code> is single-threaded and tries to enforce that. It records the thread it
- * has been {@link Builder#build() created} by and checks that all subsequent calls are coming from
- * the same thread. There is 1:1 mapping between {@link TruffleVM} and a thread that can tell it
- * what to do.
+ * @deprecated
  */
-@SuppressWarnings("rawtypes")
-public final class TruffleVM {
-    static final Logger LOG = Logger.getLogger(TruffleVM.class.getName());
-    private static final SPIAccessor SPI = new SPIAccessor();
-    private final Thread initThread;
-    private final Executor executor;
-    private final Map<String, Language> langs;
-    private final InputStream in;
-    private final OutputStream err;
-    private final OutputStream out;
-    private final EventConsumer<?>[] handlers;
-    private final Map<String, Object> globals;
-    private Debugger debugger;
-
-    /**
-     * Private & temporary only constructor.
-     */
+@Deprecated
+@SuppressWarnings({"rawtypes", "deprecated"})
+public final class TruffleVM extends PolyglotEngine {
     private TruffleVM() {
-        this.initThread = null;
-        this.in = null;
-        this.err = null;
-        this.out = null;
-        this.langs = null;
-        this.handlers = null;
-        this.globals = null;
-        this.executor = null;
+        super();
     }
 
     /**
      * Real constructor used from the builder.
      */
-    private TruffleVM(Executor executor, Map<String, Object> globals, OutputStream out, OutputStream err, InputStream in, EventConsumer<?>[] handlers) {
-        this.executor = executor;
-        this.out = out;
-        this.err = err;
-        this.in = in;
-        this.handlers = handlers;
-        this.initThread = Thread.currentThread();
-        this.globals = new HashMap<>(globals);
-        Map<String, Language> map = new HashMap<>();
-        for (Map.Entry<String, LanguageCache> en : LanguageCache.languages().entrySet()) {
-            map.put(en.getKey(), new Language(en.getValue()));
-        }
-        this.langs = map;
+    TruffleVM(Executor executor, Map<String, Object> globals, OutputStream out, OutputStream err, InputStream in, EventConsumer<?>[] handlers) {
+        super(executor, globals, out, err, in, handlers);
     }
 
-    /**
-     * Creation of new Truffle virtual machine. Use the {@link Builder} methods to configure your
-     * virtual machine and then create one using {@link Builder#build()}:
-     *
-     * <pre>
-     * {@link TruffleVM} vm = {@link TruffleVM}.{@link TruffleVM#newVM() newVM()}
-     *     .{@link Builder#setOut(java.io.OutputStream) setOut}({@link OutputStream yourOutput})
-     *     .{@link Builder#setErr(java.io.OutputStream) setrr}({@link OutputStream yourOutput})
-     *     .{@link Builder#setIn(java.io.InputStream) setIn}({@link InputStream yourInput})
-     *     .{@link Builder#build() build()};
-     * </pre>
-     *
-     * It searches for {@link Registration languages registered} in the system class loader and
-     * makes them available for later evaluation via
-     * {@link #eval(java.lang.String, java.lang.String)} methods.
-     *
-     * @return new, isolated virtual machine with pre-registered languages
-     */
+    @Deprecated
     public static TruffleVM.Builder newVM() {
         // making Builder non-static inner class is a
         // nasty trick to avoid the Builder class to appear
@@ -169,766 +63,126 @@
         return vm.new Builder();
     }
 
-    /**
-     * Builder for a new {@link TruffleVM}. Call various configuration methods in a chain and at the
-     * end create new {@link TruffleVM virtual machine}:
-     *
-     * <pre>
-     * {@link TruffleVM} vm = {@link TruffleVM}.{@link TruffleVM#newVM() newVM()}
-     *     .{@link Builder#setOut(java.io.OutputStream) setOut}({@link OutputStream yourOutput})
-     *     .{@link Builder#setErr(java.io.OutputStream) setrr}({@link OutputStream yourOutput})
-     *     .{@link Builder#setIn(java.io.InputStream) setIn}({@link InputStream yourInput})
-     *     .{@link Builder#build() build()};
-     * </pre>
-     */
-    public final class Builder {
-        private OutputStream out;
-        private OutputStream err;
-        private InputStream in;
-        private final List<EventConsumer<?>> handlers = new ArrayList<>();
-        private final Map<String, Object> globals = new HashMap<>();
-        private Executor executor;
-
+    @SuppressWarnings("deprecation")
+    @Deprecated
+    public final class Builder extends PolyglotEngine.Builder {
         Builder() {
         }
 
-        /**
-         * Changes the default output for languages running in <em>to be created</em>
-         * {@link TruffleVM virtual machine}. The default is to use {@link System#out}.
-         *
-         * @param os the stream to use as output
-         * @return instance of this builder
-         */
+        @Deprecated
+        @Override
         public Builder setOut(OutputStream os) {
-            out = os;
-            return this;
-        }
-
-        /**
-         * @deprecated does nothing
-         */
-        @Deprecated
-        @SuppressWarnings("unused")
-        public Builder stdOut(Writer w) {
-            return this;
-        }
-
-        /**
-         * Changes the error output for languages running in <em>to be created</em>
-         * {@link TruffleVM virtual machine}. The default is to use {@link System#err}.
-         *
-         * @param os the stream to use as output
-         * @return instance of this builder
-         */
-        public Builder setErr(OutputStream os) {
-            err = os;
-            return this;
-        }
-
-        /**
-         * @deprecated does nothing
-         */
-        @Deprecated
-        @SuppressWarnings("unused")
-        public Builder stdErr(Writer w) {
+            super.setOut(os);
             return this;
         }
 
-        /**
-         * Changes the default input for languages running in <em>to be created</em>
-         * {@link TruffleVM virtual machine}. The default is to use {@link System#in}.
-         *
-         * @param is the stream to use as input
-         * @return instance of this builder
-         */
-        public Builder setIn(InputStream is) {
-            in = is;
-            return this;
-        }
-
-        /**
-         * @deprecated does nothing
-         */
         @Deprecated
-        @SuppressWarnings("unused")
-        public Builder stdIn(Reader r) {
-            return this;
-        }
-
-        /**
-         * Registers another instance of {@link EventConsumer} into the to be created
-         * {@link TruffleVM}.
-         *
-         * @param handler the handler to register
-         * @return instance of this builder
-         */
-        public Builder onEvent(EventConsumer<?> handler) {
-            handler.getClass();
-            handlers.add(handler);
-            return this;
+        @Override
+        public Builder executor(Executor executor) {
+            return (Builder) super.executor(executor);
         }
 
-        /**
-         * Adds global named symbol into the configuration of to-be-built {@link TruffleVM}. This
-         * symbol will be accessible to all languages via {@link Env#importSymbol(java.lang.String)}
-         * and will take precedence over {@link TruffleLanguage#findExportedSymbol symbols exported
-         * by languages itself}. Repeated use of <code>globalSymbol</code> is possible; later
-         * definition of the same name overrides the previous one.
-         *
-         * @param name name of the symbol to register
-         * @param obj value of the object - expected to be primitive wrapper, {@link String} or
-         *            <code>TruffleObject</code> for mutual inter-operability
-         * @return instance of this builder
-         * @see TruffleVM#findGlobalSymbol(java.lang.String)
-         */
-        public Builder globalSymbol(String name, Object obj) {
-            globals.put(name, obj);
-            return this;
-        }
-
-        /**
-         * Provides own executor for running {@link TruffleVM} scripts. By default
-         * {@link TruffleVM#eval(com.oracle.truffle.api.source.Source)} and
-         * {@link Symbol#invoke(java.lang.Object, java.lang.Object...)} are executed synchronously
-         * in the calling thread. Sometimes, however it is more beneficial to run them
-         * asynchronously - the easiest way to do so is to provide own executor when configuring the
-         * { {@link #executor(java.util.concurrent.Executor) the builder}. The executor is expected
-         * to execute all {@link Runnable runnables} passed into its
-         * {@link Executor#execute(java.lang.Runnable)} method in the order they arrive and in a
-         * single (yet arbitrary) thread.
-         *
-         * @param executor the executor to use for internal execution inside the {@link #build() to
-         *            be created} {@link TruffleVM}
-         * @return instance of this builder
-         */
-        @SuppressWarnings("hiding")
-        public Builder executor(Executor executor) {
-            this.executor = executor;
+        @Deprecated
+        @Override
+        public Builder setErr(OutputStream os) {
+            super.setErr(os);
             return this;
         }
 
-        /**
-         * Creates the {@link TruffleVM Truffle virtual machine}. The configuration is taken from
-         * values passed into configuration methods in this class.
-         *
-         * @return new, isolated virtual machine with pre-registered languages
-         */
-        public TruffleVM build() {
-            if (out == null) {
-                out = System.out;
-            }
-            if (err == null) {
-                err = System.err;
-            }
-            if (in == null) {
-                in = System.in;
-            }
-            Executor nonNullExecutor = executor != null ? executor : new Executor() {
-                @Override
-                public void execute(Runnable command) {
-                    command.run();
-                }
-            };
-            return new TruffleVM(nonNullExecutor, globals, out, err, in, handlers.toArray(new EventConsumer[0]));
+        @Deprecated
+        @Override
+        public Builder globalSymbol(String name, Object obj) {
+            return (Builder) super.globalSymbol(name, obj);
         }
-    }
-
-    /**
-     * Descriptions of languages supported in this Truffle virtual machine.
-     *
-     * @return an immutable map with keys being MIME types and values the {@link Language
-     *         descriptions} of associated languages
-     */
-    public Map<String, Language> getLanguages() {
-        return Collections.unmodifiableMap(langs);
-    }
 
-    /**
-     * Evaluates file located on a given URL. Is equivalent to loading the content of a file and
-     * executing it via {@link #eval(java.lang.String, java.lang.String)} with a MIME type guess
-     * based on the file's extension and/or content.
-     *
-     * @param location the location of a file to execute
-     * @return result of a processing the file, possibly <code>null</code>
-     * @throws IOException exception to signal I/O problems or problems with processing the file's
-     *             content
-     * @deprecated use {@link #eval(com.oracle.truffle.api.source.Source)}
-     */
-    @Deprecated
-    public Object eval(URI location) throws IOException {
-        checkThread();
-        Source s;
-        String mimeType;
-        if (location.getScheme().equals("file")) {
-            File file = new File(location);
-            s = Source.fromFileName(file.getPath(), true);
-            if (file.getName().endsWith(".c")) {
-                mimeType = "text/x-c";
-            } else if (file.getName().endsWith(".sl")) {
-                mimeType = "application/x-sl";
-            } else if (file.getName().endsWith(".R") || file.getName().endsWith(".r")) {
-                mimeType = "application/x-r";
-            } else {
-                mimeType = Files.probeContentType(file.toPath());
-            }
-        } else {
-            URL url = location.toURL();
-            s = Source.fromURL(url, location.toString());
-            URLConnection conn = url.openConnection();
-            mimeType = conn.getContentType();
-        }
-        Language l = langs.get(mimeType);
-        if (l == null) {
-            throw new IOException("No language for " + location + " with MIME type " + mimeType + " found. Supported types: " + langs.keySet());
+        @Deprecated
+        @Override
+        public Builder setIn(InputStream is) {
+            super.setIn(is);
+            return this;
         }
-        return eval(l, s).get();
-    }
 
-    /**
-     * Evaluates code snippet. Chooses a language registered for a given MIME type (throws
-     * {@link IOException} if there is none). And passes the specified code to it for execution.
-     *
-     * @param mimeType MIME type of the code snippet - chooses the right language
-     * @param reader the source of code snippet to execute
-     * @return result of an execution, possibly <code>null</code>
-     * @throws IOException thrown to signal errors while processing the code
-     * @deprecated use {@link #eval(com.oracle.truffle.api.source.Source)}
-     */
-    @Deprecated
-    public Object eval(String mimeType, Reader reader) throws IOException {
-        checkThread();
-        Language l = langs.get(mimeType);
-        if (l == null) {
-            throw new IOException("No language for MIME type " + mimeType + " found. Supported types: " + langs.keySet());
+        @Deprecated
+        @Override
+        public Builder onEvent(EventConsumer<?> handler) {
+            return (Builder) super.onEvent(handler);
         }
-        return eval(l, Source.fromReader(reader, mimeType)).get();
-    }
-
-    /**
-     * Evaluates code snippet. Chooses a language registered for a given MIME type (throws
-     * {@link IOException} if there is none). And passes the specified code to it for execution.
-     *
-     * @param mimeType MIME type of the code snippet - chooses the right language
-     * @param code the code snippet to execute
-     * @return result of an execution, possibly <code>null</code>
-     * @throws IOException thrown to signal errors while processing the code
-     * @deprecated use {@link #eval(com.oracle.truffle.api.source.Source)}
-     */
-    @Deprecated
-    public Object eval(String mimeType, String code) throws IOException {
-        checkThread();
-        Language l = langs.get(mimeType);
-        if (l == null) {
-            throw new IOException("No language for MIME type " + mimeType + " found. Supported types: " + langs.keySet());
-        }
-        return eval(l, Source.fromText(code, mimeType)).get();
-    }
 
-    /**
-     * Evaluates provided source. Chooses language registered for a particular
-     * {@link Source#getMimeType() MIME type} (throws {@link IOException} if there is none). The
-     * language is then allowed to parse and execute the source.
-     *
-     * @param source code snippet to execute
-     * @return a {@link Symbol} object that holds result of an execution, never <code>null</code>
-     * @throws IOException thrown to signal errors while processing the code
-     */
-    public Symbol eval(Source source) throws IOException {
-        String mimeType = source.getMimeType();
-        checkThread();
-        Language l = langs.get(mimeType);
-        if (l == null) {
-            throw new IOException("No language for MIME type " + mimeType + " found. Supported types: " + langs.keySet());
+        @Deprecated
+        @Override
+        public Builder stdIn(Reader r) {
+            return (Builder) super.stdIn(r);
         }
-        return eval(l, source);
-    }
-
-    private Symbol eval(final Language l, final Source s) throws IOException {
-        final Debugger[] fillIn = {debugger};
-        final Object[] result = {null, null};
-        final CountDownLatch ready = new CountDownLatch(1);
-        final TruffleLanguage[] lang = {null};
-        executor.execute(new Runnable() {
-            @Override
-            public void run() {
-                evalImpl(fillIn, lang, s, result, l, ready);
-            }
-        });
-        exceptionCheck(result);
-        return new Symbol(lang[0], result, ready);
-    }
-
-    @SuppressWarnings("try")
-    private void evalImpl(Debugger[] fillIn, TruffleLanguage<?>[] fillLang, Source s, Object[] result, Language l, CountDownLatch ready) {
-        try (Closeable d = SPI.executionStart(this, fillIn, s)) {
-            TruffleLanguage<?> langImpl = l.getImpl(true);
-            fillLang[0] = langImpl;
-            TruffleVM.findDebuggerSupport(langImpl);
-            if (debugger == null) {
-                debugger = fillIn[0];
-            }
-            result[0] = SPI.eval(langImpl, s);
-        } catch (IOException ex) {
-            result[1] = ex;
-        } finally {
-            ready.countDown();
-        }
-    }
 
-    /**
-     * Looks global symbol provided by one of initialized languages up. First of all execute your
-     * program via one of your {@link #eval(java.lang.String, java.lang.String)} and then look
-     * expected symbol up using this method.
-     * <p>
-     * The names of the symbols are language dependent, but for example the Java language bindings
-     * follow the specification for method references:
-     * <ul>
-     * <li>"java.lang.Exception::new" is a reference to constructor of {@link Exception}
-     * <li>"java.lang.Integer::valueOf" is a reference to static method in {@link Integer} class
-     * </ul>
-     * Once an symbol is obtained, it remembers values for fast access and is ready for being
-     * invoked.
-     *
-     * @param globalName the name of the symbol to find
-     * @return found symbol or <code>null</code> if it has not been found
-     */
-    public Symbol findGlobalSymbol(final String globalName) {
-        checkThread();
-        final TruffleLanguage<?>[] lang = {null};
-        final Object[] obj = {globals.get(globalName), null};
-        final CountDownLatch ready = new CountDownLatch(1);
-        if (obj[0] == null) {
-            executor.execute(new Runnable() {
-                @Override
-                public void run() {
-                    findGlobalSymbolImpl(obj, globalName, lang, ready);
-                }
-            });
-            try {
-                ready.await();
-            } catch (InterruptedException ex) {
-                LOG.log(Level.SEVERE, null, ex);
-            }
-        } else {
-            ready.countDown();
+        @Deprecated
+        @Override
+        public Builder stdErr(Writer w) {
+            return (Builder) super.stdErr(w);
         }
-        return obj[0] == null ? null : new Symbol(lang[0], obj, ready);
-    }
 
-    private void findGlobalSymbolImpl(Object[] obj, String globalName, TruffleLanguage<?>[] lang, CountDownLatch ready) {
-        if (obj[0] == null) {
-            for (Language dl : langs.values()) {
-                TruffleLanguage.Env env = dl.getEnv(false);
-                if (env == null) {
-                    continue;
-                }
-                obj[0] = SPI.findExportedSymbol(env, globalName, true);
-                if (obj[0] != null) {
-                    lang[0] = dl.getImpl(true);
-                    break;
-                }
-            }
+        @Deprecated
+        @Override
+        public Builder stdOut(Writer w) {
+            return (Builder) super.stdOut(w);
         }
-        if (obj[0] == null) {
-            for (Language dl : langs.values()) {
-                TruffleLanguage.Env env = dl.getEnv(false);
-                if (env == null) {
-                    continue;
-                }
-                obj[0] = SPI.findExportedSymbol(env, globalName, true);
-                if (obj[0] != null) {
-                    lang[0] = dl.getImpl(true);
-                    break;
-                }
-            }
-        }
-        ready.countDown();
-    }
 
-    private void checkThread() {
-        if (initThread != Thread.currentThread()) {
-            throw new IllegalStateException("TruffleVM created on " + initThread.getName() + " but used on " + Thread.currentThread().getName());
+        @Deprecated
+        @Override
+        public TruffleVM build() {
+            return (TruffleVM) super.build();
         }
     }
 
-    @SuppressWarnings("unchecked")
-    void dispatch(Object ev) {
-        Class type = ev.getClass();
-        if (type == SuspendedEvent.class) {
-            dispatchSuspendedEvent((SuspendedEvent) ev);
-        }
-        if (type == ExecutionEvent.class) {
-            dispatchExecutionEvent((ExecutionEvent) ev);
-        }
-        dispatch(type, ev);
+    @Override
+    Value createValue(TruffleLanguage lang, Object[] result, CountDownLatch ready) {
+        return new Symbol(lang, result, ready);
+    }
+
+    @Override
+    Language createLanguage(Map.Entry<String, LanguageCache> en) {
+        return new Language(en.getValue());
     }
 
-    @SuppressWarnings("unused")
+    @Override
+    @SuppressWarnings("unchecked")
+    public Map<String, Language> getLanguages() {
+        return (Map<String, Language>) super.getLanguages();
+    }
+
+    @Override
+    public Symbol eval(Source source) throws IOException {
+        return (Symbol) super.eval(source);
+    }
+
+    @Override
+    public Symbol findGlobalSymbol(final String globalName) {
+        return (Symbol) super.findGlobalSymbol(globalName);
+    }
+
+    @Override
     void dispatchSuspendedEvent(SuspendedEvent event) {
     }
 
-    @SuppressWarnings("unused")
+    @Override
     void dispatchExecutionEvent(ExecutionEvent event) {
     }
 
-    @SuppressWarnings("unchecked")
-    <Event> void dispatch(Class<Event> type, Event event) {
-        for (EventConsumer handler : handlers) {
-            if (handler.type == type) {
-                handler.on(event);
-            }
-        }
-    }
-
-    static void exceptionCheck(Object[] result) throws RuntimeException, IOException {
-        if (result[1] instanceof IOException) {
-            throw (IOException) result[1];
-        }
-        if (result[1] instanceof RuntimeException) {
-            throw (RuntimeException) result[1];
-        }
-    }
-
-    /**
-     * Represents {@link TruffleVM#findGlobalSymbol(java.lang.String) global symbol} provided by one
-     * of the initialized languages in {@link TruffleVM Truffle virtual machine}.
-     */
-    public class Symbol {
-        private final TruffleLanguage<?> language;
-        private final Object[] result;
-        private final CountDownLatch ready;
-        private CallTarget target;
-
+    @Deprecated
+    public class Symbol extends Value {
         Symbol(TruffleLanguage<?> language, Object[] result, CountDownLatch ready) {
-            this.language = language;
-            this.result = result;
-            this.ready = ready;
-        }
-
-        /**
-         * Obtains the object represented by this symbol. The <em>raw</em> object can either be a
-         * wrapper about primitive type (e.g. {@link Number}, {@link String}, {@link Character},
-         * {@link Boolean}) or a <em>TruffleObject</em> representing more complex object from a
-         * language. The method can return <code>null</code>.
-         *
-         * @return the object or <code>null</code>
-         * @throws IOException in case it is not possible to obtain the value of the object
-         */
-        public Object get() throws IOException {
-            waitForSymbol();
-            exceptionCheck(result);
-            return result[0];
-        }
-
-        /**
-         * Obtains Java view of the object represented by this symbol. The method basically
-         * delegates to
-         * {@link JavaInterop#asJavaObject(java.lang.Class, com.oracle.truffle.api.interop.TruffleObject)}
-         * just handles primitive types as well.
-         * 
-         * @param <T> the type of the view one wants to obtain
-         * @param representation the class of the view interface (it has to be an interface)
-         * @return instance of the view wrapping the object of this symbol
-         * @throws IOException in case it is not possible to obtain the value of the object
-         * @throws ClassCastException if the value cannot be converted to desired view
-         */
-        public <T> T as(Class<T> representation) throws IOException {
-            Object obj = get();
-            if (representation.isInstance(obj)) {
-                return representation.cast(obj);
-            }
-            T wrapper = JavaInterop.asJavaObject(representation, (TruffleObject) obj);
-            return JavaWrapper.create(representation, wrapper, this);
+            super(language, result, ready);
         }
 
-        /**
-         * Invokes the symbol. If the symbol represents a function, then it should be invoked with
-         * provided arguments. If the symbol represents a field, then first argument (if provided)
-         * should set the value to the field; the return value should be the actual value of the
-         * field when the <code>invoke</code> method returns.
-         *
-         * @param thiz this/self in language that support such concept; use <code>null</code> to let
-         *            the language use default this/self or ignore the value
-         * @param args arguments to pass when invoking the symbol
-         * @return symbol wrapper around the value returned by invoking the symbol, never
-         *         <code>null</code>
-         * @throws IOException signals problem during execution
-         */
+        @Override
         public Symbol invoke(final Object thiz, final Object... args) throws IOException {
-            get();
-            final Debugger[] fillIn = {debugger};
-            final CountDownLatch done = new CountDownLatch(1);
-            final Object[] res = {null, null};
-            executor.execute(new Runnable() {
-                @Override
-                public void run() {
-                    invokeImpl(fillIn, thiz, args, res, done);
-                }
-            });
-            exceptionCheck(res);
-            return new Symbol(language, res, done);
-        }
-
-        @SuppressWarnings("try")
-        final Symbol invokeProxy(final InvocationHandler chain, final Object wrapper, final Method method, final Object[] args) throws IOException {
-            final Debugger[] fillIn = {debugger};
-            final CountDownLatch done = new CountDownLatch(1);
-            final Object[] res = {null, null};
-            executor.execute(new Runnable() {
-                @Override
-                public void run() {
-                    try (final Closeable c = SPI.executionStart(TruffleVM.this, fillIn, null)) {
-                        if (debugger == null) {
-                            debugger = fillIn[0];
-                        }
-                        res[0] = chain.invoke(wrapper, method, args);
-                    } catch (IOException ex) {
-                        res[1] = ex;
-                    } catch (Throwable ex) {
-                        res[1] = ex;
-                    } finally {
-                        done.countDown();
-                    }
-                }
-            });
-            exceptionCheck(res);
-            return new Symbol(language, res, done);
-        }
-
-        @SuppressWarnings("try")
-        private void invokeImpl(Debugger[] fillIn, Object thiz, Object[] args, Object[] res, CountDownLatch done) {
-            try (final Closeable c = SPI.executionStart(TruffleVM.this, fillIn, null)) {
-                if (debugger == null) {
-                    debugger = fillIn[0];
-                }
-                List<Object> arr = new ArrayList<>();
-                if (thiz == null && language != null) {
-                    Object global = SPI.languageGlobal(SPI.findLanguage(TruffleVM.this, language.getClass()));
-                    if (global != null) {
-                        arr.add(global);
-                    }
-                } else {
-                    arr.add(thiz);
-                }
-                arr.addAll(Arrays.asList(args));
-                for (;;) {
-                    try {
-                        if (target == null) {
-                            target = SymbolInvokerImpl.createCallTarget(language, result[0], arr.toArray());
-                        }
-                        res[0] = target.call(arr.toArray());
-                        break;
-                    } catch (ArgumentsMishmashException ex) {
-                        target = null;
-                    }
-                }
-            } catch (IOException ex) {
-                res[1] = ex;
-            } catch (RuntimeException ex) {
-                res[1] = ex;
-            } finally {
-                done.countDown();
-            }
-        }
-
-        private void waitForSymbol() throws InterruptedIOException {
-            checkThread();
-            try {
-                ready.await();
-            } catch (InterruptedException ex) {
-                throw (InterruptedIOException) new InterruptedIOException(ex.getMessage()).initCause(ex);
-            }
+            return (Symbol) super.invoke(thiz, args);
         }
     }
 
-    /**
-     * Description of a language registered in {@link TruffleVM Truffle virtual machine}. Languages
-     * are registered by {@link Registration} annotation which stores necessary information into a
-     * descriptor inside of the language's JAR file. When a new {@link TruffleVM} is created, it
-     * reads all available descriptors and creates {@link Language} objects to represent them. One
-     * can obtain a {@link #getName() name} or list of supported {@link #getMimeTypes() MIME types}
-     * for each language. The actual language implementation is not initialized until
-     * {@link TruffleVM#eval(java.lang.String, java.lang.String) a code is evaluated} in it.
-     */
-    public final class Language {
-        private final LanguageCache info;
-        private TruffleLanguage.Env env;
-
+    @Deprecated
+    public final class Language extends PolyglotEngine.Language {
         Language(LanguageCache info) {
-            this.info = info;
-        }
-
-        /**
-         * MIME types recognized by the language.
-         *
-         * @return returns immutable set of recognized MIME types
-         */
-        public Set<String> getMimeTypes() {
-            return info.getMimeTypes();
-        }
-
-        /**
-         * Human readable name of the language. Think of C, Ruby, JS, etc.
-         *
-         * @return string giving the language a name
-         */
-        public String getName() {
-            return info.getName();
-        }
-
-        /**
-         * Name of the language version.
-         *
-         * @return string specifying the language version
-         */
-        public String getVersion() {
-            return info.getVersion();
-        }
-
-        /**
-         * Human readable string that identifies the language and version.
-         *
-         * @return string describing the specific language version
-         */
-        public String getShortName() {
-            return getName() + "(" + getVersion() + ")";
-        }
-
-        TruffleLanguage<?> getImpl(boolean create) {
-            getEnv(create);
-            return info.getImpl(false);
-        }
-
-        TruffleLanguage.Env getEnv(boolean create) {
-            if (env == null && create) {
-                env = SPI.attachEnv(TruffleVM.this, info.getImpl(true), out, err, in);
-            }
-            return env;
-        }
-
-        @Override
-        public String toString() {
-            return "[" + getShortName() + " for " + getMimeTypes() + "]";
+            super(info);
         }
     } // end of Language
-
-    //
-    // Accessor helper methods
-    //
-
-    TruffleLanguage<?> findLanguage(Probe probe) {
-        Class<? extends TruffleLanguage> languageClazz = SPI.findLanguage(probe);
-        for (Map.Entry<String, Language> entrySet : langs.entrySet()) {
-            Language languageDescription = entrySet.getValue();
-            final TruffleLanguage<?> impl = languageDescription.getImpl(false);
-            if (languageClazz.isInstance(impl)) {
-                return impl;
-            }
-        }
-        throw new IllegalStateException("Cannot find language " + languageClazz + " among " + langs);
-    }
-
-    Env findEnv(Class<? extends TruffleLanguage> languageClazz) {
-        for (Map.Entry<String, Language> entrySet : langs.entrySet()) {
-            Language languageDescription = entrySet.getValue();
-            Env env = languageDescription.getEnv(false);
-            if (env != null && languageClazz.isInstance(languageDescription.getImpl(false))) {
-                return env;
-            }
-        }
-        throw new IllegalStateException("Cannot find language " + languageClazz + " among " + langs);
-    }
-
-    static DebugSupportProvider findDebuggerSupport(TruffleLanguage<?> l) {
-        return SPI.getDebugSupport(l);
-    }
-
-    private static class SPIAccessor extends Accessor {
-        @Override
-        public Object importSymbol(Object vmObj, TruffleLanguage<?> ownLang, String globalName) {
-            TruffleVM vm = (TruffleVM) vmObj;
-            Object g = vm.globals.get(globalName);
-            if (g != null) {
-                return g;
-            }
-            Set<Language> uniqueLang = new LinkedHashSet<>(vm.langs.values());
-            for (Language dl : uniqueLang) {
-                TruffleLanguage<?> l = dl.getImpl(false);
-                TruffleLanguage.Env env = dl.getEnv(false);
-                if (l == ownLang || l == null || env == null) {
-                    continue;
-                }
-                Object obj = SPI.findExportedSymbol(env, globalName, true);
-                if (obj != null) {
-                    return obj;
-                }
-            }
-            for (Language dl : uniqueLang) {
-                TruffleLanguage<?> l = dl.getImpl(false);
-                TruffleLanguage.Env env = dl.getEnv(false);
-                if (l == ownLang || l == null || env == null) {
-                    continue;
-                }
-                Object obj = SPI.findExportedSymbol(env, globalName, false);
-                if (obj != null) {
-                    return obj;
-                }
-            }
-            return null;
-        }
-
-        @Override
-        protected Env attachEnv(Object obj, TruffleLanguage<?> language, OutputStream stdOut, OutputStream stdErr, InputStream stdIn) {
-            TruffleVM vm = (TruffleVM) obj;
-            return super.attachEnv(vm, language, stdOut, stdErr, stdIn);
-        }
-
-        @Override
-        public Object eval(TruffleLanguage<?> l, Source s) throws IOException {
-            return super.eval(l, s);
-        }
-
-        @Override
-        public Object findExportedSymbol(TruffleLanguage.Env env, String globalName, boolean onlyExplicit) {
-            return super.findExportedSymbol(env, globalName, onlyExplicit);
-        }
-
-        @Override
-        protected Object languageGlobal(TruffleLanguage.Env env) {
-            return super.languageGlobal(env);
-        }
-
-        @Override
-        public ToolSupportProvider getToolSupport(TruffleLanguage<?> l) {
-            return super.getToolSupport(l);
-        }
-
-        @Override
-        public DebugSupportProvider getDebugSupport(TruffleLanguage<?> l) {
-            return super.getDebugSupport(l);
-        }
-
-        @Override
-        protected Class<? extends TruffleLanguage> findLanguage(Probe probe) {
-            return super.findLanguage(probe);
-        }
-
-        @Override
-        protected Env findLanguage(Object obj, Class<? extends TruffleLanguage> languageClass) {
-            TruffleVM vm = (TruffleVM) obj;
-            return vm.findEnv(languageClass);
-        }
-
-        @Override
-        protected Closeable executionStart(Object obj, Debugger[] fillIn, Source s) {
-            TruffleVM vm = (TruffleVM) obj;
-            return super.executionStart(vm, fillIn, s);
-        }
-
-        @Override
-        protected void dispatchEvent(Object obj, Object event) {
-            TruffleVM vm = (TruffleVM) obj;
-            vm.dispatch(event);
-        }
-    } // end of SPIAccessor
 }
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/package-info.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/package-info.java	Tue Sep 22 11:22:26 2015 +0200
@@ -30,8 +30,8 @@
  */
 
 /**
- * Central place to create and control {@link com.oracle.truffle.api.vm.TruffleVM Truffle Virtual
- * Machine} and all languages hosted in it.
+ * Central place to create and control {@link com.oracle.truffle.api.vm.PolyglotEngine polyglot
+ * execution engine} and all languages hosted in it.
  */
 package com.oracle.truffle.api.vm;
 
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java	Tue Sep 22 11:22:26 2015 +0200
@@ -48,10 +48,10 @@
 /**
  * An entry point for everyone who wants to implement a Truffle based language. By providing an
  * implementation of this type and registering it using {@link Registration} annotation, your
- * language becomes accessible to users of the {@link com.oracle.truffle.api.vm.TruffleVM Truffle
- * virtual machine} - all they will need to do is to include your JAR into their application and all
- * the Truffle goodies (multi-language support, multitenant hosting, debugging, etc.) will be made
- * available to them.
+ * language becomes accessible to users of the {@link com.oracle.truffle.api.vm.PolyglotEngine
+ * polyglot execution engine} - all they will need to do is to include your JAR into their
+ * application and all the Truffle goodies (multi-language support, multitenant hosting, debugging,
+ * etc.) will be made available to them.
  *
  * @param <C> internal state of the language associated with every thread that is executing program
  *            {@link #parse(com.oracle.truffle.api.source.Source, com.oracle.truffle.api.nodes.Node, java.lang.String...)
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Breakpoint.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Breakpoint.java	Tue Sep 22 11:22:26 2015 +0200
@@ -30,7 +30,7 @@
 import java.io.IOException;
 
 /**
- * Breakpoint in a {@link com.oracle.truffle.api.vm.TruffleVM} with
+ * Breakpoint in a {@link com.oracle.truffle.api.vm.PolyglotEngine} with
  * {@link com.oracle.truffle.api.debug debugging turned on}. You can ask
  * {@link Debugger#setLineBreakpoint(int, com.oracle.truffle.api.source.LineLocation, boolean)} or
  * {@link Debugger#setTagBreakpoint(int, com.oracle.truffle.api.instrument.SyntaxTag, boolean)} to
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java	Tue Sep 22 11:22:26 2015 +0200
@@ -51,8 +51,8 @@
 import java.util.List;
 
 /**
- * Represents debugging related state of a {@link com.oracle.truffle.api.vm.TruffleVM}. Instance of
- * this class is delivered via {@link SuspendedEvent#getDebugger()} and
+ * Represents debugging related state of a {@link com.oracle.truffle.api.vm.PolyglotEngine}.
+ * Instance of this class is delivered via {@link SuspendedEvent#getDebugger()} and
  * {@link ExecutionEvent#getDebugger()} events, once {@link com.oracle.truffle.api.debug debugging
  * is turned on}.
  */
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/ExecutionEvent.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/ExecutionEvent.java	Tue Sep 22 11:22:26 2015 +0200
@@ -26,7 +26,7 @@
 
 /**
  * This event is delivered to all
- * {@link com.oracle.truffle.api.vm.TruffleVM.Builder#onEvent(com.oracle.truffle.api.vm.EventConsumer)
+ * {@link com.oracle.truffle.api.vm.PolyglotEngine.Builder#onEvent(com.oracle.truffle.api.vm.EventConsumer)
  * registered event handlers} when an execution is about to be started. The event is the intended
  * place to initialize debugger - e.g. set
  * {@link Debugger#setLineBreakpoint(int, com.oracle.truffle.api.source.LineLocation, boolean)
@@ -35,7 +35,7 @@
  * the state of the event becomes invalid and subsequent calls to the event methods yield
  * {@link IllegalStateException}. One can however obtain reference to {@link Debugger} instance and
  * keep it to further manipulate with debugging capabilities of the
- * {@link com.oracle.truffle.api.vm.TruffleVM} when it is running.
+ * {@link com.oracle.truffle.api.vm.PolyglotEngine} when it is running.
  */
 @SuppressWarnings("javadoc")
 public final class ExecutionEvent {
@@ -48,10 +48,10 @@
     /**
      * Debugger associated with the execution. This debugger remains valid after the event is
      * processed, it is possible and suggested to keep a reference to it and use it any time later
-     * when evaluating sources in the {@link com.oracle.truffle.api.vm.TruffleVM}.
+     * when evaluating sources in the {@link com.oracle.truffle.api.vm.PolyglotEngine}.
      *
      * @return instance of debugger associated with the just starting execution and any subsequent
-     *         ones in the same {@link com.oracle.truffle.api.vm.TruffleVM}.
+     *         ones in the same {@link com.oracle.truffle.api.vm.PolyglotEngine}.
      */
     public Debugger getDebugger() {
         return debugger;
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java	Tue Sep 22 11:22:26 2015 +0200
@@ -37,7 +37,7 @@
 
 /**
  * This event is delivered to all
- * {@link com.oracle.truffle.api.vm.TruffleVM.Builder#onEvent(com.oracle.truffle.api.vm.EventConsumer)
+ * {@link com.oracle.truffle.api.vm.PolyglotEngine.Builder#onEvent(com.oracle.truffle.api.vm.EventConsumer)
  * registered event handlers} when an execution is suspended on a
  * {@link Debugger#setLineBreakpoint(int, com.oracle.truffle.api.source.LineLocation, boolean)
  * breakpoint} or during {@link #prepareStepInto(int) stepping}. Methods in this event can only be
@@ -82,10 +82,10 @@
     /**
      * Debugger associated with the just suspended execution. This debugger remains valid after the
      * event is processed, it is possible and suggested to keep a reference to it and use it any
-     * time later when evaluating sources in the {@link com.oracle.truffle.api.vm.TruffleVM}.
+     * time later when evaluating sources in the {@link com.oracle.truffle.api.vm.PolyglotEngine}.
      *
      * @return instance of debugger associated with the just suspended execution and any subsequent
-     *         ones in the same {@link com.oracle.truffle.api.vm.TruffleVM}.
+     *         ones in the same {@link com.oracle.truffle.api.vm.PolyglotEngine}.
      */
     public Debugger getDebugger() {
         return debugger;
@@ -104,8 +104,8 @@
     }
 
     /**
-     * Gets the stack frames from the currently halted {@link com.oracle.truffle.api.vm.TruffleVM}
-     * execution.
+     * Gets the stack frames from the currently halted
+     * {@link com.oracle.truffle.api.vm.PolyglotEngine} execution.
      *
      * @return list of stack frames
      */
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/package-info.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/package-info.java	Tue Sep 22 11:22:26 2015 +0200
@@ -30,28 +30,28 @@
  */
 
 /**
- * Control over {@link com.oracle.truffle.api.debug.Debugger debugging} of your {@link com.oracle.truffle.api.vm.TruffleVM}. Each {@link com.oracle.truffle.api.vm.TruffleVM}
+ * Control over {@link com.oracle.truffle.api.debug.Debugger debugging} of your {@link com.oracle.truffle.api.vm.PolyglotEngine}. Each {@link com.oracle.truffle.api.vm.PolyglotEngine}
  * is inherently capable to run in debugging mode - there is just one thing
- * to do - the {@link com.oracle.truffle.api.vm.TruffleVM.Builder creator of the virtual machine}
- * needs to turn debugging on when constructing its Truffle virtual machine:
+ * to do - the {@link com.oracle.truffle.api.vm.PolyglotEngine.Builder creator of the virtual machine}
+ * needs to turn debugging on when constructing its polyglot execution engine:
  * <pre>
- * vm = {@link com.oracle.truffle.api.vm.TruffleVM#newVM()}.
- *     {@link com.oracle.truffle.api.vm.TruffleVM.Builder#onEvent(com.oracle.truffle.api.vm.EventConsumer) onEvent}(<b>new</b> {@link com.oracle.truffle.api.vm.EventConsumer EventConsumer}
+ * vm = {@link com.oracle.truffle.api.vm.PolyglotEngine#buildNew()}.
+ *     {@link com.oracle.truffle.api.vm.PolyglotEngine.Builder#onEvent(com.oracle.truffle.api.vm.EventConsumer) onEvent}(<b>new</b> {@link com.oracle.truffle.api.vm.EventConsumer EventConsumer}
  *     {@code <}{@link com.oracle.truffle.api.debug.ExecutionEvent}{@code >}() {
  *         <b>public void</b> handle({@link com.oracle.truffle.api.debug.ExecutionEvent} ev) {
- *             <em>// configure the virtual machine as {@link com.oracle.truffle.api.vm.TruffleVM#eval(com.oracle.truffle.api.source.Source) new execution} is starting</em>
+ *             <em>// configure the virtual machine as {@link com.oracle.truffle.api.vm.PolyglotEngine#eval(com.oracle.truffle.api.source.Source) new execution} is starting</em>
  *         }
  *     }).
- *     {@link com.oracle.truffle.api.vm.TruffleVM.Builder#onEvent(com.oracle.truffle.api.vm.EventConsumer) onEvent}(<b>new</b> {@link com.oracle.truffle.api.vm.EventConsumer EventConsumer}{@code <}
+ *     {@link com.oracle.truffle.api.vm.PolyglotEngine.Builder#onEvent(com.oracle.truffle.api.vm.EventConsumer) onEvent}(<b>new</b> {@link com.oracle.truffle.api.vm.EventConsumer EventConsumer}{@code <}
  *     {@link com.oracle.truffle.api.debug.SuspendedEvent}{@code >}() {
  *         <b>public void</b> handle({@link com.oracle.truffle.api.debug.SuspendedEvent} ev) {
  *             <em>// execution is suspended on a breakpoint or on a step - decide what next</em>
  *         }
- *     }).{@link com.oracle.truffle.api.vm.TruffleVM.Builder#build() build()};
+ *     }).{@link com.oracle.truffle.api.vm.PolyglotEngine.Builder#build() build()};
  * </pre>
  * The debugging is controlled by events emitted by the Truffle virtual machine
  * at important moments. The {@link com.oracle.truffle.api.debug.ExecutionEvent}
- * is sent when a call to {@link com.oracle.truffle.api.vm.TruffleVM#eval(com.oracle.truffle.api.source.Source)}
+ * is sent when a call to {@link com.oracle.truffle.api.vm.PolyglotEngine#eval(com.oracle.truffle.api.source.Source)}
  * is made and allows one to configure {@link com.oracle.truffle.api.debug.Breakpoint breakpoints} and/or decide whether the
  * program should {@link com.oracle.truffle.api.debug.ExecutionEvent#prepareStepInto() step-into} or
  * {@link com.oracle.truffle.api.debug.ExecutionEvent#prepareContinue() just run}. Once the execution is suspended a
@@ -63,7 +63,7 @@
  * The events methods are only available when the event is being delivered and
  * shouldn't be used anytime later. Both events however provide access to
  * {@link com.oracle.truffle.api.debug.Debugger} which can be kept and used
- * during whole existence of the {@link com.oracle.truffle.api.vm.TruffleVM}.
+ * during whole existence of the {@link com.oracle.truffle.api.vm.PolyglotEngine}.
  * {@link com.oracle.truffle.api.debug.Debugger} is the central class that
  * keeps information about {@link com.oracle.truffle.api.debug.Debugger#getBreakpoints() registered breakpoints}
  * and allows one create new {@link com.oracle.truffle.api.debug.Breakpoint ones}.
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Tue Sep 22 11:22:26 2015 +0200
@@ -44,7 +44,7 @@
 import java.lang.ref.WeakReference;
 
 /**
- * Communication between TruffleVM and TruffleLanguage API/SPI.
+ * Communication between PolyglotEngine and TruffleLanguage API/SPI.
  */
 @SuppressWarnings("rawtypes")
 public abstract class Accessor {
--- a/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTckTest.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTckTest.java	Tue Sep 22 11:22:26 2015 +0200
@@ -41,7 +41,7 @@
 package com.oracle.truffle.sl.test;
 
 import com.oracle.truffle.api.source.Source;
-import com.oracle.truffle.api.vm.TruffleVM;
+import com.oracle.truffle.api.vm.PolyglotEngine;
 import com.oracle.truffle.tck.TruffleTCK;
 import static org.junit.Assert.assertTrue;
 import org.junit.Test;
@@ -53,13 +53,13 @@
 public class SLTckTest extends TruffleTCK {
     @Test
     public void testVerifyPresence() {
-        TruffleVM vm = TruffleVM.newVM().build();
+        PolyglotEngine vm = PolyglotEngine.buildNew().build();
         assertTrue("Our language is present", vm.getLanguages().containsKey("application/x-sl"));
     }
 
     @Override
-    protected TruffleVM prepareVM() throws Exception {
-        TruffleVM vm = TruffleVM.newVM().build();
+    protected PolyglotEngine prepareVM() throws Exception {
+        PolyglotEngine vm = PolyglotEngine.buildNew().build();
         // @formatter:off
         vm.eval(
             Source.fromText(
--- a/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java	Tue Sep 22 11:22:26 2015 +0200
@@ -41,7 +41,7 @@
 package com.oracle.truffle.sl.test;
 
 import com.oracle.truffle.api.dsl.NodeFactory;
-import com.oracle.truffle.api.vm.TruffleVM;
+import com.oracle.truffle.api.vm.PolyglotEngine;
 import com.oracle.truffle.sl.SLLanguage;
 import com.oracle.truffle.sl.builtins.SLBuiltinNode;
 import com.oracle.truffle.sl.test.SLTestRunner.TestCase;
@@ -229,7 +229,7 @@
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         try {
-            TruffleVM vm = TruffleVM.newVM().setIn(new ByteArrayInputStream(repeat(testCase.testInput, repeats).getBytes("UTF-8"))).setOut(out).build();
+            PolyglotEngine vm = PolyglotEngine.buildNew().setIn(new ByteArrayInputStream(repeat(testCase.testInput, repeats).getBytes("UTF-8"))).setOut(out).build();
 
             String script = readAllLines(testCase.path);
 
--- a/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java	Tue Sep 22 11:22:26 2015 +0200
@@ -46,7 +46,7 @@
 import com.oracle.truffle.api.instrument.StandardSyntaxTag;
 import com.oracle.truffle.api.instrument.impl.DefaultSimpleInstrumentListener;
 import com.oracle.truffle.api.source.Source;
-import com.oracle.truffle.api.vm.TruffleVM;
+import com.oracle.truffle.api.vm.PolyglotEngine;
 import com.oracle.truffle.sl.nodes.instrument.SLStandardASTProber;
 import com.oracle.truffle.sl.nodes.local.SLWriteLocalVariableNode;
 import com.oracle.truffle.sl.test.SLTestRunner;
@@ -241,7 +241,7 @@
             // We use the name of the file to determine what visitor to attach to it.
             if (testCase.baseName.endsWith(ASSIGNMENT_VALUE_SUFFIX)) {
                 // Set up the execution context for Simple and register our two listeners
-                TruffleVM vm = TruffleVM.newVM().setIn(new ByteArrayInputStream(testCase.testInput.getBytes("UTF-8"))).setOut(out).build();
+                PolyglotEngine vm = PolyglotEngine.buildNew().setIn(new ByteArrayInputStream(testCase.testInput.getBytes("UTF-8"))).setOut(out).build();
 
                 final String src = readAllLines(testCase.path);
                 vm.eval(Source.fromText(src, testCase.path.toString()).withMimeType("application/x-sl"));
@@ -252,7 +252,7 @@
                     probe.attach(Instrument.create(slPrintAssigmentValueListener, "SL print assignment value"));
                 }
 
-                TruffleVM.Symbol main = vm.findGlobalSymbol("main");
+                PolyglotEngine.Value main = vm.findGlobalSymbol("main");
                 main.invoke(null);
             } else {
                 notifier.fireTestFailure(new Failure(testCase.name, new UnsupportedOperationException("No instrumentation found.")));
--- a/truffle/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLHandler.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLHandler.java	Tue Sep 22 11:22:26 2015 +0200
@@ -43,7 +43,7 @@
 import com.oracle.truffle.api.instrument.KillException;
 import com.oracle.truffle.api.instrument.QuitException;
 import com.oracle.truffle.api.source.Source;
-import com.oracle.truffle.api.vm.TruffleVM;
+import com.oracle.truffle.api.vm.PolyglotEngine;
 import com.oracle.truffle.tools.debug.shell.REPLMessage;
 import com.oracle.truffle.tools.debug.shell.client.SimpleREPLClient;
 import com.oracle.truffle.tools.debug.shell.server.REPLHandler;
@@ -128,9 +128,9 @@
             if (!file.canRead()) {
                 return finishReplyFailed(reply, "can't find file \"" + fileName + "\"");
             }
-            final TruffleVM vm = serverContext.vm();
+            final PolyglotEngine vm = serverContext.vm();
             vm.eval(Source.fromFileName(file.getPath()));
-            TruffleVM.Symbol main = vm.findGlobalSymbol("main");
+            PolyglotEngine.Value main = vm.findGlobalSymbol("main");
             if (main != null) {
                 main.invoke(null);
             }
--- a/truffle/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLServer.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLServer.java	Tue Sep 22 11:22:26 2015 +0200
@@ -49,8 +49,8 @@
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
 import com.oracle.truffle.api.vm.EventConsumer;
-import com.oracle.truffle.api.vm.TruffleVM;
-import com.oracle.truffle.api.vm.TruffleVM.Language;
+import com.oracle.truffle.api.vm.PolyglotEngine;
+import com.oracle.truffle.api.vm.PolyglotEngine.Language;
 import com.oracle.truffle.sl.SLLanguage;
 import com.oracle.truffle.sl.nodes.instrument.SLDefaultVisualizer;
 import com.oracle.truffle.tools.debug.shell.REPLMessage;
@@ -90,7 +90,7 @@
     }
 
     private final Language language;
-    private final TruffleVM vm;
+    private final PolyglotEngine vm;
     private Debugger db;
     private final String statusPrefix;
     private final Map<String, REPLHandler> handlerMap = new HashMap<>();
@@ -140,7 +140,7 @@
             }
         };
 
-        TruffleVM newVM = TruffleVM.newVM().onEvent(onHalted).onEvent(onExec).build();
+        PolyglotEngine newVM = PolyglotEngine.buildNew().onEvent(onHalted).onEvent(onExec).build();
         this.language = newVM.getLanguages().get("application/x-sl");
         assert language != null;
 
@@ -215,7 +215,7 @@
         }
 
         @Override
-        public TruffleVM vm() {
+        public PolyglotEngine vm() {
             return vm;
         }
 
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java	Tue Sep 22 11:22:26 2015 +0200
@@ -61,8 +61,8 @@
 import com.oracle.truffle.api.nodes.NodeUtil;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
-import com.oracle.truffle.api.vm.TruffleVM;
-import com.oracle.truffle.api.vm.TruffleVM.Symbol;
+import com.oracle.truffle.api.vm.PolyglotEngine;
+import com.oracle.truffle.api.vm.PolyglotEngine.Value;
 import com.oracle.truffle.sl.builtins.SLBuiltinNode;
 import com.oracle.truffle.sl.builtins.SLDefineFunctionBuiltin;
 import com.oracle.truffle.sl.builtins.SLNanoTimeBuiltin;
@@ -226,7 +226,7 @@
      * The main entry point. Use the mx command "mx sl" to run it with the correct class path setup.
      */
     public static void main(String[] args) throws IOException {
-        TruffleVM vm = TruffleVM.newVM().build();
+        PolyglotEngine vm = PolyglotEngine.buildNew().build();
         assert vm.getLanguages().containsKey("application/x-sl");
 
         setupToolDemos();
@@ -243,7 +243,7 @@
             source = Source.fromFileName(args[0]);
         }
         vm.eval(source);
-        Symbol main = vm.findGlobalSymbol("main");
+        Value main = vm.findGlobalSymbol("main");
         if (main == null) {
             throw new SLException("No function main() defined in SL source file.");
         }
@@ -257,10 +257,10 @@
      * Temporary method during API evolution, supports debugger integration.
      */
     public static void run(Source source) throws IOException {
-        TruffleVM vm = TruffleVM.newVM().build();
+        PolyglotEngine vm = PolyglotEngine.buildNew().build();
         assert vm.getLanguages().containsKey("application/x-sl");
         vm.eval(source);
-        Symbol main = vm.findGlobalSymbol("main");
+        Value main = vm.findGlobalSymbol("main");
         if (main == null) {
             throw new SLException("No function main() defined in SL source file.");
         }
@@ -271,7 +271,7 @@
      * Parse and run the specified SL source. Factored out in a separate method so that it can also
      * be used by the unit test harness.
      */
-    public static long run(TruffleVM context, Path path, PrintWriter logOutput, PrintWriter out, int repeats, List<NodeFactory<? extends SLBuiltinNode>> currentBuiltins) throws IOException {
+    public static long run(PolyglotEngine context, Path path, PrintWriter logOutput, PrintWriter out, int repeats, List<NodeFactory<? extends SLBuiltinNode>> currentBuiltins) throws IOException {
         builtins = currentBuiltins;
 
         if (logOutput != null) {
@@ -287,7 +287,7 @@
         }
 
         /* Lookup our main entry point, which is per definition always named "main". */
-        Symbol main = context.findGlobalSymbol("main");
+        Value main = context.findGlobalSymbol("main");
         if (main == null) {
             throw new SLException("No function main() defined in SL source file.");
         }
@@ -495,7 +495,7 @@
         // if (statementCounts || coverage) {
         // if (registeredASTProber == null) {
         // final ASTProber newProber = new SLStandardASTProber();
-        // // This should be registered on the TruffleVM
+        // // This should be registered on the PolyglotEngine
         // Probe.registerASTProber(newProber);
         // registeredASTProber = newProber;
         // }
@@ -544,7 +544,7 @@
         public SLDebugProvider() {
             if (registeredASTProber == null) {
                 registeredASTProber = new SLStandardASTProber();
-                // This should be registered on the TruffleVM
+                // This should be registered on the PolyglotEngine
                 Probe.registerASTProber(registeredASTProber);
             }
         }
@@ -558,7 +558,7 @@
 
         public void enableASTProbing(ASTProber prober) {
             if (prober != null) {
-                // This should be registered on the TruffleVM
+                // This should be registered on the PolyglotEngine
                 Probe.registerASTProber(prober);
             }
         }
--- a/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.tck/src/com/oracle/truffle/tck/TruffleTCK.java	Tue Sep 22 11:22:26 2015 +0200
@@ -27,7 +27,7 @@
 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.TruffleVM;
+import com.oracle.truffle.api.vm.PolyglotEngine;
 import java.io.IOException;
 import java.util.Random;
 import static org.junit.Assert.assertEquals;
@@ -45,28 +45,28 @@
  */
 public abstract class TruffleTCK {
     private static final Random RANDOM = new Random();
-    private TruffleVM tckVM;
+    private PolyglotEngine tckVM;
 
     protected TruffleTCK() {
     }
 
     /**
-     * This methods is called before first test is executed. It's purpose is to set a TruffleVM with
-     * your language up, so it is ready for testing.
-     * {@link TruffleVM#eval(com.oracle.truffle.api.source.Source) Execute} any scripts you need,
-     * and prepare global symbols with proper names. The symbols will then be looked up by the
+     * This methods is called before first test is executed. It's purpose is to set a
+     * {@link PolyglotEngine} with your language up, so it is ready for testing.
+     * {@link PolyglotEngine#eval(com.oracle.truffle.api.source.Source) Execute} any scripts you
+     * need, and prepare global symbols with proper names. The symbols will then be looked up by the
      * infrastructure (using the names provided by you from methods like {@link #plusInt()}) and
      * used for internal testing.
      *
      * @return initialized Truffle virtual machine
      * @throws java.lang.Exception thrown when the VM preparation fails
      */
-    protected abstract TruffleVM prepareVM() throws Exception;
+    protected abstract PolyglotEngine prepareVM() throws Exception;
 
     /**
      * MIME type associated with your language. The MIME type will be passed to
-     * {@link TruffleVM#eval(com.oracle.truffle.api.source.Source)} method of the
-     * {@link #prepareVM() created TruffleVM}.
+     * {@link PolyglotEngine#eval(com.oracle.truffle.api.source.Source)} method of the
+     * {@link #prepareVM() created engine}.
      *
      * @return mime type of the tested language
      */
@@ -84,8 +84,9 @@
     /**
      * Name of a function that returns <code>null</code>. Truffle languages are encouraged to have
      * their own type representing <code>null</code>, but when such value is returned from
-     * {@link TruffleVM#eval}, it needs to be converted to real Java <code>null</code> by sending a
-     * foreign access <em>isNull</em> message. There is a test to verify it is really true.
+     * {@link PolyglotEngine#eval}, it needs to be converted to real Java <code>null</code> by
+     * sending a foreign access <em>isNull</em> message. There is a test to verify it is really
+     * true.
      *
      * @return name of globally exported symbol
      */
@@ -140,7 +141,7 @@
     }
 
     /**
-     * Name of a function that counts number of its invocations in current {@link TruffleVM}
+     * Name of a function that counts number of its invocations in current {@link PolyglotEngine}
      * context. Your function should somehow keep a counter to remember number of its invocations
      * and always increment it. The first invocation should return <code>1</code>, the second
      * <code>2</code> and so on. The returned values are expected to be instances of {@link Number}.
@@ -154,8 +155,8 @@
 
     /**
      * Return a code snippet that is invalid in your language. Its
-     * {@link TruffleVM#eval(com.oracle.truffle.api.source.Source) evaluation} should fail and yield
-     * an exception.
+     * {@link PolyglotEngine#eval(com.oracle.truffle.api.source.Source) evaluation} should fail and
+     * yield an exception.
      *
      * @return code snippet invalid in the tested language
      */
@@ -186,7 +187,7 @@
         throw new UnsupportedOperationException("compoundObject() method not implemented");
     }
 
-    private TruffleVM vm() throws Exception {
+    private PolyglotEngine vm() throws Exception {
         if (tckVM == null) {
             tckVM = prepareVM();
         }
@@ -199,7 +200,7 @@
 
     @Test
     public void testFortyTwo() throws Exception {
-        TruffleVM.Symbol fourtyTwo = findGlobalSymbol(fourtyTwo());
+        PolyglotEngine.Value fourtyTwo = findGlobalSymbol(fourtyTwo());
 
         Object res = fourtyTwo.invoke(null).get();
 
@@ -222,7 +223,7 @@
 
     @Test
     public void testNull() throws Exception {
-        TruffleVM.Symbol retNull = findGlobalSymbol(returnsNull());
+        PolyglotEngine.Value retNull = findGlobalSymbol(returnsNull());
 
         Object res = retNull.invoke(null).get();
 
@@ -244,7 +245,7 @@
         int a = RANDOM.nextInt(100);
         int b = RANDOM.nextInt(100);
 
-        TruffleVM.Symbol plus = findGlobalSymbol(plus(int.class, int.class));
+        PolyglotEngine.Value plus = findGlobalSymbol(plus(int.class, int.class));
 
         Number n = plus.invoke(null, a, b).as(Number.class);
         assert a + b == n.intValue() : "The value is correct: (" + a + " + " + b + ") =  " + n.intValue();
@@ -255,7 +256,7 @@
         int a = RANDOM.nextInt(100);
         int b = RANDOM.nextInt(100);
 
-        TruffleVM.Symbol plus = findGlobalSymbol(plus(byte.class, byte.class));
+        PolyglotEngine.Value plus = findGlobalSymbol(plus(byte.class, byte.class));
 
         Number n = plus.invoke(null, (byte) a, (byte) b).as(Number.class);
         assert a + b == n.intValue() : "The value is correct: (" + a + " + " + b + ") =  " + n.intValue();
@@ -266,7 +267,7 @@
         int a = RANDOM.nextInt(100);
         int b = RANDOM.nextInt(100);
 
-        TruffleVM.Symbol plus = findGlobalSymbol(plus(short.class, short.class));
+        PolyglotEngine.Value plus = findGlobalSymbol(plus(short.class, short.class));
 
         Number n = plus.invoke(null, (short) a, (short) b).as(Number.class);
         assert a + b == n.intValue() : "The value is correct: (" + a + " + " + b + ") =  " + n.intValue();
@@ -277,7 +278,7 @@
         long a = RANDOM.nextInt(100);
         long b = RANDOM.nextInt(100);
 
-        TruffleVM.Symbol plus = findGlobalSymbol(plus(long.class, long.class));
+        PolyglotEngine.Value plus = findGlobalSymbol(plus(long.class, long.class));
 
         Number n = plus.invoke(null, a, b).as(Number.class);
         assert a + b == n.longValue() : "The value is correct: (" + a + " + " + b + ") =  " + n.longValue();
@@ -288,7 +289,7 @@
         float a = RANDOM.nextFloat();
         float b = RANDOM.nextFloat();
 
-        TruffleVM.Symbol plus = findGlobalSymbol(plus(float.class, float.class));
+        PolyglotEngine.Value plus = findGlobalSymbol(plus(float.class, float.class));
 
         Number n = plus.invoke(null, a, b).as(Number.class);
         assertEquals("Correct value computed", a + b, n.floatValue(), 0.01f);
@@ -299,7 +300,7 @@
         double a = RANDOM.nextDouble();
         double b = RANDOM.nextDouble();
 
-        TruffleVM.Symbol plus = findGlobalSymbol(plus(float.class, float.class));
+        PolyglotEngine.Value plus = findGlobalSymbol(plus(float.class, float.class));
 
         Number n = plus.invoke(null, a, b).as(Number.class);
         assertEquals("Correct value computed", a + b, n.doubleValue(), 0.01);
@@ -329,7 +330,7 @@
 
     @Test
     public void testMaxOrMinValue() throws Exception {
-        TruffleVM.Symbol apply = findGlobalSymbol(applyNumbers());
+        PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
 
         TruffleObject fn = JavaInterop.asTruffleFunction(LongBinaryOperation.class, new MaxMinObject(true));
         Object res = apply.invoke(null, fn).get();
@@ -343,10 +344,10 @@
 
     @Test
     public void testMaxOrMinValue2() throws Exception {
-        TruffleVM.Symbol apply = findGlobalSymbol(applyNumbers());
+        PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
 
         TruffleObject fn = JavaInterop.asTruffleFunction(LongBinaryOperation.class, new MaxMinObject(false));
-        final TruffleVM.Symbol result = apply.invoke(null, fn);
+        final PolyglotEngine.Value result = apply.invoke(null, fn);
 
         try {
             String res = result.as(String.class);
@@ -361,7 +362,7 @@
 
     @Test
     public void testPrimitiveReturnTypeByte() throws Exception {
-        TruffleVM.Symbol apply = findGlobalSymbol(applyNumbers());
+        PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
 
         byte value = (byte) RANDOM.nextInt(100);
 
@@ -372,7 +373,7 @@
 
     @Test
     public void testPrimitiveReturnTypeShort() throws Exception {
-        TruffleVM.Symbol apply = findGlobalSymbol(applyNumbers());
+        PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
 
         short value = (short) RANDOM.nextInt(100);
 
@@ -383,7 +384,7 @@
 
     @Test
     public void testPrimitiveReturnTypeInt() throws Exception {
-        TruffleVM.Symbol apply = findGlobalSymbol(applyNumbers());
+        PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
 
         int value = RANDOM.nextInt(100);
 
@@ -394,7 +395,7 @@
 
     @Test
     public void testPrimitiveReturnTypeLong() throws Exception {
-        TruffleVM.Symbol apply = findGlobalSymbol(applyNumbers());
+        PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
 
         long value = RANDOM.nextInt(1000);
 
@@ -405,7 +406,7 @@
 
     @Test
     public void testPrimitiveReturnTypeFloat() throws Exception {
-        TruffleVM.Symbol apply = findGlobalSymbol(applyNumbers());
+        PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
 
         float value = RANDOM.nextInt(1000) + RANDOM.nextFloat();
 
@@ -416,7 +417,7 @@
 
     @Test
     public void testPrimitiveReturnTypeDouble() throws Exception {
-        TruffleVM.Symbol apply = findGlobalSymbol(applyNumbers());
+        PolyglotEngine.Value apply = findGlobalSymbol(applyNumbers());
 
         double value = RANDOM.nextInt(1000) + RANDOM.nextDouble();
 
@@ -431,7 +432,7 @@
         if (id == null) {
             return;
         }
-        TruffleVM.Symbol apply = findGlobalSymbol(id);
+        PolyglotEngine.Value apply = findGlobalSymbol(id);
 
         byte value = (byte) RANDOM.nextInt(100);
 
@@ -445,7 +446,7 @@
         if (id == null) {
             return;
         }
-        TruffleVM.Symbol apply = findGlobalSymbol(id);
+        PolyglotEngine.Value apply = findGlobalSymbol(id);
 
         short value = (short) RANDOM.nextInt(100);
         Number n = (Number) apply.invoke(null, value).get();
@@ -458,7 +459,7 @@
         if (id == null) {
             return;
         }
-        TruffleVM.Symbol apply = findGlobalSymbol(id);
+        PolyglotEngine.Value apply = findGlobalSymbol(id);
 
         int value = RANDOM.nextInt(100);
 
@@ -472,7 +473,7 @@
         if (id == null) {
             return;
         }
-        TruffleVM.Symbol apply = findGlobalSymbol(id);
+        PolyglotEngine.Value apply = findGlobalSymbol(id);
 
         long value = RANDOM.nextInt(1000);
 
@@ -486,7 +487,7 @@
         if (id == null) {
             return;
         }
-        TruffleVM.Symbol apply = findGlobalSymbol(id);
+        PolyglotEngine.Value apply = findGlobalSymbol(id);
 
         float value = RANDOM.nextInt(1000) + RANDOM.nextFloat();
 
@@ -500,7 +501,7 @@
         if (id == null) {
             return;
         }
-        TruffleVM.Symbol apply = findGlobalSymbol(id);
+        PolyglotEngine.Value apply = findGlobalSymbol(id);
 
         double value = RANDOM.nextInt(1000) + RANDOM.nextDouble();
 
@@ -514,7 +515,7 @@
         if (id == null) {
             return;
         }
-        TruffleVM.Symbol apply = findGlobalSymbol(id);
+        PolyglotEngine.Value apply = findGlobalSymbol(id);
 
         TruffleObject fn = JavaInterop.asTruffleFunction(LongBinaryOperation.class, new MaxMinObject(true));
 
@@ -525,11 +526,11 @@
     @Test
     public void testCoExistanceOfMultipleLanguageInstances() throws Exception {
         final String countMethod = countInvocations();
-        TruffleVM.Symbol count1 = findGlobalSymbol(countMethod);
-        TruffleVM vm1 = tckVM;
+        PolyglotEngine.Value count1 = findGlobalSymbol(countMethod);
+        PolyglotEngine vm1 = tckVM;
         tckVM = null; // clean-up
-        TruffleVM.Symbol count2 = findGlobalSymbol(countMethod);
-        TruffleVM vm2 = tckVM;
+        PolyglotEngine.Value count2 = findGlobalSymbol(countMethod);
+        PolyglotEngine vm2 = tckVM;
 
         assertNotSame("Two virtual machines allocated", vm1, vm2);
 
@@ -554,17 +555,17 @@
 
     }
 
-    private TruffleVM.Symbol findGlobalSymbol(String name) throws Exception {
-        TruffleVM.Symbol s = vm().findGlobalSymbol(name);
+    private PolyglotEngine.Value findGlobalSymbol(String name) throws Exception {
+        PolyglotEngine.Value s = vm().findGlobalSymbol(name);
         assert s != null : "Symbol " + name + " is not found!";
         return s;
     }
 
     private CompoundObject findCompoundSymbol() throws Exception {
         final String compoundObjectName = compoundObject();
-        TruffleVM.Symbol s = vm().findGlobalSymbol(compoundObjectName);
+        PolyglotEngine.Value s = vm().findGlobalSymbol(compoundObjectName);
         assert s != null : "Symbol " + compoundObjectName + " is not found!";
-        final TruffleVM.Symbol value = s.invoke(null);
+        final PolyglotEngine.Value value = s.invoke(null);
         CompoundObject obj = value.as(CompoundObject.class);
         assertNotNull("Compound object for " + value + " found", obj);
         int traverse = RANDOM.nextInt(10);
--- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java	Tue Sep 22 11:22:26 2015 +0200
@@ -32,8 +32,8 @@
 import com.oracle.truffle.api.instrument.Visualizer;
 import com.oracle.truffle.api.instrument.impl.DefaultVisualizer;
 import com.oracle.truffle.api.nodes.Node;
-import com.oracle.truffle.api.vm.TruffleVM;
-import com.oracle.truffle.api.vm.TruffleVM.Language;
+import com.oracle.truffle.api.vm.PolyglotEngine;
+import com.oracle.truffle.api.vm.PolyglotEngine.Language;
 import com.oracle.truffle.tools.debug.shell.REPLMessage;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -76,7 +76,7 @@
         return new DefaultVisualizer();
     }
 
-    public abstract TruffleVM vm();
+    public abstract PolyglotEngine vm();
 
     protected abstract Debugger db();
 
--- a/truffle/overview.html	Mon Sep 21 13:11:41 2015 +0200
+++ b/truffle/overview.html	Tue Sep 22 11:22:26 2015 +0200
@@ -33,7 +33,7 @@
 <p>
 Truffle is a framework for writing and executing interpreters. In case
 you want to execute already written interpreters from your Java application,
-start at {@link com.oracle.truffle.api.vm.TruffleVM}. In case you'd like
+start at {@link com.oracle.truffle.api.vm.PolyglotEngine}. In case you'd like
 to write your own Truffle based language, start at 
 {@link com.oracle.truffle.api.TruffleLanguage}.
 <p>