mirror of
https://github.com/servo/servo.git
synced 2025-07-24 07:40:27 +01:00
Support callback interfaces with constants.
This commit is contained in:
parent
10c68e7519
commit
d2b0d5e040
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
|
# FIXME https://bugzilla.mozilla.org/show_bug.cgi?id=772822
|
||||||
# We should be able to check for special operations without an
|
# We should be able to check for special operations without an
|
||||||
# identifier. For now we check if the name starts with __
|
# identifier. For now we check if the name starts with __
|
||||||
methods = [m for m in descriptor.interface.members if
|
|
||||||
m.isMethod() and m.isStatic() == static and
|
# Ignore non-static methods for callback interfaces
|
||||||
not m.isIdentifierLess()]
|
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,
|
self.regular = [{"name": m.identifier.name,
|
||||||
"methodInfo": not m.isStatic(),
|
"methodInfo": not m.isStatic(),
|
||||||
"length": methodLength(m),
|
"length": methodLength(m),
|
||||||
|
@ -2085,7 +2090,6 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
||||||
properties should be a PropertyArrays instance.
|
properties should be a PropertyArrays instance.
|
||||||
"""
|
"""
|
||||||
def __init__(self, descriptor, properties):
|
def __init__(self, descriptor, properties):
|
||||||
assert not descriptor.interface.isCallback()
|
|
||||||
args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'global'),
|
args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'global'),
|
||||||
Argument('*mut JSObject', 'receiver')]
|
Argument('*mut JSObject', 'receiver')]
|
||||||
CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', '*mut JSObject', args)
|
CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', '*mut JSObject', args)
|
||||||
|
@ -2102,6 +2106,11 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
||||||
getParentProto = ("let parent_proto: *mut JSObject = %s;\n"
|
getParentProto = ("let parent_proto: *mut JSObject = %s;\n"
|
||||||
"assert!(!parent_proto.is_null());\n") % getParentProto
|
"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.concrete:
|
||||||
if self.descriptor.proxy:
|
if self.descriptor.proxy:
|
||||||
domClass = "&Class"
|
domClass = "&Class"
|
||||||
|
@ -2126,9 +2135,9 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
||||||
|
|
||||||
call = """\
|
call = """\
|
||||||
return do_create_interface_objects(cx, global, receiver, parent_proto,
|
return do_create_interface_objects(cx, global, receiver, parent_proto,
|
||||||
&PrototypeClass, %s,
|
%s, %s,
|
||||||
%s,
|
%s,
|
||||||
&sNativeProperties);""" % (constructor, domClass)
|
&sNativeProperties);""" % (protoClass, constructor, domClass)
|
||||||
|
|
||||||
return CGList([
|
return CGList([
|
||||||
CGGeneric(getParentProto),
|
CGGeneric(getParentProto),
|
||||||
|
@ -2276,9 +2285,11 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
||||||
return CGAbstractMethod.define(self)
|
return CGAbstractMethod.define(self)
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
return CGGeneric("""\
|
if self.descriptor.interface.isCallback():
|
||||||
assert!(!global.is_null());
|
code = "CreateInterfaceObjects(cx, global, global);"
|
||||||
assert!(!GetProtoObject(cx, global, global).is_null());""")
|
else:
|
||||||
|
code = "assert!(!GetProtoObject(cx, global, global).is_null());"
|
||||||
|
return CGGeneric("assert!(!global.is_null());\n" + code)
|
||||||
|
|
||||||
def needCx(returnType, arguments, considerTypes):
|
def needCx(returnType, arguments, considerTypes):
|
||||||
return (considerTypes and
|
return (considerTypes and
|
||||||
|
@ -4258,10 +4269,11 @@ class CGDescriptor(CGThing):
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
CGThing.__init__(self)
|
CGThing.__init__(self)
|
||||||
|
|
||||||
assert not descriptor.interface.isCallback()
|
assert not descriptor.concrete or not descriptor.interface.isCallback()
|
||||||
|
|
||||||
cgThings = []
|
cgThings = []
|
||||||
cgThings.append(CGGetProtoObjectMethod(descriptor))
|
if not descriptor.interface.isCallback():
|
||||||
|
cgThings.append(CGGetProtoObjectMethod(descriptor))
|
||||||
if descriptor.interface.hasInterfaceObject():
|
if descriptor.interface.hasInterfaceObject():
|
||||||
# https://github.com/mozilla/servo/issues/2665
|
# https://github.com/mozilla/servo/issues/2665
|
||||||
# cgThings.append(CGGetConstructorObjectMethod(descriptor))
|
# cgThings.append(CGGetConstructorObjectMethod(descriptor))
|
||||||
|
@ -4275,7 +4287,7 @@ class CGDescriptor(CGThing):
|
||||||
if m.isStatic():
|
if m.isStatic():
|
||||||
assert descriptor.interface.hasInterfaceObject()
|
assert descriptor.interface.hasInterfaceObject()
|
||||||
cgThings.append(CGStaticMethod(descriptor, m))
|
cgThings.append(CGStaticMethod(descriptor, m))
|
||||||
else:
|
elif not descriptor.interface.isCallback():
|
||||||
cgThings.append(CGSpecializedMethod(descriptor, m))
|
cgThings.append(CGSpecializedMethod(descriptor, m))
|
||||||
cgThings.append(CGMemberJITInfo(descriptor, m))
|
cgThings.append(CGMemberJITInfo(descriptor, m))
|
||||||
hasMethod = True
|
hasMethod = True
|
||||||
|
@ -4288,7 +4300,7 @@ class CGDescriptor(CGThing):
|
||||||
if m.isStatic():
|
if m.isStatic():
|
||||||
assert descriptor.interface.hasInterfaceObject()
|
assert descriptor.interface.hasInterfaceObject()
|
||||||
cgThings.append(CGStaticGetter(descriptor, m))
|
cgThings.append(CGStaticGetter(descriptor, m))
|
||||||
else:
|
elif not descriptor.interface.isCallback():
|
||||||
cgThings.append(CGSpecializedGetter(descriptor, m))
|
cgThings.append(CGSpecializedGetter(descriptor, m))
|
||||||
if m.hasLenientThis():
|
if m.hasLenientThis():
|
||||||
hasLenientGetter = True
|
hasLenientGetter = True
|
||||||
|
@ -4299,14 +4311,15 @@ class CGDescriptor(CGThing):
|
||||||
if m.isStatic():
|
if m.isStatic():
|
||||||
assert descriptor.interface.hasInterfaceObject()
|
assert descriptor.interface.hasInterfaceObject()
|
||||||
cgThings.append(CGStaticSetter(descriptor, m))
|
cgThings.append(CGStaticSetter(descriptor, m))
|
||||||
else:
|
elif not descriptor.interface.isCallback():
|
||||||
cgThings.append(CGSpecializedSetter(descriptor, m))
|
cgThings.append(CGSpecializedSetter(descriptor, m))
|
||||||
if m.hasLenientThis():
|
if m.hasLenientThis():
|
||||||
hasLenientSetter = True
|
hasLenientSetter = True
|
||||||
else:
|
else:
|
||||||
hasSetter = True
|
hasSetter = True
|
||||||
|
|
||||||
if not m.isStatic():
|
if (not m.isStatic() and
|
||||||
|
not descriptor.interface.isCallback()):
|
||||||
cgThings.append(CGMemberJITInfo(descriptor, m))
|
cgThings.append(CGMemberJITInfo(descriptor, m))
|
||||||
if hasMethod:
|
if hasMethod:
|
||||||
cgThings.append(CGGenericMethod(descriptor))
|
cgThings.append(CGGenericMethod(descriptor))
|
||||||
|
@ -4327,7 +4340,8 @@ class CGDescriptor(CGThing):
|
||||||
cgThings.append(CGClassConstructHook(descriptor))
|
cgThings.append(CGClassConstructHook(descriptor))
|
||||||
cgThings.append(CGInterfaceObjectJSClass(descriptor))
|
cgThings.append(CGInterfaceObjectJSClass(descriptor))
|
||||||
|
|
||||||
cgThings.append(CGPrototypeJSClass(descriptor))
|
if not descriptor.interface.isCallback():
|
||||||
|
cgThings.append(CGPrototypeJSClass(descriptor))
|
||||||
|
|
||||||
properties = PropertyArrays(descriptor)
|
properties = PropertyArrays(descriptor)
|
||||||
cgThings.append(CGGeneric(str(properties)))
|
cgThings.append(CGGeneric(str(properties)))
|
||||||
|
@ -4373,8 +4387,9 @@ class CGDescriptor(CGThing):
|
||||||
|
|
||||||
cgThings.append(CGWrapMethod(descriptor))
|
cgThings.append(CGWrapMethod(descriptor))
|
||||||
|
|
||||||
cgThings.append(CGIDLInterface(descriptor))
|
if not descriptor.interface.isCallback():
|
||||||
cgThings.append(CGInterfaceTrait(descriptor))
|
cgThings.append(CGIDLInterface(descriptor))
|
||||||
|
cgThings.append(CGInterfaceTrait(descriptor))
|
||||||
|
|
||||||
cgThings = CGList(cgThings, "\n")
|
cgThings = CGList(cgThings, "\n")
|
||||||
#self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
|
#self.cgRoot = CGWrapper(CGNamespace(toBindingNamespace(descriptor.name),
|
||||||
|
@ -4628,7 +4643,14 @@ class CGBindingRoot(CGThing):
|
||||||
"""
|
"""
|
||||||
def __init__(self, config, prefix, webIDLFile):
|
def __init__(self, config, prefix, webIDLFile):
|
||||||
descriptors = config.getDescriptors(webIDLFile=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)
|
dictionaries = config.getDictionaries(webIDLFile=webIDLFile)
|
||||||
|
|
||||||
cgthings = []
|
cgthings = []
|
||||||
|
|
|
@ -162,10 +162,12 @@ class Descriptor(DescriptorProvider):
|
||||||
self.concreteType = ifaceName
|
self.concreteType = ifaceName
|
||||||
self.register = desc.get('register', True)
|
self.register = desc.get('register', True)
|
||||||
self.outerObjectHook = desc.get('outerObjectHook', 'None')
|
self.outerObjectHook = desc.get('outerObjectHook', 'None')
|
||||||
|
self.proxy = False
|
||||||
|
|
||||||
# If we're concrete, we need to crawl our ancestor interfaces and mark
|
# If we're concrete, we need to crawl our ancestor interfaces and mark
|
||||||
# them as having a concrete descendant.
|
# 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 = {
|
self.operations = {
|
||||||
'IndexedGetter': None,
|
'IndexedGetter': None,
|
||||||
|
@ -190,7 +192,6 @@ class Descriptor(DescriptorProvider):
|
||||||
addOperation('Stringifier', m)
|
addOperation('Stringifier', m)
|
||||||
|
|
||||||
if self.concrete:
|
if self.concrete:
|
||||||
self.proxy = False
|
|
||||||
iface = self.interface
|
iface = self.interface
|
||||||
while iface:
|
while iface:
|
||||||
for m in iface.members:
|
for m in iface.members:
|
||||||
|
|
|
@ -180,36 +180,38 @@ unsafe impl Sync for NativeProperties {}
|
||||||
pub type NonNullJSNative =
|
pub type NonNullJSNative =
|
||||||
unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool;
|
unsafe extern "C" fn (arg1: *mut JSContext, arg2: c_uint, arg3: *mut JSVal) -> JSBool;
|
||||||
|
|
||||||
/// Creates the *interface prototype object* and the *interface object* (if
|
/// Creates the *interface prototype object* (if a `proto_class` is given)
|
||||||
/// needed).
|
/// and the *interface object* (if a `constructor` is given).
|
||||||
/// Fails on JSAPI failure.
|
/// Fails on JSAPI failure.
|
||||||
pub fn do_create_interface_objects(cx: *mut JSContext, global: *mut JSObject,
|
pub fn do_create_interface_objects(cx: *mut JSContext, global: *mut JSObject,
|
||||||
receiver: *mut JSObject,
|
receiver: *mut JSObject,
|
||||||
proto_proto: *mut JSObject,
|
proto_proto: *mut JSObject,
|
||||||
proto_class: &'static JSClass,
|
proto_class: Option<&'static JSClass>,
|
||||||
constructor: Option<(NonNullJSNative, &'static str, u32)>,
|
constructor: Option<(NonNullJSNative, &'static str, u32)>,
|
||||||
dom_class: *const DOMClass,
|
dom_class: *const DOMClass,
|
||||||
members: &'static NativeProperties)
|
members: &'static NativeProperties)
|
||||||
-> *mut JSObject {
|
-> *mut JSObject {
|
||||||
let proto = create_interface_prototype_object(cx, global, proto_proto,
|
|
||||||
proto_class, members);
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
|
let proto = match proto_class {
|
||||||
PrivateValue(dom_class as *const libc::c_void));
|
Some(proto_class) => {
|
||||||
}
|
let proto = create_interface_prototype_object(cx, global, proto_proto,
|
||||||
|
proto_class, members);
|
||||||
|
JS_SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
|
||||||
|
PrivateValue(dom_class as *const libc::c_void));
|
||||||
|
proto
|
||||||
|
},
|
||||||
|
None => ptr::null_mut()
|
||||||
|
};
|
||||||
|
|
||||||
match constructor {
|
if let Some((native, name, nargs)) = constructor {
|
||||||
Some((native, name, nargs)) => {
|
|
||||||
let s = CString::new(name).unwrap();
|
let s = CString::new(name).unwrap();
|
||||||
create_interface_object(cx, global, receiver,
|
create_interface_object(cx, global, receiver,
|
||||||
native, nargs, proto,
|
native, nargs, proto,
|
||||||
members, s.as_ptr())
|
members, s.as_ptr())
|
||||||
},
|
}
|
||||||
None => (),
|
|
||||||
}
|
|
||||||
|
|
||||||
proto
|
proto
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the *interface object*.
|
/// Creates the *interface object*.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue