changeset 22206:dc91e9ee752e

SuspendedEvent.eval to let debugger evaluate variables in currently suspended execution context
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 30 Sep 2015 11:17:30 +0200
parents 7804ee711b7d
children e2ae3893ef98
files truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java
diffstat 5 files changed, 62 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java	Wed Sep 30 10:59:40 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java	Wed Sep 30 11:17:30 2015 +0200
@@ -25,10 +25,13 @@
 package com.oracle.truffle.api;
 
 import com.oracle.truffle.api.debug.DebugSupportProvider;
+import com.oracle.truffle.api.debug.SuspendedEvent;
+import com.oracle.truffle.api.frame.FrameInstance;
 import com.oracle.truffle.api.impl.Accessor;
 import com.oracle.truffle.api.impl.FindContextNode;
 import com.oracle.truffle.api.instrument.ToolSupportProvider;
 import com.oracle.truffle.api.nodes.Node;
+import com.oracle.truffle.api.nodes.RootNode;
 import com.oracle.truffle.api.source.Source;
 import java.io.IOException;
 import java.io.InputStream;
@@ -382,6 +385,18 @@
         }
 
         @Override
+        protected Object evalInContext(Object vm, SuspendedEvent ev, String code, FrameInstance frame) throws IOException {
+            Node n = frame == null ? ev.getNode() : frame.getCallNode();
+            RootNode rootNode = n.getRootNode();
+            Class<? extends TruffleLanguage> languageType = findLanguage(rootNode);
+            Env env = findLanguage(vm, languageType);
+            TruffleLanguage<?> lang = findLanguage(env);
+            Source source = Source.fromText(code, "eval in context");
+            CallTarget target = lang.parse(source, n);
+            return target.call();
+        }
+
+        @Override
         protected Object findExportedSymbol(TruffleLanguage.Env env, String globalName, boolean onlyExplicit) {
             return env.langCtx.findExportedSymbol(globalName, onlyExplicit);
         }
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java	Wed Sep 30 10:59:40 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java	Wed Sep 30 11:17:30 2015 +0200
@@ -807,6 +807,10 @@
         debugContext = debugContext.predecessor;
     }
 
+    Object evalInContext(SuspendedEvent ev, String code, FrameInstance frame) throws IOException {
+        return ACCESSOR.evalInContext(vm, ev, code, frame);
+    }
+
     @SuppressWarnings("rawtypes")
     private static final class AccessorDebug extends Accessor {
         @Override
@@ -850,6 +854,11 @@
         protected void dispatchEvent(Object vm, Object event) {
             super.dispatchEvent(vm, event);
         }
+
+        @Override
+        protected Object evalInContext(Object vm, SuspendedEvent ev, String code, FrameInstance frame) throws IOException {
+            return super.evalInContext(vm, ev, code, frame);
+        }
     }
 
     // registers into Accessor.DEBUG
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java	Wed Sep 30 10:59:40 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java	Wed Sep 30 11:17:30 2015 +0200
@@ -31,6 +31,7 @@
 import com.oracle.truffle.api.frame.MaterializedFrame;
 import com.oracle.truffle.api.instrument.StandardSyntaxTag;
 import com.oracle.truffle.api.nodes.Node;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -192,4 +193,18 @@
     public void prepareStepOver(int stepCount) {
         debugger.prepareStepOver(stepCount);
     }
+
+    /**
+     * Evaluates given code snippet in the context of currently suspended execution.
+     *
+     * @param code the snippet to evaluate
+     * @param frame <code>null</code> in case the evaluation should happen in top most frame,
+     *            non-null value to specify a frame from those {@link #getStack() currently on
+     *            stack} to perform the evaluation in context of
+     * @return the computed value
+     * @throws IOException in case an evaluation goes wrong
+     */
+    public Object eval(String code, FrameInstance frame) throws IOException {
+        return debugger.evalInContext(this, code, frame);
+    }
 }
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Wed Sep 30 10:59:40 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Wed Sep 30 11:17:30 2015 +0200
@@ -31,6 +31,8 @@
 import com.oracle.truffle.api.TruffleLanguage.Env;
 import com.oracle.truffle.api.debug.DebugSupportProvider;
 import com.oracle.truffle.api.debug.Debugger;
+import com.oracle.truffle.api.debug.SuspendedEvent;
+import com.oracle.truffle.api.frame.FrameInstance;
 import com.oracle.truffle.api.instrument.Probe;
 import com.oracle.truffle.api.instrument.ToolSupportProvider;
 import com.oracle.truffle.api.nodes.Node;
@@ -140,6 +142,10 @@
         return API.eval(l, s);
     }
 
+    protected Object evalInContext(Object vm, SuspendedEvent ev, String code, FrameInstance frame) throws IOException {
+        return API.evalInContext(vm, ev, code, frame);
+    }
+
     protected Object importSymbol(Object vm, TruffleLanguage<?> queryingLang, String globalName) {
         return SPI.importSymbol(vm, queryingLang, globalName);
     }
--- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java	Wed Sep 30 10:59:40 2015 +0200
+++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java	Wed Sep 30 11:17:30 2015 +0200
@@ -24,10 +24,6 @@
  */
 package com.oracle.truffle.tools.debug.shell.server;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 import com.oracle.truffle.api.debug.Breakpoint;
 import com.oracle.truffle.api.debug.Debugger;
 import com.oracle.truffle.api.debug.SuspendedEvent;
@@ -39,6 +35,10 @@
 import com.oracle.truffle.api.vm.PolyglotEngine;
 import com.oracle.truffle.api.vm.PolyglotEngine.Language;
 import com.oracle.truffle.tools.debug.shell.REPLMessage;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
 public abstract class REPLServerContext {
 
@@ -65,6 +65,19 @@
     }
 
     /**
+     * Evaluates given code snippet in the context of currently suspended execution.
+     * 
+     * @param code the snippet to evaluate
+     * @param frame <code>null</code> in case the evaluation should happen in top most frame,
+     *            non-null value
+     * @return result of the evaluation
+     * @throws IOException if something goes wrong
+     */
+    public Object eval(String code, FrameInstance frame) throws IOException {
+        return event.eval(code, frame);
+    }
+
+    /**
      * The frame where execution is halted in this context.
      */
     public MaterializedFrame getFrameAtHalt() {