mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00: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);
|
||||
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):
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue