thread_local_.step_into_fp_ = 0;
thread_local_.step_out_fp_ = 0;
// TODO(isolates): frames_are_dropped_?
- thread_local_.debugger_entry_ = NULL;
+ thread_local_.current_debug_scope_ = NULL;
thread_local_.restarter_frame_function_pointer_ = NULL;
thread_local_.promise_on_stack_ = NULL;
}
if (break_disabled_) return;
// Enter the debugger.
- EnterDebugger debugger(isolate_);
- if (debugger.FailedToEnter()) return;
+ DebugScope debug_scope(this);
+ if (debug_scope.failed()) return;
// Postpone interrupt during breakpoint processing.
PostponeInterruptsScope postpone(isolate_);
PrepareForBreakPoints();
- ASSERT(is_entered());
+ ASSERT(in_debug_scope());
// Remember this step action and count.
thread_local_.last_step_action_ = step_action;
void Debug::ClearMirrorCache() {
PostponeInterruptsScope postpone(isolate_);
HandleScope scope(isolate_);
- ASSERT(isolate_->context() == *Debug::debug_context());
+ AssertDebugContext();
Factory* factory = isolate_->factory();
JSObject::SetProperty(isolate_->global_object(),
factory->NewStringFromAsciiChecked("next_handle_"),
MaybeHandle<Object> Debug::MakeJSObject(const char* constructor_name,
int argc,
Handle<Object> argv[]) {
- ASSERT(isolate_->context() == *debug_context());
+ AssertDebugContext();
// Create the execution state object.
Handle<Object> constructor = Object::GetProperty(
isolate_, isolate_->global_object(), constructor_name).ToHandleChecked();
void Debug::OnException(Handle<Object> exception, bool uncaught) {
- if (is_entered() || ignore_events()) return;
+ if (in_debug_scope() || ignore_events()) return;
HandleScope scope(isolate_);
Handle<Object> promise = GetPromiseForUncaughtException();
if (!break_on_exception_) return;
}
- // Enter the debugger.
- EnterDebugger debugger(isolate_);
- if (debugger.FailedToEnter()) return;
+ DebugScope debug_scope(this);
+ if (debug_scope.failed()) return;
// Clear all current stepping setup.
ClearStepping();
void Debug::OnDebugBreak(Handle<Object> break_points_hit,
bool auto_continue) {
- // Debugger has already been entered by caller.
- ASSERT(isolate_->context() == *debug_context());
+ // The caller provided for DebugScope.
+ AssertDebugContext();
// Bail out if there is no listener for this event
if (ignore_events()) return;
void Debug::OnBeforeCompile(Handle<Script> script) {
- if (is_entered() || ignore_events()) return;
+ if (in_debug_scope() || ignore_events()) return;
HandleScope scope(isolate_);
- // Enter the debugger.
- EnterDebugger debugger(isolate_);
- if (debugger.FailedToEnter()) return;
+ DebugScope debug_scope(this);
+ if (debug_scope.failed()) return;
// Create the event data object.
Handle<Object> event_data;
if (script_cache_ != NULL) script_cache_->Add(script);
// No more to do if not debugging.
- if (is_entered() || ignore_events()) return;
+ if (in_debug_scope() || ignore_events()) return;
HandleScope scope(isolate_);
// Store whether in debugger before entering debugger.
- bool in_debugger = is_entered();
+ bool was_in_scope = in_debug_scope();
- // Enter the debugger.
- EnterDebugger debugger(isolate_);
- if (debugger.FailedToEnter()) return;
+ DebugScope debug_scope(this);
+ if (debug_scope.failed()) return;
// If debugging there might be script break points registered for this
// script. Make sure that these break points are set.
return;
}
// Bail out based on state or if there is no listener for this event
- if (in_debugger && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return;
+ if (was_in_scope && (after_compile_flags & SEND_WHEN_DEBUGGING) == 0) return;
// Create the compile state object.
Handle<Object> event_data;
void Debug::OnScriptCollected(int id) {
- if (is_entered() || ignore_events()) return;
+ if (in_debug_scope() || ignore_events()) return;
HandleScope scope(isolate_);
- // Enter the debugger.
- EnterDebugger debugger(isolate_);
- if (debugger.FailedToEnter()) return;
+ DebugScope debug_scope(this);
+ if (debug_scope.failed()) return;
// Create the script collected state object.
Handle<Object> event_data;
Handle<Context> Debug::GetDebugContext() {
- EnterDebugger debugger(isolate_);
+ DebugScope debug_scope(this);
// The global handle may be destroyed soon after. Return it reboxed.
return handle(*debug_context(), isolate_);
}
// The debug command interrupt flag might have been set when the command was
// added. It should be enough to clear the flag only once while we are in the
// debugger.
- ASSERT(is_entered());
+ ASSERT(in_debug_scope());
isolate_->stack_guard()->ClearDebugCommand();
// Notify the debugger that a debug event has occurred unless auto continue is
void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
message_handler_ = handler;
UpdateState();
- if (handler == NULL && is_entered()) {
+ if (handler == NULL && in_debug_scope()) {
// Send an empty command to the debugger if in a break to make JavaScript
// run again if the debugger is closed.
EnqueueCommandMessage(Vector<const uint16_t>::empty());
void Debug::UpdateState() {
is_active_ = message_handler_ != NULL || !event_listener_.is_null();
- if (is_active_ || is_entered()) {
+ if (is_active_ || in_debug_scope()) {
// Note that the debug context could have already been loaded to
// bootstrap test cases.
isolate_->compilation_cache()->Disable();
is_active_ = Load();
- } else if (is_loaded() && !is_active_) {
+ } else if (is_loaded()) {
isolate_->compilation_cache()->Enable();
Unload();
}
command_received_.Signal();
// Set the debug command break flag to have the command processed.
- if (!is_entered()) isolate_->stack_guard()->RequestDebugCommand();
+ if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
}
event_command_queue_.Put(message);
// Set the debug command break flag to have the command processed.
- if (!is_entered()) isolate_->stack_guard()->RequestDebugCommand();
+ if (!in_debug_scope()) isolate_->stack_guard()->RequestDebugCommand();
}
MaybeHandle<Object> Debug::Call(Handle<JSFunction> fun, Handle<Object> data) {
- // Enter the debugger.
- EnterDebugger debugger(isolate_);
- if (debugger.FailedToEnter()) {
- return isolate_->factory()->undefined_value();
- }
+ DebugScope debug_scope(this);
+ if (debug_scope.failed()) return isolate_->factory()->undefined_value();
// Create the execution state.
Handle<Object> exec_state;
if (check.HasOverflowed()) return;
HandleScope scope(isolate_);
- // Enter the debugger. Just continue if we fail to enter the debugger.
- EnterDebugger debugger(isolate_);
- if (debugger.FailedToEnter()) return;
+ DebugScope debug_scope(this);
+ if (debug_scope.failed()) return;
// Notify the debug event listeners. Indicate auto continue if the break was
// a debug command break.
}
-EnterDebugger::EnterDebugger(Isolate* isolate)
- : isolate_(isolate),
- prev_(isolate_->debug()->debugger_entry()),
- save_(isolate_) {
- Debug* debug = isolate_->debug();
-
+DebugScope::DebugScope(Debug* debug) : debug_(debug),
+ prev_(debug->debugger_entry()),
+ save_(debug_->isolate_) {
// Link recursive debugger entry.
- debug->thread_local_.debugger_entry_ = this;
+ debug_->thread_local_.current_debug_scope_ = this;
// Store the previous break id and frame id.
- break_id_ = debug->break_id();
- break_frame_id_ = debug->break_frame_id();
+ break_id_ = debug_->break_id();
+ break_frame_id_ = debug_->break_frame_id();
// Create the new break info. If there is no JavaScript frames there is no
// break frame id.
- JavaScriptFrameIterator it(isolate_);
+ JavaScriptFrameIterator it(isolate());
bool has_js_frames = !it.done();
- debug->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
- : StackFrame::NO_ID;
- debug->SetNextBreakId();
+ debug_->thread_local_.break_frame_id_ = has_js_frames ? it.frame()->id()
+ : StackFrame::NO_ID;
+ debug_->SetNextBreakId();
- debug->UpdateState();
+ debug_->UpdateState();
// Make sure that debugger is loaded and enter the debugger context.
// The previous context is kept in save_.
- load_failed_ = !debug->is_loaded();
- if (!load_failed_) isolate_->set_context(*debug->debug_context());
+ failed_ = !debug_->is_loaded();
+ if (!failed_) isolate()->set_context(*debug->debug_context());
}
-EnterDebugger::~EnterDebugger() {
- Debug* debug = isolate_->debug();
- // Restore to the previous break state.
- debug->thread_local_.break_frame_id_ = break_frame_id_;
- debug->thread_local_.break_id_ = break_id_;
-
- // Check for leaving the debugger.
- if (!load_failed_ && prev_ == NULL) {
+DebugScope::~DebugScope() {
+ if (!failed_ && prev_ == NULL) {
// Clear mirror cache when leaving the debugger. Skip this if there is a
// pending exception as clearing the mirror cache calls back into
// JavaScript. This can happen if the v8::Debug::Call is used in which
// case the exception should end up in the calling code.
- if (!isolate_->has_pending_exception()) debug->ClearMirrorCache();
+ if (!isolate()->has_pending_exception()) debug_->ClearMirrorCache();
// If there are commands in the queue when leaving the debugger request
// that these commands are processed.
- if (debug->has_commands()) isolate_->stack_guard()->RequestDebugCommand();
+ if (debug_->has_commands()) isolate()->stack_guard()->RequestDebugCommand();
}
// Leaving this debugger entry.
- debug->thread_local_.debugger_entry_ = prev_;
+ debug_->thread_local_.current_debug_scope_ = prev_;
+
+ // Restore to the previous break state.
+ debug_->thread_local_.break_frame_id_ = break_frame_id_;
+ debug_->thread_local_.break_id_ = break_id_;
- debug->UpdateState();
+ debug_->UpdateState();
}
// Forward declarations.
-class EnterDebugger;
+class DebugScope;
// Step actions. NOTE: These values are in macros.py as well.
void AfterGarbageCollection();
// Flags and states.
- EnterDebugger* debugger_entry() { return thread_local_.debugger_entry_; }
+ DebugScope* debugger_entry() { return thread_local_.current_debug_scope_; }
inline Handle<Context> debug_context() { return debug_context_; }
void set_live_edit_enabled(bool v) { live_edit_enabled_ = v; }
bool live_edit_enabled() const {
inline bool is_active() const { return is_active_; }
inline bool is_loaded() const { return !debug_context_.is_null(); }
inline bool has_break_points() const { return has_break_points_; }
- inline bool is_entered() const {
- return thread_local_.debugger_entry_ != NULL;
+ inline bool in_debug_scope() const {
+ return thread_local_.current_debug_scope_ != NULL;
}
void set_disable_break(bool v) { break_disabled_ = v; }
Handle<Object> CheckBreakPoints(Handle<Object> break_point);
bool CheckBreakPoint(Handle<Object> break_point_object);
+ inline void AssertDebugContext() {
+ ASSERT(isolate_->context() == *debug_context());
+ ASSERT(in_debug_scope());
+ }
+
void ThreadInit();
// Global handles.
class ThreadLocal {
public:
// Top debugger entry.
- EnterDebugger* debugger_entry_;
+ DebugScope* current_debug_scope_;
// Counter for generating next break id.
int break_count_;
Isolate* isolate_;
friend class Isolate;
- friend class EnterDebugger;
- friend class FrameDropper;
+ friend class DebugScope;
friend class DisableBreak;
friend class SuppressDebug;
DECLARE_RUNTIME_FUNCTION(Debug_Break);
-// This class is used for entering the debugger. Create an instance in the stack
-// to enter the debugger. This will set the current break state, make sure the
-// debugger is loaded and switch to the debugger context. If the debugger for
-// some reason could not be entered FailedToEnter will return true.
-class EnterDebugger BASE_EMBEDDED {
+// 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.
+// On failure to load, FailedToEnter returns true.
+class DebugScope BASE_EMBEDDED {
public:
- explicit EnterDebugger(Isolate* isolate);
- ~EnterDebugger();
+ explicit DebugScope(Debug* debug);
+ ~DebugScope();
- // Check whether the debugger could be entered.
- inline bool FailedToEnter() { return load_failed_; }
+ // Check whether loading was successful.
+ inline bool failed() { return failed_; }
// Get the active context from before entering the debugger.
inline Handle<Context> GetContext() { return save_.context(); }
private:
- Isolate* isolate_;
- EnterDebugger* prev_; // Previous debugger entry if entered recursively.
+ Isolate* isolate() { return debug_->isolate_; }
+
+ Debug* debug_;
+ DebugScope* prev_; // Previous scope if entered recursively.
StackFrame::Id break_frame_id_; // Previous break frame id.
- int break_id_; // Previous break id.
- bool load_failed_; // Did the debugger fail to load?
- SaveContext save_; // Saves previous context.
+ int break_id_; // Previous break id.
+ bool failed_; // Did the debug context fail to load?
+ SaveContext save_; // Saves previous context.
};