d8-debug.cc 4.19 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4

5 6
#include "src/d8.h"
#include "src/d8-debug.h"
7 8 9

namespace v8 {

10 11 12
void PrintPrompt(bool is_running) {
  const char* prompt = is_running? "> " : "dbg> ";
  printf("%s", prompt);
13 14 15
  fflush(stdout);
}

16

17
void HandleDebugEvent(const Debug::EventDetails& event_details) {
18 19 20
  // TODO(svenpanne) There should be a way to retrieve this in the callback.
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);
21

22
  DebugEvent event = event_details.GetEvent();
23 24 25 26
  // Check for handled event.
  if (event != Break && event != Exception && event != AfterCompile) {
    return;
  }
27 28 29

  TryCatch try_catch;

30
  // Get the toJSONProtocol function on the event and get the JSON format.
31 32
  Local<String> to_json_fun_name =
      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 37
  Local<Value> event_json = to_json_fun->Call(event_data, 0, NULL);
  if (try_catch.HasCaught()) {
38
    Shell::ReportException(isolate, &try_catch);
39 40 41
    return;
  }

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 48
    return;
  }
49
  String::Utf8Value str(details->Get(String::NewFromUtf8(isolate, "text")));
50
  if (str.length() == 0) {
51 52 53
    // Empty string is used to signal not to process this event.
    return;
  }
54 55 56
  printf("%s\n", *str);

  // Get the debug command processor.
57 58
  Local<String> fun_name =
      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 66 67 68 69 70 71
    return;
  }

  static const int kBufferSize = 256;
  bool running = false;
  while (!running) {
    char command[kBufferSize];
72
    PrintPrompt(running);
73 74 75 76 77 78 79 80 81
    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.
82 83
    Handle<Value> request = Shell::DebugCommandToJSONRequest(
        isolate, String::NewFromUtf8(isolate, command));
84
    if (try_catch.HasCaught()) {
85
      Shell::ReportException(isolate, &try_catch);
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
      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.
104
    fun_name = String::NewFromUtf8(isolate, "processDebugRequest");
105 106 107 108
    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()) {
109
      Shell::ReportException(isolate, &try_catch);
110 111 112 113 114
      continue;
    }
    Handle<String> response = Handle<String>::Cast(response_val);

    // Convert the debugger response into text details and the running state.
115 116
    Handle<Object> response_details =
        Shell::DebugMessageDetails(isolate, response);
117
    if (try_catch.HasCaught()) {
118
      Shell::ReportException(isolate, &try_catch);
119 120
      continue;
    }
121 122
    String::Utf8Value text_str(
        response_details->Get(String::NewFromUtf8(isolate, "text")));
123 124 125
    if (text_str.length() > 0) {
      printf("%s\n", *text_str);
    }
126
    running = response_details->Get(String::NewFromUtf8(isolate, "running"))
127
                  ->ToBoolean(isolate)
128
                  ->Value();
129 130 131 132
  }
}

}  // namespace v8