changeset 21890:894f82515e38

Truffle/APIs and Debugging: Evolutionary steps to integrating debugging and tool support with TruffleVM APIs - Add a version string to language registration: Language.getShortName() produces a string with both language and version - Rename SLMain --> SLLanguage (little change current machinery) - Remove DebugEngine dependence on ExecutionContext: Visualizer access migrated to TruffleLanguage - ExecutionContext now has only one method left: getCompilerOptions() - Rename SourceExecutionProvider to DebugSupportProvider, now supplied by implementing abstract TruffleLanguage.getDebugSupport() - Revise DebugEngine and its helper classes to work with the new APIs
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Tue, 09 Jun 2015 15:20:30 -0700
parents 45083be8a812
children ccaf9eb1f5eb
files graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugSupportException.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugSupportProvider.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ToolSupportProvider.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java graal/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java graal/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLServer.java graal/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLSourceExecutionProvider.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/factory/SLContextFactory.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTypes.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLDefaultVisualizer.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStandardASTProber.java graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugClient.java graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugEngine.java graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugException.java graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugExecutionSupport.java graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/LineBreakpointFactory.java graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/SourceExecutionProvider.java graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/TagBreakpointFactory.java graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/SimpleREPLClient.java graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java mx/mx_graal.py mx/suite.py
diffstat 33 files changed, 992 insertions(+), 789 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/processor/LanguageRegistrationTest.java	Tue Jun 09 15:20:30 2015 -0700
@@ -25,7 +25,9 @@
 import java.io.*;
 
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.debug.*;
 import com.oracle.truffle.api.dsl.test.*;
+import com.oracle.truffle.api.instrument.*;
 import com.oracle.truffle.api.source.*;
 
 public class LanguageRegistrationTest {
@@ -71,6 +73,17 @@
         protected boolean isObjectOfLanguage(Object object) {
             return false;
         }
+
+        @Override
+        protected ToolSupportProvider getToolSupport() {
+            return null;
+        }
+
+        @Override
+        protected DebugSupportProvider getDebugSupport() {
+            return null;
+        }
+
     }
 
     @ExpectError("Language must have a public constructor accepting TruffleLanguage.Env as parameter")
@@ -99,6 +112,17 @@
         protected boolean isObjectOfLanguage(Object object) {
             return false;
         }
+
+        @Override
+        protected ToolSupportProvider getToolSupport() {
+            return null;
+        }
+
+        @Override
+        protected DebugSupportProvider getDebugSupport() {
+            return null;
+        }
+
     }
 
     @TruffleLanguage.Registration(name = "myLangGood", version = "0", mimeType = "text/x-my")
@@ -126,5 +150,16 @@
         protected boolean isObjectOfLanguage(Object object) {
             return false;
         }
+
+        @Override
+        protected ToolSupportProvider getToolSupport() {
+            return null;
+        }
+
+        @Override
+        protected DebugSupportProvider getDebugSupport() {
+            return null;
+        }
+
     }
 }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/vm/ImplicitExplicitExportTest.java	Tue Jun 09 15:20:30 2015 -0700
@@ -22,18 +22,18 @@
  */
 package com.oracle.truffle.api.test.vm;
 
-import com.oracle.truffle.api.TruffleLanguage;
-import com.oracle.truffle.api.source.Source;
-import com.oracle.truffle.api.vm.TruffleVM;
-import java.io.IOException;
-import java.io.Reader;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
 import static org.junit.Assert.*;
-import org.junit.Before;
-import org.junit.Test;
+
+import java.io.*;
+import java.util.*;
+
+import org.junit.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.debug.*;
+import com.oracle.truffle.api.instrument.*;
+import com.oracle.truffle.api.source.*;
+import com.oracle.truffle.api.vm.*;
 
 public class ImplicitExplicitExportTest {
     private TruffleVM vm;
@@ -159,6 +159,16 @@
         protected boolean isObjectOfLanguage(Object object) {
             return false;
         }
+
+        @Override
+        protected ToolSupportProvider getToolSupport() {
+            return null;
+        }
+
+        @Override
+        protected DebugSupportProvider getDebugSupport() {
+            return null;
+        }
     }
 
     private static final String L1 = "application/x-test-import-export-1";
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/ExecutionContext.java	Tue Jun 09 15:20:30 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,44 +25,17 @@
 package com.oracle.truffle.api;
 
 import com.oracle.truffle.api.impl.*;
-import com.oracle.truffle.api.instrument.*;
-import com.oracle.truffle.api.instrument.impl.*;
 
 /**
  * Access to information and basic services in the runtime context for a Truffle-implemented guest
  * language.
- * <p>
- * <strong>Disclaimer:</strong> this class is under development and will change.
  */
 public abstract class ExecutionContext {
 
-    private Visualizer visualizer = new DefaultVisualizer();
-
     protected ExecutionContext() {
     }
 
     /**
-     * Access to information visualization services for the specific language.
-     */
-    public final Visualizer getVisualizer() {
-        return visualizer;
-    }
-
-    /**
-     * Assign guest language-specific visualization support for tools. This must be assigned outside
-     * the implementation context to avoid build circularities.
-     */
-    public final void setVisualizer(Visualizer visualizer) {
-        this.visualizer = visualizer;
-    }
-
-    /**
-     * Gets the name of the language, possibly with version number. in short enough form that it
-     * might be used for an interactive prompt.
-     */
-    public abstract String getLanguageShortName();
-
-    /**
      * Get compiler options specific to this <code>ExecutionContext</code>.
      */
     public CompilerOptions getCompilerOptions() {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java	Tue Jun 09 15:20:30 2015 -0700
@@ -28,7 +28,9 @@
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 
+import com.oracle.truffle.api.debug.*;
 import com.oracle.truffle.api.impl.*;
+import com.oracle.truffle.api.instrument.*;
 import com.oracle.truffle.api.source.*;
 import com.oracle.truffle.api.vm.*;
 import com.oracle.truffle.api.vm.TruffleVM.Language;
@@ -104,10 +106,10 @@
      * somebody asks for it (by calling this method).
      * <p>
      * The exported object can either be <code>TruffleObject</code> (e.g. a native object from the
-     * other language) to support inter-operability between languages, {@link String} or one of Java
+     * other language) to support interoperability between languages, {@link String} or one of Java
      * primitive wrappers ( {@link Integer}, {@link Double}, {@link Short}, {@link Boolean}, etc.).
      * <p>
-     * The way a symbol becomes <em>exported</em> is language dependant. In general it is preferred
+     * The way a symbol becomes <em>exported</em> is language dependent. In general it is preferred
      * to make the export explicit - e.g. call some function or method to register an object under
      * specific name. Some languages may however decide to support implicit export of symbols (for
      * example from global scope, if they have one). However explicit exports should always be
@@ -143,6 +145,10 @@
      */
     protected abstract boolean isObjectOfLanguage(Object object);
 
+    protected abstract ToolSupportProvider getToolSupport();
+
+    protected abstract DebugSupportProvider getDebugSupport();
+
     /**
      * Represents execution environment of the {@link TruffleLanguage}. Each active
      * {@link TruffleLanguage} receives instance of the environment before any code is executed upon
@@ -237,5 +243,16 @@
         protected Object languageGlobal(TruffleLanguage l) {
             return l.getLanguageGlobal();
         }
+
+        @Override
+        protected ToolSupportProvider getToolSupport(TruffleLanguage l) {
+            return l.getToolSupport();
+        }
+
+        @Override
+        protected DebugSupportProvider getDebugSupport(TruffleLanguage l) {
+            return l.getDebugSupport();
+        }
     }
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugSupportException.java	Tue Jun 09 15:20:30 2015 -0700
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 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.debug;
+
+public class DebugSupportException extends Exception {
+
+    private static final long serialVersionUID = 3039074861617372741L;
+
+    public DebugSupportException(String string) {
+        super(string);
+    }
+
+    public DebugSupportException(Exception ex) {
+        super(ex);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/DebugSupportProvider.java	Tue Jun 09 15:20:30 2015 -0700
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 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.debug;
+
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.instrument.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.source.*;
+
+/**
+ * Access to language-specific information and execution services to enable debugging.
+ */
+public interface DebugSupportProvider extends ToolSupportProvider {
+
+    /**
+     * Runs source code.
+     *
+     * @param source code
+     * @throws DebugSupportException if unable to run successfully
+     */
+    void run(Source source) throws DebugSupportException;
+
+    /**
+     * Runs source code in a halted execution context, or at top level.
+     *
+     * @param source the code to run
+     * @param node node where execution halted, {@code null} if no execution context
+     * @param mFrame frame where execution halted, {@code null} if no execution context
+     * @return result of running the code in the context, or at top level if no execution context.
+     * @throws DebugSupportException if the evaluation cannot be performed
+     */
+    Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws DebugSupportException;
+
+    /**
+     * Creates a language-specific factory to produce instances of {@link AdvancedInstrumentRoot}
+     * that, when executed, computes the result of a textual expression in the language; used to
+     * create an
+     * {@linkplain Instrument#create(AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String)
+     * Advanced Instrument}.
+     *
+     * @param expr a guest language expression
+     * @param resultListener optional listener for the result of each evaluation.
+     * @return a new factory
+     * @throws DebugSupportException if the factory cannot be created, for example if the expression
+     *             is badly formed.
+     */
+    AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws DebugSupportException;
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Tue Jun 09 15:20:30 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -29,6 +29,8 @@
 import java.util.*;
 
 import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.debug.*;
+import com.oracle.truffle.api.instrument.*;
 import com.oracle.truffle.api.source.*;
 import com.oracle.truffle.api.vm.*;
 
@@ -59,6 +61,16 @@
             protected boolean isObjectOfLanguage(Object object) {
                 return false;
             }
+
+            @Override
+            protected ToolSupportProvider getToolSupport() {
+                return null;
+            }
+
+            @Override
+            protected DebugSupportProvider getDebugSupport() {
+                return null;
+            }
         };
         lng.hashCode();
     }
@@ -97,6 +109,14 @@
         return API.languageGlobal(l);
     }
 
