aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorMs2ger <Ms2ger@gmail.com>2017-02-14 16:49:25 +0100
committerMs2ger <Ms2ger@gmail.com>2017-02-16 11:03:25 +0100
commitf1605ab149032adb20aec667d7660a4e433824e8 (patch)
treef0d893a9652678faf054836d00fd17e6caa22c2b /components/script
parent8c8eb41cdf56feb3b03d3b47cf0a13024a2690d9 (diff)
downloadservo-f1605ab149032adb20aec667d7660a4e433824e8.tar.gz
servo-f1605ab149032adb20aec667d7660a4e433824e8.zip
Introduce RootedTraceableBox.
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/bindings/conversions.rs17
-rw-r--r--components/script/dom/bindings/trace.rs55
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