Changeset 52877 in webkit


Ignore:
Timestamp:
Jan 6, 2010 4:16:00 PM (14 years ago)
Author:
abarth@webkit.org
Message:

2010-01-06 Adam Barth <abarth@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):
Location:
trunk/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r52875 r52877  
     12010-01-06  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        [v8] Let ScriptController have more than one windowShell
     6        https://bugs.webkit.org/show_bug.cgi?id=33243
     7
     8        This patch lets ScriptController have more than one windowShell.  We're
     9        currently only using one of them (for the main world), but this patch
     10        lets us use other ones for isolated worlds soon.
     11
     12        * bindings/ScriptControllerBase.cpp:
     13        (WebCore::ScriptController::executeScriptInWorld):
     14        * bindings/js/ScriptController.cpp:
     15        * bindings/v8/ScriptController.cpp:
     16        (WebCore::ScriptController::createWorld):
     17        (WebCore::ScriptController::initScript):
     18        (WebCore::ScriptController::ScriptController):
     19        (WebCore::ScriptController::~ScriptController):
     20        (WebCore::ScriptController::updateSecurityOrigin):
     21        (WebCore::ScriptController::evaluateInIsolatedWorld):
     22        (WebCore::ScriptController::evaluateInWorld):
     23        (WebCore::ScriptController::mainWorldWindowShell):
     24        (WebCore::ScriptController::clearWindowShell):
     25        (WebCore::ScriptController::clearForClose):
     26        (WebCore::ScriptController::destroyWindowShell):
     27        (WebCore::ScriptController::updateDocument):
     28        * bindings/v8/ScriptController.h:
     29        (WebCore::ScriptController::windowShell):
     30        (WebCore::ScriptController::existingWindowShell):
     31        (WebCore::ScriptController::globalObject):
     32        (WebCore::ScriptController::proxy):
     33        * bindings/v8/V8DOMWindowShell.cpp:
     34        (WebCore::V8DOMWindowShell::create):
     35        (WebCore::V8DOMWindowShell::V8DOMWindowShell):
     36        (WebCore::V8DOMWindowShell::initContextIfNeeded):
     37        * bindings/v8/V8DOMWindowShell.h:
     38        * bindings/v8/V8DOMWrapper.cpp:
     39        (WebCore::V8DOMWrapper::instantiateV8Object):
     40        (WebCore::V8DOMWrapper::convertNewNodeToV8Object):
     41
    1422010-01-06  Mark Rowe  <mrowe@apple.com>
    243
  • trunk/WebCore/bindings/ScriptControllerBase.cpp

    r51820 r52877  
    5454}
    5555
     56ScriptValue ScriptController::executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture)
     57{
     58    ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url());
     59
     60    if (!isEnabled() || isPaused())
     61        return ScriptValue();
     62
     63    bool wasInExecuteScript = m_inExecuteScript;
     64    m_inExecuteScript = true;
     65
     66    ScriptValue result = evaluateInWorld(sourceCode, world);
     67
     68    if (!wasInExecuteScript) {
     69        m_inExecuteScript = false;
     70        Document::updateStyleForAllDocuments();
     71    }
     72
     73    return result;
     74}
    5675
    5776bool ScriptController::executeIfJavaScriptURL(const KURL& url, bool userGesture, bool replaceDocument)
  • trunk/WebCore/bindings/js/ScriptController.cpp

    r51577 r52877  
    447447}
    448448
    449 ScriptValue ScriptController::executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture)
    450 {
    451     ScriptSourceCode sourceCode(script, forceUserGesture ? KURL() : m_frame->loader()->url());
    452 
    453     if (!isEnabled() || isPaused())
    454         return ScriptValue();
    455 
    456     bool wasInExecuteScript = m_inExecuteScript;
    457     m_inExecuteScript = true;
    458 
    459     ScriptValue result = evaluateInWorld(sourceCode, world);
    460 
    461     if (!wasInExecuteScript) {
    462         m_inExecuteScript = false;
    463         Document::updateStyleForAllDocuments();
    464     }
    465 
    466     return result;
    467 }
    468 
    469449} // namespace WebCore
  • trunk/WebCore/bindings/v8/ScriptController.cpp

    r52847 r52877  
    6161namespace WebCore {
    6262
     63PassRefPtr<DOMWrapperWorld> ScriptController::createWorld()
     64{
     65    return IsolatedWorld::create();
     66}
     67
     68V8DOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world)
     69{
     70    ASSERT(!m_windowShells.contains(world));
     71
     72    RefPtr<V8DOMWindowShell> windowShell = V8DOMWindowShell::create(m_frame, world);
     73    m_windowShells.add(world, windowShell);
     74    windowShell->initContextIfNeeded();
     75    windowShell->updateDocument();
     76
     77    m_frame->loader()->dispatchDidClearWindowObjectInWorld(world);
     78
     79    return windowShell.get();
     80}
     81
    6382void ScriptController::initializeThreading()
    6483{
     
    107126    , m_paused(false)
    108127    , m_proxy(new V8Proxy(frame))
    109     , m_windowShell(V8DOMWindowShell::create(frame))
    110128#if ENABLE(NETSCAPE_PLUGIN_API)
    111129    , m_windowScriptNPObject(0)
     
    118136{
    119137    m_proxy->disconnectFrame();
    120     m_windowShell.clear();
     138
     139    if (!m_windowShells.isEmpty()) {
     140        m_windowShells.clear();
     141        m_mainWorldWindowShell = 0;
     142        // JSC triggers a GC here, but we haven't historically.
     143    }
    121144}
    122145
     
    143166void ScriptController::updateSecurityOrigin()
    144167{
    145     m_windowShell->updateSecurityOrigin();
     168    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
     169        iter->second->updateSecurityOrigin();
    146170}
    147171
     
    209233{
    210234    // FIXME: This will need to get reorganized once we have a windowShell for the isolated world.
    211     m_windowShell->initContextIfNeeded();
     235   
     236    // Force the mainWindowShell to exist.
     237    windowShell(mainThreadNormalWorld());
    212238    m_proxy->evaluateInIsolatedWorld(worldID, sources, 0);
    213239}
     
    249275}
    250276
     277ScriptValue ScriptController::evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*)
     278{
     279    // FIXME: Move isolated world execution to here!
     280    notImplemented();
     281    return ScriptValue();
     282}
     283
    251284void ScriptController::setEventHandlerLineNumber(int lineNumber)
    252285{
     
    292325{
    293326    v8::V8::LowMemoryNotification();
    294 }
    295 
    296 bool ScriptController::haveInterpreter() const
    297 {
    298     return m_windowShell->isContextInitialized();
    299327}
    300328
     
    440468}
    441469
    442 V8DOMWindowShell* ScriptController::mainWorldWindowShell() const
    443 {
    444     m_windowShell->initContextIfNeeded();
    445     return m_windowShell.get();
     470V8DOMWindowShell* ScriptController::mainWorldWindowShell()
     471{
     472    if (!m_mainWorldWindowShell)
     473        m_mainWorldWindowShell = windowShell(mainThreadNormalWorld());
     474    return m_mainWorldWindowShell.get();
    446475}
    447476
     
    454483    // when a frame is loading a new page. V8DOMWindowShell::clearForNavigation
    455484    // creates a new context for the new page.
    456     m_windowShell->clearForNavigation();
     485    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
     486        iter->second->clearForNavigation();
    457487}
    458488
    459489void ScriptController::clearForClose()
    460490{
    461     m_windowShell->clearForClose();
     491    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
     492        iter->second->clearForClose();
    462493}
    463494
    464495void ScriptController::destroyWindowShell()
    465496{
    466     m_windowShell->clearForClose();
    467     m_windowShell->destroyGlobal();
     497    m_windowShells.clear();
     498    m_mainWorldWindowShell = 0;
    468499}
    469500
     
    475506void ScriptController::updateDocument()
    476507{
    477     m_windowShell->updateDocument();
     508    // This seems redudant, but JSC does it.
     509    if (!m_frame->document())
     510        return;
     511
     512    for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter)
     513        iter->second->updateDocument();
    478514}
    479515
  • trunk/WebCore/bindings/v8/ScriptController.h

    r52847 r52877  
    5252class ScriptState;
    5353class String;
     54class V8DOMWindow;
    5455class Widget;
    5556class XSSAuditor;
    5657
    5758class ScriptController {
     59    typedef WTF::HashMap< RefPtr<DOMWrapperWorld>, RefPtr<V8DOMWindowShell> > ShellMap;
     60
    5861public:
    5962    ScriptController(Frame*);
    6063    ~ScriptController();
    6164
     65    static PassRefPtr<DOMWrapperWorld> createWorld();
     66
     67    V8DOMWindowShell* windowShell(DOMWrapperWorld* world)
     68    {
     69        ShellMap::iterator iter = m_windowShells.find(world);
     70        return (iter != m_windowShells.end()) ? iter->second.get() : initScript(world);
     71    }
     72    V8DOMWindowShell* existingWindowShell(DOMWrapperWorld* world) const
     73    {
     74        ShellMap::const_iterator iter = m_windowShells.find(world);
     75        return (iter != m_windowShells.end()) ? iter->second.get() : 0;
     76    }
     77    V8DOMWindow* globalObject(DOMWrapperWorld* world)
     78    {
     79        notImplemented();
     80        return 0;
     81    }
     82
     83    static void getAllWorlds(Vector<DOMWrapperWorld*>&);
     84
     85    ScriptValue executeScript(const ScriptSourceCode&);
     86    ScriptValue executeScript(const String& script, bool forceUserGesture = false);
     87    ScriptValue executeScriptInWorld(DOMWrapperWorld* world, const String& script, bool forceUserGesture = false);
     88
     89    // Returns true if argument is a JavaScript URL.
     90    bool executeIfJavaScriptURL(const KURL&, bool userGesture = false, bool replaceDocument = true);
     91
     92    // This function must be called from the main thread. It is safe to call it repeatedly.
     93    static void initializeThreading();
     94
     95    ScriptValue evaluate(const ScriptSourceCode&);
     96    ScriptValue evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*);
     97
     98    // ==== End identical match with JSC's ScriptController === //
     99
    62100    // FIXME: V8Proxy should either be folded into ScriptController
    63101    // or this accessor should be made JSProxy*
    64102    V8Proxy* proxy() { return m_proxy.get(); }
    65103
    66     V8DOMWindowShell* mainWorldWindowShell() const;
    67 
    68     ScriptValue executeScript(const ScriptSourceCode&);
    69     ScriptValue executeScript(const String& script, bool forceUserGesture = false);
    70 
    71     // Returns true if argument is a JavaScript URL.
    72     bool executeIfJavaScriptURL(const KURL&, bool userGesture = false, bool replaceDocument = true);
    73 
    74     // This function must be called from the main thread. It is safe to call it repeatedly.
    75     static void initializeThreading();
    76 
    77     // Evaluate a script file in the environment of this proxy.
    78     // If succeeded, 'succ' is set to true and result is returned
    79     // as a string.
    80     ScriptValue evaluate(const ScriptSourceCode&);
     104    // FIXME: We should eventually remove all clients of this method. The
     105    // problem is that some of them are in very hot code paths.
     106    V8DOMWindowShell* mainWorldWindowShell();
    81107
    82108    void evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>&);
     
    94120    void evaluateInIsolatedWorld(unsigned worldID, const Vector<ScriptSourceCode>&, int extensionGroup);
    95121
    96     // Masquerade 'this' as the windowShell.
    97     // This is a bit of a hack, but provides reasonable compatibility
    98     // with what JSC does as well.
    99     ScriptController* windowShell(DOMWrapperWorld*) { return this; }
    100     ScriptController* existingWindowShell(DOMWrapperWorld*) { return this; }
    101 
    102122    XSSAuditor* xssAuditor() { return m_XSSAuditor.get(); }
    103123
     
    111131
    112132    PassScriptInstance createScriptInstanceForWidget(Widget*);
    113 
    114     // Check if the javascript engine has been initialized.
    115     bool haveInterpreter() const;
    116133
    117134    bool isEnabled() const;
     
    171188#endif
    172189
    173     // Dummy method to avoid a bunch of ifdef's in WebCore.
    174     void evaluateInWorld(const ScriptSourceCode&, DOMWrapperWorld*) { }
    175     static void getAllWorlds(Vector<DOMWrapperWorld*>& worlds);
    176 
    177190    // Script state for the main world context.
    178191    ScriptState* mainWorldScriptState();
     
    182195
    183196private:
     197    V8DOMWindowShell* initScript(DOMWrapperWorld*);
     198
     199    ShellMap m_windowShells;
    184200    Frame* m_frame;
     201
     202    // This is a cache of the main world's windowShell.  We have this
     203    // because we need access to it during some wrapper operations that
     204    // are performance sensitive.  Those call sites are wrong, but I'm
     205    // waiting to remove them until the next patch.
     206    RefPtr<V8DOMWindowShell> m_mainWorldWindowShell;
     207
    185208    const String* m_sourceURL;
    186209
     
    192215    // FIXME: V8Proxy should eventually be removed.
    193216    OwnPtr<V8Proxy> m_proxy;
    194 
    195     // For the moment, we have one of these.  Soon we will have one per DOMWrapperWorld.
    196     RefPtr<V8DOMWindowShell> m_windowShell;
    197217
    198218    typedef HashMap<Widget*, NPObject*> PluginObjectMap;
  • trunk/WebCore/bindings/v8/V8DOMWindowShell.cpp

    r52867 r52877  
    3737#include "DocumentLoader.h"
    3838#include "DOMObjectsInclude.h"
     39#include "DOMWrapperWorld.h"
    3940#include "Frame.h"
    4041#include "FrameLoaderClient.h"
     
    123124}
    124125
    125 PassRefPtr<V8DOMWindowShell> V8DOMWindowShell::create(Frame* frame)
    126 {
    127     return adoptRef(new V8DOMWindowShell(frame));
    128 }
    129 
    130 V8DOMWindowShell::V8DOMWindowShell(Frame* frame)
     126PassRefPtr<V8DOMWindowShell> V8DOMWindowShell::create(Frame* frame, DOMWrapperWorld* world)
     127{
     128    return adoptRef(new V8DOMWindowShell(frame, world));
     129}
     130
     131V8DOMWindowShell::V8DOMWindowShell(Frame* frame, DOMWrapperWorld* world)
    131132    : m_frame(frame)
     133    , m_world(world)
    132134{
    133135}
     
    312314    setSecurityToken();
    313315
     316    // FIXME: JSC doesn't seem to make this callback.
    314317    m_frame->loader()->client()->didCreateScriptContextForFrame();
    315 
    316     // FIXME: This is wrong. We should actually do this for the proper world once
    317     // we do isolated worlds the WebCore way.
    318     m_frame->loader()->dispatchDidClearWindowObjectInWorld(0);
    319318}
    320319
Note: See TracChangeset for help on using the changeset viewer.