Fix for bug 768692 (Move DOM list binding generation to the new DOM binding codegen). r=bzbarsky.

--HG--
extra : rebase_source : 651a0fac4c9a87ef1c0a9cd91588c6421fd050c4
This commit is contained in:
Peter Van der Beken 2012-05-22 15:46:20 +02:00
parent 75ae552319
commit 13f425b97c
50 changed files with 1768 additions and 314 deletions

View File

@ -2399,10 +2399,7 @@ nsScriptSecurityManager::old_doGetObjectPrincipal(JSObject *aObj,
if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
priv = (nsISupports *) js::GetObjectPrivate(aObj);
} else if (IsDOMClass(jsClass) &&
DOMJSClass::FromJSClass(jsClass)->mDOMObjectIsISupports) {
priv = UnwrapDOMObject<nsISupports>(aObj);
} else {
} else if (!UnwrapDOMObjectToISupports(aObj, priv)) {
priv = nullptr;
}

View File

@ -391,7 +391,7 @@ JSObject*
nsChildContentList::WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::NodeList::create(cx, scope, this, triedToWrap);
return mozilla::dom::oldproxybindings::NodeList::create(cx, scope, this, triedToWrap);
}
NS_IMETHODIMP

View File

@ -162,7 +162,7 @@ JSObject*
nsSimpleContentList::WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::NodeList::create(cx, scope, this, triedToWrap);
return mozilla::dom::oldproxybindings::NodeList::create(cx, scope, this, triedToWrap);
}
// nsFormContentList
@ -478,7 +478,7 @@ nsContentList::~nsContentList()
JSObject*
nsContentList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
{
return mozilla::dom::binding::HTMLCollection::create(cx, scope, this,
return mozilla::dom::oldproxybindings::HTMLCollection::create(cx, scope, this,
triedToWrap);
}

View File

@ -688,7 +688,7 @@ JSObject*
nsDOMFileList::WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::FileList::create(cx, scope, this, triedToWrap);
return mozilla::dom::oldproxybindings::FileList::create(cx, scope, this, triedToWrap);
}
nsIDOMFile*

View File

@ -51,6 +51,6 @@ JSObject*
nsDOMSettableTokenList::WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::DOMSettableTokenList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::DOMSettableTokenList::create(cx, scope, this,
triedToWrap);
}

View File

@ -272,7 +272,7 @@ nsDOMTokenList::ToString(nsAString& aResult)
JSObject*
nsDOMTokenList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
{
return mozilla::dom::binding::DOMTokenList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::DOMTokenList::create(cx, scope, this,
triedToWrap);
}

View File

@ -46,7 +46,7 @@ public:
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::PaintRequestList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::PaintRequestList::create(cx, scope, this,
triedToWrap);
}

View File

@ -108,7 +108,7 @@ JSObject*
HTMLPropertiesCollection::WrapObject(JSContext* cx, JSObject* scope,
bool* triedToWrap)
{
return mozilla::dom::binding::HTMLPropertiesCollection::create(cx, scope, this,
return mozilla::dom::oldproxybindings::HTMLPropertiesCollection::create(cx, scope, this,
triedToWrap);
}
@ -426,7 +426,7 @@ JSObject*
PropertyNodeList::WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::PropertyNodeList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::PropertyNodeList::create(cx, scope, this,
triedToWrap);
}

View File

@ -106,7 +106,7 @@ nsClientRectList::GetItemAt(uint32_t aIndex)
JSObject*
nsClientRectList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
{
return mozilla::dom::binding::ClientRectList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::ClientRectList::create(cx, scope, this,
triedToWrap);
}

View File

@ -121,7 +121,7 @@ public:
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::HTMLCollection::create(cx, scope, this,
return mozilla::dom::oldproxybindings::HTMLCollection::create(cx, scope, this,
triedToWrap);
}

View File

@ -2015,7 +2015,7 @@ JSObject*
nsHTMLOptionCollection::WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::HTMLOptionsCollection::create(cx, scope, this,
return mozilla::dom::oldproxybindings::HTMLOptionsCollection::create(cx, scope, this,
triedToWrap);
}

View File

@ -56,7 +56,7 @@ public:
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::HTMLCollection::create(cx, scope, this,
return mozilla::dom::oldproxybindings::HTMLCollection::create(cx, scope, this,
triedToWrap);
}

View File

@ -76,7 +76,7 @@ NS_INTERFACE_MAP_END
JSObject*
DOMSVGLengthList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
{
return mozilla::dom::binding::SVGLengthList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::SVGLengthList::create(cx, scope, this,
triedToWrap);
}

View File

@ -77,7 +77,7 @@ NS_INTERFACE_MAP_END
JSObject*
DOMSVGNumberList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
{
return mozilla::dom::binding::SVGNumberList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::SVGNumberList::create(cx, scope, this,
triedToWrap);
}

View File

@ -84,7 +84,7 @@ DOMSVGPathSegList::~DOMSVGPathSegList()
JSObject*
DOMSVGPathSegList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
{
return mozilla::dom::binding::SVGPathSegList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::SVGPathSegList::create(cx, scope, this,
triedToWrap);
}

View File

@ -103,7 +103,7 @@ DOMSVGPointList::~DOMSVGPointList()
JSObject*
DOMSVGPointList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap)
{
return mozilla::dom::binding::SVGPointList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::SVGPointList::create(cx, scope, this,
triedToWrap);
}

View File

@ -77,7 +77,7 @@ JSObject*
DOMSVGTransformList::WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::SVGTransformList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::SVGTransformList::create(cx, scope, this,
triedToWrap);
}

View File

