mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
Cache legacy callback interface objects in proto_or_icache_array
We need them to be cached to not instantiate them multiple times with lazy initialisation.
This commit is contained in:
parent
2c4d5da866
commit
ca979e115b
3 changed files with 31 additions and 18 deletions
|
@ -2379,9 +2379,8 @@ 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):
|
||||||
args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'global')]
|
args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'global'),
|
||||||
if not descriptor.interface.isCallback():
|
Argument('*mut ProtoOrIfaceArray', 'cache')]
|
||||||
args.append(Argument('*mut ProtoOrIfaceArray', 'cache'))
|
|
||||||
CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args,
|
CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args,
|
||||||
unsafe=True)
|
unsafe=True)
|
||||||
self.properties = properties
|
self.properties = properties
|
||||||
|
@ -2391,7 +2390,14 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
||||||
if self.descriptor.interface.isCallback():
|
if self.descriptor.interface.isCallback():
|
||||||
assert not self.descriptor.interface.ctor() and self.descriptor.interface.hasConstants()
|
assert not self.descriptor.interface.ctor() and self.descriptor.interface.hasConstants()
|
||||||
return CGGeneric("""\
|
return CGGeneric("""\
|
||||||
create_callback_interface_object(cx, global, sConstants, %s);""" % str_to_const_array(name))
|
let mut interface = RootedObject::new(cx, ptr::null_mut());
|
||||||
|
create_callback_interface_object(cx, global, sConstants, %(name)s, interface.handle_mut());
|
||||||
|
assert!(!interface.ptr.is_null());
|
||||||
|
(*cache)[PrototypeList::Constructor::%(id)s as usize] = interface.ptr;
|
||||||
|
if <*mut JSObject>::needs_post_barrier(interface.ptr) {
|
||||||
|
<*mut JSObject>::post_barrier((*cache).as_mut_ptr().offset(PrototypeList::Constructor::%(id)s as isize));
|
||||||
|
}
|
||||||
|
""" % {"id": name, "name": str_to_const_array(name)})
|
||||||
|
|
||||||
if len(self.descriptor.prototypeChain) == 1:
|
if len(self.descriptor.prototypeChain) == 1:
|
||||||
if self.descriptor.interface.getExtendedAttribute("ExceptionClass"):
|
if self.descriptor.interface.getExtendedAttribute("ExceptionClass"):
|
||||||
|
@ -2672,14 +2678,14 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
if self.descriptor.interface.isCallback():
|
if self.descriptor.interface.isCallback():
|
||||||
code = "CreateInterfaceObjects(cx, global);"
|
function = "GetConstructorObject"
|
||||||
else:
|
else:
|
||||||
code = """\
|
function = "GetProtoObject"
|
||||||
|
return CGGeneric("""\
|
||||||
|
assert!(!global.get().is_null());
|
||||||
let mut proto = RootedObject::new(cx, ptr::null_mut());
|
let mut proto = RootedObject::new(cx, ptr::null_mut());
|
||||||
GetProtoObject(cx, global, proto.handle_mut());
|
%s(cx, global, proto.handle_mut());
|
||||||
assert!(!proto.ptr.is_null());
|
assert!(!proto.ptr.is_null());""" % function)
|
||||||
"""
|
|
||||||
return CGGeneric("assert!(!global.get().is_null());\n" + code)
|
|
||||||
|
|
||||||
|
|
||||||
def needCx(returnType, arguments, considerTypes):
|
def needCx(returnType, arguments, considerTypes):
|
||||||
|
@ -4956,7 +4962,8 @@ class CGDescriptor(CGThing):
|
||||||
cgThings = []
|
cgThings = []
|
||||||
if not descriptor.interface.isCallback():
|
if not descriptor.interface.isCallback():
|
||||||
cgThings.append(CGGetProtoObjectMethod(descriptor))
|
cgThings.append(CGGetProtoObjectMethod(descriptor))
|
||||||
if descriptor.interface.hasInterfaceObject() and descriptor.hasDescendants():
|
if (descriptor.interface.hasInterfaceObject() and
|
||||||
|
descriptor.shouldHaveGetConstructorObjectMethod()):
|
||||||
cgThings.append(CGGetConstructorObjectMethod(descriptor))
|
cgThings.append(CGGetConstructorObjectMethod(descriptor))
|
||||||
|
|
||||||
for m in descriptor.interface.members:
|
for m in descriptor.interface.members:
|
||||||
|
@ -6093,7 +6100,8 @@ class GlobalGenRoots():
|
||||||
# Prototype ID enum.
|
# Prototype ID enum.
|
||||||
interfaces = config.getDescriptors(isCallback=False)
|
interfaces = config.getDescriptors(isCallback=False)
|
||||||
protos = [d.name for d in interfaces]
|
protos = [d.name for d in interfaces]
|
||||||
constructors = [d.name for d in interfaces if d.hasDescendants()]
|
constructors = [d.name for d in config.getDescriptors(hasInterfaceObject=True)
|
||||||
|
if d.shouldHaveGetConstructorObjectMethod()]
|
||||||
proxies = [d.name for d in config.getDescriptors(proxy=True)]
|
proxies = [d.name for d in config.getDescriptors(proxy=True)]
|
||||||
|
|
||||||
return CGList([
|
return CGList([
|
||||||
|
|
|
@ -345,6 +345,10 @@ class Descriptor(DescriptorProvider):
|
||||||
return (self.interface.getUserData("hasConcreteDescendant", False) or
|
return (self.interface.getUserData("hasConcreteDescendant", False) or
|
||||||
self.interface.getUserData("hasProxyDescendant", False))
|
self.interface.getUserData("hasProxyDescendant", False))
|
||||||
|
|
||||||
|
def shouldHaveGetConstructorObjectMethod(self):
|
||||||
|
assert self.interface.hasInterfaceObject()
|
||||||
|
return self.interface.isCallback() or self.hasDescendants()
|
||||||
|
|
||||||
def isGlobal(self):
|
def isGlobal(self):
|
||||||
"""
|
"""
|
||||||
Returns true if this is the primary interface for a global object
|
Returns true if this is the primary interface for a global object
|
||||||
|
|
|
@ -178,13 +178,14 @@ pub unsafe fn create_callback_interface_object(
|
||||||
cx: *mut JSContext,
|
cx: *mut JSContext,
|
||||||
receiver: HandleObject,
|
receiver: HandleObject,
|
||||||
constants: &'static [ConstantSpec],
|
constants: &'static [ConstantSpec],
|
||||||
name: &'static [u8]) {
|
name: &'static [u8],
|
||||||
|
rval: MutableHandleObject) {
|
||||||
assert!(!constants.is_empty());
|
assert!(!constants.is_empty());
|
||||||
let interface_object = RootedObject::new(cx, JS_NewObject(cx, ptr::null()));
|
rval.set(JS_NewObject(cx, ptr::null()));
|
||||||
assert!(!interface_object.ptr.is_null());
|
assert!(!rval.ptr.is_null());
|
||||||
define_constants(cx, interface_object.handle(), constants);
|
define_constants(cx, rval.handle(), constants);
|
||||||
define_name(cx, interface_object.handle(), name);
|
define_name(cx, rval.handle(), name);
|
||||||
define_on_global_object(cx, receiver, name, interface_object.handle());
|
define_on_global_object(cx, receiver, name, rval.handle());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create the interface prototype object of a non-callback interface.
|
/// Create the interface prototype object of a non-callback interface.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue