diff options
Diffstat (limited to 'components/script')
-rw-r--r-- | components/script/dom/bindings/DESIGN.md | 15 | ||||
-rw-r--r-- | components/script/dom/bindings/trace.rs | 11 |
2 files changed, 11 insertions, 15 deletions
diff --git a/components/script/dom/bindings/DESIGN.md b/components/script/dom/bindings/DESIGN.md index 0b8f6b01dd4..52829d48f64 100644 --- a/components/script/dom/bindings/DESIGN.md +++ b/components/script/dom/bindings/DESIGN.md @@ -13,13 +13,14 @@ This is very tricky and magically mechanism helped by Rust Compiler. 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()` defined in InhertTypes.rs. -3. `Foo::trace()` calls `Foo::encode()`. This `encode()` method is derived by the annotation of `#[deriving(Encodable)]` for a Rust DOM Element struct. -4. `Foo::encode()` calls `JS<T>::encode()` method of `JS<T>` which is contained to `Foo`’s member. So this is the compiler magic! Rust compiler generates [codes like this](https://github.com/mozilla/rust/blob/db5206c32a879d5058d6a5cdce39c13c763fbdd5/src/libsyntax/ext/deriving/encodable.rs) for all structs annotated `#[deriving(Encodable)]`. This is based on [the assumption](https://github.com/mozilla/servo/blob/54da52fa774ce2ee59fcf811af595bf292169ad8/src/components/script/dom/bindings/trace.rs#L16). -5. `JS<T>::encode()` calls `dom::bindings::trace::trace_reflector()`. -6. `trace_reflector()` fetches the reflector that is reachable from a Rust object, and notifies it to the GC with using JSTracer. -7. This operation continues to the end of the graph. -8. Finally, GC gets whether Rust object lives or not from JSObjects which is hold by Rust object. +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()` + calls `trace()` on the field. For example, for fields of type `JS<T>`, `JS<T>::trace()` calls + `trace_reflector()`. +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. ## Destruct diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index f8f63091db0..f0b4e5af237 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -13,13 +13,13 @@ //! through `ProxyTraps.trace` otherwise.) //! 2. `_trace` calls `Foo::trace()` (an implementation of `JSTraceable`). //! This is typically derived via a #[jstraceable] annotation -//! 4. For all fields (except those wrapped in `Untraceable`), `Foo::trace()` +//! 3. For all fields (except those wrapped in `Untraceable`), `Foo::trace()` //! calls `trace()` on the field. //! For example, for fields of type `JS<T>`, `JS<T>::trace()` calls //! `trace_reflector()`. -//! 6. `trace_reflector()` calls `trace_object()` with the `JSObject` for the +//! 4. `trace_reflector()` calls `trace_object()` with the `JSObject` for the //! reflector. -//! 7. `trace_object()` calls `JS_CallTracer()` to notify the GC, which will +//! 5. `trace_object()` calls `JS_CallTracer()` to notify the GC, which will //! add the object to the graph, and will trace that object as well. //! //! The untraceable!() macro adds an empty implementation of JSTraceable to @@ -44,11 +44,6 @@ use std::collections::hashmap::HashMap; use collections::hash::Hash; use style::PropertyDeclarationBlock; -// IMPORTANT: We rely on the fact that we never attempt to encode DOM objects using -// any encoder but JSTracer. Since we derive trace hooks automatically, -// we are unfortunately required to use generic types everywhere and -// unsafely cast to the concrete JSTracer we actually require. - impl<T: Reflectable> JSTraceable for JS<T> { fn trace(&self, trc: *mut JSTracer) { trace_reflector(trc, "", self.reflector()); |