Commit 3c120a80 authored by ap@webkit.org's avatar ap@webkit.org

Reviewed by Darin Adler.

        https://bugs.webkit.org/show_bug.cgi?id=21923
        Create an abstraction for script execution context

        * GNUmakefile.am:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * WebCoreSources.bkl:
        Added ScriptExecutionContext.{h,cpp}.

        * bindings/js/JSAudioConstructor.cpp:
        (WebCore::JSAudioConstructor::JSAudioConstructor):
        * bindings/js/JSAudioConstructor.h:
        * bindings/js/JSImageConstructor.cpp:
        (WebCore::JSImageConstructor::JSImageConstructor):
        * bindings/js/JSImageConstructor.h:
        * bindings/js/JSOptionConstructor.cpp:
        (WebCore::JSOptionConstructor::JSOptionConstructor):
        * bindings/js/JSOptionConstructor.h:
        * bindings/js/JSXMLHttpRequestConstructor.cpp:
        (WebCore::JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor):
        * bindings/js/JSXMLHttpRequestConstructor.h:
        Pass ScriptExecutionContext instead of Document to make getDOMConstructor() happy.
        Since these objects can only work within documents now, it is immediately converted back
        to Document.

        * bindings/js/JSMessageChannelConstructor.cpp:
        (WebCore::JSMessageChannelConstructor::JSMessageChannelConstructor):
        (WebCore::JSMessageChannelConstructor::construct):
        * bindings/js/JSMessageChannelConstructor.h:
        (WebCore::JSMessageChannelConstructor::scriptExecutionContext):
        MessageChannel needs to be supported in workers right away, so the constructor operates with
        it directly.

        * dom/ActiveDOMObject.cpp:
        (WebCore::ActiveDOMObject::ActiveDOMObject):
        (WebCore::ActiveDOMObject::~ActiveDOMObject):
        (WebCore::ActiveDOMObject::contextDestroyed):
        * dom/ActiveDOMObject.h:
        (WebCore::ActiveDOMObject::scriptExecutionContext):
        * bindings/js/JSDOMBinding.cpp:
        (WebCore::markActiveObjectsForContext):
        (WebCore::markCrossHeapDependentObjectsForContext):
        Use ScriptExecutionContext instead of Document, now that ActiveDOMObject and MessagePort
        tracking is handled by ScriptExecutionContext.

        * bindings/js/JSDOMBinding.h: (WebCore::getDOMPrototype): Moved to JSDOMGlobalObject.

        * bindings/js/JSDOMGlobalObject.h:
        (WebCore::getDOMConstructor): Moved to this file, as constructors live in JSDOMGlobalObject.
        Also, the two-argument version that used to be in JSDOMWindowBase.cpp need to be accessible
        to worker context implementation.
        (WebCore::scriptExecutionContext): Added a pure virtual method to access
        ScriptExecutionContext, implemented by subclasses.

        * bindings/js/JSDOMWindowBase.h:
        * bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::scriptExecutionContext):
        Implement by returning the associated document. Note that this method currently gives bogus
        results after navigation - DOMWindow Frame reference is not zeroed out, so we get a document
        that is currently in the frame, not the one associated with this window.

        * bindings/js/JSDedicatedWorkerConstructor.cpp: Removed unnecessary include of DOMWindow.h.

        * bindings/js/JSDocumentCustom.cpp: (WebCore::JSDocument::mark):
        Call markActiveObjectsForContext() by its new name.

        * dom/DedicatedWorker.cpp:
        (WebCore::DedicatedWorker::DedicatedWorker):
        (WebCore::DedicatedWorker::document):
        * dom/DedicatedWorker.h:
        * xml/XMLHttpRequest.cpp:
        (WebCore::XMLHttpRequest::document):
        * xml/XMLHttpRequest.h:
        Added a document() function that upcasts ScriptExecutionContext, as these objects only work
        within documents currently (at least for XMLHttpRequest, this will change soon though).

        * dom/Document.cpp:
        (WebCore::Document::Document):
        (WebCore::Document::~Document):
        Moved active object and MessagePort tracking up to ScriptExecutionContext, to share code
        with workers.
        
        * dom/Document.h:
        (WebCore::Document::isDocument):
        (WebCore::Document::refScriptExecutionContext):
        (WebCore::Document::derefScriptExecutionContext):
        Inherit from ScriptExecutionContext.

        * dom/MessageChannel.cpp:
        (WebCore::MessageChannel::MessageChannel):
        * dom/MessageChannel.h:
        (WebCore::MessageChannel::create):
        Use ScriptExecutionContext instead of Document.

        * dom/MessagePort.cpp:
        (WebCore::CloseMessagePortTimer::CloseMessagePortTimer): Make m_port a RefPtr, because
        MessagePort doesn't ref() itself when posting this event any more (this is a fix for an
        unrelated issue that was causing random crashes in layout tests).
        (WebCore::MessagePort::MessagePort):
        (WebCore::MessagePort::~MessagePort):
        (WebCore::MessagePort::associatedFrame):
        (WebCore::MessagePort::clone):
        (WebCore::MessagePort::postMessage):
        (WebCore::MessagePort::startConversation):
        (WebCore::MessagePort::start):
        (WebCore::MessagePort::contextDestroyed):
        (WebCore::MessagePort::dispatchMessages):
        * dom/MessagePort.h:
        (WebCore::MessagePort::create):
        (WebCore::MessagePort::scriptExecutionContext):
        Use ScriptExecutionContext instead of Document. This is a step toward making MessagePort
        work in worker contexts - we need to also make some its method thread safe for cross-thread
        messaging, and make event dispatching thread safe.

        * dom/ScriptExecutionContext.cpp: Added.
        * dom/ScriptExecutionContext.h: Added.
        ActiveDOMObject and MessagePort tracking is moved from Document.
        It is debatable whether ScriptExecutionContext should be a parent of Document or DOMWindow,
        but as I'm just moving Document code, and it is Document that is the main context object
        in our implementation currently.
        Changing ScriptExecutionContext to be a parent of DOMWindow causes a number of bugs that
        seem non-trivial to fix, and isn't really a part of this task.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@37966 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent d077c81c
