[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

abarth at webkit.org abarth at webkit.org
Thu Apr 8 00:56:08 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 9d0c59ddabf2817791e1326e394610c380262f4d
Author: abarth at webkit.org <abarth at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Jan 7 00:16:00 2010 +0000

    2010-01-06  Adam Barth  <abarth at webkit.org>
    
            Reviewed by Eric Seidel.
    
            [v8] Let ScriptController have more than one windowShell
            https://bugs.webkit.org/show_bug.cgi?id=33243
    
            This patch lets ScriptController have more than one windowShell.  We're
            currently only using one of them (for the main world), but this patch
            lets us use other ones for isolated worlds soon.
    
            * bindings/ScriptControllerBase.cpp:
            (WebCore::ScriptController::executeScriptInWorld):
            * bindings/js/ScriptController.cpp:
            * bindings/v8/ScriptController.cpp:
            (WebCore::ScriptController::createWorld):
            (WebCore::ScriptController::initScript):
            (WebCore::ScriptController::ScriptController):
            (WebCore::ScriptController::~ScriptController):
            (WebCore::ScriptController::updateSecurityOrigin):
            (WebCore::ScriptController::evaluateInIsolatedWorld):
            (WebCore::ScriptController::evaluateInWorld):
            (WebCore::ScriptController::mainWorldWindowShell):
            (WebCore::ScriptController::clearWindowShell):
            (WebCore::ScriptController::clearForClose):
            (WebCore::ScriptController::destroyWindowShell):
            (WebCore::ScriptController::updateDocument):
            * bindings/v8/ScriptController.h:
            (WebCore::ScriptController::windowShell):
            (WebCore::ScriptController::existingWindowShell):
            (WebCore::ScriptController::globalObject):
            (WebCore::ScriptController::proxy):
            * bindings/v8/V8DOMWindowShell.cpp:
            (WebCore::V8DOMWindowShell::create):
            (WebCore::V8DOMWindowShell::V8DOMWindowShell):
            (WebCore::V8DOMWindowShell::initContextIfNeeded):
            * bindings/v8/V8DOMWindowShell.h:
            * bindings/v8/V8DOMWrapper.cpp:
            (WebCore::V8DOMWrapper::instantiateV8Object):
            (WebCore::V8DOMWrapper::convertNewNodeToV8Object):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52877 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 7f672bb..c2a3342 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,44 @@
+2010-01-06  Adam Barth  <abarth at webkit.org>
+
+        Reviewed by Eric Seidel.
+
+        [v8] Let ScriptController have more than one windowShell
+        https://bugs.webkit.org/show_bug.cgi?id=33243
+
+        This patch lets ScriptController have more than one windowShell.  We're
+        currently only using one of them (for the main world), but this patch
+        lets us use other ones for isolated worlds soon.
+
+        * bindings/ScriptControllerBase.cpp:
+        (WebCore::ScriptController::executeScriptInWorld):
+        * bindings/js/ScriptController.cpp:
+        * bindings/v8/ScriptController.cpp:
+        (WebCore::ScriptController::createWorld):
+        (WebCore::ScriptController::initScript):
+        (WebCore::ScriptController::ScriptController):
+        (WebCore::ScriptController::~ScriptController):
+        (WebCore::ScriptController::updateSecurityOrigin):
+        (WebCore::ScriptController::evaluateInIsolatedWorld):
+        (WebCore::ScriptController::evaluateInWorld):
+        (WebCore::ScriptController::mainWorldWindowShell):
+        (WebCore::ScriptController::clearWindowShell):
+        (WebCore::ScriptController::clearForClose):
+        (WebCore::ScriptController::destroyWindowShell):
+        (WebCore::ScriptController::updateDocument):
+        * bindings/v8/ScriptController.h:
+        (WebCore::ScriptController::windowShell):
+        (WebCore::ScriptController::existingWindowShell):
+        (WebCore::ScriptController::globalObject):
+        (WebCore::ScriptController::proxy):
+        * bindings/v8/V8DOMWindowShell.cpp:
+        (WebCore::V8DOMWindowShell::create):
+        (WebCore::V8DOMWindowShell::V8DOMWindowShell):
+        (WebCore::V8DOMWindowShell::initContextIfNeeded):
+        * bindings/v8/V8DOMWindowShell.h:
+        * bindings/v8/V8DOMWrapper.cpp:
+        (WebCore::V8DOMWrapper::instantiateV8Object):
+        (WebCore::V8DOMWrapper::convertNewNodeToV8Object):
+
 2010-01-06  Mark Rowe  <mrowe at apple.com>
 
         Fix the Mac build.
diff --git a/WebCore/bindings/ScriptControllerBase.cpp b/WebCore/bindings/ScriptControllerBase.cpp
index 72c9f45..59b2a1b 100644
--- a/WebCore/bindings/ScriptControllerBase.cpp
+++ b/WebCore/bindings/ScriptControllerBase.cpp
@@ -53,6 +53,25 @@ ScriptValue ScriptController::executeScript(const ScriptSourceCode& sourceCode)
     return result;
 }
 
