Previously we would emit class metadata for classes with resilient
ancestry, and relocate it at runtime once the correct size was known.
However most of the fields were blank, so it makes more sense to
construct the metadata from scratch, and store the few bits that we
do need in a true-const pattern where we can use relative pointers.
Similar to the non-resilient case, except we also emit a 'relocation
function'. The class descriptor now contains this relocation function
if the class has resilient ancestry, and the relocation function
calls the runtime's swift_relocateClassMetadata() entry point.
The metadata completion function calls swift_initClassMetadata() and
does layout, just like the non-resilient case.
Fixes <rdar://problem/40810002>.
This saves us some expensive cross-referencing and caching in the runtime, and lets us reclaim the `isReflectable` bit from the context descriptor flags (since a null field descriptor is a suitable and more accurate indicator of whether a type is reflectable).
- Instead of keeping multiple flags in the type descriptor flags,
just keep a single flag indicating the presence of additional
import information after the name.
- That import information consists of a sequence of null-terminated
C strings, terminated by an empty string (i.e. by a double null
terminator), each prefixed with a character describing its purpose.
- In addition to the symbol namespace and related entity name,
include the ABI name if it differs from the user-facing name of the
type, and make the name the user-facing Swift name.
There's a remaining issue here that isn't great: we don't correctly
represent the parent relationship between error types and their codes,
and instead we just use the Clang module as the parent. But I'll
leave that for a later commit.
- `swift_getForeignTypeMetadata` is now a request/response function.
- The initialization function is now a completion function, and the
pointer to it has moved into the type descriptor.
- The cache variable is no longer part of the ABI; it's an
implementation detail of the access function.
- The two points above mean that there is no special header on foreign
type metadata and therefore that they can be marked constant when
there isn't something about them that needs to be initialized.
The only foreign-metadata initialization we actually do right now is
of the superclass field of a foreign class, and since that relationship
is a proper DAG, it's not actually possible to have recursive
initialization problems. But this is the right long-term thing to do,
and it removes one of the last two clients of once-based initialization.
As part of this, rename TypeMetadataRecordKind to TypeReferenceKind
and consistently give it three bits of storage.
The better modelling of these type references appears to have been
sufficient to make dynamic conformance checks succeed, which is good
but unexpected.
From what I see the only fields are DATA_VALUE_WITNESS which
all have type size_t. I converted them to use the target-dependent
`StoredSize`. While I was around I fixed also isValueInline()
to do the right thing (it was using ValueBuffer instead of
TargetValueBuffer) and all the getters for the data value witnesses.
<rdar://problem/41546568>
Protocols are never generic, so don't inherit from
TrailingGenericContextObjects. Instead, directly use
swift::ABI::TrailingObjects. Since protocols are never generic, this
doesn't actually affect layout at all; it's cleanup.
These were used to encode the “inherited protocols” for Objective-C
Protocol structures. These are no longer a part of either Swift protocol
descriptors or the part of Objective-C Protocol structures that the
Swift runtime inspects.
Reimplement protocol descriptors for Swift protocols as a kind of
context descriptor, dropping the Objective-C protocol compatibility
layout. The new protocol descriptors have several advantages over the
current implementation:
* They drop all of the unused fields required for layout-compatibility
with Objective-C protocols.
* They encode the full requirement signature of the protocol. This
maintains more information about the protocol itself, including
(e.g.) correctly encoding superclass requirements.
* They fit within the general scheme of context descriptors, rather than
being their own thing, which allows us to share more code with
nominal type descriptors.
* They only use relative pointers, so they’re smaller and can be placed
in read-only memory
Implements rdar://problem/38815359.
When reading the protocol metadata from existential type metadata,
check the “isObjC” bit and handle the reading of the Objective-C
protocol name (using TargetObjCProtocolPrefix) separately from the reading the name of a Swift protocol (using TargetProtocolDescriptor).
More preparation for separating the layout of these two entities.
Introduce TargetObjCProtocolPrefix, which describes just enough of the
Objective-C runtime’s Protocol structure to extract the name without
having to call Objective-C’s protocol_getName().
In a generic requirement, distinguish between Swift and
Objective-C protocols using a spare bit within the relative
(indirectable) reference to the protocol.
Switch one entry point in the runtime (swift_getExistentialTypeMetadata)
to use ProtocolDescriptorRef rather than a protocol descriptor. Update
IRGen to produce ProtocolDescriptorRef instances for its calls, setting
the discriminator bit appropriately.
Within the runtime, verify that all instances of ProtocolDescriptorRef have
the right layout, i.e., the discriminator bit is set for @objc protocols
but not Swift protocols.
Use ProtocolDescriptorRefs within the runtime representation of
existential type metadata (TargetExistentialTypeMetadata) instead of
bare protocol descriptor pointers. Start rolling out the use of
ProtocolDescriptorRef in a few places in the runtime that touch this
code. Note that we’re not yet establishing any strong invariants on
the TargetProtocolDescriptorRef instances.
While here, replace TargetExistentialTypeMetadata’s hand-rolled pointer
arithmetic with swift::ABI::TrailingObjects and centralize knowledge of
its layout better.
TargetProtocolDescriptorRef provides a reference to either a Swift or
an Objective-C protocol, using a spare bit to indicate which kind of
protocol it is. At present, the protocol descriptor also has this
information (so this is redundant), but that will change shortly.
There are no clients of TargetProtocolDescriptorRef yet.
Clang-importer-synthesized declarations get an extra tag character included in their mangling, which was not being preserved in type context descriptors. This caused runtime lookup for these synthesized types to fail. Fix this by adding the tag information to type context descriptors and teaching the runtime to match it up when fetching metadata by mangled name. Fixes rdar://problem/40878715.
Runtime/Metadata.h collected a large number of metadata data
structures that are actually part of the ABI. Move those data
structures into a new header, ABI/Metadata.h, and keep the in-process,
runtime-specific bits in Runtime/Metadata.h.