2008-10-28 Alexey Proskuryakov <ap@webkit.org>
Reviewed by Darin Adler.
https://bugs.webkit.org/show_bug.cgi?id=21923
Create an abstraction for script execution context
* GNUmakefile.am:
* WebCore.pro:
* WebCore.vcproj/WebCore.vcproj:
* WebCore.xcodeproj/project.pbxproj:
* WebCoreSources.bkl:
Added ScriptExecutionContext.{h,cpp}.
* bindings/js/JSAudioConstructor.cpp:
(WebCore::JSAudioConstructor::JSAudioConstructor):
* bindings/js/JSAudioConstructor.h:
* bindings/js/JSImageConstructor.cpp:
(WebCore::JSImageConstructor::JSImageConstructor):
* bindings/js/JSImageConstructor.h:
* bindings/js/JSOptionConstructor.cpp:
(WebCore::JSOptionConstructor::JSOptionConstructor):
* bindings/js/JSOptionConstructor.h:
* bindings/js/JSXMLHttpRequestConstructor.cpp:
(WebCore::JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor):
* bindings/js/JSXMLHttpRequestConstructor.h:
Pass ScriptExecutionContext instead of Document to make getDOMConstructor() happy.
Since these objects can only work within documents now, it is immediately converted back
to Document.
* bindings/js/JSMessageChannelConstructor.cpp:
(WebCore::JSMessageChannelConstructor::JSMessageChannelConstructor):
(WebCore::JSMessageChannelConstructor::construct):
* bindings/js/JSMessageChannelConstructor.h:
(WebCore::JSMessageChannelConstructor::scriptExecutionContext):
MessageChannel needs to be supported in workers right away, so the constructor operates with
it directly.
* dom/ActiveDOMObject.cpp:
(WebCore::ActiveDOMObject::ActiveDOMObject):
(WebCore::ActiveDOMObject::~ActiveDOMObject):
(WebCore::ActiveDOMObject::contextDestroyed):
* dom/ActiveDOMObject.h:
(WebCore::ActiveDOMObject::scriptExecutionContext):
* bindings/js/JSDOMBinding.cpp:
(WebCore::markActiveObjectsForContext):
(WebCore::markCrossHeapDependentObjectsForContext):
Use ScriptExecutionContext instead of Document, now that ActiveDOMObject and MessagePort
tracking is handled by ScriptExecutionContext.
* bindings/js/JSDOMBinding.h: (WebCore::getDOMPrototype): Moved to JSDOMGlobalObject.
* bindings/js/JSDOMGlobalObject.h:
(WebCore::getDOMConstructor): Moved to this file, as constructors live in JSDOMGlobalObject.
Also, the two-argument version that used to be in JSDOMWindowBase.cpp need to be accessible
to worker context implementation.
(WebCore::scriptExecutionContext): Added a pure virtual method to access
ScriptExecutionContext, implemented by subclasses.
* bindings/js/JSDOMWindowBase.h:
* bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::scriptExecutionContext):
Implement by returning the associated document. Note that this method currently gives bogus
results after navigation - DOMWindow Frame reference is not zeroed out, so we get a document
that is currently in the frame, not the one associated with this window.
* bindings/js/JSDedicatedWorkerConstructor.cpp: Removed unnecessary include of DOMWindow.h.
* bindings/js/JSDocumentCustom.cpp: (WebCore::JSDocument::mark):
Call markActiveObjectsForContext() by its new name.
* dom/DedicatedWorker.cpp:
(WebCore::DedicatedWorker::DedicatedWorker):
(WebCore::DedicatedWorker::document):
* dom/DedicatedWorker.h:
* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::document):
* xml/XMLHttpRequest.h:
Added a document() function that upcasts ScriptExecutionContext, as these objects only work
within documents currently (at least for XMLHttpRequest, this will change soon though).
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::~Document):
Moved active object and MessagePort tracking up to ScriptExecutionContext, to share code
with workers.
* dom/Document.h:
(WebCore::Document::isDocument):
(WebCore::Document::refScriptExecutionContext):
(WebCore::Document::derefScriptExecutionContext):
Inherit from ScriptExecutionContext.
* dom/MessageChannel.cpp:
(WebCore::MessageChannel::MessageChannel):
* dom/MessageChannel.h:
(WebCore::MessageChannel::create):
Use ScriptExecutionContext instead of Document.
* dom/MessagePort.cpp:
(WebCore::CloseMessagePortTimer::CloseMessagePortTimer): Make m_port a RefPtr, because
MessagePort doesn't ref() itself when posting this event any more (this is a fix for an
unrelated issue that was causing random crashes in layout tests).
(WebCore::MessagePort::MessagePort):
(WebCore::MessagePort::~MessagePort):
(WebCore::MessagePort::associatedFrame):
(WebCore::MessagePort::clone):
(WebCore::MessagePort::postMessage):
(WebCore::MessagePort::startConversation):
(WebCore::MessagePort::start):
(WebCore::MessagePort::contextDestroyed):
(WebCore::MessagePort::dispatchMessages):
* dom/MessagePort.h:
(WebCore::MessagePort::create):
(WebCore::MessagePort::scriptExecutionContext):
Use ScriptExecutionContext instead of Document. This is a step toward making MessagePort
work in worker contexts - we need to also make some its method thread safe for cross-thread
messaging, and make event dispatching thread safe.
* dom/ScriptExecutionContext.cpp: Added.
* dom/ScriptExecutionContext.h: Added.
ActiveDOMObject and MessagePort tracking is moved from Document.
It is debatable whether ScriptExecutionContext should be a parent of Document or DOMWindow,
but as I'm just moving Document code, and it is Document that is the main context object
in our implementation currently.
Changing ScriptExecutionContext to be a parent of DOMWindow causes a number of bugs that
seem non-trivial to fix, and isn't really a part of this task.
2008-10-28 Alp Toker <alp@nuanti.com>
List newly-added ImageBufferData.h in build system.
......
......@@ -627,6 +627,8 @@ webcore_sources += \
WebCore/dom/RegisteredEventListener.h \
WebCore/dom/ScriptElement.cpp \
WebCore/dom/ScriptElement.h \
WebCore/dom/ScriptExecutionContext.cpp \
WebCore/dom/ScriptExecutionContext.h \
WebCore/dom/SelectorNodeList.cpp \
WebCore/dom/SelectorNodeList.h \
WebCore/dom/StaticNodeList.cpp \
......
......@@ -563,6 +563,7 @@ SOURCES += \
dom/Range.cpp \
dom/RegisteredEventListener.cpp \
dom/ScriptElement.cpp \
dom/ScriptExecutionContext.cpp \
dom/SelectorNodeList.cpp \
dom/StaticNodeList.cpp \
dom/StyledElement.cpp \
......
......@@ -11117,6 +11117,22 @@
RelativePath="..\dom\ScriptElement.h"
>
</File>
<File
RelativePath="..\dom\ScriptExecutionContext.cpp"
>
<FileConfiguration
Name="Release_PGO|Win32"
>
<Tool
Name="VCCLCompilerTool"
WholeProgramOptimization="true"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\dom\ScriptExecutionContext.h"
>
</File>
<File
RelativePath="..\dom\SelectorNodeList.cpp"
>
......
......@@ -4142,6 +4142,8 @@
E10B9B6D0B747599003ED890 /* NativeXPathNSResolver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E10B9B6B0B747599003ED890 /* NativeXPathNSResolver.cpp */; };
E10B9CCC0B747A44003ED890 /* DOMCustomXPathNSResolver.h in Headers */ = {isa = PBXBuildFile; fileRef = E10B9CCA0B747A44003ED890 /* DOMCustomXPathNSResolver.h */; };
E10B9CCD0B747A44003ED890 /* DOMCustomXPathNSResolver.mm in Sources */ = {isa = PBXBuildFile; fileRef = E10B9CCB0B747A44003ED890 /* DOMCustomXPathNSResolver.mm */; };
E11C9D9B0EB3681200E409DB /* ScriptExecutionContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E11C9D9A0EB3681200E409DB /* ScriptExecutionContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
E11C9DB00EB3699500E409DB /* ScriptExecutionContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E11C9DAF0EB3699500E409DB /* ScriptExecutionContext.cpp */; };
E12EDB7B0B308A78002704B6 /* EventTarget.h in Headers */ = {isa = PBXBuildFile; fileRef = E12EDB7A0B308A78002704B6 /* EventTarget.h */; settings = {ATTRIBUTES = (Private, ); }; };
E12EDBEA0B308E0B002704B6 /* EventTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E12EDBE90B308E0B002704B6 /* EventTarget.cpp */; };
E17A4A1B0D97991D00FC10C6 /* DOMSVGAltGlyphElement.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 65AA6BAC0D974A00000541AE /* DOMSVGAltGlyphElement.h */; };
......@@ -8752,6 +8754,8 @@
E10B9B6B0B747599003ED890 /* NativeXPathNSResolver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NativeXPathNSResolver.cpp; sourceTree = "<group>"; };
E10B9CCA0B747A44003ED890 /* DOMCustomXPathNSResolver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMCustomXPathNSResolver.h; sourceTree = "<group>"; };
E10B9CCB0B747A44003ED890 /* DOMCustomXPathNSResolver.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMCustomXPathNSResolver.mm; sourceTree = "<group>"; };
E11C9D9A0EB3681200E409DB /* ScriptExecutionContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptExecutionContext.h; sourceTree = "<group>"; };
E11C9DAF0EB3699500E409DB /* ScriptExecutionContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScriptExecutionContext.cpp; sourceTree = "<group>"; };
E12EDB7A0B308A78002704B6 /* EventTarget.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventTarget.h; sourceTree = "<group>"; };
E12EDBE90B308E0B002704B6 /* EventTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventTarget.cpp; sourceTree = "<group>"; };
E1A302BB0DE8370300C52F2C /* StringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringBuilder.h; sourceTree = "<group>"; };
......@@ -13978,6 +13982,8 @@
85031B360A44EFC700F992E0 /* RegisteredEventListener.h */,
08A484750E5272C500C3FE76 /* ScriptElement.cpp */,
08A484760E5272C500C3FE76 /* ScriptElement.h */,
E11C9DAF0EB3699500E409DB /* ScriptExecutionContext.cpp */,
E11C9D9A0EB3681200E409DB /* ScriptExecutionContext.h */,
BC7FA6800D1F167900DB22A9 /* SelectorNodeList.cpp */,
BC7FA67F0D1F167900DB22A9 /* SelectorNodeList.h */,
BC7FA62C0D1F0EFF00DB22A9 /* StaticNodeList.cpp */,
......@@ -16154,6 +16160,7 @@
BCFF64920EAD15C200C1D6F7 /* LengthSize.h in Headers */,
E1C36C030EB076D6007410BC /* JSDOMGlobalObject.h in Headers */,
0FC705210EB1815600B90AD8 /* AtomicStringHash.h in Headers */,
E11C9D9B0EB3681200E409DB /* ScriptExecutionContext.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -18039,6 +18046,7 @@
BCE65BEA0EACDF16007E4533 /* Length.cpp in Sources */,
BCE65D320EAD1211007E4533 /* Theme.cpp in Sources */,
E1C36CBD0EB08062007410BC /* JSDOMGlobalObject.cpp in Sources */,
E11C9DB00EB3699500E409DB /* ScriptExecutionContext.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -428,6 +428,7 @@ This file contains the list of files needed to build WebCore.
dom/Range.cpp
dom/RegisteredEventListener.cpp
dom/ScriptElement.cpp
dom/ScriptExecutionContext.cpp
dom/SelectorNodeList.cpp
dom/StaticNodeList.cpp
dom/StyleElement.cpp
......
......@@ -29,9 +29,9 @@
#include "JSAudioConstructor.h"
#include "Document.h"
#include "HTMLAudioElement.h"
#include "JSHTMLAudioElement.h"
#include "ScriptExecutionContext.h"
#include "Text.h"
using namespace JSC;
......@@ -40,10 +40,12 @@ namespace WebCore {
const ClassInfo JSAudioConstructor::s_info = { "AudioConstructor", 0, 0, 0 };
JSAudioConstructor::JSAudioConstructor(ExecState* exec, Document* document)
JSAudioConstructor::JSAudioConstructor(ExecState* exec, ScriptExecutionContext* context)
: DOMObject(JSAudioConstructor::createStructureID(exec->lexicalGlobalObject()->objectPrototype()))
, m_document(static_cast<JSDocument*>(asObject(toJS(exec, document))))
{
ASSERT(context->isDocument());
m_document = static_cast<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(context))));
putDirect(exec->propertyNames().length, jsNumber(exec, 1), ReadOnly|DontDelete|DontEnum);
}
......
......@@ -36,7 +36,7 @@ namespace WebCore {
class JSAudioConstructor : public DOMObject {
public:
JSAudioConstructor(JSC::ExecState*, Document*);
JSAudioConstructor(JSC::ExecState*, ScriptExecutionContext*);
Document* document() const { return m_document->impl(); }
......
......@@ -35,7 +35,6 @@
#include "HTMLImageElement.h"
#include "HTMLNames.h"
#include "JSDOMCoreException.h"
#include "JSDOMGlobalObject.h"
#include "JSDOMWindowCustom.h"
#include "JSEventException.h"
#include "JSNode.h"
......@@ -281,12 +280,12 @@ void markDOMNodesForDocument(Document* doc)
}
}
void markActiveObjectsForDocument(JSGlobalData& globalData, Document* doc)
void markActiveObjectsForContext(JSGlobalData& globalData, ScriptExecutionContext* scriptExecutionContext)
{
// If an element has pending activity that may result in listeners being called
// (e.g. an XMLHttpRequest), we need to keep all JS wrappers alive.
const HashMap<ActiveDOMObject*, void*>& activeObjects = doc->activeDOMObjects();
const HashMap<ActiveDOMObject*, void*>& activeObjects = scriptExecutionContext->activeDOMObjects();
HashMap<ActiveDOMObject*, void*>::const_iterator activeObjectsEnd = activeObjects.end();
for (HashMap<ActiveDOMObject*, void*>::const_iterator iter = activeObjects.begin(); iter != activeObjectsEnd; ++iter) {
if (iter->first->hasPendingActivity()) {
......@@ -297,7 +296,7 @@ void markActiveObjectsForDocument(JSGlobalData& globalData, Document* doc)
}
}
const HashSet<MessagePort*>& messagePorts = doc->messagePorts();
const HashSet<MessagePort*>& messagePorts = scriptExecutionContext->messagePorts();
HashSet<MessagePort*>::const_iterator portsEnd = messagePorts.end();
for (HashSet<MessagePort*>::const_iterator iter = messagePorts.begin(); iter != portsEnd; ++iter) {
if ((*iter)->hasPendingActivity()) {
......@@ -309,9 +308,9 @@ void markActiveObjectsForDocument(JSGlobalData& globalData, Document* doc)
}
}
void markCrossHeapDependentObjectsForDocument(JSGlobalData& globalData, Document* document)
void markCrossHeapDependentObjectsForContext(JSGlobalData& globalData, ScriptExecutionContext* scriptExecutionContext)
{
const HashSet<MessagePort*>& messagePorts = document->messagePorts();
const HashSet<MessagePort*>& messagePorts = scriptExecutionContext->messagePorts();
HashSet<MessagePort*>::const_iterator portsEnd = messagePorts.end();
for (HashSet<MessagePort*>::const_iterator iter = messagePorts.begin(); iter != portsEnd; ++iter) {
MessagePort* port = *iter;
......@@ -324,7 +323,7 @@ void markCrossHeapDependentObjectsForDocument(JSGlobalData& globalData, Document
// Don't use cross-heap model of marking on same-heap pairs. Otherwise, they will never be destroyed, because a port will mark its entangled one,
// and it will never get a chance to be marked as inaccessible. So, the port will keep getting marked in this function.
if ((port->document() && entangledPort->document()) || (port->workerContext() == entangledPort->workerContext()))
if ((port->scriptExecutionContext() == entangledPort->scriptExecutionContext()) || (port->scriptExecutionContext()->isDocument() && entangledPort->scriptExecutionContext()->isDocument()))
continue;
// If the wrapper hasn't been marked during the mark phase of GC, then the port shouldn't protect its entangled one.
......
......@@ -21,9 +21,10 @@
#ifndef JSDOMBinding_h
#define JSDOMBinding_h
#include <runtime/JSFunction.h>
#include "JSDOMGlobalObject.h"
#include <kjs/interpreter.h>
#include <kjs/lookup.h>
#include <runtime/JSFunction.h>
#include <wtf/Noncopyable.h>
namespace JSC {
......@@ -68,9 +69,9 @@ namespace WebCore {
void forgetAllDOMNodesForDocument(Document*);
void updateDOMNodeDocument(Node*, Document* oldDocument, Document* newDocument);
void markDOMNodesForDocument(Document*);
void markActiveObjectsForDocument(JSC::JSGlobalData&, Document*);
void markActiveObjectsForContext(JSC::JSGlobalData&, ScriptExecutionContext*);
void markDOMObjectWrapper(JSC::JSGlobalData& globalData, void* object);
void markCrossHeapDependentObjectsForDocument(JSC::JSGlobalData&, Document*);
void markCrossHeapDependentObjectsForContext(JSC::JSGlobalData&, ScriptExecutionContext*);
JSC::StructureID* getCachedDOMStructure(JSC::ExecState*, const JSC::ClassInfo*);
JSC::StructureID* cacheDOMStructure(JSC::ExecState*, PassRefPtr<JSC::StructureID>, const JSC::ClassInfo*);
......@@ -88,15 +89,6 @@ namespace WebCore {
{
return static_cast<JSC::JSObject*>(asObject(getDOMStructure<WrapperClass>(exec)->storedPrototype()));
}
template<class ConstructorClass> inline JSC::JSObject* getDOMConstructor(JSC::ExecState* exec)
{
if (JSC::JSObject* constructor = getCachedDOMConstructor(exec, &ConstructorClass::s_info))
return constructor;
JSC::JSObject* constructor = new (exec) ConstructorClass(exec);
cacheDOMConstructor(exec, &ConstructorClass::s_info, constructor);
return constructor;
}
#define CREATE_DOM_OBJECT_WRAPPER(exec, className, object) createDOMObjectWrapper<JS##className>(exec, static_cast<className*>(object))
template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object)
{
......
......@@ -31,6 +31,8 @@
namespace WebCore {
class ScriptExecutionContext;
typedef HashMap<const JSC::ClassInfo*, RefPtr<JSC::StructureID> > JSDOMStructureMap;
typedef HashMap<const JSC::ClassInfo*, JSC::JSObject*> JSDOMConstructorMap;
......@@ -45,14 +47,38 @@ namespace WebCore {
JSDOMGlobalObject(PassRefPtr<JSC::StructureID>, JSDOMGlobalObjectData*, JSC::JSObject* thisValue);
public:
JSDOMGlobalObjectData* d() const { return static_cast<JSDOMGlobalObjectData*>(JSC::JSVariableObject::d); }
JSDOMStructureMap& structures() { return d()->structures; }
JSDOMConstructorMap& constructors() const { return d()->constructors; }
virtual ScriptExecutionContext* scriptExecutionContext() const = 0;
virtual void mark();
private:
JSDOMGlobalObjectData* d() const { return static_cast<JSDOMGlobalObjectData*>(JSC::JSVariableObject::d); }
};
template<class ConstructorClass>
inline JSC::JSObject* getDOMConstructor(JSC::ExecState* exec)
{
if (JSC::JSObject* constructor = getCachedDOMConstructor(exec, &ConstructorClass::s_info))
return constructor;
JSC::JSObject* constructor = new (exec) ConstructorClass(exec);
cacheDOMConstructor(exec, &ConstructorClass::s_info, constructor);
return constructor;
}
template<class ConstructorClass>
inline JSC::JSObject* getDOMConstructor(JSC::ExecState* exec, JSDOMGlobalObject* globalObject)
{
if (JSC::JSObject* constructor = globalObject->constructors().get(&ConstructorClass::s_info))
return constructor;
JSC::JSObject* constructor = new (exec) ConstructorClass(exec, globalObject->scriptExecutionContext());
ASSERT(!globalObject->constructors().contains(&ConstructorClass::s_info));
globalObject->constructors().set(&ConstructorClass::s_info, constructor);
return constructor;
}
} // namespace WebCore
#endif // JSDOMGlobalObject_h
......@@ -223,6 +223,11 @@ JSDOMWindowBase::~JSDOMWindowBase()
i1->second->clearWindow();
}
ScriptExecutionContext* JSDOMWindowBase::scriptExecutionContext() const
{
return d()->impl->document();
}
static bool allowPopUp(ExecState* exec)
{
Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();
......@@ -402,17 +407,6 @@ static JSValue* showModalDialog(ExecState* exec, Frame* frame, const String& url
return returnValue ? returnValue : jsUndefined();
}
template<class ConstructorClass>
static JSObject* getDOMConstructor(JSC::ExecState* exec, const JSDOMWindowBase* window)
{
if (JSObject* constructor = window->constructors().get(&ConstructorClass::s_info))
return constructor;
JSObject* constructor = new (exec) ConstructorClass(exec, window->impl()->document());
ASSERT(!window->constructors().contains(&ConstructorClass::s_info));
window->constructors().set(&ConstructorClass::s_info, constructor);
return constructor;
}
} // namespace WebCore
using namespace WebCore;
......@@ -526,7 +520,7 @@ void JSDOMWindowBase::markCrossHeapDependentObjects()
if (!document)
return;
markCrossHeapDependentObjectsForDocument(*globalData(), document);
markCrossHeapDependentObjectsForContext(*globalData(), document);
}
bool JSDOMWindowBase::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
......
......@@ -22,7 +22,6 @@
#include "PlatformString.h"
#include "JSDOMBinding.h"
#include "JSDOMGlobalObject.h"
#include <kjs/protect.h>
#include <wtf/HashMap.h>
#include <wtf/OwnPtr.h>
......@@ -59,6 +58,7 @@ namespace WebCore {
void updateDocument();
DOMWindow* impl() const { return d()->impl.get(); }
virtual ScriptExecutionContext* scriptExecutionContext() const;
void disconnectFrame();
......
......@@ -29,7 +29,6 @@
#include "JSDedicatedWorkerConstructor.h"
#include "DOMWindow.h"
#include "DedicatedWorker.h"
#include "Document.h"
#include "ExceptionCode.h"
......
......@@ -46,7 +46,7 @@ void JSDocument::mark()
{
JSEventTargetNode::mark();
markDOMNodesForDocument(impl());
markActiveObjectsForDocument(*Heap::heap(this)->globalData(), impl());
markActiveObjectsForContext(*Heap::heap(this)->globalData(), impl());
}
JSValue* JSDocument::location(ExecState* exec) const
......
......@@ -20,9 +20,9 @@
#include "config.h"
#include "JSImageConstructor.h"
#include "Document.h"
#include "HTMLImageElement.h"
#include "JSNode.h"
#include "ScriptExecutionContext.h"
using namespace JSC;
......@@ -32,10 +32,11 @@ ASSERT_CLASS_FITS_IN_CELL(JSImageConstructor)
const ClassInfo JSImageConstructor::s_info = { "ImageConstructor", 0, 0, 0 };
JSImageConstructor::JSImageConstructor(ExecState* exec, Document* document)
JSImageConstructor::JSImageConstructor(ExecState* exec, ScriptExecutionContext* context)
: DOMObject(JSImageConstructor::createStructureID(exec->lexicalGlobalObject()->objectPrototype()))
, m_document(static_cast<JSDocument*>(asObject(toJS(exec, document))))
{
ASSERT(context->isDocument());
m_document = static_cast<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(context))));
}
static JSObject* constructImage(ExecState* exec, JSObject* constructor, const ArgList& args)
......
......@@ -25,11 +25,9 @@
namespace WebCore {
class Document;
class JSImageConstructor : public DOMObject {
public:
JSImageConstructor(JSC::ExecState*, Document*);
JSImageConstructor(JSC::ExecState*, ScriptExecutionContext*);
Document* document() const { return m_document->impl(); }
static const JSC::ClassInfo s_info;
......
......@@ -27,6 +27,7 @@
#include "JSMessageChannelConstructor.h"
#include "Document.h"
#include "JSDocument.h"
#include "JSMessageChannel.h"
#include "MessageChannel.h"
......@@ -36,10 +37,17 @@ namespace WebCore {
const ClassInfo JSMessageChannelConstructor::s_info = { "MessageChannelConstructor", 0, 0, 0 };
JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, Document* document)
JSMessageChannelConstructor::JSMessageChannelConstructor(ExecState* exec, ScriptExecutionContext* scriptExecutionContext)
: DOMObject(JSMessageChannelConstructor::createStructureID(exec->lexicalGlobalObject()->objectPrototype()))
, m_document(static_cast<JSDocument*>(asObject(toJS(exec, document))))
, m_scriptExecutionContext(scriptExecutionContext)
{
if (m_scriptExecutionContext->isDocument())
m_contextWrapper = toJS(exec, static_cast<Document*>(scriptExecutionContext));
else if (m_scriptExecutionContext->isWorkerContext())
; // Not yet implemented.
else
ASSERT_NOT_REACHED();
putDirect(exec->propertyNames().prototype, JSMessageChannelPrototype::self(exec), None);
}
......@@ -55,14 +63,14 @@ ConstructType JSMessageChannelConstructor::getConstructData(ConstructData& const
JSObject* JSMessageChannelConstructor::construct(ExecState* exec, JSObject* constructor, const ArgList&)
{
return asObject(toJS(exec, MessageChannel::create(static_cast<JSMessageChannelConstructor*>(constructor)->document())));
return asObject(toJS(exec, MessageChannel::create(static_cast<JSMessageChannelConstructor*>(constructor)->scriptExecutionContext())));
}
void JSMessageChannelConstructor::mark()
{
DOMObject::mark();
if (!m_document->marked())
m_document->mark();
if (!m_contextWrapper->marked())
m_contextWrapper->mark();
}
} // namespace WebCore
......@@ -27,28 +27,27 @@
#define JSMessageChannelConstructor_h
#include "JSDOMBinding.h"
#include "JSDocument.h"
namespace WebCore {
class Frame;
class JSMessageChannelConstructor : public DOMObject {
public:
JSMessageChannelConstructor(JSC::ExecState*, Document*);
JSMessageChannelConstructor(JSC::ExecState*, ScriptExecutionContext*);
virtual ~JSMessageChannelConstructor();
virtual const JSC::ClassInfo* classInfo() const { return &s_info; }
static const JSC::ClassInfo s_info;
Document* document() const { return m_document->impl(); }
ScriptExecutionContext* scriptExecutionContext() const { return m_scriptExecutionContext; }
virtual bool implementsHasInstance() const { return true; }
static JSC::JSObject* construct(JSC::ExecState*, JSC::JSObject*, const JSC::ArgList&);
virtual JSC::ConstructType getConstructData(JSC::ConstructData&);
virtual void mark();
private:
JSDocument* m_document;
ScriptExecutionContext* m_scriptExecutionContext;
JSC::JSValue* m_contextWrapper;
};
} // namespace WebCore
......
......@@ -20,9 +20,9 @@
#include "config.h"
#include "JSOptionConstructor.h"
#include "Document.h"
#include "HTMLOptionElement.h"
#include "JSHTMLOptionElement.h"
#include "ScriptExecutionContext.h"
#include "Text.h"
using namespace JSC;
......@@ -33,10 +33,12 @@ ASSERT_CLASS_FITS_IN_CELL(JSOptionConstructor)
const ClassInfo JSOptionConstructor::s_info = { "OptionConstructor", 0, 0, 0 };
JSOptionConstructor::JSOptionConstructor(ExecState* exec, Document* document)
JSOptionConstructor::JSOptionConstructor(ExecState* exec, ScriptExecutionContext* context)
: DOMObject(JSOptionConstructor::createStructureID(exec->lexicalGlobalObject()->objectPrototype()))
, m_document(static_cast<JSDocument*>(asObject(toJS(exec, document))))
{
ASSERT(context->isDocument());
m_document = static_cast<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(context))));
putDirect(exec->propertyNames().length, jsNumber(exec, 4), ReadOnly|DontDelete|DontEnum);
}
......
......@@ -28,7 +28,7 @@ namespace WebCore {
class JSOptionConstructor : public DOMObject {
public:
JSOptionConstructor(JSC::ExecState*, Document*);
JSOptionConstructor(JSC::ExecState*, ScriptExecutionContext*);
Document* document() const { return m_document->impl(); }
static const JSC::ClassInfo s_info;
......
......@@ -20,8 +20,8 @@
#include "config.h"
#include "JSXMLHttpRequestConstructor.h"
#include "Document.h"
#include "JSXMLHttpRequest.h"
#include "ScriptExecutionContext.h"
#include "XMLHttpRequest.h"
using namespace JSC;
......@@ -32,10 +32,12 @@ ASSERT_CLASS_FITS_IN_CELL(JSXMLHttpRequestConstructor)
const ClassInfo JSXMLHttpRequestConstructor::s_info = { "XMLHttpRequestConstructor", 0, 0, 0 };
JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor(ExecState* exec, Document* document)
JSXMLHttpRequestConstructor::JSXMLHttpRequestConstructor(ExecState* exec, ScriptExecutionContext* context)
: DOMObject(JSXMLHttpRequestConstructor::createStructureID(exec->lexicalGlobalObject()->objectPrototype()))
, m_document(static_cast<JSDocument*>(asObject(toJS(exec, document))))
{
ASSERT(context->isDocument());
m_document = static_cast<JSDocument*>(asObject(toJS(exec, static_cast<Document*>(context))));
putDirect(exec->propertyNames().prototype, JSXMLHttpRequestPrototype::self(exec), None);
}
......
......@@ -25,11 +25,9 @@
namespace WebCore {
class Document; <