On Nov 12, 2013, at 9:01 PM, Patrick Walton <[email protected]> wrote:

> On 11/13/13 12:18 PM, Kevin Ballard wrote:
>> The only penalty this approach has (that comes to mind) over the
>> single-inheritance model is that, because of the loss of the prefix
>> property, any field access on the trait object itself will require
>> looking up the field offset in the virtual table. But trait objects
>> already use the virtual table for everything else, and the actual trait
>> implementations don’t require this, so I don’t think it’s problematic to
>> require a virtual table lookup on trait object field access.
> 
> I think it is. This is a performance cost over C++ that is just too risky. 
> Note that browser reflow is very much gated on the ability to load and store 
> fields from a constant offset. I think we stand a good chance of losing to 
> the competition if we do this.

How does C++ multiple inheritance deal with this? I've never looked much at the 
actual implementation. Specifically, if I have something like

  #include <iostream>

  class A {
  public:
    int x = 1;
    virtual ~A() = default;
  };

  class B {
  public:
    int y = 2;
    virtual ~B() = default;
  };

  class C: public A, public B {
  public:
    int z = 3;
  };

  int main(int argc, char *argv[]) {
    B *someB = new C();
    std::cout << "y: " << someB->y << std::endl;
  }

I assume that `someB` really is a pointer to an instance `B`, somewhere within 
the enclosing instance of `C`. I also assume that the vtable for this instance 
of `B` contains a pointer back to the root `C` (or perhaps an offset back to 
the root `C`, so the vtable can be shared). This would allow field access and 
non-virtual methods to work exactly as they do on a non-virtual class, and 
virtual methods would look up the root C object before resolving (and 
dynamic_cast<> would use this as well).

Why can't something similar be done in Rust? I assume a ~Trait right now is a 
pair of pointers: a pointer to the wrapped object, and a pointer to the vtable. 
Stick the offset from the embedded field back to its parent in the vtable, and 
have the value pointer in the trait point to the portion of the wrapped value 
that represents the struct that the trait inherits from. This obviously means 
that traits are then required to only inherit from a single struct, but I think 
that's reasonable. And even that restriction could be lifted if ~Trait objects 
could be represented using an array of pointers (one to each inherited struct), 
e.g. ([*A,*B,*C],*vtable) instead of just (*A,*vtable), though I suspect this 
is not worth doing.

Anyway, if the trait object contains the pointer to the inherited struct, then 
field access would still be a constant offset, and virtual method calls could 
be done by looking up the "master" pointer from the vtable, just as I assume 
C++ multiple inheritance does.

-Kevin

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to