зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1444286. Common up the Get*ObjectHandle methods in bindings. r=peterv
This reduces codesize, at the cost of a bit more includes in the binding headers. MozReview-Commit-ID: 40dLELF36Oh
This commit is contained in:
Родитель
1ce292d679
Коммит
272ace7ae2
|
@ -543,6 +543,17 @@ public:
|
||||||
operator CallerType() const { return CallerType::System; }
|
operator CallerType() const { return CallerType::System; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ProtoAndIfaceCache;
|
||||||
|
typedef void (*CreateInterfaceObjectsMethod)(JSContext* aCx,
|
||||||
|
JS::Handle<JSObject*> aGlobal,
|
||||||
|
ProtoAndIfaceCache& aCache,
|
||||||
|
bool aDefineOnGlobal);
|
||||||
|
JS::Handle<JSObject*> GetPerInterfaceObjectHandle(
|
||||||
|
JSContext* aCx,
|
||||||
|
size_t aSlotId,
|
||||||
|
CreateInterfaceObjectsMethod aCreator,
|
||||||
|
bool aDefineOnGlobal);
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -3805,5 +3805,41 @@ UnprivilegedJunkScopeOrWorkerGlobal()
|
||||||
}
|
}
|
||||||
} // namespace binding_detail
|
} // namespace binding_detail
|
||||||
|
|
||||||
|
JS::Handle<JSObject*>
|
||||||
|
GetPerInterfaceObjectHandle(JSContext* aCx,
|
||||||
|
size_t aSlotId,
|
||||||
|
CreateInterfaceObjectsMethod aCreator,
|
||||||
|
bool aDefineOnGlobal)
|
||||||
|
{
|
||||||
|
/* Make sure our global is sane. Hopefully we can remove this sometime */
|
||||||
|
JSObject* global = JS::CurrentGlobalOrNull(aCx);
|
||||||
|
if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check to see whether the interface objects are already installed */
|
||||||
|
ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
|
||||||
|
if (!protoAndIfaceCache.HasEntryInSlot(aSlotId)) {
|
||||||
|
JS::Rooted<JSObject*> rootedGlobal(aCx, global);
|
||||||
|
aCreator(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The object might _still_ be null, but that's OK.
|
||||||
|
*
|
||||||
|
* Calling fromMarkedLocation() is safe because protoAndIfaceCache is
|
||||||
|
* traced by TraceProtoAndIfaceCache() and its contents are never
|
||||||
|
* changed after they have been set.
|
||||||
|
*
|
||||||
|
* Calling address() avoids the read barrier that does gray unmarking, but
|
||||||
|
* it's not possible for the object to be gray here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const JS::Heap<JSObject*>& entrySlot =
|
||||||
|
protoAndIfaceCache.EntrySlotMustExist(aSlotId);
|
||||||
|
MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
|
||||||
|
return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
@ -3400,66 +3400,28 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
||||||
"\n").define()
|
"\n").define()
|
||||||
|
|
||||||
|
|
||||||
class CGGetPerInterfaceObject(CGAbstractMethod):
|
class CGGetProtoObjectHandleMethod(CGAbstractMethod):
|
||||||
"""
|
|
||||||
A method for getting a per-interface object (a prototype object or interface
|
|
||||||
constructor object).
|
|
||||||
"""
|
|
||||||
def __init__(self, descriptor, name, idPrefix="", extraArgs=[]):
|
|
||||||
args = [Argument('JSContext*', 'aCx')] + extraArgs
|
|
||||||
CGAbstractMethod.__init__(self, descriptor, name,
|
|
||||||
'JS::Handle<JSObject*>', args)
|
|
||||||
self.id = idPrefix + "id::" + self.descriptor.name
|
|
||||||
|
|
||||||
def definition_body(self):
|
|
||||||
return fill(
|
|
||||||
"""
|
|
||||||
/* Make sure our global is sane. Hopefully we can remove this sometime */
|
|
||||||
JSObject* global = JS::CurrentGlobalOrNull(aCx);
|
|
||||||
if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check to see whether the interface objects are already installed */
|
|
||||||
ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
|
|
||||||
if (!protoAndIfaceCache.HasEntryInSlot(${id})) {
|
|
||||||
JS::Rooted<JSObject*> rootedGlobal(aCx, global);
|
|
||||||
CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The object might _still_ be null, but that's OK.
|
|
||||||
*
|
|
||||||
* Calling fromMarkedLocation() is safe because protoAndIfaceCache is
|
|
||||||
* traced by TraceProtoAndIfaceCache() and its contents are never
|
|
||||||
* changed after they have been set.
|
|
||||||
*
|
|
||||||
* Calling address() avoids the read read barrier that does gray
|
|
||||||
* unmarking, but it's not possible for the object to be gray here.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(${id});
|
|
||||||
MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
|
|
||||||
return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
|
|
||||||
""",
|
|
||||||
id=self.id)
|
|
||||||
|
|
||||||
|
|
||||||
class CGGetProtoObjectHandleMethod(CGGetPerInterfaceObject):
|
|
||||||
"""
|
"""
|
||||||
A method for getting the interface prototype object.
|
A method for getting the interface prototype object.
|
||||||
"""
|
"""
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
CGGetPerInterfaceObject.__init__(self, descriptor, "GetProtoObjectHandle",
|
CGAbstractMethod.__init__(
|
||||||
"prototypes::")
|
self, descriptor, "GetProtoObjectHandle",
|
||||||
|
'JS::Handle<JSObject*>',
|
||||||
|
[Argument('JSContext*', 'aCx')],
|
||||||
|
inline=True)
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
return dedent("""
|
return fill(
|
||||||
|
"""
|
||||||
/* Get the interface prototype object for this class. This will create the
|
/* Get the interface prototype object for this class. This will create the
|
||||||
object as needed. */
|
object as needed. */
|
||||||
bool aDefineOnGlobal = true;
|
return GetPerInterfaceObjectHandle(aCx, prototypes::id::${name},
|
||||||
|
&CreateInterfaceObjects,
|
||||||
|
/* aDefineOnGlobal = */ true);
|
||||||
|
|
||||||
""") + CGGetPerInterfaceObject.definition_body(self)
|
""",
|
||||||
|
name=self.descriptor.name)
|
||||||
|
|
||||||
|
|
||||||
class CGGetProtoObjectMethod(CGAbstractMethod):
|
class CGGetProtoObjectMethod(CGAbstractMethod):
|
||||||
|
@ -3475,22 +3437,29 @@ class CGGetProtoObjectMethod(CGAbstractMethod):
|
||||||
return "return GetProtoObjectHandle(aCx);\n"
|
return "return GetProtoObjectHandle(aCx);\n"
|
||||||
|
|
||||||
|
|
||||||
class CGGetConstructorObjectHandleMethod(CGGetPerInterfaceObject):
|
class CGGetConstructorObjectHandleMethod(CGAbstractMethod):
|
||||||
"""
|
"""
|
||||||
A method for getting the interface constructor object.
|
A method for getting the interface constructor object.
|
||||||
"""
|
"""
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
CGGetPerInterfaceObject.__init__(
|
CGAbstractMethod.__init__(
|
||||||
self, descriptor, "GetConstructorObjectHandle",
|
self, descriptor, "GetConstructorObjectHandle",
|
||||||
"constructors::",
|
'JS::Handle<JSObject*>',
|
||||||
extraArgs=[Argument("bool", "aDefineOnGlobal", "true")])
|
[Argument('JSContext*', 'aCx'),
|
||||||
|
Argument('bool', 'aDefineOnGlobal', 'true')],
|
||||||
|
inline=True)
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
return dedent("""
|
return fill(
|
||||||
|
"""
|
||||||
/* Get the interface object for this class. This will create the object as
|
/* Get the interface object for this class. This will create the object as
|
||||||
needed. */
|
needed. */
|
||||||
|
|
||||||
""") + CGGetPerInterfaceObject.definition_body(self)
|
return GetPerInterfaceObjectHandle(aCx, constructors::id::${name},
|
||||||
|
&CreateInterfaceObjects,
|
||||||
|
aDefineOnGlobal);
|
||||||
|
""",
|
||||||
|
name=self.descriptor.name)
|
||||||
|
|
||||||
|
|
||||||
class CGGetConstructorObjectMethod(CGAbstractMethod):
|
class CGGetConstructorObjectMethod(CGAbstractMethod):
|
||||||
|
@ -14386,6 +14355,7 @@ class CGBindingRoot(CGThing):
|
||||||
jsImplemented = config.getDescriptors(webIDLFile=webIDLFile,
|
jsImplemented = config.getDescriptors(webIDLFile=webIDLFile,
|
||||||
isJSImplemented=True)
|
isJSImplemented=True)
|
||||||
bindingDeclareHeaders["nsWeakReference.h"] = jsImplemented
|
bindingDeclareHeaders["nsWeakReference.h"] = jsImplemented
|
||||||
|
bindingDeclareHeaders["mozilla/dom/PrototypeList.h"] = descriptors
|
||||||
bindingHeaders["nsIGlobalObject.h"] = jsImplemented
|
bindingHeaders["nsIGlobalObject.h"] = jsImplemented
|
||||||
bindingHeaders["AtomList.h"] = hasNonEmptyDictionaries or jsImplemented or callbackDescriptors
|
bindingHeaders["AtomList.h"] = hasNonEmptyDictionaries or jsImplemented or callbackDescriptors
|
||||||
|
|
||||||
|
@ -17332,6 +17302,7 @@ class GlobalGenRoots():
|
||||||
idEnum = CGWrapper(idEnum, post='\n')
|
idEnum = CGWrapper(idEnum, post='\n')
|
||||||
|
|
||||||
curr = CGList([CGGeneric(define="#include <stdint.h>\n\n"),
|
curr = CGList([CGGeneric(define="#include <stdint.h>\n\n"),
|
||||||
|
CGGeneric(declare='#include "jsfriendapi.h"\n\n'),
|
||||||
idEnum])
|
idEnum])
|
||||||
|
|
||||||
# Let things know the maximum length of the prototype chain.
|
# Let things know the maximum length of the prototype chain.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче