diff options
-rw-r--r-- | src/components/script/dom/bindings/js.rs | 11 | ||||
-rw-r--r-- | src/components/script/script_task.rs | 21 |
2 files changed, 30 insertions, 2 deletions
diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs index 9b61482e41a..1efd25dc72c 100644 --- a/src/components/script/dom/bindings/js.rs +++ b/src/components/script/dom/bindings/js.rs @@ -6,9 +6,11 @@ use dom::bindings::utils::{Reflector, Reflectable, cx_for_dom_object}; use dom::window::Window; use js::jsapi::{JSObject, JSContext, JS_AddObjectRoot, JS_RemoveObjectRoot}; use layout_interface::TrustedNodeAddress; +use script_task::StackRoots; use std::cast; use std::cell::RefCell; +use std::local_data; /// A type that represents a JS-owned value that is rooted for the lifetime of this value. /// Importantly, it requires explicit rooting in order to interact with the inner value. @@ -52,8 +54,13 @@ impl<T: Reflectable> Temporary<T> { } /// Root this unrooted value. - pub fn root<'a, 'b>(self, collection: &'a RootCollection) -> Root<'a, 'b, T> { - collection.new_root(&self.inner) + pub fn root<'a, 'b>(self, _collection: &'a RootCollection) -> Root<'a, 'b, T> { + local_data::get(StackRoots, |opt| { + let collection = opt.unwrap(); + unsafe { + (**collection).new_root(&self.inner) + } + }) } unsafe fn inner(&self) -> JS<T> { diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index c945f8c3451..2bfe058cc65 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -55,6 +55,7 @@ use servo_util::namespace::Null; use std::cast; use std::cell::{RefCell, Ref, RefMut}; use std::comm::{channel, Sender, Receiver, Empty, Disconnected, Data}; +use std::local_data; use std::mem::replace; use std::ptr; use std::rc::Rc; @@ -63,6 +64,8 @@ use url::Url; use serialize::{Encoder, Encodable}; +local_data_key!(pub StackRoots: *RootCollection) + /// Messages used to control the script task. pub enum ScriptMsg { /// Loads a new URL on the specified pipeline. @@ -510,6 +513,21 @@ pub struct JSPageInfo { pub js_context: Untraceable<Rc<Cx>>, } +struct StackRootTLS; + +impl StackRootTLS { + fn new(roots: &RootCollection) -> StackRootTLS { + local_data::set(StackRoots, roots as *RootCollection); + StackRootTLS + } +} + +impl Drop for StackRootTLS { + fn drop(&mut self) { + let _ = local_data::pop(StackRoots); + } +} + /// Information for an entire page. Pages are top-level browsing contexts and can contain multiple /// frames. /// @@ -653,6 +671,9 @@ impl ScriptTask { /// Handle incoming control messages. fn handle_msgs(&self) -> bool { + let roots = RootCollection::new(); + let _stack_roots_tls = StackRootTLS::new(&roots); + // Handle pending resize events. // Gather them first to avoid a double mut borrow on self. let mut resizes = vec!(); |