@@ -946,6 +946,9 @@ namespace {
946
946
}
947
947
948
948
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 ;
949
952
Entries.push_back (WitnessTableEntry::forAssociatedType (requirement));
950
953
}
951
954
@@ -1671,6 +1674,10 @@ class AccessorConformanceInfo : public ConformanceInfo {
1671
1674
auto &entry = SILEntries.front ();
1672
1675
SILEntries = SILEntries.slice (1 );
1673
1676
1677
+ // In Embedded Swift witness tables don't have associated-types entries.
1678
+ if (IGM.Context .LangOpts .hasFeature (Feature::Embedded))
1679
+ return ;
1680
+
1674
1681
#ifndef NDEBUG
1675
1682
assert (entry.getKind () == SILWitnessTable::AssociatedType
1676
1683
&& " sil witness table does not match protocol" );
@@ -1735,6 +1742,16 @@ class AccessorConformanceInfo : public ConformanceInfo {
1735
1742
" offset doesn't match ProtocolInfo layout" );
1736
1743
#endif
1737
1744
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
+
1738
1755
llvm::Constant *witnessEntry =
1739
1756
getAssociatedConformanceWitness (requirement, associate,
1740
1757
associatedConformance);
@@ -2670,11 +2687,11 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
2670
2687
// Produce the initializer value.
2671
2688
auto initializer = wtableContents.finishAndCreateFuture ();
2672
2689
2690
+ auto *normalConf = dyn_cast<NormalProtocolConformance>(conf);
2673
2691
global = cast<llvm::GlobalVariable>(
2674
2692
(isDependent && conf->getDeclContext ()->isGenericContext () &&
2675
- !useRelativeProtocolWitnessTable)
2676
- ? getAddrOfWitnessTablePattern (cast<NormalProtocolConformance>(conf),
2677
- initializer)
2693
+ !useRelativeProtocolWitnessTable && normalConf)
2694
+ ? getAddrOfWitnessTablePattern (normalConf, initializer)
2678
2695
: getAddrOfWitnessTable (conf, initializer));
2679
2696
// Eelative protocol witness tables are always constant. They don't cache
2680
2697
// results in the table.
@@ -3321,6 +3338,18 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
3321
3338
3322
3339
if (!source) return MetadataResponse ();
3323
3340
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
+
3324
3353
auto *sourceMetadata =
3325
3354
IGF.emitAbstractTypeMetadataRef (sourceType);
3326
3355
@@ -3394,10 +3423,7 @@ MetadataResponse MetadataPath::followComponent(IRGenFunction &IGF,
3394
3423
3395
3424
auto sourceWTable = source.getMetadata ();
3396
3425
3397
- AssociatedConformance associatedConformanceRef (sourceProtocol,
3398
- association,
3399
- associatedRequirement);
3400
- auto associatedWTable =
3426
+ auto associatedWTable =
3401
3427
emitAssociatedTypeWitnessTableRef (IGF, sourceMetadata, sourceWTable,
3402
3428
associatedConformanceRef,
3403
3429
associatedMetadata);
@@ -4329,6 +4355,29 @@ FunctionPointer irgen::emitWitnessMethodValue(IRGenFunction &IGF,
4329
4355
signature);
4330
4356
}
4331
4357
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
+
4332
4381
FunctionPointer irgen::emitWitnessMethodValue (
4333
4382
IRGenFunction &IGF, CanType baseTy, llvm::Value **baseMetadataCache,
4334
4383
SILDeclRef member, ProtocolConformanceRef conformance) {
0 commit comments