Index: src/debug/debug.cc |
diff --git a/src/debug/debug.cc b/src/debug/debug.cc |
index 393fadc72a88d49f511b2c481e04817e89504b59..9d6d14422e31f69f247351e8147a8a278ae7d0e2 100644 |
--- a/src/debug/debug.cc |
+++ b/src/debug/debug.cc |
@@ -1720,6 +1720,23 @@ void Debug::OnPromiseReject(Handle<Object> promise, Handle<Object> value) { |
} |
} |
+namespace { |
+v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) { |
+ Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); |
+ // Isolate::context() may have been NULL when "script collected" event |
+ // occured. |
+ if (context.is_null()) return v8::Local<v8::Context>(); |
+ Handle<Context> native_context(context->native_context()); |
+ return v8::Utils::ToLocal(native_context); |
+} |
+} // anonymous namespace |
+ |
+void Debug::SetExceptionEventListener(debug::ExceptionEventListener listener, |
+ void* data) { |
+ exception_event_listener_ = listener; |
+ exception_event_listener_data_ = data; |
+ UpdateState(); |
+} |
void Debug::OnException(Handle<Object> exception, Handle<Object> promise) { |
// We cannot generate debug events when JS execution is disallowed. |
@@ -1759,6 +1776,22 @@ void Debug::OnException(Handle<Object> exception, Handle<Object> promise) { |
DebugScope debug_scope(this); |
if (debug_scope.failed()) return; |
+ if (exception_event_listener_) { |
+ HandleScope scope(isolate_); |
+ |
+ // Create the execution state. |
+ Handle<Object> exec_state; |
+ // Bail out and don't call debugger if exception. |
+ if (!MakeExecutionState().ToHandle(&exec_state)) return; |
+ |
+ exception_event_listener_( |
+ GetDebugEventContext(isolate_), |
+ v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)), |
+ v8::Utils::ToLocal(exception), promise->IsJSObject(), uncaught, |
+ exception_event_listener_data_); |
+ if (!non_inspector_listener_exists()) return; |
+ } |
+ |
// Create the event data object. |
Handle<Object> event_data; |
// Bail out and don't call debugger if exception. |
@@ -1772,6 +1805,13 @@ void Debug::OnException(Handle<Object> exception, Handle<Object> promise) { |
// Return to continue execution from where the exception was thrown. |
} |
+void Debug::SetBreakEventListener(debug::BreakEventListener listener, |
+ void* data) { |
+ break_event_listener_ = listener; |
+ break_event_listener_data_ = data; |
+ UpdateState(); |
+} |
+ |
void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) { |
// The caller provided for DebugScope. |
AssertDebugContext(); |
@@ -1782,6 +1822,21 @@ void Debug::OnDebugBreak(Handle<Object> break_points_hit, bool auto_continue) { |
PrintBreakLocation(); |
#endif // DEBUG |
+ if (break_event_listener_) { |
+ HandleScope scope(isolate_); |
+ |
+ // Create the execution state. |
+ Handle<Object> exec_state; |
+ // Bail out and don't call debugger if exception. |
+ if (!MakeExecutionState().ToHandle(&exec_state)) return; |
+ |
+ break_event_listener_( |
+ GetDebugEventContext(isolate_), |
+ v8::Utils::ToLocal(Handle<JSObject>::cast(exec_state)), |
+ v8::Utils::ToLocal(break_points_hit), break_event_listener_data_); |
+ if (!non_inspector_listener_exists()) return; |
+ } |
+ |
HandleScope scope(isolate_); |
// Create the event data object. |
Handle<Object> event_data; |
@@ -1932,7 +1987,7 @@ void Debug::CallEventCallback(v8::DebugEvent event, |
in_debug_event_listener_ = true; |
if (event_listener_->IsForeign()) { |
// Invoke the C debug event listener. |
- debug::EventCallback callback = FUNCTION_CAST<debug::EventCallback>( |
+ v8::Debug::EventCallback callback = FUNCTION_CAST<v8::Debug::EventCallback>( |
Handle<Foreign>::cast(event_listener_)->foreign_address()); |
EventDetailsImpl event_details(event, |
Handle<JSObject>::cast(exec_state), |
@@ -2170,9 +2225,10 @@ void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) { |
} |
void Debug::UpdateState() { |
- bool is_active = message_handler_ != nullptr || !event_listener_.is_null() || |
- async_task_listener_ != nullptr || |
- compile_event_listener_ != nullptr; |
+ bool is_active = |
+ message_handler_ != nullptr || !event_listener_.is_null() || |
+ async_task_listener_ != nullptr || compile_event_listener_ != nullptr || |
+ break_event_listener_ != nullptr || exception_event_listener_ != nullptr; |
if (is_active || in_debug_scope()) { |
// Note that the debug context could have already been loaded to |
// bootstrap test cases. |
@@ -2508,17 +2564,6 @@ v8::Local<v8::String> MessageImpl::GetJSON() const { |
} |
} |
-namespace { |
-v8::Local<v8::Context> GetDebugEventContext(Isolate* isolate) { |
- Handle<Context> context = isolate->debug()->debugger_entry()->GetContext(); |
- // Isolate::context() may have been NULL when "script collected" event |
- // occured. |
- if (context.is_null()) return v8::Local<v8::Context>(); |
- Handle<Context> native_context(context->native_context()); |
- return v8::Utils::ToLocal(native_context); |
-} |
-} // anonymous namespace |
- |
v8::Local<v8::Context> MessageImpl::GetEventContext() const { |
Isolate* isolate = event_data_->GetIsolate(); |
v8::Local<v8::Context> context = GetDebugEventContext(isolate); |