diff options
author | Ms2ger <Ms2ger@gmail.com> | 2017-02-14 16:49:25 +0100 |
---|---|---|
committer | Ms2ger <Ms2ger@gmail.com> | 2017-02-16 11:03:25 +0100 |
commit | f1605ab149032adb20aec667d7660a4e433824e8 (patch) | |
tree | f0d893a9652678faf054836d00fd17e6caa22c2b /components/script | |
parent | 8c8eb41cdf56feb3b03d3b47cf0a13024a2690d9 (diff) | |
download | servo-f1605ab149032adb20aec667d7660a4e433824e8.tar.gz servo-f1605ab149032adb20aec667d7660a4e433824e8.zip |
Introduce RootedTraceableBox.
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/bindings/conversions.rs | 17 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 55 |
2 files changed, 72 insertions, 0 deletions
diff --git a/components/script/dom/bindings/conversions.rs b/components/script/dom/bindings/conversions.rs index 747573cec05..0cbb49bea3e 100644 --- a/components/script/dom/bindings/conversions.rs +++ b/components/script/dom/bindings/conversions.rs @@ -37,6 +37,7 @@ use dom::bindings::js::Root; use dom::bindings::num::Finite; use dom::bindings::reflector::{DomObject, Reflector}; use dom::bindings::str::{ByteString, DOMString, USVString}; +use dom::bindings::trace::{JSTraceable, RootedTraceableBox}; use dom::bindings::utils::DOMClass; use js; pub use js::conversions::{FromJSValConvertible, ToJSValConvertible, ConversionResult}; @@ -117,6 +118,22 @@ impl <T: DomObject + IDLInterface> FromJSValConvertible for Root<T> { } } +impl <T: FromJSValConvertible + JSTraceable> FromJSValConvertible for RootedTraceableBox<T> { + type Config = T::Config; + + unsafe fn from_jsval(cx: *mut JSContext, + value: HandleValue, + config: Self::Config) + -> Result<ConversionResult<Self>, ()> { + T::from_jsval(cx, value, config).map(|result| { + match result { + ConversionResult::Success(v) => ConversionResult::Success(RootedTraceableBox::new(v)), + ConversionResult::Failure(e) => ConversionResult::Failure(e), + } + }) + } +} + /// Convert `id` to a `DOMString`, assuming it is string-valued. /// /// Handling of invalid UTF-16 in strings depends on the relevant option. diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 763ccb9b22b..aeddcdabe4b 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -653,6 +653,61 @@ impl<'a, T: JSTraceable + 'static> Drop for RootedTraceable<'a, T> { } } +/// Roots any JSTraceable thing +/// +/// If you have a valid DomObject, use Root. +/// If you have GC things like *mut JSObject or JSVal, use rooted!. +/// If you have an arbitrary number of DomObjects to root, use rooted_vec!. +/// If you know what you're doing, use this. +pub struct RootedTraceableBox<T: 'static + JSTraceable> { + ptr: *mut T, +} + +unsafe impl<T: JSTraceable + 'static> JSTraceable for RootedTraceableBox<T> { + unsafe fn trace(&self, tracer: *mut JSTracer) { + (*self.ptr).trace(tracer); + } +} + +impl<T: JSTraceable + 'static> RootedTraceableBox<T> { + /// Root a JSTraceable thing for the life of this RootedTraceable + pub fn new(traceable: T) -> RootedTraceableBox<T> { + let traceable = Box::into_raw(box traceable); + unsafe { + RootedTraceableSet::add(traceable); + } + RootedTraceableBox { + ptr: traceable, + } + } +} + +impl<T: JSTraceable> Deref for RootedTraceableBox<T> { + type Target = T; + fn deref(&self) -> &T { + unsafe { + &*self.ptr + } + } +} + +impl<T: JSTraceable> DerefMut for RootedTraceableBox<T> { + fn deref_mut(&mut self) -> &mut T { + unsafe { + &mut *self.ptr + } + } +} + +impl<T: JSTraceable + 'static> Drop for RootedTraceableBox<T> { + fn drop(&mut self) { + unsafe { + RootedTraceableSet::remove(self.ptr); + let _ = Box::from_raw(self.ptr); + } + } +} + /// A vector of items to be rooted with `RootedVec`. /// Guaranteed to be empty when not rooted. /// Usage: `rooted_vec!(let mut v);` or if you have an |