Index: src/debug/debug.h |
diff --git a/src/debug/debug.h b/src/debug/debug.h |
index 802e630e133b59adad4809ee9dc97fecfa4462c2..91061c9b4cc02363fb228dec099dfdf9d4a796f5 100644 |
--- a/src/debug/debug.h |
+++ b/src/debug/debug.h |
@@ -231,28 +231,6 @@ class DebugInfoListNode { |
DebugInfoListNode* next_; |
}; |
-// Details of the debug event delivered to the debug event listener. |
-class EventDetailsImpl : public v8::Debug::EventDetails { |
- public: |
- EventDetailsImpl(DebugEvent event, Handle<JSObject> exec_state, |
- Handle<JSObject> event_data, Handle<Object> callback_data); |
- virtual DebugEvent GetEvent() const; |
- virtual v8::Local<v8::Object> GetExecutionState() const; |
- virtual v8::Local<v8::Object> GetEventData() const; |
- virtual v8::Local<v8::Context> GetEventContext() const; |
- virtual v8::Local<v8::Value> GetCallbackData() const; |
- virtual v8::Debug::ClientData* GetClientData() const { return nullptr; } |
- virtual v8::Isolate* GetIsolate() const; |
- |
- private: |
- DebugEvent event_; // Debug event causing the break. |
- Handle<JSObject> exec_state_; // Current execution state. |
- Handle<JSObject> event_data_; // Data associated with the event. |
- Handle<Object> callback_data_; // User data passed with the callback |
- // when it was registered. |
-}; |
- |
- |
class DebugFeatureTracker { |
public: |
enum Feature { |
@@ -291,10 +269,9 @@ class Debug { |
void OnPromiseReject(Handle<Object> promise, Handle<Object> value); |
void OnCompileError(Handle<Script> script); |
void OnAfterCompile(Handle<Script> script); |
- void OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id); |
+ void OnAsyncTaskEvent(debug::PromiseDebugActionType type, int id, |
+ int parent_id); |
- // API facing. |
- void SetEventListener(Handle<Object> callback, Handle<Object> data); |
MUST_USE_RESULT MaybeHandle<Object> Call(Handle<Object> fun, |
Handle<Object> data); |
Handle<Context> GetDebugContext(); |
@@ -347,7 +324,7 @@ class Debug { |
bool IsBlackboxed(Handle<SharedFunctionInfo> shared); |
- void SetDebugDelegate(debug::DebugDelegate* delegate); |
+ void SetDebugDelegate(debug::DebugDelegate* delegate, bool pass_ownership); |
// Returns whether the operation succeeded. |
bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared); |
@@ -447,9 +424,11 @@ class Debug { |
private: |
explicit Debug(Isolate* isolate); |
+ ~Debug() { DCHECK_NULL(debug_delegate_); } |
void UpdateState(); |
void UpdateHookOnFunctionCall(); |
+ void RemoveDebugDelegate(); |
void Unload(); |
void SetNextBreakId() { |
thread_local_.break_id_ = ++thread_local_.break_count_; |
@@ -461,9 +440,7 @@ class Debug { |
inline bool ignore_events() const { |
return is_suppressed_ || !is_active_ || isolate_->needs_side_effect_check(); |
} |
- inline bool break_disabled() const { |
- return break_disabled_ || in_debug_event_listener_; |
- } |
+ inline bool break_disabled() const { return break_disabled_; } |
void clear_suspended_generator() { |
thread_local_.suspended_generator_ = Smi::kZero; |
@@ -473,17 +450,6 @@ class Debug { |
return thread_local_.suspended_generator_ != Smi::kZero; |
} |
- // There are three types of event listeners: C++ message_handler, |
- // JavaScript event listener and C++ event listener. |
- // Currently inspector still uses C++ event listener and installs |
- // more specific event listeners for part of events. Calling of |
- // C++ event listener is redundant when more specific event listener |
- // is presented. Other clients can install JavaScript event listener |
- // (e.g. some of NodeJS module). |
- bool non_inspector_listener_exists() const { |
- return !event_listener_.is_null() && !event_listener_->IsForeign(); |
- } |
- |
bool IsExceptionBlackboxed(bool uncaught); |
void OnException(Handle<Object> exception, Handle<Object> promise); |
@@ -498,8 +464,8 @@ class Debug { |
Handle<Object> promise); |
MUST_USE_RESULT MaybeHandle<Object> MakeCompileEvent( |
Handle<Script> script, v8::DebugEvent type); |
- MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent(Handle<Smi> type, |
- Handle<Smi> id); |
+ MUST_USE_RESULT MaybeHandle<Object> MakeAsyncTaskEvent( |
+ v8::debug::PromiseDebugActionType type, int id); |
void ProcessCompileEvent(v8::DebugEvent event, Handle<Script> script); |
void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); |
@@ -539,10 +505,9 @@ class Debug { |
// Global handles. |
Handle<Context> debug_context_; |
- Handle<Object> event_listener_; |
- Handle<Object> event_listener_data_; |
debug::DebugDelegate* debug_delegate_ = nullptr; |
+ bool owns_debug_delegate_ = false; |
// Debugger is active, i.e. there is a debug event listener attached. |
bool is_active_; |
@@ -557,8 +522,6 @@ class Debug { |
bool break_disabled_; |
// Do not break on break points. |
bool break_points_active_; |
- // Nested inside a debug event listener. |
- bool in_debug_event_listener_; |
// Trigger debug break events for all exceptions. |
bool break_on_exception_; |
// Trigger debug break events for uncaught exceptions. |
@@ -622,6 +585,7 @@ class Debug { |
friend class LiveEdit; |
friend class SuppressDebug; |
friend class NoSideEffectScope; |
+ friend class LegacyDebugDelegate; |
friend Handle<FixedArray> GetDebuggedFunctions(); // In test-debug.cc |
friend void CheckDebuggerUnloaded(bool check_functions); // In test-debug.cc |
@@ -629,6 +593,84 @@ class Debug { |
DISALLOW_COPY_AND_ASSIGN(Debug); |
}; |
+class LegacyDebugDelegate : public v8::debug::DebugDelegate { |
+ public: |
+ explicit LegacyDebugDelegate(Isolate* isolate) : isolate_(isolate) {} |
+ void PromiseEventOccurred(v8::debug::PromiseDebugActionType type, int id, |
+ int parent_id) override; |
+ void ScriptCompiled(v8::Local<v8::debug::Script> script, |
+ bool has_compile_error) override; |
+ void BreakProgramRequested(v8::Local<v8::Context> paused_context, |
+ v8::Local<v8::Object> exec_state, |
+ v8::Local<v8::Value> break_points_hit) override; |
+ void ExceptionThrown(v8::Local<v8::Context> paused_context, |
+ v8::Local<v8::Object> exec_state, |
+ v8::Local<v8::Value> exception, |
+ v8::Local<v8::Value> promise, bool is_uncaught) override; |
+ bool IsFunctionBlackboxed(v8::Local<v8::debug::Script> script, |
+ const v8::debug::Location& start, |
+ const v8::debug::Location& end) override { |
+ return false; |
+ } |
+ |
+ protected: |
+ Isolate* isolate_; |
+ |
+ private: |
+ void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data); |
+ virtual void ProcessDebugEvent(v8::DebugEvent event, |
+ Handle<JSObject> event_data, |
+ Handle<JSObject> exec_state) = 0; |
+}; |
+ |
+class JavaScriptDebugDelegate : public LegacyDebugDelegate { |
+ public: |
+ JavaScriptDebugDelegate(Isolate* isolate, Handle<JSFunction> listener, |
+ Handle<Object> data); |
+ virtual ~JavaScriptDebugDelegate(); |
+ |
+ private: |
+ void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data, |
+ Handle<JSObject> exec_state) override; |
+ |
+ Handle<JSFunction> listener_; |
+ Handle<Object> data_; |
+}; |
+ |
+class NativeDebugDelegate : public LegacyDebugDelegate { |
+ public: |
+ NativeDebugDelegate(Isolate* isolate, v8::Debug::EventCallback callback, |
+ Handle<Object> data); |
+ virtual ~NativeDebugDelegate(); |
+ |
+ private: |
+ // Details of the debug event delivered to the debug event listener. |
+ class EventDetails : public v8::Debug::EventDetails { |
+ public: |
+ EventDetails(DebugEvent event, Handle<JSObject> exec_state, |
+ Handle<JSObject> event_data, Handle<Object> callback_data); |
+ virtual DebugEvent GetEvent() const; |
+ virtual v8::Local<v8::Object> GetExecutionState() const; |
+ virtual v8::Local<v8::Object> GetEventData() const; |
+ virtual v8::Local<v8::Context> GetEventContext() const; |
+ virtual v8::Local<v8::Value> GetCallbackData() const; |
+ virtual v8::Debug::ClientData* GetClientData() const { return nullptr; } |
+ virtual v8::Isolate* GetIsolate() const; |
+ |
+ private: |
+ DebugEvent event_; // Debug event causing the break. |
+ Handle<JSObject> exec_state_; // Current execution state. |
+ Handle<JSObject> event_data_; // Data associated with the event. |
+ Handle<Object> callback_data_; // User data passed with the callback |
+ // when it was registered. |
+ }; |
+ |
+ void ProcessDebugEvent(v8::DebugEvent event, Handle<JSObject> event_data, |
+ Handle<JSObject> exec_state) override; |
+ |
+ v8::Debug::EventCallback callback_; |
+ Handle<Object> data_; |
+}; |
// This scope is used to load and enter the debug context and create a new |
// break state. Leaving the scope will restore the previous state. |
@@ -662,21 +704,16 @@ class DebugScope BASE_EMBEDDED { |
class DisableBreak BASE_EMBEDDED { |
public: |
explicit DisableBreak(Debug* debug) |
- : debug_(debug), |
- previous_break_disabled_(debug->break_disabled_), |
- previous_in_debug_event_listener_(debug->in_debug_event_listener_) { |
+ : debug_(debug), previous_break_disabled_(debug->break_disabled_) { |
debug_->break_disabled_ = true; |
- debug_->in_debug_event_listener_ = true; |
} |
~DisableBreak() { |
debug_->break_disabled_ = previous_break_disabled_; |
- debug_->in_debug_event_listener_ = previous_in_debug_event_listener_; |
} |
private: |
Debug* debug_; |
bool previous_break_disabled_; |
- bool previous_in_debug_event_listener_; |
DISALLOW_COPY_AND_ASSIGN(DisableBreak); |
}; |