Bug 850958 - Implement instanceof without relying on nsIDOM interfaces r=bz

This commit is contained in:
David Zbarsky 2013-03-18 19:14:39 -04:00
parent 23b2de3bc0
commit d4058ab34c
2 changed files with 37 additions and 15 deletions

View File

@ -499,11 +499,18 @@ class CGHeaders(CGWrapper):
# Grab all the implementation declaration files we need.
implementationIncludes = set(d.headerFile for d in descriptors if d.needsHeaderInclude())
# Grab the includes for checking hasInstance
interfacesImplementingSelf = set()
for d in descriptors:
interfacesImplementingSelf |= d.interface.interfacesImplementingSelf
implementationIncludes |= set(self.getDeclarationFilename(i) for i in
interfacesImplementingSelf)
# Grab the includes for the things that involve XPCOM interfaces
hasInstanceIncludes = set("nsIDOM" + d.interface.identifier.name + ".h" for d
in descriptors if
NeedsGeneratedHasInstance(d) and
d.interface.hasInterfaceObject())
d.interface.hasInterfacePrototypeObject())
# Now find all the things we'll need as arguments because we
# need to wrap or unwrap them.
@ -1066,23 +1073,20 @@ class CGClassHasInstanceHook(CGAbstractStaticMethod):
def generate_code(self):
assert self.descriptor.nativeOwnership == 'nsisupports'
if self.descriptor.interface.hasInterfacePrototypeObject():
hasInstanceCode = """
bool ok = InterfaceHasInstance(cx, obj, instance, bp);
if (!ok || *bp) {
return ok;
}
"""
else:
hasInstanceCode = ""
return """ if (!vp.isObject()) {
header = """
if (!vp.isObject()) {
*bp = false;
return true;
}
JSObject* instance = &vp.toObject();
%s
"""
if self.descriptor.interface.hasInterfacePrototypeObject():
return header + """
bool ok = InterfaceHasInstance(cx, obj, instance, bp);
if (!ok || *bp) {
return ok;
}
// FIXME Limit this to chrome by checking xpc::AccessCheck::isChrome(obj).
nsISupports* native =
@ -1090,7 +1094,21 @@ class CGClassHasInstanceHook(CGAbstractStaticMethod):
js::UnwrapObject(instance));
nsCOMPtr<nsIDOM%s> qiResult = do_QueryInterface(native);
*bp = !!qiResult;
return true;""" % (hasInstanceCode, self.descriptor.interface.identifier.name)
return true;
""" % self.descriptor.interface.identifier.name
hasInstanceCode = """
const DOMClass* domClass = GetDOMClass(js::UnwrapObject(instance));
*bp = false;
"""
for iface in self.descriptor.interface.interfacesImplementingSelf:
hasInstanceCode += """
if (domClass->mInterfaceChain[PrototypeTraits<prototypes::id::%s>::Depth] == prototypes::id::%s) {
*bp = true;
return true;
}""" % (iface.identifier.name, iface.identifier.name)
hasInstanceCode += "return true;"
return header + hasInstanceCode;
def isChromeOnly(m):
return m.getExtendedAttribute("ChromeOnly")

View File

@ -503,6 +503,9 @@ class IDLInterface(IDLObjectWithScope):
# self or have self as a consequential interface, including self itself.
# Used for distinguishability checking.
self.interfacesBasedOnSelf = set([self])
# self.interfacesImplementingSelf is the set of interfaces that directly
# have self as a consequential interface
self.interfacesImplementingSelf = set()
IDLObjectWithScope.__init__(self, location, parentScope, name)
@ -638,6 +641,7 @@ class IDLInterface(IDLObjectWithScope):
(member.identifier.name, self),
[additionalMember.location, member.location])
self.members.extend(additionalMembers)
iface.interfacesImplementingSelf.add(self)
for ancestor in self.getInheritedInterfaces():
ancestor.interfacesBasedOnSelf.add(self)