summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/v8/ScriptDebugServer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/v8/ScriptDebugServer.cpp')
-rw-r--r--WebCore/bindings/v8/ScriptDebugServer.cpp85
1 files changed, 68 insertions, 17 deletions
diff --git a/WebCore/bindings/v8/ScriptDebugServer.cpp b/WebCore/bindings/v8/ScriptDebugServer.cpp
index 0c24678..3f1a0c5 100644
--- a/WebCore/bindings/v8/ScriptDebugServer.cpp
+++ b/WebCore/bindings/v8/ScriptDebugServer.cpp
@@ -84,6 +84,7 @@ ScriptDebugServer::ScriptDebugServer()
: m_pauseOnExceptionsState(DontPauseOnExceptions)
, m_pausedPage(0)
, m_enabled(true)
+ , m_breakpointsActivated(true)
{
}
@@ -186,7 +187,7 @@ void ScriptDebugServer::clearBreakpoints()
v8::Debug::Call(clearBreakpoints);
}
-void ScriptDebugServer::setBreakpointsActivated(bool enabled)
+void ScriptDebugServer::setBreakpointsActivated(bool activated)
{
ensureDebuggerScriptCompiled();
v8::HandleScope scope;
@@ -194,9 +195,11 @@ void ScriptDebugServer::setBreakpointsActivated(bool enabled)
v8::Context::Scope contextScope(debuggerContext);
v8::Local<v8::Object> args = v8::Object::New();
- args->Set(v8::String::New("enabled"), v8::Boolean::New(enabled));
+ args->Set(v8::String::New("enabled"), v8::Boolean::New(activated));
v8::Handle<v8::Function> setBreakpointsActivated = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("setBreakpointsActivated")));
v8::Debug::Call(setBreakpointsActivated, args);
+
+ m_breakpointsActivated = activated;
}
ScriptDebugServer::PauseOnExceptionsState ScriptDebugServer::pauseOnExceptionsState()
@@ -228,6 +231,31 @@ void ScriptDebugServer::pause()
v8::Debug::DebugBreak();
}
+void ScriptDebugServer::breakProgram()
+{
+ DEFINE_STATIC_LOCAL(v8::Persistent<v8::FunctionTemplate>, callbackTemplate, ());
+
+ if (!m_breakpointsActivated)
+ return;
+
+ if (!v8::Context::InContext())
+ return;
+
+ if (callbackTemplate.IsEmpty()) {
+ callbackTemplate = v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
+ callbackTemplate->SetCallHandler(&ScriptDebugServer::breakProgramCallback);
+ }
+
+ v8::Handle<v8::Context> context = v8::Context::GetCurrent();
+ if (context.IsEmpty())
+ return;
+
+ m_pausedPageContext = *context;
+ v8::Handle<v8::Function> breakProgramFunction = callbackTemplate->GetFunction();
+ v8::Debug::Call(breakProgramFunction);
+ m_pausedPageContext.Clear();
+}
+
void ScriptDebugServer::continueProgram()
{
if (m_pausedPage)
@@ -323,6 +351,41 @@ void ScriptDebugServer::runPendingTasks()
v8::Debug::ProcessDebugMessages();
}
+v8::Handle<v8::Value> ScriptDebugServer::breakProgramCallback(const v8::Arguments& args)
+{
+ ASSERT(2 == args.Length());
+ ScriptDebugServer::shared().breakProgram(v8::Handle<v8::Object>::Cast(args[0]));
+ return v8::Undefined();
+}
+
+void ScriptDebugServer::breakProgram(v8::Handle<v8::Object> executionState)
+{
+ // Don't allow nested breaks.
+ if (m_pausedPage)
+ return;
+
+ Frame* frame = retrieveFrame(m_pausedPageContext);
+ if (!frame)
+ return;
+
+ ScriptDebugListener* listener = m_listenersMap.get(frame->page());
+ if (!listener)
+ return;
+
+ m_executionState.set(executionState);
+ m_pausedPage = frame->page();
+ ScriptState* currentCallFrameState = ScriptState::forContext(m_pausedPageContext);
+ listener->didPause(currentCallFrameState);
+
+ // Wait for continue or step command.
+ m_clientMessageLoop->run(m_pausedPage);
+ ASSERT(!m_pausedPage);
+
+ // The listener may have been removed in the nested loop.
+ if (ScriptDebugListener* listener = m_listenersMap.get(frame->page()))
+ listener->didContinue();
+}
+
void ScriptDebugServer::v8DebugEventCallback(const v8::Debug::EventDetails& eventDetails)
{
ScriptDebugServer::shared().handleV8DebugEvent(eventDetails);
@@ -365,21 +428,9 @@ void ScriptDebugServer::handleV8DebugEvent(const v8::Debug::EventDetails& eventD
return;
}
- // Don't allow nested breaks.
- if (m_pausedPage)
- return;
- m_executionState.set(eventDetails.GetExecutionState());
- m_pausedPage = frame->page();
- ScriptState* currentCallFrameState = mainWorldScriptState(frame);
- listener->didPause(currentCallFrameState);
-
- // Wait for continue or step command.
- m_clientMessageLoop->run(m_pausedPage);
- ASSERT(!m_pausedPage);
-
- // The listener may have been removed in the nested loop.
- if (ScriptDebugListener* listener = m_listenersMap.get(frame->page()))
- listener->didContinue();
+ m_pausedPageContext = *eventContext;
+ breakProgram(eventDetails.GetExecutionState());
+ m_pausedPageContext.Clear();
}
}
}