From 747a99d3f6ddc1f3e3cf539cf873120efd69ef46 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 26 May 2023 01:02:38 -0400 Subject: [PATCH 1/3] Extract bodies of DefineDOMInterface and GetProtoObject/GetConstructorObject out of generated bindings. --- .../dom/bindings/codegen/CodegenRust.py | 41 +++++---------- components/script/dom/bindings/interface.rs | 51 ++++++++++++++++++- 2 files changed, 62 insertions(+), 30 deletions(-) diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 1bf2b917a9d..828a0e380c0 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -3493,21 +3493,8 @@ class CGGetPerInterfaceObject(CGAbstractMethod): def definition_body(self): return CGGeneric(""" -unsafe { - assert!(((*get_object_class(global.get())).flags & JSCLASS_DOM_GLOBAL) != 0); - - /* Check to see whether the interface objects are already installed */ - let proto_or_iface_array = get_proto_or_iface_array(global.get()); - rval.set((*proto_or_iface_array)[%(id)s as usize]); - if !rval.get().is_null() { - return; - } - - CreateInterfaceObjects(cx, global, proto_or_iface_array); - rval.set((*proto_or_iface_array)[%(id)s as usize]); - assert!(!rval.get().is_null()); -} -""" % {"id": self.id}) + get_per_interface_object_handle(cx, global, %s as usize, CreateInterfaceObjects, rval) + """ % self.id) class CGGetProtoObjectMethod(CGGetPerInterfaceObject): @@ -3655,25 +3642,19 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): ] CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'void', args, pub=True) + if self.descriptor.interface.isCallback() or self.descriptor.interface.isNamespace(): + idPrefix = "PrototypeList::Constructor" + else: + idPrefix = "PrototypeList::ID" + self.id = idPrefix + "::" + MakeNativeName(self.descriptor.name) def define(self): return CGAbstractMethod.define(self) def definition_body(self): - if self.descriptor.interface.isCallback() or self.descriptor.interface.isNamespace(): - function = "GetConstructorObject" - else: - function = "GetProtoObject" - return CGGeneric("""\ -assert!(!global.get().is_null()); - -if !ConstructorEnabled(cx, global) { - return; -} - -rooted!(in(*cx) let mut proto = ptr::null_mut::()); -%s(cx, global, proto.handle_mut()); -assert!(!proto.is_null());""" % (function,)) + return CGGeneric(""" + define_dom_interface(cx, global, %s as usize, CreateInterfaceObjects, ConstructorEnabled) + """ % self.id) def needCx(returnType, arguments, considerTypes): @@ -6453,6 +6434,8 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries 'crate::dom::bindings::interface::define_guarded_methods', 'crate::dom::bindings::interface::define_guarded_properties', 'crate::dom::bindings::interface::is_exposed_in', + 'crate::dom::bindings::interface::get_per_interface_object_handle', + 'crate::dom::bindings::interface::define_dom_interface', 'crate::dom::bindings::htmlconstructor::pop_current_element_queue', 'crate::dom::bindings::htmlconstructor::push_new_element_queue', 'crate::dom::bindings::iterable::Iterable', diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index e6d0b9d0df5..fbab9bfcf32 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -10,7 +10,9 @@ use crate::dom::bindings::constant::{define_constants, ConstantSpec}; use crate::dom::bindings::conversions::{get_dom_class, DOM_OBJECT_SLOT}; use crate::dom::bindings::guard::Guard; use crate::dom::bindings::principals::ServoJSPrincipals; -use crate::dom::bindings::utils::{ProtoOrIfaceArray, DOM_PROTOTYPE_SLOT}; +use crate::dom::bindings::utils::{ + get_proto_or_iface_array, ProtoOrIfaceArray, DOM_PROTOTYPE_SLOT, JSCLASS_DOM_GLOBAL +}; use crate::script_runtime::JSContext as SafeJSContext; use js::error::throw_type_error; use js::glue::UncheckedUnwrapObject; @@ -534,3 +536,50 @@ unsafe extern "C" fn non_new_constructor( throw_type_error(cx, "This constructor needs to be called with `new`."); false } + +pub fn get_per_interface_object_handle( + cx: SafeJSContext, + global: HandleObject, + id: usize, + creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray), + mut rval: MutableHandleObject, +) { + unsafe { + assert!(((*get_object_class(global.get())).flags & JSCLASS_DOM_GLOBAL) != 0); + + /* Check to see whether the interface objects are already installed */ + let proto_or_iface_array = get_proto_or_iface_array(global.get()); + rval.set((*proto_or_iface_array)[id]); + if !rval.get().is_null() { + return; + } + + creator(cx, global, proto_or_iface_array); + rval.set((*proto_or_iface_array)[id]); + assert!(!rval.get().is_null()); + } +} + +pub fn define_dom_interface( + cx: SafeJSContext, + global: HandleObject, + id: usize, + creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray), + enabled: fn(SafeJSContext, HandleObject) -> bool, +) { + assert!(!global.get().is_null()); + + if !enabled(cx, global) { + return; + } + + rooted!(in(*cx) let mut proto = ptr::null_mut::()); + get_per_interface_object_handle( + cx, + global, + id, + creator, + proto.handle_mut(), + ); + assert!(!proto.is_null()); +} From 7d9dc458afca1b1931c33fd18c7ba5937dc8732e Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 26 May 2023 01:21:31 -0400 Subject: [PATCH 2/3] Use an enum to pass the index value for interfaces/protos. --- .../dom/bindings/codegen/CodegenRust.py | 13 +++++++---- components/script/dom/bindings/interface.rs | 23 +++++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 828a0e380c0..24cf71d8820 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -3490,11 +3490,12 @@ class CGGetPerInterfaceObject(CGAbstractMethod): CGAbstractMethod.__init__(self, descriptor, name, 'void', args, pub=pub) self.id = idPrefix + "::" + MakeNativeName(self.descriptor.name) + self.variant = self.id.split('::')[-2] def definition_body(self): return CGGeneric(""" - get_per_interface_object_handle(cx, global, %s as usize, CreateInterfaceObjects, rval) - """ % self.id) + get_per_interface_object_handle(cx, global, ProtoOrIfaceIndex::%s(%s), CreateInterfaceObjects, rval) + """ % (self.variant, self.id)) class CGGetProtoObjectMethod(CGGetPerInterfaceObject): @@ -3647,14 +3648,15 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): else: idPrefix = "PrototypeList::ID" self.id = idPrefix + "::" + MakeNativeName(self.descriptor.name) + self.variant = self.id.split('::')[-2] def define(self): return CGAbstractMethod.define(self) def definition_body(self): return CGGeneric(""" - define_dom_interface(cx, global, %s as usize, CreateInterfaceObjects, ConstructorEnabled) - """ % self.id) + define_dom_interface(cx, global, ProtoOrIfaceIndex::%s(%s), CreateInterfaceObjects, ConstructorEnabled) + """ % (self.variant, self.id)) def needCx(returnType, arguments, considerTypes): @@ -6425,17 +6427,18 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries 'crate::dom::bindings::interface::ConstructorClassHook', 'crate::dom::bindings::interface::InterfaceConstructorBehavior', 'crate::dom::bindings::interface::NonCallbackInterfaceObjectClass', + 'crate::dom::bindings::interface::ProtoOrIfaceIndex', 'crate::dom::bindings::interface::create_global_object', 'crate::dom::bindings::interface::create_callback_interface_object', 'crate::dom::bindings::interface::create_interface_prototype_object', 'crate::dom::bindings::interface::create_named_constructors', 'crate::dom::bindings::interface::create_noncallback_interface_object', + 'crate::dom::bindings::interface::define_dom_interface', 'crate::dom::bindings::interface::define_guarded_constants', 'crate::dom::bindings::interface::define_guarded_methods', 'crate::dom::bindings::interface::define_guarded_properties', 'crate::dom::bindings::interface::is_exposed_in', 'crate::dom::bindings::interface::get_per_interface_object_handle', - 'crate::dom::bindings::interface::define_dom_interface', 'crate::dom::bindings::htmlconstructor::pop_current_element_queue', 'crate::dom::bindings::htmlconstructor::push_new_element_queue', 'crate::dom::bindings::iterable::Iterable', diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index fbab9bfcf32..bf14d8ef496 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -537,10 +537,24 @@ unsafe extern "C" fn non_new_constructor( false } +pub enum ProtoOrIfaceIndex { + ID(PrototypeList::ID), + Constructor(PrototypeList::Constructor), +} + +impl Into for ProtoOrIfaceIndex { + fn into(self) -> usize { + match self { + ProtoOrIfaceIndex::ID(id) => id as usize, + ProtoOrIfaceIndex::Constructor(constructor) => constructor as usize, + } + } +} + pub fn get_per_interface_object_handle( cx: SafeJSContext, global: HandleObject, - id: usize, + id: ProtoOrIfaceIndex, creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray), mut rval: MutableHandleObject, ) { @@ -549,13 +563,14 @@ pub fn get_per_interface_object_handle( /* Check to see whether the interface objects are already installed */ let proto_or_iface_array = get_proto_or_iface_array(global.get()); - rval.set((*proto_or_iface_array)[id]); + let index: usize = id.into(); + rval.set((*proto_or_iface_array)[index]); if !rval.get().is_null() { return; } creator(cx, global, proto_or_iface_array); - rval.set((*proto_or_iface_array)[id]); + rval.set((*proto_or_iface_array)[index]); assert!(!rval.get().is_null()); } } @@ -563,7 +578,7 @@ pub fn get_per_interface_object_handle( pub fn define_dom_interface( cx: SafeJSContext, global: HandleObject, - id: usize, + id: ProtoOrIfaceIndex, creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray), enabled: fn(SafeJSContext, HandleObject) -> bool, ) { From 123937a500e2d847d3e1e8eeb16c94a860e18a99 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 26 May 2023 01:24:47 -0400 Subject: [PATCH 3/3] Formatting. --- components/script/dom/bindings/interface.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index bf14d8ef496..86b8f464629 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -11,7 +11,7 @@ use crate::dom::bindings::conversions::{get_dom_class, DOM_OBJECT_SLOT}; use crate::dom::bindings::guard::Guard; use crate::dom::bindings::principals::ServoJSPrincipals; use crate::dom::bindings::utils::{ - get_proto_or_iface_array, ProtoOrIfaceArray, DOM_PROTOTYPE_SLOT, JSCLASS_DOM_GLOBAL + get_proto_or_iface_array, ProtoOrIfaceArray, DOM_PROTOTYPE_SLOT, JSCLASS_DOM_GLOBAL, }; use crate::script_runtime::JSContext as SafeJSContext; use js::error::throw_type_error; @@ -589,12 +589,6 @@ pub fn define_dom_interface( } rooted!(in(*cx) let mut proto = ptr::null_mut::()); - get_per_interface_object_handle( - cx, - global, - id, - creator, - proto.handle_mut(), - ); + get_per_interface_object_handle(cx, global, id, creator, proto.handle_mut()); assert!(!proto.is_null()); }