Index: src/debug.cc |
=================================================================== |
--- src/debug.cc (revision 1810) |
+++ src/debug.cc (working copy) |
@@ -41,6 +41,8 @@ |
#include "stub-cache.h" |
#include "log.h" |
+#include "../include/v8-debug.h" |
+ |
namespace v8 { namespace internal { |
#ifdef ENABLE_DEBUGGER_SUPPORT |
@@ -377,7 +379,9 @@ |
// is set the patching performed by the runtime system will take place in |
// the code copy and will therefore have no effect on the running code |
// keeping it from using the inlined code. |
- if (code->is_keyed_load_stub()) KeyedLoadIC::ClearInlinedVersion(pc()); |
+ if (code->is_keyed_load_stub() && KeyedLoadIC::HasInlinedVersion(pc())) { |
+ KeyedLoadIC::ClearInlinedVersion(pc()); |
+ } |
} |
} |
@@ -1552,8 +1556,8 @@ |
return; |
} |
- // Process debug event |
- ProcessDebugEvent(v8::Exception, event_data, false); |
+ // Process debug event. |
+ ProcessDebugEvent(v8::Exception, Handle<JSObject>::cast(event_data), false); |
// Return to continue execution from where the exception was thrown. |
} |
@@ -1584,8 +1588,10 @@ |
return; |
} |
- // Process debug event |
- ProcessDebugEvent(v8::Break, event_data, auto_continue); |
+ // Process debug event. |
+ ProcessDebugEvent(v8::Break, |
+ Handle<JSObject>::cast(event_data), |
+ auto_continue); |
} |
@@ -1609,8 +1615,10 @@ |
return; |
} |
- // Process debug event |
- ProcessDebugEvent(v8::BeforeCompile, event_data, true); |
+ // Process debug event. |
+ ProcessDebugEvent(v8::BeforeCompile, |
+ Handle<JSObject>::cast(event_data), |
+ true); |
} |
@@ -1670,8 +1678,10 @@ |
if (caught_exception) { |
return; |
} |
- // Process debug event |
- ProcessDebugEvent(v8::AfterCompile, event_data, true); |
+ // Process debug event. |
+ ProcessDebugEvent(v8::AfterCompile, |
+ Handle<JSObject>::cast(event_data), |
+ true); |
} |
@@ -1696,12 +1706,12 @@ |
return; |
} |
// Process debug event. |
- ProcessDebugEvent(v8::NewFunction, event_data, true); |
+ ProcessDebugEvent(v8::NewFunction, Handle<JSObject>::cast(event_data), true); |
} |
void Debugger::ProcessDebugEvent(v8::DebugEvent event, |
- Handle<Object> event_data, |
+ Handle<JSObject> event_data, |
bool auto_continue) { |
HandleScope scope; |
@@ -1713,7 +1723,10 @@ |
} |
// First notify the message handler if any. |
if (message_handler_ != NULL) { |
- NotifyMessageHandler(event, exec_state, event_data, auto_continue); |
+ NotifyMessageHandler(event, |
+ Handle<JSObject>::cast(exec_state), |
+ event_data, |
+ auto_continue); |
} |
// Notify registered debug event listener. This can be either a C or a |
// JavaScript function. |
@@ -1725,7 +1738,7 @@ |
FUNCTION_CAST<v8::Debug::EventCallback>(callback_obj->proxy()); |
callback(event, |
v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)), |
- v8::Utils::ToLocal(Handle<JSObject>::cast(event_data)), |
+ v8::Utils::ToLocal(event_data), |
v8::Utils::ToLocal(Handle<Object>::cast(event_listener_data_))); |
} else { |
// JavaScript debug event listener. |
@@ -1736,7 +1749,7 @@ |
const int argc = 4; |
Object** argv[argc] = { Handle<Object>(Smi::FromInt(event)).location(), |
exec_state.location(), |
- event_data.location(), |
+ Handle<Object>::cast(event_data).location(), |
event_listener_data_.location() }; |
Handle<Object> result = Execution::TryCall(fun, Top::global(), |
argc, argv, &caught_exception); |
@@ -1766,8 +1779,8 @@ |
void Debugger::NotifyMessageHandler(v8::DebugEvent event, |
- Handle<Object> exec_state, |
- Handle<Object> event_data, |
+ Handle<JSObject> exec_state, |
+ Handle<JSObject> event_data, |
bool auto_continue) { |
HandleScope scope; |
@@ -1802,7 +1815,12 @@ |
// Notify the debugger that a debug event has occurred unless auto continue is |
// active in which case no event is send. |
if (sendEventMessage) { |
- InvokeMessageHandlerWithEvent(event_data); |
+ MessageImpl message = MessageImpl::NewEvent( |
+ event, |
+ auto_continue, |
+ Handle<JSObject>::cast(exec_state), |
+ Handle<JSObject>::cast(event_data)); |
+ InvokeMessageHandler(message); |
} |
if (auto_continue && !HasCommands()) { |
return; |
@@ -1857,7 +1875,6 @@ |
request = v8::String::New(command.text().start(), |
command.text().length()); |
- command.text().Dispose(); |
static const int kArgc = 1; |
v8::Handle<Value> argv[kArgc] = { request }; |
v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv); |
@@ -1894,7 +1911,15 @@ |
} |
// Return the result. |
- InvokeMessageHandler(response, command.client_data()); |
+ MessageImpl message = MessageImpl::NewResponse( |
+ event, |
+ running, |
+ Handle<JSObject>::cast(exec_state), |
+ Handle<JSObject>::cast(event_data), |
+ Handle<String>(Utils::OpenHandle(*response)), |
+ command.client_data()); |
+ InvokeMessageHandler(message); |
+ command.Dispose(); |
// Return from debug event processing if either the VM is put into the |
// runnning state (through a continue command) or auto continue is active |
@@ -1965,57 +1990,16 @@ |
// Calls the registered debug message handler. 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::InvokeMessageHandler(v8::Handle<v8::String> output, |
- v8::Debug::ClientData* data) { |
+// public API. |
+void Debugger::InvokeMessageHandler(MessageImpl message) { |
ScopedLock with(debugger_access_); |
if (message_handler_ != NULL) { |
- Vector<uint16_t> text = Vector<uint16_t>::New(output->Length()); |
- output->Write(text.start(), 0, output->Length()); |
- |
- message_handler_(text.start(), |
- text.length(), |
- data); |
- |
- text.Dispose(); |
+ message_handler_(message); |
} |
- delete data; |
} |
-bool Debugger::InvokeMessageHandlerWithEvent(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); |
- } |
- InvokeMessageHandler(json_event_string, |
- NULL /* no user data since there was no request */); |
- } else { |
- InvokeMessageHandler(v8::String::Empty(), NULL); |
- } |
- } else { |
- PrintLn(try_catch.Exception()); |
- return false; |
- } |
- return true; |
-} |
- |
- |
// 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 |
@@ -2098,6 +2082,107 @@ |
} |
+MessageImpl MessageImpl::NewEvent(DebugEvent event, |
+ bool running, |
+ Handle<JSObject> exec_state, |
+ Handle<JSObject> event_data) { |
+ MessageImpl message(true, event, running, |
+ exec_state, event_data, Handle<String>(), NULL); |
+ return message; |
+} |
+ |
+ |
+MessageImpl MessageImpl::NewResponse(DebugEvent event, |
+ bool running, |
+ Handle<JSObject> exec_state, |
+ Handle<JSObject> event_data, |
+ Handle<String> response_json, |
+ v8::Debug::ClientData* client_data) { |
+ MessageImpl message(false, event, running, |
+ exec_state, event_data, response_json, client_data); |
+ return message; |
+} |
+ |
+ |
+MessageImpl::MessageImpl(bool is_event, |
+ DebugEvent event, |
+ bool running, |
+ Handle<JSObject> exec_state, |
+ Handle<JSObject> event_data, |
+ Handle<String> response_json, |
+ v8::Debug::ClientData* client_data) |
+ : is_event_(is_event), |
+ event_(event), |
+ running_(running), |
+ exec_state_(exec_state), |
+ event_data_(event_data), |
+ response_json_(response_json), |
+ client_data_(client_data) {} |
+ |
+ |
+bool MessageImpl::IsEvent() const { |
+ return is_event_; |
+} |
+ |
+ |
+bool MessageImpl::IsResponse() const { |
+ return !is_event_; |
+} |
+ |
+ |
+DebugEvent MessageImpl::GetEvent() const { |
+ return event_; |
+} |
+ |
+ |
+bool MessageImpl::WillStartRunning() const { |
+ return running_; |
+} |
+ |
+ |
+v8::Handle<v8::Object> MessageImpl::GetExecutionState() const { |
+ return v8::Utils::ToLocal(exec_state_); |
+} |
+ |
+ |
+v8::Handle<v8::Object> MessageImpl::GetEventData() const { |
+ return v8::Utils::ToLocal(event_data_); |
+} |
+ |
+ |
+v8::Handle<v8::String> MessageImpl::GetJSON() const { |
+ v8::HandleScope scope; |
+ |
+ if (IsEvent()) { |
+ // Call toJSONProtocol on the debug event object. |
+ Handle<Object> fun = GetProperty(event_data_, "toJSONProtocol"); |
+ if (!fun->IsJSFunction()) { |
+ return v8::Handle<v8::String>(); |
+ } |
+ bool caught_exception; |
+ Handle<Object> json = Execution::TryCall(Handle<JSFunction>::cast(fun), |
+ event_data_, |
+ 0, NULL, &caught_exception); |
+ if (caught_exception || !json->IsString()) { |
+ return v8::Handle<v8::String>(); |
+ } |
+ return scope.Close(v8::Utils::ToLocal(Handle<String>::cast(json))); |
+ } else { |
+ return v8::Utils::ToLocal(response_json_); |
+ } |
+} |
+ |
+ |
+v8::Handle<v8::Context> MessageImpl::GetEventContext() const { |
+ return v8::Handle<v8::Context>(); |
+} |
+ |
+ |
+v8::Debug::ClientData* MessageImpl::GetClientData() const { |
+ return client_data_; |
+} |
+ |
+ |
CommandMessage::CommandMessage() : text_(Vector<uint16_t>::empty()), |
client_data_(NULL) { |
} |