Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Unified Diff: pkg/fletchc/lib/vm_session.dart

Issue 1659163007: Rename fletch -> dartino (Closed) Base URL: https://github.com/dartino/sdk.git@master
Patch Set: address comments Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/fletchc/lib/vm_commands.dart ('k') | pkg/fletchc/samples/fletchc_driver/target.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/fletchc/lib/vm_session.dart
diff --git a/pkg/fletchc/lib/vm_session.dart b/pkg/fletchc/lib/vm_session.dart
deleted file mode 100644
index 94757fe153afe595f89fd0fb4b373275a9948c95..0000000000000000000000000000000000000000
--- a/pkg/fletchc/lib/vm_session.dart
+++ /dev/null
@@ -1,868 +0,0 @@
-// Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library fletch.vm_session;
-
-import 'dart:core';
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io' hide exit;
-
-import 'dart:typed_data' show
- ByteData,
- Uint8List;
-
-import 'vm_commands.dart';
-import 'fletch_system.dart';
-
-import 'incremental/fletchc_incremental.dart'
- show IncrementalCompiler;
-
-import 'src/codegen_visitor.dart';
-import 'src/debug_info.dart';
-
-// TODO(ahe): Get rid of this import.
-import 'src/fletch_backend.dart' show FletchBackend;
-
-import 'src/fletch_selector.dart' show
- FletchSelector,
- SelectorKind;
-
-import 'debug_state.dart';
-
-import 'src/shared_command_infrastructure.dart' show
- CommandTransformerBuilder,
- toUint8ListView;
-
-import 'src/hub/session_manager.dart' show
- SessionState;
-
-part 'vm_command_reader.dart';
-part 'input_handler.dart';
-
-/// Encapsulates a TCP connection to a running fletch-vm and provides a
-/// [VmCommand] based view on top of it.
-class FletchVmSession {
- /// The outgoing connection to the fletch-vm.
- final StreamSink<List<int>> _outgoingSink;
-
- final Sink<List<int>> stdoutSink;
- final Sink<List<int>> stderrSink;
-
- /// The VM command reader reads data from the vm, converts the data
- /// into a [VmCommand], and provides a stream iterator iterating over
- /// these commands.
- /// If the [VmCommand] is for stdout or stderr the reader automatically
- /// forwards them to the stdout/stderr sinks and does not add them to the
- /// iterator.
- final VmCommandReader _commandReader;
-
- /// Completes when the underlying TCP connection is terminated.
- final Future _done;
-
- bool _connectionIsDead = false;
- bool _drainedIncomingCommands = false;
-
- // TODO(ahe): Get rid of this. See also issue 67.
- bool silent = false;
-
- /// When true, messages generated by this class (or its subclasses) will not
- /// contain IDs. Note: we only hide these IDs for debugger tests that use
- /// golden files.
- bool hideRawIds = false;
-
- /// When true, don't use colors to highlight focus when printing code.
- /// This is currently only true when running tests to avoid having to deal
- /// with color control characters in the expected files.
- bool colorsDisabled = false;
-
- VmCommand connectionError = new ConnectionError("Connection is closed", null);
-
- FletchVmSession(Socket vmSocket,
- Sink<List<int>> stdoutSink,
- Sink<List<int>> stderrSink)
- : _outgoingSink = vmSocket,
- this.stdoutSink = stdoutSink,
- this.stderrSink = stderrSink,
- _done = vmSocket.done,
- _commandReader = new VmCommandReader(vmSocket, stdoutSink, stderrSink) {
- _done.catchError((_, __) {}).then((_) {
- _connectionIsDead = true;
- });
- }
-
- void writeStdout(String s) {
- if (!silent && stdoutSink != null) stdoutSink.add(UTF8.encode(s));
- }
-
- void writeStdoutLine(String s) => writeStdout("$s\n");
-
- /// Convenience around [runCommands] for running just a single command.
- Future<VmCommand> runCommand(VmCommand command) {
- return runCommands([command]);
- }
-
- /// Sends the given commands to a fletch-vm and reads response commands
- /// (if necessary).
- ///
- /// If all commands have been successfully applied and responses been awaited,
- /// this function will complete with the last received [VmCommand] from the
- /// remote peer (or `null` if there was none).
- Future<VmCommand> runCommands(List<VmCommand> commands) async {
- if (commands.any((VmCommand c) => c.numberOfResponsesExpected == null)) {
- throw new ArgumentError(
- 'The runComands() method will read response commands and therefore '
- 'needs to know how many to read. One of the given commands does'
- 'not specify how many commands the response will have.');
- }
-
- VmCommand lastResponse;
- for (VmCommand command in commands) {
- await sendCommand(command);
- for (int i = 0; i < command.numberOfResponsesExpected; i++) {
- lastResponse = await readNextCommand();
- }
- }
- return lastResponse;
- }
-
- /// Sends all given [VmCommand]s to a fletch-vm.
- Future sendCommands(List<VmCommand> commands) async {
- for (var command in commands) {
- await sendCommand(command);
- }
- }
-
- /// Sends a [VmCommand] to a fletch-vm.
- Future sendCommand(VmCommand command) async {
- if (_connectionIsDead) {
- throw new StateError(
- 'Trying to send command ${command} to fletch-vm, but '
- 'the connection is already closed.');
- }
- command.addTo(_outgoingSink);
- }
-
- /// Will read the next [VmCommand] the fletch-vm sends to us.
- Future<VmCommand> readNextCommand({bool force: true}) async {
- if (_drainedIncomingCommands) {
- return connectionError;
- }
-
- _drainedIncomingCommands = !await _commandReader.iterator.moveNext()
- .catchError((error, StackTrace trace) {
- connectionError = new ConnectionError(error, trace);
- return false;
- });
-
- if (_drainedIncomingCommands && force) {
- return connectionError;
- }
-
- return _commandReader.iterator.current;
- }
-
- /// Closes the connection to the fletch-vm and drains the remaining response
- /// commands.
- ///
- /// If [ignoreExtraCommands] is `false` it will throw a StateError if the
- /// fletch-vm sent any commands.
- Future shutdown({bool ignoreExtraCommands: false}) async {
- await _outgoingSink.close().catchError((_) {});
-
- while (!_drainedIncomingCommands) {
- VmCommand response = await readNextCommand(force: false);
- if (!ignoreExtraCommands && response != null) {
- await kill();
- throw new StateError(
- "Got unexpected command from fletch-vm during shutdown "
- "($response)");
- }
- }
-
- return _done;
- }
-
- Future interrupt() {
- return sendCommand(const ProcessDebugInterrupt());
- }
-
- /// Closes the connection to the fletch-vm. It does not wait until it shuts
- /// down.
- ///
- /// This method will never complete with an exception.
- Future kill() async {
- _connectionIsDead = true;
- _drainedIncomingCommands = true;
-
- await _outgoingSink.close().catchError((_) {});
- var value = _commandReader.iterator.cancel();
- if (value != null) {
- await value.catchError((_) {});
- }
- _drainedIncomingCommands = true;
- }
-}
-
-/// Extends a bare [FletchVmSession] with debugging functionality.
-class Session extends FletchVmSession {
- final IncrementalCompiler compiler;
- final Future processExitCodeFuture;
-
- DebugState debugState;
- FletchSystem fletchSystem;
- bool loaded = false;
- bool running = false;
- bool terminated = false;
-
- Session(Socket fletchVmSocket,
- this.compiler,
- Sink<List<int>> stdoutSink,
- Sink<List<int>> stderrSink,
- [this.processExitCodeFuture])
- : super(fletchVmSocket, stdoutSink, stderrSink) {
- // We send many small packages, so use no-delay.
- fletchVmSocket.setOption(SocketOption.TCP_NODELAY, true);
- // TODO(ajohnsen): Should only be initialized on debug()/testDebugger().
- debugState = new DebugState(this);
- }
-
- Future applyDelta(FletchDelta delta) async {
- VmCommand response = await runCommands(delta.commands);
- fletchSystem = delta.system;
- return response;
- }
-
- Future<HandShakeResult> handShake(String version) async {
- VmCommand command = await runCommand(new HandShake(version));
- if (command != null && command is HandShakeResult) return command;
- return null;
- }
-
- Future disableVMStandardOutput() async {
- await runCommand(const DisableStandardOutput());
- }
-
- // Returns either a [WriteSnapshotResult] or a [ConnectionError].
- Future<VmCommand> writeSnapshot(String snapshotPath) async {
- VmCommand result = await runCommand(new WriteSnapshot(snapshotPath));
- await shutdown();
- return result;
- }
-
- Future enableDebugger() async {
- await runCommand(const Debugging());
- }
-
- Future spawnProcess() async {
- await runCommand(const ProcessSpawnForMain());
- }
-
- Future run() async {
- await spawnProcess();
- loaded = true;
- await runCommand(const ProcessRun());
- // NOTE: The [ProcessRun] command normally results in a
- // [ProcessTerminated] command. But if the compiler emitted a compile time
- // error, the fletch-vm will just halt()/exit() and we therefore get no
- // response.
- var command = await readNextCommand(force: false);
- if (command != null && command is! ProcessTerminated) {
- throw new Exception('Expected process to finish complete with '
- '[ProcessTerminated] but got [$command]');
- }
- await shutdown();
- }
-
- Future<int> debug(
- Stream<String> inputLines,
- Uri base,
- SessionState state,
- {bool echo: false}) async {
- await enableDebugger();
- await spawnProcess();
- return new InputHandler(this, inputLines, echo, base).run(state);
- }
-
- Future terminateSession() async {
- await runCommand(const SessionEnd());
- if (processExitCodeFuture != null) await processExitCodeFuture;
- await shutdown();
- terminated = true;
- }
-
- // This method handles the various responses a command can return to indicate
- // the process has stopped running.
- // The session's state is updated to match the current state of the vm.
- Future<VmCommand> handleProcessStop(VmCommand response) async {
- debugState.reset();
- switch (response.code) {
- case VmCommandCode.UncaughtException:
- case VmCommandCode.ProcessCompileTimeError:
- running = false;
- break;
-
- case VmCommandCode.ProcessTerminated:
- running = false;
- loaded = false;
- // TODO(ahe): Let the caller terminate the session. See issue 67.
- await terminateSession();
- break;
-
- case VmCommandCode.ConnectionError:
- running = false;
- loaded = false;
- await shutdown();
- terminated = true;
- break;
-
- case VmCommandCode.ProcessBreakpoint:
- ProcessBreakpoint command = response;
- var function = fletchSystem.lookupFunctionById(command.functionId);
- debugState.topFrame = new BackTraceFrame(
- function, command.bytecodeIndex, compiler, debugState);
- running = true;
- break;
-
- default:
- throw new StateError(
- "Unhandled response from Fletch VM connection: ${response.code}");
-
- }
- return response;
- }
-
- Future<VmCommand> debugRun() async {
- assert(!loaded);
- assert(!running);
- loaded = true;
- running = true;
- await sendCommand(const ProcessRun());
- return handleProcessStop(await readNextCommand());
- }
-
- Future setBreakpointHelper(String name,
- FletchFunction 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(name, bytecodeIndex, breakpointId);
- debugState.breakpoints[breakpointId] = breakpoint;
- return breakpoint;
- }
-
- // TODO(ager): Let setBreakpoint return a stream instead and deal with
- // error situations such as bytecode indices that are out of bounds for
- // some of the methods with the given name.
- Future setBreakpoint({String methodName, int bytecodeIndex}) async {
- Iterable<FletchFunction> functions =
- fletchSystem.functionsWhere((f) => f.name == methodName);
- List<Breakpoint> breakpoints = [];
- for (FletchFunction function in functions) {
- breakpoints.add(
- await setBreakpointHelper(methodName, function, bytecodeIndex));
- }
- return breakpoints;
- }
-
- Future setFileBreakpointFromPosition(String name,
- Uri file,
- int position) async {
- if (position == null) {
- return null;
- }
- DebugInfo debugInfo = compiler.debugInfoForPosition(
- file,
- position,
- fletchSystem);
- if (debugInfo == null) {
- return null;
- }
- SourceLocation location = debugInfo.locationForPosition(position);
- if (location == null) {
- return null;
- }
- FletchFunction function = debugInfo.function;
- int bytecodeIndex = location.bytecodeIndex;
- return setBreakpointHelper(function.name, function, bytecodeIndex);
- }
-
- Future setFileBreakpointFromPattern(Uri file,
- int line,
- String pattern) async {
- assert(line > 0);
- int position = compiler.positionInFileFromPattern(file, line - 1, pattern);
- return setFileBreakpointFromPosition(
- '$file:$line:$pattern', file, position);
- }
-
- Future 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 doDeleteBreakpoint(int id) async {
- ProcessDeleteBreakpoint response =
- await runCommand(new ProcessDeleteBreakpoint(id));
- assert(response.id == id);
- }
-
- Future<Breakpoint> deleteBreakpoint(int id) async {
- if (!debugState.breakpoints.containsKey(id)) {
- return null;
- }
- await doDeleteBreakpoint(id);
- return debugState.breakpoints.remove(id);
- }
-
- List<Breakpoint> breakpoints() {
- assert(debugState.breakpoints != null);
- return debugState.breakpoints.values.toList();
- }
-
- Iterable<Uri> findSourceFiles(Pattern pattern) {
- return compiler.findSourceFiles(pattern);
- }
-
- bool stepMadeProgress(BackTraceFrame frame) {
- return frame.functionId != debugState.topFrame.functionId ||
- frame.bytecodePointer != debugState.topFrame.bytecodePointer;
- }
-
- Future<VmCommand> stepTo(int functionId, int bcp) async {
- assert(running);
- VmCommand response = await runCommand(new ProcessStepTo(functionId, bcp));
- return handleProcessStop(response);
- }
-
- Future<VmCommand> step() async {
- assert(running);
- final SourceLocation previous = debugState.currentLocation;
- final BackTraceFrame initialFrame = debugState.topFrame;
- VmCommand response;
- do {
- int bcp = debugState.topFrame.stepBytecodePointer(previous);
- if (bcp != -1) {
- response = await stepTo(debugState.topFrame.functionId, bcp);
- } else {
- response = await stepBytecode();
- }
- } while (running &&
- debugState.atLocation(previous) &&
- stepMadeProgress(initialFrame));
- return response;
- }
-
- Future<VmCommand> stepOver() async {
- assert(running);
- VmCommand response;
- final SourceLocation previous = debugState.currentLocation;
- final BackTraceFrame initialFrame = debugState.topFrame;
- do {
- response = await stepOverBytecode();
- } while (running &&
- debugState.atLocation(previous) &&
- stepMadeProgress(initialFrame));
- return response;
- }
-
- Future<VmCommand> stepOut() async {
- assert(running);
- BackTrace trace = await backTrace();
- // If we are at the last frame, just continue. This will either terminate
- // the process or stop at any user configured breakpoints.
- if (trace.visibleFrames <= 1) return cont();
-
- // Since we know there is at least two visible frames at this point stepping
- // out will hit a visible frame before the process terminates, hence we can
- // step out until we either hit another breakpoint or a visible frame, ie.
- // we skip internal frame and stop at the next visible frame.
- SourceLocation return_location = trace.visibleFrame(1).sourceLocation();
- VmCommand response;
- do {
- await sendCommand(const ProcessStepOut());
- ProcessSetBreakpoint setBreakpoint = await readNextCommand();
- assert(setBreakpoint.value != -1);
-
- // handleProcessStop resets the debugState and sets the top frame if it
- // hits either the above setBreakpoint or another breakpoint.
- response = await handleProcessStop(await readNextCommand());
- bool success =
- response is ProcessBreakpoint &&
- response.breakpointId == setBreakpoint.value;
- if (!success) {
- await doDeleteBreakpoint(setBreakpoint.value);
- return response;
- }
- } while (!debugState.topFrame.isVisible);
- if (running && debugState.atLocation(return_location)) {
- response = await step();
- }
- return response;
- }
-
- Future<VmCommand> restart() async {
- assert(loaded);
- assert(debugState.currentBackTrace != null);
- assert(debugState.currentBackTrace.length > 1);
- int frame = debugState.actualCurrentFrameNumber;
- return handleProcessStop(await runCommand(new ProcessRestartFrame(frame)));
- }
-
- Future<VmCommand> stepBytecode() async {
- assert(running);
- return handleProcessStop(await runCommand(const ProcessStep()));
- }
-
- Future<VmCommand> stepOverBytecode() async {
- assert(running);
- await sendCommand(const ProcessStepOver());
- ProcessSetBreakpoint setBreakpoint = await readNextCommand();
- VmCommand response = await handleProcessStop(await readNextCommand());
- bool success =
- response is ProcessBreakpoint &&
- response.breakpointId == setBreakpoint.value;
- if (!success && !terminated && setBreakpoint.value != -1) {
- // Delete the initial one-time breakpoint as it wasn't hit.
- await doDeleteBreakpoint(setBreakpoint.value);
- }
- return response;
- }
-
- Future<VmCommand> cont() async {
- assert(running);
- return handleProcessStop(await runCommand(const ProcessContinue()));
- }
-
- bool selectFrame(int frame) {
- if (debugState.currentBackTrace == null ||
- debugState.currentBackTrace.actualFrameNumber(frame) == -1) {
- return false;
- }
- debugState.currentFrame = frame;
- return true;
- }
-
- BackTrace stackTraceFromBacktraceResponse(
- ProcessBacktrace backtraceResponse) {
- int frames = backtraceResponse.frames;
- BackTrace stackTrace = new BackTrace(frames, debugState);
- for (int i = 0; i < frames; ++i) {
- int functionId = backtraceResponse.functionIds[i];
- FletchFunction function = fletchSystem.lookupFunctionById(functionId);
- if (function == null) {
- function = const FletchFunction.missing();
- }
- stackTrace.addFrame(
- compiler,
- new BackTraceFrame(function,
- backtraceResponse.bytecodeIndices[i],
- compiler,
- debugState));
- }
- return stackTrace;
- }
-
- Future<RemoteObject> uncaughtException() async {
- assert(loaded);
- assert(!terminated);
- if (debugState.currentUncaughtException == null) {
- await sendCommand(const ProcessUncaughtExceptionRequest());
- VmCommand response = await readNextCommand();
- if (response is DartValue) {
- debugState.currentUncaughtException = new RemoteValue(response);
- } else {
- assert(response is InstanceStructure);
- List<DartValue> fields = await readInstanceStructureFields(response);
- debugState.currentUncaughtException =
- new RemoteInstance(response, fields);
- }
- }
- return debugState.currentUncaughtException;
- }
-
- Future<BackTrace> backTrace() async {
- assert(loaded);
- if (debugState.currentBackTrace == null) {
- ProcessBacktrace backtraceResponse =
- await runCommand(const ProcessBacktraceRequest());
- debugState.currentBackTrace =
- stackTraceFromBacktraceResponse(backtraceResponse);
- }
- return debugState.currentBackTrace;
- }
-
- Future<BackTrace> backtraceForFiber(int fiber) async {
- ProcessBacktrace backtraceResponse =
- await runCommand(new ProcessFiberBacktraceRequest(fiber));
- return stackTraceFromBacktraceResponse(backtraceResponse);
- }
-
- Future<List<BackTrace>> fibers() async {
- assert(running);
- await runCommand(const NewMap(MapId.fibers));
- ProcessNumberOfStacks response =
- await runCommand(const ProcessAddFibersToMap());
- int numberOfFibers = response.value;
- List<BackTrace> stacktraces = new List(numberOfFibers);
- for (int i = 0; i < numberOfFibers; i++) {
- stacktraces[i] = await backtraceForFiber(i);
- }
- await runCommand(const DeleteMap(MapId.fibers));
- return stacktraces;
- }
-
- Future<List<int>> processes() async {
- assert(running);
- ProcessGetProcessIdsResult response =
- await runCommand(const ProcessGetProcessIds());
- return response.ids;
- }
-
- Future<BackTrace> processStack(int processId) async {
- assert(running);
- ProcessBacktrace backtraceResponse =
- await runCommand(new ProcessBacktraceRequest(processId));
- return stackTraceFromBacktraceResponse(backtraceResponse);
- }
-
- String dartValueToString(DartValue value) {
- if (value is Instance) {
- Instance i = value;
- String className = fletchSystem.lookupClassById(i.classId).name;
- return "Instance of '$className'";
- } else {
- return value.dartToString();
- }
- }
-
- String instanceStructureToString(InstanceStructure structure,
- List<DartValue> fields) {
- int classId = structure.classId;
- FletchClass klass = fletchSystem.lookupClassById(classId);
-
- // TODO(fletchc-team): This should be more strict and a compiler bug
- // should be reported to the user in order for us to get a bugreport.
- if (klass == null) {
- return 'Unknown (Fletch compiler was unable to find exception class)';
- }
-
- StringBuffer sb = new StringBuffer();
- sb.writeln("Instance of '${klass.name}' {");
- for (int i = 0; i < structure.fields; i++) {
- DartValue value = fields[i];
- String fieldName = debugState.lookupFieldName(klass, i);
- if (fieldName == null) {
- fieldName = '<unnamed>';
- }
- sb.writeln(' $fieldName: ${dartValueToString(value)}');
- }
- sb.write('}');
- return '$sb';
- }
-
- String noSuchMethodErrorToString(List<DartValue> nsmFields) {
- assert(nsmFields.length == 3);
- DartValue receiver = nsmFields[0];
- ClassValue receiverClass = nsmFields[1];
- Integer receiverSelector = nsmFields[2];
- FletchSelector selector = new FletchSelector(receiverSelector.value);
-
- String method =
- fletchSystem.lookupSymbolBySelector(selector.encodedSelector);
- FletchClass klass = fletchSystem.lookupClassById(receiverClass.classId);
- // TODO(ahe): If FletchClass is a synthetic closure class, improve the
- // message. For example, "(local) function `foo` takes 3 arguments, but
- // called with 4" instead of "Class '<internal>' has no method named 'call'
- // that takes 4 arguments".
- String name = klass.name;
- String raw = hideRawIds
- ? "" : " (${receiverClass.classId}::${selector.encodedSelector})";
- // TODO(ahe): Lookup the name in the receiverClass and include that as a
- // suggestion in the error mesage.
- switch (selector.kind) {
- case SelectorKind.Method:
- return "NoSuchMethodError: Class '$name' has no method named "
- "'$method' that takes ${selector.arity} arguments$raw";
-
- case SelectorKind.Getter:
- return "NoSuchMethodError: "
- "Class '$name' has no getter named '$method'$raw";
-
- case SelectorKind.Setter:
- return "NoSuchMethodError: "
- "Class '$name' has no setter named '$method'$raw";
- }
- }
-
- Future<List<DartValue>> readInstanceStructureFields(
- InstanceStructure structure) async {
- List<DartValue> fields = <DartValue>[];
- for (int i = 0; i < structure.fields; i++) {
- fields.add(await readNextCommand());
- }
- return fields;
- }
-
- String exceptionToString(RemoteObject exception) {
- String message;
- if (exception is RemoteValue) {
- message = dartValueToString(exception.value);
- } else if (exception is RemoteInstance) {
- InstanceStructure structure = exception.instance;
- int classId = structure.classId;
- FletchClass klass = fletchSystem.lookupClassById(classId);
-
- FletchBackend backend = compiler.compiler.backend;
- var fletchNoSuchMethodErrorClass = fletchSystem.lookupClassByElement(
- backend.fletchNoSuchMethodErrorClass);
-
- if (klass == fletchNoSuchMethodErrorClass) {
- message = noSuchMethodErrorToString(exception.fields);
- } else {
- message = instanceStructureToString(
- exception.instance, exception.fields);
- }
- } else {
- throw new UnimplementedError();
- }
- return 'Uncaught exception: $message';
- }
-
- Future<RemoteValue> processVariable(String name) async {
- assert(loaded);
- LocalValue local = await lookupValue(name);
- return local != null ? await processLocal(local) : null;
- }
-
- Future<RemoteObject> processVariableStructure(String name) async {
- assert(loaded);
- LocalValue local = await lookupValue(name);
- return local != null ? await processLocalStructure(local) : null;
- }
-
- Future<List<RemoteObject>> processAllVariables() async {
- assert(loaded);
- BackTrace trace = await backTrace();
- ScopeInfo info = trace.scopeInfoForCurrentFrame;
- List<RemoteObject> variables = [];
- for (ScopeInfo current = info;
- current != ScopeInfo.sentinel;
- current = current.previous) {
- variables.add(await processLocal(current.local, current.name));
- }
- return variables;
- }
-
- Future<LocalValue> lookupValue(String name) async {
- assert(loaded);
- BackTrace trace = await backTrace();
- return trace.scopeInfoForCurrentFrame.lookup(name);
- }
-
- Future<RemoteValue> processLocal(LocalValue local, [String name]) async {
- var actualFrameNumber = debugState.actualCurrentFrameNumber;
- VmCommand response = await runCommand(
- new ProcessLocal(actualFrameNumber, local.slot));
- assert(response is DartValue);
- return new RemoteValue(response, name: name);
- }
-
- Future<RemoteObject> processLocalStructure(LocalValue local) async {
- var frameNumber = debugState.actualCurrentFrameNumber;
- await sendCommand(new ProcessLocalStructure(frameNumber, local.slot));
- VmCommand response = await readNextCommand();
- if (response is DartValue) {
- return new RemoteValue(response);
- } else {
- assert(response is InstanceStructure);
- List<DartValue> fields = await readInstanceStructureFields(response);
- return new RemoteInstance(response, fields);
- }
- }
-
- String remoteObjectToString(RemoteObject object) {
- String message;
- if (object is RemoteValue) {
- message = dartValueToString(object.value);
- } else if (object is RemoteInstance) {
- message = instanceStructureToString(object.instance, object.fields);
- } else {
- throw new UnimplementedError();
- }
- if (object.name != null) {
- // Prefix with name.
- message = "${object.name}: $message";
- }
- return message;
- }
-
- bool toggleInternal() {
- debugState.showInternalFrames = !debugState.showInternalFrames;
- if (debugState.currentBackTrace != null) {
- debugState.currentBackTrace.visibilityChanged();
- }
- return debugState.showInternalFrames;
- }
-
- bool toggleVerbose() {
- debugState.verbose = !debugState.verbose;
- return debugState.verbose;
- }
-
- // This method is a helper method for computing the default output for one
- // of the stop command results. There are currently the following stop
- // responses:
- // ProcessTerminated
- // ProcessBreakpoint
- // UncaughtException
- // ProcessCompileError
- // ConnectionError
- Future<String> processStopResponseToString(
- VmCommand response,
- SessionState state) async {
- if (response is UncaughtException) {
- StringBuffer sb = new StringBuffer();
- // Print the exception first, followed by a stack trace.
- RemoteObject exception = await uncaughtException();
- sb.writeln(exceptionToString(exception));
- BackTrace trace = await backTrace();
- assert(trace != null);
- sb.write(trace.format());
- String result = '$sb';
- if (!result.endsWith('\n')) result = '$result\n';
- return result;
-
- } else if (response is ProcessBreakpoint) {
- // Print the current line of source code.
- BackTrace trace = await backTrace();
- assert(trace != null);
- BackTraceFrame topFrame = trace.visibleFrame(0);
- if (topFrame != null) {
- String result;
- if (debugState.verbose) {
- result = topFrame.list(state, contextLines: 0);
- } else {
- result = topFrame.shortString();
- }
- if (!result.endsWith('\n')) result = '$result\n';
- return result;
- }
- } else if (response is ProcessCompileTimeError) {
- // TODO(wibling): add information to ProcessCompileTimeError about the
- // specific error and print here.
- return '';
- } else if (response is ProcessTerminated) {
- return '### process terminated\n';
-
- } else if (response is ConnectionError) {
- return '### lost connection to the virtual machine\n';
- }
- return '';
- }
-}
« no previous file with comments | « pkg/fletchc/lib/vm_commands.dart ('k') | pkg/fletchc/samples/fletchc_driver/target.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698