⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 debug.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
  // Bail out based on state or if there is no listener for this event  if (Debug::InDebugger()) return;  if (compiling_natives()) return;  if (!Debugger::EventActive(v8::NewFunction)) return;  // Enter the debugger.  Bail out if the debugger cannot be loaded.  if (!Debug::Load()) return;  SaveBreakFrame save;  EnterDebuggerContext enter;  // Create the event object.  bool caught_exception = false;  Handle<Object> event_data = MakeNewFunctionEvent(function, &caught_exception);  // Bail out and don't call debugger if exception.  if (caught_exception) {    return;  }  // Process debug event.  ProcessDebugEvent(v8::NewFunction, event_data);}void Debugger::ProcessDebugEvent(v8::DebugEvent event,                                 Handle<Object> event_data) {  // Create the execution state.  bool caught_exception = false;  Handle<Object> exec_state = MakeExecutionState(&caught_exception);  if (caught_exception) {    return;  }  // First notify the builtin debugger.  if (message_thread_ != NULL) {    message_thread_->DebugEvent(event, exec_state, event_data);  }  // Notify registered debug event listeners. The list can contain both C and  // JavaScript functions.  v8::NeanderArray listeners(Factory::debug_event_listeners());  int length = listeners.length();  for (int i = 0; i < length; i++) {    if (listeners.get(i)->IsUndefined()) continue;   // Skip deleted ones.    v8::NeanderObject listener(JSObject::cast(listeners.get(i)));    Handle<Object> callback_data(listener.get(1));    if (listener.get(0)->IsProxy()) {      // C debug event listener.      Handle<Proxy> callback_obj(Proxy::cast(listener.get(0)));      v8::DebugEventCallback callback =            FUNCTION_CAST<v8::DebugEventCallback>(callback_obj->proxy());      callback(event,               v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)),               v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)),               v8::Utils::ToLocal(callback_data));    } else {      // JavaScript debug event listener.      ASSERT(listener.get(0)->IsJSFunction());      Handle<JSFunction> fun(JSFunction::cast(listener.get(0)));      // Invoke the JavaScript debug event listener.      const int argc = 4;      Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(),                              exec_state.location(),                              event_data.location(),                              callback_data.location() };      Handle<Object> result = Execution::TryCall(fun, Top::global(),                                                 argc, argv, &caught_exception);      if (caught_exception) {        // Silently ignore exceptions from debug event listeners.      }    }  }}void Debugger::SetMessageHandler(v8::DebugMessageHandler handler, void* data) {  debug_message_handler_ = handler;  debug_message_handler_data_ = data;  if (!message_thread_) {    message_thread_  = new DebugMessageThread();    message_thread_->Start();  }  UpdateActiveDebugger();}// Posts an output message from the debugger to the debug_message_handler// callback.  This callback is part of the public API.  Messages are// kept internally as Vector<uint16_t> strings, which are allocated in various// places and deallocated by the calling function sometime after this call.void Debugger::SendMessage(Vector< uint16_t> message) {  if (debug_message_handler_ != NULL) {    debug_message_handler_(message.start(), message.length(),                           debug_message_handler_data_);  }}void Debugger::ProcessCommand(Vector<const uint16_t> command) {  if (message_thread_ != NULL) {    message_thread_->ProcessCommand(        Vector<uint16_t>(const_cast<uint16_t *>(command.start()),                         command.length()));  }}void Debugger::UpdateActiveDebugger() {  v8::NeanderArray listeners(Factory::debug_event_listeners());  int length = listeners.length();  bool active_listener = false;  for (int i = 0; i < length && !active_listener; i++) {    active_listener = !listeners.get(i)->IsUndefined();  }  set_debugger_active((Debugger::message_thread_ != NULL &&                       Debugger::debug_message_handler_ != NULL) ||                       active_listener);  if (!debugger_active() && message_thread_)    message_thread_->OnDebuggerInactive();}DebugMessageThread::DebugMessageThread()    : host_running_(true),      command_queue_(kQueueInitialSize),      message_queue_(kQueueInitialSize) {  command_received_ = OS::CreateSemaphore(0);  message_received_ = OS::CreateSemaphore(0);}// Does not free resources held by DebugMessageThread// because this cannot be done thread-safely.DebugMessageThread::~DebugMessageThread() {}// Puts an event coming from V8 on the queue.  Creates// a copy of the JSON formatted event string managed by the V8.// Called by the V8 thread.// The new copy of the event string is destroyed in Run().void DebugMessageThread::SendMessage(Vector<uint16_t> message) {  Vector<uint16_t> message_copy = message.Clone();  Logger::DebugTag("Put message on event message_queue.");  message_queue_.Put(message_copy);  message_received_->Signal();}void DebugMessageThread::SetEventJSONFromEvent(Handle<Object> event_data) {  v8::HandleScope scope;  // Call toJSONProtocol on the debug event object.  v8::Local<v8::Object> api_event_data =      v8::Utils::ToLocal(Handle<JSObject>::cast(event_data));  v8::Local<v8::String> fun_name = v8::String::New("toJSONProtocol");  v8::Local<v8::Function> fun =      v8::Function::Cast(*api_event_data->Get(fun_name));  v8::TryCatch try_catch;  v8::Local<v8::Value> json_event = *fun->Call(api_event_data, 0, NULL);  v8::Local<v8::String> json_event_string;  if (!try_catch.HasCaught()) {    if (!json_event->IsUndefined()) {      json_event_string = json_event->ToString();      if (FLAG_trace_debug_json) {        PrintLn(json_event_string);      }      v8::String::Value val(json_event_string);      Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),                          json_event_string->Length());      SendMessage(str);    } else {      SendMessage(Vector<uint16_t>::empty());    }  } else {    PrintLn(try_catch.Exception());    SendMessage(Vector<uint16_t>::empty());  }}void DebugMessageThread::Run() {  // Sends debug events to an installed debugger message callback.  while (true) {    // Wait and Get are paired so that semaphore count equals queue length.    message_received_->Wait();    Logger::DebugTag("Get message from event message_queue.");    Vector<uint16_t> message = message_queue_.Get();    if (message.length() > 0) {      Debugger::SendMessage(message);    }  }}// This method is called by the V8 thread whenever a debug event occurs in// the VM.void DebugMessageThread::DebugEvent(v8::DebugEvent event,                                    Handle<Object> exec_state,                                    Handle<Object> event_data) {  if (!Debug::Load()) return;  // Process the individual events.  bool interactive = false;  switch (event) {    case v8::Break:      interactive = true;  // Break event is always interactive      break;    case v8::Exception:      interactive = true;  // Exception event is always interactive      break;    case v8::BeforeCompile:      break;    case v8::AfterCompile:      break;    case v8::NewFunction:      break;    default:      UNREACHABLE();  }  // Done if not interactive.  if (!interactive) return;  // Get the DebugCommandProcessor.  v8::Local<v8::Object> api_exec_state =      v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state));  v8::Local<v8::String> fun_name =      v8::String::New("debugCommandProcessor");  v8::Local<v8::Function> fun =      v8::Function::Cast(*api_exec_state->Get(fun_name));  v8::TryCatch try_catch;  v8::Local<v8::Object> cmd_processor =      v8::Object::Cast(*fun->Call(api_exec_state, 0, NULL));  if (try_catch.HasCaught()) {    PrintLn(try_catch.Exception());    return;  }  // Notify the debugger that a debug event has occurred.  host_running_ = false;  SetEventJSONFromEvent(event_data);  // Wait for commands from the debugger.  while (true) {    command_received_->Wait();    Logger::DebugTag("Get command from command queue, in interactive loop.");    Vector<uint16_t> command = command_queue_.Get();    ASSERT(!host_running_);    if (!Debugger::debugger_active()) {      host_running_ = true;      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.    v8::Local<v8::String> fun_name;    v8::Local<v8::Function> fun;    v8::Local<v8::Value> args[1];    v8::TryCatch try_catch;    fun_name = v8::String::New("processDebugCommand");    fun = v8::Function::Cast(*cmd_processor->Get(fun_name));    args[0] = v8::String::New(reinterpret_cast<uint16_t*>(command.start()),                              command.length());    v8::Local<v8::Value> result_val = fun->Call(cmd_processor, 1, args);    // Get the result of the command.    v8::Local<v8::String> result_string;    bool running = false;    if (!try_catch.HasCaught()) {      // Get the result as an object.      v8::Local<v8::Object> result = v8::Object::Cast(*result_val);      // Log the JSON request/response.      if (FLAG_trace_debug_json) {        PrintLn(result->Get(v8::String::New("request")));        PrintLn(result->Get(v8::String::New("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("");      }    } else {      // In case of failure the result text is the exception text.      result_string = try_catch.Exception()->ToString();    }    // Convert text result to C string.    v8::String::Value val(result_string);    Vector<uint16_t> str(reinterpret_cast<uint16_t*>(*val),                        result_string->Length());    // Set host_running_ correctly for nested debugger evaluations.    host_running_ = running;    // Return the result.    SendMessage(str);    // Return from debug event processing is VM should be running.    if (running) {      return;    }  }}// Puts a command coming from the public API on the queue.  Creates// a copy of the command string managed by the debugger.  Up to this// point, the command data was managed by the API client.  Called// by the API client thread.  This is where the API client hands off// processing of the command to the DebugMessageThread thread.// The new copy of the command is destroyed in HandleCommand().void DebugMessageThread::ProcessCommand(Vector<uint16_t> command) {  Vector<uint16_t> command_copy = command.Clone();  Logger::DebugTag("Put command on command_queue.");  command_queue_.Put(command_copy);  command_received_->Signal();}void DebugMessageThread::OnDebuggerInactive() {  // Send an empty command to the debugger if in a break to make JavaScript run  // again if the debugger is closed.  if (!host_running_) {    ProcessCommand(Vector<uint16_t>::empty());  }}MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) {  messages_ = NewArray<Vector<uint16_t> >(size);}MessageQueue::~MessageQueue() {  DeleteArray(messages_);}Vector<uint16_t> MessageQueue::Get() {  ASSERT(!IsEmpty());  int result = start_;  start_ = (start_ + 1) % size_;  return messages_[result];}void MessageQueue::Put(const Vector<uint16_t>& message) {  if ((end_ + 1) % size_ == start_) {    Expand();  }  messages_[end_] = message;  end_ = (end_ + 1) % size_;}void MessageQueue::Expand() {  MessageQueue new_queue(size_ * 2);  while (!IsEmpty()) {    new_queue.Put(Get());  }  Vector<uint16_t>* array_to_free = messages_;  *this = new_queue;  new_queue.messages_ = array_to_free;  // Automatic destructor called on new_queue, freeing array_to_free.}LockingMessageQueue::LockingMessageQueue(int size) : queue_(size) {  lock_ = OS::CreateMutex();}LockingMessageQueue::~LockingMessageQueue() {  delete lock_;}bool LockingMessageQueue::IsEmpty() const {  ScopedLock sl(lock_);  return queue_.IsEmpty();}Vector<uint16_t> LockingMess

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -