};
-// Convenience function for C debugger code to process a text command. This
-// function converts the text command to a JSON request, performs the request
-// and converts the request to a text result for display. The result is an
-// object containing the text result and the intermediate results.
-DebugCommandProcessor.prototype.processDebugCommand = function (command) {
- var request;
- var response;
- var text_result;
- var running;
-
- request = this.commandToJSONRequest(command);
- response = this.processDebugJSONRequest(request);
- text_result = this.responseToText(response);
- running = this.isRunning(response);
-
- return { "request" : request,
- "response" : response,
- "text_result" : text_result,
- "running" : running };
+DebugCommandProcessor.prototype.processDebugRequest = function (request) {
+ return this.processDebugJSONRequest(request);
}
-// Converts a text command to a JSON request.
-DebugCommandProcessor.prototype.commandToJSONRequest = function(cmd_line) {
- // If the wery first character is a { assume that a JSON request have been
- // entered as a command. Converting that to a JSON request is trivial.
- if (cmd_line && cmd_line.length > 0 && cmd_line.charAt(0) == '{') {
- return cmd_line;
- }
-
- // Trim string for leading and trailing whitespace.
- cmd_line = cmd_line.replace(/^\s+|\s+$/g, "");
-
- // Find the command.
- var pos = cmd_line.indexOf(" ");
- var cmd;
- var args;
- if (pos == -1) {
- cmd = cmd_line;
- args = "";
- } else {
- cmd = cmd_line.slice(0, pos);
- args = cmd_line.slice(pos).replace(/^\s+|\s+$/g, "");
- }
-
- // Switch on command.
- if (cmd == 'continue' || cmd == 'c') {
- return this.continueCommandToJSONRequest_(args);
- } else if (cmd == 'step' || cmd == 's') {
- return this.stepCommandToJSONRequest_(args);
- } else if (cmd == 'backtrace' || cmd == 'bt') {
- return this.backtraceCommandToJSONRequest_(args);
- } else if (cmd == 'frame' || cmd == 'f') {
- return this.frameCommandToJSONRequest_(args);
- } else if (cmd == 'print' || cmd == 'p') {
- return this.printCommandToJSONRequest_(args);
- } else if (cmd == 'source') {
- return this.sourceCommandToJSONRequest_(args);
- } else if (cmd == 'scripts') {
- return this.scriptsCommandToJSONRequest_(args);
- } else if (cmd[0] == '{') {
- return cmd_line;
- } else {
- throw new Error('Unknown command "' + cmd + '"');
- }
-};
-
-
-// Create a JSON request for the continue command.
-DebugCommandProcessor.prototype.continueCommandToJSONRequest_ = function(args) {
- var request = this.createRequest('continue');
- return request.toJSONProtocol();
-};
-
-
-// Create a JSON request for the step command.
-DebugCommandProcessor.prototype.stepCommandToJSONRequest_ = function(args) {
- // Requesting a step is through the continue command with additional
- // arguments.
- var request = this.createRequest('continue');
- request.arguments = {};
-
- // Process arguments if any.
- if (args && args.length > 0) {
- args = args.split(/\s*[ ]+\s*/g);
-
- if (args.length > 2) {
- throw new Error('Invalid step arguments.');
- }
-
- if (args.length > 0) {
- // Get step count argument if any.
- if (args.length == 2) {
- request.arguments.stepcount = %ToNumber(args[1]);
- }
-
- // Get the step action.
- if (args[0] == 'in' || args[0] == 'i') {
- request.arguments.stepaction = 'in';
- } else if (args[0] == 'min' || args[0] == 'm') {
- request.arguments.stepaction = 'min';
- } else if (args[0] == 'next' || args[0] == 'n') {
- request.arguments.stepaction = 'next';
- } else if (args[0] == 'out' || args[0] == 'o') {
- request.arguments.stepaction = 'out';
- } else {
- throw new Error('Invalid step argument "' + args[0] + '".');
- }
- }
- } else {
- // Default is step next.
- request.arguments.stepaction = 'next';
- }
-
- return request.toJSONProtocol();
-};
-
-
-// Create a JSON request for the backtrace command.
-DebugCommandProcessor.prototype.backtraceCommandToJSONRequest_ = function(args) {
- // Build a backtrace request from the text command.
- var request = this.createRequest('backtrace');
- args = args.split(/\s*[ ]+\s*/g);
- if (args.length == 2) {
- request.arguments = {};
- request.arguments.fromFrame = %ToNumber(args[0]);
- request.arguments.toFrame = %ToNumber(args[1]) + 1;
- }
- return request.toJSONProtocol();
-};
-
-
-// Create a JSON request for the frame command.
-DebugCommandProcessor.prototype.frameCommandToJSONRequest_ = function(args) {
- // Build a frame request from the text command.
- var request = this.createRequest('frame');
- args = args.split(/\s*[ ]+\s*/g);
- if (args.length > 0 && args[0].length > 0) {
- request.arguments = {};
- request.arguments.number = args[0];
- }
- return request.toJSONProtocol();
-};
-
-
-// Create a JSON request for the print command.
-DebugCommandProcessor.prototype.printCommandToJSONRequest_ = function(args) {
- // Build a evaluate request from the text command.
- var request = this.createRequest('evaluate');
- if (args.length == 0) {
- throw new Error('Missing expression.');
- }
-
- request.arguments = {};
- request.arguments.expression = args;
-
- return request.toJSONProtocol();
-};
-
-
-// Create a JSON request for the source command.
-DebugCommandProcessor.prototype.sourceCommandToJSONRequest_ = function(args) {
- // Build a evaluate request from the text command.
- var request = this.createRequest('source');
-
- // Default is one line before and two lines after current location.
- var before = 1;
- var after = 2;
-
- // Parse the arguments.
- args = args.split(/\s*[ ]+\s*/g);
- if (args.length > 1 && args[0].length > 0 && args[1].length > 0) {
- before = %ToNumber(args[0]);
- after = %ToNumber(args[1]);
- } else if (args.length > 0 && args[0].length > 0) {
- after = %ToNumber(args[0]);
- }
-
- // Request source arround current source location.
- request.arguments = {};
- request.arguments.fromLine = this.exec_state_.frame().sourceLine() - before;
- if (request.arguments.fromLine < 0) {
- request.arguments.fromLine = 0
- }
- request.arguments.toLine = this.exec_state_.frame().sourceLine() + after + 1;
-
- return request.toJSONProtocol();
-};
-
-
-// Create a JSON request for the scripts command.
-DebugCommandProcessor.prototype.scriptsCommandToJSONRequest_ = function(args) {
- // Build a evaluate request from the text command.
- var request = this.createRequest('scripts');
-
- // Process arguments if any.
- if (args && args.length > 0) {
- args = args.split(/\s*[ ]+\s*/g);
-
- if (args.length > 1) {
- throw new Error('Invalid scripts arguments.');
- }
-
- request.arguments = {};
- if (args[0] == 'natives') {
- request.arguments.types = ScriptTypeFlag(Debug.ScriptType.Native);
- } else if (args[0] == 'extensions') {
- request.arguments.types = ScriptTypeFlag(Debug.ScriptType.Extension);
- } else if (args[0] == 'all') {
- request.arguments.types =
- ScriptTypeFlag(Debug.ScriptType.Normal) |
- ScriptTypeFlag(Debug.ScriptType.Native) |
- ScriptTypeFlag(Debug.ScriptType.Extension);
- } else {
- throw new Error('Invalid argument "' + args[0] + '".');
- }
- }
-
- return request.toJSONProtocol();
-};
-
-
-// Convert a JSON response to text for display in a text based debugger.
-DebugCommandProcessor.prototype.responseToText = function(json_response) {
- try {
- // Convert the JSON string to an object.
- response = %CompileString('(' + json_response + ')', 0, false)();
-
- if (!response.success) {
- return response.message;
- }
-
- if (response.command == 'backtrace') {
- var body = response.body;
- var result = 'Frames #' + body.fromFrame + ' to #' +
- (body.toFrame - 1) + ' of ' + body.totalFrames + '\n';
- for (i = 0; i < body.frames.length; i++) {
- if (i != 0) result += '\n';
- result += body.frames[i].text;
- }
- return result;
- } else if (response.command == 'frame') {
- return SourceUnderline(response.body.sourceLineText,
- response.body.column);
- } else if (response.command == 'evaluate') {
- return response.body.text;
- } else if (response.command == 'source') {
- // Get the source from the response.
- var source = response.body.source;
-
- // Get rid of last line terminator.
- var remove_count = 0;
- if (source[source.length - 1] == '\n') remove_count++;
- if (source[source.length - 2] == '\r') remove_count++;
- if (remove_count > 0) source = source.substring(0, source.length - remove_count);
-
- return source;
- } else if (response.command == 'scripts') {
- var result = '';
- for (i = 0; i < response.body.length; i++) {
- if (i != 0) result += '\n';
- if (response.body[i].name) {
- result += response.body[i].name;
- } else {
- result += '[unnamed] ';
- var sourceStart = response.body[i].sourceStart;
- if (sourceStart.length > 40) {
- sourceStart = sourceStart.substring(0, 37) + '...';
- }
- result += sourceStart;
- }
- result += ' (lines: ';
- result += response.body[i].sourceLines;
- result += ', length: ';
- result += response.body[i].sourceLength;
- if (response.body[i].type == Debug.ScriptType.Native) {
- result += ', native';
- } else if (response.body[i].type == Debug.ScriptType.Extension) {
- result += ', extension';
- }
- result += ')';
- }
- return result;
- }
- } catch (e) {
- return 'Error: "' + %ToString(e) + '" formatting response';
- }
-};
-
-
-function SourceUnderline(source_text, position) {
- if (IS_UNDEFINED(source_text)) {
- return;
- }
-
- // Create an underline with a caret pointing to the source position. If the
- // source contains a tab character the underline will have a tab character in
- // the same place otherwise the underline will have a space character.
- var underline = '';
- for (var i = 0; i < position; i++) {
- if (source_text[i] == '\t') {
- underline += '\t';
- } else {
- underline += ' ';
- }
- }
- underline += '^';
-
- // Return the source line text with the underline beneath.
- return source_text + '\n' + underline;
-}
-
-
-function FrameSourceUnderline(frame) {
- var location = frame.sourceLocation();
- if (location) {
- return SourceUnderline(location.sourceText(), location.position - location.start);
- }
+DebugCommandProcessor.prototype.responseIsRunning = function (response) {
+ return this.isRunning(response);
}
host_running_ = false;
SetEventJSONFromEvent(event_data);
- // Wait for commands from the debugger.
+ // Wait for requests from the debugger.
while (true) {
command_received_->Wait();
- Logger::DebugTag("Get command from command queue, in interactive loop.");
+ Logger::DebugTag("Got request from command queue, in interactive loop.");
Vector<uint16_t> command = command_queue_.Get();
ASSERT(!host_running_);
if (!Debugger::debugger_active()) {
return;
}
- // Invoke the JavaScript to convert the debug command line to a JSON
- // request, invoke the JSON request and convert the JSON response to a text
- // representation.
+ // Invoke the JavaScript to process the debug request.
v8::Local<v8::String> fun_name;
v8::Local<v8::Function> fun;
- v8::Local<v8::Value> args[1];
+ v8::Local<v8::Value> request;
v8::TryCatch try_catch;
- fun_name = v8::String::New("processDebugCommand");
+ fun_name = v8::String::New("processDebugRequest");
fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
- args[0] = v8::String::New(reinterpret_cast<uint16_t*>(command.start()),
+ request = v8::String::New(reinterpret_cast<uint16_t*>(command.start()),
command.length());
- v8::Local<v8::Value> result_val = fun->Call(cmd_processor, 1, args);
+ static const int kArgc = 1;
+ v8::Handle<Value> argv[kArgc] = { request };
+ v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv);
- // Get the result of the command.
- v8::Local<v8::String> result_string;
+ // Get the response.
+ v8::Local<v8::String> response;
bool running = false;
if (!try_catch.HasCaught()) {
- // Get the result as an object.
- v8::Local<v8::Object> result = v8::Object::Cast(*result_val);
+ // Get response string.
+ if (!response_val->IsUndefined()) {
+ response = v8::String::Cast(*response_val);
+ } else {
+ response = v8::String::New("");
+ }
// Log the JSON request/response.
if (FLAG_trace_debug_json) {
- PrintLn(result->Get(v8::String::New("request")));
- PrintLn(result->Get(v8::String::New("response")));
+ PrintLn(request);
+ PrintLn(response);
}
// Get the running state.
- running = result->Get(v8::String::New("running"))->ToBoolean()->Value();
-
- // Get result text.
- v8::Local<v8::Value> text_result =
- result->Get(v8::String::New("response"));
- if (!text_result->IsUndefined()) {
- result_string = text_result->ToString();
- } else {
- result_string = v8::String::New("");
+ fun_name = v8::String::New("isRunning");
+ fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
+ static const int kArgc = 1;
+ v8::Handle<Value> argv[kArgc] = { response };
+ v8::Local<v8::Value> running_val = fun->Call(cmd_processor, kArgc, argv);
+ if (!try_catch.HasCaught()) {
+ running = running_val->ToBoolean()->Value();
}
} else {
// In case of failure the result text is the exception text.
- result_string = try_catch.Exception()->ToString();
+ response = try_catch.Exception()->ToString();
}
// Convert text result to C string.
- v8::String::Value val(result_string);
+ v8::String::Value val(response);
Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),
- result_string->Length());
+ response->Length());
// Set host_running_ correctly for nested debugger evaluations.
host_running_ = running;