Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upImplement GC rooting for DOM objects #1764
Comments
|
Extracting the key points from above: macro_rules! root( ($rooted:ident = $x:expr) => {
let tmp = $x;
unsafe {
let $rooted = JSManaged::root(tmp);
let kung_fu_death_grip = &$rooted;
}
})
root!(x = node.parent.as_ref().unwrap())And root! replaces |
|
More conversation:
|
|
Other interesting points:
|
|
Here's a small proof-of-concept sketch gist showing what a rooting API might look like: https://gist.github.com/pcwalton/9280996 |
|
I have elaborated on the above to allow optional types. Unfortunately it requires two macros, root! and maybe_root!: https://gist.github.com/jdm/9332689 |
|
I guess you need the macro to be |
|
New sketch: https://gist.github.com/jdm/9816586 Now stack-based, with dynamic failures for incorrect unrooting order (ie. ownership of a root was moved without re-rooting) and incorrectly initializing (ie. missing Root::init call). Neither of these should be too bad in practice, since the scope in which they can occur should be limited to the failing stack frame. |
|
Improvement! No more need to call |
|
I've been putting this into practice, and come up with this rooting scheme which I believe is sound: https://gist.github.com/jdm/9920531 |
|
In particular, if all DOM constructors return
|
|
Two more thoughts:
|
|
Alternatively, do not implement Clonable for Unrooted, and make Unrooted::root take by-value self and ensure that Unrooted is not implicitly copyable. |
|
It was pointed out to me that we could also create a static analysis to check that unrooted types are created immediately. |
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)
|
This happened. |
Dump from a previous IRC conversation: