# HG changeset patch # User Michael Van De Vanter # Date 1447208752 28800 # Node ID a8b796ac350da46c4fa103c6415c7a6fe34932ed # Parent 5b6e15432aae1f2c9114a75ecf2289ec510337c5 Truffle/REPL: upate to use new support for "eval" diff -r 5b6e15432aae -r a8b796ac350d truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/SimpleREPLClient.java --- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/SimpleREPLClient.java Tue Nov 10 18:25:30 2015 -0800 +++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/client/SimpleREPLClient.java Tue Nov 10 18:25:52 2015 -0800 @@ -152,6 +152,7 @@ public SimpleREPLClient(REPLServer replServer) { this.replServer = replServer; + // TODO (mlvdv) language-dependent this.languageName = replServer.getLanguageName(); this.writer = System.out; try { @@ -258,18 +259,26 @@ this.level = predecessor == null ? 0 : predecessor.level + 1; if (message != null) { + final String sourceName = message.get(REPLMessage.SOURCE_NAME); try { - this.haltedSource = Source.fromFileName(message.get(REPLMessage.SOURCE_NAME)); - selectedSource = this.haltedSource; + this.haltedSource = Source.fromFileName(sourceName); + } catch (IOException ex) { + final String code = message.get(REPLMessage.SOURCE_TEXT); + if (code != null) { + this.haltedSource = Source.fromText(code, sourceName); + } + } + if (this.haltedSource != null) { + selectedSource = haltedSource; try { haltedLineNumber = Integer.parseInt(message.get(REPLMessage.LINE_NUMBER)); } catch (NumberFormatException e) { haltedLineNumber = 0; } - } catch (IOException e1) { + } else { this.haltedSource = null; this.haltedLineNumber = 0; - this.unknownSourceName = message.get(REPLMessage.SOURCE_NAME); + this.unknownSourceName = sourceName; } } updatePrompt(); diff -r 5b6e15432aae -r a8b796ac350d truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java --- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java Tue Nov 10 18:25:30 2015 -0800 +++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLHandler.java Tue Nov 10 18:25:52 2015 -0800 @@ -43,6 +43,7 @@ import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.api.vm.PolyglotEngine.Language; import com.oracle.truffle.tools.debug.shell.REPLMessage; +import com.oracle.truffle.tools.debug.shell.server.REPLServer.Context; /** * Server-side REPL implementation of an {@linkplain REPLMessage "op"}. @@ -403,30 +404,19 @@ } }; public static final REPLHandler EVAL_HANDLER = new REPLHandler(REPLMessage.EVAL) { - @SuppressWarnings("unused") @Override public REPLMessage[] receive(REPLMessage request, REPLServer replServer) { final REPLMessage reply = createReply(); final String sourceName = request.get(REPLMessage.SOURCE_NAME); reply.put(REPLMessage.SOURCE_NAME, sourceName); - reply.put(REPLMessage.DEBUG_LEVEL, Integer.toString(replServer.getCurrentContext().getLevel())); + final Context serverContext = replServer.getCurrentContext(); + reply.put(REPLMessage.DEBUG_LEVEL, Integer.toString(serverContext.getLevel())); final String source = request.get(REPLMessage.CODE); final Visualizer visualizer = replServer.getVisualizer(); - final Integer frameNumber = request.getIntValue(REPLMessage.FRAME_NUMBER); - FrameInstance frameInstance = null; - if (frameNumber != null) { - final List stack = replServer.getCurrentContext().getStack(); - if (frameNumber < 0 || frameNumber >= stack.size()) { - return finishReplyFailed(reply, "invalid frame number"); - } - final FrameDebugDescription frameDescription = stack.get(frameNumber); - // frameInstance = frameDescription == null ? null : - // frameDescription.frameInstance(); - } try { - Object returnValue = replServer.getCurrentContext().eval(source, frameInstance); + Object returnValue = serverContext.eval(source, frameNumber); return finishReplySucceeded(reply, visualizer.displayValue(returnValue, 0)); } catch (QuitException ex) { throw ex; diff -r 5b6e15432aae -r a8b796ac350d truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServer.java --- a/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServer.java Tue Nov 10 18:25:30 2015 -0800 +++ b/truffle/com.oracle.truffle.tools.debug.shell/src/com/oracle/truffle/tools/debug/shell/server/REPLServer.java Tue Nov 10 18:25:52 2015 -0800 @@ -68,6 +68,7 @@ private final Map handlerMap = new HashMap<>(); // TODO (mlvdv) Language-specific + private final String mimeType; private final PolyglotEngine.Language language; private final Visualizer visualizer; @@ -79,6 +80,7 @@ * Create a single-language server. */ public REPLServer(String mimeType, Visualizer visualizer) { + this.mimeType = mimeType; this.visualizer = visualizer == null ? new DefaultVisualizer() : visualizer; EventConsumer onHalted = new EventConsumer(SuspendedEvent.class) { @Override @@ -90,7 +92,9 @@ @Override protected void on(ExecutionEvent event) { db = event.getDebugger(); - event.prepareStepInto(); + if (!currentServerContext.isEval) { + event.prepareStepInto(); + } } }; engine = PolyglotEngine.buildNew().onEvent(onHalted).onEvent(onExec).build(); @@ -110,13 +114,6 @@ */ public void start() { - addHandlers(); - this.replClient = new SimpleREPLClient(this); - this.currentServerContext = new Context(null, null); - replClient.start(); - } - - protected void addHandlers() { add(REPLHandler.BACKTRACE_HANDLER); add(REPLHandler.BREAK_AT_LINE_HANDLER); add(REPLHandler.BREAK_AT_LINE_ONCE_HANDLER); @@ -143,6 +140,9 @@ add(REPLHandler.TRUFFLE_HANDLER); add(REPLHandler.TRUFFLE_NODE_HANDLER); add(REPLHandler.UNSET_BREAK_CONDITION_HANDLER); + this.replClient = new SimpleREPLClient(this); + this.currentServerContext = new Context(null, null); + replClient.start(); } void haltedAt(SuspendedEvent event) { @@ -155,7 +155,12 @@ final SourceSection src = event.getNode().getSourceSection(); final Source source = src.getSource(); message.put(REPLMessage.SOURCE_NAME, source.getName()); - message.put(REPLMessage.FILE_PATH, source.getPath()); + final String path = source.getPath(); + if (path == null) { + message.put(REPLMessage.SOURCE_TEXT, source.getCode()); + } else { + message.put(REPLMessage.FILE_PATH, path); + } message.put(REPLMessage.LINE_NUMBER, Integer.toString(src.getStartLine())); message.put(REPLMessage.STATUS, REPLMessage.SUCCEEDED); message.put(REPLMessage.DEBUG_LEVEL, Integer.toString(currentServerContext.getLevel())); @@ -187,6 +192,7 @@ private final Context predecessor; private final int level; private final SuspendedEvent event; + private boolean isEval = false; // When true, run without StepInto Context(Context predecessor, SuspendedEvent event) { this.level = predecessor == null ? 0 : predecessor.getLevel() + 1; @@ -209,19 +215,26 @@ } /** - * Evaluates given code snippet in the context of currently suspended execution. + * Evaluates a code snippet in the context of a selected frame in the 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 + * @param frameNumber index of the stack frame in which to evaluate, {@code null} if the + * topmost frame should be used. * @return result of the evaluation * @throws IOException if something goes wrong */ - Object eval(String code, FrameInstance frame) throws IOException { + Object eval(String code, Integer frameNumber) throws IOException { if (event == null) { - throw new IOException("top level \"eval\" not yet supported"); + try { + isEval = true; + final Value value = engine.eval(Source.fromText(code, "eval(\"" + code + "\")").withMimeType(mimeType)); + return value.get(); + } finally { + isEval = false; + } } - return event.eval(code, frame); + return event.eval(code, frameNumber); } /** @@ -364,7 +377,7 @@ void call(String name) throws IOException { Value symbol = engine.findGlobalSymbol(name); if (symbol == null) { - throw new IOException("symboleval f \"" + name + "\" not found"); + throw new IOException("symbol \"" + name + "\" not found"); } symbol.invoke(null); }