changeset 22268:b56fe0d3b560

Merge with acfea340b19199faaa44bd5e103c716c17ea2b21
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Wed, 30 Sep 2015 19:40:55 -0700
parents ebcb4878b011 (current diff) acfea340b191 (diff)
children 24fe7ae281e5
files CHANGELOG.md truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java
diffstat 19 files changed, 322 insertions(+), 97 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Wed Sep 30 16:34:53 2015 -0700
+++ b/.hgignore	Wed Sep 30 19:40:55 2015 -0700
@@ -1,4 +1,5 @@
 ^mx.truffle/env
+^mx.truffle/savedDeps
 ^mx.truffle/checkstyle-timestamps
 ^mx.truffle/eclipse-config.zip
 ^mx.truffle/eclipse-config-libs.zip
@@ -9,6 +10,7 @@
 ^mx.truffle/currentAnnotationProcessors
 ^mx.truffle/ecj.jar
 ^mx.truffle/includes
+^mxbuild/
 ^build/
 ^build-nograal/
 ^build-nojvmci/
--- a/CHANGELOG.md	Wed Sep 30 16:34:53 2015 -0700
+++ b/CHANGELOG.md	Wed Sep 30 19:40:55 2015 -0700
@@ -5,7 +5,9 @@
 
 ## `tip`
 ### Truffle
