Miscellaneous script splitting preparation changes (#36216)

* script: Move num module to script_bindings.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* script: Make JS reflector creation generic over DOM trait.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* script: Move bindings-specific lock to script_bindings.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* script: Move DOM proto array code to script_bindings.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* script: Move finalizer implementations to script_bindings.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* script: Move some error routines to script_bindings.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* script: Move some DOM interface conversion routines to script_bindings.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* script: Make is_array_like generic over DOM trait.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* script: Use generic interfaces for conditional exposure functions.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* script: Move a bunch of routines used by codegen to script_bindings.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* Formatting.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

* Fix clippy warnings.

Signed-off-by: Josh Matthews <josh@joshmatthews.net>

---------

Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Josh Matthews 2025-03-29 04:11:27 -04:00 committed by GitHub
parent 2c94110952
commit c30ad5a30e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
28 changed files with 836 additions and 691 deletions

View file

@ -35,6 +35,7 @@ use js::rust::{
use script_bindings::constant::{ConstantSpec, define_constants};
use servo_url::MutableOrigin;
use crate::DomTypes;
use crate::dom::bindings::codegen::InterfaceObjectMap::Globals;
use crate::dom::bindings::codegen::PrototypeList;
use crate::dom::bindings::conversions::{DOM_OBJECT_SLOT, get_dom_class};
@ -43,8 +44,6 @@ use crate::dom::bindings::principals::ServoJSPrincipals;
use crate::dom::bindings::utils::{
DOM_PROTOTYPE_SLOT, DOMJSClass, JSCLASS_DOM_GLOBAL, ProtoOrIfaceArray, get_proto_or_iface_array,
};
use crate::dom::globalscope::GlobalScope;
use crate::realms::{AlreadyInRealm, InRealm};
use crate::script_runtime::JSContext as SafeJSContext;
/// The class of a non-callback interface object.
@ -213,7 +212,7 @@ fn select_compartment(cx: SafeJSContext, options: &mut RealmOptions) {
}
/// Create and define the interface object of a callback interface.
pub(crate) fn create_callback_interface_object(
pub(crate) fn create_callback_interface_object<D: DomTypes>(
cx: SafeJSContext,
global: HandleObject,
constants: &[Guard<&[ConstantSpec]>],
@ -225,14 +224,14 @@ pub(crate) fn create_callback_interface_object(
rval.set(JS_NewObject(*cx, ptr::null()));
}
assert!(!rval.is_null());
define_guarded_constants(cx, rval.handle(), constants, global);
define_guarded_constants::<D>(cx, rval.handle(), constants, global);
define_name(cx, rval.handle(), name);
define_on_global_object(cx, global, name, rval.handle());
}
/// Create the interface prototype object of a non-callback interface.
#[allow(clippy::too_many_arguments)]
pub(crate) fn create_interface_prototype_object(
pub(crate) fn create_interface_prototype_object<D: DomTypes>(
cx: SafeJSContext,
global: HandleObject,
proto: HandleObject,
@ -243,7 +242,7 @@ pub(crate) fn create_interface_prototype_object(
unscopable_names: &[&CStr],
mut rval: MutableHandleObject,
) {
create_object(
create_object::<D>(
cx,
global,
proto,
@ -277,7 +276,7 @@ pub(crate) fn create_interface_prototype_object(
/// Create and define the interface object of a non-callback interface.
#[allow(clippy::too_many_arguments)]
pub(crate) fn create_noncallback_interface_object(
pub(crate) fn create_noncallback_interface_object<D: DomTypes>(
cx: SafeJSContext,
global: HandleObject,
proto: HandleObject,
@ -291,7 +290,7 @@ pub(crate) fn create_noncallback_interface_object(
legacy_window_alias_names: &[&CStr],
mut rval: MutableHandleObject,
) {
create_object(
create_object::<D>(
cx,
global,
proto,
@ -350,7 +349,7 @@ pub(crate) fn create_named_constructors(
/// Create a new object with a unique type.
#[allow(clippy::too_many_arguments)]
pub(crate) fn create_object(
pub(crate) fn create_object<D: DomTypes>(
cx: SafeJSContext,
global: HandleObject,
proto: HandleObject,
@ -364,34 +363,34 @@ pub(crate) fn create_object(
rval.set(JS_NewObjectWithGivenProto(*cx, class, proto));
}
assert!(!rval.is_null());
define_guarded_methods(cx, rval.handle(), methods, global);
define_guarded_properties(cx, rval.handle(), properties, global);
define_guarded_constants(cx, rval.handle(), constants, global);
define_guarded_methods::<D>(cx, rval.handle(), methods, global);
define_guarded_properties::<D>(cx, rval.handle(), properties, global);
define_guarded_constants::<D>(cx, rval.handle(), constants, global);
}
/// Conditionally define constants on an object.
pub(crate) fn define_guarded_constants(
pub(crate) fn define_guarded_constants<D: DomTypes>(
cx: SafeJSContext,
obj: HandleObject,
constants: &[Guard<&[ConstantSpec]>],
global: HandleObject,
) {
for guard in constants {
if let Some(specs) = guard.expose(cx, obj, global) {
if let Some(specs) = guard.expose::<D>(cx, obj, global) {
define_constants(cx, obj, specs);
}
}
}
/// Conditionally define methods on an object.
pub(crate) fn define_guarded_methods(
pub(crate) fn define_guarded_methods<D: DomTypes>(
cx: SafeJSContext,
obj: HandleObject,
methods: &[Guard<&'static [JSFunctionSpec]>],
global: HandleObject,
) {
for guard in methods {
if let Some(specs) = guard.expose(cx, obj, global) {
if let Some(specs) = guard.expose::<D>(cx, obj, global) {
unsafe {
define_methods(*cx, obj, specs).unwrap();
}
@ -400,14 +399,14 @@ pub(crate) fn define_guarded_methods(
}
/// Conditionally define properties on an object.
pub(crate) fn define_guarded_properties(
pub(crate) fn define_guarded_properties<D: DomTypes>(
cx: SafeJSContext,
obj: HandleObject,
properties: &[Guard<&'static [JSPropertySpec]>],
global: HandleObject,
) {
for guard in properties {
if let Some(specs) = guard.expose(cx, obj, global) {
if let Some(specs) = guard.expose::<D>(cx, obj, global) {
unsafe {
define_properties(*cx, obj, specs).unwrap();
}
@ -425,16 +424,6 @@ pub(crate) fn is_exposed_in(object: HandleObject, globals: Globals) -> bool {
}
}
/// The navigator.servo api is only exposed to about: pages except about:blank
pub(crate) fn is_servo_internal(cx: SafeJSContext, _object: HandleObject) -> bool {
unsafe {
let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
let global_scope = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
let url = global_scope.get_url();
url.scheme() == "about" && url.as_str() != "about:blank"
}
}
/// Define a property with a given name on the global object. Should be called
/// through the resolve hook.
pub(crate) fn define_on_global_object(