mirror of
https://github.com/servo/servo.git
synced 2025-06-11 01:50:10 +00:00
script: Refer to DOM interfaces with generic types in generated bindings. (#35457)
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
14db055d46
commit
1192ae32b0
20 changed files with 627 additions and 167 deletions
|
@ -397,14 +397,14 @@ pub(crate) unsafe fn call_html_constructor<T: DerivedFrom<Element> + DomObject>(
|
|||
.is_ok()
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn call_default_constructor(
|
||||
pub(crate) unsafe fn call_default_constructor<D: crate::DomTypes>(
|
||||
cx: JSContext,
|
||||
args: &CallArgs,
|
||||
global: &GlobalScope,
|
||||
global: &D::GlobalScope,
|
||||
proto_id: PrototypeList::ID,
|
||||
ctor_name: &str,
|
||||
creator: unsafe fn(JSContext, HandleObject, *mut ProtoOrIfaceArray),
|
||||
constructor: impl FnOnce(JSContext, &CallArgs, &GlobalScope, HandleObject) -> bool,
|
||||
constructor: impl FnOnce(JSContext, &CallArgs, &D::GlobalScope, HandleObject) -> bool,
|
||||
) -> bool {
|
||||
if !args.is_constructing() {
|
||||
throw_constructor_without_new(cx, ctor_name);
|
||||
|
|
|
@ -58,7 +58,6 @@ use crate::dom::htmlcollection::HTMLCollection;
|
|||
use crate::dom::htmlformcontrolscollection::HTMLFormControlsCollection;
|
||||
use crate::dom::htmloptionscollection::HTMLOptionsCollection;
|
||||
use crate::dom::nodelist::NodeList;
|
||||
use crate::dom::windowproxy::WindowProxy;
|
||||
|
||||
impl<T: Float + ToJSValConvertible> ToJSValConvertible for Finite<T> {
|
||||
#[inline]
|
||||
|
@ -425,10 +424,10 @@ where
|
|||
|
||||
/// Get a `DomRoot<T>` for a WindowProxy accessible from a `HandleValue`.
|
||||
/// Caller is responsible for throwing a JS exception if needed in case of error.
|
||||
pub(crate) unsafe fn windowproxy_from_handlevalue(
|
||||
pub(crate) unsafe fn windowproxy_from_handlevalue<D: crate::DomTypes>(
|
||||
v: HandleValue,
|
||||
_cx: *mut JSContext,
|
||||
) -> Result<DomRoot<WindowProxy>, ()> {
|
||||
) -> Result<DomRoot<D::WindowProxy>, ()> {
|
||||
if !v.get().is_object() {
|
||||
return Err(());
|
||||
}
|
||||
|
@ -438,6 +437,6 @@ pub(crate) unsafe fn windowproxy_from_handlevalue(
|
|||
}
|
||||
let mut value = UndefinedValue();
|
||||
GetProxyReservedSlot(object, 0, &mut value);
|
||||
let ptr = value.to_private() as *const WindowProxy;
|
||||
let ptr = value.to_private() as *const D::WindowProxy;
|
||||
Ok(DomRoot::from_ref(&*ptr))
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ pub(crate) mod base {
|
|||
ChannelInterpretationValues,
|
||||
};
|
||||
pub(crate) use crate::dom::bindings::codegen::DomTypes::DomTypes;
|
||||
pub(crate) use crate::dom::bindings::codegen::UnionTypes;
|
||||
pub(crate) use crate::dom::bindings::codegen::{GenericUnionTypes, UnionTypes};
|
||||
pub(crate) use crate::dom::bindings::conversions::{
|
||||
root_from_handlevalue, ConversionBehavior, ConversionResult, FromJSValConvertible,
|
||||
StringificationBehavior, ToJSValConvertible,
|
||||
|
@ -35,14 +35,15 @@ pub(crate) mod base {
|
|||
pub(crate) use crate::dom::bindings::error::{throw_dom_exception, Fallible};
|
||||
pub(crate) use crate::dom::bindings::num::Finite;
|
||||
pub(crate) use crate::dom::bindings::proxyhandler::CrossOriginProperties;
|
||||
pub(crate) use crate::dom::bindings::reflector::{DomGlobal, DomObject};
|
||||
pub(crate) use crate::dom::bindings::reflector::{DomGlobalGeneric, DomObject};
|
||||
pub(crate) use crate::dom::bindings::root::DomRoot;
|
||||
pub(crate) use crate::dom::bindings::str::{ByteString, DOMString, USVString};
|
||||
pub(crate) use crate::dom::bindings::trace::RootedTraceableBox;
|
||||
pub(crate) use crate::dom::bindings::utils::{
|
||||
get_dictionary_property, set_dictionary_property, ThreadUnsafeOnceLock,
|
||||
get_dictionary_property, set_dictionary_property, DomHelpers, ThreadUnsafeOnceLock,
|
||||
};
|
||||
pub(crate) use crate::dom::globalscope::GlobalScope;
|
||||
pub(crate) use crate::dom::globalscope::{GlobalScope, GlobalScopeHelpers};
|
||||
pub(crate) use crate::dom::promise::PromiseHelpers;
|
||||
pub(crate) use crate::script_runtime::JSContext as SafeJSContext;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//! Implementation of `iterable<...>` and `iterable<..., ...>` WebIDL declarations.
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
use std::ptr::NonNull;
|
||||
|
||||
|
@ -15,18 +16,20 @@ use js::conversions::ToJSValConvertible;
|
|||
use js::jsapi::{Heap, JSObject};
|
||||
use js::jsval::UndefinedValue;
|
||||
use js::rust::{HandleObject, HandleValue, MutableHandleObject};
|
||||
use script_bindings::conversions::IDLInterface;
|
||||
use script_bindings::utils::DOMClass;
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::IterableIteratorBinding::{
|
||||
IterableKeyAndValueResult, IterableKeyOrValueResult,
|
||||
};
|
||||
use crate::dom::bindings::error::Fallible;
|
||||
use crate::dom::bindings::reflector::{
|
||||
reflect_dom_object, DomGlobal, DomObjectIteratorWrap, DomObjectWrap, Reflector,
|
||||
reflect_dom_object, DomGlobalGeneric, DomObjectIteratorWrap, DomObjectWrap, Reflector,
|
||||
};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot, Root};
|
||||
use crate::dom::bindings::trace::{JSTraceable, RootedTraceableBox};
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::bindings::trace::{JSTraceable, NoTrace, RootedTraceableBox};
|
||||
use crate::script_runtime::{CanGc, JSContext};
|
||||
use crate::DomTypes;
|
||||
|
||||
/// The values that an iterator will iterate over.
|
||||
#[derive(JSTraceable, MallocSizeOf)]
|
||||
|
@ -55,14 +58,41 @@ pub(crate) trait Iterable {
|
|||
|
||||
/// An iterator over the iterable entries of a given DOM interface.
|
||||
#[dom_struct]
|
||||
pub(crate) struct IterableIterator<T: DomObjectIteratorWrap + JSTraceable + Iterable> {
|
||||
pub(crate) struct IterableIterator<
|
||||
D: DomTypes,
|
||||
T: DomObjectIteratorWrap<D> + JSTraceable + Iterable + DomGlobalGeneric<D>,
|
||||
> {
|
||||
reflector: Reflector,
|
||||
iterable: Dom<T>,
|
||||
type_: IteratorType,
|
||||
index: Cell<u32>,
|
||||
_marker: NoTrace<PhantomData<D>>,
|
||||
}
|
||||
|
||||
impl<T: DomObjectIteratorWrap + JSTraceable + Iterable> IterableIterator<T> {
|
||||
impl<D: DomTypes, T: DomObjectIteratorWrap<D> + JSTraceable + Iterable> IterableIterator<D, T> {
|
||||
pub fn global(&self) -> DomRoot<D::GlobalScope> {
|
||||
<Self as DomGlobalGeneric<D>>::global(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<
|
||||
D: DomTypes,
|
||||
T: DomObjectIteratorWrap<D>
|
||||
+ JSTraceable
|
||||
+ Iterable
|
||||
+ DomGlobalGeneric<D>
|
||||
+ IDLInterface
|
||||
+ IteratorDerives,
|
||||
> IDLInterface for IterableIterator<D, T>
|
||||
{
|
||||
fn derives(class: &'static DOMClass) -> bool {
|
||||
<T as IteratorDerives>::derives(class)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DomTypes, T: DomObjectIteratorWrap<D> + JSTraceable + Iterable + DomGlobalGeneric<D>>
|
||||
IterableIterator<D, T>
|
||||
{
|
||||
/// Create a new iterator instance for the provided iterable DOM interface.
|
||||
pub(crate) fn new(iterable: &T, type_: IteratorType) -> DomRoot<Self> {
|
||||
let iterator = Box::new(IterableIterator {
|
||||
|
@ -70,6 +100,7 @@ impl<T: DomObjectIteratorWrap + JSTraceable + Iterable> IterableIterator<T> {
|
|||
type_,
|
||||
iterable: Dom::from_ref(iterable),
|
||||
index: Cell::new(0),
|
||||
_marker: NoTrace(PhantomData),
|
||||
});
|
||||
reflect_dom_object(iterator, &*iterable.global(), CanGc::note())
|
||||
}
|
||||
|
@ -119,16 +150,26 @@ impl<T: DomObjectIteratorWrap + JSTraceable + Iterable> IterableIterator<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: DomObjectIteratorWrap + JSTraceable + Iterable> DomObjectWrap for IterableIterator<T> {
|
||||
impl<D: DomTypes, T: DomObjectIteratorWrap<D> + JSTraceable + Iterable + DomGlobalGeneric<D>>
|
||||
DomObjectWrap<D> for IterableIterator<D, T>
|
||||
{
|
||||
const WRAP: unsafe fn(
|
||||
JSContext,
|
||||
&GlobalScope,
|
||||
&D::GlobalScope,
|
||||
Option<HandleObject>,
|
||||
Box<Self>,
|
||||
CanGc,
|
||||
) -> Root<Dom<Self>> = T::ITER_WRAP;
|
||||
}
|
||||
|
||||
/// A version of the [IDLInterface] trait that is specific to types that have
|
||||
/// iterators defined for them. This allows the `script` crate to define the
|
||||
/// derives check for the concrete interface type, while the [IteratableIterator]
|
||||
/// type defined in this module can be parameterized over an unknown generic.
|
||||
pub trait IteratorDerives {
|
||||
fn derives(class: &'static DOMClass) -> bool;
|
||||
}
|
||||
|
||||
fn dict_return(
|
||||
cx: JSContext,
|
||||
mut result: MutableHandleObject,
|
||||
|
|
|
@ -179,9 +179,16 @@ pub(crate) mod codegen {
|
|||
include!(concat!(env!("BINDINGS_OUT_DIR"), "/DomTypes.rs"));
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub(crate) mod Bindings {
|
||||
pub(crate) mod GenericBindings {
|
||||
include!(concat!(env!("BINDINGS_OUT_DIR"), "/Bindings/mod.rs"));
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub(crate) mod Bindings {
|
||||
include!(concat!(
|
||||
env!("BINDINGS_OUT_DIR"),
|
||||
"/ConcreteBindings/mod.rs"
|
||||
));
|
||||
}
|
||||
pub(crate) mod InterfaceObjectMap {
|
||||
include!(concat!(env!("BINDINGS_OUT_DIR"), "/InterfaceObjectMap.rs"));
|
||||
pub(crate) use script_bindings::codegen::Globals::Globals;
|
||||
|
@ -206,6 +213,10 @@ pub(crate) mod codegen {
|
|||
clippy::upper_case_acronyms,
|
||||
clippy::enum_variant_names
|
||||
)]
|
||||
pub(crate) mod GenericUnionTypes {
|
||||
include!(concat!(env!("BINDINGS_OUT_DIR"), "/GenericUnionTypes.rs"));
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub(crate) mod UnionTypes {
|
||||
include!(concat!(env!("BINDINGS_OUT_DIR"), "/UnionTypes.rs"));
|
||||
}
|
||||
|
|
|
@ -10,59 +10,74 @@ use crate::dom::bindings::conversions::DerivedFrom;
|
|||
use crate::dom::bindings::iterable::{Iterable, IterableIterator};
|
||||
use crate::dom::bindings::root::{Dom, DomRoot, Root};
|
||||
use crate::dom::bindings::trace::JSTraceable;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::globalscope::{GlobalScope, GlobalScopeHelpers};
|
||||
use crate::realms::AlreadyInRealm;
|
||||
use crate::script_runtime::{CanGc, JSContext};
|
||||
use crate::DomTypes;
|
||||
|
||||
/// Create the reflector for a new DOM object and yield ownership to the
|
||||
/// reflector.
|
||||
pub(crate) fn reflect_dom_object<T, U>(obj: Box<T>, global: &U, can_gc: CanGc) -> DomRoot<T>
|
||||
pub(crate) fn reflect_dom_object<D, T, U>(obj: Box<T>, global: &U, can_gc: CanGc) -> DomRoot<T>
|
||||
where
|
||||
T: DomObject + DomObjectWrap,
|
||||
U: DerivedFrom<GlobalScope>,
|
||||
D: DomTypes,
|
||||
T: DomObject + DomObjectWrap<D>,
|
||||
U: DerivedFrom<D::GlobalScope>,
|
||||
{
|
||||
let global_scope = global.upcast();
|
||||
unsafe { T::WRAP(GlobalScope::get_cx(), global_scope, None, obj, can_gc) }
|
||||
unsafe { T::WRAP(D::GlobalScope::get_cx(), global_scope, None, obj, can_gc) }
|
||||
}
|
||||
|
||||
pub(crate) fn reflect_dom_object_with_proto<T, U>(
|
||||
pub(crate) fn reflect_dom_object_with_proto<D, T, U>(
|
||||
obj: Box<T>,
|
||||
global: &U,
|
||||
proto: Option<HandleObject>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<T>
|
||||
where
|
||||
T: DomObject + DomObjectWrap,
|
||||
U: DerivedFrom<GlobalScope>,
|
||||
D: DomTypes,
|
||||
T: DomObject + DomObjectWrap<D>,
|
||||
U: DerivedFrom<D::GlobalScope>,
|
||||
{
|
||||
let global_scope = global.upcast();
|
||||
unsafe { T::WRAP(GlobalScope::get_cx(), global_scope, proto, obj, can_gc) }
|
||||
unsafe { T::WRAP(D::GlobalScope::get_cx(), global_scope, proto, obj, can_gc) }
|
||||
}
|
||||
|
||||
pub trait DomGlobal: DomObject {
|
||||
pub(crate) trait DomGlobalGeneric<D: DomTypes>: DomObject {
|
||||
/// Returns the [`GlobalScope`] of the realm that the [`DomObject`] was created in. If this
|
||||
/// object is a `Node`, this will be different from it's owning `Document` if adopted by. For
|
||||
/// `Node`s it's almost always better to use `NodeTraits::owning_global`.
|
||||
fn global(&self) -> DomRoot<GlobalScope>
|
||||
fn global(&self) -> DomRoot<D::GlobalScope>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let realm = AlreadyInRealm::assert_for_cx(GlobalScope::get_cx());
|
||||
GlobalScope::from_reflector(self, &realm)
|
||||
let realm = AlreadyInRealm::assert_for_cx(D::GlobalScope::get_cx());
|
||||
D::GlobalScope::from_reflector(self, &realm)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: DomObject> DomGlobal for T {}
|
||||
impl<D: DomTypes, T: DomObject> DomGlobalGeneric<D> for T {}
|
||||
|
||||
pub(crate) trait DomGlobal {
|
||||
fn global(&self) -> DomRoot<GlobalScope>;
|
||||
}
|
||||
|
||||
impl<T: DomGlobalGeneric<crate::DomTypeHolder>> DomGlobal for T {
|
||||
fn global(&self) -> DomRoot<GlobalScope> {
|
||||
<Self as DomGlobalGeneric<crate::DomTypeHolder>>::global(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use script_bindings::reflector::{DomObject, MutDomObject, Reflector};
|
||||
|
||||
/// A trait to provide a function pointer to wrap function for DOM objects.
|
||||
pub(crate) trait DomObjectWrap: Sized + DomObject {
|
||||
pub(crate) trait DomObjectWrap<D: DomTypes>:
|
||||
Sized + DomObject + DomGlobalGeneric<D>
|
||||
{
|
||||
/// Function pointer to the general wrap function type
|
||||
#[allow(clippy::type_complexity)]
|
||||
const WRAP: unsafe fn(
|
||||
JSContext,
|
||||
&GlobalScope,
|
||||
&D::GlobalScope,
|
||||
Option<HandleObject>,
|
||||
Box<Self>,
|
||||
CanGc,
|
||||
|
@ -71,14 +86,16 @@ pub(crate) trait DomObjectWrap: Sized + DomObject {
|
|||
|
||||
/// A trait to provide a function pointer to wrap function for
|
||||
/// DOM iterator interfaces.
|
||||
pub(crate) trait DomObjectIteratorWrap: DomObjectWrap + JSTraceable + Iterable {
|
||||
pub(crate) trait DomObjectIteratorWrap<D: DomTypes>:
|
||||
DomObjectWrap<D> + JSTraceable + Iterable
|
||||
{
|
||||
/// Function pointer to the wrap function for `IterableIterator<T>`
|
||||
#[allow(clippy::type_complexity)]
|
||||
const ITER_WRAP: unsafe fn(
|
||||
JSContext,
|
||||
&GlobalScope,
|
||||
&D::GlobalScope,
|
||||
Option<HandleObject>,
|
||||
Box<IterableIterator<Self>>,
|
||||
Box<IterableIterator<D, Self>>,
|
||||
CanGc,
|
||||
) -> Root<Dom<IterableIterator<Self>>>;
|
||||
) -> Root<Dom<IterableIterator<D, Self>>>;
|
||||
}
|
||||
|
|
|
@ -37,15 +37,18 @@ use js::rust::{
|
|||
use js::JS_CALLEE;
|
||||
|
||||
use crate::dom::bindings::codegen::InterfaceObjectMap;
|
||||
use crate::dom::bindings::codegen::PrototypeList::PROTO_OR_IFACE_LENGTH;
|
||||
use crate::dom::bindings::codegen::PrototypeList::{self, PROTO_OR_IFACE_LENGTH};
|
||||
use crate::dom::bindings::constructor::call_html_constructor;
|
||||
use crate::dom::bindings::conversions::{
|
||||
jsstring_to_str, private_from_proto_check, PrototypeCheck,
|
||||
jsstring_to_str, private_from_proto_check, DerivedFrom, PrototypeCheck,
|
||||
};
|
||||
use crate::dom::bindings::error::throw_invalid_this;
|
||||
use crate::dom::bindings::error::{throw_dom_exception, throw_invalid_this, Error};
|
||||
use crate::dom::bindings::reflector::DomObject;
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::bindings::trace::trace_object;
|
||||
use crate::dom::windowproxy::WindowProxyHandler;
|
||||
use crate::script_runtime::JSContext as SafeJSContext;
|
||||
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
|
||||
use crate::DomTypes;
|
||||
|
||||
/// A OnceLock wrapping a type that is not considered threadsafe by the Rust compiler, but
|
||||
/// will be used in a threadsafe manner (it will not be mutated, after being initialized).
|
||||
|
@ -660,3 +663,40 @@ pub(crate) unsafe fn exception_to_promise(cx: *mut JSContext, rval: RawMutableHa
|
|||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// Operations that must be invoked from the generated bindings.
|
||||
pub(crate) trait DomHelpers<D: DomTypes> {
|
||||
fn throw_dom_exception(cx: SafeJSContext, global: &D::GlobalScope, result: Error);
|
||||
|
||||
unsafe fn call_html_constructor<T: DerivedFrom<D::Element> + DomObject>(
|
||||
cx: SafeJSContext,
|
||||
args: &CallArgs,
|
||||
global: &D::GlobalScope,
|
||||
proto_id: crate::dom::bindings::codegen::PrototypeList::ID,
|
||||
creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
|
||||
can_gc: CanGc,
|
||||
) -> bool;
|
||||
}
|
||||
|
||||
impl DomHelpers<crate::DomTypeHolder> for crate::DomTypeHolder {
|
||||
fn throw_dom_exception(
|
||||
cx: SafeJSContext,
|
||||
global: &<crate::DomTypeHolder as DomTypes>::GlobalScope,
|
||||
result: Error,
|
||||
) {
|
||||
throw_dom_exception(cx, global, result)
|
||||
}
|
||||
|
||||
unsafe fn call_html_constructor<
|
||||
T: DerivedFrom<<crate::DomTypeHolder as DomTypes>::Element> + DomObject,
|
||||
>(
|
||||
cx: SafeJSContext,
|
||||
args: &CallArgs,
|
||||
global: &<crate::DomTypeHolder as DomTypes>::GlobalScope,
|
||||
proto_id: PrototypeList::ID,
|
||||
creator: unsafe fn(SafeJSContext, HandleObject, *mut ProtoOrIfaceArray),
|
||||
can_gc: CanGc,
|
||||
) -> bool {
|
||||
call_html_constructor::<T>(cx, args, global, proto_id, creator, can_gc)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,9 @@ use super::bindings::codegen::Bindings::FunctionBinding::Function;
|
|||
use super::bindings::codegen::Bindings::QueuingStrategyBinding::{
|
||||
ByteLengthQueuingStrategyMethods, QueuingStrategyInit,
|
||||
};
|
||||
use super::bindings::import::module::{DomGlobal, DomRoot, Fallible, Reflector};
|
||||
use super::bindings::reflector::reflect_dom_object_with_proto;
|
||||
use super::bindings::error::Fallible;
|
||||
use super::bindings::reflector::{reflect_dom_object_with_proto, DomGlobal, Reflector};
|
||||
use super::bindings::root::DomRoot;
|
||||
use super::types::GlobalScope;
|
||||
use crate::dom::bindings::import::module::get_dictionary_property;
|
||||
use crate::native_fn;
|
||||
|
|
|
@ -13,8 +13,9 @@ use super::bindings::codegen::Bindings::FunctionBinding::Function;
|
|||
use super::bindings::codegen::Bindings::QueuingStrategyBinding::{
|
||||
CountQueuingStrategyMethods, QueuingStrategy, QueuingStrategyInit, QueuingStrategySize,
|
||||
};
|
||||
use super::bindings::import::module::{DomGlobal, DomRoot, Error, Fallible, Reflector};
|
||||
use super::bindings::reflector::reflect_dom_object_with_proto;
|
||||
use super::bindings::error::{Error, Fallible};
|
||||
use super::bindings::reflector::{reflect_dom_object_with_proto, DomGlobal, Reflector};
|
||||
use super::bindings::root::DomRoot;
|
||||
use super::types::GlobalScope;
|
||||
use crate::script_runtime::CanGc;
|
||||
use crate::{native_fn, native_raw_obj_fn};
|
||||
|
|
|
@ -3331,9 +3331,23 @@ unsafe fn global_scope_from_global_static(global: *mut JSObject) -> DomRoot<Glob
|
|||
root_from_object_static(global).unwrap()
|
||||
}
|
||||
|
||||
/// Operations that must be invoked from the generated bindings.
|
||||
#[allow(unsafe_code)]
|
||||
pub(crate) trait GlobalScopeHelpers<D: crate::DomTypes> {
|
||||
unsafe fn from_context(cx: *mut JSContext, realm: InRealm) -> DomRoot<D::GlobalScope>;
|
||||
fn get_cx() -> SafeJSContext;
|
||||
unsafe fn from_object(obj: *mut JSObject) -> DomRoot<D::GlobalScope>;
|
||||
fn from_reflector(
|
||||
reflector: &impl DomObject,
|
||||
realm: &AlreadyInRealm,
|
||||
) -> DomRoot<D::GlobalScope>;
|
||||
|
||||
unsafe fn from_object_maybe_wrapped(
|
||||
obj: *mut JSObject,
|
||||
cx: *mut JSContext,
|
||||
) -> DomRoot<D::GlobalScope>;
|
||||
|
||||
fn origin(&self) -> &MutableOrigin;
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
|
@ -3341,4 +3355,24 @@ impl GlobalScopeHelpers<crate::DomTypeHolder> for GlobalScope {
|
|||
unsafe fn from_context(cx: *mut JSContext, realm: InRealm) -> DomRoot<Self> {
|
||||
GlobalScope::from_context(cx, realm)
|
||||
}
|
||||
|
||||
fn get_cx() -> SafeJSContext {
|
||||
GlobalScope::get_cx()
|
||||
}
|
||||
|
||||
unsafe fn from_object(obj: *mut JSObject) -> DomRoot<Self> {
|
||||
GlobalScope::from_object(obj)
|
||||
}
|
||||
|
||||
fn from_reflector(reflector: &impl DomObject, realm: &AlreadyInRealm) -> DomRoot<Self> {
|
||||
GlobalScope::from_reflector(reflector, realm)
|
||||
}
|
||||
|
||||
unsafe fn from_object_maybe_wrapped(obj: *mut JSObject, cx: *mut JSContext) -> DomRoot<Self> {
|
||||
GlobalScope::from_object_maybe_wrapped(obj, cx)
|
||||
}
|
||||
|
||||
fn origin(&self) -> &MutableOrigin {
|
||||
GlobalScope::origin(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1925,7 +1925,7 @@ fn as_uintptr<T>(t: &T) -> uintptr_t {
|
|||
impl Node {
|
||||
pub(crate) fn reflect_node<N>(node: Box<N>, document: &Document, can_gc: CanGc) -> DomRoot<N>
|
||||
where
|
||||
N: DerivedFrom<Node> + DomObject + DomObjectWrap,
|
||||
N: DerivedFrom<Node> + DomObject + DomObjectWrap<crate::DomTypeHolder>,
|
||||
{
|
||||
Self::reflect_node_with_proto(node, document, None, can_gc)
|
||||
}
|
||||
|
@ -1937,7 +1937,7 @@ impl Node {
|
|||
can_gc: CanGc,
|
||||
) -> DomRoot<N>
|
||||
where
|
||||
N: DerivedFrom<Node> + DomObject + DomObjectWrap,
|
||||
N: DerivedFrom<Node> + DomObject + DomObjectWrap<crate::DomTypeHolder>,
|
||||
{
|
||||
let window = document.window();
|
||||
reflect_dom_object_with_proto(node, window, proto, can_gc)
|
||||
|
|
|
@ -384,3 +384,22 @@ fn create_native_handler_function(
|
|||
obj.get()
|
||||
}
|
||||
}
|
||||
|
||||
/// Operations that must be invoked from the generated bindings.
|
||||
pub(crate) trait PromiseHelpers<D: crate::DomTypes> {
|
||||
fn new_resolved(
|
||||
global: &D::GlobalScope,
|
||||
cx: SafeJSContext,
|
||||
value: impl ToJSValConvertible,
|
||||
) -> Rc<D::Promise>;
|
||||
}
|
||||
|
||||
impl PromiseHelpers<crate::DomTypeHolder> for Promise {
|
||||
fn new_resolved(
|
||||
global: &GlobalScope,
|
||||
cx: SafeJSContext,
|
||||
value: impl ToJSValConvertible,
|
||||
) -> Rc<Promise> {
|
||||
Promise::new_resolved(global, cx, value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ use crate::dom::bindings::codegen::Bindings::UnderlyingSourceBinding::Underlying
|
|||
use crate::dom::bindings::conversions::{ConversionBehavior, ConversionResult};
|
||||
use crate::dom::bindings::error::Error;
|
||||
use crate::dom::bindings::import::module::Fallible;
|
||||
use crate::dom::bindings::import::module::UnionTypes::ReadableStreamDefaultReaderOrReadableStreamBYOBReader as ReadableStreamReader;
|
||||
use crate::dom::bindings::codegen::UnionTypes::ReadableStreamDefaultReaderOrReadableStreamBYOBReader as ReadableStreamReader;
|
||||
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
|
||||
use crate::dom::bindings::root::{DomRoot, MutNullableDom, Dom};
|
||||
use crate::dom::bindings::trace::RootedTraceableBox;
|
||||
|
@ -666,13 +666,13 @@ impl ReadableStream {
|
|||
|
||||
// If stream.[[state]] is "closed", return a promise resolved with undefined.
|
||||
if self.is_closed() {
|
||||
let promise = Promise::new(&self.reflector_.global(), can_gc);
|
||||
let promise = Promise::new(&self.global(), can_gc);
|
||||
promise.resolve_native(&());
|
||||
return promise;
|
||||
}
|
||||
// If stream.[[state]] is "errored", return a promise rejected with stream.[[storedError]].
|
||||
if self.is_errored() {
|
||||
let promise = Promise::new(&self.reflector_.global(), can_gc);
|
||||
let promise = Promise::new(&self.global(), can_gc);
|
||||
unsafe {
|
||||
let cx = GlobalScope::get_cx();
|
||||
rooted!(in(*cx) let mut rval = UndefinedValue());
|
||||
|
@ -708,7 +708,7 @@ impl ReadableStream {
|
|||
|
||||
// Create a new promise,
|
||||
// and setup a handler in order to react to the fulfillment of sourceCancelPromise.
|
||||
let global = self.reflector_.global();
|
||||
let global = self.global();
|
||||
let result_promise = Promise::new(&global, can_gc);
|
||||
let fulfillment_handler = Box::new(SourceCancelPromiseFulfillmentHandler {
|
||||
result: result_promise.clone(),
|
||||
|
@ -784,7 +784,7 @@ impl ReadableStream {
|
|||
// Let reason2 be undefined.
|
||||
let reason_2 = Rc::new(Heap::boxed(UndefinedValue()));
|
||||
// Let cancelPromise be a new promise.
|
||||
let cancel_promise = Promise::new(&self.reflector_.global(), can_gc);
|
||||
let cancel_promise = Promise::new(&self.global(), can_gc);
|
||||
|
||||
let tee_source_1 = DefaultTeeUnderlyingSource::new(
|
||||
&reader,
|
||||
|
@ -824,7 +824,7 @@ impl ReadableStream {
|
|||
|
||||
// Set branch_1 to ! CreateReadableStream(startAlgorithm, pullAlgorithm, cancel1Algorithm).
|
||||
let branch_1 = create_readable_stream(
|
||||
&self.reflector_.global(),
|
||||
&self.global(),
|
||||
underlying_source_type_branch_1,
|
||||
QueuingStrategy::empty(),
|
||||
can_gc,
|
||||
|
@ -834,7 +834,7 @@ impl ReadableStream {
|
|||
|
||||
// Set branch_2 to ! CreateReadableStream(startAlgorithm, pullAlgorithm, cancel2Algorithm).
|
||||
let branch_2 = create_readable_stream(
|
||||
&self.reflector_.global(),
|
||||
&self.global(),
|
||||
underlying_source_type_branch_2,
|
||||
QueuingStrategy::empty(),
|
||||
can_gc,
|
||||
|
|
|
@ -19,7 +19,7 @@ use super::bindings::root::Dom;
|
|||
use crate::dom::bindings::buffer_source::create_buffer_source;
|
||||
use crate::dom::bindings::callback::ExceptionHandling;
|
||||
use crate::dom::bindings::codegen::Bindings::ReadableStreamDefaultControllerBinding::ReadableStreamDefaultControllerMethods;
|
||||
use crate::dom::bindings::import::module::UnionTypes::ReadableStreamDefaultControllerOrReadableByteStreamController as Controller;
|
||||
use crate::dom::bindings::codegen::UnionTypes::ReadableStreamDefaultControllerOrReadableByteStreamController as Controller;
|
||||
use crate::dom::bindings::import::module::{throw_dom_exception, Error, Fallible};
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object, DomGlobal, Reflector};
|
||||
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
||||
|
|
|
@ -374,7 +374,7 @@ impl ReadableStreamDefaultReaderMethods<crate::DomTypeHolder> for ReadableStream
|
|||
return Promise::new_rejected(&self.global(), cx, error.handle());
|
||||
}
|
||||
// Let promise be a new promise.
|
||||
let promise = Promise::new(&self.reflector_.global(), can_gc);
|
||||
let promise = Promise::new(&self.global(), can_gc);
|
||||
|
||||
// Let readRequest be a new read request with the following items:
|
||||
// chunk steps, given chunk
|
||||
|
|
|
@ -1069,14 +1069,15 @@ pub(crate) fn handle_get_property(
|
|||
property.handle_mut(),
|
||||
)
|
||||
} {
|
||||
Ok(_) => match unsafe {
|
||||
jsval_to_webdriver(*cx, &node.reflector().global(), property.handle())
|
||||
} {
|
||||
Ok(_) => {
|
||||
match unsafe { jsval_to_webdriver(*cx, &node.global(), property.handle()) }
|
||||
{
|
||||
Ok(property) => property,
|
||||
Err(_) => WebDriverJSValue::Undefined,
|
||||
}
|
||||
},
|
||||
Err(error) => {
|
||||
throw_dom_exception(cx, &node.reflector().global(), error);
|
||||
throw_dom_exception(cx, &node.global(), error);
|
||||
WebDriverJSValue::Undefined
|
||||
},
|
||||
}
|
||||
|
|
|
@ -414,6 +414,7 @@ DOMInterfaces = {
|
|||
|
||||
'Promise': {
|
||||
'spiderMonkeyInterface': True,
|
||||
'additionalTraits': ["crate::dom::promise::PromiseHelpers<Self>"]
|
||||
},
|
||||
|
||||
'Range': {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -209,10 +209,12 @@ class Descriptor(DescriptorProvider):
|
|||
# nativeType of the iterable interface. That way we can have a
|
||||
# templated implementation for all the duplicated iterator
|
||||
# functionality.
|
||||
prefix = "D::"
|
||||
if self.interface.isIteratorInterface():
|
||||
itrName = self.interface.iterableInterface.identifier.name
|
||||
itrDesc = self.getDescriptor(itrName)
|
||||
nativeTypeDefault = iteratorNativeType(itrDesc)
|
||||
prefix = ""
|
||||
|
||||
typeName = desc.get('nativeType', nativeTypeDefault)
|
||||
|
||||
|
@ -232,15 +234,15 @@ class Descriptor(DescriptorProvider):
|
|||
self.argumentType = "???"
|
||||
self.nativeType = ty
|
||||
else:
|
||||
self.returnType = "DomRoot<%s>" % typeName
|
||||
self.argumentType = "&%s" % typeName
|
||||
self.nativeType = "*const %s" % typeName
|
||||
self.returnType = "DomRoot<%s%s>" % (prefix, typeName)
|
||||
self.argumentType = "&%s%s" % (prefix, typeName)
|
||||
self.nativeType = "*const %s%s" % (prefix, typeName)
|
||||
if self.interface.isIteratorInterface():
|
||||
pathDefault = 'crate::dom::bindings::iterable::IterableIterator'
|
||||
else:
|
||||
pathDefault = 'crate::dom::types::%s' % MakeNativeName(typeName)
|
||||
|
||||
self.concreteType = typeName
|
||||
self.concreteType = "%s%s" % (prefix, typeName)
|
||||
self.register = desc.get('register', True)
|
||||
self.path = desc.get('path', pathDefault)
|
||||
self.inRealmMethods = [name for name in desc.get('inRealms', [])]
|
||||
|
@ -489,7 +491,7 @@ def getIdlFileName(object):
|
|||
|
||||
|
||||
def getModuleFromObject(object):
|
||||
return ('crate::dom::bindings::codegen::Bindings::' + getIdlFileName(object) + 'Binding')
|
||||
return ('crate::dom::bindings::codegen::GenericBindings::' + getIdlFileName(object) + 'Binding')
|
||||
|
||||
|
||||
def getTypesFromDescriptor(descriptor):
|
||||
|
@ -547,7 +549,7 @@ def iteratorNativeType(descriptor, infer=False):
|
|||
iterableDecl = descriptor.interface.maplikeOrSetlikeOrIterable
|
||||
assert (iterableDecl.isIterable() and iterableDecl.isPairIterator()) \
|
||||
or iterableDecl.isSetlike() or iterableDecl.isMaplike()
|
||||
res = "IterableIterator%s" % ("" if infer else '<%s>' % descriptor.interface.identifier.name)
|
||||
res = "IterableIterator%s" % ("" if infer else '<D, D::%s>' % descriptor.interface.identifier.name)
|
||||
# todo: this hack is telling us that something is still wrong in codegen
|
||||
if iterableDecl.isSetlike() or iterableDecl.isMaplike():
|
||||
res = f"crate::dom::bindings::iterable::{res}"
|
||||
|
|
|
@ -28,7 +28,7 @@ def main():
|
|||
|
||||
import WebIDL
|
||||
from Configuration import Configuration
|
||||
from CodegenRust import CGBindingRoot
|
||||
from CodegenRust import CGBindingRoot, CGConcreteBindingRoot
|
||||
|
||||
parser = WebIDL.Parser(make_dir(os.path.join(out_dir, "cache")))
|
||||
webidls = [name for name in os.listdir(webidls_dir) if name.endswith(".webidl")]
|
||||
|
@ -48,6 +48,7 @@ def main():
|
|||
parser_results = parser.finish()
|
||||
config = Configuration(config_file, parser_results)
|
||||
make_dir(os.path.join(out_dir, "Bindings"))
|
||||
make_dir(os.path.join(out_dir, "ConcreteBindings"))
|
||||
|
||||
for name, filename in [
|
||||
("PrototypeList", "PrototypeList.rs"),
|
||||
|
@ -59,7 +60,9 @@ def main():
|
|||
("InheritTypes", "InheritTypes.rs"),
|
||||
("ConcreteInheritTypes", "ConcreteInheritTypes.rs"),
|
||||
("Bindings", "Bindings/mod.rs"),
|
||||
("UnionTypes", "UnionTypes.rs"),
|
||||
("Bindings", "ConcreteBindings/mod.rs"),
|
||||
("UnionTypes", "GenericUnionTypes.rs"),
|
||||
("ConcreteUnionTypes", "UnionTypes.rs"),
|
||||
("DomTypes", "DomTypes.rs"),
|
||||
("DomTypeHolder", "DomTypeHolder.rs"),
|
||||
]:
|
||||
|
@ -74,6 +77,11 @@ def main():
|
|||
if module:
|
||||
with open(os.path.join(out_dir, prefix + ".rs"), "wb") as f:
|
||||
f.write(module.encode("utf-8"))
|
||||
prefix = "ConcreteBindings/%sBinding" % webidl[:-len(".webidl")]
|
||||
module = CGConcreteBindingRoot(config, prefix, filename).define()
|
||||
if module:
|
||||
with open(os.path.join(out_dir, prefix + ".rs"), "wb") as f:
|
||||
f.write(module.encode("utf-8"))
|
||||
|
||||
|
||||
def make_dir(path):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue