mirror of
https://github.com/servo/servo.git
synced 2025-06-08 16:43:28 +00:00
Root Temporary values for the duration of their lifetime.
This commit is contained in:
parent
522d3f167b
commit
a09a4bd297
3 changed files with 30 additions and 15 deletions
|
@ -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.
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue