aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/js.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/js.rs')
-rw-r--r--components/script/dom/bindings/js.rs90
1 files changed, 33 insertions, 57 deletions
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs
index a6dc495fc04..e7f790fb1ab 100644
--- a/components/script/dom/bindings/js.rs
+++ b/components/script/dom/bindings/js.rs
@@ -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