aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGae24 <96017547+Gae24@users.noreply.github.com>2024-10-09 14:33:44 +0200
committerGitHub <noreply@github.com>2024-10-09 12:33:44 +0000
commit5ba8054b69e3f9867cecde89a18bf0f134d6f276 (patch)
tree42d933f7907b8dff5c4b4d4fd3922b4bf8784d08
parent3eee02869a8a9673a52d807c737e4c203d32b1b7 (diff)
downloadservo-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.py62
-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.rs7
-rw-r--r--components/script/dom/bindings/mod.rs2
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;