# HG changeset patch # User Jaroslav Tulach # Date 1443604742 -7200 # Node ID e2ae3893ef98c088063dec1701bc70dce01a4647 # Parent 3975d87a5d466c0beeb095f68e0d1d13c067e712# Parent dc91e9ee752e14d344eb1a43e37bd55ccab80155 Merge of SuspendedEvent.eval into main development line diff -r 3975d87a5d46 -r e2ae3893ef98 truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java --- a/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Wed Sep 30 11:02:02 2015 +0200 +++ b/truffle/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java Wed Sep 30 11:19:02 2015 +0200 @@ -27,13 +27,17 @@ import com.oracle.truffle.api.TruffleRuntime; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameInstance; import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.frame.FrameSlotKind; import com.oracle.truffle.api.frame.FrameSlotTypeException; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; import org.junit.Assert; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import org.junit.Test; /** @@ -152,4 +156,31 @@ } } } + + @Test + public void framesCanBeMaterialized() { + final TruffleRuntime runtime = Truffle.getRuntime(); + + class FrameRootNode extends RootNode { + + public FrameRootNode() { + super(TestingLanguage.class, null, null); + } + + @Override + public Object execute(VirtualFrame frame) { + FrameInstance frameInstance = runtime.getCurrentFrame(); + Frame readWrite = frameInstance.getFrame(FrameInstance.FrameAccess.READ_WRITE, true); + Frame materialized = frameInstance.getFrame(FrameInstance.FrameAccess.MATERIALIZE, true); + + assertTrue("Really materilized: " + materialized, materialized instanceof MaterializedFrame); + assertEquals("It's my frame", frame, readWrite); + return this; + } + } + + FrameRootNode frn = new FrameRootNode(); + Object ret = Truffle.getRuntime().createCallTarget(frn).call(); + assertEquals("Returns itself", frn, ret); + } } diff -r 3975d87a5d46 -r e2ae3893ef98 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Wed Sep 30 11:02:02 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java Wed Sep 30 11:19:02 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 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); } diff -r 3975d87a5d46 -r e2ae3893ef98 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java Wed Sep 30 11:02:02 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/Debugger.java Wed Sep 30 11:19:02 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 diff -r 3975d87a5d46 -r e2ae3893ef98 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java Wed Sep 30 11:02:02 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/debug/SuspendedEvent.java Wed Sep 30 11:19:02 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 null in case the evaluation should happen in top most frame, + * non-null value to specify a frame from those {@link #getStack() currently on + * stack} to perform the evaluation in context of + * @return the computed value + * @throws IOException in case an evaluation goes wrong + */ + public Object eval(String code, FrameInstance frame) throws IOException { + return debugger.evalInContext(this, code, frame); + } } diff -r 3975d87a5d46 -r e2ae3893ef98 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Wed Sep 30 11:02:02 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java Wed Sep 30 11:19:02 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); } diff -r 3975d87a5d46 -r e2ae3893ef98 truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java --- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Wed Sep 30 11:02:02 2015 +0200 +++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallTarget.java Wed Sep 30 11:19:02 2015 +0200 @@ -30,7 +30,6 @@ import com.oracle.truffle.api.TruffleRuntime; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameInstance; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; @@ -59,10 +58,13 @@ @Override public Object call(Object... args) { - final VirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), args); + final DefaultVirtualFrame frame = new DefaultVirtualFrame(getRootNode().getFrameDescriptor(), args); FrameInstance oldCurrentFrame = defaultTruffleRuntime().setCurrentFrame(new FrameInstance() { public Frame getFrame(FrameAccess access, boolean slowPath) { + if (access == FrameAccess.MATERIALIZE) { + return new DefaultMaterializedFrame(frame); + } return frame; } diff -r 3975d87a5d46 -r e2ae3893ef98 truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java --- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java Wed Sep 30 11:02:02 2015 +0200 +++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServerContext.java Wed Sep 30 11:19:02 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 null in case the evaluation should happen in top most frame, + * non-null value + * @return result of the evaluation + * @throws IOException if something goes wrong + */ + public Object eval(String code, FrameInstance frame) throws IOException { + return event.eval(code, frame); + } + + /** * The frame where execution is halted in this context. */ public MaterializedFrame getFrameAtHalt() {