+    protected ToolSupportProvider getToolSupport(TruffleLanguage l) {
+        return API.getToolSupport(l);
+    }
+
+    protected DebugSupportProvider getDebugSupport(TruffleLanguage l) {
+        return API.getDebugSupport(l);
+    }
+
     protected Object invoke(Object obj, Object[] args) throws IOException {
         for (SymbolInvoker si : ServiceLoader.load(SymbolInvoker.class)) {
             return si.invoke(obj, args);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ToolSupportProvider.java	Tue Jun 09 15:20:30 2015 -0700
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 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.instrument;
+
+/**
+ * Access to language-specific information and execution services for external tools.
+ */
+public interface ToolSupportProvider {
+
+    /**
+     * Gets visualization services for language-specific information.
+     */
+    Visualizer getVisualizer();
+
+    /**
+     * Enables AST probing on all subsequently created ASTs (sources parsed).
+     *
+     * @param astProber optional AST prober to enable; the default for the language used if
+     *            {@code null}
+     */
+    void enableASTProbing(ASTProber astProber);
+
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Visualizer.java	Tue Jun 09 15:20:30 2015 -0700
@@ -61,11 +61,11 @@
 
     /**
      * Converts a value in the guest language to a display string. If
-     *
+     * 
      * @param trim if {@code > 0}, them limit size of String to either the value of trim or the
      *            number of characters in the first line, whichever is lower.
      */
-    String displayValue(ExecutionContext context, Object value, int trim);
+    String displayValue(Object value, int trim);
 
     /**
      * Converts a slot identifier in the guest language to a display string.
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/DefaultVisualizer.java	Tue Jun 09 15:20:30 2015 -0700
@@ -73,7 +73,7 @@
         return callTarget.toString();
     }
 
-    public String displayValue(ExecutionContext context, Object value, int trim) {
+    public String displayValue(Object value, int trim) {
         return trim(value.toString(), trim);
     }
 
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java	Tue Jun 09 15:20:30 2015 -0700
@@ -34,7 +34,9 @@
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.TruffleLanguage.Env;
 import com.oracle.truffle.api.TruffleLanguage.Registration;
+import com.oracle.truffle.api.debug.*;
 import com.oracle.truffle.api.impl.*;
+import com.oracle.truffle.api.instrument.*;
 import com.oracle.truffle.api.source.*;
 
 /**
@@ -416,6 +418,7 @@
         private final Properties props;
         private TruffleLanguage impl;
         private final String prefix;
+        private String shortName;
 
         Language(String prefix, Properties props) {
             this.prefix = prefix;
@@ -463,7 +466,18 @@
          * @return string describing the specific language version
          */
         public String getShortName() {
-            return getName() + getVersion();
+            if (shortName == null) {
+                shortName = getName() + "(" + getVersion() + ")";
+            }
+            return shortName;
+        }
+
+        public ToolSupportProvider getToolSupport() {
+            return SPI.getToolSupport(getImpl());
+        }
+
+        public DebugSupportProvider getDebugSupport() {
+            return SPI.getDebugSupport(getImpl());
         }
 
         TruffleLanguage getImpl() {
@@ -537,5 +551,15 @@
         public Object invoke(Object obj, Object[] args) throws IOException {
             return super.invoke(obj, args);
         }
+
+        @Override
+        public ToolSupportProvider getToolSupport(TruffleLanguage l) {
+            return super.getToolSupport(l);
+        }
+
+        @Override
+        public DebugSupportProvider getDebugSupport(TruffleLanguage l) {
+            return super.getDebugSupport(l);
+        }
     } // end of SPIAccessor
 }
--- a/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java	Tue Jun 09 15:20:30 2015 -0700
@@ -168,7 +168,7 @@
             TruffleVM vm = TruffleVM.newVM().stdIn(new BufferedReader(new StringReader(repeat(testCase.testInput, repeats)))).stdOut(printer).build();
 
             String script = readAllLines(testCase.path);
-            SLMain.run(vm, testCase.path.toUri(), null, printer, repeats, builtins);
+            SLLanguage.run(vm, testCase.path.toUri(), null, printer, repeats, builtins);
 
             printer.flush();
             String actualOutput = new String(out.toByteArray());
--- a/graal/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLServer.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLREPLServer.java	Tue Jun 09 15:20:30 2015 -0700
@@ -24,20 +24,18 @@
  */
 package com.oracle.truffle.sl.tools.debug;
 
-import java.io.*;
 import java.util.*;
 
-import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.instrument.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.source.*;
+import com.oracle.truffle.api.vm.*;
+import com.oracle.truffle.api.vm.TruffleVM.Language;
 import com.oracle.truffle.tools.debug.engine.*;
 import com.oracle.truffle.tools.debug.shell.*;
 import com.oracle.truffle.tools.debug.shell.client.*;
 import com.oracle.truffle.tools.debug.shell.server.*;
-import com.oracle.truffle.sl.factory.*;
-import com.oracle.truffle.sl.runtime.*;
 
 /**
  * Instantiation of the "server" side of the "REPL*" debugger for the Simple language.
@@ -49,10 +47,11 @@
  * @see SimpleREPLClient
  */
 public final class SLREPLServer implements REPLServer {
+
     public static void main(String[] args) {
         // Cheating for the prototype: start from SL, rather than from the client.
         final SLREPLServer server = new SLREPLServer();
-        final SimpleREPLClient client = new SimpleREPLClient(server.slContext, server);
+        final SimpleREPLClient client = new SimpleREPLClient(server.language.getShortName(), server);
 
         // Cheating for the prototype: allow server access to client for recursive debugging
         server.setClient(client);
@@ -63,7 +62,7 @@
         }
     }
 
-    private final SLContext slContext;
+    private final Language language;
     private final DebugEngine slDebugEngine;
     private final String statusPrefix;
     private final Map<String, REPLHandler> handlerMap = new HashMap<>();
@@ -99,13 +98,14 @@
         add(REPLHandler.TRUFFLE_HANDLER);
         add(REPLHandler.TRUFFLE_NODE_HANDLER);
 
-        // Set up an SL context
-        this.slContext = SLContextFactory.create(null, new PrintWriter(System.out));
+        TruffleVM vm = TruffleVM.newVM().build();
+        this.language = vm.getLanguages().get("application/x-sl");
+        assert language != null;
 
-        final SLSourceExecutionProvider slSourceExecution = new SLSourceExecutionProvider(slContext);
-        final SLREPLDebugClient slDebugClient = new SLREPLDebugClient(this.slContext);
-        this.slDebugEngine = DebugEngine.create(slDebugClient, slSourceExecution);
-        this.statusPrefix = slContext.getLanguageShortName() + " REPL:";
+        final SLREPLDebugClient slDebugClient = new SLREPLDebugClient(language);
+        this.slDebugEngine = DebugEngine.create(slDebugClient, language);
+
+        this.statusPrefix = language.getShortName() + " REPL:";
     }
 
     private void setClient(SimpleREPLClient replClient) {
@@ -119,7 +119,7 @@
         // SL doesn't load modules (like other languages), so we just return a success
         final REPLMessage reply = new REPLMessage();
         reply.put(REPLMessage.STATUS, REPLMessage.SUCCEEDED);
-        reply.put(REPLMessage.DISPLAY_MSG, slContext.getLanguageShortName() + " started");
+        reply.put(REPLMessage.DISPLAY_MSG, language.getShortName() + " started");
         return reply;
     }
 
@@ -163,8 +163,8 @@
         }
 
         @Override
