diff options
author | bors-servo <release+servo@mozilla.com> | 2014-05-03 14:25:22 -0400 |
---|---|---|
committer | bors-servo <release+servo@mozilla.com> | 2014-05-03 14:25:22 -0400 |
commit | 731e66ff132e41cdc49bc5324c0e15be19c46ec2 (patch) | |
tree | ccce9b42e8a6c54245e53620082efe0b9840eae1 /src/components/script/dom/bindings/utils.rs | |
parent | 4051a8096d7ba7e7f9c86e76d0b4bffd83e85805 (diff) | |
parent | 91278da9dd55582401154e07f9eea34425a332c2 (diff) | |
download | servo-731e66ff132e41cdc49bc5324c0e15be19c46ec2.tar.gz servo-731e66ff132e41cdc49bc5324c0e15be19c46ec2.zip |
auto merge of #2101 : jdm/servo/newroot_rebase, r=Ms2ger
As described in #1764, this strategy uses the following properties:
* DOM members are `JS<T>` types. These cannot be used with being explicitly rooted, but they are required for compiler-derived trace hooks.
* Methods that take DOM type arguments receive `&[mut] JSRef<T>`. These are rooted value references that are cloneable but cannot escape.
* Methods that return DOM values use `Unrooted<T>`. These are values that may or may not be rooted elsewhere, but callers must root them in order to interact with them in any way. One unsoundness hole exists - `Unrooted` values must be rooted ASAP, or there exists the danger that JSAPI calls could be made that could cause the underlying JS value to be GCed.
* All methods are implemented on `JSRef<T>`, enforcing the requirement that all DOM values are rooted for the duration of a method call (with a few exceptions for layout-related code, which cannot root values and therefore interacts with `JS<T>` and `&T` values - this is safe under the assumption that layout code interacts with DOM nodes that are in the tree, therefore rooted, and does not run concurrently with content code)
Diffstat (limited to 'src/components/script/dom/bindings/utils.rs')
-rw-r--r-- | src/components/script/dom/bindings/utils.rs | 50 |
1 files changed, 19 insertions, 31 deletions
diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 417d4c434c2..a99189ae161 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -5,7 +5,7 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::codegen::PrototypeList::MAX_PROTO_CHAIN_LENGTH; use dom::bindings::conversions::{FromJSValConvertible, IDLInterface}; -use dom::bindings::js::JS; +use dom::bindings::js::{JS, JSRef, Temporary, Root}; use dom::bindings::trace::Untraceable; use dom::browsercontext; use dom::window; @@ -37,7 +37,6 @@ use js::jsapi::{JSContext, JSObject, JSBool, jsid, JSClass, JSNative}; use js::jsapi::{JSFunctionSpec, JSPropertySpec}; use js::jsapi::{JS_NewGlobalObject, JS_InitStandardClasses}; use js::jsapi::{JSString}; -use js::jsapi::{JS_AllowGC, JS_InhibitGC}; use js::jsfriendapi::bindgen::JS_NewObjectWithUniqueType; use js::jsval::JSVal; use js::jsval::{PrivateValue, ObjectValue, NullValue, ObjectOrNullValue}; @@ -390,10 +389,10 @@ pub trait Reflectable { pub fn reflect_dom_object<T: Reflectable> (obj: ~T, - window: &JS<window::Window>, - wrap_fn: extern "Rust" fn(*JSContext, &JS<window::Window>, ~T) -> JS<T>) - -> JS<T> { - JS::new(obj, window, wrap_fn) + window: &JSRef<window::Window>, + wrap_fn: extern "Rust" fn(*JSContext, &JSRef<window::Window>, ~T) -> JS<T>) + -> Temporary<T> { + Temporary::new(wrap_fn(window.deref().get_cx(), window, obj)) } #[deriving(Eq)] @@ -413,6 +412,13 @@ impl Reflector { self.object = object; } + /// Return a pointer to the memory location at which the JS reflector object is stored. + /// Used by Temporary values to root the reflector, as required by the JSAPI rooting + /// APIs. + pub fn rootable<'a>(&'a self) -> &'a *JSObject { + &self.object + } + pub fn new() -> Reflector { Reflector { object: ptr::null(), @@ -605,11 +611,13 @@ pub extern fn outerize_global(_cx: *JSContext, obj: JSHandleObject) -> *JSObject unsafe { debug!("outerizing"); let obj = *obj.unnamed; - let win: JS<window::Window> = + let win: Root<window::Window> = unwrap_jsmanaged(obj, IDLInterface::get_prototype_id(None::<window::Window>), - IDLInterface::get_prototype_depth(None::<window::Window>)).unwrap(); - win.get().browser_context.get_ref().window_proxy() + IDLInterface::get_prototype_depth(None::<window::Window>)) + .unwrap() + .root(); + win.deref().browser_context.get_ref().window_proxy() } } @@ -625,8 +633,8 @@ pub fn global_object_for_js_object(obj: *JSObject) -> JS<window::Window> { } fn cx_for_dom_reflector(obj: *JSObject) -> *JSContext { - let win = global_object_for_js_object(obj); - let js_info = win.get().page().js_info(); + let win = global_object_for_js_object(obj).root(); + let js_info = win.deref().page().js_info(); match *js_info { Some(ref info) => info.js_context.deref().deref().ptr, None => fail!("no JS context for DOM global") @@ -637,26 +645,6 @@ pub fn cx_for_dom_object<T: Reflectable>(obj: &T) -> *JSContext { cx_for_dom_reflector(obj.reflector().get_jsobject()) } -/// Execute arbitrary code with the JS GC enabled, then disable it afterwards. -pub fn with_gc_enabled<R>(cx: *JSContext, f: || -> R) -> R { - unsafe { - JS_AllowGC(cx); - let rv = f(); - JS_InhibitGC(cx); - rv - } -} - -/// Execute arbitrary code with the JS GC disabled, then enable it afterwards. -pub fn with_gc_disabled<R>(cx: *JSContext, f: || -> R) -> R { - unsafe { - JS_InhibitGC(cx); - let rv = f(); - JS_AllowGC(cx); - rv - } -} - /// Check if an element name is valid. See http://www.w3.org/TR/xml/#NT-Name /// for details. #[deriving(Eq)] |