Create a replacement for Cell<SM primitive>. Fixes #4337.

This commit is contained in:
Josh Matthews 2014-12-16 21:23:24 -05:00
parent b9edc2243a
commit 8ff3e6bbdc
4 changed files with 45 additions and 13 deletions

View file

@ -45,11 +45,13 @@
//! - `OptionalSettable`: allows assigning `Option` values of `JSRef`/`Temporary` to fields of `Option<JS<T>>`
//! - `RootedReference`: makes obtaining an `Option<JSRef<T>>` from an `Option<Root<T>>` easy
use dom::bindings::trace::JSTraceable;
use dom::bindings::utils::{Reflector, Reflectable};
use dom::node::Node;
use dom::xmlhttprequest::{XMLHttpRequest, TrustedXHRAddress};
use dom::worker::{Worker, TrustedWorkerAddress};
use js::jsapi::JSObject;
use js::jsval::JSVal;
use layout_interface::TrustedNodeAddress;
use script_task::StackRoots;
@ -194,6 +196,40 @@ impl<T: Reflectable> Reflectable for JS<T> {
}
}
pub trait HeapGCValue: JSTraceable {
}
impl HeapGCValue for JSVal {
}
impl<T: Reflectable> HeapGCValue for JS<T> {
}
/// A mutable holder for a GC-owned SpiderMonkey value stored on the heap.
/// Must be used in place of traditional interior mutability to ensure proper
/// GC barriers are enforced.
#[must_root]
#[jstraceable]
pub struct MutHeap<T: HeapGCValue+Copy> {
val: Cell<T>,
}
impl<T: HeapGCValue+Copy> MutHeap<T> {
pub fn new(initial: T) -> MutHeap<T> {
MutHeap {
val: Cell::new(initial),
}
}
pub fn set(&self, val: T) {
self.val.set(val)
}
pub fn get(&self) -> T {
self.val.get()
}
}
/// A mutable `JS<T>` value, with nullability represented by an enclosing
/// Option wrapper. Must be used in place of traditional internal mutability
/// to ensure that the proper GC barriers are enforced.

View file

@ -8,19 +8,17 @@ use dom::bindings::codegen::Bindings::EventBinding::EventMethods;
use dom::bindings::codegen::InheritTypes::{EventCast, CustomEventDerived};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::js::{JSRef, Temporary, MutHeap};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::event::{Event, EventTypeId};
use js::jsapi::JSContext;
use js::jsval::{JSVal, NullValue};
use servo_util::str::DOMString;
use std::cell::Cell;
#[dom_struct]
pub struct CustomEvent {
event: Event,
detail: Cell<JSVal>,
detail: MutHeap<JSVal>,
}
impl CustomEventDerived for Event {
@ -33,7 +31,7 @@ impl CustomEvent {
fn new_inherited(type_id: EventTypeId) -> CustomEvent {
CustomEvent {
event: Event::new_inherited(type_id),
detail: Cell::new(NullValue()),
detail: MutHeap::new(NullValue()),
}
}

View file

@ -8,7 +8,7 @@ use dom::bindings::codegen::Bindings::ErrorEventBinding::ErrorEventMethods;
use dom::bindings::codegen::InheritTypes::{EventCast, ErrorEventDerived};
use dom::bindings::error::Fallible;
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::js::{JSRef, Temporary, MutHeap};
use js::jsapi::JSContext;
use dom::bindings::trace::JSTraceable;
@ -27,7 +27,7 @@ pub struct ErrorEvent {
filename: DOMRefCell<DOMString>,
lineno: Cell<u32>,
colno: Cell<u32>,
error: Cell<JSVal>
error: MutHeap<JSVal>,
}
impl ErrorEventDerived for Event {
@ -44,7 +44,7 @@ impl ErrorEvent {
filename: DOMRefCell::new("".to_string()),
lineno: Cell::new(0),
colno: Cell::new(0),
error: Cell::new(NullValue())
error: MutHeap::new(NullValue())
}
}

View file

@ -13,19 +13,17 @@ use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilter;
// use dom::bindings::codegen::Bindings::NodeFilterBinding::NodeFilterConstants;
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::global::GlobalRef;
use dom::bindings::js::{JS, JSRef, OptionalRootable, Temporary};
use dom::bindings::js::{JS, JSRef, OptionalRootable, Temporary, MutHeap};
use dom::bindings::utils::{Reflectable, Reflector, reflect_dom_object};
use dom::document::{Document, DocumentHelpers};
use dom::node::{Node, NodeHelpers};
use std::cell::Cell;
// http://dom.spec.whatwg.org/#interface-treewalker
#[dom_struct]
pub struct TreeWalker {
reflector_: Reflector,
root_node: JS<Node>,
current_node: Cell<JS<Node>>,
current_node: MutHeap<JS<Node>>,
what_to_show: u32,
filter: Filter
}
@ -37,7 +35,7 @@ impl TreeWalker {
TreeWalker {
reflector_: Reflector::new(),
root_node: JS::from_rooted(root_node),
current_node: Cell::new(JS::from_rooted(root_node)),
current_node: MutHeap::new(JS::from_rooted(root_node)),
what_to_show: what_to_show,
filter: filter
}