+ScriptValue ScriptController::executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture)
+{
+    ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url());
+
+    if (!isEnabled() || isPaused())
+        return ScriptValue();
+
+    bool wasInExecuteScript = m_inExecuteScript;
+    m_inExecuteScript = true;
+
+    ScriptValue result = evaluateInWorld(sourceCode, world);
+
+    if (!wasInExecuteScript) {
+        m_inExecuteScript = false;
+        Document::updateStyleForAllDocuments();
+    }
+
+    return result;
+}
 
 bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture, bool replaceDocument)
 {
diff --git a/WebCore/bindings/js/ScriptController.cpp b/WebCore/bindings/js/ScriptController.cpp
index 3c440db..d778122 100644
--- a/WebCore/bindings/js/ScriptController.cpp
+++ b/WebCore/bindings/js/ScriptController.cpp
@@ -446,24 +446,4 @@ void ScriptController::clearScriptObjects()
 #endif
 }
 
-ScriptValue ScriptController::executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture)
-{
-    ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url());
-
-    if (!isEnabled() || isPaused())
-        return ScriptValue();
-
-    bool wasInExecuteScript = m_inExecuteScript;
-    m_inExecuteScript = true;
-
-    ScriptValue result = evaluateInWorld(sourceCode, world);
-
-    if (!wasInExecuteScript) {
-        m_inExecuteScript = false;
-        Document::updateStyleForAllDocuments();
-    }
-
-    return result;
-}
-
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptController.cpp b/WebCore/bindings/v8/ScriptController.cpp
index 456a038..61923b8 100644
--- a/WebCore/bindings/v8/ScriptController.cpp
+++ b/WebCore/bindings/v8/ScriptController.cpp
@@ -60,6 +60,25 @@
 
 namespace WebCore {
 
+PassRefPtr<DOMWrapperWorld> ScriptController::createWorld()
+{
+    return IsolatedWorld::create();
+}
+
+V8DOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world)
+{
+    ASSERT(!m_windowShells.contains(world));
+
+    RefPtr<V8DOMWindowShell> windowShell = V8DOMWindowShell::create(m_frame, world);
+    m_windowShells.add(world, windowShell);
+    windowShell->initContextIfNeeded();
+    windowShell->updateDocument();
+
+    m_frame->loader()->dispatchDidClearWindowObjectInWorld(world);
+
+    return windowShell.get();
+}
+
 void ScriptController::initializeThreading()
 {
     static bool initializedThreading = false;
@@ -106,7 +125,6 @@ ScriptController::ScriptController(Frame* frame)
     , m_processingTimerCallback(false)
     , m_paused(false)
     , m_proxy(new V8Proxy(frame))
-    , m_windowShell(V8DOMWindowShell::create(frame))
 #if ENABLE(NETSCAPE_PLUGIN_API)
     , m_windowScriptNPObject(0)
 #endif
@@ -117,7 +135,12 @@ ScriptController::ScriptController(Frame* frame)
 ScriptController::~ScriptController()
 {
     m_proxy->disconnectFrame();
-    m_windowShell.clear();
+
+    if (!m_windowShells.isEmpty()) {
+        m_windowShells.clear();
+        m_mainWorldWindowShell = 0;
+        // JSC triggers a GC here, but we haven't historically.
+    }
 }
 
 void ScriptController::clearScriptObjects()
@@ -142,7 +165,8 @@ void ScriptController::clearScriptObjects()
 
 void ScriptController::updateSecurityOrigin()
 {
-    m_windowShell->updateSecurityOrigin();
+    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
+        iter->second->updateSecurityOrigin();
 }
 
 void ScriptController::updatePlatformScriptObjects()
@@ -208,7 +232,9 @@ bool ScriptController::anyPageIsProcessingUserGesture() const
 void ScriptController::evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>& sources)
 {
     // FIXME: This will need to get reorganized once we have a windowShell for the isolated world.
-    m_windowShell->initContextIfNeeded();
+    
+    // Force the mainWindowShell to exist.
+    windowShell(mainThreadNormalWorld());
     m_proxy->evaluateInIsolatedWorld(worldID, sources, 0);
 }
 
