diff options
Diffstat (limited to 'src/components/script/dom/bindings/trace.rs')
-rw-r--r-- | src/components/script/dom/bindings/trace.rs | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/src/components/script/dom/bindings/trace.rs b/src/components/script/dom/bindings/trace.rs index 1cedf246728..4e32bacec68 100644 --- a/src/components/script/dom/bindings/trace.rs +++ b/src/components/script/dom/bindings/trace.rs @@ -8,6 +8,7 @@ use dom::bindings::utils::{Reflectable, Reflector}; use js::jsapi::{JSTracer, JS_CallTracer, JSTRACE_OBJECT}; use std::cast; +use std::cell::RefCell; use std::libc; use std::ptr; use std::ptr::null; @@ -30,7 +31,7 @@ impl<S: Encoder> Encodable<S> for Reflector { } } -pub trait Traceable { +pub trait JSTraceable { fn trace(&self, trc: *mut JSTracer); } @@ -46,3 +47,69 @@ pub fn trace_reflector(tracer: *mut JSTracer, description: &str, reflector: &Ref }); } } + +/// Encapsulates a type that cannot easily have Encodable derived automagically, +/// but also does not need to be made known to the SpiderMonkey garbage collector. +/// Use only with types that are not associated with a JS reflector and do not contain +/// fields of types associated with JS reflectors. +pub struct Untraceable<T> { + priv inner: T, +} + +impl<T> Untraceable<T> { + pub fn new(val: T) -> Untraceable<T> { + Untraceable { + inner: val + } + } +} + +impl<S: Encoder, T> Encodable<S> for Untraceable<T> { + fn encode(&self, _s: &mut S) { + } +} + +impl<T> Deref<T> for Untraceable<T> { + fn deref<'a>(&'a self) -> &'a T { + &self.inner + } +} + +impl<T> DerefMut<T> for Untraceable<T> { + fn deref_mut<'a>(&'a mut self) -> &'a mut T { + &mut self.inner + } +} + +/// Encapsulates a type that can be traced but is boxed in a type we don't control +/// (such as RefCell). Wrap a field in Traceable and implement the Encodable trait +/// for that new concrete type to achieve magic compiler-derived trace hooks. +pub struct Traceable<T> { + priv inner: T +} + +impl<T> Traceable<T> { + pub fn new(val: T) -> Traceable<T> { + Traceable { + inner: val + } + } +} + +impl<T> Deref<T> for Traceable<T> { + fn deref<'a>(&'a self) -> &'a T { + &self.inner + } +} + +impl<T> DerefMut<T> for Traceable<T> { + fn deref_mut<'a>(&'a mut self) -> &'a mut T { + &mut self.inner + } +} + +impl<S: Encoder, T: Encodable<S>> Encodable<S> for Traceable<RefCell<T>> { + fn encode(&self, s: &mut S) { + self.borrow().encode(s) + } +}
\ No newline at end of file |