void Debug::OnCompileError(Handle<Script> script) {
if (ignore_events()) return;
+ SuppressDebug while_processing(this);
if (in_debug_scope()) {
ProcessCompileEventInDebugScope(v8::CompileError, script);
void Debug::OnBeforeCompile(Handle<Script> script) {
if (in_debug_scope() || ignore_events()) return;
+ SuppressDebug while_processing(this);
HandleScope scope(isolate_);
DebugScope debug_scope(this);
// Handle debugger actions when a new script is compiled.
void Debug::OnAfterCompile(Handle<Script> script) {
if (ignore_events()) return;
+ SuppressDebug while_processing(this);
if (in_debug_scope()) {
ProcessCompileEventInDebugScope(v8::AfterCompile, script);
Handle<Object> exec_state,
Handle<Object> event_data,
v8::Debug::ClientData* client_data) {
+ // Prevent other interrupts from triggering, for example API callbacks,
+ // while dispatching event listners.
+ PostponeInterruptsScope postpone(isolate_);
bool previous = in_debug_event_listener_;
in_debug_event_listener_ = true;
if (event_listener_->IsForeign()) {
Handle<Script> script) {
if (event_listener_.is_null()) return;
- SuppressDebug while_processing(this);
DebugScope debug_scope(this);
if (debug_scope.failed()) return;
"x * y",
30);
}
+
+static int after_compile_handler_depth = 0;
+static void HandleInterrupt(v8::Isolate* isolate, void* data) {
+ CHECK_EQ(0, after_compile_handler_depth);
+}
+
+static void NoInterruptsOnDebugEvent(
+ const v8::Debug::EventDetails& event_details) {
+ if (event_details.GetEvent() != v8::AfterCompile) return;
+ ++after_compile_handler_depth;
+ // Do not allow nested AfterCompile events.
+ CHECK(after_compile_handler_depth <= 1);
+ v8::Isolate* isolate = event_details.GetEventContext()->GetIsolate();
+ isolate->RequestInterrupt(&HandleInterrupt, nullptr);
+ CompileRun("function foo() {}; foo();");
+ --after_compile_handler_depth;
+}
+
+
+TEST(NoInterruptsInDebugListener) {
+ DebugLocalContext env;
+ v8::Debug::SetDebugEventListener(NoInterruptsOnDebugEvent);
+ CompileRun("void(0);");
+}