aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/root.rs
diff options
context:
space:
mode:
authorAnthony Ramine <n.oxyde@gmail.com>2017-09-27 13:44:07 +0200
committerAnthony Ramine <n.oxyde@gmail.com>2017-09-27 13:44:07 +0200
commita6d01c92d9a8a8d67cd8164916c86bf1928098f8 (patch)
treea6f72636d2ad7230c16a5083780bd4df55ce7915 /components/script/dom/bindings/root.rs
parent0160aaeeea848f685ba090b4541646b0429a37e1 (diff)
downloadservo-a6d01c92d9a8a8d67cd8164916c86bf1928098f8.tar.gz
servo-a6d01c92d9a8a8d67cd8164916c86bf1928098f8.zip
Reorder things in dom::bindings::root
The type DomRoot<T> is now the first one defined in it.
Diffstat (limited to 'components/script/dom/bindings/root.rs')
-rw-r--r--components/script/dom/bindings/root.rs410
1 files changed, 205 insertions, 205 deletions
diff --git a/components/script/dom/bindings/root.rs b/components/script/dom/bindings/root.rs
index 251b17c3054..6f1dbcc2735 100644
--- a/components/script/dom/bindings/root.rs
+++ b/components/script/dom/bindings/root.rs
@@ -47,6 +47,211 @@ use std::ptr;
use std::rc::Rc;
use style::thread_state;
+/// A rooted reference to a DOM object.
+///
+/// The JS value is pinned for the duration of this object's lifetime; roots
+/// are additive, so this object's destruction will not invalidate other roots
+/// for the same JS value. `Root`s cannot outlive the associated
+/// `RootCollection` object.
+#[allow(unrooted_must_root)]
+#[allow_unrooted_interior]
+pub struct DomRoot<T: DomObject> {
+ /// Reference to rooted value that must not outlive this container
+ ptr: Dom<T>,
+ /// List that ensures correct dynamic root ordering
+ root_list: *const RootCollection,
+}
+
+impl<T: Castable> DomRoot<T> {
+ /// Cast a DOM object root upwards to one of the interfaces it derives from.
+ pub fn upcast<U>(root: DomRoot<T>) -> DomRoot<U>
+ where U: Castable,
+ T: DerivedFrom<U>
+ {
+ unsafe { mem::transmute(root) }
+ }
+
+ /// Cast a DOM object root downwards to one of the interfaces it might implement.
+ pub fn downcast<U>(root: DomRoot<T>) -> Option<DomRoot<U>>
+ where U: DerivedFrom<T>
+ {
+ if root.is::<U>() {
+ Some(unsafe { mem::transmute(root) })
+ } else {
+ None
+ }
+ }
+}
+
+impl<T: DomObject> DomRoot<T> {
+ /// Create a new stack-bounded root for the provided JS-owned value.
+ /// It cannot outlive its associated `RootCollection`, and it gives
+ /// out references which cannot outlive this new `Root`.
+ #[allow(unrooted_must_root)]
+ unsafe fn new(unrooted: Dom<T>) -> DomRoot<T> {
+ debug_assert!(thread_state::get().is_script());
+ STACK_ROOTS.with(|ref collection| {
+ let RootCollectionPtr(collection) = collection.get().unwrap();
+ (*collection).root(unrooted.reflector());
+ DomRoot {
+ ptr: unrooted,
+ root_list: collection,
+ }
+ })
+ }
+
+ /// Generate a new root from a reference
+ pub fn from_ref(unrooted: &T) -> DomRoot<T> {
+ unsafe { DomRoot::new(Dom::from_ref(unrooted)) }
+ }
+}
+
+impl<T: DomObject> Deref for DomRoot<T> {
+ type Target = T;
+ fn deref(&self) -> &T {
+ debug_assert!(thread_state::get().is_script());
+ &self.ptr
+ }
+}
+
+impl<T: DomObject + HeapSizeOf> HeapSizeOf for DomRoot<T> {
+ fn heap_size_of_children(&self) -> usize {
+ (**self).heap_size_of_children()
+ }
+}
+
+impl<T: DomObject> PartialEq for DomRoot<T> {
+ fn eq(&self, other: &Self) -> bool {
+ self.ptr == other.ptr
+ }
+}
+
+impl<T: DomObject> Clone for DomRoot<T> {
+ fn clone(&self) -> DomRoot<T> {
+ DomRoot::from_ref(&*self)
+ }
+}
+
+unsafe impl<T: DomObject> JSTraceable for DomRoot<T> {
+ unsafe fn trace(&self, _: *mut JSTracer) {
+ // Already traced.
+ }
+}
+
+impl<T: DomObject> Drop for DomRoot<T> {
+ fn drop(&mut self) {
+ unsafe {
+ (*self.root_list).unroot(self.reflector());
+ }
+ }
+}
+
+/// A rooting mechanism for reflectors on the stack.
+/// LIFO is not required.
+///
+/// See also [*Exact Stack Rooting - Storing a GCPointer on the CStack*]
+/// (https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting).
+pub struct RootCollection {
+ roots: UnsafeCell<Vec<*const Reflector>>,
+}
+
+/// A pointer to a RootCollection, for use in global variables.
+pub struct RootCollectionPtr(pub *const RootCollection);
+
+impl Copy for RootCollectionPtr {}
+impl Clone for RootCollectionPtr {
+ fn clone(&self) -> RootCollectionPtr {
+ *self
+ }
+}
+
+impl RootCollection {
+ /// Create an empty collection of roots
+ pub fn new() -> RootCollection {
+ debug_assert!(thread_state::get().is_script());
+ RootCollection {
+ roots: UnsafeCell::new(vec![]),
+ }
+ }
+
+ /// Start tracking a stack-based root
+ unsafe fn root(&self, untracked_reflector: *const Reflector) {
+ debug_assert!(thread_state::get().is_script());
+ let roots = &mut *self.roots.get();
+ roots.push(untracked_reflector);
+ assert!(!(*untracked_reflector).get_jsobject().is_null())
+ }
+
+ /// Stop tracking a stack-based reflector, asserting if it isn't found.
+ unsafe fn unroot(&self, tracked_reflector: *const Reflector) {
+ assert!(!tracked_reflector.is_null());
+ assert!(!(*tracked_reflector).get_jsobject().is_null());
+ debug_assert!(thread_state::get().is_script());
+ let roots = &mut *self.roots.get();
+ match roots.iter().rposition(|r| *r == tracked_reflector) {
+ Some(idx) => {
+ roots.remove(idx);
+ },
+ None => panic!("Can't remove a root that was never rooted!"),
+ }
+ }
+}
+
+/// SM Callback that traces the rooted reflectors
+pub unsafe fn trace_roots(tracer: *mut JSTracer) {
+ debug!("tracing stack roots");
+ STACK_ROOTS.with(|ref collection| {
+ let RootCollectionPtr(collection) = collection.get().unwrap();
+ let collection = &*(*collection).roots.get();
+ for root in collection {
+ trace_reflector(tracer, "on stack", &**root);
+ }
+ });
+}
+
+/// Get a reference out of a rooted value.
+pub trait RootedReference<'root> {
+ /// The type of the reference.
+ type Ref: 'root;
+ /// Obtain a reference out of the rooted value.
+ fn r(&'root self) -> Self::Ref;
+}
+
+impl<'root, T: DomObject + 'root> RootedReference<'root> for DomRoot<T> {
+ type Ref = &'root T;
+ fn r(&'root self) -> &'root T {
+ self
+ }
+}
+
+impl<'root, T: DomObject + 'root> RootedReference<'root> for Dom<T> {
+ type Ref = &'root T;
+ fn r(&'root self) -> &'root T {
+ &self
+ }
+}
+
+impl<'root, T: JSTraceable + DomObject + 'root> RootedReference<'root> for [Dom<T>] {
+ type Ref = &'root [&'root T];
+ fn r(&'root self) -> &'root [&'root T] {
+ unsafe { mem::transmute(self) }
+ }
+}
+
+impl<'root, T: DomObject + 'root> RootedReference<'root> for Rc<T> {
+ type Ref = &'root T;
+ fn r(&'root self) -> &'root T {
+ self
+ }
+}
+
+impl<'root, T: RootedReference<'root> + 'root> RootedReference<'root> for Option<T> {
+ type Ref = Option<T::Ref>;
+ fn r(&'root self) -> Option<T::Ref> {
+ self.as_ref().map(RootedReference::r)
+ }
+}
+
/// A traced reference to a DOM object
///
/// This type is critical to making garbage collection work with the DOM,
@@ -88,13 +293,6 @@ impl<T: DomObject> Dom<T> {
}
}
-impl<'root, T: DomObject + 'root> RootedReference<'root> for Dom<T> {
- type Ref = &'root T;
- fn r(&'root self) -> &'root T {
- &self
- }
-}
-
impl<T: DomObject> Deref for Dom<T> {
type Target = T;
@@ -460,204 +658,6 @@ impl<T: DomObject> LayoutDom<T> {
}
}
-/// Get a reference out of a rooted value.
-pub trait RootedReference<'root> {
- /// The type of the reference.
- type Ref: 'root;
- /// Obtain a reference out of the rooted value.
- fn r(&'root self) -> Self::Ref;
-}
-
-impl<'root, T: JSTraceable + DomObject + 'root> RootedReference<'root> for [Dom<T>] {
- type Ref = &'root [&'root T];
- fn r(&'root self) -> &'root [&'root T] {
- unsafe { mem::transmute(self) }
- }
-}
-
-impl<'root, T: DomObject + 'root> RootedReference<'root> for Rc<T> {
- type Ref = &'root T;
- fn r(&'root self) -> &'root T {
- self
- }
-}
-
-impl<'root, T: RootedReference<'root> + 'root> RootedReference<'root> for Option<T> {
- type Ref = Option<T::Ref>;
- fn r(&'root self) -> Option<T::Ref> {
- self.as_ref().map(RootedReference::r)
- }
-}
-
-/// A rooting mechanism for reflectors on the stack.
-/// LIFO is not required.
-///
-/// See also [*Exact Stack Rooting - Storing a GCPointer on the CStack*]
-/// (https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting).
-pub struct RootCollection {
- roots: UnsafeCell<Vec<*const Reflector>>,
-}
-
-/// A pointer to a RootCollection, for use in global variables.
-pub struct RootCollectionPtr(pub *const RootCollection);
-
-impl Copy for RootCollectionPtr {}
-impl Clone for RootCollectionPtr {
- fn clone(&self) -> RootCollectionPtr {
- *self
- }
-}
-
-impl RootCollection {
- /// Create an empty collection of roots
- pub fn new() -> RootCollection {
- debug_assert!(thread_state::get().is_script());
- RootCollection {
- roots: UnsafeCell::new(vec![]),
- }
- }
-
- /// Start tracking a stack-based root
- unsafe fn root(&self, untracked_reflector: *const Reflector) {
- debug_assert!(thread_state::get().is_script());
- let roots = &mut *self.roots.get();
- roots.push(untracked_reflector);
- assert!(!(*untracked_reflector).get_jsobject().is_null())
- }
-
- /// Stop tracking a stack-based reflector, asserting if it isn't found.
- unsafe fn unroot(&self, tracked_reflector: *const Reflector) {
- assert!(!tracked_reflector.is_null());
- assert!(!(*tracked_reflector).get_jsobject().is_null());
- debug_assert!(thread_state::get().is_script());
- let roots = &mut *self.roots.get();
- match roots.iter().rposition(|r| *r == tracked_reflector) {
- Some(idx) => {
- roots.remove(idx);
- },
- None => panic!("Can't remove a root that was never rooted!"),
- }
- }
-}
-
-/// SM Callback that traces the rooted reflectors
-pub unsafe fn trace_roots(tracer: *mut JSTracer) {
- debug!("tracing stack roots");
- STACK_ROOTS.with(|ref collection| {
- let RootCollectionPtr(collection) = collection.get().unwrap();
- let collection = &*(*collection).roots.get();
- for root in collection {
- trace_reflector(tracer, "on stack", &**root);
- }
- });
-}
-
-/// A rooted reference to a DOM object.
-///
-/// The JS value is pinned for the duration of this object's lifetime; roots
-/// are additive, so this object's destruction will not invalidate other roots
-/// for the same JS value. `Root`s cannot outlive the associated
-/// `RootCollection` object.
-#[allow(unrooted_must_root)]
-#[allow_unrooted_interior]
-pub struct DomRoot<T: DomObject> {
- /// Reference to rooted value that must not outlive this container
- ptr: Dom<T>,
- /// List that ensures correct dynamic root ordering
- root_list: *const RootCollection,
-}
-
-impl<T: Castable> DomRoot<T> {
- /// Cast a DOM object root upwards to one of the interfaces it derives from.
- pub fn upcast<U>(root: DomRoot<T>) -> DomRoot<U>
- where U: Castable,
- T: DerivedFrom<U>
- {
- unsafe { mem::transmute(root) }
- }
-
- /// Cast a DOM object root downwards to one of the interfaces it might implement.
- pub fn downcast<U>(root: DomRoot<T>) -> Option<DomRoot<U>>
- where U: DerivedFrom<T>
- {
- if root.is::<U>() {
- Some(unsafe { mem::transmute(root) })
- } else {
- None
- }
- }
-}
-
-impl<T: DomObject> DomRoot<T> {
- /// Create a new stack-bounded root for the provided JS-owned value.
- /// It cannot outlive its associated `RootCollection`, and it gives
- /// out references which cannot outlive this new `Root`.
- #[allow(unrooted_must_root)]
- unsafe fn new(unrooted: Dom<T>) -> DomRoot<T> {
- debug_assert!(thread_state::get().is_script());
- STACK_ROOTS.with(|ref collection| {
- let RootCollectionPtr(collection) = collection.get().unwrap();
- (*collection).root(unrooted.reflector());
- DomRoot {
- ptr: unrooted,
- root_list: collection,
- }
- })
- }
-
- /// Generate a new root from a reference
- pub fn from_ref(unrooted: &T) -> DomRoot<T> {
- unsafe { DomRoot::new(Dom::from_ref(unrooted)) }
- }
-}
-
-impl<'root, T: DomObject + 'root> RootedReference<'root> for DomRoot<T> {
- type Ref = &'root T;
- fn r(&'root self) -> &'root T {
- self
- }
-}
-
-impl<T: DomObject> Deref for DomRoot<T> {
- type Target = T;
- fn deref(&self) -> &T {
- debug_assert!(thread_state::get().is_script());
- &self.ptr
- }
-}
-
-impl<T: DomObject + HeapSizeOf> HeapSizeOf for DomRoot<T> {
- fn heap_size_of_children(&self) -> usize {
- (**self).heap_size_of_children()
- }
-}
-
-impl<T: DomObject> PartialEq for DomRoot<T> {
- fn eq(&self, other: &Self) -> bool {
- self.ptr == other.ptr
- }
-}
-
-impl<T: DomObject> Clone for DomRoot<T> {
- fn clone(&self) -> DomRoot<T> {
- DomRoot::from_ref(&*self)
- }
-}
-
-impl<T: DomObject> Drop for DomRoot<T> {
- fn drop(&mut self) {
- unsafe {
- (*self.root_list).unroot(self.reflector());
- }
- }
-}
-
-unsafe impl<T: DomObject> JSTraceable for DomRoot<T> {
- unsafe fn trace(&self, _: *mut JSTracer) {
- // Already traced.
- }
-}
-
/// Helper trait for safer manipulations of Option<Heap<T>> values.
pub trait OptionalHeapSetter {
type Value;