@@ -946,6 +946,9 @@ namespace {
946946 }
947947
948948 void addAssociatedType (AssociatedType requirement) {
949+ // In Embedded Swift witness tables don't have associated-types entries.
950+ if (requirement.getAssociation ()->getASTContext ().LangOpts .hasFeature (Feature::Embedded))
951+ return ;
949952 Entries.push_back (WitnessTableEntry::forAssociatedType (requirement));
950953 }
951954
@@ -1671,6 +1674,10 @@ class AccessorConformanceInfo : public ConformanceInfo {
16711674 auto &entry = SILEntries.front ();
16721675 SILEntries = SILEntries.slice (1 );
16731676
1677+ // In Embedded Swift witness tables don't have associated-types entries.
1678+ if (IGM.Context .LangOpts .hasFeature (Feature::Embedded))
1679+ return ;
1680+
16741681#ifndef NDEBUG
16751682 assert (entry.getKind () == SILWitnessTable::AssociatedType
16761683 && " sil witness table does not match protocol" );
@@ -1735,6 +1742,16 @@ class AccessorConformanceInfo : public ConformanceInfo {
17351742 " offset doesn't match ProtocolInfo layout" );
17361743#endif
17371744
1745+ if (IGM.Context .LangOpts .hasFeature (Feature::Embedded)) {
1746+ // In Embedded Swift associated-conformance entries simply point to the witness table
1747+ // of the associated conformance.
1748+ llvm::Constant *witnessEntry = IGM.getAddrOfWitnessTable (associatedConformance.getConcrete ());
1749+ auto &schema = IGM.getOptions ().PointerAuth
1750+ .ProtocolAssociatedTypeWitnessTableAccessFunctions ;
1751+ Table.addSignedPointer (witnessEntry, schema, requirement);
1752+ return ;
1753+ }
1754+
17381755 llvm::Constant *witnessEntry =
17391756 getAssociatedConformanceWitness (requirement, associate,
17401757 associatedConformance);
@@ -2670,11 +2687,11 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
26702687 // Produce the initializer value.
26712688 auto initializer = wtableContents.finishAndCreateFuture ();
26722689
2690+ auto *normalConf = dyn_cast<NormalProtocolConformance>(conf);
26732691 global = cast<llvm::GlobalVariable>(
26742692 (isDependent && conf->getDeclContext ()->isGenericContext () &&
2675- !useRelativeProtocolWitnessTable)
2676- ? getAddrOfWitnessTablePattern (cast<NormalProtocolConformance>(conf),
2677- initializer)
2693+ !useRelativeProtocolWitnessTable && normalConf)
2694+ ? getAddrOfWitnessTablePattern (normalConf, initializer)
26782695 : getAddrOfWitnessTable (conf, initializer));
26792696 // Eelative protocol witness tables are always constant. They don't cache
26802697 // results in the table.
@@ -3321,6 +3338,18 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
33213338
33223339 if (!source) return MetadataResponse ();
33233340
3341+ AssociatedConformance associatedConformanceRef (sourceProtocol,
3342+ association,
3343+ associatedRequirement);
3344+
3345+ if (IGF.IGM .Context .LangOpts .hasFeature (Feature::Embedded)) {
3346+ // In Embedded Swift associated-conformance entries simply point to the witness table
3347+ // of the associated conformance.
3348+ llvm::Value *sourceWTable = source.getMetadata ();
3349+ llvm::Value *associatedWTable = emitAssociatedConformanceValue (IGF, sourceWTable, associatedConformanceRef);
3350+ return MetadataResponse::forComplete (associatedWTable);
3351+ }
3352+
33243353 auto *sourceMetadata =
33253354 IGF.emitAbstractTypeMetadataRef (sourceType);
33263355
@@ -3394,10 +3423,7 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
33943423
33953424 auto sourceWTable = source.getMetadata ();
33963425
3397- AssociatedConformance associatedConformanceRef (sourceProtocol,
3398- association,
3399- associatedRequirement);
3400- auto associatedWTable =
3426+ auto associatedWTable =
34013427 emitAssociatedTypeWitnessTableRef (IGF, sourceMetadata, sourceWTable,
34023428 associatedConformanceRef,
34033429 associatedMetadata);
@@ -4329,6 +4355,29 @@ FunctionPointer irgen::emitWitnessMethodValue(IRGenFunction &IGF,
43294355 signature);
43304356}
43314357
4358+ llvm::Value *irgen::emitAssociatedConformanceValue (IRGenFunction &IGF,
4359+ llvm::Value *wtable,
4360+ const AssociatedConformance &conf) {
4361+ auto proto = conf.getSourceProtocol ();
4362+ assert (!IGF.IGM .isResilient (proto, ResilienceExpansion::Maximal));
4363+
4364+ // Find the witness we're interested in.
4365+ auto &fnProtoInfo = IGF.IGM .getProtocolInfo (proto, ProtocolInfoKind::Full);
4366+ auto index = fnProtoInfo.getAssociatedConformanceIndex (conf);
4367+ assert (!IGF.IGM .IRGen .Opts .UseRelativeProtocolWitnessTables );
4368+
4369+ wtable = IGF.optionallyLoadFromConditionalProtocolWitnessTable (wtable);
4370+ auto slot =
4371+ slotForLoadOfOpaqueWitness (IGF, wtable, index.forProtocolWitnessTable (),
4372+ false /* isRelativeTable*/ );
4373+ llvm::Value *confPointer = IGF.emitInvariantLoad (slot);
4374+ if (auto &schema = IGF.getOptions ().PointerAuth .ProtocolAssociatedTypeWitnessTableAccessFunctions ) {
4375+ auto authInfo = PointerAuthInfo::emit (IGF, schema, slot.getAddress (), conf);
4376+ confPointer = emitPointerAuthAuth (IGF, confPointer, authInfo);
4377+ }
4378+ return confPointer;
4379+ }
4380+
43324381FunctionPointer irgen::emitWitnessMethodValue (
43334382 IRGenFunction &IGF, CanType baseTy, llvm::Value **baseMetadataCache,
43344383 SILDeclRef member, ProtocolConformanceRef conformance) {
0 commit comments