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; 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"); 33 Handle<Object> event_data = event_details.GetEventData(); 34 Local<Function> to_json_fun = 35 Local<Function>::Cast(event_data->Get(to_json_fun_name)); 36 Local<Value> event_json = to_json_fun->Call(event_data, 0, NULL); 37 if (try_catch.HasCaught()) { 38 Shell::ReportException(isolate, &try_catch); 39 return; 40 } 41 42 // Print the event details. 43 Handle<Object> details = 44 Shell::DebugMessageDetails(isolate, Handle<String>::Cast(event_json)); 45 if (try_catch.HasCaught()) { 46 Shell::ReportException(isolate, &try_catch); 47 return; 48 } 49 String::Utf8Value str(details->Get(String::NewFromUtf8(isolate, "text"))); 50 if (str.length() == 0) { 51 // Empty string is used to signal not to process this event. 52 return; 53 } 54 printf("%s\n", *str); 55 56 // Get the debug command processor. 57 Local<String> fun_name = 58 String::NewFromUtf8(isolate, "debugCommandProcessor"); 59 Handle<Object> exec_state = event_details.GetExecutionState(); 60 Local<Function> fun = Local<Function>::Cast(exec_state->Get(fun_name)); 61 Local<Object> cmd_processor = 62 Local<Object>::Cast(fun->Call(exec_state, 0, NULL)); 63 if (try_catch.HasCaught()) { 64 Shell::ReportException(isolate, &try_catch); 65 return; 66 } 67 68 static const int kBufferSize = 256; 69 bool running = false; 70 while (!running) { 71 char command[kBufferSize]; 72 PrintPrompt(running); 73 char* str = fgets(command, kBufferSize, stdin); 74 if (str == NULL) break; 75 76 // Ignore empty commands. 77 if (strlen(command) == 0) continue; 78 79 TryCatch try_catch; 80 81 // Convert the debugger command to a JSON debugger request. 82 Handle<Value> request = Shell::DebugCommandToJSONRequest( 83 isolate, String::NewFromUtf8(isolate, command)); 84 if (try_catch.HasCaught()) { 85 Shell::ReportException(isolate, &try_catch); 86 continue; 87 } 88 89 // If undefined is returned the command was handled internally and there is 90 // no JSON to send. 91 if (request->IsUndefined()) { 92 continue; 93 } 94 95 Handle<String> fun_name; 96 Handle<Function> fun; 97 // All the functions used below take one argument. 98 static const int kArgc = 1; 99 Handle<Value> args[kArgc]; 100 101 // Invoke the JavaScript to convert the debug command line to a JSON 102 // request, invoke the JSON request and convert the JSON respose to a text 103 // representation. 104 fun_name = String::NewFromUtf8(isolate, "processDebugRequest"); 105 fun = Handle<Function>::Cast(cmd_processor->Get(fun_name)); 106 args[0] = request; 107 Handle<Value> response_val = fun->Call(cmd_processor, kArgc, args); 108 if (try_catch.HasCaught()) { 109 Shell::ReportException(isolate, &try_catch); 110 continue; 111 } 112 Handle<String> response = Handle<String>::Cast(response_val); 113 114 // Convert the debugger response into text details and the running state. 115 Handle<Object> response_details = 116 Shell::DebugMessageDetails(isolate, response); 117 if (try_catch.HasCaught()) { 118 Shell::ReportException(isolate, &try_catch); 119 continue; 120 } 121 String::Utf8Value text_str( 122 response_details->Get(String::NewFromUtf8(isolate, "text"))); 123 if (text_str.length() > 0) { 124 printf("%s\n", *text_str); 125 } 126 running = response_details->Get(String::NewFromUtf8(isolate, "running")) 127 ->ToBoolean() 128 ->Value(); 129 } 130 } 131 132 } // namespace v8 133