aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/script/dom/bindings/js.rs11
-rw-r--r--src/components/script/script_task.rs21
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!();