@ -80,7 +80,7 @@ public:
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap)
{
return mozilla::dom::binding::NodeList::create(cx, scope, this,
return mozilla::dom::oldproxybindings::NodeList::create(cx, scope, this,
triedToWrap);
}

View File

@ -543,6 +543,7 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
#undef None // something included above defines this preprocessor symbol, maybe Xlib headers
#include "WebGLContext.h"
#include "nsICanvasRenderingContextInternal.h"
#include "mozilla/dom/BindingUtils.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -4575,12 +4576,13 @@ nsDOMClassInfo::Init()
sDisableGlobalScopePollutionSupport =
Preferences::GetBool("browser.dom.global_scope_pollution.disabled");
// Proxy bindings
mozilla::dom::binding::Register(nameSpaceManager);
// Non-proxy bindings
mozilla::dom::Register(nameSpaceManager);
// This needs to happen after the call to mozilla::dom::Register, because we
// overwrite some values.
mozilla::dom::oldproxybindings::Register(nameSpaceManager);
if (!AzureCanvasEnabled()) {
nameSpaceManager->RegisterDefineDOMInterface(NS_LITERAL_STRING("CanvasRenderingContext2D"), NULL);
}
@ -6746,7 +6748,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
name_struct->mType == nsGlobalNameStruct::eTypeClassProto ||
name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) {
// Lookup new DOM bindings.
mozilla::dom::binding::DefineInterface define =
mozilla::dom::DefineInterface define =
name_struct->mDefineDOMInterface;
if (define) {
if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor &&
@ -6754,7 +6756,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx,
return NS_OK;
}
if (mozilla::dom::binding::DefineConstructor(cx, obj, define, &rv)) {
if (mozilla::dom::DefineConstructor(cx, obj, define, &rv)) {
*did_resolve = NS_SUCCEEDED(rv);
return rv;
@ -8791,9 +8793,9 @@ nsHTMLDocumentSH::GetDocumentAllNodeList(JSContext *cx, JSObject *obj,
if (!JSVAL_IS_PRIMITIVE(collection)) {
// We already have a node list in our reserved slot, use it.
JSObject *obj = JSVAL_TO_OBJECT(collection);
if (mozilla::dom::binding::HTMLCollection::objIsWrapper(obj)) {
if (mozilla::dom::oldproxybindings::HTMLCollection::objIsWrapper(obj)) {
nsIHTMLCollection *native =
mozilla::dom::binding::HTMLCollection::getNative(obj);
mozilla::dom::oldproxybindings::HTMLCollection::getNative(obj);
NS_ADDREF(*nodeList = static_cast<nsContentList*>(native));
}
else {

View File

@ -781,7 +781,7 @@ nsScriptNameSpaceManager::Observe(nsISupports* aSubject, const char* aTopic,
void
nsScriptNameSpaceManager::RegisterDefineDOMInterface(const nsAFlatString& aName,
mozilla::dom::binding::DefineInterface aDefineDOMInterface)
mozilla::dom::DefineInterface aDefineDOMInterface)
{
nsGlobalNameStruct *s = AddToHash(&mGlobalNames, &aName);
if (s) {

View File

@ -67,7 +67,7 @@ struct nsGlobalNameStruct
};
// For new style DOM bindings.
mozilla::dom::binding::DefineInterface mDefineDOMInterface;
mozilla::dom::DefineInterface mDefineDOMInterface;
private:
@ -139,7 +139,7 @@ public:
nsGlobalNameStruct* GetConstructorProto(const nsGlobalNameStruct* aStruct);
void RegisterDefineDOMInterface(const nsAFlatString& aName,
mozilla::dom::binding::DefineInterface aDefineDOMInterface);
mozilla::dom::DefineInterface aDefineDOMInterface);
private:
// Adds a new entry to the hash and returns the nsGlobalNameStruct

View File

@ -8,6 +8,7 @@
#include "BindingUtils.h"
#include "WrapperFactory.h"
#include "xpcprivate.h"
#include "XPCQuickStubs.h"
@ -242,7 +243,7 @@ JSObject*
CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject *receiver,
JSObject* protoProto, JSClass* protoClass,
JSClass* constructorClass, JSNative constructor,
unsigned ctorNargs, JSClass* instanceClass,
unsigned ctorNargs, const DOMClass* domClass,
Prefable<JSFunctionSpec>* methods,
Prefable<JSPropertySpec>* properties,
Prefable<ConstantSpec>* constants,
@ -267,7 +268,7 @@ CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject *receiver,
}
js::SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
JS::PrivateValue(instanceClass));
JS::PrivateValue(const_cast<DOMClass*>(domClass)));
}
else {
proto = NULL;
@ -333,10 +334,8 @@ JSBool
InstanceClassHasProtoAtDepth(JSHandleObject protoObject, uint32_t protoID,
uint32_t depth)
{
JSClass* instanceClass = static_cast<JSClass*>(
const DOMClass* domClass = static_cast<DOMClass*>(
js::GetReservedSlot(protoObject, DOM_PROTO_INSTANCE_CLASS_SLOT).toPrivate());
MOZ_ASSERT(IsDOMClass(instanceClass));
DOMJSClass* domClass = DOMJSClass::FromJSClass(instanceClass);
return (uint32_t)domClass->mInterfaceChain[depth] == protoID;
}
@ -377,14 +376,11 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp)
if (!obj)
return false;
JSClass* clasp = js::GetObjectJSClass(obj);
if (!IsDOMClass(clasp) ||
!DOMJSClass::FromJSClass(clasp)->mDOMObjectIsISupports) {
nsISupports* native;
if (!UnwrapDOMObjectToISupports(obj, native)) {
return Throw<true>(cx, NS_ERROR_FAILURE);
}
nsISupports* native = UnwrapDOMObject<nsISupports>(obj);
if (argc < 1) {
return Throw<true>(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
}
@ -451,8 +447,9 @@ XrayResolveProperty(JSContext* cx, JSObject* wrapper, jsid id,
JSFunction *fun = JS_NewFunctionById(cx, methodSpecs[i].call.op,
methodSpecs[i].nargs, 0,
wrapper, id);
if (!fun)
return false;
if (!fun) {
return false;
}
SET_JITINFO(fun, methodSpecs[i].call.info);
JSObject *funobj = JS_GetFunctionObject(fun);
desc->value.setObject(*funobj);
@ -590,5 +587,46 @@ XrayEnumerateProperties(JS::AutoIdVector& props,
return true;
}
bool
GetPropertyOnPrototype(JSContext* cx, JSObject* proxy, jsid id, bool* found,
JS::Value* vp)
{
JSObject* proto = js::GetObjectProto(proxy);
if (!proto) {
*found = false;
return true;
}
JSBool hasProp;
if (!JS_HasPropertyById(cx, proto, id, &hasProp)) {
return false;
}
*found = hasProp;
if (!hasProp || !vp) {
return true;
}
return JS_ForwardGetPropertyTo(cx, proto, id, proxy, vp);
}
bool
HasPropertyOnPrototype(JSContext* cx, JSObject* proxy, DOMProxyHandler* handler,
jsid id)
{
JSAutoEnterCompartment ac;
if (xpc::WrapperFactory::IsXrayWrapper(proxy)) {
proxy = js::UnwrapObject(proxy);
if (!ac.enter(cx, proxy)) {
return false;
}
}
MOZ_ASSERT(js::IsProxy(proxy) && js::GetProxyHandler(proxy) == handler);
bool found;
// We ignore an error from GetPropertyOnPrototype.
return !GetPropertyOnPrototype(cx, proxy, id, &found, NULL) || found;
}
} // namespace dom
} // namespace mozilla

View File

@ -8,6 +8,7 @@
#define mozilla_dom_BindingUtils_h__
#include "mozilla/dom/DOMJSClass.h"
#include "mozilla/dom/DOMJSProxyHandler.h"
#include "mozilla/dom/workers/Workers.h"
#include "mozilla/ErrorResult.h"
@ -78,13 +79,34 @@ IsDOMClass(const js::Class* clasp)
return IsDOMClass(Jsvalify(clasp));
}
// It's ok for eRegularDOMObject and eProxyDOMObject to be the same, but
// eNonDOMObject should always be different from the other two. This enum
// shouldn't be used to differentiate between non-proxy and proxy bindings.
enum DOMObjectSlot {
eNonDOMObject = -1,
eRegularDOMObject = DOM_OBJECT_SLOT,
eProxyDOMObject = DOM_PROXY_OBJECT_SLOT
};
template <class T>
inline T*
UnwrapDOMObject(JSObject* obj)
UnwrapDOMObject(JSObject* obj, DOMObjectSlot slot)
{
MOZ_ASSERT(IsDOMClass(JS_GetClass(obj)));
MOZ_ASSERT(slot != eNonDOMObject,
"Don't pass non-DOM objects to this function");
JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);
#ifdef DEBUG
if (IsDOMClass(js::GetObjectClass(obj))) {
MOZ_ASSERT(slot == eRegularDOMObject);
} else {
MOZ_ASSERT(js::IsObjectProxyClass(js::GetObjectClass(obj)) ||
js::IsFunctionProxyClass(js::GetObjectClass(obj)));
MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
MOZ_ASSERT(slot == eProxyDOMObject);
}
#endif
JS::Value val = js::GetReservedSlot(obj, slot);
// XXXbz/khuey worker code tries to unwrap interface objects (which have
// nothing here). That needs to stop.
// XXX We don't null-check UnwrapObject's result; aren't we going to crash
@ -96,6 +118,62 @@ UnwrapDOMObject(JSObject* obj)
return static_cast<T*>(val.toPrivate());
}
// Only use this with a new DOM binding object (either proxy or regular).
inline const DOMClass*
GetDOMClass(JSObject* obj)
{
js::Class* clasp = js::GetObjectClass(obj);
if (IsDOMClass(clasp)) {
return &DOMJSClass::FromJSClass(clasp)->mClass;
}
js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
MOZ_ASSERT(handler->family() == ProxyFamily());
return &static_cast<DOMProxyHandler*>(handler)->mClass;
}
inline DOMObjectSlot
GetDOMClass(JSObject* obj, const DOMClass*& result)
{
js::Class* clasp = js::GetObjectClass(obj);
if (IsDOMClass(clasp)) {
result = &DOMJSClass::FromJSClass(clasp)->mClass;
return eRegularDOMObject;
}
if (js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) {
js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
if (handler->family() == ProxyFamily()) {
result = &static_cast<DOMProxyHandler*>(handler)->mClass;
return eProxyDOMObject;
}
}
return eNonDOMObject;
}
inline bool
UnwrapDOMObjectToISupports(JSObject* obj, nsISupports*& result)
{
const DOMClass* clasp;
DOMObjectSlot slot = GetDOMClass(obj, clasp);
if (slot == eNonDOMObject || !clasp->mDOMObjectIsISupports) {
return false;
}
result = UnwrapDOMObject<nsISupports>(obj, slot);
return true;
}
inline bool
IsDOMObject(JSObject* obj)
{
js::Class* clasp = js::GetObjectClass(obj);
return IsDOMClass(clasp) ||
((js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) &&
js::GetProxyHandler(obj)->family() == ProxyFamily());
}
// Some callers don't want to set an exception when unwrappin fails
// (for example, overload resolution uses unwrapping to tell what sort
// of thing it's looking at).
@ -105,8 +183,9 @@ inline nsresult
UnwrapObject(JSContext* cx, JSObject* obj, U& value)
{
/* First check to see whether we have a DOM object */
JSClass* clasp = js::GetObjectJSClass(obj);
if (!IsDOMClass(clasp)) {
const DOMClass* domClass;
DOMObjectSlot slot = GetDOMClass(obj, domClass);
if (slot == eNonDOMObject) {
/* Maybe we have a security wrapper or outer window? */
if (!js::IsWrapper(obj)) {
/* Not a DOM object, not a wrapper, just bail */
@ -118,22 +197,19 @@ UnwrapObject(JSContext* cx, JSObject* obj, U& value)
return NS_ERROR_XPC_SECURITY_MANAGER_VETO;
}
MOZ_ASSERT(!js::IsWrapper(obj));
clasp = js::GetObjectJSClass(obj);
if (!IsDOMClass(clasp)) {
slot = GetDOMClass(obj, domClass);
if (slot == eNonDOMObject) {
/* We don't have a DOM object */
return NS_ERROR_XPC_BAD_CONVERT_JS;
}
}
MOZ_ASSERT(IsDOMClass(clasp));
/* This object is a DOM object. Double-check that it is safely
castable to T by checking whether it claims to inherit from the
class identified by protoID. */
DOMJSClass* domClass = DOMJSClass::FromJSClass(clasp);
if (domClass->mInterfaceChain[PrototypeTraits<PrototypeID>::Depth] ==
PrototypeID) {
value = UnwrapDOMObject<T>(obj);
value = UnwrapDOMObject<T>(obj, slot);
return NS_OK;
}
@ -309,7 +385,7 @@ JSObject*
CreateInterfaceObjects(JSContext* cx, JSObject* global, JSObject* receiver,
JSObject* protoProto, JSClass* protoClass,
JSClass* constructorClass, JSNative constructor,
unsigned ctorNargs, JSClass* instanceClass,
unsigned ctorNargs, const DOMClass* domClass,
Prefable<JSFunctionSpec>* methods,
Prefable<JSPropertySpec>* properties,
Prefable<ConstantSpec>* constants,
@ -555,6 +631,22 @@ GetParentPointer(const ParentObject& aObject)
return ToSupports(aObject.mObject);
}
template<class T>
inline void
ClearWrapper(T* p, nsWrapperCache* cache)
{
cache->ClearWrapper();
}
template<class T>
inline void
ClearWrapper(T* p, void*)
{
nsWrapperCache* cache;
CallQueryInterface(p, &cache);
ClearWrapper(p, cache);
}
// Can only be called with the immediate prototype of the instance object. Can
// only be called on the prototype of an object known to be a DOM instance.
JSBool
@ -700,6 +792,14 @@ QueryInterface(JSContext* cx, unsigned argc, JS::Value* vp);
JSBool
ThrowingConstructor(JSContext* cx, unsigned argc, JS::Value* vp);
bool
GetPropertyOnPrototype(JSContext* cx, JSObject* proxy, jsid id, bool* found,
JS::Value* vp);
bool
HasPropertyOnPrototype(JSContext* cx, JSObject* proxy, DOMProxyHandler* handler,
jsid id);
template<class T>
class NonNull
{

View File

@ -301,6 +301,52 @@ DOMInterfaces = {
'register': False
},
'TestIndexedGetterInterface' : {
'nativeType': 'mozilla::dom::TestIndexedGetterInterface',
'headerFile': 'TestBindingHeader.h',
'register': False,
'infallible': [ 'length' ]
},
'TestNamedGetterInterface' : {
'nativeType': 'mozilla::dom::TestNamedGetterInterface',
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestIndexedAndNamedGetterInterface' : {
'nativeType': 'mozilla::dom::TestIndexedAndNamedGetterInterface',
'headerFile': 'TestBindingHeader.h',
'register': False,
'infallible': [ 'length' ]
},
'TestIndexedSetterInterface' : {
'nativeType': 'mozilla::dom::TestIndexedSetterInterface',
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestNamedSetterInterface' : {
'nativeType': 'mozilla::dom::TestNamedSetterInterface',
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestIndexedAndNamedSetterInterface' : {
'nativeType': 'mozilla::dom::TestIndexedAndNamedSetterInterface',
'headerFile': 'TestBindingHeader.h',
'register': False
},
'TestIndexedAndNamedGetterAndSetterInterface' : {
'nativeType': 'mozilla::dom::TestIndexedAndNamedGetterAndSetterInterface',
'headerFile': 'TestBindingHeader.h',
'register': False,
'infallible': [ 'length', '__stringifier' ],
'binaryNames': { '__stringifier': 'Stringify' }
},
}
# These are temporary, until they've been converted to use new DOM bindings

File diff suppressed because it is too large Load Diff

View File

@ -147,13 +147,63 @@ class Descriptor(DescriptorProvider):
# If we're concrete, we need to crawl our ancestor interfaces and mark
# them as having a concrete descendant.
self.concrete = desc.get('concrete', True)
self.concrete = desc.get('concrete', not self.interface.isExternal())
if self.concrete:
self.proxy = False
operations = {
'IndexedGetter': None,
'IndexedSetter': None,
'IndexedCreator': None,
'IndexedDeleter': None,
'NamedGetter': None,
'NamedSetter': None,
'NamedCreator': None,
'NamedDeleter': None,
'Stringifier': None
}
iface = self.interface
while iface:
for m in iface.members:
if not m.isMethod():
continue
def addOperation(operation, m):
if not operations[operation]:
operations[operation] = m
def addIndexedOrNamedOperation(operation, m):
self.proxy = True
if m.isIndexed():
operation = 'Indexed' + operation
else:
assert m.isNamed()
operation = 'Named' + operation
addOperation(operation, m)
if m.isStringifier():
addOperation('Stringifier', m)
else:
if m.isGetter():
addIndexedOrNamedOperation('Getter', m)
if m.isSetter():
addIndexedOrNamedOperation('Setter', m)
if m.isCreator():
addIndexedOrNamedOperation('Creator', m)
if m.isDeleter():
addIndexedOrNamedOperation('Deleter', m)
raise TypeError("deleter specified on %s but we "
"don't support deleters yet" %
self.interface.identifier.name)
iface.setUserData('hasConcreteDescendant', True)
iface = iface.parent
if self.proxy:
self.operations = operations
iface = self.interface
while iface:
iface.setUserData('hasProxyDescendant', True)
iface = iface.parent
if self.interface.isExternal() and 'prefable' in desc:
raise TypeError("%s is external but has a prefable setting" %
self.interface.identifier.name)
@ -188,8 +238,14 @@ class Descriptor(DescriptorProvider):
elif isinstance(config, list):
add('all', config, attribute)
else:
assert isinstance(config, string)
add('all', [config], attribute)
assert isinstance(config, str)
if config == '*':
iface = self.interface
while iface:
add('all', map(lambda m: m.name, iface.members), attribute)
iface = iface.parent
else:
add('all', [config], attribute)
for attribute in ['infallible', 'implicitJSContext', 'resultNotAddRefed']:
addExtendedAttribute(attribute, desc.get(attribute, {}))

View File

@ -45,6 +45,21 @@ struct NativePropertyHooks
const NativePropertyHooks *mProtoHooks;
};
struct DOMClass
{
// A list of interfaces that this object implements, in order of decreasing
// derivedness.
const prototypes::ID mInterfaceChain[prototypes::id::_ID_Count];
// We store the DOM object in reserved slot with index DOM_OBJECT_SLOT or in
// the proxy private if we use a proxy object.
// Sometimes it's an nsISupports and sometimes it's not; this class tells
// us which it is.
const bool mDOMObjectIsISupports;
const NativePropertyHooks* mNativeHooks;
};
// Special JSClass for reflected DOM objects.
struct DOMJSClass
{
@ -53,9 +68,7 @@ struct DOMJSClass
// only allows brace initialization for aggregate/POD types.
JSClass mBase;
// A list of interfaces that this object implements, in order of decreasing
// derivedness.
const prototypes::ID mInterfaceChain[prototypes::id::_ID_Count];
DOMClass mClass;
// We cache the VTable index of GetWrapperCache for objects that support it.
//
@ -63,13 +76,6 @@ struct DOMJSClass
// XXXkhuey this is unused and needs to die.
const int16_t mGetWrapperCacheVTableOffset;
// We store the DOM object in a reserved slot whose index is mNativeSlot.
// Sometimes it's an nsISupports and sometimes it's not; this class tells
// us which it is.
const bool mDOMObjectIsISupports;
const NativePropertyHooks* mNativeHooks;
static DOMJSClass* FromJSClass(JSClass* base) {
MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
return reinterpret_cast<DOMJSClass*>(base);

View File

@ -0,0 +1,228 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=2 sw=2 et tw=99 ft=cpp: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Util.h"
#include "DOMJSProxyHandler.h"
#include "xpcpublic.h"
#include "xpcprivate.h"
#include "XPCQuickStubs.h"
#include "XPCWrapper.h"
#include "WrapperFactory.h"
#include "nsDOMClassInfo.h"
#include "nsGlobalWindow.h"
#include "nsWrapperCacheInlines.h"
#include "mozilla/dom/BindingUtils.h"
#include "jsapi.h"
#include "jsatom.h"
using namespace JS;
namespace mozilla {
namespace dom {
jsid s_length_id = JSID_VOID;
bool
DefineStaticJSVals(JSContext* cx)
{
JSAutoRequest ar(cx);
return InternJSString(cx, s_length_id, "length");
}
int HandlerFamily;
bool
DefineConstructor(JSContext* cx, JSObject* obj, DefineInterface aDefine, nsresult* aResult)
{
bool enabled;
bool defined = aDefine(cx, obj, &enabled);
MOZ_ASSERT(!defined || enabled,
"We defined a constructor but the new bindings are disabled?");
*aResult = defined ? NS_OK : NS_ERROR_FAILURE;
return enabled;
}
// static
JSObject*
DOMProxyHandler::EnsureExpandoObject(JSContext* cx, JSObject* obj)
{
NS_ASSERTION(IsDOMProxy(obj), "expected a DOM proxy object");
JSObject* expando = GetExpandoObject(obj);
if (!expando) {
expando = JS_NewObjectWithGivenProto(cx, nullptr, nullptr,
js::GetObjectParent(obj));
if (!expando) {
return NULL;
}
xpc::CompartmentPrivate* priv = xpc::GetCompartmentPrivate(obj);
if (!priv->RegisterDOMExpandoObject(obj)) {
return NULL;
}
nsWrapperCache* cache;
CallQueryInterface(UnwrapDOMObject<nsISupports>(obj, eProxyDOMObject), &cache);
cache->SetPreservingWrapper(true);
js::SetProxyExtra(obj, JSPROXYSLOT_EXPANDO, ObjectValue(*expando));
}
return expando;
}
bool
DOMProxyHandler::getPropertyDescriptor(JSContext* cx, JSObject* proxy, jsid id, bool set,
JSPropertyDescriptor* desc)
{
if (!getOwnPropertyDescriptor(cx, proxy, id, set, desc)) {
return false;
}
if (desc->obj) {
return true;
}
JSObject* proto = js::GetObjectProto(proxy);
if (!proto) {
desc->obj = NULL;
return true;
}
return JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, desc);
}
bool
DOMProxyHandler::defineProperty(JSContext* cx, JSObject* proxy, jsid id,
JSPropertyDescriptor* desc)
{
if ((desc->attrs & JSPROP_GETTER) && desc->setter == JS_StrictPropertyStub) {
return JS_ReportErrorFlagsAndNumber(cx,
JSREPORT_WARNING | JSREPORT_STRICT |
JSREPORT_STRICT_MODE_ERROR,
js_GetErrorMessage, NULL,
JSMSG_GETTER_ONLY);
}
if (xpc::WrapperFactory::IsXrayWrapper(proxy)) {
return true;
}
JSObject* expando = EnsureExpandoObject(cx, proxy);
if (!expando) {
return false;
}
return JS_DefinePropertyById(cx, expando, id, desc->value, desc->getter, desc->setter,
desc->attrs);
}
bool
DOMProxyHandler::delete_(JSContext* cx, JSObject* proxy, jsid id, bool* bp)
{
JSBool b = true;
JSObject* expando;
if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
Value v;
if (!JS_DeletePropertyById2(cx, expando, id, &v) || !JS_ValueToBoolean(cx, v, &b)) {
return false;
}
}
*bp = !!b;
return true;
}
bool
DOMProxyHandler::enumerate(JSContext* cx, JSObject* proxy, AutoIdVector& props)
{
JSObject* proto = JS_GetPrototype(proxy);
return getOwnPropertyNames(cx, proxy, props) &&
(!proto || js::GetPropertyNames(cx, proto, 0, &props));
}
bool
DOMProxyHandler::fix(JSContext* cx, JSObject* proxy, Value* vp)
{
vp->setUndefined();
return true;
}
bool
DOMProxyHandler::has(JSContext* cx, JSObject* proxy, jsid id, bool* bp)
{
if (!hasOwn(cx, proxy, id, bp)) {
return false;
}
if (*bp) {
// We have the property ourselves; no need to worry about our prototype
// chain.
return true;
}
// OK, now we have to look at the proto
JSObject *proto = js::GetObjectProto(proxy);
if (!proto) {
return true;
}
JSBool protoHasProp;
bool ok = JS_HasPropertyById(cx, proto, id, &protoHasProp);
if (ok) {
*bp = protoHasProp;
}
return ok;
}
// static
JSString*
DOMProxyHandler::obj_toString(JSContext* cx, const char* className)
{
size_t nchars = sizeof("[object ]") - 1 + strlen(className);
jschar* chars = static_cast<jschar*>(JS_malloc(cx, (nchars + 1) * sizeof(jschar)));
if (!chars) {
return NULL;
}
const char* prefix = "[object ";
nchars = 0;
while ((chars[nchars] = (jschar)*prefix) != 0) {
nchars++, prefix++;
}
while ((chars[nchars] = (jschar)*className) != 0) {
nchars++, className++;
}
chars[nchars++] = ']';
chars[nchars] = 0;
JSString* str = JS_NewUCString(cx, chars, nchars);
if (!str) {
JS_free(cx, chars);
}
return str;
}
int32_t
IdToInt32(JSContext* cx, jsid id)
{
JSAutoRequest ar(cx);
jsval idval;
double array_index;
int32_t i;
if (!::JS_IdToValue(cx, id, &idval) ||
!::JS_ValueToNumber(cx, idval, &array_index) ||
!::JS_DoubleIsInt32(array_index, &i)) {
return -1;
}
return i;
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,109 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_DOMJSProxyHandler_h
#define mozilla_dom_DOMJSProxyHandler_h
#include "jsapi.h"
#include "jsatom.h"
#include "jsproxy.h"
#include "xpcpublic.h"
#include "nsString.h"
#include "mozilla/Likely.h"
#define DOM_PROXY_OBJECT_SLOT js::JSSLOT_PROXY_PRIVATE
namespace mozilla {
namespace dom {
enum {
JSPROXYSLOT_EXPANDO = 0
};
template<typename T> struct Prefable;
class DOMProxyHandler : public js::BaseProxyHandler
{
public:
DOMProxyHandler(const DOMClass& aClass)
: js::BaseProxyHandler(ProxyFamily()),
mClass(aClass)
{
}
bool getPropertyDescriptor(JSContext* cx, JSObject* proxy, jsid id, bool set,
JSPropertyDescriptor* desc);
bool defineProperty(JSContext* cx, JSObject* proxy, jsid id,
JSPropertyDescriptor* desc);
bool delete_(JSContext* cx, JSObject* proxy, jsid id, bool* bp);
bool enumerate(JSContext* cx, JSObject* proxy, JS::AutoIdVector& props);
bool fix(JSContext* cx, JSObject* proxy, JS::Value* vp);
bool has(JSContext* cx, JSObject* proxy, jsid id, bool* bp);
using js::BaseProxyHandler::obj_toString;
static JSObject* GetExpandoObject(JSObject* obj)
{
MOZ_ASSERT(IsDOMProxy(obj), "expected a DOM proxy object");
JS::Value v = js::GetProxyExtra(obj, JSPROXYSLOT_EXPANDO);
return v.isUndefined() ? NULL : v.toObjectOrNull();
}
static JSObject* EnsureExpandoObject(JSContext* cx, JSObject* obj);
const DOMClass& mClass;
protected:
static JSString* obj_toString(JSContext* cx, const char* className);
};
extern jsid s_length_id;
int32_t IdToInt32(JSContext* cx, jsid id);
inline int32_t
GetArrayIndexFromId(JSContext* cx, jsid id)
{
if (MOZ_LIKELY(JSID_IS_INT(id))) {
return JSID_TO_INT(id);
}
if (MOZ_LIKELY(id == s_length_id)) {
return -1;
}
if (MOZ_LIKELY(JSID_IS_ATOM(id))) {
JSAtom* atom = JSID_TO_ATOM(id);
jschar s = *js::GetAtomChars(atom);
if (MOZ_LIKELY((unsigned)s >= 'a' && (unsigned)s <= 'z'))
return -1;
uint32_t i;
JSLinearString* str = js::AtomToLinearString(JSID_TO_ATOM(id));
return js::StringIsArrayIndex(str, &i) ? i : -1;
}
return IdToInt32(cx, id);
}
inline void
FillPropertyDescriptor(JSPropertyDescriptor* desc, JSObject* obj, bool readonly)
{
desc->obj = obj;
desc->attrs = (readonly ? JSPROP_READONLY : 0) | JSPROP_ENUMERATE;
desc->getter = NULL;
desc->setter = NULL;
desc->shortid = 0;
}
inline void
FillPropertyDescriptor(JSPropertyDescriptor* desc, JSObject* obj, jsval v, bool readonly)
{
desc->value = v;
FillPropertyDescriptor(desc, obj, readonly);
}
JSObject*
EnsureExpandoObject(JSContext* cx, JSObject* obj);
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_DOMProxyHandler_h */

View File

@ -25,3 +25,4 @@ MSG_DEF(MSG_NOT_OBJECT, 0, "Value not an object.")
MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 1, "Value does not implement interface {0}.")
MSG_DEF(MSG_NOT_IN_UNION, 1, "Value could not be converted to any of: {0}.")
MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, "Illegal constructor.")
MSG_DEF(MSG_NO_PROPERTY_SETTER, 1, "{0} doesn't have an indexed property setter.")

View File

@ -45,6 +45,7 @@ CPPSRCS = \
$(linked_binding_cpp_files) \
$(filter %.cpp, $(globalgen_targets)) \
BindingUtils.cpp \
DOMJSProxyHandler.cpp \
$(NULL)
EXPORTS_NAMESPACES = $(binding_include_path) mozilla
@ -56,6 +57,7 @@ EXPORTS_mozilla = \
EXPORTS_$(binding_include_path) = \
BindingUtils.h \
DOMJSClass.h \
DOMJSProxyHandler.h \
Errors.msg \
Nullable.h \
PrimitiveConversions.h \

View File

@ -2133,6 +2133,9 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def hasOverloads(self):
return self._hasOverloads
def isIdentifierLess(self):
return self.identifier.name[:2] == "__"
def resolve(self, parentScope):
assert isinstance(parentScope, IDLScope)
IDLObjectWithIdentifier.resolve(self, parentScope)

View File

@ -558,6 +558,102 @@ private:
};
class TestIndexedGetterInterface : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_ISUPPORTS
// We need a GetParentObject to make binding codegen happy
virtual nsISupports* GetParentObject();
uint32_t IndexedGetter(uint32_t, bool&, ErrorResult&);
uint32_t IndexedGetter(uint32_t, ErrorResult&) MOZ_DELETE;
uint32_t Item(uint32_t, ErrorResult&);
uint32_t Item(uint32_t, bool&, ErrorResult&) MOZ_DELETE;
uint32_t GetLength();
};
class TestNamedGetterInterface : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_ISUPPORTS
// We need a GetParentObject to make binding codegen happy
virtual nsISupports* GetParentObject();
void NamedGetter(const nsAString&, bool&, nsAString&, ErrorResult&);
};
class TestIndexedAndNamedGetterInterface : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_ISUPPORTS
// We need a GetParentObject to make binding codegen happy
virtual nsISupports* GetParentObject();
uint32_t IndexedGetter(uint32_t, bool&, ErrorResult&);
void NamedGetter(const nsAString&, bool&, nsAString&, ErrorResult&);
void NamedItem(const nsAString&, nsAString&, ErrorResult&);
uint32_t GetLength();
};
class TestIndexedSetterInterface : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_ISUPPORTS
// We need a GetParentObject to make binding codegen happy
virtual nsISupports* GetParentObject();
void IndexedSetter(uint32_t, const nsAString&, ErrorResult&);
void SetItem(uint32_t, const nsAString&, ErrorResult&);
};
class TestNamedSetterInterface : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_ISUPPORTS
// We need a GetParentObject to make binding codegen happy
virtual nsISupports* GetParentObject();
void NamedSetter(const nsAString&, TestIndexedSetterInterface&, ErrorResult&);
};
class TestIndexedAndNamedSetterInterface : public nsISupports,
public nsWrapperCache
{
public:
NS_DECL_ISUPPORTS
// We need a GetParentObject to make binding codegen happy
virtual nsISupports* GetParentObject();
void IndexedSetter(uint32_t, TestIndexedSetterInterface&, ErrorResult&);
void NamedSetter(const nsAString&, TestIndexedSetterInterface&, ErrorResult&);
void SetNamedItem(const nsAString&, TestIndexedSetterInterface&, ErrorResult&);
};
class TestIndexedAndNamedGetterAndSetterInterface : public TestIndexedSetterInterface
{
public:
uint32_t IndexedGetter(uint32_t, bool&, ErrorResult&);
uint32_t Item(uint32_t, ErrorResult&);
void NamedGetter(const nsAString&, bool&, nsAString&, ErrorResult&);
void NamedItem(const nsAString&, nsAString&, ErrorResult&);
void IndexedSetter(uint32_t, int32_t&, ErrorResult&);
void IndexedSetter(uint32_t, const nsAString&, ErrorResult&) MOZ_DELETE;
void NamedSetter(const nsAString&, const nsAString&, ErrorResult&);
void Stringify(nsAString&);
uint32_t GetLength();
};
} // namespace dom
} // namespace mozilla

