This library uses GenericMetadataBuilder with a ReaderWriter that can read data and resolve pointers from MachO files, and emit a JSON representation of a dylib containing the built metadata.
We use LLVM's binary file readers to parse the MachO files and resolve fixups so we can follow pointers. This code is somewhat MachO specific, but could be generalized to other formats that LLVM supports.
rdar://116592577
`AbsoluteFunctionPointer` was not able to be passed to a function that
takes a `TargetCompactFunctionPointer` because the template parameters
`Nullable` and `Offset` were not parameterized by `AbsoluteFunctionPointer`.
29c350e813 introduced the first such
function `InProcessReaderWriter::resolveFunctionPointer` and it revealed
this issue.
When SWIFT_COMPACT_ABSOLUTE_FUNCTION_POINTER is enabled, relative direct
pointers whose pointees are functions will be turned into absolute
pointer at compile-time.
The immediate use case is only concretely-constrained existential
types, which could use a much simpler representation, but I've
future-proofed the representation as much as I can; thus, the
requirement signature can have arbitrary parameters and
requirements, and the type can have an arbitrary type as the
sub-expression. The latter is also necessary for existential
metatypes.
The chief implementation complexity here is that we must be able
to agree on the identity of an existential type that might be
produced by substitution. Thus, for example, `any P<T>` when
`T == Int` must resolve to the same type metadata as
`any P<Int>`. To handle this, we identify the "shape" of the
existential type, consisting of those parts which cannot possibly
be the result of substitution, and then abstract the substitutable
"holes" as an application of a generalization signature. That
algorithm will come in a later patch; this patch just represents
it.
Uniquing existential shapes from the requirements would be quite
complex because of all the symbolic mangled names they use.
This is particularly true because it's not reasonable to require
translation units to agree about what portions they mangle vs.
reference symbolically. Instead, we expect the compiler to do
a cryptographic hash of a mangling of the shape, then use that
as the unique key identifying the shape.
This is just the core representation and runtime interface; other
parts of the runtime, such as dynamic casting and demangling
support, will come later.