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
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