View File

@ -372,3 +372,40 @@ dictionary ParentDict : GrandparentDict {
dictionary DictContainingDict {
Dict memberDict;
};
interface TestIndexedGetterInterface {
getter long item(unsigned long index);
readonly attribute unsigned long length;
};
interface TestNamedGetterInterface {
getter DOMString (DOMString name);
};
interface TestIndexedAndNamedGetterInterface {
getter long (unsigned long index);
getter DOMString namedItem(DOMString name);
readonly attribute unsigned long length;
};
interface TestIndexedSetterInterface {
setter creator void setItem(unsigned long index, DOMString item);
};
interface TestNamedSetterInterface {
setter creator void (DOMString name, TestIndexedSetterInterface item);
};
interface TestIndexedAndNamedSetterInterface {
setter creator void (unsigned long index, TestIndexedSetterInterface item);
setter creator void setNamedItem(DOMString name, TestIndexedSetterInterface item);
};
interface TestIndexedAndNamedGetterAndSetterInterface : TestIndexedSetterInterface {
getter long item(unsigned long index);
getter DOMString namedItem(DOMString name);
setter creator void (unsigned long index, long item);
setter creator void (DOMString name, DOMString item);
stringifier DOMString ();
readonly attribute unsigned long length;
};

View File

@ -233,7 +233,8 @@ private:
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == Class());
WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
WorkerPrivate* worker =
UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
if (worker) {
worker->_finalize(aFop);
}
@ -243,7 +244,8 @@ private:
Trace(JSTracer* aTrc, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == Class());
WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
WorkerPrivate* worker =
UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
if (worker) {
worker->_trace(aTrc);
}
@ -303,9 +305,13 @@ DOMJSClass Worker::sClass = {
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,
NULL, NULL, NULL, NULL, Trace
},
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count },
-1, false, &sNativePropertyHooks
{
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count },
false,
&sNativePropertyHooks
},
-1
};
JSPropertySpec Worker::sProperties[] = {
@ -376,7 +382,7 @@ private:
if (aObj) {
JSClass* classPtr = JS_GetClass(aObj);
if (classPtr == Class()) {
return UnwrapDOMObject<WorkerPrivate>(aObj);
return UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
}
}
@ -393,7 +399,8 @@ private:
Finalize(JSFreeOp* aFop, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == Class());
WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
WorkerPrivate* worker =
UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
if (worker) {
worker->_finalize(aFop);
}
@ -403,7 +410,8 @@ private:
Trace(JSTracer* aTrc, JSObject* aObj)
{
JS_ASSERT(JS_GetClass(aObj) == Class());
WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
WorkerPrivate* worker =
UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
if (worker) {
worker->_trace(aTrc);
}
@ -423,9 +431,13 @@ DOMJSClass ChromeWorker::sClass = {
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,
NULL, NULL, NULL, NULL, Trace,
},
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count },
-1, false, &sNativePropertyHooks
{
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count },
false,
&sNativePropertyHooks
},
-1
};
WorkerPrivate*
@ -434,7 +446,7 @@ Worker::GetInstancePrivate(JSContext* aCx, JSObject* aObj,
{
JSClass* classPtr = JS_GetClass(aObj);
if (classPtr == Class() || classPtr == ChromeWorker::Class()) {
return UnwrapDOMObject<WorkerPrivate>(aObj);
return UnwrapDOMObject<WorkerPrivate>(aObj, eRegularDOMObject);
}
JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,

View File

@ -768,7 +768,8 @@ private:
{
JSClass* classPtr = JS_GetClass(aObj);
if (classPtr == Class()) {
return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj,
eRegularDOMObject);
}
JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
@ -803,7 +804,7 @@ private:
{
JS_ASSERT(JS_GetClass(aObj) == Class());
DedicatedWorkerGlobalScope* scope =
UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj, eRegularDOMObject);
if (scope) {
DestroyProtoOrIfaceCache(aObj);
scope->_finalize(aFop);
@ -815,7 +816,7 @@ private:
{
JS_ASSERT(JS_GetClass(aObj) == Class());
DedicatedWorkerGlobalScope* scope =
UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj, eRegularDOMObject);
if (scope) {
mozilla::dom::TraceProtoOrIfaceCache(aTrc, aObj);
scope->_trace(aTrc);
@ -859,9 +860,13 @@ DOMJSClass DedicatedWorkerGlobalScope::sClass = {
JS_EnumerateStub, reinterpret_cast<JSResolveOp>(Resolve), JS_ConvertStub,
Finalize, NULL, NULL, NULL, NULL, Trace
},
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count },
-1, false, &sNativePropertyHooks
{
{ prototypes::id::EventTarget_workers, prototypes::id::_ID_Count,
prototypes::id::_ID_Count },
false,
&sNativePropertyHooks
},
-1
};
JSPropertySpec DedicatedWorkerGlobalScope::sProperties[] = {
@ -890,7 +895,7 @@ WorkerGlobalScope::GetInstancePrivate(JSContext* aCx, JSObject* aObj,
JS_ASSERT(classPtr != Class());
if (classPtr == DedicatedWorkerGlobalScope::Class()) {
return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj, eRegularDOMObject);
}
JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,

View File

@ -75,12 +75,7 @@ XPCConvert::GetISupportsFromJSObject(JSObject* obj, nsISupports** iface)
*iface = (nsISupports*) xpc_GetJSPrivate(obj);
return true;
}
if (jsclass && IsDOMClass(jsclass) &&
DOMJSClass::FromJSClass(jsclass)->mDOMObjectIsISupports) {
*iface = UnwrapDOMObject<nsISupports>(obj);
return true;
}
return false;
return UnwrapDOMObjectToISupports(obj, *iface);
}
/***************************************************************************/

View File

@ -482,15 +482,10 @@ nsJSIID::HasInstance(nsIXPConnectWrappedNative *wrapper,
}
nsISupports *identity;
if (mozilla::dom::binding::instanceIsProxy(obj)) {
if (mozilla::dom::oldproxybindings::instanceIsProxy(obj)) {
identity =
static_cast<nsISupports*>(js::GetProxyPrivate(obj).toPrivate());
} else if (mozilla::dom::IsDOMClass(js::GetObjectJSClass(obj)) &&
mozilla::dom::DOMJSClass::FromJSClass(
js::GetObjectJSClass(obj))->mDOMObjectIsISupports) {
identity =
mozilla::dom::UnwrapDOMObject<nsISupports>(obj);
} else {
} else if (!mozilla::dom::UnwrapDOMObjectToISupports(obj, identity)) {
identity = nullptr;
}

View File

@ -447,15 +447,14 @@ SuspectDOMExpandos(nsPtrHashKey<JSObject> *key, void *arg)
Closure *closure = static_cast<Closure*>(arg);
JSObject* obj = key->GetKey();
nsISupports* native = nullptr;
if (js::IsProxy(obj)) {
NS_ASSERTION(dom::binding::instanceIsProxy(obj),
"Not a DOM proxy?");
if (dom::oldproxybindings::instanceIsProxy(obj)) {
native = static_cast<nsISupports*>(js::GetProxyPrivate(obj).toPrivate());
}
else {
NS_ASSERTION(dom::DOMJSClass::FromJSClass(JS_GetClass(obj))->mDOMObjectIsISupports,
"Someone added a wrapper for a non-nsISupports native to DOMExpandos!");
native = dom::UnwrapDOMObject<nsISupports>(obj);
const dom::DOMClass* clasp;
dom::DOMObjectSlot slot = GetDOMClass(obj, clasp);
MOZ_ASSERT(slot != dom::eNonDOMObject && clasp->mDOMObjectIsISupports);
native = dom::UnwrapDOMObject<nsISupports>(obj, slot);
}
closure->cb->NoteXPCOMRoot(native);
return PL_DHASH_NEXT;
@ -2294,7 +2293,8 @@ XPCJSRuntime::OnJSContextNew(JSContext *cx)
}
}
ok = mozilla::dom::binding::DefineStaticJSVals(cx);
ok = mozilla::dom::DefineStaticJSVals(cx) &&
mozilla::dom::oldproxybindings::DefineStaticJSVals(cx);
if (!ok)
return false;

View File

@ -697,9 +697,7 @@ getWrapper(JSContext *cx,
*cur = nullptr;
*tearoff = nullptr;
js::Class* clasp = js::GetObjectClass(obj);
if (dom::IsDOMClass(clasp) ||
dom::binding::instanceIsProxy(obj)) {
if (dom::IsDOMObject(obj)) {
*cur = obj;
return NS_OK;
@ -711,6 +709,7 @@ getWrapper(JSContext *cx,
// object reflection of a particular interface (ie, |foo.nsIBar|). These
// JS objects are parented to their wrapper, so we snag the tearoff object
// along the way (if desired), and then set |obj| to its parent.
js::Class* clasp = js::GetObjectClass(obj);
if (clasp == &XPC_WN_Tearoff_JSClass) {
*tearoff = (XPCWrappedNativeTearOff*) js::GetObjectPrivate(obj);
obj = js::GetObjectParent(obj);
@ -751,23 +750,14 @@ castNative(JSContext *cx,
} else if (cur) {
nsISupports *native;
QITableEntry *entries;
js::Class* clasp = js::GetObjectClass(cur);
if (dom::IsDOMClass(clasp)) {
dom::DOMJSClass* domClass = dom::DOMJSClass::FromJSClass(clasp);
if (!domClass->mDOMObjectIsISupports) {
*pThisRef = nullptr;
return NS_ERROR_ILLEGAL_VALUE;
}
native = dom::UnwrapDOMObject<nsISupports>(cur);
if (mozilla::dom::UnwrapDOMObjectToISupports(cur, native)) {
entries = nullptr;
} else if (dom::binding::instanceIsProxy(cur)) {
native = static_cast<nsISupports*>(js::GetProxyPrivate(cur).toPrivate());
entries = nullptr;
} else if (IS_WRAPPER_CLASS(clasp) && IS_SLIM_WRAPPER_OBJECT(cur)) {
} else if (IS_SLIM_WRAPPER(cur)) {
native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
entries = GetOffsetsFromSlimWrapper(cur);
} else {
MOZ_NOT_REACHED("what kind of wrapper is this?");
*pThisRef = nullptr;
return NS_ERROR_ILLEGAL_VALUE;
}
if (NS_SUCCEEDED(getNative(native, entries, cur, iid, ppThis, pThisRef, vp))) {

View File

@ -31,10 +31,9 @@ bool
xpc_OkToHandOutWrapper(nsWrapperCache *cache)
{
NS_ABORT_IF_FALSE(cache->GetWrapper(), "Must have wrapper");
NS_ABORT_IF_FALSE(cache->IsDOMBinding() || IS_WN_WRAPPER(cache->GetWrapper()),
"Must have proxy or XPCWrappedNative wrapper");
return cache->IsDOMBinding() ?
mozilla::dom::binding::instanceIsProxy(cache->GetWrapper()) :
NS_ABORT_IF_FALSE(IS_WN_WRAPPER(cache->GetWrapper()),
"Must have XPCWrappedNative wrapper");
return
!static_cast<XPCWrappedNative*>(xpc_GetJSPrivate(cache->GetWrapper()))->
NeedsSOW();
}

View File

@ -217,23 +217,20 @@ XPCWrappedNativeScope::SetGlobal(XPCCallContext& ccx, JSObject* aGlobal,
native = aNative;
} else {
const JSClass *jsClass = js::GetObjectJSClass(aGlobal);
nsISupports *priv;
if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
// Our global has an nsISupports native pointer. Let's
// see whether it's what we want.
priv = static_cast<nsISupports*>(xpc_GetJSPrivate(aGlobal));
} else if (dom::IsDOMClass(jsClass) &&
dom::DOMJSClass::FromJSClass(jsClass)->mDOMObjectIsISupports) {
priv = dom::UnwrapDOMObject<nsISupports>(aGlobal);
} else {
priv = nullptr;
nsISupports *priv =
static_cast<nsISupports*>(xpc_GetJSPrivate(aGlobal));
nsCOMPtr<nsIXPConnectWrappedNative> wn = do_QueryInterface(priv);
if (wn)
native = static_cast<XPCWrappedNative*>(wn.get())->GetIdentityObject();
else
native = nullptr;
} else if (!mozilla::dom::UnwrapDOMObjectToISupports(aGlobal, native)) {
native = nullptr;
}
nsCOMPtr<nsIXPConnectWrappedNative> wn = do_QueryInterface(priv);
if (wn)
native = static_cast<XPCWrappedNative*>(wn.get())->GetIdentityObject();
else
native = priv;
}
// Now init our script object principal, if the new global has one.

View File

@ -293,6 +293,8 @@ def outParamForm(name, type):
if type.specialtype == 'jsval':
return 'vp'
elif type.modifier == 'ref':
if isStringType(type):
return '(nsAString&)' + name
return name
else:
return '&' + name

View File

@ -26,7 +26,7 @@ using namespace mozilla::dom;
namespace mozilla {
namespace dom {
namespace binding {
namespace oldproxybindings {
enum {
JSPROXYSLOT_EXPANDO = 0

View File

@ -15,7 +15,7 @@
namespace mozilla {
namespace dom {
namespace binding {
namespace oldproxybindings {
class ProxyHandler : public js::BaseProxyHandler {
protected:

View File

@ -375,7 +375,7 @@ def writeHeaderFile(filename, config):
f.write("namespace mozilla {\n"
"namespace dom {\n"
"namespace binding {\n\n")
"namespace oldproxybindings {\n\n")
f.write("bool\n"
"DefinePropertyStaticJSVals(JSContext *cx);\n\n")
@ -638,7 +638,7 @@ def writeStubFile(filename, config, interfaces):
f.write("namespace mozilla {\n"
"namespace dom {\n"
"namespace binding {\n\n")
"namespace oldproxybindings {\n\n")
f.write("// Property name ids\n\n")
@ -712,7 +712,7 @@ def writeStubFile(filename, config, interfaces):
else:
setterName = "NULL"
propertiesList.append(" { s_length_id, length_getter, %s }" % setterName)
propertiesList.append(" { mozilla::dom::s_length_id, length_getter, %s }" % setterName)
continue
isAttr = (member.kind == 'attribute')

View File

@ -836,16 +836,17 @@ NoteGCThingXPCOMChildren(js::Class *clasp, JSObject *obj,
clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "xpc_GetJSPrivate(obj)");
cb.NoteXPCOMChild(static_cast<nsISupports*>(xpc_GetJSPrivate(obj)));
} else if (binding::instanceIsProxy(obj)) {
} else if (oldproxybindings::instanceIsProxy(obj)) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "js::GetProxyPrivate(obj)");
nsISupports *identity =
static_cast<nsISupports*>(js::GetProxyPrivate(obj).toPrivate());
cb.NoteXPCOMChild(identity);
} else if (IsDOMClass(clasp) &&
DOMJSClass::FromJSClass(clasp)->mDOMObjectIsISupports) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "UnwrapDOMObject(obj)");
nsISupports *identity = UnwrapDOMObject<nsISupports>(obj);
cb.NoteXPCOMChild(identity);
} else {
nsISupports *identity;
if (UnwrapDOMObjectToISupports(obj, identity)) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "UnwrapDOMObject(obj)");
cb.NoteXPCOMChild(identity);
}
}
}
@ -1419,7 +1420,8 @@ nsXPConnect::GetNativeOfWrapper(JSContext * aJSContext,
if (obj2)
return (nsISupports*)xpc_GetJSPrivate(obj2);
if (mozilla::dom::binding::instanceIsProxy(aJSObj)) {
if (mozilla::dom::IsDOMProxy(aJSObj) ||
mozilla::dom::oldproxybindings::instanceIsProxy(aJSObj)) {
// FIXME: Provide a fast non-refcounting way to get the canonical
// nsISupports from the proxy.
nsISupports *supports =
@ -1457,7 +1459,8 @@ nsXPConnect::GetJSObjectOfWrapper(JSContext * aJSContext,
*_retval = obj2;
return NS_OK;
}
if (mozilla::dom::binding::instanceIsProxy(aJSObj)) {
if (mozilla::dom::IsDOMProxy(aJSObj) ||
mozilla::dom::oldproxybindings::instanceIsProxy(aJSObj)) {
*_retval = aJSObj;
return NS_OK;
}

View File

@ -131,7 +131,7 @@ xpc_FastGetCachedWrapper(nsWrapperCache *cache, JSObject *scope, jsval *vp)
"Should never have a slim wrapper when IsDOMBinding()");
if (wrapper &&
js::GetObjectCompartment(wrapper) == js::GetObjectCompartment(scope) &&
(IS_SLIM_WRAPPER(wrapper) ||
(IS_SLIM_WRAPPER(wrapper) || cache->IsDOMBinding() ||
xpc_OkToHandOutWrapper(cache))) {
*vp = OBJECT_TO_JSVAL(wrapper);
return wrapper;
@ -306,11 +306,10 @@ xpc_JSCompartmentParticipant();
namespace mozilla {
namespace dom {
namespace binding {
extern int HandlerFamily;
inline void* ProxyFamily() { return &HandlerFamily; }
inline bool instanceIsProxy(JSObject *obj)
inline bool IsDOMProxy(JSObject *obj)
{
return js::IsProxy(obj) &&
js::GetProxyHandler(obj)->family() == ProxyFamily();
@ -327,7 +326,22 @@ extern bool
DefineConstructor(JSContext *cx, JSObject *obj, DefineInterface aDefine,
nsresult *aResult);
} // namespace binding
namespace oldproxybindings {
extern int HandlerFamily;
inline void* ProxyFamily() { return &HandlerFamily; }
inline bool instanceIsProxy(JSObject *obj)
{
return js::IsProxy(obj) &&
js::GetProxyHandler(obj)->family() == ProxyFamily();
}
extern bool
DefineStaticJSVals(JSContext *cx);
void
Register(nsScriptNameSpaceManager* aNameSpaceManager);
} // namespace oldproxybindings
} // namespace dom
} // namespace mozilla

View File

@ -299,7 +299,7 @@ GetXrayType(JSObject *obj)
if (mozilla::dom::IsDOMClass(Jsvalify(clasp))) {
return XrayForDOMObject;
}
if (mozilla::dom::binding::instanceIsProxy(obj)) {
if (mozilla::dom::oldproxybindings::instanceIsProxy(obj)) {
return XrayForDOMProxyObject;
}
if (IS_WRAPPER_CLASS(clasp) || clasp->ext.innerObject) {
@ -385,7 +385,7 @@ WrapperFactory::Rewrap(JSContext *cx, JSObject *obj, JSObject *wrappedProto, JSO
wrapper = &FilteringWrapper<Xray, LocationPolicy>::singleton;
else
wrapper = &FilteringWrapper<Xray, CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (mozilla::dom::binding::instanceIsProxy(obj)) {
} else if (mozilla::dom::oldproxybindings::instanceIsProxy(obj)) {
wrapper = &FilteringWrapper<XrayProxy, CrossOriginAccessiblePropertiesOnly>::singleton;
} else if (mozilla::dom::IsDOMClass(JS_GetClass(obj))) {
wrapper = &FilteringWrapper<XrayDOM, CrossOriginAccessiblePropertiesOnly>::singleton;

View File

@ -1057,7 +1057,7 @@ DOMXrayTraits::resolveNativeProperty(JSContext *cx, JSObject *wrapper, JSObject
{
JSObject *obj = getInnerObject(wrapper);
const NativePropertyHooks *nativeHooks =
DOMJSClass::FromJSClass(JS_GetClass(obj))->mNativeHooks;
DOMJSClass::FromJSClass(JS_GetClass(obj))->mClass.mNativeHooks;
do {
if (nativeHooks->mResolveProperty(cx, wrapper, id, set, desc) &&
@ -1108,7 +1108,7 @@ DOMXrayTraits::enumerateNames(JSContext *cx, JSObject *wrapper, unsigned flags,
JSObject *obj = getInnerObject(wrapper);
const NativePropertyHooks *nativeHooks =
DOMJSClass::FromJSClass(JS_GetClass(obj))->mNativeHooks;
DOMJSClass::FromJSClass(JS_GetClass(obj))->mClass.mNativeHooks;
do {
if (!nativeHooks->mEnumerateProperties(props)) {
@ -1184,7 +1184,7 @@ XrayToString(JSContext *cx, unsigned argc, jsval *vp)
nsAutoString result(NS_LITERAL_STRING("[object XrayWrapper "));
JSObject *obj = &js::GetProxyPrivate(wrapper).toObject();
if (mozilla::dom::binding::instanceIsProxy(obj)) {
if (IsDOMProxy(obj) || oldproxybindings::instanceIsProxy(obj)) {
JSString *wrapperStr = js::GetProxyHandler(wrapper)->obj_toString(cx, wrapper);
size_t length;
const jschar* chars = JS_GetStringCharsAndLength(cx, wrapperStr, &length);