2012-01-19 16:52:16 +00:00
|
|
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
2014-04-29 06:42:26 +00:00
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
2008-12-18 10:06:49 +00:00
|
|
|
|
2014-06-03 08:12:43 +00:00
|
|
|
#include "src/d8.h"
|
|
|
|
#include "src/d8-debug.h"
|
2008-12-18 10:06:49 +00:00
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
|
2011-01-03 07:56:30 +00:00
|
|
|
void PrintPrompt(bool is_running) {
|
|
|
|
const char* prompt = is_running? "> " : "dbg> ";
|
|
|
|
printf("%s", prompt);
|
2010-04-16 12:19:47 +00:00
|
|
|
fflush(stdout);
|
|
|
|
}
|
|
|
|
|
2008-12-18 10:06:49 +00:00
|
|
|
|
2013-07-19 09:38:18 +00:00
|
|
|
void HandleDebugEvent(const Debug::EventDetails& event_details) {
|
2013-03-15 12:06:53 +00:00
|
|
|
// TODO(svenpanne) There should be a way to retrieve this in the callback.
|
|
|
|
Isolate* isolate = Isolate::GetCurrent();
|
|
|
|
HandleScope scope(isolate);
|
2008-12-18 10:06:49 +00:00
|
|
|
|
2013-07-19 09:38:18 +00:00
|
|
|
DebugEvent event = event_details.GetEvent();
|
2009-02-05 10:10:45 +00:00
|
|
|
// Check for handled event.
|
|
|
|
if (event != Break && event != Exception && event != AfterCompile) {
|
|
|
|
return;
|
|
|
|
}
|
2008-12-18 10:06:49 +00:00
|
|
|
|
|
|
|
TryCatch try_catch;
|
|
|
|
|
2009-02-26 11:55:35 +00:00
|
|
|
// Get the toJSONProtocol function on the event and get the JSON format.
|
2013-11-22 12:35:39 +00:00
|
|
|
Local<String> to_json_fun_name =
|
|
|
|
String::NewFromUtf8(isolate, "toJSONProtocol");
|
2013-07-19 09:38:18 +00:00
|
|
|
Handle<Object> event_data = event_details.GetEventData();
|
2009-02-26 11:55:35 +00:00
|
|
|
Local<Function> to_json_fun =
|
2013-06-13 09:27:09 +00:00
|
|
|
Local<Function>::Cast(event_data->Get(to_json_fun_name));
|
2009-02-26 11:55:35 +00:00
|
|
|
Local<Value> event_json = to_json_fun->Call(event_data, 0, NULL);
|
|
|
|
if (try_catch.HasCaught()) {
|
2013-03-15 12:06:53 +00:00
|
|
|
Shell::ReportException(isolate, &try_catch);
|
2009-02-26 11:55:35 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2008-12-18 10:06:49 +00:00
|
|
|
// Print the event details.
|
2009-03-02 19:02:27 +00:00
|
|
|
Handle<Object> details =
|
2013-05-02 20:18:42 +00:00
|
|
|
Shell::DebugMessageDetails(isolate, Handle<String>::Cast(event_json));
|
2009-03-02 19:02:27 +00:00
|
|
|
if (try_catch.HasCaught()) {
|
2013-03-15 12:06:53 +00:00
|
|
|
Shell::ReportException(isolate, &try_catch);
|
2009-03-02 19:02:27 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-11-22 12:35:39 +00:00
|
|
|
String::Utf8Value str(details->Get(String::NewFromUtf8(isolate, "text")));
|
2009-03-02 19:02:27 +00:00
|
|
|
if (str.length() == 0) {
|
2009-02-05 10:10:45 +00:00
|
|
|
// Empty string is used to signal not to process this event.
|
|
|
|
return;
|
|
|
|
}
|
2008-12-18 10:06:49 +00:00
|
|
|
printf("%s\n", *str);
|
|
|
|
|
|
|
|
// Get the debug command processor.
|
2013-11-22 12:35:39 +00:00
|
|
|
Local<String> fun_name =
|
|
|
|
String::NewFromUtf8(isolate, "debugCommandProcessor");
|
2013-07-19 09:38:18 +00:00
|
|
|
Handle<Object> exec_state = event_details.GetExecutionState();
|
2013-06-13 09:27:09 +00:00
|
|
|
Local<Function> fun = Local<Function>::Cast(exec_state->Get(fun_name));
|
2008-12-18 10:06:49 +00:00
|
|
|
Local<Object> cmd_processor =
|
2013-06-13 09:27:09 +00:00
|
|
|
Local<Object>::Cast(fun->Call(exec_state, 0, NULL));
|
2008-12-18 10:06:49 +00:00
|
|
|
if (try_catch.HasCaught()) {
|
2013-03-15 12:06:53 +00:00
|
|
|
Shell::ReportException(isolate, &try_catch);
|
2008-12-18 10:06:49 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const int kBufferSize = 256;
|
|
|
|
bool running = false;
|
|
|
|
while (!running) {
|
|
|
|
char command[kBufferSize];
|
2011-01-03 07:56:30 +00:00
|
|
|
PrintPrompt(running);
|
2008-12-18 10:06:49 +00:00
|
|
|
char* str = fgets(command, kBufferSize, stdin);
|
|
|
|
if (str == NULL) break;
|
|
|
|
|
|
|
|
// Ignore empty commands.
|
|
|
|
if (strlen(command) == 0) continue;
|
|
|
|
|
|
|
|
TryCatch try_catch;
|
|
|
|
|
|
|
|
// Convert the debugger command to a JSON debugger request.
|
2013-11-22 12:35:39 +00:00
|
|
|
Handle<Value> request = Shell::DebugCommandToJSONRequest(
|
|
|
|
isolate, String::NewFromUtf8(isolate, command));
|
2008-12-18 10:06:49 +00:00
|
|
|
if (try_catch.HasCaught()) {
|
2013-03-15 12:06:53 +00:00
|
|
|
Shell::ReportException(isolate, &try_catch);
|
2008-12-18 10:06:49 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If undefined is returned the command was handled internally and there is
|
|
|
|
// no JSON to send.
|
|
|
|
if (request->IsUndefined()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Handle<String> fun_name;
|
|
|
|
Handle<Function> fun;
|
|
|
|
// All the functions used below take one argument.
|
|
|
|
static const int kArgc = 1;
|
|
|
|
Handle<Value> args[kArgc];
|
|
|
|
|
|
|
|
// Invoke the JavaScript to convert the debug command line to a JSON
|
|
|
|
// request, invoke the JSON request and convert the JSON respose to a text
|
|
|
|
// representation.
|
2013-11-22 12:35:39 +00:00
|
|
|
fun_name = String::NewFromUtf8(isolate, "processDebugRequest");
|
2008-12-18 10:06:49 +00:00
|
|
|
fun = Handle<Function>::Cast(cmd_processor->Get(fun_name));
|
|
|
|
args[0] = request;
|
|
|
|
Handle<Value> response_val = fun->Call(cmd_processor, kArgc, args);
|
|
|
|
if (try_catch.HasCaught()) {
|
2013-03-15 12:06:53 +00:00
|
|
|
Shell::ReportException(isolate, &try_catch);
|
2008-12-18 10:06:49 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Handle<String> response = Handle<String>::Cast(response_val);
|
|
|
|
|
|
|
|
// Convert the debugger response into text details and the running state.
|
2013-05-02 20:18:42 +00:00
|
|
|
Handle<Object> response_details =
|
|
|
|
Shell::DebugMessageDetails(isolate, response);
|
2008-12-18 10:06:49 +00:00
|
|
|
if (try_catch.HasCaught()) {
|
2013-03-15 12:06:53 +00:00
|
|
|
Shell::ReportException(isolate, &try_catch);
|
2008-12-18 10:06:49 +00:00
|
|
|
continue;
|
|
|
|
}
|
2013-11-22 12:35:39 +00:00
|
|
|
String::Utf8Value text_str(
|
|
|
|
response_details->Get(String::NewFromUtf8(isolate, "text")));
|
2008-12-18 10:06:49 +00:00
|
|
|
if (text_str.length() > 0) {
|
|
|
|
printf("%s\n", *text_str);
|
|
|
|
}
|
2013-11-22 12:35:39 +00:00
|
|
|
running = response_details->Get(String::NewFromUtf8(isolate, "running"))
|
|
|
|
->ToBoolean()
|
|
|
|
->Value();
|
2008-12-18 10:06:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace v8
|