aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/js.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2017-05-26 14:27:05 -0400
committerJosh Matthews <josh@joshmatthews.net>2017-09-25 16:11:48 -0400
commitf5eb8445b05d892b432d769f5e036f786e223fd4 (patch)
tree323092cd64b7bf493114aa4dbb5582b39ddad2cb /components/script/dom/bindings/js.rs
parent16166d66731d7040a91ddbed6ffd05d4fc64c97b (diff)
downloadservo-f5eb8445b05d892b432d769f5e036f786e223fd4.tar.gz
servo-f5eb8445b05d892b432d769f5e036f786e223fd4.zip
Initialize rooted dictionaries to a stable value before setting fields.
Diffstat (limited to 'components/script/dom/bindings/js.rs')
-rw-r--r--components/script/dom/bindings/js.rs29
1 files changed, 28 insertions, 1 deletions
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs
index 976665e4850..07dc4d74778 100644
--- a/components/script/dom/bindings/js.rs
+++ b/components/script/dom/bindings/js.rs
@@ -31,7 +31,8 @@ use dom::bindings::trace::JSTraceable;
use dom::bindings::trace::trace_reflector;
use dom::node::Node;
use heapsize::HeapSizeOf;
-use js::jsapi::{JSObject, JSTracer};
+use js::jsapi::{JSObject, JSTracer, Heap};
+use js::rust::GCMethods;
use mitochondria::OnceCell;
use script_layout_interface::TrustedNodeAddress;
use script_thread::STACK_ROOTS;
@@ -654,3 +655,29 @@ unsafe impl<T: DomObject> JSTraceable for Root<T> {
// Already traced.
}
}
+
+/// Helper trait for safer manipulations of Option<Heap<T>> values.
+pub trait OptionalHeapSetter {
+ type Value;
+ /// Update this optional heap value with a new value.
+ fn set(&mut self, v: Option<Self::Value>);
+}
+
+impl<T: GCMethods + Copy> OptionalHeapSetter for Option<Heap<T>> where Heap<T>: Default {
+ type Value = T;
+ fn set(&mut self, v: Option<T>) {
+ let v = match v {
+ None => {
+ *self = None;
+ return;
+ }
+ Some(v) => v,
+ };
+
+ if self.is_none() {
+ *self = Some(Heap::default());
+ }
+
+ self.as_ref().unwrap().set(v);
+ }
+}