-        public SLContext getLanguageContext() {
-            return slContext;
+        public Language getLanguage() {
+            return language;
         }
 
         @Override
@@ -186,10 +186,10 @@
      */
     private final class SLREPLDebugClient implements DebugClient {
 
-        private final SLContext slContext;
+        private final Language language;
 
-        SLREPLDebugClient(SLContext slContext) {
-            this.slContext = slContext;
+        SLREPLDebugClient(Language language) {
+            this.language = language;
         }
 
         public void haltedAt(Node node, MaterializedFrame mFrame, List<String> warnings) {
@@ -225,8 +225,8 @@
             }
         }
 
-        public ExecutionContext getExecutionContext() {
-            return slContext;
+        public Language getLanguage() {
+            return language;
         }
     }
 
--- a/graal/com.oracle.truffle.sl.tools/src/com/oracle/truffle/sl/tools/debug/SLSourceExecutionProvider.java	Fri Jun 05 18:05:13 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * 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.sl.tools.debug;
-
-import java.io.*;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.instrument.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.source.*;
-import com.oracle.truffle.sl.*;
-import com.oracle.truffle.sl.nodes.instrument.*;
-import com.oracle.truffle.sl.runtime.*;
-import com.oracle.truffle.tools.debug.engine.*;
-
-/**
- * Specialization of the Truffle debugging engine for the Simple language. The engine implements
- * basic debugging operations during Truffle-based execution.
- */
-public final class SLSourceExecutionProvider extends SourceExecutionProvider {
-
-    @SuppressWarnings("unused") private final SLContext slContext;
-
-    public SLSourceExecutionProvider(SLContext context) {
-        this.slContext = context;
-        Probe.registerASTProber(new SLStandardASTProber());
-    }
-
-    @Override
-    public void languageRun(Source source) {
-        try {
-            SLMain.run(source);
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * The implementation of Simple is too, well, simple to support eval. Just for starters, the
-     * parser can only produce a whole program.
-     */
-    @Override
-    public Object languageEval(Source source, Node node, MaterializedFrame mFrame) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * The implementation of Simple is too, well, simple to support this. Just for starters, the
-     * parser can only produce a whole program.
-     */
-    @Override
-    public AdvancedInstrumentRootFactory languageAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws DebugException {
-        throw new UnsupportedOperationException();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java	Tue Jun 09 15:20:30 2015 -0700
@@ -0,0 +1,492 @@
+/*
+ * 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.sl;
+
+import java.io.*;
+import java.math.*;
+import java.net.*;
+import java.util.*;
+import java.util.Scanner;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.debug.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.instrument.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.source.*;
+import com.oracle.truffle.api.vm.*;
+import com.oracle.truffle.api.vm.TruffleVM.Symbol;
+import com.oracle.truffle.sl.builtins.*;
+import com.oracle.truffle.sl.factory.*;
+import com.oracle.truffle.sl.nodes.*;
+import com.oracle.truffle.sl.nodes.call.*;
+import com.oracle.truffle.sl.nodes.controlflow.*;
+import com.oracle.truffle.sl.nodes.expression.*;
+import com.oracle.truffle.sl.nodes.instrument.*;
+import com.oracle.truffle.sl.nodes.local.*;
+import com.oracle.truffle.sl.parser.*;
+import com.oracle.truffle.sl.runtime.*;
+import com.oracle.truffle.tools.*;
+
+/**
+ * SL is a simple language to demonstrate and showcase features of Truffle. The implementation is as
+ * simple and clean as possible in order to help understanding the ideas and concepts of Truffle.
+ * The language has first class functions, but no object model.
+ * <p>
+ * SL is dynamically typed, i.e., there are no type names specified by the programmer. SL is
+ * strongly typed, i.e., there is no automatic conversion between types. If an operation is not
+ * available for the types encountered at run time, a type error is reported and execution is
+ * stopped. For example, {@code 4 - "2"} results in a type error because subtraction is only defined
+ * for numbers.
+ *
+ * <p>
+ * <b>Types:</b>
+ * <ul>
+ * <li>Number: arbitrary precision integer numbers. The implementation uses the Java primitive type
+ * {@code long} to represent numbers that fit into the 64 bit range, and {@link BigInteger} for
+ * numbers that exceed the range. Using a primitive type such as {@code long} is crucial for
+ * performance.
+ * <li>Boolean: implemented as the Java primitive type {@code boolean}.
+ * <li>String: implemented as the Java standard type {@link String}.
+ * <li>Function: implementation type {@link SLFunction}.
+ * <li>Null (with only one value {@code null}): implemented as the singleton
+ * {@link SLNull#SINGLETON}.
+ * </ul>
+ * The class {@link SLTypes} lists these types for the Truffle DSL, i.e., for type-specialized
+ * operations that are specified using Truffle DSL annotations.
+ *
+ * <p>
+ * <b>Language concepts:</b>
+ * <ul>
+ * <li>Literals for {@link SLBigIntegerLiteralNode numbers} , {@link SLStringLiteralNode strings},
+ * and {@link SLFunctionLiteralNode functions}.
+ * <li>Basic arithmetic, logical, and comparison operations: {@link SLAddNode +}, {@link SLSubNode
+ * -}, {@link SLMulNode *}, {@link SLDivNode /}, {@link SLLogicalAndNode logical and},
+ * {@link SLLogicalOrNode logical or}, {@link SLEqualNode ==}, !=, {@link SLLessThanNode &lt;},
+ * {@link SLLessOrEqualNode &le;}, &gt;, &ge;.
+ * <li>Local variables: local variables must be defined (via a {@link SLWriteLocalVariableNode
+ * write}) before they can be used (by a {@link SLReadLocalVariableNode read}). Local variables are
+ * not visible outside of the block where they were first defined.
+ * <li>Basic control flow statements: {@link SLBlockNode blocks}, {@link SLIfNode if},
+ * {@link SLWhileNode while} with {@link SLBreakNode break} and {@link SLContinueNode continue},
+ * {@link SLReturnNode return}.
+ * <li>Function calls: {@link SLInvokeNode invocations} are efficiently implemented with
+ * {@link SLDispatchNode polymorphic inline caches}.
+ * </ul>
+ *
+ * <p>
+ * <b>Syntax and parsing:</b><br>
+ * The syntax is described as an attributed grammar. The {@link Parser} and {@link Scanner} are
+ * automatically generated by the parser generator Coco/R (available from <a
+ * href="http://ssw.jku.at/coco/">http://ssw.jku.at/coco/</a>). The grammar contains semantic
+ * actions that build the AST for a method. To keep these semantic actions short, they are mostly
+ * calls to the {@link SLNodeFactory} that performs the actual node creation. All functions found in
+ * the SL source are added to the {@link SLFunctionRegistry}, which is accessible from the
+ * {@link SLContext}.
+ *
+ * <p>
+ * <b>Builtin functions:</b><br>
+ * Library functions that are available to every SL source without prior definition are called
+ * builtin functions. They are added to the {@link SLFunctionRegistry} when the {@link SLContext} is
+ * created. There current builtin functions are
+ * <ul>
+ * <li>{@link SLReadlnBuiltin readln}: Read a String from the {@link SLContext#getInput() standard
+ * input}.
+ * <li>{@link SLPrintlnBuiltin println}: Write a value to the {@link SLContext#getOutput() standard
+ * output}.
+ * <li>{@link SLNanoTimeBuiltin nanoTime}: Returns the value of a high-resolution time, in
+ * nanoseconds.
+ * <li>{@link SLDefineFunctionBuiltin defineFunction}: Parses the functions provided as a String
+ * argument and adds them to the function registry. Functions that are already defined are replaced
+ * with the new version.
+ * </ul>
+ *
+ * <p>
+ * <b>Tools:</b><br>
+ * The use of some of Truffle's support for developer tools (based on the Truffle Instrumentation
+ * Framework) are demonstrated in this file, for example:
+ * <ul>
+ * <li>a {@linkplain NodeExecCounter counter for node executions}, tabulated by node type; and</li>
+ * <li>a simple {@linkplain CoverageTracker code coverage engine}.</li>
+ * </ul>
+ * In each case, the tool is enabled if a corresponding local boolean variable in this file is set
+ * to {@code true}. Results are printed at the end of the execution using each tool's
+ * <em>default printer</em>.
+ *
+ */
+@TruffleLanguage.Registration(name = "SL", version = "0.5", mimeType = "application/x-sl")
+public class SLLanguage extends TruffleLanguage {
+    private static SLLanguage LAST;
+    private static List<NodeFactory<? extends SLBuiltinNode>> builtins = Collections.emptyList();
+    private static Visualizer visualizer = new SLDefaultVisualizer();
+    private static ASTProber registeredASTProber; // non-null if prober already registered
+    private final SLContext context;
+    private DebugSupportProvider debugSupport;
+
+    public SLLanguage(Env env) {
+        super(env);
+        context = SLContextFactory.create(new BufferedReader(env().stdIn()), new PrintWriter(env().stdOut(), true));
+        LAST = this;
+        for (NodeFactory<? extends SLBuiltinNode> builtin : builtins) {
+            context.installBuiltin(builtin);
+        }
+    }
+
+    // TODO (mlvdv) command line options
+    /* Enables demonstration of per-type tabulation of node execution counts */
+    private static boolean nodeExecCounts = false;
+    /* Enables demonstration of per-line tabulation of STATEMENT node execution counts */
+    private static boolean statementCounts = false;
+    /* Enables demonstration of per-line tabulation of STATEMENT coverage */
+    private static boolean coverage = false;
+
+    /* Small tools that can be installed for demonstration */
+    private static NodeExecCounter nodeExecCounter = null;
+    private static NodeExecCounter statementExecCounter = null;
+    private static CoverageTracker coverageTracker = null;
+
+    /**
+     * 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();
+        assert vm.getLanguages().containsKey("application/x-sl");
+
+        setupToolDemos();
+
+        int repeats = 1;
+        if (args.length >= 2) {
+            repeats = Integer.parseInt(args[1]);
+        }
+
+        if (args.length == 0) {
+            vm.eval("application/x-sl", new InputStreamReader(System.in));
+        } else {
+            vm.eval(new File(args[0]).toURI());
+        }
+        Symbol main = vm.findGlobalSymbol("main");
+        if (main == null) {
+            throw new SLException("No function main() defined in SL source file.");
+        }
+        while (repeats-- > 0) {
+            main.invoke(null);
+        }
+        reportToolDemos();
+    }
+
+    /**
+     * Temporary method during API evolution, supports debugger integration.
+     */
+    public static void run(Source source) throws IOException {
+        TruffleVM vm = TruffleVM.newVM().build();
+        assert vm.getLanguages().containsKey("application/x-sl");
+        vm.eval(new File(source.getPath()).toURI());
+        Symbol main = vm.findGlobalSymbol("main");
+        if (main == null) {
+            throw new SLException("No function main() defined in SL source file.");
+        }
+        main.invoke(null);
+    }
+
+    /**
+     * 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, URI source, PrintWriter logOutput, PrintWriter out, int repeats, List<NodeFactory<? extends SLBuiltinNode>> currentBuiltins) throws IOException {
+        builtins = currentBuiltins;
+
+        if (logOutput != null) {
+            logOutput.println("== running on " + Truffle.getRuntime().getName());
+            // logOutput.println("Source = " + source.getCode());
+        }
+
+        /* Parse the SL source file. */
+        Object result = context.eval(source);
+        if (result != null) {
+            out.println(result);
+        }
+
+        /* Lookup our main entry point, which is per definition always named "main". */
+        Symbol main = context.findGlobalSymbol("main");
+        if (main == null) {
+            throw new SLException("No function main() defined in SL source file.");
+        }
+
+        /* Change to true if you want to see the AST on the console. */
+        boolean printASTToLog = false;
+        /* Change to true if you want to see source attribution for the AST to the console */
+        boolean printSourceAttributionToLog = false;
+        /* Change to dump the AST to IGV over the network. */
+        boolean dumpASTToIGV = false;
+
+        printScript("before execution", LAST.context, logOutput, printASTToLog, printSourceAttributionToLog, dumpASTToIGV);
+        long totalRuntime = 0;
+        try {
+            for (int i = 0; i < repeats; i++) {
+                long start = System.nanoTime();
+                /* Call the main entry point, without any arguments. */
+                try {
+                    result = main.invoke(null);
+                    if (result != null) {
+                        out.println(result);
+                    }
+                } catch (UnsupportedSpecializationException ex) {
+                    out.println(formatTypeError(ex));
+                } catch (SLUndefinedFunctionException ex) {
+                    out.println(String.format("Undefined function: %s", ex.getFunctionName()));
+                }
+                long end = System.nanoTime();
+                totalRuntime += end - start;
+
+                if (logOutput != null && repeats > 1) {
+                    logOutput.println("== iteration " + (i + 1) + ": " + ((end - start) / 1000000) + " ms");
+                }
+            }
+
+        } finally {
+            printScript("after execution", LAST.context, logOutput, printASTToLog, printSourceAttributionToLog, dumpASTToIGV);
+        }
+        return totalRuntime;
+    }
+
+    /**
+     * When dumpASTToIGV is true: dumps the AST of all functions to the IGV visualizer, via a socket
+     * connection. IGV can be started with the mx command "mx igv".
+     * <p>
+     * When printASTToLog is true: prints the ASTs to the console.
+     */
+    private static void printScript(String groupName, SLContext context, PrintWriter logOutput, boolean printASTToLog, boolean printSourceAttributionToLog, boolean dumpASTToIGV) {
+        if (dumpASTToIGV) {
+            GraphPrintVisitor graphPrinter = new GraphPrintVisitor();
+            graphPrinter.beginGroup(groupName);
+            for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
+                RootCallTarget callTarget = function.getCallTarget();
+                if (callTarget != null) {
+                    graphPrinter.beginGraph(function.toString()).visit(callTarget.getRootNode());
+                }
+            }
+            graphPrinter.printToNetwork(true);
+        }
+        if (printASTToLog && logOutput != null) {
+            for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
+                RootCallTarget callTarget = function.getCallTarget();
+                if (callTarget != null) {
+                    logOutput.println("=== " + function);
+                    NodeUtil.printTree(logOutput, callTarget.getRootNode());
+                }
+            }
+        }
+        if (printSourceAttributionToLog && logOutput != null) {
+            for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
+                RootCallTarget callTarget = function.getCallTarget();
+                if (callTarget != null) {
+                    logOutput.println("=== " + function);
+                    NodeUtil.printSourceAttributionTree(logOutput, callTarget.getRootNode());
+                }
+            }
+        }
+    }
+
+    /**
+     * Provides a user-readable message for run-time type errors. SL is strongly typed, i.e., there
+     * are no automatic type conversions of values. Therefore, Truffle does the type checking for
+     * us: if no matching node specialization for the actual values is found, then we have a type
+     * error. Specialized nodes use the {@link UnsupportedSpecializationException} to report that no
+     * specialization was found. We therefore just have to convert the information encapsulated in
+     * this exception in a user-readable form.
+     */
+    private static String formatTypeError(UnsupportedSpecializationException ex) {
+        StringBuilder result = new StringBuilder();
+        result.append("Type error");
+        if (ex.getNode() != null && ex.getNode().getSourceSection() != null) {
+            SourceSection ss = ex.getNode().getSourceSection();
+            if (ss != null && !(ss instanceof NullSourceSection)) {
+                result.append(" at ").append(ss.getSource().getShortName()).append(" line ").append(ss.getStartLine()).append(" col ").append(ss.getStartColumn());
+            }
+        }
+        result.append(": operation");
+        if (ex.getNode() != null) {
+            NodeInfo nodeInfo = SLContext.lookupNodeInfo(ex.getNode().getClass());
+            if (nodeInfo != null) {
+                result.append(" \"").append(nodeInfo.shortName()).append("\"");
+            }
+        }
+        result.append(" not defined for");
+
+        String sep = " ";
+        for (int i = 0; i < ex.getSuppliedValues().length; i++) {
+            Object value = ex.getSuppliedValues()[i];
+            Node node = ex.getSuppliedNodes()[i];
+            if (node != null) {
+                result.append(sep);
+                sep = ", ";
+
+                if (value instanceof Long || value instanceof BigInteger) {
+                    result.append("Number ").append(value);
+                } else if (value instanceof Boolean) {
+                    result.append("Boolean ").append(value);
+                } else if (value instanceof String) {
+                    result.append("String \"").append(value).append("\"");
+                } else if (value instanceof SLFunction) {
+                    result.append("Function ").append(value);
+                } else if (value == SLNull.SINGLETON) {
+                    result.append("NULL");
+                } else if (value == null) {
+                    // value is not evaluated because of short circuit evaluation
+                    result.append("ANY");
+                } else {
+                    result.append(value);
+                }
+            }
+        }
+        return result.toString();
+    }
+
+    @Override
+    protected Object eval(Source code) throws IOException {
+        try {
+            context.evalSource(code);
+        } catch (Exception e) {
+            throw new IOException(e);
+        }
+        return null;
+    }
+
+    @Override
+    protected Object findExportedSymbol(String globalName, boolean onlyExplicit) {
+        for (SLFunction f : context.getFunctionRegistry().getFunctions()) {
+            if (globalName.equals(f.getName())) {
+                return f;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    protected Object getLanguageGlobal() {
+        return context;
+    }
+
+    @Override
+    protected boolean isObjectOfLanguage(Object object) {
+        return object instanceof SLFunction;
+    }
+
+    @Override
+    protected ToolSupportProvider getToolSupport() {
+        return getDebugSupport();
+    }
+
+    @Override
+    protected DebugSupportProvider getDebugSupport() {
+        if (debugSupport == null) {
+            debugSupport = new SLDebugProvider();
+        }
+        return debugSupport;
+    }
+
+    // TODO (mlvdv) remove the static hack when we no longer have the static demo variables
+    private static void setupToolDemos() {
+        if (statementCounts || coverage) {
+            if (registeredASTProber == null) {
+                registeredASTProber = new SLStandardASTProber();
+                // This should be registered on the TruffleVM
+                Probe.registerASTProber(registeredASTProber);
+            }
+        }
+        if (nodeExecCounts) {
+            nodeExecCounter = new NodeExecCounter();
+            nodeExecCounter.install();
+        }
+
+        if (statementCounts) {
+            statementExecCounter = new NodeExecCounter(StandardSyntaxTag.STATEMENT);
+            statementExecCounter.install();
+        }
+
+        if (coverage) {
+            coverageTracker = new CoverageTracker();
+            coverageTracker.install();
+        }
+    }
+
+    private static void reportToolDemos() {
+        if (nodeExecCounter != null) {
+            nodeExecCounter.print(System.out);
+            nodeExecCounter.dispose();
+        }
+        if (statementExecCounter != null) {
+            statementExecCounter.print(System.out);
+            statementExecCounter.dispose();
+        }
+        if (coverageTracker != null) {
+            coverageTracker.print(System.out);
+            coverageTracker.dispose();
+        }
+    }
+
+    private final class SLDebugProvider implements DebugSupportProvider {
+
+        public SLDebugProvider() {
+            if (registeredASTProber == null) {
+                registeredASTProber = new SLStandardASTProber();
+                // This should be registered on the TruffleVM
+                Probe.registerASTProber(registeredASTProber);
+            }
+        }
+
+        public Visualizer getVisualizer() {
+            if (visualizer == null) {
+                visualizer = new SLDefaultVisualizer();
+            }
+            return visualizer;
+        }
+
+        public void enableASTProbing(ASTProber prober) {
+            if (prober != null) {
+                // This should be registered on the TruffleVM
+                Probe.registerASTProber(prober);
+            }
+        }
+
+        public void run(Source source) throws DebugSupportException {
+            // TODO (mlvdv) fix to run properly in the current VM
+            try {
+                SLLanguage.run(source);
+            } catch (Exception e) {
+                throw new DebugSupportException(e);
+            }
+        }
+
+        public Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws DebugSupportException {
+            throw new DebugSupportException("evalInContext not supported in this language");
+        }
+
+        public AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws DebugSupportException {
+            throw new DebugSupportException("createAdvancedInstrumentRootFactory not supported in this language");
+        }
+
+    }
+
+}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLMain.java	Fri Jun 05 18:05:13 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,425 +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.sl;
-
-import java.io.*;
-import java.math.*;
-import java.net.*;
-import java.util.*;
-import java.util.Scanner;
-
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.instrument.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.source.*;
-import com.oracle.truffle.api.vm.*;
-import com.oracle.truffle.api.vm.TruffleVM.Symbol;
-import com.oracle.truffle.sl.builtins.*;
-import com.oracle.truffle.sl.factory.*;
-import com.oracle.truffle.sl.nodes.*;
-import com.oracle.truffle.sl.nodes.call.*;
-import com.oracle.truffle.sl.nodes.controlflow.*;
-import com.oracle.truffle.sl.nodes.expression.*;
-import com.oracle.truffle.sl.nodes.instrument.*;
-import com.oracle.truffle.sl.nodes.local.*;
-import com.oracle.truffle.sl.parser.*;
-import com.oracle.truffle.sl.runtime.*;
-import com.oracle.truffle.tools.*;
-
-/**
- * SL is a simple language to demonstrate and showcase features of Truffle. The implementation is as
- * simple and clean as possible in order to help understanding the ideas and concepts of Truffle.
- * The language has first class functions, but no object model.
- * <p>
- * SL is dynamically typed, i.e., there are no type names specified by the programmer. SL is
- * strongly typed, i.e., there is no automatic conversion between types. If an operation is not
- * available for the types encountered at run time, a type error is reported and execution is
- * stopped. For example, {@code 4 - "2"} results in a type error because subtraction is only defined
- * for numbers.
- *
- * <p>
- * <b>Types:</b>
- * <ul>
- * <li>Number: arbitrary precision integer numbers. The implementation uses the Java primitive type
- * {@code long} to represent numbers that fit into the 64 bit range, and {@link BigInteger} for
- * numbers that exceed the range. Using a primitive type such as {@code long} is crucial for
- * performance.
- * <li>Boolean: implemented as the Java primitive type {@code boolean}.
- * <li>String: implemented as the Java standard type {@link String}.
- * <li>Function: implementation type {@link SLFunction}.
- * <li>Null (with only one value {@code null}): implemented as the singleton
- * {@link SLNull#SINGLETON}.
- * </ul>
- * The class {@link SLTypes} lists these types for the Truffle DSL, i.e., for type-specialized
- * operations that are specified using Truffle DSL annotations.
- *
- * <p>
- * <b>Language concepts:</b>
- * <ul>
- * <li>Literals for {@link SLBigIntegerLiteralNode numbers} , {@link SLStringLiteralNode strings},
- * and {@link SLFunctionLiteralNode functions}.
- * <li>Basic arithmetic, logical, and comparison operations: {@link SLAddNode +}, {@link SLSubNode
- * -}, {@link SLMulNode *}, {@link SLDivNode /}, {@link SLLogicalAndNode logical and},
- * {@link SLLogicalOrNode logical or}, {@link SLEqualNode ==}, !=, {@link SLLessThanNode &lt;},
- * {@link SLLessOrEqualNode &le;}, &gt;, &ge;.
- * <li>Local variables: local variables must be defined (via a {@link SLWriteLocalVariableNode
- * write}) before they can be used (by a {@link SLReadLocalVariableNode read}). Local variables are
- * not visible outside of the block where they were first defined.
- * <li>Basic control flow statements: {@link SLBlockNode blocks}, {@link SLIfNode if},
- * {@link SLWhileNode while} with {@link SLBreakNode break} and {@link SLContinueNode continue},
- * {@link SLReturnNode return}.
- * <li>Function calls: {@link SLInvokeNode invocations} are efficiently implemented with
- * {@link SLDispatchNode polymorphic inline caches}.
- * </ul>
- *
- * <p>
- * <b>Syntax and parsing:</b><br>
- * The syntax is described as an attributed grammar. The {@link Parser} and {@link Scanner} are
- * automatically generated by the parser generator Coco/R (available from <a
- * href="http://ssw.jku.at/coco/">http://ssw.jku.at/coco/</a>). The grammar contains semantic
- * actions that build the AST for a method. To keep these semantic actions short, they are mostly
- * calls to the {@link SLNodeFactory} that performs the actual node creation. All functions found in
- * the SL source are added to the {@link SLFunctionRegistry}, which is accessible from the
- * {@link SLContext}.
- *
- * <p>
- * <b>Builtin functions:</b><br>
- * Library functions that are available to every SL source without prior definition are called
- * builtin functions. They are added to the {@link SLFunctionRegistry} when the {@link SLContext} is
- * created. There current builtin functions are
- * <ul>
- * <li>{@link SLReadlnBuiltin readln}: Read a String from the {@link SLContext#getInput() standard
- * input}.
- * <li>{@link SLPrintlnBuiltin println}: Write a value to the {@link SLContext#getOutput() standard
- * output}.
- * <li>{@link SLNanoTimeBuiltin nanoTime}: Returns the value of a high-resolution time, in
- * nanoseconds.
- * <li>{@link SLDefineFunctionBuiltin defineFunction}: Parses the functions provided as a String
- * argument and adds them to the function registry. Functions that are already defined are replaced
- * with the new version.
- * </ul>
- *
- * <p>
- * <b>Tools:</b><br>
- * The use of some of Truffle's support for developer tools (based on the Truffle Instrumentation
- * Framework) are demonstrated in this file, for example:
- * <ul>
- * <li>a {@linkplain NodeExecCounter counter for node executions}, tabulated by node type; and</li>
- * <li>a simple {@linkplain CoverageTracker code coverage engine}.</li>
- * </ul>
- * In each case, the tool is enabled if a corresponding local boolean variable in this file is set
- * to {@code true}. Results are printed at the end of the execution using each tool's
- * <em>default printer</em>.
- *
- */
-@TruffleLanguage.Registration(name = "sl", version = "0.5", mimeType = "application/x-sl")
-public class SLMain extends TruffleLanguage {
-    private static SLMain LAST;
-    private static List<NodeFactory<? extends SLBuiltinNode>> builtins = Collections.emptyList();
-    private final SLContext context;
-
-    public SLMain(Env env) {
-        super(env);
-        context = SLContextFactory.create(new BufferedReader(env().stdIn()), new PrintWriter(env().stdOut(), true));
-        LAST = this;
-        for (NodeFactory<? extends SLBuiltinNode> builtin : builtins) {
-            context.installBuiltin(builtin);
-        }
-    }
-
-    /* Enables demonstration of per-type tabulation of node execution counts */
-    private static boolean nodeExecCounts = false;
-    /* Enables demonstration of per-line tabulation of STATEMENT node execution counts */
-    private static boolean statementCounts = false;
-    /* Enables demonstration of er-line tabulation of STATEMENT coverage */
-    private static boolean coverage = false;
-
-    /* Small tools that can be installed for demonstration */
-    private static NodeExecCounter nodeExecCounter = null;
-    private static NodeExecCounter statementExecCounter = null;
-    private static CoverageTracker coverageTracker = null;
-
-    /**
-     * 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();
-        assert vm.getLanguages().containsKey("application/x-sl");
-
-        setupToolDemos();
-
-        int repeats = 1;
-        if (args.length >= 2) {
-            repeats = Integer.parseInt(args[1]);
-        }
-
-        if (args.length == 0) {
-            vm.eval("application/x-sl", new InputStreamReader(System.in));
-        } else {
-            vm.eval(new File(args[0]).toURI());
-        }
-        Symbol main = vm.findGlobalSymbol("main");
-        if (main == null) {
-            throw new SLException("No function main() defined in SL source file.");
-        }
-        while (repeats-- > 0) {
-            main.invoke(null);
-        }
-        reportToolDemos();
-    }
-
-    /**
-     * Temporary method during API evolution, supports debugger integration.
-     */
-    public static void run(Source source) throws IOException {
-        TruffleVM vm = TruffleVM.newVM().build();
-        assert vm.getLanguages().containsKey("application/x-sl");
-        vm.eval(new File(source.getPath()).toURI());
-        Symbol main = vm.findGlobalSymbol("main");
-        if (main == null) {
-            throw new SLException("No function main() defined in SL source file.");
-        }
-        main.invoke(null);
-    }
-
-    /**
-     * 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, URI source, PrintWriter logOutput, PrintWriter out, int repeats, List<NodeFactory<? extends SLBuiltinNode>> currentBuiltins) throws IOException {
-        builtins = currentBuiltins;
-
-        if (logOutput != null) {
-            logOutput.println("== running on " + Truffle.getRuntime().getName());
-            // logOutput.println("Source = " + source.getCode());
-        }
-
-        /* Parse the SL source file. */
-        Object result = context.eval(source);
-        if (result != null) {
-            out.println(result);
-        }
-
-        /* Lookup our main entry point, which is per definition always named "main". */
-        Symbol main = context.findGlobalSymbol("main");
-        if (main == null) {
-            throw new SLException("No function main() defined in SL source file.");
-        }
-
-        /* Change to true if you want to see the AST on the console. */
-        boolean printASTToLog = false;
-        /* Change to true if you want to see source attribution for the AST to the console */
-        boolean printSourceAttributionToLog = false;
-        /* Change to dump the AST to IGV over the network. */
-        boolean dumpASTToIGV = false;
-
-        printScript("before execution", LAST.context, logOutput, printASTToLog, printSourceAttributionToLog, dumpASTToIGV);
-        long totalRuntime = 0;
-        try {
-            for (int i = 0; i < repeats; i++) {
-                long start = System.nanoTime();
-                /* Call the main entry point, without any arguments. */
-                try {
-                    result = main.invoke(null);
-                    if (result != null) {
-                        out.println(result);
-                    }
-                } catch (UnsupportedSpecializationException ex) {
-                    out.println(formatTypeError(ex));
-                } catch (SLUndefinedFunctionException ex) {
-                    out.println(String.format("Undefined function: %s", ex.getFunctionName()));
-                }
-                long end = System.nanoTime();
-                totalRuntime += end - start;
-
-                if (logOutput != null && repeats > 1) {
-                    logOutput.println("== iteration " + (i + 1) + ": " + ((end - start) / 1000000) + " ms");
-                }
-            }
-
-        } finally {
-            printScript("after execution", LAST.context, logOutput, printASTToLog, printSourceAttributionToLog, dumpASTToIGV);
-        }
-        return totalRuntime;
-    }
-
-    /**
-     * When dumpASTToIGV is true: dumps the AST of all functions to the IGV visualizer, via a socket
-     * connection. IGV can be started with the mx command "mx igv".
-     * <p>
-     * When printASTToLog is true: prints the ASTs to the console.
-     */
-    private static void printScript(String groupName, SLContext context, PrintWriter logOutput, boolean printASTToLog, boolean printSourceAttributionToLog, boolean dumpASTToIGV) {
-        if (dumpASTToIGV) {
-            GraphPrintVisitor graphPrinter = new GraphPrintVisitor();
-            graphPrinter.beginGroup(groupName);
-            for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
-                RootCallTarget callTarget = function.getCallTarget();
-                if (callTarget != null) {
-                    graphPrinter.beginGraph(function.toString()).visit(callTarget.getRootNode());
-                }
-            }
-            graphPrinter.printToNetwork(true);
-        }
-        if (printASTToLog && logOutput != null) {
-            for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
-                RootCallTarget callTarget = function.getCallTarget();
-                if (callTarget != null) {
-                    logOutput.println("=== " + function);
-                    NodeUtil.printTree(logOutput, callTarget.getRootNode());
-                }
-            }
-        }
-        if (printSourceAttributionToLog && logOutput != null) {
-            for (SLFunction function : context.getFunctionRegistry().getFunctions()) {
-                RootCallTarget callTarget = function.getCallTarget();
-                if (callTarget != null) {
-                    logOutput.println("=== " + function);
-                    NodeUtil.printSourceAttributionTree(logOutput, callTarget.getRootNode());
-                }
-            }
-        }
-    }
-
-    /**
-     * Provides a user-readable message for run-time type errors. SL is strongly typed, i.e., there
-     * are no automatic type conversions of values. Therefore, Truffle does the type checking for
-     * us: if no matching node specialization for the actual values is found, then we have a type
-     * error. Specialized nodes use the {@link UnsupportedSpecializationException} to report that no
-     * specialization was found. We therefore just have to convert the information encapsulated in
-     * this exception in a user-readable form.
-     */
-    private static String formatTypeError(UnsupportedSpecializationException ex) {
-        StringBuilder result = new StringBuilder();
-        result.append("Type error");
-        if (ex.getNode() != null && ex.getNode().getSourceSection() != null) {
-            SourceSection ss = ex.getNode().getSourceSection();
-            if (ss != null && !(ss instanceof NullSourceSection)) {
-                result.append(" at ").append(ss.getSource().getShortName()).append(" line ").append(ss.getStartLine()).append(" col ").append(ss.getStartColumn());
-            }
-        }
-        result.append(": operation");
-        if (ex.getNode() != null) {
-            NodeInfo nodeInfo = SLContext.lookupNodeInfo(ex.getNode().getClass());
-            if (nodeInfo != null) {
-                result.append(" \"").append(nodeInfo.shortName()).append("\"");
-            }
-        }
-        result.append(" not defined for");
-
-        String sep = " ";
-        for (int i = 0; i < ex.getSuppliedValues().length; i++) {
-            Object value = ex.getSuppliedValues()[i];
-            Node node = ex.getSuppliedNodes()[i];
-            if (node != null) {
-                result.append(sep);
-                sep = ", ";
-
-                if (value instanceof Long || value instanceof BigInteger) {
-                    result.append("Number ").append(value);
-                } else if (value instanceof Boolean) {
-                    result.append("Boolean ").append(value);
-                } else if (value instanceof String) {
-                    result.append("String \"").append(value).append("\"");
-                } else if (value instanceof SLFunction) {
-                    result.append("Function ").append(value);
-                } else if (value == SLNull.SINGLETON) {
-                    result.append("NULL");
-                } else if (value == null) {
-                    // value is not evaluated because of short circuit evaluation
-                    result.append("ANY");
-                } else {
-                    result.append(value);
-                }
-            }
-        }
-        return result.toString();
-    }
-
-    @Override
-    protected Object eval(Source code) throws IOException {
-        try {
-            context.executeMain(code);
-        } catch (Exception e) {
-            throw new IOException(e);
-        }
-        return null;
-    }
-
-    @Override
-    protected Object findExportedSymbol(String globalName, boolean onlyExplicit) {
-        for (SLFunction f : context.getFunctionRegistry().getFunctions()) {
-            if (globalName.equals(f.getName())) {
-                return f;
-            }
-        }
-        return null;
-    }
-
-    @Override
-    protected Object getLanguageGlobal() {
-        return context;
-    }
-
-    @Override
-    protected boolean isObjectOfLanguage(Object object) {
-        return object instanceof SLFunction;
-    }
-
-    private static void setupToolDemos() {
-        if (statementCounts || coverage) {
-            Probe.registerASTProber(new SLStandardASTProber());
-        }
-        if (nodeExecCounts) {
-            nodeExecCounter = new NodeExecCounter();
-            nodeExecCounter.install();
-        }
-
-        if (statementCounts) {
-            statementExecCounter = new NodeExecCounter(StandardSyntaxTag.STATEMENT);
-            statementExecCounter.install();
-        }
-
-        if (coverage) {
-            coverageTracker = new CoverageTracker();
-            coverageTracker.install();
-        }
-    }
-
-    private static void reportToolDemos() {
-        if (nodeExecCounter != null) {
-            nodeExecCounter.print(System.out);
-            nodeExecCounter.dispose();
-        }
-        if (statementExecCounter != null) {
-            statementExecCounter.print(System.out);
-            statementExecCounter.dispose();
-        }
-        if (coverageTracker != null) {
-            coverageTracker.print(System.out);
-            coverageTracker.dispose();
-        }
-    }
-
-}
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/factory/SLContextFactory.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/factory/SLContextFactory.java	Tue Jun 09 15:20:30 2015 -0700
@@ -24,7 +24,6 @@
 
 import java.io.*;
 
-import com.oracle.truffle.sl.nodes.instrument.*;
 import com.oracle.truffle.sl.runtime.*;
 
 public final class SLContextFactory {
@@ -33,8 +32,6 @@
     }
 
     public static SLContext create(BufferedReader input, PrintWriter output) {
-        final SLContext slContext = new SLContext(input, output);
-        slContext.setVisualizer(new SLDefaultVisualizer());
-        return slContext;
+        return new SLContext(input, output);
     }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTypes.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/SLTypes.java	Tue Jun 09 15:20:30 2015 -0700
@@ -30,7 +30,7 @@
 import com.oracle.truffle.sl.runtime.*;
 
 /**
- * The type system of SL, as explained in {@link SLMain}. Based on the {@link TypeSystem}
+ * The type system of SL, as explained in {@link SLLanguage}. Based on the {@link TypeSystem}
  * annotation, the Truffle DSL generates the subclass {@link SLTypesGen} with type test and type
  * conversion methods for all types. In this class, we only cover types where the automatically
  * generated ones would not be sufficient.
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLDefaultVisualizer.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLDefaultVisualizer.java	Tue Jun 09 15:20:30 2015 -0700
@@ -73,7 +73,7 @@
     }
 
     @Override
-    public String displayValue(ExecutionContext context, Object value, int trim) {
+    public String displayValue(Object value, int trim) {
         if (value == SLNull.SINGLETON) {
             return "null";
         }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStandardASTProber.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/instrument/SLStandardASTProber.java	Tue Jun 09 15:20:30 2015 -0700
@@ -44,7 +44,7 @@
      */
     public boolean visit(Node node) {
 
-        if (node instanceof SLStatementNode && node.getParent() != null && node.getSourceSection() != null) {
+        if (!(node instanceof InstrumentationNode) && node instanceof SLStatementNode && node.getParent() != null && node.getSourceSection() != null) {
             // All SL nodes are instrumentable, but treat expressions specially
 
             if (node instanceof SLExpressionNode) {
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/runtime/SLContext.java	Tue Jun 09 15:20:30 2015 -0700
@@ -62,11 +62,6 @@
         this.emptyShape = LAYOUT.createShape(new ObjectType());
     }
 
-    @Override
-    public String getLanguageShortName() {
-        return "Simple";
-    }
-
     /**
      * Returns the default input, i.e., the source for the {@link SLReadlnBuiltin}. To allow unit
      * testing, we do not use {@link System#in} directly.
@@ -146,16 +141,11 @@
     }
 
     /**
-     * This function will parse the given source code, parse the code using the {@link Parser}, and
-     * then execute the function named main. To use this method with instrumentation,
-     * setASTNodeProber must have been already called. There is currently no guard to check if this
-     * is the case. <br/>
-     * Due to the experimental nature of the instrumentation framework, the parse that happens in
-     * this method will remove any previously added instrumentation.
+     * Evaluate a source, causing any definitions to be registered (but not executed).
      *
-     * @param source The {@link Source} to execute.
+     * @param source The {@link Source} to parse.
      */
-    public void executeMain(Source source) {
+    public void evalSource(Source source) {
         Parser.parseSL(this, source);
     }
 
--- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugClient.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugClient.java	Tue Jun 09 15:20:30 2015 -0700
@@ -26,9 +26,9 @@
 
 import java.util.*;
 
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.frame.MaterializedFrame;
-import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.vm.TruffleVM.Language;
 
 /**
  * A client of the debugger where certain events should be posted.
@@ -43,13 +43,12 @@
      *
      * @param astNode AST node that is just about to be executed
      * @param mFrame frame that will be passed to the node when executed
-     * @param warnings any warnings generated since thie most recent halt.
+     * @param warnings any warnings generated since the most recent halt.
      */
     void haltedAt(Node astNode, MaterializedFrame mFrame, List<String> warnings);
 
-    // TODO (mlvdv) temporary; will eventually be accessible by a new Truffle language API
     /**
-     * Gets the context for the language being debugged.
+     * Gets information and services for the language being debugged.
      */
-    ExecutionContext getExecutionContext();
+    Language getLanguage();
 }
--- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugEngine.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugEngine.java	Tue Jun 09 15:20:30 2015 -0700
@@ -33,7 +33,8 @@
 import com.oracle.truffle.api.instrument.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.source.*;
-import com.oracle.truffle.tools.debug.engine.SourceExecutionProvider.ExecutionListener;
+import com.oracle.truffle.api.vm.TruffleVM.Language;
+import com.oracle.truffle.tools.debug.engine.DebugExecutionSupport.DebugExecutionListener;
 
 /**
  * Language-agnostic engine for running Truffle languages under debugging control.
@@ -70,12 +71,14 @@
         void addWarning(String warning);
     }
 
+    private final Language language;
+
     /**
      * The client of this engine.
      */
     private final DebugClient debugClient;
 
-    private final SourceExecutionProvider sourceExecutionProvider;
+    private final DebugExecutionSupport executionSupport;
 
     /**
      * Implementation of line-oriented breakpoints.
@@ -94,11 +97,12 @@
 
     /**
      * @param debugClient
-     * @param sourceExecutionProvider
+     * @param language
      */
-    private DebugEngine(DebugClient debugClient, SourceExecutionProvider sourceExecutionProvider) {
+    private DebugEngine(DebugClient debugClient, Language language) {
         this.debugClient = debugClient;
-        this.sourceExecutionProvider = sourceExecutionProvider;
+        this.language = language;
+        this.executionSupport = new DebugExecutionSupport(language.getShortName(), language.getDebugSupport());
 
         Source.setFileCaching(true);
 
@@ -107,7 +111,7 @@
         prepareContinue();
         debugContext.contextTrace("START EXEC DEFAULT");
 
-        sourceExecutionProvider.addExecutionListener(new ExecutionListener() {
+        executionSupport.addExecutionListener(new DebugExecutionListener() {
 
             public void executionStarted(Source source, boolean stepInto) {
                 // Push a new execution context onto stack
@@ -146,13 +150,13 @@
             }
         };
 
-        this.lineBreaks = new LineBreakpointFactory(sourceExecutionProvider, breakpointCallback, warningLog);
+        this.lineBreaks = new LineBreakpointFactory(executionSupport, breakpointCallback, warningLog);
 
-        this.tagBreaks = new TagBreakpointFactory(sourceExecutionProvider, breakpointCallback, warningLog);
+        this.tagBreaks = new TagBreakpointFactory(executionSupport, breakpointCallback, warningLog);
     }
 
-    public static DebugEngine create(DebugClient debugClient, SourceExecutionProvider sourceExecutionProvider) {
-        return new DebugEngine(debugClient, sourceExecutionProvider);
+    public static DebugEngine create(DebugClient debugClient, Language language) {
+        return new DebugEngine(debugClient, language);
     }
 
     /**
@@ -162,7 +166,7 @@
      * @throws DebugException if an unexpected failure occurs
      */
     public void run(Source source, boolean stepInto) throws DebugException {
-        sourceExecutionProvider.run(source, stepInto);
+        executionSupport.run(source, stepInto);
     }
 
     /**
@@ -316,9 +320,11 @@
 
     /**
      * Evaluates code in a halted execution context, at top-level if <code>mFrame==null</code>.
+     *
+     * @throws DebugException
      */
-    public Object eval(Source source, Node node, MaterializedFrame mFrame) {
-        return sourceExecutionProvider.eval(source, node, mFrame);
+    public Object eval(Source source, Node node, MaterializedFrame mFrame) throws DebugException {
+        return executionSupport.evalInContext(source, node, mFrame);
     }
 
     /**
@@ -806,9 +812,7 @@
             if (frames == null) {
                 stream.println("<empty stack>");
             } else {
-                // TODO (mlvdv) get visualizer via the (to be developed) Truffle langauge API
-                final Visualizer visualizer = debugClient.getExecutionContext().getVisualizer();
-
+                final Visualizer visualizer = language.getDebugSupport().getVisualizer();
                 for (FrameDebugDescription frameDesc : frames) {
                     final StringBuilder sb = new StringBuilder("    frame " + Integer.toString(frameDesc.index()));
                     sb.append(":at " + visualizer.displaySourceLocation(frameDesc.node()));
--- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugException.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugException.java	Tue Jun 09 15:20:30 2015 -0700
@@ -33,6 +33,10 @@
         super(string);
     }
 
+    public DebugException(Exception ex) {
+        super(ex);
+    }
+
     private static final long serialVersionUID = 3307454453821997224L;
 
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/DebugExecutionSupport.java	Tue Jun 09 15:20:30 2015 -0700
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 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.tools.debug.engine;
+
+import java.util.*;
+
+import com.oracle.truffle.api.debug.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.api.instrument.*;
+import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.source.*;
+
+/**
+ * Access to language-specific support for debugging.
+ */
+final class DebugExecutionSupport {
+
+    interface DebugExecutionListener {
+
+        /**
+         * Notifies that execution is about to start and requests initial execution mode.
+         */
+        void executionStarted(Source source, boolean stepInto);
+
+        /**
+         * Notification that the current execution has just ended.
+         */
+        void executionEnded();
+    }
+
+    private final String languageName;
+    private final DebugSupportProvider provider;
+    private final List<DebugExecutionListener> listeners = new ArrayList<>();
+
+    DebugExecutionSupport(String languageName, DebugSupportProvider provider) {
+        this.languageName = languageName;
+        this.provider = provider;
+    }
+
+    void addExecutionListener(DebugExecutionListener listener) {
+        assert listener != null;
+        listeners.add(listener);
+    }
+
+    String getLanguageName() {
+        return languageName;
+    }
+
+    Visualizer getVisualizer() {
+        return provider.getVisualizer();
+    }
+
+    /**
+     * Runs a script. If "StepInto" is specified, halts at the first location tagged as a
+     * {@linkplain StandardSyntaxTag#STATEMENT STATEMENT}.
+     */
+    void run(Source source, boolean stepInto) throws DebugException {
+        for (DebugExecutionListener listener : listeners) {
+            listener.executionStarted(source, stepInto);
+        }
+        try {
+            provider.run(source);
+        } catch (DebugSupportException ex) {
+            throw new DebugException(ex);
+        } finally {
+            for (DebugExecutionListener listener : listeners) {
+                listener.executionEnded();
+            }
+        }
+    }
+
+    /**
+     * Evaluates string of language code in a halted execution context, at top level if
+     * <code>mFrame==null</code>.
+     *
+     * @throws DebugException
+     */
+    Object evalInContext(Source source, Node node, MaterializedFrame mFrame) throws DebugException {
+        for (DebugExecutionListener listener : listeners) {
+            listener.executionStarted(source, false);
+        }
+        try {
+            return provider.evalInContext(source, node, mFrame);
+        } catch (DebugSupportException ex) {
+            throw new DebugException(ex);
+        } finally {
+            for (DebugExecutionListener listener : listeners) {
+                listener.executionEnded();
+            }
+        }
+    }
+
+    /**
+     * Creates a language-specific factory to produce instances of {@link AdvancedInstrumentRoot}
+     * that, when executed, computes the result of a textual expression in the language; used to
+     * create an
+     * {@linkplain Instrument#create(AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String)
+     * Advanced Instrument}.
+     *
+     * @param expr a guest language expression
+     * @param resultListener optional listener for the result of each evaluation.
+     * @return a new factory
+     * @throws DebugException if the factory cannot be created, for example if the expression is
+     *             badly formed.
+     */
+    AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws DebugException {
+        try {
+            return provider.createAdvancedInstrumentRootFactory(expr, resultListener);
+        } catch (DebugSupportException ex) {
+            throw new DebugException(ex);
+        }
+    }
+
+}
--- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/LineBreakpointFactory.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/LineBreakpointFactory.java	Tue Jun 09 15:20:30 2015 -0700
@@ -90,7 +90,7 @@
         }
     };
 
-    private final SourceExecutionProvider sourceExecutionProvider;
+    private final DebugExecutionSupport executionSupport;
     private final BreakpointCallback breakpointCallback;
     private final WarningLog warningLog;
 
@@ -113,8 +113,8 @@
     @CompilationFinal private boolean breakpointsActive = true;
     private final CyclicAssumption breakpointsActiveUnchanged = new CyclicAssumption(BREAKPOINT_NAME + " globally active");
 
-    LineBreakpointFactory(SourceExecutionProvider sourceExecutionProvider, BreakpointCallback breakpointCallback, WarningLog warningLog) {
-        this.sourceExecutionProvider = sourceExecutionProvider;
+    LineBreakpointFactory(DebugExecutionSupport executionSupport, BreakpointCallback breakpointCallback, WarningLog warningLog) {
+        this.executionSupport = executionSupport;
         this.breakpointCallback = breakpointCallback;
         this.warningLog = warningLog;
 
@@ -376,7 +376,7 @@
             if (conditionExpr == null) {
                 newInstrument = Instrument.create(new UnconditionalLineBreakInstrumentListener(), BREAKPOINT_NAME);
             } else {
-                newInstrument = Instrument.create(this, sourceExecutionProvider.createAdvancedInstrumentRootFactory(conditionExpr, this), Boolean.class, BREAKPOINT_NAME);
+                newInstrument = Instrument.create(this, executionSupport.createAdvancedInstrumentRootFactory(conditionExpr, this), Boolean.class, BREAKPOINT_NAME);
             }
             newProbe.attach(newInstrument);
             instruments.add(newInstrument);
--- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/SourceExecutionProvider.java	Fri Jun 05 18:05:13 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 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.tools.debug.engine;
-
-import java.util.*;
-
-import com.oracle.truffle.api.frame.*;
-import com.oracle.truffle.api.instrument.*;
-import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.source.*;
-
-/**
- * Base for language-specific support required by the {@link DebugEngine} and any other tools that
- * run sources.
- */
-public abstract class SourceExecutionProvider {
-
-    interface ExecutionListener {
-
-        /**
-         * Notifies that execution is about to start and requests initial execution mode.
-         */
-        void executionStarted(Source source, boolean stepInto);
-
-        /**
-         * Notification that the current execution has just ended.
-         */
-        void executionEnded();
-    }
-
-    private final List<ExecutionListener> listeners = new ArrayList<>();
-
-    final void addExecutionListener(ExecutionListener listener) {
-        assert listener != null;
-        listeners.add(listener);
-    }
-
-    /**
-     * Runs a script. If "StepInto" is specified, halts at the first location tagged as a
-     * {@linkplain StandardSyntaxTag#STATEMENT STATEMENT}.
-     */
-    final void run(Source source, boolean stepInto) throws DebugException {
-        for (ExecutionListener listener : listeners) {
-            listener.executionStarted(source, stepInto);
-        }
-        try {
-            languageRun(source);
-        } finally {
-            for (ExecutionListener listener : listeners) {
-                listener.executionEnded();
-            }
-        }
-    }
-
-    /**
-     * Evaluates string of language code in a halted execution context, at top level if
-     * <code>mFrame==null</code>.
-     */
-    final Object eval(Source source, Node node, MaterializedFrame mFrame) {
-        for (ExecutionListener listener : listeners) {
-            listener.executionStarted(source, false);
-        }
-        try {
-            return languageEval(source, node, mFrame);
-        } finally {
-            for (ExecutionListener listener : listeners) {
-                listener.executionEnded();
-            }
-        }
-    }
-
-    /**
-     * Creates a language-specific factory to produce instances of {@link AdvancedInstrumentRoot}
-     * that, when executed, computes the result of a textual expression in the language; used to
-     * create an
-     * {@linkplain Instrument#create(AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory, Class, String)
-     * Advanced Instrument}.
-     *
-     * @param expr a guest language expression
-     * @param resultListener optional listener for the result of each evaluation.
-     * @return a new factory
-     * @throws DebugException if the factory cannot be created, for example if the expression is
-     *             badly formed.
-     */
-    final AdvancedInstrumentRootFactory createAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws DebugException {
-        return languageAdvancedInstrumentRootFactory(expr, resultListener);
-    }
-
-    /**
-     * Runs source code.
-     *
-     * @param source code
-     * @throws DebugException if unable to run successfully
-     */
-    public abstract void languageRun(Source source) throws DebugException;
-
-    /**
-     * Runs source code in a halted execution context, or at top level.
-     *
-     * @param source the code to run
-     * @param node node where execution halted, {@code null} if no execution context
-     * @param mFrame frame where execution halted, {@code null} if no execution context
-     * @return result of running the code in the context, or at top level if no execution context.
-     */
-    public abstract Object languageEval(Source source, Node node, MaterializedFrame mFrame);
-
-    /**
-     * Creates a {@linkplain AdvancedInstrumentRootFactory factory} that produces AST fragments from
-     * a textual expression, suitable for execution in context by the Instrumentation Framework.
-     *
-     * @param expr
-     * @param resultListener
-     * @return a factory that returns AST fragments that compute the expression
-     * @throws DebugException if the expression cannot be processed
-     *
-     * @see Instrument#create(AdvancedInstrumentResultListener, AdvancedInstrumentRootFactory,
-     *      Class, String)
-     */
-    public abstract AdvancedInstrumentRootFactory languageAdvancedInstrumentRootFactory(String expr, AdvancedInstrumentResultListener resultListener) throws DebugException;
-}
--- a/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/TagBreakpointFactory.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/TagBreakpointFactory.java	Tue Jun 09 15:20:30 2015 -0700
@@ -86,7 +86,7 @@
         }
     };
 
-    private final SourceExecutionProvider sourceExecutionProvider;
+    private final DebugExecutionSupport executionSupport;
     private final BreakpointCallback breakpointCallback;
     private final WarningLog warningLog;
 
@@ -102,8 +102,8 @@
     @CompilationFinal private boolean breakpointsActive = true;
     private final CyclicAssumption breakpointsActiveUnchanged = new CyclicAssumption(BREAKPOINT_NAME + " globally active");
 
-    TagBreakpointFactory(SourceExecutionProvider sourceExecutionProvider, BreakpointCallback breakpointCallback, WarningLog warningLog) {
-        this.sourceExecutionProvider = sourceExecutionProvider;
+    TagBreakpointFactory(DebugExecutionSupport executionSupport, BreakpointCallback breakpointCallback, WarningLog warningLog) {
+        this.executionSupport = executionSupport;
         this.breakpointCallback = breakpointCallback;
         this.warningLog = warningLog;
 
@@ -338,7 +338,7 @@
             if (conditionExpr == null) {
                 newInstrument = Instrument.create(new UnconditionalTagBreakInstrumentListener(), BREAKPOINT_NAME);
             } else {
-                newInstrument = Instrument.create(this, sourceExecutionProvider.createAdvancedInstrumentRootFactory(conditionExpr, this), Boolean.class, BREAKPOINT_NAME);
+                newInstrument = Instrument.create(this, executionSupport.createAdvancedInstrumentRootFactory(conditionExpr, this), Boolean.class, BREAKPOINT_NAME);
             }
             newProbe.attach(newInstrument);
             instruments.add(newInstrument);
--- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/SimpleREPLClient.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/SimpleREPLClient.java	Tue Jun 09 15:20:30 2015 -0700
@@ -29,7 +29,6 @@
 
 import jline.console.*;
 
-import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.source.*;
 import com.oracle.truffle.tools.debug.shell.*;
 
@@ -84,7 +83,7 @@
     private static final String STACK_FRAME_FORMAT = "    %3d: at %s in %s    line =\"%s\"\n";
     private static final String STACK_FRAME_SELECTED_FORMAT = "==> %3d: at %s in %s    line =\"%s\"\n";
 
-    private final ExecutionContext executionContext;  // Language context
+    private final String languageName;
 
     // Top level commands
     private final Map<String, REPLCommand> commandMap = new HashMap<>();
@@ -139,8 +138,8 @@
      */
     private Source selectedSource = null;
 
-    public SimpleREPLClient(ExecutionContext context, REPLServer replServer) {
-        this.executionContext = context;
+    public SimpleREPLClient(String languageName, REPLServer replServer) {
+        this.languageName = languageName;
         this.replServer = replServer;
         this.writer = System.out;
         try {
@@ -211,7 +210,7 @@
         try {
             clientContext.startSession();
         } finally {
-            clientContext.displayReply("Goodbye from " + executionContext.getLanguageShortName() + "/REPL");
+            clientContext.displayReply("Goodbye from " + languageName + "/REPL");
         }
 
     }
@@ -282,8 +281,7 @@
             if (level == 0) {
                 // 0-level context; no executions halted.
                 if (selectedSource == null) {
-                    final String languageName = executionContext.getLanguageShortName();
-                    currentPrompt = languageName == null ? "() " : "(" + languageName + ") ";
+                    currentPrompt = languageName == null ? "() " : "( " + languageName + " ) ";
                 } else {
                     currentPrompt = "(" + selectedSource.getShortName() + ") ";
                 }
--- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java	Tue Jun 09 15:20:30 2015 -0700
@@ -26,13 +26,13 @@
 
 import java.util.*;
 
-import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.instrument.*;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.api.source.*;
+import com.oracle.truffle.api.vm.TruffleVM.Language;
+import com.oracle.truffle.tools.debug.engine.*;
 import com.oracle.truffle.tools.debug.shell.*;
-import com.oracle.truffle.tools.debug.engine.*;
 
 /**
  * Server-side REPL implementation of an {@linkplain REPLMessage "op"}.
@@ -115,7 +115,7 @@
     }
 
     protected static REPLMessage createFrameInfoMessage(final REPLServerContext serverContext, FrameDebugDescription frame) {
-        final Visualizer visualizer = serverContext.getLanguageContext().getVisualizer();
+        final Visualizer visualizer = serverContext.getLanguage().getDebugSupport().getVisualizer();
         final REPLMessage infoMessage = new REPLMessage(REPLMessage.OP, REPLMessage.FRAME_INFO);
         infoMessage.put(REPLMessage.FRAME_NUMBER, Integer.toString(frame.index()));
         final Node node = frame.node();
@@ -402,15 +402,16 @@
             final FrameDebugDescription frameDescription = stack.get(frameNumber);
             final REPLMessage frameMessage = createFrameInfoMessage(serverContext, frameDescription);
             final Frame frame = frameDescription.frameInstance().getFrame(FrameInstance.FrameAccess.READ_ONLY, true);
-            final ExecutionContext context = serverContext.getLanguageContext();
+            final Language language = serverContext.getLanguage();
+            final Visualizer visualizer = language.getDebugSupport().getVisualizer();
             final FrameDescriptor frameDescriptor = frame.getFrameDescriptor();
             try {
                 final StringBuilder sb = new StringBuilder();
                 for (FrameSlot slot : frameDescriptor.getSlots()) {
-                    sb.append(Integer.toString(slot.getIndex()) + ": " + context.getVisualizer().displayIdentifier(slot) + " = ");
+                    sb.append(Integer.toString(slot.getIndex()) + ": " + visualizer.displayIdentifier(slot) + " = ");
                     try {
                         final Object value = frame.getValue(slot);
-                        sb.append(context.getVisualizer().displayValue(context, value, 0));
+                        sb.append(visualizer.displayValue(value, 0));
                     } catch (Exception ex) {
                         sb.append("???");
                     }
@@ -513,7 +514,7 @@
         @Override
         public REPLMessage[] receive(REPLMessage request, REPLServerContext serverContext) {
             final REPLMessage reply = createReply();
-            final ASTPrinter astPrinter = serverContext.getLanguageContext().getVisualizer().getASTPrinter();
+            final ASTPrinter astPrinter = serverContext.getLanguage().getDebugSupport().getVisualizer().getASTPrinter();
             final String topic = request.get(REPLMessage.TOPIC);
             reply.put(REPLMessage.TOPIC, topic);
             Node node = serverContext.getNode();
@@ -574,7 +575,7 @@
         @Override
         public REPLMessage[] receive(REPLMessage request, REPLServerContext serverContext) {
             final REPLMessage reply = createReply();
-            final ASTPrinter astPrinter = serverContext.getLanguageContext().getVisualizer().getASTPrinter();
+            final ASTPrinter astPrinter = serverContext.getLanguage().getDebugSupport().getVisualizer().getASTPrinter();
             final Node node = serverContext.getNode();
             if (node == null) {
                 return finishReplyFailed(reply, "no current AST node");
--- a/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java	Fri Jun 05 18:05:13 2015 -0700
+++ b/graal/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java	Tue Jun 09 15:20:30 2015 -0700
@@ -24,11 +24,11 @@
  */
 package com.oracle.truffle.tools.debug.shell.server;
 
-import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.nodes.*;
+import com.oracle.truffle.api.vm.TruffleVM.Language;
+import com.oracle.truffle.tools.debug.engine.*;
 import com.oracle.truffle.tools.debug.shell.*;
-import com.oracle.truffle.tools.debug.engine.*;
 
 public abstract class REPLServerContext {
 
@@ -63,7 +63,7 @@
         return mFrame;
     }
 
-    public abstract ExecutionContext getLanguageContext();
+    public abstract Language getLanguage();
 
     public abstract DebugEngine getDebugEngine();
 
--- a/mx/mx_graal.py	Fri Jun 05 18:05:13 2015 -0700
+++ b/mx/mx_graal.py	Tue Jun 09 15:20:30 2015 -0700
@@ -2404,7 +2404,7 @@
 def sl(args):
     """run an SL program"""
     vmArgs, slArgs = _extract_VM_args(args)
-    vm(vmArgs + ['-cp', mx.classpath(["TRUFFLE", "com.oracle.truffle.sl"]), "com.oracle.truffle.sl.SLMain"] + slArgs)
+    vm(vmArgs + ['-cp', mx.classpath(["TRUFFLE", "com.oracle.truffle.sl"]), "com.oracle.truffle.sl.SLLanguage"] + slArgs)
 
 def sldebug(args):
     """run a simple command line debugger for the Simple Language"""
--- a/mx/suite.py	Fri Jun 05 18:05:13 2015 -0700
+++ b/mx/suite.py	Tue Jun 09 15:20:30 2015 -0700
@@ -1224,10 +1224,7 @@
      "com.oracle.truffle.sl.tools" : {
       "subDir" : "graal",
       "sourceDirs" : ["src"],
-      "dependencies" : [
-        "com.oracle.truffle.sl",
-        "com.oracle.truffle.tools.debug.shell",
-      ],
+      "dependencies" : ["com.oracle.truffle.tools.debug.shell"],
       "checkstyle" : "com.oracle.truffle.api",
       "javaCompliance" : "1.8",
       "workingSets" : "Truffle,SimpleLanguage,Tools",