@@ -248,6 +274,13 @@ ScriptValue ScriptController::evaluate(const ScriptSourceCode& sourceCode)
     return ScriptValue(object);
 }
 
+ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*)
+{
+    // FIXME: Move isolated world execution to here!
+    notImplemented();
+    return ScriptValue();
+}
+
 void ScriptController::setEventHandlerLineNumber(int lineNumber)
 {
     m_proxy->setEventHandlerLineNumber(lineNumber);
@@ -293,11 +326,6 @@ void ScriptController::lowMemoryNotification()
     v8::V8::LowMemoryNotification();
 }
 
-bool ScriptController::haveInterpreter() const
-{
-    return m_windowShell->isContextInitialized();
-}
-
 bool ScriptController::isEnabled() const
 {
     Settings* settings = m_proxy->frame()->settings();
@@ -439,10 +467,11 @@ NPObject* ScriptController::createScriptObjectForPluginElement(HTMLPlugInElement
     return npCreateV8ScriptObject(0, v8::Handle<v8::Object>::Cast(v8plugin), window);
 }
 
-V8DOMWindowShell* ScriptController::mainWorldWindowShell() const
+V8DOMWindowShell* ScriptController::mainWorldWindowShell()
 {
-    m_windowShell->initContextIfNeeded();
-    return m_windowShell.get();
+    if (!m_mainWorldWindowShell)
+        m_mainWorldWindowShell = windowShell(mainThreadNormalWorld());
+    return m_mainWorldWindowShell.get();
 }
 
 void ScriptController::clearWindowShell()
@@ -453,18 +482,20 @@ void ScriptController::clearWindowShell()
     // V8 binding expects ScriptController::clearWindowShell only be called
     // when a frame is loading a new page. V8DOMWindowShell::clearForNavigation
     // creates a new context for the new page.
-    m_windowShell->clearForNavigation();
+    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
+        iter->second->clearForNavigation();
 }
 
 void ScriptController::clearForClose()
 {
-    m_windowShell->clearForClose();
+    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
+        iter->second->clearForClose();
 }
 
 void ScriptController::destroyWindowShell()
 {
-    m_windowShell->clearForClose();
-    m_windowShell->destroyGlobal();
+    m_windowShells.clear();
+    m_mainWorldWindowShell = 0;
 }
 
 void ScriptController::attachDebugger(void*)
