summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h')
-rw-r--r--src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h132
1 files changed, 115 insertions, 17 deletions
diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h
index e3fd41733..3975940e1 100644
--- a/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h
+++ b/src/3rdparty/webkit/WebCore/bindings/js/JSDOMBinding.h
@@ -2,6 +2,7 @@
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
* Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2007 Samuel Weinig <sam@webkit.org>
+ * Copyright (C) 2009 Google, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,6 +23,7 @@
#define JSDOMBinding_h
#include "JSDOMGlobalObject.h"
+#include "Document.h" // For DOMConstructorWithDocument
#include <runtime/Completion.h>
#include <runtime/Lookup.h>
#include <runtime/JSFunction.h>
@@ -59,6 +61,73 @@ namespace WebCore {
#endif
};
+ // FIXME: This class should colapse into DOMObject once all DOMObjects are
+ // updated to store a globalObject pointer.
+ class DOMObjectWithGlobalPointer : public DOMObject {
+ public:
+ JSDOMGlobalObject* globalObject() const { return m_globalObject; }
+
+ ScriptExecutionContext* scriptExecutionContext() const
+ {
+ // FIXME: Should never be 0, but can be due to bug 27640.
+ return m_globalObject->scriptExecutionContext();
+ }
+
+ protected:
+ DOMObjectWithGlobalPointer(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject)
+ : DOMObject(structure)
+ , m_globalObject(globalObject)
+ {
+ // FIXME: This ASSERT is valid, but fires in fast/dom/gc-6.html when trying to create
+ // new JavaScript objects on detached windows due to DOMWindow::document()
+ // needing to reach through the frame to get to the Document*. See bug 27640.
+ // ASSERT(globalObject->scriptExecutionContext());
+ }
+ virtual ~DOMObjectWithGlobalPointer() {}
+
+ void mark()
+ {
+ DOMObject::mark();
+ if (!m_globalObject->marked())
+ m_globalObject->mark();
+ }
+
+ private:
+ JSDOMGlobalObject* m_globalObject;
+ };
+
+ // Base class for all constructor objects in the JSC bindings.
+ class DOMConstructorObject : public DOMObjectWithGlobalPointer {
+ public:
+ static PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype)
+ {
+ return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::HasStandardGetOwnPropertySlot | JSC::ImplementsHasInstance));
+ }
+
+ protected:
+ DOMConstructorObject(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject)
+ : DOMObjectWithGlobalPointer(structure, globalObject)
+ {
+ }
+ };
+
+ // Constructors using this base class depend on being in a Document and
+ // can never be used from a WorkerContext.
+ class DOMConstructorWithDocument : public DOMConstructorObject {
+ public:
+ Document* document() const
+ {
+ return static_cast<Document*>(scriptExecutionContext());
+ }
+
+ protected:
+ DOMConstructorWithDocument(PassRefPtr<JSC::Structure> structure, JSDOMGlobalObject* globalObject)
+ : DOMConstructorObject(structure, globalObject)
+ {
+ ASSERT(globalObject->scriptExecutionContext()->isDocument());
+ }
+ };
+
DOMObject* getCachedDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle);
void cacheDOMObjectWrapper(JSC::JSGlobalData&, void* objectHandle, DOMObject* wrapper);
void forgetDOMObject(JSC::JSGlobalData&, void* objectHandle);
@@ -80,6 +149,14 @@ namespace WebCore {
JSC::JSObject* getCachedDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*);
void cacheDOMConstructor(JSC::ExecState*, const JSC::ClassInfo*, JSC::JSObject* constructor);
+ inline JSDOMGlobalObject* deprecatedGlobalObjectForPrototype(JSC::ExecState* exec)
+ {
+ // FIXME: Callers to this function should be using the global object
+ // from which the object is being created, instead of assuming the lexical one.
+ // e.g. subframe.document.body should use the subframe's global object, not the lexical one.
+ return static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject());
+ }
+
template<class WrapperClass> inline JSC::Structure* getDOMStructure(JSC::ExecState* exec, JSDOMGlobalObject* globalObject)
{
if (JSC::Structure* structure = getCachedDOMStructure(globalObject, &WrapperClass::s_info))
@@ -89,69 +166,69 @@ namespace WebCore {
template<class WrapperClass> inline JSC::Structure* deprecatedGetDOMStructure(JSC::ExecState* exec)
{
// FIXME: This function is wrong. It uses the wrong global object for creating the prototype structure.
- return getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()));
+ return getDOMStructure<WrapperClass>(exec, deprecatedGlobalObjectForPrototype(exec));
}
template<class WrapperClass> inline JSC::JSObject* getDOMPrototype(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject)
{
return static_cast<JSC::JSObject*>(asObject(getDOMStructure<WrapperClass>(exec, static_cast<JSDOMGlobalObject*>(globalObject))->storedPrototype()));
}
- #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)
+ #define CREATE_DOM_OBJECT_WRAPPER(exec, globalObject, className, object) createDOMObjectWrapper<JS##className>(exec, globalObject, static_cast<className*>(object))
+ template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object)
{
ASSERT(object);
ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object));
// FIXME: new (exec) could use a different globalData than the globalData this wrapper is cached on.
- WrapperClass* wrapper = new (exec) WrapperClass(deprecatedGetDOMStructure<WrapperClass>(exec), object);
+ WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, object);
cacheDOMObjectWrapper(exec->globalData(), object, wrapper);
return wrapper;
}
- template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object)
+ template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object)
{
if (!object)
return JSC::jsNull();
if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object))
return wrapper;
- return createDOMObjectWrapper<WrapperClass>(exec, object);
+ return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object);
}
#if ENABLE(SVG)
- #define CREATE_SVG_OBJECT_WRAPPER(exec, className, object, context) createDOMObjectWrapper<JS##className>(exec, static_cast<className*>(object), context)
- template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context)
+ #define CREATE_SVG_OBJECT_WRAPPER(exec, globalObject, className, object, context) createDOMObjectWrapper<JS##className>(exec, globalObject, static_cast<className*>(object), context)
+ template<class WrapperClass, class DOMClass> inline DOMObject* createDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object, SVGElement* context)
{
ASSERT(object);
ASSERT(!getCachedDOMObjectWrapper(exec->globalData(), object));
- WrapperClass* wrapper = new (exec) WrapperClass(deprecatedGetDOMStructure<WrapperClass>(exec), object, context);
+ WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, object, context);
cacheDOMObjectWrapper(exec->globalData(), object, wrapper);
return wrapper;
}
- template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, DOMClass* object, SVGElement* context)
+ template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMObjectWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* object, SVGElement* context)
{
if (!object)
return JSC::jsNull();
if (DOMObject* wrapper = getCachedDOMObjectWrapper(exec->globalData(), object))
return wrapper;
- return createDOMObjectWrapper<WrapperClass>(exec, object, context);
+ return createDOMObjectWrapper<WrapperClass>(exec, globalObject, object, context);
}
#endif
- #define CREATE_DOM_NODE_WRAPPER(exec, className, object) createDOMNodeWrapper<JS##className>(exec, static_cast<className*>(object))
- template<class WrapperClass, class DOMClass> inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node)
+ #define CREATE_DOM_NODE_WRAPPER(exec, globalObject, className, object) createDOMNodeWrapper<JS##className>(exec, globalObject, static_cast<className*>(object))
+ template<class WrapperClass, class DOMClass> inline JSNode* createDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node)
{
ASSERT(node);
ASSERT(!getCachedDOMNodeWrapper(node->document(), node));
- WrapperClass* wrapper = new (exec) WrapperClass(deprecatedGetDOMStructure<WrapperClass>(exec), node);
+ WrapperClass* wrapper = new (exec) WrapperClass(getDOMStructure<WrapperClass>(exec, globalObject), globalObject, node);
// FIXME: The entire function can be removed, once we fix caching.
// This function is a one-off hack to make Nodes cache in the right global object.
cacheDOMNodeWrapper(node->document(), node, wrapper);
return wrapper;
}
- template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMNodeWrapper(JSC::ExecState* exec, DOMClass* node)
+ template<class WrapperClass, class DOMClass> inline JSC::JSValue getDOMNodeWrapper(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, DOMClass* node)
{
if (!node)
return JSC::jsNull();
if (JSNode* wrapper = getCachedDOMNodeWrapper(node->document(), node))
return wrapper;
- return createDOMNodeWrapper<WrapperClass>(exec, node);
+ return createDOMNodeWrapper<WrapperClass>(exec, globalObject, node);
}
const JSC::HashTable* getHashTableForGlobalData(JSC::JSGlobalData&, const JSC::HashTable* staticTable);
@@ -178,7 +255,28 @@ namespace WebCore {
JSC::UString valueToStringWithNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null
JSC::UString valueToStringWithUndefinedOrNullCheck(JSC::ExecState*, JSC::JSValue); // null if the value is null or undefined
- template <typename T> inline JSC::JSValue toJS(JSC::ExecState* exec, PassRefPtr<T> ptr) { return toJS(exec, ptr.get()); }
+ // FIXME: These are a stop-gap until all toJS calls can be converted to pass a globalObject
+ template <typename T>
+ inline JSC::JSValue toJS(JSC::ExecState* exec, T* ptr)
+ {
+ return toJS(exec, deprecatedGlobalObjectForPrototype(exec), ptr);
+ }
+ template <typename T>
+ inline JSC::JSValue toJS(JSC::ExecState* exec, PassRefPtr<T> ptr)
+ {
+ return toJS(exec, deprecatedGlobalObjectForPrototype(exec), ptr.get());
+ }
+ template <typename T>
+ inline JSC::JSValue toJSNewlyCreated(JSC::ExecState* exec, T* ptr)
+ {
+ return toJSNewlyCreated(exec, deprecatedGlobalObjectForPrototype(exec), ptr);
+ }
+
+ template <typename T>
+ inline JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, PassRefPtr<T> ptr)
+ {
+ return toJS(exec, globalObject, ptr.get());
+ }
bool checkNodeSecurity(JSC::ExecState*, Node*);