| Index: pkg/dartino_compiler/lib/vm_context.dart
|
| diff --git a/pkg/dartino_compiler/lib/vm_context.dart b/pkg/dartino_compiler/lib/vm_context.dart
|
| index 7edaf8fedf729eecdb7ae6b43c4f5b741bfba58b..4945625c25137d9e9c86ba16be7187124f911d90 100644
|
| --- a/pkg/dartino_compiler/lib/vm_context.dart
|
| +++ b/pkg/dartino_compiler/lib/vm_context.dart
|
| @@ -84,15 +84,17 @@ abstract class DebugListener {
|
| // Notification that a process has exited.
|
| processExit(int processId) {}
|
| // A process has paused at start, before executing code.
|
| - pauseStart(int processId, BackTraceFrame topframe) {}
|
| + // This is sent on spawning processes.
|
| + pauseStart(int processId) {}
|
| // An process has paused at exit, before terminating.
|
| - pauseExit(int processId, BackTraceFrame topframe) {}
|
| + pauseExit(int processId, BackTraceFrame topFrame) {}
|
| // A process has paused at a breakpoint or due to stepping.
|
| - pauseBreakpoint(int processId, BackTraceFrame topframe, int breakpointId) {}
|
| + pauseBreakpoint(
|
| + int processId, BackTraceFrame topFrame, Breakpoint breakpoint) {}
|
| // A process has paused due to interruption.
|
| - pauseInterrupted(int processId, BackTraceFrame topframe) {}
|
| + pauseInterrupted(int processId, BackTraceFrame topFrame) {}
|
| // A process has paused due to an exception.
|
| - pauseException(int processId, BackTraceFrame topframe, RemoteObject thrown) {}
|
| + pauseException(int processId, BackTraceFrame topFrame, RemoteObject thrown) {}
|
| // A process has started or resumed execution.
|
| resume(int processId) {}
|
| // A breakpoint has been added for a process.
|
| @@ -107,6 +109,8 @@ abstract class DebugListener {
|
| writeStdErr(int processId, List<int> data) {}
|
| // The connection to the vm was lost.
|
| lostConnection() {}
|
| + // The debugged program is over.
|
| + terminated() {}
|
| }
|
|
|
| class SinkDebugListener extends DebugListener {
|
| @@ -208,6 +212,10 @@ class DartinoVmContext {
|
| debugState = new DebugState(this);
|
| }
|
|
|
| + void notifyListeners(void f(DebugListener listener)) {
|
| + listeners.forEach(f);
|
| + }
|
| +
|
| /// Convenience around [runCommands] for running just a single command.
|
| Future<VmCommand> runCommand(VmCommand command) {
|
| return runCommands([command]);
|
| @@ -275,11 +283,11 @@ class DartinoVmContext {
|
| translateFunctionMessage,
|
| translateClassMessage);
|
| if (command is StdoutData) {
|
| - listeners.forEach((DebugListener listener) {
|
| + notifyListeners((DebugListener listener) {
|
| listener.writeStdOut(0, command.value);
|
| });
|
| } else if (command is StderrData) {
|
| - listeners.forEach((DebugListener listener) {
|
| + notifyListeners((DebugListener listener) {
|
| listener.writeStdErr(0, command.value);
|
| });
|
| } else {
|
| @@ -308,6 +316,9 @@ class DartinoVmContext {
|
| }
|
| }
|
| vmState = VmState.terminated;
|
| + notifyListeners((DebugListener listener) {
|
| + listener.terminated();
|
| + });
|
| return connection.done;
|
| }
|
|
|
| @@ -409,6 +420,10 @@ class DartinoVmContext {
|
| Future spawnProcess(List<String> arguments) async {
|
| await runCommand(new ProcessSpawnForMain(arguments));
|
| vmState = VmState.spawned;
|
| + notifyListeners((DebugListener listener) {
|
| + listener.pauseStart(0);
|
| + listener.processRunnable(0);
|
| + });
|
| }
|
|
|
| /// Returns the [NameOffsetMapping] stored in the '.info.json' adjacent to a
|
| @@ -507,9 +522,23 @@ class DartinoVmContext {
|
| case VmCommandCode.UncaughtException:
|
| interactiveExitCode = exit_codes.DART_VM_EXITCODE_UNCAUGHT_EXCEPTION;
|
| vmState = VmState.terminating;
|
| + UncaughtException command = response;
|
| + debugState.currentProcess = command.processId;
|
| + var function = dartinoSystem.lookupFunctionById(command.functionId);
|
| + debugState.topFrame = new BackTraceFrame(
|
| + function, command.bytecodeIndex, compiler, debugState);
|
| + RemoteObject thrown = await uncaughtException();
|
| + notifyListeners((DebugListener listener) {
|
| + listener.pauseException(
|
| + debugState.currentProcess, debugState.topFrame, thrown);
|
| + });
|
| break;
|
|
|
| case VmCommandCode.ProcessCompileTimeError:
|
| + notifyListeners((DebugListener listener) {
|
| + // TODO(sigurdm): Add processId and exception data.
|
| + listener.pauseException(0, null, null);
|
| + });
|
| interactiveExitCode = exit_codes.DART_VM_EXITCODE_COMPILE_TIME_ERROR;
|
| vmState = VmState.terminating;
|
| break;
|
| @@ -517,12 +546,19 @@ class DartinoVmContext {
|
| case VmCommandCode.ProcessTerminated:
|
| interactiveExitCode = 0;
|
| vmState = VmState.terminating;
|
| + notifyListeners((DebugListener listener) {
|
| + // TODO(sigurdm): Communicate process id.
|
| + listener.processExit(0);
|
| + });
|
| break;
|
|
|
| case VmCommandCode.ConnectionError:
|
| interactiveExitCode = exit_codes.COMPILER_EXITCODE_CONNECTION_ERROR;
|
| vmState = VmState.terminating;
|
| await shutdown();
|
| + notifyListeners((DebugListener listener) {
|
| + listener.lostConnection();
|
| + });
|
| break;
|
|
|
| case VmCommandCode.ProcessBreakpoint:
|
| @@ -533,6 +569,21 @@ class DartinoVmContext {
|
| debugState.topFrame = new BackTraceFrame(
|
| function, command.bytecodeIndex, compiler, debugState);
|
| vmState = VmState.paused;
|
| + Breakpoint bp = debugState.breakpoints[command.breakpointId];
|
| + if (bp == null) {
|
| + notifyListeners((DebugListener listener) {
|
| + listener.pauseInterrupted(
|
| + command.processId,
|
| + debugState.topFrame);
|
| + });
|
| + } else {
|
| + notifyListeners((DebugListener listener) {
|
| + listener.pauseBreakpoint(
|
| + command.processId,
|
| + debugState.topFrame,
|
| + bp);
|
| + });
|
| + }
|
| break;
|
|
|
| default:
|
| @@ -546,19 +597,30 @@ class DartinoVmContext {
|
| Future<VmCommand> startRunning() async {
|
| await sendCommand(const ProcessRun());
|
| vmState = VmState.running;
|
| + notifyListeners((DebugListener listener) {
|
| + listener.processStart(0);
|
| + });
|
| + notifyListeners((DebugListener listener) {
|
| + listener.processRunnable(0);
|
| + });
|
| + notifyListeners((DebugListener listener) {
|
| + listener.resume(0);
|
| + });
|
| return handleProcessStop(await readNextCommand());
|
| }
|
|
|
| - Future setBreakpointHelper(String name,
|
| - DartinoFunction function,
|
| + Future<Breakpoint> setBreakpointHelper(DartinoFunction function,
|
| int bytecodeIndex) async {
|
| ProcessSetBreakpoint response = await runCommands([
|
| new PushFromMap(MapId.methods, function.functionId),
|
| new ProcessSetBreakpoint(bytecodeIndex),
|
| ]);
|
| int breakpointId = response.value;
|
| - var breakpoint = new Breakpoint(function, bytecodeIndex, breakpointId);
|
| + Breakpoint breakpoint =
|
| + new Breakpoint(function, bytecodeIndex, breakpointId);
|
| debugState.breakpoints[breakpointId] = breakpoint;
|
| + notifyListeners(
|
| + (DebugListener listener) => listener.breakpointAdded(0, breakpoint));
|
| return breakpoint;
|
| }
|
|
|
| @@ -571,12 +633,12 @@ class DartinoVmContext {
|
| List<Breakpoint> breakpoints = [];
|
| for (DartinoFunction function in functions) {
|
| breakpoints.add(
|
| - await setBreakpointHelper(methodName, function, bytecodeIndex));
|
| + await setBreakpointHelper(function, bytecodeIndex));
|
| }
|
| return breakpoints;
|
| }
|
|
|
| - Future setFileBreakpointFromPosition(String name,
|
| + Future<Breakpoint> setFileBreakpointFromPosition(String name,
|
| Uri file,
|
| int position) async {
|
| if (position == null) {
|
| @@ -595,10 +657,10 @@ class DartinoVmContext {
|
| }
|
| DartinoFunction function = debugInfo.function;
|
| int bytecodeIndex = location.bytecodeIndex;
|
| - return setBreakpointHelper(function.name, function, bytecodeIndex);
|
| + return setBreakpointHelper(function, bytecodeIndex);
|
| }
|
|
|
| - Future setFileBreakpointFromPattern(Uri file,
|
| + Future<Breakpoint> setFileBreakpointFromPattern(Uri file,
|
| int line,
|
| String pattern) async {
|
| assert(line > 0);
|
| @@ -607,26 +669,32 @@ class DartinoVmContext {
|
| '$file:$line:$pattern', file, position);
|
| }
|
|
|
| - Future setFileBreakpoint(Uri file, int line, int column) async {
|
| + Future<Breakpoint> setFileBreakpoint(Uri file, int line, int column) async {
|
| assert(line > 0 && column > 0);
|
| int position = compiler.positionInFile(file, line - 1, column - 1);
|
| return setFileBreakpointFromPosition('$file:$line:$column', file, position);
|
| }
|
|
|
| - Future doDeleteOneShotBreakpoint(int processId, int breakpointId) async {
|
| + Future<Null> doDeleteOneShotBreakpoint(
|
| + int processId, int breakpointId) async {
|
| ProcessDeleteBreakpoint response = await runCommand(
|
| new ProcessDeleteOneShotBreakpoint(processId, breakpointId));
|
| assert(response.id == breakpointId);
|
| }
|
|
|
| Future<Breakpoint> deleteBreakpoint(int id) async {
|
| + assert(!isRunning && !isTerminated);
|
| if (!debugState.breakpoints.containsKey(id)) {
|
| return null;
|
| }
|
| ProcessDeleteBreakpoint response =
|
| await runCommand(new ProcessDeleteBreakpoint(id));
|
| assert(response.id == id);
|
| - return debugState.breakpoints.remove(id);
|
| + Breakpoint breakpoint = debugState.breakpoints.remove(id);
|
| + notifyListeners((DebugListener listener) {
|
| + listener.breakpointRemoved(0, breakpoint);
|
| + });
|
| + return breakpoint;
|
| }
|
|
|
| List<Breakpoint> breakpoints() {
|
| @@ -749,6 +817,9 @@ class DartinoVmContext {
|
|
|
| Future<VmCommand> cont() async {
|
| assert(isPaused);
|
| + notifyListeners((DebugListener listener) {
|
| + listener.resume(0);
|
| + });
|
| return handleProcessStop(await runCommand(const ProcessContinue()));
|
| }
|
|
|
| @@ -798,12 +869,13 @@ class DartinoVmContext {
|
| return debugState.currentUncaughtException;
|
| }
|
|
|
| - Future<BackTrace> backTrace() async {
|
| + Future<BackTrace> backTrace({int processId}) async {
|
| + processId ??= debugState.currentProcess;
|
| assert(isSpawned);
|
| if (debugState.currentBackTrace == null) {
|
| ProcessBacktrace backtraceResponse =
|
| await runCommand(
|
| - new ProcessBacktraceRequest(debugState.currentProcess));
|
| + new ProcessBacktraceRequest(processId));
|
| debugState.currentBackTrace =
|
| stackTraceFromBacktraceResponse(backtraceResponse);
|
| }
|
| @@ -831,7 +903,7 @@ class DartinoVmContext {
|
| }
|
|
|
| Future<List<int>> processes() async {
|
| - assert(isRunning || isPaused);
|
| + assert(isSpawned);
|
| ProcessGetProcessIdsResult response =
|
| await runCommand(const ProcessGetProcessIds());
|
| return response.ids;
|
|
|