@@ -474,7 +505,12 @@ void ScriptController::attachDebugger(void*)
 
 void ScriptController::updateDocument()
 {
-    m_windowShell->updateDocument();
+    // This seems redudant, but JSC does it.
+    if (!m_frame->document())
+        return;
+
+    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
+        iter->second->updateDocument();
 }
 
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/ScriptController.h b/WebCore/bindings/v8/ScriptController.h
index 958ebfb..25a4811 100644
--- a/WebCore/bindings/v8/ScriptController.h
+++ b/WebCore/bindings/v8/ScriptController.h
@@ -51,22 +51,40 @@ class HTMLPlugInElement;
 class ScriptSourceCode;
 class ScriptState;
 class String;
+class V8DOMWindow;
 class Widget;
 class XSSAuditor;
 
 class ScriptController {
+    typedef WTF::HashMap< RefPtr<DOMWrapperWorld>, RefPtr<V8DOMWindowShell> > ShellMap;
+
 public:
     ScriptController(Frame*);
     ~ScriptController();
 
-    // FIXME: V8Proxy should either be folded into ScriptController
-    // or this accessor should be made JSProxy*
-    V8Proxy* proxy() { return m_proxy.get(); }
-
-    V8DOMWindowShell* mainWorldWindowShell() const;
+    static PassRefPtr<DOMWrapperWorld> createWorld();
+
+    V8DOMWindowShell* windowShell(DOMWrapperWorld* world)
+    {
+        ShellMap::iterator iter = m_windowShells.find(world);
+        return (iter != m_windowShells.end()) ? iter->second.get() : initScript(world);
+    }
+    V8DOMWindowShell* existingWindowShell(DOMWrapperWorld* world) const
+    {
+        ShellMap::const_iterator iter = m_windowShells.find(world);
+        return (iter != m_windowShells.end()) ? iter->second.get() : 0;
+    }
+    V8DOMWindow* globalObject(DOMWrapperWorld* world)
+    {
+        notImplemented();
+        return 0;
+    }
+
+    static void getAllWorlds(Vector<DOMWrapperWorld*>&);
 
     ScriptValue executeScript(const ScriptSourceCode&);
     ScriptValue executeScript(const String& script, bool forceUserGesture = false);
+    ScriptValue executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture = false);
 
     // Returns true if argument is a JavaScript URL.
     bool executeIfJavaScriptURL(const KURL&, bool userGesture = false, bool replaceDocument = true);
@@ -74,10 +92,18 @@ public:
     // This function must be called from the main thread. It is safe to call it repeatedly.
     static void initializeThreading();
 
-    // Evaluate a script file in the environment of this proxy.
-    // If succeeded, 'succ' is set to true and result is returned
-    // as a string.
     ScriptValue evaluate(const ScriptSourceCode&);
+    ScriptValue evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*);
+
+    // ==== End identical match with JSC's ScriptController === //
+
+    // FIXME: V8Proxy should either be folded into ScriptController
+    // or this accessor should be made JSProxy*
+    V8Proxy* proxy() { return m_proxy.get(); }
+
+    // FIXME: We should eventually remove all clients of this method. The
+    // problem is that some of them are in very hot code paths.
+    V8DOMWindowShell* mainWorldWindowShell();
 
     void evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>&);
 
@@ -93,12 +119,6 @@ public:
     // FIXME: Get rid of extensionGroup here.
     void evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>&, int extensionGroup);
 
-    // Masquerade 'this' as the windowShell.
-    // This is a bit of a hack, but provides reasonable compatibility
-    // with what JSC does as well.
-    ScriptController* windowShell(DOMWrapperWorld*) { return this; }
-    ScriptController* existingWindowShell(DOMWrapperWorld*) { return this; }
-
     XSSAuditor* xssAuditor() { return m_XSSAuditor.get(); }
 
     void collectGarbage();
@@ -111,9 +131,6 @@ public:
 
     PassScriptInstance createScriptInstanceForWidget(Widget*);
 
