Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazily define interface objects on globals (fixes #6419) #9652

Merged
merged 5 commits into from Feb 25, 2016
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

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.
  • Loading branch information
nox committed Feb 25, 2016
commit ca979e115b087cf627baf2be8d54ea47b1f773a1
@@ -2379,9 +2379,8 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
properties should be a PropertyArrays instance.
"""
def __init__(self, descriptor, properties):
args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'global')]
if not descriptor.interface.isCallback():
args.append(Argument('*mut ProtoOrIfaceArray', 'cache'))
args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'global'),
Argument('*mut ProtoOrIfaceArray', 'cache')]
CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args,
unsafe=True)
self.properties = properties
@@ -2391,7 +2390,14 @@ def definition_body(self):
if self.descriptor.interface.isCallback():
assert not self.descriptor.interface.ctor() and self.descriptor.interface.hasConstants()
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 self.descriptor.interface.getExtendedAttribute("ExceptionClass"):
@@ -2672,14 +2678,14 @@ def define(self):

def definition_body(self):
if self.descriptor.interface.isCallback():
code = "CreateInterfaceObjects(cx, global);"
function = "GetConstructorObject"
else:
code = """\
function = "GetProtoObject"
return CGGeneric("""\
assert!(!global.get().is_null());
let mut proto = RootedObject::new(cx, ptr::null_mut());
GetProtoObject(cx, global, proto.handle_mut());
assert!(!proto.ptr.is_null());
"""
return CGGeneric("assert!(!global.get().is_null());\n" + code)
%s(cx, global, proto.handle_mut());
assert!(!proto.ptr.is_null());""" % function)


def needCx(returnType, arguments, considerTypes):
@@ -4956,7 +4962,8 @@ def __init__(self, descriptor):
cgThings = []
if not descriptor.interface.isCallback():
cgThings.append(CGGetProtoObjectMethod(descriptor))
if descriptor.interface.hasInterfaceObject() and descriptor.hasDescendants():
if (descriptor.interface.hasInterfaceObject() and
descriptor.shouldHaveGetConstructorObjectMethod()):
cgThings.append(CGGetConstructorObjectMethod(descriptor))

for m in descriptor.interface.members:
@@ -6093,7 +6100,8 @@ def PrototypeList(config):
# Prototype ID enum.
interfaces = config.getDescriptors(isCallback=False)
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)]

return CGList([
@@ -345,6 +345,10 @@ def hasDescendants(self):
return (self.interface.getUserData("hasConcreteDescendant", False) or
self.interface.getUserData("hasProxyDescendant", False))

def shouldHaveGetConstructorObjectMethod(self):
assert self.interface.hasInterfaceObject()
return self.interface.isCallback() or self.hasDescendants()

def isGlobal(self):
"""
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,
receiver: HandleObject,
constants: &'static [ConstantSpec],
name: &'static [u8]) {
name: &'static [u8],
rval: MutableHandleObject) {
assert!(!constants.is_empty());
let interface_object = RootedObject::new(cx, JS_NewObject(cx, ptr::null()));
assert!(!interface_object.ptr.is_null());
define_constants(cx, interface_object.handle(), constants);
define_name(cx, interface_object.handle(), name);
define_on_global_object(cx, receiver, name, interface_object.handle());
rval.set(JS_NewObject(cx, ptr::null()));
assert!(!rval.ptr.is_null());
define_constants(cx, rval.handle(), constants);
define_name(cx, rval.handle(), name);
define_on_global_object(cx, receiver, name, rval.handle());
}

/// Create the interface prototype object of a non-callback interface.
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.