aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/script')
-rw-r--r--src/components/script/dom/bindings/js.rs30
-rw-r--r--src/components/script/dom/bindings/utils.rs11
-rw-r--r--src/components/script/dom/window.rs4
3 files changed, 30 insertions, 15 deletions
diff --git a/src/components/script/dom/bindings/js.rs b/src/components/script/dom/bindings/js.rs
index 031987181c2..9b61482e41a 100644
--- a/src/components/script/dom/bindings/js.rs
+++ b/src/components/script/dom/bindings/js.rs
@@ -2,20 +2,20 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use dom::bindings::utils::{Reflector, Reflectable};
+use dom::bindings::utils::{Reflector, Reflectable, cx_for_dom_object};
use dom::window::Window;
-use js::jsapi::{JSObject, JSContext};
+use js::jsapi::{JSObject, JSContext, JS_AddObjectRoot, JS_RemoveObjectRoot};
use layout_interface::TrustedNodeAddress;
use std::cast;
use std::cell::RefCell;
-/// A type that represents a JS-owned value that may or may not be rooted.
-/// Importantly, it requires rooting in order to interact with the value in any way.
+/// 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.
/// Can be assigned into JS-owned member fields (ie. JS<T> types) safely via the
/// `JS<T>::assign` method or `OptionalAssignable::assign` (for Option<JS<T>> fields).
pub struct Temporary<T> {
- inner: JS<T>
+ inner: JS<T>,
}
impl<T> Eq for Temporary<T> {
@@ -24,19 +24,31 @@ impl<T> Eq for Temporary<T> {
}
}
+#[unsafe_destructor]
+impl<T: Reflectable> Drop for Temporary<T> {
+ fn drop(&mut self) {
+ let cx = cx_for_dom_object(&self.inner);
+ unsafe {
+ JS_RemoveObjectRoot(cx, self.inner.reflector().rootable());
+ }
+ }
+}
+
impl<T: Reflectable> Temporary<T> {
/// Create a new Temporary value from a JS-owned value.
pub fn new(inner: JS<T>) -> Temporary<T> {
+ let cx = cx_for_dom_object(&inner);
+ unsafe {
+ JS_AddObjectRoot(cx, inner.reflector().rootable());
+ }
Temporary {
- inner: inner
+ inner: inner,
}
}
/// Create a new Temporary value from a rooted value.
pub fn new_rooted<'a>(root: &JSRef<'a, T>) -> Temporary<T> {
- Temporary {
- inner: root.unrooted()
- }
+ Temporary::new(root.unrooted())
}
/// Root this unrooted value.
diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs
index cbccb90197a..96982ebb6e2 100644
--- a/src/components/script/dom/bindings/utils.rs
+++ b/src/components/script/dom/bindings/utils.rs
@@ -412,6 +412,10 @@ impl Reflector {
self.object = object;
}
+ pub fn rootable(&self) -> **JSObject {
+ &self.object as **JSObject
+ }
+
pub fn new() -> Reflector {
Reflector {
object: ptr::null(),
@@ -616,14 +620,13 @@ pub extern fn outerize_global(_cx: *JSContext, obj: JSHandleObject) -> *JSObject
}
/// Returns the global object of the realm that the given JS object was created in.
-pub fn global_object_for_js_object(obj: *JSObject) -> Temporary<window::Window> {
+pub fn global_object_for_js_object(obj: *JSObject) -> JS<window::Window> {
unsafe {
let global = GetGlobalForObjectCrossCompartment(obj);
let clasp = JS_GetClass(global);
assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0);
- Temporary::new(
- FromJSValConvertible::from_jsval(ptr::null(), ObjectOrNullValue(global), ())
- .ok().expect("found DOM global that doesn't unwrap to Window"))
+ FromJSValConvertible::from_jsval(ptr::null(), ObjectOrNullValue(global), ())
+ .ok().expect("found DOM global that doesn't unwrap to Window")
}
}
diff --git a/src/components/script/dom/window.rs b/src/components/script/dom/window.rs
index d3ef0769431..3908db73326 100644
--- a/src/components/script/dom/window.rs
+++ b/src/components/script/dom/window.rs
@@ -342,7 +342,7 @@ impl Window {
script_chan: ScriptChan,
compositor: ~ScriptListener,
image_cache_task: ImageCacheTask)
- -> Temporary<Window> {
+ -> JS<Window> {
let win = ~Window {
eventtarget: EventTarget::new_inherited(WindowTypeId),
script_chan: script_chan,
@@ -357,6 +357,6 @@ impl Window {
browser_context: None,
};
- Temporary::new(WindowBinding::Wrap(cx, win))
+ WindowBinding::Wrap(cx, win)
}
}