mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
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>
This commit is contained in:
parent
3eee02869a
commit
5ba8054b69
4 changed files with 65 additions and 40 deletions
|
@ -6228,17 +6228,12 @@ class CGClassConstructHook(CGAbstractExternMethod):
|
||||||
preamble = """let cx = SafeJSContext::from_ptr(cx);
|
preamble = """let cx = SafeJSContext::from_ptr(cx);
|
||||||
let args = CallArgs::from_vp(vp, argc);
|
let args = CallArgs::from_vp(vp, argc);
|
||||||
let global = GlobalScope::from_object(JS_CALLEE(*cx, vp).to_object());
|
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():
|
if self.constructor.isHTMLConstructor():
|
||||||
signatures = self.constructor.signatures()
|
signatures = self.constructor.signatures()
|
||||||
assert len(signatures) == 1
|
assert len(signatures) == 1
|
||||||
constructorCall = CGGeneric(
|
constructorCall = f"""
|
||||||
f"""
|
call_html_constructor::<dom::types::{self.descriptor.name}>(
|
||||||
dom::bindings::htmlconstructor::call_html_constructor::<dom::types::{self.descriptor.name}>(
|
|
||||||
cx,
|
cx,
|
||||||
&args,
|
&args,
|
||||||
&global,
|
&global,
|
||||||
|
@ -6246,34 +6241,39 @@ let global = DomRoot::downcast::<dom::types::{list(self.exposureSet)[0]}>(global
|
||||||
CreateInterfaceObjects,
|
CreateInterfaceObjects,
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
ctorName = GetConstructorNameForReporting(self.descriptor, self.constructor)
|
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
|
name = self.constructor.identifier.name
|
||||||
nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
|
nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
|
||||||
args = ["&global", "Some(desired_proto.handle())", "CanGc::note()"]
|
|
||||||
constructorCall = CGMethodCall(args, nativeName, True,
|
if len(self.exposureSet) == 1:
|
||||||
self.descriptor, self.constructor)
|
args = [
|
||||||
return CGList([CGGeneric(preamble), constructorCall])
|
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):
|
class CGClassFinalizeHook(CGAbstractClassHook):
|
||||||
|
|
|
@ -7,6 +7,7 @@ use std::ptr;
|
||||||
use html5ever::interface::QualName;
|
use html5ever::interface::QualName;
|
||||||
use html5ever::{local_name, namespace_url, ns, LocalName};
|
use html5ever::{local_name, namespace_url, ns, LocalName};
|
||||||
use js::conversions::ToJSValConvertible;
|
use js::conversions::ToJSValConvertible;
|
||||||
|
use js::gc::RootedGuard;
|
||||||
use js::glue::{UnwrapObjectDynamic, UnwrapObjectStatic};
|
use js::glue::{UnwrapObjectDynamic, UnwrapObjectStatic};
|
||||||
use js::jsapi::{CallArgs, CurrentGlobalOrNull, JSAutoRealm, JSObject};
|
use js::jsapi::{CallArgs, CurrentGlobalOrNull, JSAutoRealm, JSObject};
|
||||||
use js::rust::wrappers::{JS_SetPrototype, JS_WrapObject};
|
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::codegen::PrototypeList;
|
||||||
use crate::dom::bindings::conversions::DerivedFrom;
|
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::inheritance::Castable;
|
||||||
use crate::dom::bindings::interface::get_desired_proto;
|
use crate::dom::bindings::interface::get_desired_proto;
|
||||||
use crate::dom::bindings::reflector::DomObject;
|
use crate::dom::bindings::reflector::DomObject;
|
||||||
|
@ -57,14 +58,14 @@ use crate::script_thread::ScriptThread;
|
||||||
// https://html.spec.whatwg.org/multipage/#htmlconstructor
|
// https://html.spec.whatwg.org/multipage/#htmlconstructor
|
||||||
unsafe fn html_constructor(
|
unsafe fn html_constructor(
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
window: &Window,
|
global: &GlobalScope,
|
||||||
call_args: &CallArgs,
|
call_args: &CallArgs,
|
||||||
check_type: fn(&Element) -> bool,
|
check_type: fn(&Element) -> bool,
|
||||||
proto_id: PrototypeList::ID,
|
proto_id: PrototypeList::ID,
|
||||||
creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
|
creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
|
let window = global.downcast::<Window>().unwrap();
|
||||||
let document = window.Document();
|
let document = window.Document();
|
||||||
let global = window.upcast::<GlobalScope>();
|
|
||||||
|
|
||||||
// Step 1
|
// Step 1
|
||||||
let registry = window.CustomElements();
|
let registry = window.CustomElements();
|
||||||
|
@ -377,10 +378,10 @@ pub fn push_new_element_queue() {
|
||||||
ScriptThread::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,
|
cx: JSContext,
|
||||||
args: &CallArgs,
|
args: &CallArgs,
|
||||||
global: &Window,
|
global: &GlobalScope,
|
||||||
proto_id: PrototypeList::ID,
|
proto_id: PrototypeList::ID,
|
||||||
creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
|
creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
@ -398,3 +399,26 @@ pub(crate) unsafe fn call_html_constructor<T: DerivedFrom<Element> + DomObject>(
|
||||||
)
|
)
|
||||||
.is_ok()
|
.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)
|
||||||
|
}
|
|
@ -103,6 +103,10 @@ pub mod module {
|
||||||
pub use crate::dom::bindings::codegen::Bindings::EventTargetBinding::EventTarget_Binding;
|
pub use crate::dom::bindings::codegen::Bindings::EventTargetBinding::EventTarget_Binding;
|
||||||
pub use crate::dom::bindings::codegen::{InterfaceObjectMap, PrototypeList, RegisterBindings};
|
pub use crate::dom::bindings::codegen::{InterfaceObjectMap, PrototypeList, RegisterBindings};
|
||||||
pub use crate::dom::bindings::constant::{ConstantSpec, ConstantVal};
|
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::{
|
pub use crate::dom::bindings::conversions::{
|
||||||
is_array_like, jsid_to_string, native_from_handlevalue, native_from_object_static,
|
is_array_like, jsid_to_string, native_from_handlevalue, native_from_object_static,
|
||||||
IDLInterface, StringificationBehavior, ToJSValConvertible, DOM_OBJECT_SLOT,
|
IDLInterface, StringificationBehavior, ToJSValConvertible, DOM_OBJECT_SLOT,
|
||||||
|
@ -112,9 +116,6 @@ pub mod module {
|
||||||
finalize_common, finalize_global, finalize_weak_referenceable,
|
finalize_common, finalize_global, finalize_weak_referenceable,
|
||||||
};
|
};
|
||||||
pub use crate::dom::bindings::guard::{Condition, Guard};
|
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::inheritance::Castable;
|
||||||
pub use crate::dom::bindings::interface::{
|
pub use crate::dom::bindings::interface::{
|
||||||
create_callback_interface_object, create_global_object, create_interface_prototype_object,
|
create_callback_interface_object, create_global_object, create_interface_prototype_object,
|
||||||
|
|
|
@ -138,11 +138,11 @@ pub mod buffer_source;
|
||||||
pub mod callback;
|
pub mod callback;
|
||||||
pub mod cell;
|
pub mod cell;
|
||||||
pub mod constant;
|
pub mod constant;
|
||||||
|
pub mod constructor;
|
||||||
pub mod conversions;
|
pub mod conversions;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod finalize;
|
pub mod finalize;
|
||||||
pub mod guard;
|
pub mod guard;
|
||||||
pub mod htmlconstructor;
|
|
||||||
pub mod import;
|
pub mod import;
|
||||||
pub mod inheritance;
|
pub mod inheritance;
|
||||||
pub mod interface;
|
pub mod interface;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue