Came across a slight fun factor today- namely, that derived classes don't get their own vtable, but they often need one.
In Wide's current vtable layout model, each class has a vtable listing all the dynamic functions it has, regardless of source, and then we add offset to top and RTTI pointer to that. For calling dynamic functions found in the base class, we convert to the base class pointer and look them up through the base class vtable.
However, this leaves us a problem with the offset-to-top and RTTI pointers, namely that we have a derived class which needs updated offset-to-top and RTTI but has no vtable of it's own. So if I have something like
type base { dynamic f() {} } // offset, rtti, f
type base2 { dynamic g() {} } // offset, rtti, g
type base3 { dynamic h() {} } // offset, rtti, h
type derived : base2, base {} // no vtable
type more_derived : base3, derived {} // no vtable
It's pretty clear here that when derived and more_derived are constructed, they need to set new offset and RTTI pointers in their base classes, which currently they do. The problem comes when implementing RTTI and dynamic_cast for derived itself, as it doesn't have a vtable carrying the necessary data. For RTTI I can probably poll for any vtable, as they should all have the same RTTI entry. offset-to-top is more problematic because every base has a different value, and that value would need to be adjusted depending on where you got it from to account for the derived class's other bases.
In addition, I could consider adding vtable slots for inherited virtual functions. There is an argument that in some circumstances these could be more efficient.
But if I move to Itanium ABI then that whole primary-base thing will take care of this, so I think that today I will simply do that.
No comments:
Post a Comment