summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp')
-rwxr-xr-xSource/WebCore/bindings/v8/WorkerScriptDebugServer.cpp101
1 files changed, 99 insertions, 2 deletions
diff --git a/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp b/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp
index 5e2acd2..1887cea 100755
--- a/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp
+++ b/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp
@@ -33,21 +33,118 @@
#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(WORKERS)
+#include "ScriptDebugListener.h"
+#include "V8DOMWrapper.h"
+#include "V8DedicatedWorkerContext.h"
+#include "V8SharedWorkerContext.h"
#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
+#include "WorkerThread.h"
+#include <v8.h>
+#include <wtf/MessageQueue.h>
namespace WebCore {
+static WorkerContext* retrieveWorkerContext(v8::Handle<v8::Context> context)
+{
+ v8::Handle<v8::Object> global = context->Global();
+ ASSERT(!global.IsEmpty());
+
+ v8::Handle<v8::Object> prototype = v8::Handle<v8::Object>::Cast(global->GetPrototype());
+ ASSERT(!prototype.IsEmpty());
+
+ prototype = v8::Handle<v8::Object>::Cast(prototype->GetPrototype());
+ ASSERT(!prototype.IsEmpty());
+
+ WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(prototype);
+ if (&V8DedicatedWorkerContext::info == typeInfo)
+ return V8DedicatedWorkerContext::toNative(prototype);
+ if (&V8SharedWorkerContext::info == typeInfo)
+ return V8SharedWorkerContext::toNative(prototype);
+ ASSERT_NOT_REACHED();
+ return 0;
+}
+
WorkerScriptDebugServer::WorkerScriptDebugServer()
: ScriptDebugServer()
+ , m_pausedWorkerContext(0)
+{
+}
+
+void WorkerScriptDebugServer::addListener(ScriptDebugListener* listener, WorkerContext* workerContext)
+{
+ v8::HandleScope scope;
+ v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
+ v8::Context::Scope contextScope(debuggerContext);
+
+ if (!m_listenersMap.size()) {
+ // FIXME: synchronize access to this code.
+ ensureDebuggerScriptCompiled();
+ ASSERT(!m_debuggerScript.get()->IsUndefined());
+ v8::Debug::SetDebugEventListener2(&WorkerScriptDebugServer::v8DebugEventCallback, v8::External::New(this));
+ }
+ m_listenersMap.set(workerContext, listener);
+
+ WorkerContextExecutionProxy* proxy = workerContext->script()->proxy();
+ if (!proxy)
+ return;
+ v8::Handle<v8::Context> context = proxy->context();
+
+ v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getWorkerScripts")));
+ v8::Handle<v8::Value> argv[] = { v8::Handle<v8::Value>() };
+ v8::Handle<v8::Value> value = getScriptsFunction->Call(m_debuggerScript.get(), 0, argv);
+ if (value.IsEmpty())
+ return;
+ ASSERT(!value->IsUndefined() && value->IsArray());
+ v8::Handle<v8::Array> scriptsArray = v8::Handle<v8::Array>::Cast(value);
+ for (unsigned i = 0; i < scriptsArray->Length(); ++i)
+ dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(i))));
+}
+
+void WorkerScriptDebugServer::removeListener(ScriptDebugListener* listener, WorkerContext* workerContext)
{
+ if (!m_listenersMap.contains(workerContext))
+ return;
+
+ if (m_pausedWorkerContext == workerContext)
+ continueProgram();
+
+ m_listenersMap.remove(workerContext);
+
+ if (m_listenersMap.isEmpty())
+ v8::Debug::SetDebugEventListener2(0);
}
-void WorkerScriptDebugServer::addListener(ScriptDebugListener*, WorkerContext*)
+ScriptDebugListener* WorkerScriptDebugServer::getDebugListenerForContext(v8::Handle<v8::Context> context)
{
+ WorkerContext* workerContext = retrieveWorkerContext(context);
+ if (!workerContext)
+ return 0;
+ return m_listenersMap.get(workerContext);
+}
+
+void WorkerScriptDebugServer::runMessageLoopOnPause(v8::Handle<v8::Context> context)
+{
+ WorkerContext* workerContext = retrieveWorkerContext(context);
+ WorkerThread* workerThread = workerContext->thread();
+
+ m_pausedWorkerContext = workerContext;
+
+ MessageQueueWaitResult result;
+ do {
+ result = workerThread->runLoop().runInMode(workerContext, "debugger");
+ // Keep waiting until execution is resumed.
+ } while (result == MessageQueueMessageReceived && isPaused());
+ m_pausedWorkerContext = 0;
+
+ // The listener may have been removed in the nested loop.
+ if (ScriptDebugListener* listener = m_listenersMap.get(workerContext))
+ listener->didContinue();
}
-void WorkerScriptDebugServer::removeListener(ScriptDebugListener*, WorkerContext*)
+void WorkerScriptDebugServer::quitMessageLoopOnPause()
{
+ // FIXME: do exit nested loop when listener is removed on pause.
}
} // namespace WebCore