Friday, September 28, 2018

How Swift’s Mirror Works

Mike Ash (now at Apple, but thankfully allowed to blog):

There isn’t a single universal way to fetch the info we want from any type. Tuples, structs, classes, and enums all need different code for many of these tasks, such as looking up the number of children. There are further subtleties, such as different treatment for Swift and Objective-C classes.

All of these functions will need code that disptaches to different implementations based on what kind of type is being examined. This sounds a lot like dynamic dispatch of methods, except that the choice of which implementation to call is more complicated than checking the class of the object the method is being used on. The reflection code attempts to simplify matters by using C++ dynamic dispatch with an abstract base class that contains a C++ version of the above interface, and a bunch of subclasses covering all the various cases. A single function maps a Swift type to an instance of one of those C++ classes. Calling a method on that instance then dispatches to the appropriate implementation.


Looking up the elements in structs, classes, and enums is currently quite complex. Much of this complexity is due to the lack of a direct reference between these types and the field descriptors which contain the information about a type’s fields. A helper function called swift_getFieldAt searches for the appropriate field descriptor for a given type. This whole function should go away once we add that direct reference, but in the meantime it provides an interesting look at how the runtime code is able to use the language’s metadata to look up type information.

Comments RSS · Twitter

Leave a Comment