mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Uniformise root() methods
They now live in traits Rootable, OptionalOptionalRootable, OptionalRootable and ResultRootable.
This commit is contained in:
parent
d7987e43c9
commit
7197052c0d
71 changed files with 122 additions and 139 deletions
|
@ -4733,8 +4733,8 @@ class CGBindingRoot(CGThing):
|
|||
'dom::bindings::global::GlobalRef',
|
||||
'dom::bindings::global::global_object_for_js_object',
|
||||
'dom::bindings::js::{JS, JSRef, Root, RootedReference, Temporary, Unrooted}',
|
||||
'dom::bindings::js::{OptionalRootable, OptionalRootedRootable, ResultRootable}',
|
||||
'dom::bindings::js::{OptionalRootedReference, OptionalOptionalRootedRootable}',
|
||||
'dom::bindings::js::{OptionalOptionalRootable, OptionalRootable}',
|
||||
'dom::bindings::js::{OptionalRootedReference, ResultRootable, Rootable}',
|
||||
'dom::bindings::utils::{create_dom_global, do_create_interface_objects}',
|
||||
'dom::bindings::utils::ConstantSpec',
|
||||
'dom::bindings::utils::{DOMClass}',
|
||||
|
@ -5415,7 +5415,7 @@ class GlobalGenRoots():
|
|||
descriptors = config.getDescriptors(register=True, isCallback=False)
|
||||
allprotos = [CGGeneric("#![allow(unused_imports)]\n"),
|
||||
CGGeneric("use dom::types::*;\n"),
|
||||
CGGeneric("use dom::bindings::js::{JS, JSRef, LayoutJS, Temporary};\n"),
|
||||
CGGeneric("use dom::bindings::js::{JS, JSRef, LayoutJS, Rootable, Temporary};\n"),
|
||||
CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
|
||||
CGGeneric("use dom::bindings::utils::Reflectable;\n"),
|
||||
CGGeneric("use js::jsapi::JSTracer;\n\n"),
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
use dom::bindings::conversions::ToJSValConvertible;
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::Rootable;
|
||||
use dom::domexception::{DOMException, DOMErrorName};
|
||||
|
||||
use util::str::DOMString;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
//! code that works in workers as well as window scopes.
|
||||
|
||||
use dom::bindings::conversions::native_from_reflector_jsmanaged;
|
||||
use dom::bindings::js::{JS, JSRef, Root, Unrooted};
|
||||
use dom::bindings::js::{JS, JSRef, Rootable, Root, Unrooted};
|
||||
use dom::bindings::utils::{Reflectable, Reflector};
|
||||
use dom::workerglobalscope::{WorkerGlobalScope, WorkerGlobalScopeHelpers};
|
||||
use dom::window::{self, WindowHelpers};
|
||||
|
|
|
@ -31,17 +31,18 @@
|
|||
//! the self value will not be collected for the duration of the method call.
|
||||
//!
|
||||
//! Both `Temporary<T>` and `JS<T>` do not allow access to their inner value
|
||||
//! without explicitly creating a stack-based root via the `root` method. This
|
||||
//! returns a `Root<T>`, which causes the JS-owned value to be uncollectable
|
||||
//! for the duration of the `Root` object's lifetime. A `JSRef<T>` can be
|
||||
//! obtained from a `Root<T>` by calling the `r` method. These `JSRef<T>`
|
||||
//! values are not allowed to outlive their originating `Root<T>`, to ensure
|
||||
//! that all interactions with the enclosed value only occur when said value is
|
||||
//! uncollectable, and will cause static lifetime errors if misused.
|
||||
//! without explicitly creating a stack-based root via the `root` method
|
||||
//! through the `Rootable<T>` trait. This returns a `Root<T>`, which causes the
|
||||
//! JS-owned value to be uncollectable for the duration of the `Root` object's
|
||||
//! lifetime. A `JSRef<T>` can be obtained from a `Root<T>` by calling the `r`
|
||||
//! method. These `JSRef<T>` values are not allowed to outlive their
|
||||
//! originating `Root<T>`, to ensure that all interactions with the enclosed
|
||||
//! value only occur when said value is uncollectable, and will cause static
|
||||
//! lifetime errors if misused.
|
||||
//!
|
||||
//! Other miscellaneous helper traits:
|
||||
//!
|
||||
//! - `OptionalRootable` and `OptionalRootedRootable`: make rooting `Option`
|
||||
//! - `OptionalRootable` and `OptionalOptionalRootable`: make rooting `Option`
|
||||
//! values easy via a `root` method
|
||||
//! - `ResultRootable`: make rooting successful `Result` values easy
|
||||
//! - `TemporaryPushable`: allows mutating vectors of `JS<T>` with new elements
|
||||
|
@ -108,9 +109,11 @@ impl<T: Reflectable> Unrooted<T> {
|
|||
pub unsafe fn unsafe_get(&self) -> *const T {
|
||||
*self.ptr
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable> Rootable<T> for Unrooted<T> {
|
||||
/// Create a stack-bounded root for this value.
|
||||
pub fn root(self) -> Root<T> {
|
||||
fn root(&self) -> Root<T> {
|
||||
STACK_ROOTS.with(|ref collection| {
|
||||
let RootCollectionPtr(collection) = collection.get().unwrap();
|
||||
unsafe {
|
||||
|
@ -172,21 +175,18 @@ impl<T: Reflectable> Temporary<T> {
|
|||
Temporary::new(JS::from_rooted(root))
|
||||
}
|
||||
|
||||
/// Create a stack-bounded root for this value.
|
||||
pub fn root(&self) -> Root<T> {
|
||||
STACK_ROOTS.with(|ref collection| {
|
||||
let RootCollectionPtr(collection) = collection.get().unwrap();
|
||||
unsafe {
|
||||
Root::new(&*collection, self.inner.ptr)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
unsafe fn inner(&self) -> JS<T> {
|
||||
self.inner.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable> Rootable<T> for Temporary<T> {
|
||||
/// Create a stack-bounded root for this value.
|
||||
fn root(&self) -> Root<T> {
|
||||
self.inner.root()
|
||||
}
|
||||
}
|
||||
|
||||
/// A traced reference to a DOM object. Must only be used as a field in other
|
||||
/// DOM objects.
|
||||
#[must_root]
|
||||
|
@ -264,9 +264,9 @@ impl LayoutJS<Node> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable> JS<T> {
|
||||
impl<T: Reflectable> Rootable<T> for JS<T> {
|
||||
/// Root this JS-owned value to prevent its collection as garbage.
|
||||
pub fn root(&self) -> Root<T> {
|
||||
fn root(&self) -> Root<T> {
|
||||
STACK_ROOTS.with(|ref collection| {
|
||||
let RootCollectionPtr(collection) = collection.get().unwrap();
|
||||
unsafe {
|
||||
|
@ -475,12 +475,12 @@ impl<T: Reflectable> Assignable<T> for Temporary<T> {
|
|||
/// Root a rootable `Option` type (used for `Option<Temporary<T>>`)
|
||||
pub trait OptionalRootable<T> {
|
||||
/// Root the inner value, if it exists.
|
||||
fn root(self) -> Option<Root<T>>;
|
||||
fn root(&self) -> Option<Root<T>>;
|
||||
}
|
||||
|
||||
impl<T: Reflectable> OptionalRootable<T> for Option<Temporary<T>> {
|
||||
fn root(self) -> Option<Root<T>> {
|
||||
self.map(|inner| inner.root())
|
||||
impl<T: Reflectable, U: Rootable<T>> OptionalRootable<T> for Option<U> {
|
||||
fn root(&self) -> Option<Root<T>> {
|
||||
self.as_ref().map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -496,61 +496,37 @@ impl<'a, T: Reflectable> OptionalUnrootable<T> for Option<JSRef<'a, T>> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Root a rootable `Option` type (used for `Option<JS<T>>`)
|
||||
pub trait OptionalRootedRootable<T> {
|
||||
/// Root the inner value, if it exists.
|
||||
fn root(&self) -> Option<Root<T>>;
|
||||
}
|
||||
|
||||
impl<T: Reflectable> OptionalRootedRootable<T> for Option<JS<T>> {
|
||||
fn root(&self) -> Option<Root<T>> {
|
||||
self.as_ref().map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable> OptionalRootedRootable<T> for Option<Unrooted<T>> {
|
||||
fn root(&self) -> Option<Root<T>> {
|
||||
self.as_ref().map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
||||
/// Root a rootable `Option<Option>` type (used for `Option<Option<JS<T>>>`)
|
||||
pub trait OptionalOptionalRootedRootable<T> {
|
||||
pub trait OptionalOptionalRootable<T> {
|
||||
/// Root the inner value, if it exists.
|
||||
fn root(&self) -> Option<Option<Root<T>>>;
|
||||
}
|
||||
|
||||
impl<T: Reflectable> OptionalOptionalRootedRootable<T> for Option<Option<JS<T>>> {
|
||||
impl<T: Reflectable, U: OptionalRootable<T>> OptionalOptionalRootable<T> for Option<U> {
|
||||
fn root(&self) -> Option<Option<Root<T>>> {
|
||||
self.as_ref().map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable> OptionalOptionalRootedRootable<T> for Option<Option<Unrooted<T>>> {
|
||||
fn root(&self) -> Option<Option<Root<T>>> {
|
||||
self.as_ref().map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Root a rootable `Result` type (any of `Temporary<T>` or `JS<T>`)
|
||||
pub trait ResultRootable<T,U> {
|
||||
/// Root the inner value, if it exists.
|
||||
fn root(self) -> Result<Root<T>, U>;
|
||||
}
|
||||
|
||||
impl<T: Reflectable, U> ResultRootable<T, U> for Result<Temporary<T>, U> {
|
||||
impl<T: Reflectable, U, V: Rootable<T>> ResultRootable<T, U> for Result<V, U> {
|
||||
fn root(self) -> Result<Root<T>, U> {
|
||||
self.map(|inner| inner.root())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Reflectable, U> ResultRootable<T, U> for Result<JS<T>, U> {
|
||||
fn root(self) -> Result<Root<T>, U> {
|
||||
self.map(|inner| inner.root())
|
||||
}
|
||||
/// Root a rootable type.
|
||||
pub trait Rootable<T> {
|
||||
/// Root the value.
|
||||
fn root(&self) -> Root<T>;
|
||||
}
|
||||
|
||||
|
||||
/// Provides a facility to push unrooted values onto lists of rooted values.
|
||||
/// This is safe under the assumption that said lists are reachable via the GC
|
||||
/// graph, and therefore the new values are transitively rooted for the
|
||||
|
|
|
@ -9,7 +9,7 @@ use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH;
|
|||
use dom::bindings::conversions::{native_from_reflector_jsmanaged, is_dom_class};
|
||||
use dom::bindings::error::{Error, ErrorResult, Fallible, throw_type_error};
|
||||
use dom::bindings::global::GlobalRef;
|
||||
use dom::bindings::js::{Temporary, Root};
|
||||
use dom::bindings::js::{Temporary, Root, Rootable};
|
||||
use dom::browsercontext;
|
||||
use dom::window;
|
||||
use util::namespace;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue