mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Auto merge of #3726 - ChrisParis:callback-constants, r=jdm
This addresses https://github.com/servo/servo/issues/3149. The immediate purpose is to support the constants in NodeFilter. The changes mostly follow the current Gecko Codegen.py. The main gist is that the generation of certain code artifacts is now gated by hasInterfaceObject() or hasInterfacePrototypeObject(), rather than by isCallback().
This commit is contained in:
commit
1f9c2f9b34
3 changed files with 61 additions and 36 deletions
|
@ -1240,9 +1240,14 @@ class MethodDefiner(PropertyDefiner):
|
|||
# FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=772822
|
||||
# We should be able to check for special operations without an
|
||||
# identifier. For now we check if the name starts with __
|
||||
|
||||
# Ignore non-static methods for callback interfaces
|
||||
if not descriptor.interface.isCallback() or static:
|
||||
methods = [m for m in descriptor.interface.members if
|
||||
m.isMethod() and m.isStatic() == static and
|
||||
not m.isIdentifierLess()]
|
||||
else:
|
||||
methods = []
|
||||
self.regular = [{"name": m.identifier.name,
|
||||
"methodInfo": not m.isStatic(),
|
||||
"length": methodLength(m),
|
||||
|
@ -2095,7 +2100,6 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
properties should be a PropertyArrays instance.
|
||||
"""
|
||||
def __init__(self, descriptor, properties):
|
||||
assert not descriptor.interface.isCallback()
|
||||
args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'global'),
|
||||
Argument('*mut JSObject', 'receiver')]
|
||||
CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', '*mut JSObject', args)
|
||||
|
@ -2112,6 +2116,11 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
getParentProto = ("let parent_proto: *mut JSObject = %s;\n"
|
||||
"assert!(!parent_proto.is_null());\n") % getParentProto
|
||||
|
||||
if self.descriptor.interface.isCallback():
|
||||
protoClass = "None"
|
||||
else:
|
||||
protoClass = "Some(&PrototypeClass)"
|
||||
|
||||
if self.descriptor.concrete:
|
||||
if self.descriptor.proxy:
|
||||
domClass = "&Class"
|
||||
|
@ -2136,9 +2145,9 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
|
||||
call = """\
|
||||
return do_create_interface_objects(cx, global, receiver, parent_proto,
|
||||
&PrototypeClass, %s,
|
||||
%s, %s,
|
||||
%s,
|
||||
&sNativeProperties);""" % (constructor, domClass)
|
||||
&sNativeProperties);""" % (protoClass, constructor, domClass)
|
||||
|
||||
return CGList([
|
||||
CGGeneric(getParentProto),
|
||||
|
@ -2286,9 +2295,11 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
|||
return CGAbstractMethod.define(self)
|
||||
|
||||
def definition_body(self):
|
||||
return CGGeneric("""\
|
||||
assert!(!global.is_null());
|
||||
assert!(!GetProtoObject(cx, global, global).is_null());""")
|
||||
if self.descriptor.interface.isCallback():
|
||||
code = "CreateInterfaceObjects(cx, global, global);"
|
||||
else:
|
||||
code = "assert!(!GetProtoObject(cx, global, global).is_null());"
|
||||
return CGGeneric("assert!(!global.is_null());\n" + code)
|
||||
|
||||
def needCx(returnType, arguments, considerTypes):
|
||||
return (considerTypes and
|
||||
|
@ -4268,9 +4279,10 @@ class CGDescriptor(CGThing):
|
|||
def __init__(self, descriptor):
|
||||
CGThing.__init__(self)
|
||||
|
||||
assert not descriptor.interface.isCallback()
|
||||
assert not descriptor.concrete or not descriptor.interface.isCallback()
|
||||
|
||||
cgThings = []
|
||||
if not descriptor.interface.isCallback():
|
||||
cgThings.append(CGGetProtoObjectMethod(descriptor))
|
||||
if descriptor.interface.hasInterfaceObject():
|
||||
# https://github.com/mozilla/servo/issues/2665
|
||||
|
@ -4285,7 +4297,7 @@ class CGDescriptor(CGThing):
|
|||
if m.isStatic():
|
||||
assert descriptor.interface.hasInterfaceObject()
|
||||
cgThings.append(CGStaticMethod(descriptor, m))
|
||||
else:
|
||||
elif not descriptor.interface.isCallback():
|
||||
cgThings.append(CGSpecializedMethod(descriptor, m))
|
||||
cgThings.append(CGMemberJITInfo(descriptor, m))
|
||||
hasMethod = True
|
||||
|
@ -4298,7 +4310,7 @@ class CGDescriptor(CGThing):
|
|||
if m.isStatic():
|
||||
assert descriptor.interface.hasInterfaceObject()
|
||||
cgThings.append(CGStaticGetter(descriptor, m))
|
||||
else:
|
||||
elif not descriptor.interface.isCallback():
|
||||
cgThings.append(CGSpecializedGetter(descriptor, m))
|
||||
if m.hasLenientThis():
|
||||
hasLenientGetter = True
|
||||
|
@ -4309,14 +4321,15 @@ class CGDescriptor(CGThing):
|
|||
if m.isStatic():
|
||||
assert descriptor.interface.hasInterfaceObject()
|
||||
cgThings.append(CGStaticSetter(descriptor, m))
|
||||
else:
|
||||
elif not descriptor.interface.isCallback():
|
||||
cgThings.append(CGSpecializedSetter(descriptor, m))
|
||||
if m.hasLenientThis():
|
||||
hasLenientSetter = True
|
||||
else:
|
||||
hasSetter = True
|
||||
|
||||
if not m.isStatic():
|
||||
if (not m.isStatic() and
|
||||
not descriptor.interface.isCallback()):
|
||||
cgThings.append(CGMemberJITInfo(descriptor, m))
|
||||
if hasMethod:
|
||||
cgThings.append(CGGenericMethod(descriptor))
|
||||
|
@ -4337,6 +4350,7 @@ class CGDescriptor(CGThing):
|
|||
cgThings.append(CGClassConstructHook(descriptor))
|
||||
cgThings.append(CGInterfaceObjectJSClass(descriptor))
|
||||
|
||||
if not descriptor.interface.isCallback():
|
||||
cgThings.append(CGPrototypeJSClass(descriptor))
|
||||
|
||||
properties = PropertyArrays(descriptor)
|
||||
|
@ -4383,6 +4397,7 @@ class CGDescriptor(CGThing):
|
|||
|
||||
cgThings.append(CGWrapMethod(descriptor))
|
||||
|
||||
if not descriptor.interface.isCallback():
|
||||
cgThings.append(CGIDLInterface(descriptor))
|
||||
cgThings.append(CGInterfaceTrait(descriptor))
|
||||
|
||||
|
@ -4638,7 +4653,14 @@ class CGBindingRoot(CGThing):
|
|||
"""
|
||||
def __init__(self, config, prefix, webIDLFile):
|
||||
descriptors = config.getDescriptors(webIDLFile=webIDLFile,
|
||||
isCallback=False)
|
||||
hasInterfaceObject=True)
|
||||
# We also want descriptors that have an interface prototype object
|
||||
# (isCallback=False), but we don't want to include a second copy
|
||||
# of descriptors that we also matched in the previous line
|
||||
# (hence hasInterfaceObject=False).
|
||||
descriptors.extend(config.getDescriptors(webIDLFile=webIDLFile,
|
||||
hasInterfaceObject=False,
|
||||
isCallback=False))
|
||||
dictionaries = config.getDictionaries(webIDLFile=webIDLFile)
|
||||
|
||||
cgthings = []
|
||||
|
|
|
@ -162,10 +162,12 @@ class Descriptor(DescriptorProvider):
|
|||
self.concreteType = ifaceName
|
||||
self.register = desc.get('register', True)
|
||||
self.outerObjectHook = desc.get('outerObjectHook', 'None')
|
||||
self.proxy = False
|
||||
|
||||
# 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 = (not self.interface.isCallback() and
|
||||
desc.get('concrete', True))
|
||||
|
||||
self.operations = {
|
||||
'IndexedGetter': None,
|
||||
|
@ -190,7 +192,6 @@ class Descriptor(DescriptorProvider):
|
|||
addOperation('Stringifier', m)
|
||||
|
||||
if self.concrete:
|
||||
self.proxy = False
|
||||
iface = self.interface
|
||||
while iface:
|
||||
for m in iface.members:
|
||||
|
|
|
@ -180,36 +180,38 @@ unsafe impl Sync for NativeProperties {}
|
|||
pub type NonNullJSNative =
|
||||
unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool;
|
||||
|
||||
/// Creates the *interface prototype object* and the *interface object* (if
|
||||
/// needed).
|
||||
/// Creates the *interface prototype object* (if a `proto_class` is given)
|
||||
/// and the *interface object* (if a `constructor` is given).
|
||||
/// Fails on JSAPI failure.
|
||||
pub fn do_create_interface_objects(cx: *mut JSContext, global: *mut JSObject,
|
||||
receiver: *mut JSObject,
|
||||
proto_proto: *mut JSObject,
|
||||
proto_class: &'static JSClass,
|
||||
proto_class: Option<&'static JSClass>,
|
||||
constructor: Option<(NonNullJSNative, &'static str, u32)>,
|
||||
dom_class: *const DOMClass,
|
||||
members: &'static NativeProperties)
|
||||
-> *mut JSObject {
|
||||
unsafe {
|
||||
let proto = match proto_class {
|
||||
Some(proto_class) => {
|
||||
let proto = create_interface_prototype_object(cx, global, proto_proto,
|
||||
proto_class, members);
|
||||
|
||||
unsafe {
|
||||
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
|
||||
PrivateValue(dom_class as *const libc::c_void));
|
||||
}
|
||||
proto
|
||||
},
|
||||
None => ptr::null_mut()
|
||||
};
|
||||
|
||||
match constructor {
|
||||
Some((native, name, nargs)) => {
|
||||
if let Some((native, name, nargs)) = constructor {
|
||||
let s = CString::new(name).unwrap();
|
||||
create_interface_object(cx, global, receiver,
|
||||
native, nargs, proto,
|
||||
members, s.as_ptr())
|
||||
},
|
||||
None => (),
|
||||
}
|
||||
|
||||
proto
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates the *interface object*.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue