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

Reply via email to