diff options
author | Gae24 <96017547+Gae24@users.noreply.github.com> | 2024-10-09 14:33:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-09 12:33:44 +0000 |
commit | 5ba8054b69e3f9867cecde89a18bf0f134d6f276 (patch) | |
tree | 42d933f7907b8dff5c4b4d4fd3922b4bf8784d08 | |
parent | 3eee02869a8a9673a52d807c737e4c203d32b1b7 (diff) | |
download | servo-5ba8054b69e3f9867cecde89a18bf0f134d6f276.tar.gz servo-5ba8054b69e3f9867cecde89a18bf0f134d6f276.zip |
refactor `CGClassConstructHook` to use handwritten constructors (#33614)
* extract generated class constructor hook into handwritten functions
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* downcast to window only when it's actually used
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* simplify downcast
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
* rename htmlconstructor to constructor, include call_default_constructor in it
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
---------
Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
-rw-r--r-- | components/script/dom/bindings/codegen/CodegenRust.py | 62 | ||||
-rw-r--r-- | components/script/dom/bindings/constructor.rs (renamed from components/script/dom/bindings/htmlconstructor.rs) | 34 | ||||
-rw-r--r-- | components/script/dom/bindings/import.rs | 7 | ||||
-rw-r--r-- | components/script/dom/bindings/mod.rs | 2 |
4 files changed, 65 insertions, 40 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 246e12b16ad..9cffaf35f93 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -6229,16 +6229,11 @@ class CGClassConstructHook(CGAbstractExternMethod): let args = CallArgs::from_vp(vp, argc); let global = GlobalScope::from_object(JS_CALLEE(*cx, vp).to_object()); """ - if len(self.exposureSet) == 1: - preamble += f""" -let global = DomRoot::downcast::<dom::types::{list(self.exposureSet)[0]}>(global).unwrap(); -""" if self.constructor.isHTMLConstructor(): signatures = self.constructor.signatures() assert len(signatures) == 1 - constructorCall = CGGeneric( - f""" - dom::bindings::htmlconstructor::call_html_constructor::<dom::types::{self.descriptor.name}>( + constructorCall = f""" + call_html_constructor::<dom::types::{self.descriptor.name}>( cx, &args, &global, @@ -6246,34 +6241,39 @@ let global = DomRoot::downcast::<dom::types::{list(self.exposureSet)[0]}>(global CreateInterfaceObjects, ) """ - ) else: ctorName = GetConstructorNameForReporting(self.descriptor, self.constructor) - preamble += f""" -if !args.is_constructing() {{ - throw_constructor_without_new(*cx, "{ctorName}"); - return false; -}} - -rooted!(in(*cx) let mut desired_proto = ptr::null_mut::<JSObject>()); -let proto_result = get_desired_proto( - cx, - &args, - PrototypeList::ID::{MakeNativeName(self.descriptor.name)}, - CreateInterfaceObjects, - desired_proto.handle_mut(), -); -assert!(proto_result.is_ok()); -if proto_result.is_err() {{ - return false; -}} -""" name = self.constructor.identifier.name nativeName = MakeNativeName(self.descriptor.binaryNameFor(name)) - args = ["&global", "Some(desired_proto.handle())", "CanGc::note()"] - constructorCall = CGMethodCall(args, nativeName, True, - self.descriptor, self.constructor) - return CGList([CGGeneric(preamble), constructorCall]) + + if len(self.exposureSet) == 1: + args = [ + f"global.downcast::<dom::types::{list(self.exposureSet)[0]}>().unwrap()", + "Some(desired_proto.handle())", + "CanGc::note()" + ] + else: + args = [ + "&global", + "Some(desired_proto.handle())", + "CanGc::note()" + ] + + constructor = CGMethodCall(args, nativeName, True, self.descriptor, self.constructor) + constructorCall = f""" + call_default_constructor( + cx, + &args, + global, + PrototypeList::ID::{MakeNativeName(self.descriptor.name)}, + \"{ctorName}\", + CreateInterfaceObjects, + |cx, args, global, desired_proto| {{ + {constructor.define()} + }} + ) + """ + return CGList([CGGeneric(preamble), CGGeneric(constructorCall)]) class CGClassFinalizeHook(CGAbstractClassHook): diff --git a/components/script/dom/bindings/htmlconstructor.rs b/components/script/dom/bindings/constructor.rs index 56aedc04840..b9c29183b84 100644 --- a/components/script/dom/bindings/htmlconstructor.rs +++ b/components/script/dom/bindings/constructor.rs @@ -7,6 +7,7 @@ use std::ptr; use html5ever::interface::QualName; use html5ever::{local_name, namespace_url, ns, LocalName}; use js::conversions::ToJSValConvertible; +use js::gc::RootedGuard; use js::glue::{UnwrapObjectDynamic, UnwrapObjectStatic}; use js::jsapi::{CallArgs, CurrentGlobalOrNull, JSAutoRealm, JSObject}; use js::rust::wrappers::{JS_SetPrototype, JS_WrapObject}; @@ -40,7 +41,7 @@ use crate::dom::bindings::codegen::Bindings::{ }; use crate::dom::bindings::codegen::PrototypeList; use crate::dom::bindings::conversions::DerivedFrom; -use crate::dom::bindings::error::{throw_dom_exception, Error}; +use crate::dom::bindings::error::{throw_constructor_without_new, throw_dom_exception, Error}; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::interface::get_desired_proto; use crate::dom::bindings::reflector::DomObject; @@ -57,14 +58,14 @@ use crate::script_thread::ScriptThread; // https://html.spec.whatwg.org/multipage/#htmlconstructor unsafe fn html_constructor( cx: JSContext, - window: &Window, + global: &GlobalScope, call_args: &CallArgs, check_type: fn(&Element) -> bool, proto_id: PrototypeList::ID, creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray), ) -> Result<(), ()> { + let window = global.downcast::<Window>().unwrap(); let document = window.Document(); - let global = window.upcast::<GlobalScope>(); // Step 1 let registry = window.CustomElements(); @@ -377,10 +378,10 @@ pub fn push_new_element_queue() { ScriptThread::push_new_element_queue(); } -pub(crate) unsafe fn call_html_constructor<T: DerivedFrom<Element> + DomObject>( +pub unsafe fn call_html_constructor<T: DerivedFrom<Element> + DomObject>( cx: JSContext, args: &CallArgs, - global: &Window, + global: &GlobalScope, proto_id: PrototypeList::ID, creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray), ) -> bool { @@ -398,3 +399,26 @@ pub(crate) unsafe fn call_html_constructor<T: DerivedFrom<Element> + DomObject>( ) .is_ok() } + +pub unsafe fn call_default_constructor( + cx: JSContext, + args: &CallArgs, + global: DomRoot<GlobalScope>, + proto_id: PrototypeList::ID, + ctor_name: &str, + creator: unsafe fn(JSContext, HandleObject, *mut ProtoOrIfaceArray), + constructor: impl FnOnce(JSContext, &CallArgs, &GlobalScope, RootedGuard<*mut JSObject>) -> bool, +) -> bool { + if !args.is_constructing() { + throw_constructor_without_new(*cx, ctor_name); + return false; + } + + rooted!(in(*cx) let mut desired_proto = ptr::null_mut::<JSObject>()); + let proto_result = get_desired_proto(cx, args, proto_id, creator, desired_proto.handle_mut()); + if proto_result.is_err() { + return false; + } + + constructor(cx, args, &global, desired_proto) +} diff --git a/components/script/dom/bindings/import.rs b/components/script/dom/bindings/import.rs index 32b52cc9845..004696fb92c 100644 --- a/components/script/dom/bindings/import.rs +++ b/components/script/dom/bindings/import.rs @@ -103,6 +103,10 @@ pub mod module { pub use crate::dom::bindings::codegen::Bindings::EventTargetBinding::EventTarget_Binding; pub use crate::dom::bindings::codegen::{InterfaceObjectMap, PrototypeList, RegisterBindings}; pub use crate::dom::bindings::constant::{ConstantSpec, ConstantVal}; + pub use crate::dom::bindings::constructor::{ + call_default_constructor, call_html_constructor, pop_current_element_queue, + push_new_element_queue, + }; pub use crate::dom::bindings::conversions::{ is_array_like, jsid_to_string, native_from_handlevalue, native_from_object_static, IDLInterface, StringificationBehavior, ToJSValConvertible, DOM_OBJECT_SLOT, @@ -112,9 +116,6 @@ pub mod module { finalize_common, finalize_global, finalize_weak_referenceable, }; pub use crate::dom::bindings::guard::{Condition, Guard}; - pub use crate::dom::bindings::htmlconstructor::{ - pop_current_element_queue, push_new_element_queue, - }; pub use crate::dom::bindings::inheritance::Castable; pub use crate::dom::bindings::interface::{ create_callback_interface_object, create_global_object, create_interface_prototype_object, diff --git a/components/script/dom/bindings/mod.rs b/components/script/dom/bindings/mod.rs index 7d6d03d737a..69c327015b3 100644 --- a/components/script/dom/bindings/mod.rs +++ b/components/script/dom/bindings/mod.rs @@ -138,11 +138,11 @@ pub mod buffer_source; pub mod callback; pub mod cell; pub mod constant; +pub mod constructor; pub mod conversions; pub mod error; pub mod finalize; pub mod guard; -pub mod htmlconstructor; pub mod import; pub mod inheritance; pub mod interface; |