diff options
author | Keegan McAllister <kmcallister@mozilla.com> | 2014-10-23 14:44:17 -0700 |
---|---|---|
committer | Keegan McAllister <kmcallister@mozilla.com> | 2014-10-24 16:27:37 -0700 |
commit | 6ec0939a2248e0e092242076ed5b2cd2486c736c (patch) | |
tree | cd945ad95c170c95a99ca96259c7d20bf2b35424 /components/script | |
parent | 0162214b1fce3787bb08118790fc4d59d8528306 (diff) | |
download | servo-6ec0939a2248e0e092242076ed5b2cd2486c736c.tar.gz servo-6ec0939a2248e0e092242076ed5b2cd2486c736c.zip |
Dynamically check DOMRefCell access from layout in debug builds
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/bindings/cell.rs | 47 | ||||
-rw-r--r-- | components/script/dom/dedicatedworkerglobalscope.rs | 5 | ||||
-rw-r--r-- | components/script/script_task.rs | 3 |
3 files changed, 33 insertions, 22 deletions
diff --git a/components/script/dom/bindings/cell.rs b/components/script/dom/bindings/cell.rs index a8b8902f729..4aa993fec45 100644 --- a/components/script/dom/bindings/cell.rs +++ b/components/script/dom/bindings/cell.rs @@ -5,13 +5,15 @@ use dom::bindings::trace::JSTraceable; use js::jsapi::{JSTracer}; +use servo_util::task_state; + use std::cell::{Cell, UnsafeCell}; use std::kinds::marker; /// A mutable field in the DOM. /// /// This extends the API of `core::cell::RefCell` to allow unsafe access in -/// certain situations. +/// certain situations, with dynamic checking in debug builds. pub struct DOMRefCell<T> { value: UnsafeCell<T>, borrow: Cell<BorrowFlag>, @@ -27,8 +29,31 @@ impl<T> DOMRefCell<T> { /// /// For use in the layout task only. pub unsafe fn borrow_for_layout<'a>(&'a self) -> &'a T { + debug_assert!(task_state::get().is_layout()); &*self.value.get() } + + pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> { + debug_assert!(task_state::get().is_script()); + match self.borrow.get() { + WRITING => None, + borrow => { + self.borrow.set(borrow + 1); + Some(Ref { _parent: self }) + } + } + } + + pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> { + debug_assert!(task_state::get().is_script()); + match self.borrow.get() { + UNUSED => { + self.borrow.set(WRITING); + Some(RefMut { _parent: self }) + }, + _ => None + } + } } impl<T: JSTraceable> JSTraceable for DOMRefCell<T> { @@ -63,16 +88,6 @@ impl<T> DOMRefCell<T> { unsafe{self.value.unwrap()} } - pub fn try_borrow<'a>(&'a self) -> Option<Ref<'a, T>> { - match self.borrow.get() { - WRITING => None, - borrow => { - self.borrow.set(borrow + 1); - Some(Ref { _parent: self }) - } - } - } - pub fn borrow<'a>(&'a self) -> Ref<'a, T> { match self.try_borrow() { Some(ptr) => ptr, @@ -80,16 +95,6 @@ impl<T> DOMRefCell<T> { } } - pub fn try_borrow_mut<'a>(&'a self) -> Option<RefMut<'a, T>> { - match self.borrow.get() { - UNUSED => { - self.borrow.set(WRITING); - Some(RefMut { _parent: self }) - }, - _ => None - } - } - pub fn borrow_mut<'a>(&'a self) -> RefMut<'a, T> { match self.try_borrow_mut() { Some(ptr) => ptr, diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 84fc77d0249..76c30db5b4c 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -24,6 +24,8 @@ use script_task::WorkerPostMessage; use script_task::StackRootTLS; use servo_net::resource_task::{ResourceTask, load_whole_resource}; +use servo_util::task_state; +use servo_util::task_state::{Script, InWorker}; use js::glue::JS_STRUCTURED_CLONE_VERSION; use js::jsapi::{JSContext, JS_ReadStructuredClone, JS_WriteStructuredClone, JS_ClearPendingException}; @@ -90,6 +92,9 @@ impl DedicatedWorkerGlobalScope { .native() .named(format!("Web Worker at {}", worker_url.serialize())) .spawn(proc() { + + task_state::initialize(Script | InWorker); + let roots = RootCollection::new(); let _stack_roots_tls = StackRootTLS::new(&roots); diff --git a/components/script/script_task.rs b/components/script/script_task.rs index f07fff94983..398e9b8d4db 100644 --- a/components/script/script_task.rs +++ b/components/script/script_task.rs @@ -54,6 +54,7 @@ use servo_net::resource_task::ResourceTask; use servo_util::geometry::to_frac_px; use servo_util::smallvec::{SmallVec1, SmallVec}; use servo_util::task::spawn_named_with_send_on_failure; +use servo_util::task_state; use geom::point::Point2D; use js::jsapi::{JS_SetWrapObjectCallbacks, JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ, JS_GC}; @@ -262,7 +263,7 @@ impl ScriptTaskFactory for ScriptTask { let ConstellationChan(const_chan) = constellation_chan.clone(); let (script_chan, script_port) = channel(); let layout_chan = LayoutChan(layout_chan.sender()); - spawn_named_with_send_on_failure("ScriptTask", proc() { + spawn_named_with_send_on_failure("ScriptTask", task_state::Script, proc() { let script_task = ScriptTask::new(id, compositor as Box<ScriptListener>, layout_chan, |