Servo inside (introduction to Servo’s DOM binding) Tetsuharu OHZEKI, Gecko Inside #6 (Feb 24, 2016)
Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. http://rust-lang.org/
Rust Language • Develop by Mozilla & community • It’s just like “Modern Redesigned C++” • Today’s Gecko try to use Rust in some area: • https://wiki.mozilla.org/Oxidation • e.g. MP4 metadata parser, URL parser, style system
script crate • The implementation of “DOM” and scripting • Binding with SpiderMonkey • Handle a web driver’s script execution (from Constellation)
browser JS Engine Rust Object JS Object
DOM lifecycle & JS binding • DOM needs a complex lifecycle management • good article about this area: http://steps.dodgson.org/b/2012/12/19/ dom-and-gc-or-what-happend-at-eden/ • Other browser engines have an own garbage collector for this complexity • Cycle Collector (Gecko) • Oilpan GC (Blink) • Servo need not own GC in the browser side like other engines. • All lifecycle of Servo’s DOM object are managed by SpiderMonkey GC
How to connect with JSObject & Rust Object? • DOM Object has “Reflector” field as the first field. • Reflector stores a pointer to “wrapper” JS Object which corresponds to it. • JS Object has a pointer to Rust object which is corresponds to it. • JS Object stores the pointer in its “slot”.
Node …… Reflector handlers parent_node JSObject
Generate a glue code from WebIDL • By /components/script/dom/bindings/codegen/ BindingGen.py • Auto generate from WebIDL with special annotation • Methods, Property, JIT Information, Constants, etc • “Glue” code to connect a Rust world & JS world
How to trace object graph from SpiderMonkey GC • From GC roots, SpiderMonkey GC trace an object graph. • Remember these simple rules: • From a wrapper object (JSObject), GC can traces a Rust Object. • From a Rust Object, GC can trace a wrapper JS Object. • Some compiler plugins helps these tricks ;)
GC Managed pointer • We use a special smart pointer for GC managed object in Rust world • JS<T> can be holden as a member of a Rust’s DOM struct • Root<T> can be on stack with rooting explicitly. • To avoid SpiderMonkey exact (precise) GC’s mistake. • In practice, we use this for a return value.
Inheritance • DOM interface requires an inheritance • But Rust does not have a inheritance system as a language feature! • So we generate annotation traits for safe up/down casting from WebIDL information! • …..And write vtable by hand! 😓
vtable by hand…
Special macros and plugins • It’s hard to implement a GC hook for an object correctly. • We use a special rust compiler plugins to check & avoid typical pitfalls. • auto generate a tricky implementation for GC interaction. • check unrooted object • valid order of struct (for inheritance) • etc…