Changeset 83874 in webkit


Ignore:
Timestamp:
Apr 14, 2011 11:13:10 AM (13 years ago)
Author:
yurys@chromium.org
Message:

2011-04-14 Yury Semikhatsky <yurys@chromium.org>

Reviewed by Pavel Feldman.

[v8] Web Inspector: add initial implementation of WorkerScriptDebugServer
https://bugs.webkit.org/show_bug.cgi?id=58552

  • bindings/v8/DebuggerScript.js:
  • bindings/v8/WorkerContextExecutionProxy.cpp: (WebCore::WorkerContextExecutionProxy::initContextIfNeeded): each worker context now have a debug id (similar to frame contexts).
  • bindings/v8/WorkerScriptDebugServer.cpp: (WebCore::retrieveWorkerContext): (WebCore::WorkerScriptDebugServer::WorkerScriptDebugServer): (WebCore::WorkerScriptDebugServer::addListener): (WebCore::WorkerScriptDebugServer::removeListener): (WebCore::WorkerScriptDebugServer::getDebugListenerForContext): (WebCore::WorkerScriptDebugServer::runMessageLoopOnPause): run message loop until debugger command is received and execution is resumed. (WebCore::WorkerScriptDebugServer::quitMessageLoopOnPause):
  • bindings/v8/WorkerScriptDebugServer.h:
  • inspector/WorkerDebuggerAgent.cpp: (WebCore::WorkerDebuggerAgent::startListeningScriptDebugServer): (WebCore::WorkerDebuggerAgent::stopListeningScriptDebugServer):
Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r83873 r83874  
     12011-04-14  Yury Semikhatsky  <yurys@chromium.org>
     2
     3        Reviewed by Pavel Feldman.
     4
     5        [v8] Web Inspector: add initial implementation of WorkerScriptDebugServer
     6        https://bugs.webkit.org/show_bug.cgi?id=58552
     7
     8        * bindings/v8/DebuggerScript.js:
     9        * bindings/v8/WorkerContextExecutionProxy.cpp:
     10        (WebCore::WorkerContextExecutionProxy::initContextIfNeeded): each worker context
     11        now have a debug id (similar to frame contexts).
     12        * bindings/v8/WorkerScriptDebugServer.cpp:
     13        (WebCore::retrieveWorkerContext):
     14        (WebCore::WorkerScriptDebugServer::WorkerScriptDebugServer):
     15        (WebCore::WorkerScriptDebugServer::addListener):
     16        (WebCore::WorkerScriptDebugServer::removeListener):
     17        (WebCore::WorkerScriptDebugServer::getDebugListenerForContext):
     18        (WebCore::WorkerScriptDebugServer::runMessageLoopOnPause): run message loop until
     19        debugger command is received and execution is resumed.
     20        (WebCore::WorkerScriptDebugServer::quitMessageLoopOnPause):
     21        * bindings/v8/WorkerScriptDebugServer.h:
     22        * inspector/WorkerDebuggerAgent.cpp:
     23        (WebCore::WorkerDebuggerAgent::startListeningScriptDebugServer):
     24        (WebCore::WorkerDebuggerAgent::stopListeningScriptDebugServer):
     25
    1262011-04-14  Jian Li  <jianli@chromium.org>
    227
  • trunk/Source/WebCore/bindings/v8/DebuggerScript.js

    r83601 r83874  
    4848}
    4949
     50DebuggerScript.getWorkerScripts = function()
     51{
     52    var result = [];
     53    var scripts = Debug.scripts();
     54    for (var i = 0; i < scripts.length; ++i) {
     55        var script = scripts[i];
     56        // Workers don't share same V8 heap now so there is no need to complicate stuff with
     57        // the context id like we do to discriminate between scripts from different pages.
     58        // However we need to filter out v8 native scripts.
     59        if (script.context_data && script.context_data === "worker")
     60            result.push(DebuggerScript._formatScript(script));
     61    }
     62    return result;
     63}
     64
    5065DebuggerScript.getScripts = function(contextData)
    5166{
  • trunk/Source/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp

    r78226 r83874  
    151151    v8::Context::Scope scope(context);
    152152
     153    // Set DebugId for the new context.
     154    context->SetData(v8::String::New("worker"));
     155
    153156    // Create a new JS object and use it as the prototype for the shadow global object.
    154157    WrapperTypeInfo* contextType = &V8DedicatedWorkerContext::info;
  • trunk/Source/WebCore/bindings/v8/WorkerScriptDebugServer.cpp

    r82449 r83874  
    3434#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(WORKERS)
    3535
     36#include "ScriptDebugListener.h"
     37#include "V8DOMWrapper.h"
     38#include "V8DedicatedWorkerContext.h"
     39#include "V8SharedWorkerContext.h"
    3640#include "WorkerContext.h"
     41#include "WorkerContextExecutionProxy.h"
     42#include "WorkerThread.h"
     43#include <v8.h>
     44#include <wtf/MessageQueue.h>
    3745
    3846namespace WebCore {
    3947
     48static WorkerContext* retrieveWorkerContext(v8::Handle<v8::Context> context)
     49{
     50    v8::Handle<v8::Object> global = context->Global();
     51    ASSERT(!global.IsEmpty());
     52
     53    v8::Handle<v8::Object> prototype = v8::Handle<v8::Object>::Cast(global->GetPrototype());
     54    ASSERT(!prototype.IsEmpty());
     55
     56    prototype = v8::Handle<v8::Object>::Cast(prototype->GetPrototype());
     57    ASSERT(!prototype.IsEmpty());
     58
     59    WrapperTypeInfo* typeInfo = V8DOMWrapper::domWrapperType(prototype);
     60    if (&V8DedicatedWorkerContext::info == typeInfo)
     61        return V8DedicatedWorkerContext::toNative(prototype);
     62    if (&V8SharedWorkerContext::info == typeInfo)
     63        return V8SharedWorkerContext::toNative(prototype);
     64    ASSERT_NOT_REACHED();
     65    return 0;
     66}
     67
    4068WorkerScriptDebugServer::WorkerScriptDebugServer()
    4169    : ScriptDebugServer()
     70    , m_pausedWorkerContext(0)
    4271{
    4372}
    4473
    45 void WorkerScriptDebugServer::addListener(ScriptDebugListener*, WorkerContext*)
     74void WorkerScriptDebugServer::addListener(ScriptDebugListener* listener, WorkerContext* workerContext)
    4675{
     76    v8::HandleScope scope;
     77    v8::Local<v8::Context> debuggerContext = v8::Debug::GetDebugContext();
     78    v8::Context::Scope contextScope(debuggerContext);
     79
     80    if (!m_listenersMap.size()) {
     81        // FIXME: synchronize access to this code.
     82        ensureDebuggerScriptCompiled();
     83        ASSERT(!m_debuggerScript.get()->IsUndefined());
     84        v8::Debug::SetDebugEventListener2(&WorkerScriptDebugServer::v8DebugEventCallback, v8::External::New(this));
     85    }
     86    m_listenersMap.set(workerContext, listener);
     87   
     88    WorkerContextExecutionProxy* proxy = workerContext->script()->proxy();
     89    if (!proxy)
     90        return;
     91    v8::Handle<v8::Context> context = proxy->context();
     92
     93    v8::Handle<v8::Function> getScriptsFunction = v8::Local<v8::Function>::Cast(m_debuggerScript.get()->Get(v8::String::New("getWorkerScripts")));
     94    v8::Handle<v8::Value> argv[] = { v8::Handle<v8::Value>() };
     95    v8::Handle<v8::Value> value = getScriptsFunction->Call(m_debuggerScript.get(), 0, argv);
     96    if (value.IsEmpty())
     97        return;
     98    ASSERT(!value->IsUndefined() && value->IsArray());
     99    v8::Handle<v8::Array> scriptsArray = v8::Handle<v8::Array>::Cast(value);
     100    for (unsigned i = 0; i < scriptsArray->Length(); ++i)
     101        dispatchDidParseSource(listener, v8::Handle<v8::Object>::Cast(scriptsArray->Get(v8::Integer::New(i))));
    47102}
    48103
    49 void WorkerScriptDebugServer::removeListener(ScriptDebugListener*, WorkerContext*)
     104void WorkerScriptDebugServer::removeListener(ScriptDebugListener* listener, WorkerContext* workerContext)
    50105{
     106    if (!m_listenersMap.contains(workerContext))
     107        return;
     108
     109    if (m_pausedWorkerContext == workerContext)
     110        continueProgram();
     111
     112    m_listenersMap.remove(workerContext);
     113
     114    if (m_listenersMap.isEmpty())
     115        v8::Debug::SetDebugEventListener2(0);
     116}
     117
     118ScriptDebugListener* WorkerScriptDebugServer::getDebugListenerForContext(v8::Handle<v8::Context> context)
     119{
     120    WorkerContext* workerContext = retrieveWorkerContext(context);
     121    if (!workerContext)
     122        return 0;
     123    return m_listenersMap.get(workerContext);
     124}
     125
     126void WorkerScriptDebugServer::runMessageLoopOnPause(v8::Handle<v8::Context> context)
     127{
     128    WorkerContext* workerContext = retrieveWorkerContext(context);
     129    WorkerThread* workerThread = workerContext->thread();
     130
     131    m_pausedWorkerContext = workerContext;
     132
     133    MessageQueueWaitResult result;
     134    do {
     135        result = workerThread->runLoop().runInMode(workerContext, "debugger");
     136    // Keep waiting until execution is resumed.
     137    } while (result == MessageQueueMessageReceived && isPaused());
     138    m_pausedWorkerContext = 0;
     139   
     140    // The listener may have been removed in the nested loop.
     141    if (ScriptDebugListener* listener = m_listenersMap.get(workerContext))
     142        listener->didContinue();
     143}
     144
     145void WorkerScriptDebugServer::quitMessageLoopOnPause()
     146{
     147    // FIXME: do exit nested loop when listener is removed on pause.
    51148}
    52149
  • trunk/Source/WebCore/bindings/v8/WorkerScriptDebugServer.h

    r82449 r83874  
    5050
    5151private:
    52     virtual ScriptDebugListener* getDebugListenerForContext(v8::Handle<v8::Context>) { return 0; }
    53     virtual void runMessageLoopOnPause(v8::Handle<v8::Context>) { }
    54     virtual void quitMessageLoopOnPause() { }
     52    virtual ScriptDebugListener* getDebugListenerForContext(v8::Handle<v8::Context>);
     53    virtual void runMessageLoopOnPause(v8::Handle<v8::Context>);
     54    virtual void quitMessageLoopOnPause();
     55
     56    typedef HashMap<WorkerContext*, ScriptDebugListener*> ListenersMap;
     57    ListenersMap m_listenersMap;
     58    WorkerContext* m_pausedWorkerContext;
    5559};
    5660
  • trunk/Source/WebCore/inspector/WorkerDebuggerAgent.cpp

    r82449 r83874  
    5555void WorkerDebuggerAgent::startListeningScriptDebugServer()
    5656{
     57    scriptDebugServer().addListener(this, m_inspectedWorkerContext);
    5758}
    5859
    5960void WorkerDebuggerAgent::stopListeningScriptDebugServer()
    6061{
     62    scriptDebugServer().removeListener(this, m_inspectedWorkerContext);
    6163}
    6264
Note: See TracChangeset for help on using the changeset viewer.