-    // Check if the javascript engine has been initialized.
-    bool haveInterpreter() const;
-
     bool isEnabled() const;
 
     // FIXME: void* is a compile hack.
@@ -170,10 +187,6 @@ public:
     NPObject* windowScriptNPObject();
 #endif
 
-    // Dummy method to avoid a bunch of ifdef's in WebCore.
-    void evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*) { }
-    static void getAllWorlds(Vector<DOMWrapperWorld*>& worlds);
-
     // Script state for the main world context.
     ScriptState* mainWorldScriptState();
 
@@ -181,7 +194,17 @@ public:
     static ScriptState* currentScriptState();
 
 private:
+    V8DOMWindowShell* initScript(DOMWrapperWorld*);
+
+    ShellMap m_windowShells;
     Frame* m_frame;
+
+    // This is a cache of the main world's windowShell.  We have this
+    // because we need access to it during some wrapper operations that
+    // are performance sensitive.  Those call sites are wrong, but I'm
+    // waiting to remove them until the next patch.
+    RefPtr<V8DOMWindowShell> m_mainWorldWindowShell;
+
     const String* m_sourceURL;
 
     bool m_inExecuteScript;
@@ -192,9 +215,6 @@ private:
     // FIXME: V8Proxy should eventually be removed.
     OwnPtr<V8Proxy> m_proxy;
 
-    // For the moment, we have one of these.  Soon we will have one per DOMWrapperWorld.
-    RefPtr<V8DOMWindowShell> m_windowShell;
-
     typedef HashMap<Widget*, NPObject*> PluginObjectMap;
 
     // A mapping between Widgets and their corresponding script object.
diff --git a/WebCore/bindings/v8/V8DOMWindowShell.cpp b/WebCore/bindings/v8/V8DOMWindowShell.cpp
index 7e1491f..c89fa31 100644
--- a/WebCore/bindings/v8/V8DOMWindowShell.cpp
+++ b/WebCore/bindings/v8/V8DOMWindowShell.cpp
@@ -36,6 +36,7 @@
 #include "DateExtension.h"
 #include "DocumentLoader.h"
 #include "DOMObjectsInclude.h"
+#include "DOMWrapperWorld.h"
 #include "Frame.h"
 #include "FrameLoaderClient.h"
 #include "InspectorTimelineAgent.h"
@@ -122,13 +123,14 @@ static void reportUnsafeJavaScriptAccess(v8::Local<v8::Object> host, v8::AccessT
         V8Proxy::reportUnsafeAccessTo(target, V8Proxy::ReportLater);
 }
 
-PassRefPtr<V8DOMWindowShell> V8DOMWindowShell::create(Frame* frame)
+PassRefPtr<V8DOMWindowShell> V8DOMWindowShell::create(Frame* frame, DOMWrapperWorld* world)
 {
-    return adoptRef(new V8DOMWindowShell(frame));
+    return adoptRef(new V8DOMWindowShell(frame, world));
 }
 
-V8DOMWindowShell::V8DOMWindowShell(Frame* frame)
+V8DOMWindowShell::V8DOMWindowShell(Frame* frame, DOMWrapperWorld* world)
     : m_frame(frame)
+    , m_world(world)
 {
 }
 
@@ -311,11 +313,8 @@ void V8DOMWindowShell::initContextIfNeeded()
 
     setSecurityToken();
 
+    // FIXME: JSC doesn't seem to make this callback.
     m_frame->loader()->client()->didCreateScriptContextForFrame();
-
-    // FIXME: This is wrong. We should actually do this for the proper world once
-    // we do isolated worlds the WebCore way.
-    m_frame->loader()->dispatchDidClearWindowObjectInWorld(0);
 }
 
 v8::Persistent<v8::Context> V8DOMWindowShell::createNewContext(v8::Handle<v8::Object> global, int extensionGroup)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list