Skip to content

Commit 93bc84e

Browse files
committed
Start support for associated conformances
We need to add a version of swift_allocBox to the embedded runtime implementation for outline storage
1 parent f38ad4b commit 93bc84e

File tree

1 file changed

+45
-5
lines changed

1 file changed

+45
-5
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -962,13 +962,17 @@ namespace {
962962

963963
void addAssociatedType(AssociatedTypeDecl *assocType) {
964964
// In Embedded Swift witness tables don't have associated-types entries.
965-
if (assocType->getASTContext().LangOpts.hasFeature(Feature::Embedded))
965+
auto &langOpts = assocType->getASTContext().LangOpts;
966+
if (langOpts.hasFeature(Feature::Embedded) &&
967+
!langOpts.hasFeature(Feature::EmbeddedExistentials))
966968
return;
967969
Entries.push_back(WitnessTableEntry::forAssociatedType(assocType));
968970
}
969971

970972
void addAssociatedConformance(const AssociatedConformance &req) {
971-
if (req.getAssociation()->getASTContext().LangOpts.hasFeature(Feature::Embedded) &&
973+
auto &langOpts = req.getAssociation()->getASTContext().LangOpts;
974+
if (langOpts.hasFeature(Feature::Embedded) &&
975+
!langOpts.hasFeature(Feature::EmbeddedExistentials) &&
972976
!req.getAssociatedRequirement()->requiresClass()) {
973977
// If it's not a class protocol, the associated type can never be used to create
974978
// an existential. Therefore this witness entry is never used at runtime
@@ -1728,7 +1732,9 @@ class AccessorConformanceInfo : public ConformanceInfo {
17281732
SILEntries = SILEntries.slice(1);
17291733

17301734
// In Embedded Swift witness tables don't have associated-types entries.
1731-
if (IGM.Context.LangOpts.hasFeature(Feature::Embedded))
1735+
auto &langOpts = IGM.Context.LangOpts;
1736+
if (langOpts.hasFeature(Feature::Embedded) &&
1737+
!langOpts.hasFeature(Feature::EmbeddedExistentials))
17321738
return;
17331739

17341740
#ifndef NDEBUG
@@ -1745,6 +1751,17 @@ class AccessorConformanceInfo : public ConformanceInfo {
17451751
#endif
17461752

17471753
auto typeWitness = Conformance.getTypeWitness(assocType);
1754+
1755+
if (IGM.Context.LangOpts.hasFeature(Feature::EmbeddedExistentials)) {
1756+
// In Embedded Swift associated type witness point to the metadata.
1757+
llvm::Constant *witnessEntry = IGM.getAddrOfTypeMetadata(
1758+
typeWitness->getCanonicalType());
1759+
auto &schema = IGM.getOptions().PointerAuth
1760+
.ProtocolAssociatedTypeAccessFunctions;
1761+
Table.addSignedPointer(witnessEntry, schema, assocType);
1762+
return;
1763+
}
1764+
17481765
llvm::Constant *typeWitnessAddr =
17491766
IGM.getAssociatedTypeWitness(
17501767
typeWitness,
@@ -1768,8 +1785,9 @@ class AccessorConformanceInfo : public ConformanceInfo {
17681785
auto &entry = SILEntries.front();
17691786
(void)entry;
17701787
SILEntries = SILEntries.slice(1);
1771-
1772-
if (IGM.Context.LangOpts.hasFeature(Feature::Embedded) &&
1788+
auto &langOpts = IGM.Context.LangOpts;
1789+
if (langOpts.hasFeature(Feature::Embedded) &&
1790+
!langOpts.hasFeature(Feature::EmbeddedExistentials) &&
17731791
!requirement.getAssociatedRequirement()->requiresClass()) {
17741792
// If it's not a class protocol, the associated type can never be used to create
17751793
// an existential. Therefore this witness entry is never used at runtime
@@ -4534,6 +4552,28 @@ irgen::emitAssociatedTypeMetadataRef(IRGenFunction &IGF,
45344552
DynamicMetadataRequest request) {
45354553
auto &IGM = IGF.IGM;
45364554

4555+
// Im embedded with existentials mode the type metadata is directly referenced
4556+
// by the witness table.
4557+
if (IGF.IGM.Context.LangOpts.hasFeature(Feature::EmbeddedExistentials)) {
4558+
auto proto = assocType->getProtocol();
4559+
assert(!IGF.IGM.isResilient(proto, ResilienceExpansion::Maximal));
4560+
assert(!IGF.IGM.IRGen.Opts.UseRelativeProtocolWitnessTables);
4561+
4562+
auto &protoInfo = IGF.IGM.getProtocolInfo(proto, ProtocolInfoKind::Full);
4563+
auto index = protoInfo.getAssociatedTypeIndex(IGM, assocType);
4564+
auto slot =
4565+
slotForLoadOfOpaqueWitness(IGF, wtable, index.forProtocolWitnessTable(),
4566+
false/*isRelativeTable*/);
4567+
llvm::Value *assocTypeMetadata = IGF.emitInvariantLoad(slot);
4568+
4569+
if (auto &schema = IGF.getOptions().PointerAuth.ProtocolAssociatedTypeAccessFunctions) {
4570+
auto authInfo = PointerAuthInfo::emit(IGF, schema, slot.getAddress(), assocType);
4571+
assocTypeMetadata = emitPointerAuthAuth(IGF, assocTypeMetadata, authInfo);
4572+
4573+
}
4574+
4575+
return MetadataResponse::forComplete(assocTypeMetadata);
4576+
}
45374577
// Extract the requirements base descriptor.
45384578
auto reqBaseDescriptor =
45394579
IGM.getAddrOfProtocolRequirementsBaseDescriptor(

0 commit comments

Comments
 (0)