# HG changeset patch # User Michael Van De Vanter # Date 1443667255 25200 # Node ID b56fe0d3b5600fc702e942375c50d71c3c5a1b9a # Parent ebcb4878b0114cc36f5e629b3f8bbde1b105d966# Parent acfea340b19199faaa44bd5e103c716c17ea2b21 Merge with acfea340b19199faaa44bd5e103c716c17ea2b21 diff -r ebcb4878b011 -r b56fe0d3b560 .hgignore --- 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/ diff -r ebcb4878b011 -r b56fe0d3b560 CHANGELOG.md --- 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) diff -r ebcb4878b011 -r b56fe0d3b560 README.md --- 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 @@ -50,22 +94,10 @@ ``` -## 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 diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api.test/src/META-INF/services/java.nio.file.spi.FileTypeDetector --- /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 diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java --- 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); + } } diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/source/JavaRecognizer.java --- /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; + } +} diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java --- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/PolyglotEngine.java 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 @@ *
      * {@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()};
      * 
@@ -191,7 +191,7 @@ *
      * {@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()};
      * 
@@ -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 languageClazz) { + protected TruffleLanguage findLanguageImpl(Object obj, Class languageClazz) { final PolyglotEngine vm = (PolyglotEngine) obj; return vm.findLanguage(languageClazz); } diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java --- 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 true. + * + * @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. * diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java --- 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 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 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 diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java --- 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 diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java --- 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 null 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); + } } diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java 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 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 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 languageClass, String expr, AdvancedInstrumentResultListener resultListener) throws IOException { return API.createAdvancedInstrumentRootFactory(vm, languageClass, expr, resultListener); } + @SuppressWarnings("rawtypes") protected Class findLanguage(RootNode n) { return NODES.findLanguage(n); } + @SuppressWarnings("rawtypes") protected Class findLanguage(Probe probe) { return INSTRUMENT.findLanguage(probe); } + @SuppressWarnings("rawtypes") protected Env findLanguage(Object known, Class languageClass) { Object vm; if (known == null) { @@ -231,7 +242,8 @@ return SPI.findLanguage(vm, languageClass); } - protected TruffleLanguage findLanguageImpl(Object known, Class languageClass) { + @SuppressWarnings("rawtypes") + protected TruffleLanguage findLanguageImpl(Object known, Class languageClass) { Object vm; if (known == null) { vm = CURRENT_VM.get(); @@ -297,7 +309,7 @@ return oneVM; } - @SuppressWarnings({"unchecked"}) + @SuppressWarnings({"unchecked", "rawtypes"}) static C findContext(Class type) { Env env = SPI.findLanguage(CURRENT_VM.get(), type); return (C) API.findContext(env); diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java --- 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; } diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java --- 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; } diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java --- 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 { 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 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); } } } diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/expression/SLEqualNode.java --- 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. *

- * 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 = "==") diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/local/SLReadLocalVariableNode.java --- 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) { diff -r ebcb4878b011 -r b56fe0d3b560 truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java --- 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 null 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() { diff -r ebcb4878b011 -r b56fe0d3b560 truffle/overview.html --- 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 @@

To get the best speed out of your Truffle system, make sure you are running on top of -Graal +Graal virtual machine. +

+Our typicial sample language is called the SimpleLanguage. +A good entry point for exploring SimpleLanguage is the +SLLanguage +class. + +

Other References

+ + +