return Heap::undefined_value();
}
- SaveBreakFrame save;
- EnterDebuggerContext enter;
+ // Enter the debugger.
+ EnterDebugger debugger;
+ if (debugger.FailedToEnter()) {
+ return Heap::undefined_value();
+ }
// Postpone interrupt during breakpoint processing.
PostponeInterruptsScope postpone;
if (!Debug::break_on_exception()) return;
}
- // Enter the debugger. Bail out if the debugger cannot be loaded.
- if (!Debug::Load()) return;
- SaveBreakFrame save;
- EnterDebuggerContext enter;
+ // Enter the debugger.
+ EnterDebugger debugger;
+ if (debugger.FailedToEnter()) return;
// Clear all current stepping setup.
Debug::ClearStepping();
if (compiling_natives()) return;
if (!EventActive(v8::BeforeCompile)) return;
- // Enter the debugger. Bail out if the debugger cannot be loaded.
- if (!Debug::Load()) return;
- SaveBreakFrame save;
- EnterDebuggerContext enter;
+ // Enter the debugger.
+ EnterDebugger debugger;
+ if (debugger.FailedToEnter()) return;
// Create the event data object.
bool caught_exception = false;
// No more to do if not debugging.
if (!debugger_active()) return;
- // Enter the debugger. Bail out if the debugger cannot be loaded.
- if (!Debug::Load()) return;
- SaveBreakFrame save;
- EnterDebuggerContext enter;
+ // Enter the debugger.
+ EnterDebugger debugger;
+ if (debugger.FailedToEnter()) return;
// If debugging there might be script break points registered for this
// script. Make sure that these break points are set.
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;
+ // Enter the debugger.
+ EnterDebugger debugger;
+ if (debugger.FailedToEnter()) return;
// Create the event object.
bool caught_exception = false;
#include "../include/v8-debug.h"
#include "assembler.h"
#include "code-stubs.h"
+#include "execution.h"
#include "factory.h"
#include "platform.h"
#include "string-stream.h"
};
-// Helper class to support saving/restoring the top break frame id.
-class SaveBreakFrame {
+// 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 {
public:
- SaveBreakFrame() : set_(!it_.done()) {
+ EnterDebugger() : set_(!it_.done()) {
+ // If there is no JavaScript frames on the stack don't switch to new break
+ // and break frame.
if (set_) {
// Store the previous break is and frame id.
break_id_ = Top::break_id();
// Create the new break info.
Top::new_break(it_.frame()->id());
}
+
+ // Make sure that debugger is loaded and enter the debugger context.
+ load_failed_ = !Debug::Load();
+ if (!load_failed_) {
+ // NOTE the member variable save which saves the previous context before
+ // this change.
+ Top::set_context(*Debug::debug_context());
+ Top::set_security_context(*Debug::debug_context());
+ }
}
- ~SaveBreakFrame() {
+ ~EnterDebugger() {
if (set_) {
- // restore to the previous break state.
+ // Restore to the previous break state.
Top::set_break(break_frame_id_, break_id_);
}
}
+ // Check whether the debugger could be entered.
+ inline bool FailedToEnter() { return load_failed_; }
+
private:
JavaScriptFrameIterator it_;
const bool set_; // Was the break actually set?
StackFrame::Id break_frame_id_; // Previous break frame id.
int break_id_; // Previous break id.
-};
-
-
-class EnterDebuggerContext BASE_EMBEDDED {
- public:
- // Enter the debugger by storing the previous top context and setting the
- // current top context to the debugger context.
- EnterDebuggerContext() {
- // NOTE the member variable save which saves the previous context before
- // this change.
- Top::set_context(*Debug::debug_context());
- Top::set_security_context(*Debug::debug_context());
- }
-
- private:
- SaveContext save;
+ bool load_failed_; // Did the debugger fail to load?
+ SaveContext save_; // Saves previous context.
};
// For constructor frames display new followed by the function name.
result += 'new ';
result += func.name() ? func.name() : '[anonymous]';
- } else if (this.isDebuggerFrame()) {
+ } else if (this.isDebuggerFrame()) {
result += '[debugger]';
} else {
// If the receiver has a className which is 'global' don't display it.
static Object* Runtime_DebugBreak(Arguments args) {
- // Just continue if breaks are disabled or if we fail to load the debugger.
- if (Debug::disable_break() || !Debug::Load()) {
+ // Just continue if breaks are disabled.
+ if (Debug::disable_break()) {
return args[0];
}
StackGuard::Continue(DEBUGBREAK);
HandleScope scope;
- SaveBreakFrame save;
- EnterDebuggerContext enter;
+ // Enter the debugger. Just continue if we fail to enter the debugger.
+ EnterDebugger debugger;
+ if (debugger.FailedToEnter()) {
+ return args[0];
+ }
// Notify the debug event listeners.
Debugger::OnDebugBreak(Factory::undefined_value());
namespace v8 { namespace internal {
ThreadLocalTop Top::thread_local_;
-Mutex* Top::break_access_ = OS::CreateMutex();
+Mutex* Top::break_access_;
StackFrame::Id Top::break_frame_id_;
int Top::break_count_;
int Top::break_id_;
InitializeThreadLocal();
+ break_access_ = OS::CreateMutex();
break_frame_id_ = StackFrame::NO_ID;
break_count_ = 0;
break_id_ = 0;