Skip to content

Commit 9052579

Browse files
authored
Merge pull request swiftlang#20592 from DougGregor/runtime-get-assoc-typeconformance-override
2 parents 739169d + 7594762 commit 9052579

File tree

4 files changed

+129
-7
lines changed

4 files changed

+129
-7
lines changed

stdlib/public/runtime/CompatibilityOverride.def

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
# define OVERRIDE_FOREIGN OVERRIDE
4545
# define OVERRIDE_PROTOCOLCONFORMANCE OVERRIDE
4646
# define OVERRIDE_KEYPATH OVERRIDE
47+
# define OVERRIDE_WITNESSTABLE OVERRIDE
4748
#else
4849
# ifndef OVERRIDE_METADATALOOKUP
4950
# define OVERRIDE_METADATALOOKUP(...)
@@ -63,6 +64,9 @@
6364
# ifndef OVERRIDE_KEYPATH
6465
# define OVERRIDE_KEYPATH(...)
6566
# endif
67+
# ifndef OVERRIDE_WITNESSTABLE
68+
# define OVERRIDE_WITNESSTABLE(...)
69+
# endif
6670
#endif
6771

6872
OVERRIDE_METADATALOOKUP(getTypeByMangledName, const Metadata *,
@@ -140,6 +144,22 @@ OVERRIDE_KEYPATH(getKeyPath, const HeapObject *, , swift::,
140144
(const void *pattern, const void *arguments),
141145
(pattern, arguments))
142146

147+
OVERRIDE_WITNESSTABLE(getAssociatedTypeWitnessSlow, MetadataResponse,
148+
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL, swift::,
149+
(MetadataRequest request, WitnessTable *wtable,
150+
const Metadata *conformingType,
151+
const ProtocolRequirement *reqBase,
152+
const ProtocolRequirement *assocType),
153+
(request, wtable, conformingType, reqBase, assocType))
154+
155+
OVERRIDE_WITNESSTABLE(getAssociatedConformanceWitnessSlow, const WitnessTable *,
156+
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL, swift::,
157+
(WitnessTable *wtable, const Metadata *conformingType,
158+
const Metadata *assocType,
159+
const ProtocolRequirement *reqBase,
160+
const ProtocolRequirement *assocConformance),
161+
(wtable, conformingType, assocType, reqBase,
162+
assocConformance))
143163
#if SWIFT_OBJC_INTEROP
144164

145165
OVERRIDE_OBJC(dynamicCastObjCClass, const void *, , swift::,
@@ -183,3 +203,4 @@ OVERRIDE_FOREIGN(dynamicCastForeignClassUnconditional, const void *, , swift::,
183203
#undef OVERRIDE_FOREIGN
184204
#undef OVERRIDE_PROTOCOLCONFORMANCE
185205
#undef OVERRIDE_KEYPATH
206+
#undef OVERRIDE_WITNESSTABLE

stdlib/public/runtime/Metadata.cpp

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4053,13 +4053,13 @@ static StringRef findAssociatedTypeName(const ProtocolDescriptor *protocol,
40534053
return StringRef();
40544054
}
40554055

4056-
MetadataResponse
4057-
swift::swift_getAssociatedTypeWitness(MetadataRequest request,
4056+
static MetadataResponse
4057+
swift_getAssociatedTypeWitnessSlowImpl(
4058+
MetadataRequest request,
40584059
WitnessTable *wtable,
40594060
const Metadata *conformingType,
40604061
const ProtocolRequirement *reqBase,
40614062
const ProtocolRequirement *assocType) {
4062-
40634063
#ifndef NDEBUG
40644064
{
40654065
const ProtocolConformanceDescriptor *conformance = wtable->Description;
@@ -4077,7 +4077,7 @@ swift::swift_getAssociatedTypeWitness(MetadataRequest request,
40774077
unsigned witnessIndex = assocType - reqBase;
40784078
auto witness = ((const void* const *)wtable)[witnessIndex];
40794079
if (LLVM_LIKELY((uintptr_t(witness) &
4080-
ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0)) {
4080+
ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0)) {
40814081
// Cached metadata pointers are always complete.
40824082
return MetadataResponse{(const Metadata *)witness, MetadataState::Complete};
40834083
}
@@ -4158,7 +4158,26 @@ swift::swift_getAssociatedTypeWitness(MetadataRequest request,
41584158
return response;
41594159
}
41604160

4161-
const WitnessTable *swift::swift_getAssociatedConformanceWitness(
4161+
MetadataResponse
4162+
swift::swift_getAssociatedTypeWitness(MetadataRequest request,
4163+
WitnessTable *wtable,
4164+
const Metadata *conformingType,
4165+
const ProtocolRequirement *reqBase,
4166+
const ProtocolRequirement *assocType) {
4167+
// If the low bit of the witness is clear, it's already a metadata pointer.
4168+
unsigned witnessIndex = assocType - reqBase;
4169+
auto witness = ((const void* const *)wtable)[witnessIndex];
4170+
if (LLVM_LIKELY((uintptr_t(witness) &
4171+
ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0)) {
4172+
// Cached metadata pointers are always complete.
4173+
return MetadataResponse{(const Metadata *)witness, MetadataState::Complete};
4174+
}
4175+
4176+
return swift_getAssociatedTypeWitnessSlow(request, wtable, conformingType,
4177+
reqBase, assocType);
4178+
}
4179+
4180+
static const WitnessTable *swift_getAssociatedConformanceWitnessSlowImpl(
41624181
WitnessTable *wtable,
41634182
const Metadata *conformingType,
41644183
const Metadata *assocType,
@@ -4177,7 +4196,7 @@ const WitnessTable *swift::swift_getAssociatedConformanceWitness(
41774196
}
41784197
#endif
41794198

4180-
// Call the access function.
4199+
// Retrieve the witness.
41814200
unsigned witnessIndex = assocConformance - reqBase;
41824201
auto witness = ((const void* const *)wtable)[witnessIndex];
41834202
// Fast path: we've already resolved this to a witness table, so return it.
@@ -4222,6 +4241,26 @@ const WitnessTable *swift::swift_getAssociatedConformanceWitness(
42224241
swift_runtime_unreachable("Invalid mangled associate conformance");
42234242
}
42244243

4244+
const WitnessTable *swift::swift_getAssociatedConformanceWitness(
4245+
WitnessTable *wtable,
4246+
const Metadata *conformingType,
4247+
const Metadata *assocType,
4248+
const ProtocolRequirement *reqBase,
4249+
const ProtocolRequirement *assocConformance) {
4250+
// Retrieve the witness.
4251+
unsigned witnessIndex = assocConformance - reqBase;
4252+
auto witness = ((const void* const *)wtable)[witnessIndex];
4253+
// Fast path: we've already resolved this to a witness table, so return it.
4254+
if (LLVM_LIKELY((uintptr_t(witness) &
4255+
ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0)) {
4256+
return static_cast<const WitnessTable *>(witness);
4257+
}
4258+
4259+
return swift_getAssociatedConformanceWitnessSlow(wtable, conformingType,
4260+
assocType, reqBase,
4261+
assocConformance);
4262+
}
4263+
42254264
/***************************************************************************/
42264265
/*** Recursive metadata dependencies ***************************************/
42274266
/***************************************************************************/
@@ -4842,4 +4881,5 @@ const HeapObject *swift_getKeyPathImpl(const void *pattern,
48424881
const void *arguments);
48434882

48444883
#define OVERRIDE_KEYPATH COMPATIBILITY_OVERRIDE
4884+
#define OVERRIDE_WITNESSTABLE COMPATIBILITY_OVERRIDE
48454885
#include "CompatibilityOverride.def"

stdlib/public/runtime/Private.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,40 @@ class TypeInfo {
457457
const Metadata *findConformingSuperclass(
458458
const Metadata *type,
459459
const ProtocolConformanceDescriptor *conformance);
460+
461+
/// Retrieve an associated type witness from the given witness table.
462+
///
463+
/// \param wtable The witness table.
464+
/// \param conformingType Metadata for the conforming type.
465+
/// \param reqBase "Base" requirement used to compute the witness index
466+
/// \param assocType Associated type descriptor.
467+
///
468+
/// \returns metadata for the associated type witness.
469+
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
470+
MetadataResponse swift_getAssociatedTypeWitnessSlow(
471+
MetadataRequest request,
472+
WitnessTable *wtable,
473+
const Metadata *conformingType,
474+
const ProtocolRequirement *reqBase,
475+
const ProtocolRequirement *assocType);
476+
477+
/// Retrieve an associated conformance witness table from the given witness
478+
/// table.
479+
///
480+
/// \param wtable The witness table.
481+
/// \param conformingType Metadata for the conforming type.
482+
/// \param assocType Metadata for the associated type.
483+
/// \param reqBase "Base" requirement used to compute the witness index
484+
/// \param assocConformance Associated conformance descriptor.
485+
///
486+
/// \returns corresponding witness table.
487+
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
488+
const WitnessTable *swift_getAssociatedConformanceWitnessSlow(
489+
WitnessTable *wtable,
490+
const Metadata *conformingType,
491+
const Metadata *assocType,
492+
const ProtocolRequirement *reqBase,
493+
const ProtocolRequirement *assocConformance);
460494
} // end namespace swift
461495

462496
#endif /* SWIFT_RUNTIME_PRIVATE_H */

unittests/runtime/CompatibilityOverride.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,25 @@ using namespace swift;
2424
bool EnableOverride;
2525
bool Ran;
2626

27+
namespace {
28+
template<typename T>
29+
T getEmptyValue() {
30+
return (T)0;
31+
}
32+
33+
template<>
34+
MetadataResponse getEmptyValue<MetadataResponse>() {
35+
return MetadataResponse{nullptr, MetadataState::Complete};
36+
}
37+
}
2738

2839
#define OVERRIDE(name, ret, attrs, namespace, typedArgs, namedArgs) \
2940
static ret name ## Override(COMPATIBILITY_UNPAREN typedArgs, \
3041
Original_ ## name originalImpl) { \
3142
if (!EnableOverride) \
3243
return originalImpl namedArgs; \
3344
Ran = true; \
34-
return (ret)0; \
45+
return getEmptyValue<ret>(); \
3546
}
3647
#include "../../stdlib/public/runtime/CompatibilityOverride.def"
3748

@@ -164,4 +175,20 @@ TEST_F(CompatibilityOverrideTest, test_swift_conformsToProtocol) {
164175
ASSERT_EQ(Result, nullptr);
165176
}
166177

178+
TEST_F(CompatibilityOverrideTest, test_swift_getAssociatedTypeWitnessSlow) {
179+
auto Result = swift_getAssociatedTypeWitnessSlow(MetadataState::Complete,
180+
nullptr, nullptr,
181+
nullptr, nullptr);
182+
ASSERT_EQ(Result.Value, nullptr);
183+
ASSERT_EQ(Result.State, MetadataState::Complete);
184+
}
185+
186+
TEST_F(CompatibilityOverrideTest,
187+
test_swift_getAssociatedConformanceWitnessSlow) {
188+
auto Result = swift_getAssociatedConformanceWitnessSlow(
189+
nullptr, nullptr, nullptr,
190+
nullptr, nullptr);
191+
ASSERT_EQ(Result, nullptr);
192+
}
193+
167194
#endif

0 commit comments

Comments
 (0)