-...
+* The Instrumentation Framework has been revised and has new APIs that are integrated into the PolyglotEngine.
+  * Instrumention support required of language implementatins is specified as abstract methods on TruffleLanguage.
+  * Clients access instrumentation sevices via an instance of Instrumenter, provided by the Polyglot framework.
 
 ## Version 0.8
 17-Jul-2015, [Repository Revision](http://lafo.ssw.uni-linz.ac.at/hg/truffle/shortlog/graal-0.8)
--- a/README.md	Wed Sep 30 16:34:53 2015 -0700
+++ b/README.md	Wed Sep 30 19:40:55 2015 -0700
@@ -16,14 +16,44 @@
 Truffle is developed and maintained by Oracle Labs and the Institute for System
 Software of the Johannes Kepler University Linz.
 
+## Using Truffle
 
-## Building and Using Truffle
+Truffle official documentation is part of [Truffle javadoc](http://lafo.ssw.uni-linz.ac.at/javadoc/truffle/latest/).
+It includes description of common use-cases, references to various tutorials,
+code snippets and more. In case you want to embedded Truffle into your
+application or write your own high speed language interpreter, start
+[here](http://lafo.ssw.uni-linz.ac.at/javadoc/truffle/latest/).
 
-Truffle and Graal use the [MX build tool](https://bitbucket.org/allr/mxtool2),
-which is part of this repository. To build Truffle execute:
+Our typicial sample language is called the SimpleLanguage. A good entry point for
+exploring SimpleLanguage is the [SLLanguage class](https://github.com/graalvm/Truffle/blob/master/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java).
+In addition to that here are links to presentations, FAQs and papers about
+Graal and Truffle:
+
+  - [Truffle Tutorials and Presentations](https://wiki.openjdk.java.net/display/Graal/Publications+and+Presentations)
+  - [Truffle FAQ and Guidelines](https://wiki.openjdk.java.net/display/Graal/Truffle+FAQ+and+Guidelines)
+  - [Graal VM and Truffle/JS](http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index-2301583.html) on the Oracle Technology Network
+  - [Papers on Truffle](http://ssw.jku.at/Research/Projects/JVM/Truffle.html)
+  - [Papers on Graal](http://ssw.jku.at/Research/Projects/JVM/Graal.html)
+
+## Hacking Truffle
+
+Truffle and Graal use the [MX build tool](https://bitbucket.org/allr/mx),
+which needs to be installed before using this repository. To do so execute
+in a clean directory:
 
 ```bash
-./mx.sh build
+$ hg clone https://bitbucket.org/allr/mx
+$ mx/mx
+```
+
+the mx/*mx* command is a wrapper around Python script that serves as our build tool.
+Make sure you put it onto your ''PATH'' and then you can work with Truffle
+sources from a command line:
+
+```bash
+$ mx clean
+$ mx build
+$ mx unittest
 ```
 
 The created `./build` directory contains all necessary jars and source bundles.
@@ -31,10 +61,24 @@
   - `truffle-api.jar` contains the framework
   - `truffle-dsl-processor.jar` contains the TruffleDSL annotation processor
 
-### Maven
+You can open Truffle sources in your favorite Java IDE by invoking:
+
+```bash
+$ mx ideinit
+```
+
+the necessary IDE metadata will then be generated into *truffle* subdirectory
+and its folders.
 
-For Maven based projects, prebuilt binaries can be included into a project by
-adding the following dependencies to a `pom.xml`:
+*mx* supports Maven integration. To register prebuilt binaries into local Maven
+repository you can invoke:
+
+```bash
+$ mx build
+$ mx maven-install
+```
+
+and then it is possible to include the artifacts as dependencies to a `pom.xml`:
 
 ```xml
 <dependency>
@@ -50,22 +94,10 @@
 </dependency>
 ```
 
-## Resources and Documentation
-
-This repository contains the SimpleLanguage, which comes with JavaDoc
-documentation to demonstrate how Truffle is used. A good entry point for
-exploring SimpleLanguage is the [SLLanguage class](https://github.com/OracleLabs/Truffle/blob/master/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java).
-
-  - [Truffle Tutorials and Presentations](https://wiki.openjdk.java.net/display/Graal/Publications+and+Presentations)
-  - [Truffle FAQ and Guidelines](https://wiki.openjdk.java.net/display/Graal/Truffle+FAQ+and+Guidelines)
-  - [Graal VM and Truffle/JS](http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index-2301583.html) on the Oracle Technology Network
-  - [Papers on Truffle](http://ssw.jku.at/Research/Projects/JVM/Truffle.html)
-  - [Papers on Graal](http://ssw.jku.at/Research/Projects/JVM/Graal.html)
-
 ## Contributing
 
-TODO
-
+You can contact the Truffle developers at graal-dev@openjdk.java.net mailing
+list.
 
 ## License
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.test/src/META-INF/services/java.nio.file.spi.FileTypeDetector	Wed Sep 30 19:40:55 2015 -0700
@@ -0,0 +1,1 @@
+com.oracle.truffle.api.test.source.JavaRecognizer
--- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java	Wed Sep 30 19:40:55 2015 -0700
@@ -22,6 +22,9 @@
  */
 package com.oracle.truffle.api.test;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -32,9 +35,11 @@
 import com.oracle.truffle.api.TruffleRuntime;
 import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.FrameDescriptor;
+import com.oracle.truffle.api.frame.FrameInstance;
 import com.oracle.truffle.api.frame.FrameSlot;
 import com.oracle.truffle.api.frame.FrameSlotKind;
 import com.oracle.truffle.api.frame.FrameSlotTypeException;
+import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.RootNode;
@@ -166,4 +171,31 @@
             }
         }
     }
+
+    @Test
+    public void framesCanBeMaterialized() {
+        final TruffleRuntime runtime = Truffle.getRuntime();
+
+        class FrameRootNode extends RootNode {
+
+            public FrameRootNode() {
+                super(TestingLanguage.class, null, null);
+            }
+
+            @Override
+            public Object execute(VirtualFrame frame) {
+                FrameInstance frameInstance = runtime.getCurrentFrame();
+                Frame readWrite = frameInstance.getFrame(FrameInstance.FrameAccess.READ_WRITE, true);
+                Frame materialized = frameInstance.getFrame(FrameInstance.FrameAccess.MATERIALIZE, true);
+
+                assertTrue("Really materialized: " + materialized, materialized instanceof MaterializedFrame);
+                assertEquals("It's my frame", frame, readWrite);
+                return this;
+            }
+        }
+
+        FrameRootNode frn = new FrameRootNode();
+        Object ret = Truffle.getRuntime().createCallTarget(frn).call();
+        assertEquals("Returns itself", frn, ret);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/JavaRecognizer.java	Wed Sep 30 19:40:55 2015 -0700
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, 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.source;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.spi.FileTypeDetector;
+
+public final class JavaRecognizer extends FileTypeDetector {
+    @Override
+    public String probeContentType(Path path) throws IOException {
+        if (path.getFileName().toString().endsWith(".java")) {
+            return "text/x-java";
+        }
+        return null;
+    }
+}
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java	Wed Sep 30 19:40:55 2015 -0700
@@ -165,7 +165,7 @@
      * <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#setErr(java.io.OutputStream) setErr}({@link OutputStream yourOutput})
      *     .{@link Builder#setIn(java.io.InputStream) setIn}({@link InputStream yourInput})
      *     .{@link Builder#build() build()};
      * </pre>
@@ -191,7 +191,7 @@
      * <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#setErr(java.io.OutputStream) setErr}({@link OutputStream yourOutput})
      *     .{@link Builder#setIn(java.io.InputStream) setIn}({@link InputStream yourInput})
      *     .{@link Builder#build() build()};
      * </pre>
@@ -384,15 +384,7 @@
         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());
-            }
+            mimeType = Files.probeContentType(file.toPath());
         } else {
             URL url = location.toURL();
             s = Source.fromURL(url, location.toString());
@@ -673,11 +665,11 @@
      * 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#eval(com.oracle.truffle.api.source.Source)} or a value returned by
+     * {@link #invoke(java.lang.Object, java.lang.Object...) a subsequent 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
+     * {@link Builder#executor(java.util.concurrent.Executor) asynchronous execution}, the
+     * {@link Value} represents a future - i.e., it is returned immediately, leaving the execution
      * running on behind.
      */
     public class Value {
@@ -989,7 +981,7 @@
         }
 
         @Override
-        protected TruffleLanguage findLanguageImpl(Object obj, Class<? extends TruffleLanguage> languageClazz) {
+        protected TruffleLanguage<?> findLanguageImpl(Object obj, Class<? extends TruffleLanguage> languageClazz) {
             final PolyglotEngine vm = (PolyglotEngine) obj;
             return vm.findLanguage(languageClazz);
         }
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Wed Sep 30 19:40:55 2015 -0700
@@ -101,6 +101,19 @@
     }
 
     /**
+     * Returns a boolean indicating whether or not a given value is seen as constant during the
+     * initial partial evaluation phase. If this method is called in the interpreter this method
+     * will always return <code>true</code>.
+     *
+     * @param value
+     * @return {@code true} when given value is seen as compilation constant, {@code false} if not
+     *         compilation constant.
+     */
+    public static boolean isPartialEvaluationConstant(Object value) {
+        return CompilerDirectives.inInterpreter();
+    }
+
+    /**
      * Directive for the compiler that the given runnable should only be executed in the interpreter
      * and ignored in the compiled code.
      *
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java	Wed Sep 30 19:40:55 2015 -0700
@@ -40,6 +40,8 @@
 import java.util.WeakHashMap;
 
 import com.oracle.truffle.api.debug.Debugger;
+import com.oracle.truffle.api.debug.SuspendedEvent;
+import com.oracle.truffle.api.frame.FrameInstance;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.impl.Accessor;
 import com.oracle.truffle.api.impl.FindContextNode;
@@ -52,6 +54,7 @@
 import com.oracle.truffle.api.instrument.Visualizer;
 import com.oracle.truffle.api.instrument.WrapperNode;
 import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.nodes.RootNode;
 import com.oracle.truffle.api.source.Source;
 
 /**
@@ -463,11 +466,15 @@
         }
 
         @Override
-        protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(Object vm, Class<? extends TruffleLanguage> languageClass, String expr,
-                        AdvancedInstrumentResultListener resultListener) throws IOException {
-
-            final TruffleLanguage language = findLanguageImpl(vm, languageClass);
-            return language.createAdvancedInstrumentRootFactory(expr, resultListener);
+        protected Object evalInContext(Object vm, SuspendedEvent ev, String code, FrameInstance frame) throws IOException {
+            Node n = frame == null ? ev.getNode() : frame.getCallNode();
+            RootNode rootNode = n.getRootNode();
+            Class<? extends TruffleLanguage> languageType = findLanguage(rootNode);
+            Env env = findLanguage(vm, languageType);
+            TruffleLanguage<?> lang = findLanguage(env);
+            Source source = Source.fromText(code, "eval in context");
+            CallTarget target = lang.parse(source, n);
+            return target.call();
         }
 
         @Override
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java	Wed Sep 30 19:40:55 2015 -0700
@@ -855,6 +855,10 @@
         debugContext = debugContext.predecessor;
     }
 
+    Object evalInContext(SuspendedEvent ev, String code, FrameInstance frame) throws IOException {
+        return ACCESSOR.evalInContext(vm, ev, code, frame);
+    }
+
     @SuppressWarnings("rawtypes")
     private static final class AccessorDebug extends Accessor {
 
@@ -889,6 +893,11 @@
         protected void dispatchEvent(Object vm, Object event) {
             super.dispatchEvent(vm, event);
         }
+
+        @Override
+        protected Object evalInContext(Object vm, SuspendedEvent ev, String code, FrameInstance frame) throws IOException {
+            return super.evalInContext(vm, ev, code, frame);
+        }
     }
 
     // registers into Accessor.DEBUG
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java	Wed Sep 30 19:40:55 2015 -0700
@@ -31,6 +31,7 @@
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.instrument.StandardSyntaxTag;
 import com.oracle.truffle.api.nodes.Node;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -192,4 +193,18 @@
     public void prepareStepOver(int stepCount) {
         debugger.prepareStepOver(stepCount);
     }
+
+    /**
+     * Evaluates given code snippet in the context of currently suspended execution.
+     *
+     * @param code the snippet to evaluate
+     * @param frame <code>null</code> in case the evaluation should happen in top most frame,
+     *            non-null value to specify a frame from those {@link #getStack() currently on
+     *            stack} to perform the evaluation in context of
+     * @return the computed value
+     * @throws IOException in case an evaluation goes wrong
+     */
+    public Object eval(String code, FrameInstance frame) throws IOException {
+        return debugger.evalInContext(this, code, frame);
+    }
 }
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Wed Sep 30 19:40:55 2015 -0700
@@ -37,6 +37,8 @@
 import com.oracle.truffle.api.TruffleLanguage;
 import com.oracle.truffle.api.TruffleLanguage.Env;
 import com.oracle.truffle.api.debug.Debugger;
+import com.oracle.truffle.api.debug.SuspendedEvent;
+import com.oracle.truffle.api.frame.FrameInstance;
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.instrument.ASTProber;
 import com.oracle.truffle.api.instrument.AdvancedInstrumentResultListener;
@@ -52,7 +54,6 @@
 /**
  * Communication between PolyglotEngine, TruffleLanguage API/SPI, and other services.
  */
-@SuppressWarnings("rawtypes")
 public abstract class Accessor {
     private static Accessor API;
     private static Accessor SPI;
@@ -162,6 +163,10 @@
         return API.eval(l, s);
     }
 
+    protected Object evalInContext(Object vm, SuspendedEvent ev, String code, FrameInstance frame) throws IOException {
+        return API.evalInContext(vm, ev, code, frame);
+    }
+
     protected Object importSymbol(Object vm, TruffleLanguage<?> queryingLang, String globalName) {
         return SPI.importSymbol(vm, queryingLang, globalName);
     }
@@ -177,6 +182,7 @@
     /**
      * Provided by each {@linkplain TruffleLanguage language implementation}.
      */
+    @SuppressWarnings("rawtypes")
     protected boolean isInstrumentable(Object vm, Node node) {
         final RootNode rootNode = node.getRootNode();
         Class<? extends TruffleLanguage> languageClazz = findLanguage(rootNode);
@@ -184,13 +190,14 @@
         return isInstrumentable(node, language);
     }
 
-    protected boolean isInstrumentable(Node node, TruffleLanguage language) {
+    protected boolean isInstrumentable(Node node, TruffleLanguage<?> language) {
         return API.isInstrumentable(node, language);
     }
 
     /**
      * Provided by each {@linkplain TruffleLanguage language implementation}.
      */
+    @SuppressWarnings("rawtypes")
     protected WrapperNode createWrapperNode(Object vm, Node node) {
         final RootNode rootNode = node.getRootNode();
         Class<? extends TruffleLanguage> languageClazz = findLanguage(rootNode);
@@ -198,23 +205,27 @@
         return createWrapperNode(node, language);
     }
 
-    protected WrapperNode createWrapperNode(Node node, TruffleLanguage language) {
+    protected WrapperNode createWrapperNode(Node node, TruffleLanguage<?> language) {
         return API.createWrapperNode(node, language);
     }
 
+    @SuppressWarnings("rawtypes")
     protected AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(Object vm, Class<? extends TruffleLanguage> languageClass, String expr, AdvancedInstrumentResultListener resultListener)
                     throws IOException {
         return API.createAdvancedInstrumentRootFactory(vm, languageClass, expr, resultListener);
     }
 
+    @SuppressWarnings("rawtypes")
     protected Class<? extends TruffleLanguage> findLanguage(RootNode n) {
         return NODES.findLanguage(n);
     }
 
+    @SuppressWarnings("rawtypes")
     protected Class<? extends TruffleLanguage> findLanguage(Probe probe) {
         return INSTRUMENT.findLanguage(probe);
     }
 
+    @SuppressWarnings("rawtypes")
     protected Env findLanguage(Object known, Class<? extends TruffleLanguage> languageClass) {
         Object vm;
         if (known == null) {
@@ -231,7 +242,8 @@
         return SPI.findLanguage(vm, languageClass);
     }
 
-    protected TruffleLanguage findLanguageImpl(Object known, Class<? extends TruffleLanguage> languageClass) {
+    @SuppressWarnings("rawtypes")
+    protected TruffleLanguage<?> findLanguageImpl(Object known, Class<? extends TruffleLanguage> languageClass) {
         Object vm;
         if (known == null) {
             vm = CURRENT_VM.get();
@@ -297,7 +309,7 @@
         return oneVM;
     }
 
-    @SuppressWarnings({"unchecked"})
+    @SuppressWarnings({"unchecked", "rawtypes"})
     static <C> C findContext(Class<? extends TruffleLanguage> type) {
         Env env = SPI.findLanguage(CURRENT_VM.get(), type);
         return (C) API.findContext(env);
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java	Wed Sep 30 19:40:55 2015 -0700
@@ -30,7 +30,6 @@
 import com.oracle.truffle.api.TruffleRuntime;
 import com.oracle.truffle.api.frame.Frame;
 import com.oracle.truffle.api.frame.FrameInstance;
-import com.oracle.truffle.api.frame.VirtualFrame;
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.nodes.RootNode;
 
@@ -59,10 +58,13 @@
 
     @Override
     public Object call(Object... args) {
-        final VirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), args);
+        final DefaultVirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), args);
         FrameInstance oldCurrentFrame = defaultTruffleRuntime().setCurrentFrame(new FrameInstance() {
 
             public Frame getFrame(FrameAccess access, boolean slowPath) {
+                if (access == FrameAccess.MATERIALIZE) {
+                    return new DefaultMaterializedFrame(frame);
+                }
                 return frame;
             }
 
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java	Wed Sep 30 19:40:55 2015 -0700
@@ -906,18 +906,10 @@
 
         @Override
         String findMimeType() {
-            if (file.getName().endsWith(".c")) {
-                return "text/x-c";
-            } else if (file.getName().endsWith(".R") || file.getName().endsWith(".r")) {
-                return "application/x-r";
-            } else if (file.getName().endsWith(".js") || file.getName().endsWith(".JS")) {
-                return "application/javascript";
-            } else {
-                try {
-                    return Files.probeContentType(file.toPath());
-                } catch (IOException ex) {
-                    LOG.log(Level.SEVERE, null, ex);
-                }
+            try {
+                return Files.probeContentType(file.toPath());
+            } catch (IOException ex) {
+                LOG.log(Level.SEVERE, null, ex);
             }
             return null;
         }
@@ -996,18 +988,10 @@
 
         @Override
         String findMimeType() {
-            if (file.getName().endsWith(".c")) {
-                return "text/x-c";
-            } else if (file.getName().endsWith(".R") || file.getName().endsWith(".r")) {
-                return "application/x-r";
-            } else if (file.getName().endsWith(".js") || file.getName().endsWith(".JS")) {
-                return "application/javascript";
-            } else {
-                try {
-                    return Files.probeContentType(file.toPath());
-                } catch (IOException ex) {
-                    LOG.log(Level.SEVERE, null, ex);
-                }
+            try {
+                return Files.probeContentType(file.toPath());
+            } catch (IOException ex) {
+                LOG.log(Level.SEVERE, null, ex);
             }
             return null;
         }
--- a/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java	Wed Sep 30 19:40:55 2015 -0700
@@ -40,16 +40,12 @@
  */
 package com.oracle.truffle.sl.test;
 
-import com.oracle.truffle.api.dsl.NodeFactory;
-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;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.net.URL;
 import java.nio.charset.Charset;
@@ -60,8 +56,13 @@
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
 import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.internal.TextListener;
 import org.junit.runner.Description;
 import org.junit.runner.JUnitCore;
@@ -73,6 +74,12 @@
 import org.junit.runners.ParentRunner;
 import org.junit.runners.model.InitializationError;
 
+import com.oracle.truffle.api.dsl.NodeFactory;
+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;
+
 public final class SLTestRunner extends ParentRunner<TestCase> {
 
     private static int repeats = 1;
@@ -174,30 +181,80 @@
         return foundCases;
     }
 
+    /**
+     * Recursively deletes a file that may represent a directory.
+     */
+    private static void delete(File f) {
+        if (f.isDirectory()) {
+            for (File c : f.listFiles()) {
+                delete(c);
+            }
+        }
+        if (!f.delete()) {
+            PrintStream err = System.err;
+            err.println("Failed to delete file: " + f);
+        }
+    }
+
+    /**
+     * Unpacks a jar file to a temporary directory that will be removed when the VM exits.
+     *
+     * @param jarfilePath the path of the jar to unpack
+     * @return the path of the temporary directory
+     */
+    private static String explodeJarToTempDir(File jarfilePath) {
+        try {
+            final Path jarfileDir = Files.createTempDirectory(jarfilePath.getName());
+            Runtime.getRuntime().addShutdownHook(new Thread() {
+                @Override
+                public void run() {
+                    delete(jarfileDir.toFile());
+                }
+            });
+            jarfileDir.toFile().deleteOnExit();
+            JarFile jarfile = new JarFile(jarfilePath);
+            Enumeration<JarEntry> entries = jarfile.entries();
+            while (entries.hasMoreElements()) {
+                JarEntry e = entries.nextElement();
+                if (!e.isDirectory()) {
+                    File path = new File(jarfileDir.toFile(), e.getName().replace('/', File.separatorChar));
+                    File dir = path.getParentFile();
+                    dir.mkdirs();
+                    assert dir.exists();
+                    Files.copy(jarfile.getInputStream(e), path.toPath());
+                }
+            }
+            return jarfileDir.toFile().getAbsolutePath();
+        } catch (IOException e) {
+            throw new AssertionError(e);
+        }
+    }
+
     public static Path getRootViaResourceURL(final Class<?> c, String[] paths) {
         URL url = c.getResource(c.getSimpleName() + ".class");
         if (url != null) {
             char sep = File.separatorChar;
             String externalForm = url.toExternalForm();
             String classPart = sep + c.getName().replace('.', sep) + ".class";
-            String suffix = null;
             String prefix = null;
+            String base;
             if (externalForm.startsWith("jar:file:")) {
                 prefix = "jar:file:";
-                suffix = sep + "build/truffle-sl.jar!" + classPart;
+                int bang = externalForm.indexOf('!', prefix.length());
+                Assume.assumeTrue(bang != -1);
+                File jarfilePath = new File(externalForm.substring(prefix.length(), bang));
+                Assume.assumeTrue(jarfilePath.exists());
+                base = explodeJarToTempDir(jarfilePath);
             } else if (externalForm.startsWith("file:")) {
                 prefix = "file:";
-                suffix = classPart;
+                base = externalForm.substring(prefix.length(), externalForm.length() - classPart.length());
             } else {
                 return null;
             }
-            if (externalForm.endsWith(suffix)) {
-                String base = externalForm.substring(prefix.length(), externalForm.length() - suffix.length());
-                for (String path : paths) {
-                    String candidate = base + sep + path;
-                    if (new File(candidate).exists()) {
-                        return FileSystems.getDefault().getPath(candidate);
-                    }
+            for (String path : paths) {
+                String candidate = base + sep + path;
+                if (new File(candidate).exists()) {
+                    return FileSystems.getDefault().getPath(candidate);
                 }
             }
         }
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java	Wed Sep 30 19:40:55 2015 -0700
@@ -58,7 +58,7 @@
  * same, the specializations already cover all possible cases that can return {@code true} and the
  * generic case is trivial.
  * <p>
- * Note that we do not need the analogous {@code =!} operator, because we can just
+ * Note that we do not need the analogous {@code !=} operator, because we can just
  * {@link SLLogicalNotNode negate} the {@code ==} operator.
  */
 @NodeInfo(shortName = "==")
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java	Wed Sep 30 19:40:55 2015 -0700
@@ -84,8 +84,7 @@
     }
 
     /**
-     * This is the generic case that always succeeds. Since we already have another specialization
-     * with the same signature above, we need to order them explicitly with the order attribute.
+     * This is the generic case that always succeeds.
      */
     @Specialization(contains = {"readLong", "readBoolean", "readObject"})
     protected Object read(VirtualFrame frame) {
--- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java	Wed Sep 30 19:40:55 2015 -0700
@@ -24,10 +24,6 @@
  */
 package com.oracle.truffle.tools.debug.shell.server;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 import com.oracle.truffle.api.debug.Breakpoint;
 import com.oracle.truffle.api.debug.Debugger;
 import com.oracle.truffle.api.debug.SuspendedEvent;
@@ -39,6 +35,10 @@
 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.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 public abstract class REPLServerContext {
 
@@ -65,6 +65,19 @@
     }
 
     /**
+     * Evaluates given code snippet in the context of currently suspended execution.
+     * 
+     * @param code the snippet to evaluate
+     * @param frame <code>null</code> in case the evaluation should happen in top most frame,
+     *            non-null value
+     * @return result of the evaluation
+     * @throws IOException if something goes wrong
+     */
+    public Object eval(String code, FrameInstance frame) throws IOException {
+        return event.eval(code, frame);
+    }
+
+    /**
      * The frame where execution is halted in this context.
      */
     public MaterializedFrame getFrameAtHalt() {
--- a/truffle/overview.html	Wed Sep 30 16:34:53 2015 -0700
+++ b/truffle/overview.html	Wed Sep 30 19:40:55 2015 -0700
@@ -39,7 +39,23 @@
 <p>
 To get the best speed out of your Truffle system, make sure you are running
 on top of 
-<a target="_top" href="http://openjdk.java.net/projects/graal/">Graal</a>
+<a target="_blank" href="http://openjdk.java.net/projects/graal/">Graal</a>
 virtual machine.
+<p>
+Our typicial sample language is called the <em>SimpleLanguage</em>.
+A good entry point for exploring <em>SimpleLanguage</em> is the
+<a target="_blank" href="https://github.com/graalvm/Truffle/blob/master/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java">SLLanguage</a>
+class.
+
+<h4>Other References</h4>
+
+<ul>
+  <li><a target="_blank" href="https://wiki.openjdk.java.net/display/Graal/Publications+and+Presentations">Truffle Tutorials and Presentations</a></li>
+  <li><a target="_blank" href="https://wiki.openjdk.java.net/display/Graal/Truffle+FAQ+and+Guidelines">Truffle FAQ and Guidelines</a></li>
+  <li><a target="_blank" href="http://www.oracle.com/technetwork/oracle-labs/program-languages/overview/index-2301583.html">Graal VM and Truffle/JS</a> on the Oracle Technology Network</li>
+  <li><a target="_blank" href="http://ssw.jku.at/Research/Projects/JVM/Truffle.html">Papers on Truffle</a></li>
+  <li><a target="_blank" href="http://ssw.jku.at/Research/Projects/JVM/Graal.html">Papers on Graal</a></li>
+</ul>
+
 </body>
 </html>