Runtime: Fix dynamic casts to support resilient protocols

If a protocol witness table requires instantiation, the runtime
needs to call the witness table accessor when looking up the
conformance in swift_conformsToProtocol().

We had a bit of code for this already, but it wasn't fully
hooked up. Change IRGen to emit a reference to the witness table
accessor rather than the witness table itself if the witness
table needs instantiation, and add support to the runtime for
calling the accessor.
This commit is contained in:
Slava Pestov
2016-09-27 17:26:05 -07:00
parent 1a2beb7cda
commit 53b3a69a9a
5 changed files with 64 additions and 22 deletions

View File

@@ -637,15 +637,11 @@ recur:
C.cacheFailure(metadata, P);
}
// If the record provides a nondependent witness table for all instances
// of a generic type, cache it for the generic pattern.
// TODO: "Nondependent witness table" probably deserves its own flag.
// An accessor function might still be necessary even if the witness table
// can be shared.
} else if (record.getTypeKind()
== TypeMetadataRecordKind::UniqueNominalTypeDescriptor
&& record.getConformanceKind()
== ProtocolConformanceReferenceKind::WitnessTable) {
== TypeMetadataRecordKind::UniqueNominalTypeDescriptor) {
auto R = record.getNominalTypeDescriptor();
auto P = record.getProtocol();
@@ -658,7 +654,20 @@ recur:
continue;
// Store the type-protocol pair in the cache.
C.cacheSuccess(R, P, record.getStaticWitnessTable());
switch (record.getConformanceKind()) {
case ProtocolConformanceReferenceKind::WitnessTable:
// If the record provides a nondependent witness table for all
// instances of a generic type, cache it for the generic pattern.
C.cacheSuccess(R, P, record.getStaticWitnessTable());
break;
case ProtocolConformanceReferenceKind::WitnessTableAccessor:
// If the record provides a dependent witness table accessor,
// cache the result for the instantiated type metadata.
C.cacheSuccess(type, P, record.getWitnessTable(type));
break;
}
}
}
}