| OLD | NEW |
| (Empty) |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "src/d8.h" | |
| 6 #include "src/d8-debug.h" | |
| 7 | |
| 8 namespace v8 { | |
| 9 | |
| 10 void PrintPrompt(bool is_running) { | |
| 11 const char* prompt = is_running? "> " : "dbg> "; | |
| 12 printf("%s", prompt); | |
| 13 fflush(stdout); | |
| 14 } | |
| 15 | |
| 16 | |
| 17 void HandleDebugEvent(const Debug::EventDetails& event_details) { | |
| 18 // TODO(svenpanne) There should be a way to retrieve this in the callback. | |
| 19 Isolate* isolate = Isolate::GetCurrent(); | |
| 20 HandleScope scope(isolate); | |
| 21 | |
| 22 DebugEvent event = event_details.GetEvent(); | |
| 23 // Check for handled event. | |
| 24 if (event != Break && event != Exception && event != AfterCompile) { | |
| 25 return; | |
| 26 } | |
| 27 | |
| 28 TryCatch try_catch(isolate); | |
| 29 | |
| 30 // Get the toJSONProtocol function on the event and get the JSON format. | |
| 31 Local<String> to_json_fun_name = | |
| 32 String::NewFromUtf8(isolate, "toJSONProtocol", NewStringType::kNormal) | |
| 33 .ToLocalChecked(); | |
| 34 Local<Object> event_data = event_details.GetEventData(); | |
| 35 Local<Function> to_json_fun = | |
| 36 Local<Function>::Cast(event_data->Get(isolate->GetCurrentContext(), | |
| 37 to_json_fun_name).ToLocalChecked()); | |
| 38 Local<Value> event_json; | |
| 39 if (!to_json_fun->Call(isolate->GetCurrentContext(), event_data, 0, NULL) | |
| 40 .ToLocal(&event_json)) { | |
| 41 Shell::ReportException(isolate, &try_catch); | |
| 42 return; | |
| 43 } | |
| 44 | |
| 45 // Print the event details. | |
| 46 Local<Object> details = | |
| 47 Shell::DebugMessageDetails(isolate, Local<String>::Cast(event_json)); | |
| 48 if (try_catch.HasCaught()) { | |
| 49 Shell::ReportException(isolate, &try_catch); | |
| 50 return; | |
| 51 } | |
| 52 String::Utf8Value str( | |
| 53 details->Get(isolate->GetCurrentContext(), | |
| 54 String::NewFromUtf8(isolate, "text", NewStringType::kNormal) | |
| 55 .ToLocalChecked()).ToLocalChecked()); | |
| 56 if (str.length() == 0) { | |
| 57 // Empty string is used to signal not to process this event. | |
| 58 return; | |
| 59 } | |
| 60 printf("%s\n", *str); | |
| 61 | |
| 62 // Get the debug command processor. | |
| 63 Local<String> fun_name = | |
| 64 String::NewFromUtf8(isolate, "debugCommandProcessor", | |
| 65 NewStringType::kNormal).ToLocalChecked(); | |
| 66 Local<Object> exec_state = event_details.GetExecutionState(); | |
| 67 Local<Function> fun = Local<Function>::Cast( | |
| 68 exec_state->Get(isolate->GetCurrentContext(), fun_name).ToLocalChecked()); | |
| 69 Local<Value> cmd_processor_value; | |
| 70 if (!fun->Call(isolate->GetCurrentContext(), exec_state, 0, NULL) | |
| 71 .ToLocal(&cmd_processor_value)) { | |
| 72 Shell::ReportException(isolate, &try_catch); | |
| 73 return; | |
| 74 } | |
| 75 Local<Object> cmd_processor = Local<Object>::Cast(cmd_processor_value); | |
| 76 | |
| 77 static const int kBufferSize = 256; | |
| 78 bool running = false; | |
| 79 while (!running) { | |
| 80 char command[kBufferSize]; | |
| 81 PrintPrompt(running); | |
| 82 char* str = fgets(command, kBufferSize, stdin); | |
| 83 if (str == NULL) break; | |
| 84 | |
| 85 // Ignore empty commands. | |
| 86 if (strlen(command) == 0) continue; | |
| 87 | |
| 88 TryCatch try_catch(isolate); | |
| 89 | |
| 90 // Convert the debugger command to a JSON debugger request. | |
| 91 Local<Value> request = Shell::DebugCommandToJSONRequest( | |
| 92 isolate, String::NewFromUtf8(isolate, command, NewStringType::kNormal) | |
| 93 .ToLocalChecked()); | |
| 94 if (try_catch.HasCaught()) { | |
| 95 Shell::ReportException(isolate, &try_catch); | |
| 96 continue; | |
| 97 } | |
| 98 | |
| 99 // If undefined is returned the command was handled internally and there is | |
| 100 // no JSON to send. | |
| 101 if (request->IsUndefined()) { | |
| 102 continue; | |
| 103 } | |
| 104 | |
| 105 Local<String> fun_name; | |
| 106 Local<Function> fun; | |
| 107 // All the functions used below take one argument. | |
| 108 static const int kArgc = 1; | |
| 109 Local<Value> args[kArgc]; | |
| 110 | |
| 111 // Invoke the JavaScript to convert the debug command line to a JSON | |
| 112 // request, invoke the JSON request and convert the JSON respose to a text | |
| 113 // representation. | |
| 114 fun_name = String::NewFromUtf8(isolate, "processDebugRequest", | |
| 115 NewStringType::kNormal).ToLocalChecked(); | |
| 116 fun = Local<Function>::Cast(cmd_processor->Get(isolate->GetCurrentContext(), | |
| 117 fun_name).ToLocalChecked()); | |
| 118 args[0] = request; | |
| 119 Local<Value> response_val; | |
| 120 if (!fun->Call(isolate->GetCurrentContext(), cmd_processor, kArgc, args) | |
| 121 .ToLocal(&response_val)) { | |
| 122 Shell::ReportException(isolate, &try_catch); | |
| 123 continue; | |
| 124 } | |
| 125 Local<String> response = Local<String>::Cast(response_val); | |
| 126 | |
| 127 // Convert the debugger response into text details and the running state. | |
| 128 Local<Object> response_details = | |
| 129 Shell::DebugMessageDetails(isolate, response); | |
| 130 if (try_catch.HasCaught()) { | |
| 131 Shell::ReportException(isolate, &try_catch); | |
| 132 continue; | |
| 133 } | |
| 134 String::Utf8Value text_str( | |
| 135 response_details->Get(isolate->GetCurrentContext(), | |
| 136 String::NewFromUtf8(isolate, "text", | |
| 137 NewStringType::kNormal) | |
| 138 .ToLocalChecked()).ToLocalChecked()); | |
| 139 if (text_str.length() > 0) { | |
| 140 printf("%s\n", *text_str); | |
| 141 } | |
| 142 running = response_details->Get(isolate->GetCurrentContext(), | |
| 143 String::NewFromUtf8(isolate, "running", | |
| 144 NewStringType::kNormal) | |
| 145 .ToLocalChecked()) | |
| 146 .ToLocalChecked() | |
| 147 ->ToBoolean(isolate->GetCurrentContext()) | |
| 148 .ToLocalChecked() | |
| 149 ->Value(); | |
| 150 } | |
| 151 } | |
| 152 | |
| 153 } // namespace v8 | |
| OLD | NEW |