Skip to content

Commit bc48f14

Browse files
committed
[Runtime] Eagerly realize mangled base protocol witnesses.
If the witness for a base protocol is a mangled name, eagerly turn that name into a witness table via swift_getAssociatedConformanceWitness(). This allows the compiler to emit base protocol witnesses as mangled names (as it does for associated conformances). (cherry picked from commit 3ef38ab)
1 parent 9f7531d commit bc48f14

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3999,6 +3999,27 @@ static void initializeResilientWitnessTable(
39993999
}
40004000
}
40014001

4002+
/// Realize witness tables for base protocols.
4003+
static void realizeBaseProtocolWitnessTables(const ProtocolDescriptor *protocol,
4004+
const Metadata *conformingType,
4005+
WitnessTable *witnessTable) {
4006+
// Loop over the requirements, realizing witness tables for base class
4007+
// conformances.
4008+
auto requirements = protocol->getRequirements();
4009+
auto baseReq = protocol->getRequirementBaseDescriptor();
4010+
for (size_t i = 0, e = protocol->NumRequirements; i < e; ++i) {
4011+
// Once we hit a non-base protocol requirement, we're done.
4012+
auto &reqt = requirements[i];
4013+
if (reqt.Flags.getKind() != ProtocolRequirementFlags::Kind::BaseProtocol)
4014+
break;
4015+
4016+
// Realize the base protocol witness table.
4017+
(void)swift_getAssociatedConformanceWitness(witnessTable,
4018+
conformingType, conformingType,
4019+
baseReq, &reqt);
4020+
}
4021+
}
4022+
40024023
/// Instantiate a brand new witness table for a resilient or generic
40034024
/// protocol conformance.
40044025
WitnessTable *
@@ -4039,8 +4060,8 @@ WitnessTableCacheEntry::allocate(
40394060

40404061
// Fill in any default requirements.
40414062
initializeResilientWitnessTable(conformance, genericTable, table);
4042-
40434063
auto castTable = reinterpret_cast<WitnessTable*>(table);
4064+
realizeBaseProtocolWitnessTables(protocol, Type, castTable);
40444065

40454066
// Call the instantiation function if present.
40464067
if (!genericTable->Instantiator.isNull()) {
@@ -4073,7 +4094,10 @@ swift::swift_getWitnessTable(const ProtocolConformanceDescriptor *conformance,
40734094
// accessor directly.
40744095
auto genericTable = conformance->getGenericWitnessTable();
40754096
if (!genericTable || doesNotRequireInstantiation(conformance, genericTable)) {
4076-
return uniqueForeignWitnessTableRef(conformance->getWitnessTablePattern());
4097+
auto pattern = conformance->getWitnessTablePattern();
4098+
realizeBaseProtocolWitnessTables(conformance->getProtocol(), type,
4099+
const_cast<WitnessTable *>(pattern));
4100+
return uniqueForeignWitnessTableRef(pattern);
40774101
}
40784102

40794103
auto &cache = getCache(genericTable);

0 commit comments

Comments
 (0)