On Wed, Sep 23, 2015 at 11:01 AM, Till Schneidereit < t...@tillschneidereit.net> wrote:
> CC-ing some SpiderMonkey GC people. > > Terrence, I know that you did some Rust stuff recently, so maybe you have > the required bits of information to comment on this? > > On Wed, Sep 23, 2015 at 7:15 PM, Josh Matthews <j...@joshmatthews.net> > wrote: > >> I have a branch of rust-mozjs where I attempted to implement a Rust >> version of CustomAutoRooter/AutoGCRooter from SpiderMonkey: >> https://github.com/jdm/rust-mozjs/commit/ff89d9609e17e7727c038c8ea8deab88bae4333e >> >> This compiles fine, but I hit problems when I attempted to integrate it >> with my previous work for a safe Rust interface to SM's typed arrays: >> https://github.com/servo/servo/pull/6779 >> >> Specifically, my problems stem from this - given that creating a typed >> array is fallible, as is wrapping an existing typed array reflector, we >> decided to make the constructors for the typed array APIs return Result >> values. Unfortunately this interacts poorly with AutoGCRooter, since it >> stores pointers to Rust objects that end up moving when unwrapping the >> Result ( >> https://github.com/jdm/rust-mozjs/commit/ff89d9609e17e7727c038c8ea8deab88bae4333e#diff-5f5de62bd671c7658b23fd6be60ce6bfR41 >> ). >> >> Can anybody think of a useful way around this problem, or are we doomed >> to non-idiomatic APIs when we're trying to directly integrate with SM's >> lists of rooted values? >> > I think we've already solved this for you from the C++ side, although it will probably take a bit of new rust wrapping to make work. The weirdness with the AutoFooRooters is that they conflate traceability with root creation/destruction. We're currently working to move everything over to a world where things can be traceable -- derives from JS::Traceable in C++ or implements the Traceable trait in rust -- as a separate concept from JS::Rooted. The upshot is twofold: first you can have Rooted<MyTraceable>; secondly, (and more relevantly for your particular problem) is that construction is decisively split from the initialization of the Rooted. In C++ terms this looks like: The old way: class Foo : public CustomAutoRooter { virtual void trace(JSTracer*) {} }; Foo foo(cx, ...args...); The new way: class Foo : public JS::Traceable { static void trace(Foo* self, JSTracer* trc) {} }; Rooted<Foo> foo(cx, Foo(...args...)); // Note the separate Foo and Rooted constructors. In Mozilla's C++ dialect, these two are roughly equivalent because fallible init goes though a manual |bool init(...args...)| function after rooting (and the tracer needs to deal with partial init). In the rust world that I envision, you'd be able to fallibly construct something like (please excuse me if my rust ideoms are old /and/ shaky): let foo: Rooted<Foo> = match Foo::new(..args..) { Err(err) => handleErr!(...), Ok(foo) => Rooted<Foo>(foo) }; Does this help at all or have I totally misunderstood the problem you are facing? Please ping me on IRC and we can discuss this! The GC team is now actively churning towards a simpler (and ideally C-wrappable) API and I'd like to make sure we're all on the same page. > _______________________________________________ >> dev-servo mailing list >> dev-servo@lists.mozilla.org >> https://lists.mozilla.org/listinfo/dev-servo >> > > _______________________________________________ dev-servo mailing list dev-servo@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-servo