I've searched for a bit but can't seem to find anything, nor can I see anything in the output of the Swift compiler itself. My question: How does swift solve the abi stability problem where a class in a library adds a field but the subclass isn't recompiled so doesn't know about the change?
IIRC, if the compiler has to work through a resilience layer, it goes through an extra level of indirection when accessing properties, so that it's not tied to the layout of the actual type.
Right. From outside the defining module, all properties look as if they're "computed" and access goes through read/modify methods on the class instead of direct access. That way, if the layout of the class changes, or even if the property switches between being a stored or computed property, client code does not need to be recompiled. The class vtable is also built at runtime so that a base class adding methods to itself does not invalidate method dispatch on subclasses.
That's good to hear. What about Ivar offsets thought? If I read the ir correctly it uses a plain gep on a struct if I subclass an external module's class. I couldn't find any at runtime calculation for that ones offset. (Talking about the underlying field for a property in a subclass which parent class adds a new field)
You'll want to build your module by passing the
-enable-resilience flag to the compiler to use the resilient ABI.
Perfect. Thank you; that should get me going interoperating with Swift from a non-swift compiler.
I didn't think module resilience was a "supported" feature yet outside of the stdlib?
-enable-resilience controls both module and ABI stability. It is true that module stability won't be supported outside the standard library for Swift 5.0, but the ABI should be stable once 5.0 is released.