Skip to content

Commit 8e7733d

Browse files
committed
Generalize Metadata Lookup for Shapes
1 parent 603558f commit 8e7733d

File tree

2 files changed

+88
-17
lines changed

2 files changed

+88
-17
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2269,7 +2269,7 @@ static void installGetClassHook() {
22692269
unsigned SubstGenericParametersFromMetadata::
22702270
buildDescriptorPath(const ContextDescriptor *context,
22712271
Demangler &borrowFrom) const {
2272-
assert(sourceIsMetadata);
2272+
assert(sourceKind == SourceKind::Metadata);
22732273

22742274
// Terminating condition: we don't have a context.
22752275
if (!context)
@@ -2360,20 +2360,76 @@ buildEnvironmentPath(
23602360
return totalKeyParamCount;
23612361
}
23622362

2363+
unsigned SubstGenericParametersFromMetadata::buildShapePath(
2364+
const TargetExtendedExistentialTypeShape<InProcess> *shape) const {
2365+
unsigned totalParamCount = 0;
2366+
unsigned totalKeyParamCount = 0;
2367+
2368+
auto genSig = shape->getGeneralizationSignature();
2369+
if (!genSig.getParams().empty()) {
2370+
bool hasNonKeyGenericParams = false;
2371+
unsigned numKeyGenericParamsHere = 0;
2372+
for (const auto &gp : genSig.getParams()) {
2373+
if (gp.hasKeyArgument())
2374+
numKeyGenericParamsHere++;
2375+
else
2376+
hasNonKeyGenericParams = true;
2377+
}
2378+
totalParamCount += numKeyGenericParamsHere;
2379+
totalKeyParamCount += numKeyGenericParamsHere;
2380+
descriptorPath.push_back(PathElement{genSig.getParams(), totalParamCount,
2381+
/*numKeyGenericParamsInParent*/ 0,
2382+
numKeyGenericParamsHere,
2383+
hasNonKeyGenericParams});
2384+
}
2385+
2386+
const unsigned genSigParamCount = genSig.getParams().size();
2387+
auto reqSig = shape->getRequirementSignature();
2388+
assert(reqSig.getParams().size() > genSig.getParams().size());
2389+
{
2390+
bool hasNonKeyGenericParams = false;
2391+
unsigned numKeyGenericParamsHere = 0;
2392+
auto remainingParams = reqSig.getParams().drop_front(genSig.getParams().size());
2393+
for (const auto &gp : remainingParams) {
2394+
if (gp.hasKeyArgument())
2395+
numKeyGenericParamsHere++;
2396+
else
2397+
hasNonKeyGenericParams = true;
2398+
}
2399+
totalParamCount += numKeyGenericParamsHere;
2400+
totalKeyParamCount += numKeyGenericParamsHere;
2401+
descriptorPath.push_back(PathElement{remainingParams,
2402+
totalParamCount,
2403+
genSigParamCount,
2404+
numKeyGenericParamsHere,
2405+
hasNonKeyGenericParams});
2406+
}
2407+
2408+
return totalKeyParamCount;
2409+
}
2410+
23632411
void SubstGenericParametersFromMetadata::setup() const {
23642412
if (!descriptorPath.empty())
23652413
return;
23662414

2367-
if (sourceIsMetadata && baseContext) {
2415+
switch (sourceKind) {
2416+
case SourceKind::Metadata: {
2417+
assert(baseContext);
23682418
DemanglerForRuntimeTypeResolution<StackAllocatedDemangler<2048>> demangler;
23692419
numKeyGenericParameters = buildDescriptorPath(baseContext, demangler);
23702420
return;
23712421
}
2372-
2373-
if (!sourceIsMetadata && environment) {
2422+
case SourceKind::Environment: {
2423+
assert(environment);
23742424
numKeyGenericParameters = buildEnvironmentPath(environment);
23752425
return;
23762426
}
2427+
case SourceKind::Shape: {
2428+
assert(shape);
2429+
numKeyGenericParameters = buildShapePath(shape);
2430+
return;
2431+
}
2432+
}
23772433
}
23782434

23792435
const Metadata *

stdlib/public/runtime/Private.h

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,17 @@ class TypeInfo {
297297
/// types.
298298
class SWIFT_RUNTIME_LIBRARY_VISIBILITY SubstGenericParametersFromMetadata {
299299
/// Whether the source is metadata (vs. a generic environment);
300-
const bool sourceIsMetadata;
300+
enum class SourceKind {
301+
Metadata,
302+
Environment,
303+
Shape,
304+
};
305+
const SourceKind sourceKind;
301306

302307
union {
303308
const TargetContextDescriptor<InProcess> *baseContext;
304309
const TargetGenericEnvironment<InProcess> *environment;
310+
const TargetExtendedExistentialTypeShape<InProcess> *shape;
305311
};
306312

307313
/// The generic arguments.
@@ -343,31 +349,40 @@ class TypeInfo {
343349
unsigned buildEnvironmentPath(
344350
const TargetGenericEnvironment<InProcess> *environment) const;
345351

352+
unsigned buildShapePath(
353+
const TargetExtendedExistentialTypeShape<InProcess> *shape) const;
354+
346355
// Set up the state we need to compute substitutions.
347356
void setup() const;
348357

349358
public:
350359
/// Produce substitutions entirely from the given metadata.
351360
explicit SubstGenericParametersFromMetadata(const Metadata *base)
352-
: sourceIsMetadata(true), baseContext(base->getTypeContextDescriptor()),
353-
genericArgs(base ? (const void * const *)base->getGenericArgs()
354-
: nullptr) { }
355-
361+
: sourceKind(SourceKind::Metadata),
362+
baseContext(base->getTypeContextDescriptor()),
363+
genericArgs(base ? (const void *const *)base->getGenericArgs()
364+
: nullptr) {}
365+
356366
/// Produce substitutions from the given instantiation arguments for the
357367
/// given context.
358368
explicit SubstGenericParametersFromMetadata(const ContextDescriptor *base,
359-
const void * const *args)
360-
: sourceIsMetadata(true), baseContext(base), genericArgs(args)
361-
{}
369+
const void *const *args)
370+
: sourceKind(SourceKind::Metadata), baseContext(base),
371+
genericArgs(args) {}
362372

363373
/// Produce substitutions from the given instantiation arguments for the
364374
/// given generic environment.
365375
explicit SubstGenericParametersFromMetadata(
366-
const TargetGenericEnvironment<InProcess> *environment,
367-
const void * const *arguments)
368-
: sourceIsMetadata(false), environment(environment),
369-
genericArgs(arguments) { }
370-
376+
const TargetGenericEnvironment<InProcess> *environment,
377+
const void *const *arguments)
378+
: sourceKind(SourceKind::Environment), environment(environment),
379+
genericArgs(arguments) {}
380+
381+
explicit SubstGenericParametersFromMetadata(
382+
const TargetExtendedExistentialTypeShape<InProcess> *shape,
383+
const void *const *arguments)
384+
: sourceKind(SourceKind::Shape), shape(shape), genericArgs(arguments) {}
385+
371386
const void * const *getGenericArgs() const { return genericArgs; }
372387

373388
const Metadata *getMetadata(unsigned depth, unsigned index) const;

0 commit comments

Comments
 (0)