[ABI] Rework protocol descriptor metadata.

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.
This commit is contained in:
Doug Gregor
2018-07-23 17:01:13 -07:00
parent c56879da73
commit a54a6d8d7f
21 changed files with 528 additions and 550 deletions

View File

@@ -383,21 +383,28 @@ public:
}
#endif
auto ProtocolDescriptor = readSwiftProtocolDescriptor(
ProtocolAddress.getSwiftProtocol());
if (!ProtocolDescriptor)
// Read the protocol descriptor.
ContextDescriptorRef descriptor
= readContextDescriptor(ProtocolAddress.getSwiftProtocol());
if (!descriptor)
return BuiltType();
std::string MangledNameStr;
if (!Reader->readString(RemoteAddress(ProtocolDescriptor->Name),
MangledNameStr))
auto protocolBuffer =
reinterpret_cast<const TargetProtocolDescriptor<Runtime> *>
(descriptor.getLocalBuffer());
std::string mangledNameStr;
auto nameAddress = resolveRelativeField(descriptor,
protocolBuffer->Name);
if (!Reader->readString(RemoteAddress(nameAddress),
mangledNameStr))
return BuiltType();
StringRef MangledName =
Demangle::dropSwiftManglingPrefix(MangledNameStr);
StringRef mangledName =
Demangle::dropSwiftManglingPrefix(mangledNameStr);
Demangle::Context DCtx;
auto Demangled = DCtx.demangleTypeAsNode(MangledName);
auto Demangled = DCtx.demangleTypeAsNode(mangledName);
if (!Demangled)
return BuiltType();
@@ -1090,6 +1097,9 @@ private:
baseSize = sizeof(TargetStructDescriptor<Runtime>);
genericHeaderSize = sizeof(TypeGenericContextDescriptorHeader);
break;
case ContextDescriptorKind::Protocol:
baseSize = sizeof(TargetProtocolDescriptorRef<Runtime>);
break;
default:
// We don't know about this kind of context.
return nullptr;
@@ -1293,19 +1303,6 @@ private:
return decl;
}
OwnedProtocolDescriptorRef
readSwiftProtocolDescriptor(StoredPointer Address) {
auto Size = sizeof(TargetProtocolDescriptor<Runtime>);
auto Buffer = (uint8_t *)malloc(Size);
if (!Reader->readBytes(RemoteAddress(Address), Buffer, Size)) {
free(Buffer);
return nullptr;
}
auto Casted
= reinterpret_cast<TargetProtocolDescriptor<Runtime> *>(Buffer);
return OwnedProtocolDescriptorRef(Casted);
}
#if SWIFT_OBJC_INTEROP
std::string readObjCProtocolName(StoredPointer Address) {
auto Size = sizeof(TargetObjCProtocolPrefix<Runtime>);