Commit acb4ff99 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Removed all functions for parsing the debugger command line commands. The core...

Removed all functions for parsing the debugger command line commands. The core debugger should only support the JSON protocol. Expect these functions to re-appear in d8.

Added processDebugRequest to the debugger which will only process a JSON request. Use that function in the debugger.
Review URL: http://codereview.chromium.org/11395

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@824 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 95d1d400
......@@ -891,324 +891,13 @@ function DebugCommandProcessor(exec_state) {
};
// 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);
}
......
......@@ -1769,10 +1769,10 @@ void DebugMessageThread::DebugEvent(v8::DebugEvent event,
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()) {
......@@ -1780,52 +1780,54 @@ void DebugMessageThread::DebugEvent(v8::DebugEvent event,
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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment