From 427b3b7733eb88f48db839c53d21e7d8284b5fe9 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 29 Sep 2014 07:06:24 +0530 Subject: [PATCH] Remove Traceable/Untraceable entirely --- components/script/dom/bindings/DESIGN.md | 4 +- components/script/dom/bindings/trace.rs | 73 ++---------------------- components/script/dom/bindings/utils.rs | 4 +- components/script/dom/browsercontext.rs | 9 ++- 4 files changed, 13 insertions(+), 77 deletions(-) diff --git a/components/script/dom/bindings/DESIGN.md b/components/script/dom/bindings/DESIGN.md index 52829d48f64..d91bc6807f2 100644 --- a/components/script/dom/bindings/DESIGN.md +++ b/components/script/dom/bindings/DESIGN.md @@ -15,9 +15,9 @@ The outline is: 1. SpiderMonkey's GC calls `JSClass.trace` defined in `FooBinding` when marking phase. This JSClass is basis of each wrapper JSObject. 2. `JSClass.trace` calls `Foo::trace()` (an implementation of `JSTraceable`). This is typically derived via a #[jstraceable] annotation -3. For all fields (except those wrapped in `Untraceable`), `Foo::trace()` +3. For all fields, `Foo::trace()` calls `trace()` on the field. For example, for fields of type `JS`, `JS::trace()` calls - `trace_reflector()`. + `trace_reflector()`. Non-JS-managed types have an empty inline `trace()` method, achieved via `untraceable!` or similar. 4. `trace_reflector()` fetches the reflector that is reachable from a Rust object, and notifies it to the GC with using JSTracer. 5. This operation continues to the end of the graph. 6. Finally, GC gets whether Rust object lives or not from JSObjects which is hold by Rust object. diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 8a1154ce44a..808f62ecf49 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -13,7 +13,7 @@ //! through `ProxyTraps.trace` otherwise.) //! 2. `_trace` calls `Foo::trace()` (an implementation of `JSTraceable`). //! This is typically derived via a #[jstraceable] annotation -//! 3. For all fields (except those wrapped in `Untraceable`), `Foo::trace()` +//! 3. For all fields, `Foo::trace()` //! calls `trace()` on the field. //! For example, for fields of type `JS`, `JS::trace()` calls //! `trace_reflector()`. @@ -52,6 +52,7 @@ use std::io::timer::Timer; use servo_msg::compositor_msg::ScriptListener; use servo_msg::constellation_msg::ConstellationChan; use layout_interface::{LayoutRPC, LayoutChan}; +use dom::bindings::utils::WindowProxyHandler; impl JSTraceable for JS { fn trace(&self, trc: *mut JSTracer) { @@ -100,65 +101,6 @@ pub fn trace_object(tracer: *mut JSTracer, description: &str, obj: *mut JSObject } } -/// Encapsulates a type that cannot easily have `Encodable` derived automagically, -/// but also does not need to be made known to the SpiderMonkey garbage collector. -/// -/// Use only with types that are not associated with a JS reflector and do not contain -/// fields of types associated with JS reflectors. -/// -/// This should really only be used for types that are from other crates, -/// so we can't implement `Encodable`. See more details: mozilla#2662. -pub struct Untraceable { - inner: T, -} - -impl Untraceable { - pub fn new(val: T) -> Untraceable { - Untraceable { - inner: val - } - } -} - -impl Deref for Untraceable { - fn deref<'a>(&'a self) -> &'a T { - &self.inner - } -} - -impl DerefMut for Untraceable { - fn deref_mut<'a>(&'a mut self) -> &'a mut T { - &mut self.inner - } -} - -/// Encapsulates a type that can be traced but is boxed in a type we don't -/// control (such as `RefCell`). -/// -/// Wrap a field in Traceable and implement the `Encodable` trait -/// for that new concrete type to achieve magic compiler-derived trace hooks. -/// -/// We always prefer this, in case the contained type ever changes to something that should be traced. -/// See more details: mozilla#2662. -#[deriving(PartialEq, Clone)] -pub struct Traceable { - inner: T -} - -impl Traceable { - pub fn new(val: T) -> Traceable { - Traceable { - inner: val - } - } -} - -impl Deref for Traceable { - fn deref<'a>(&'a self) -> &'a T { - &self.inner - } -} - impl JSTraceable for RefCell { fn trace(&self, trc: *mut JSTracer) { self.borrow().trace(trc) @@ -177,13 +119,6 @@ impl JSTraceable for Box { } } -impl JSTraceable for Traceable> { - fn trace(&self, trc: *mut JSTracer) { - self.deref().get().trace(trc) - } -} - - impl JSTraceable for Cell { fn trace(&self, trc: *mut JSTracer) { self.get().trace(trc) @@ -236,14 +171,13 @@ impl JSTraceable for (A, B) { let (ref a, ref b) = *self; a.trace(trc); b.trace(trc); - } + } } untraceable!(bool, f32, f64, String, Url) untraceable!(uint, u8, u16, u32, u64) untraceable!(int, i8, i16, i32, i64) -untraceable!(Untraceable) untraceable!(Sender) untraceable!(Receiver) untraceable!(ImageCacheTask, ScriptControlChan) @@ -257,6 +191,7 @@ untraceable!(Cx) untraceable!(ResponseHeaderCollection, RequestHeaderCollection, Method) untraceable!(ConstellationChan) untraceable!(LayoutChan) +untraceable!(WindowProxyHandler) impl<'a> JSTraceable for &'a str { #[inline] diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 9e57171643a..9177a3f5124 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -49,10 +49,12 @@ use js::{JSPROP_ENUMERATE, JSPROP_READONLY, JSPROP_PERMANENT}; use js::JSFUN_CONSTRUCTOR; use js; +pub struct WindowProxyHandler(pub *const libc::c_void); + #[allow(raw_pointer_deriving)] #[jstraceable] pub struct GlobalStaticData { - pub windowproxy_handler: *const libc::c_void, + pub windowproxy_handler: WindowProxyHandler, } pub fn GlobalStaticData() -> GlobalStaticData { diff --git a/components/script/dom/browsercontext.rs b/components/script/dom/browsercontext.rs index 6140dd02a32..32d5026a165 100644 --- a/components/script/dom/browsercontext.rs +++ b/components/script/dom/browsercontext.rs @@ -3,7 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use dom::bindings::js::{JS, JSRef, Temporary}; -use dom::bindings::utils::Reflectable; +use dom::bindings::utils::{Reflectable, WindowProxyHandler}; use dom::document::Document; use dom::window::Window; @@ -11,7 +11,6 @@ use js::jsapi::JSObject; use js::glue::{WrapperNew, CreateWrapperProxyHandler, ProxyTraps}; use js::rust::with_compartment; -use libc::c_void; use std::ptr; #[allow(raw_pointer_deriving)] @@ -52,7 +51,7 @@ impl BrowserContext { let page = win.deref().page(); let js_info = page.js_info(); - let handler = js_info.as_ref().unwrap().dom_static.windowproxy_handler; + let WindowProxyHandler(handler) = js_info.as_ref().unwrap().dom_static.windowproxy_handler; assert!(handler.is_not_null()); let parent = win.deref().reflector().get_jsobject(); @@ -113,8 +112,8 @@ static proxy_handler: ProxyTraps = ProxyTraps { trace: None }; -pub fn new_window_proxy_handler() -> *const c_void { +pub fn new_window_proxy_handler() -> WindowProxyHandler { unsafe { - CreateWrapperProxyHandler(&proxy_handler) + WindowProxyHandler(CreateWrapperProxyHandler(&proxy_handler)) } }