Skip to content

Commit 14edd57

Browse files
committed
Generalize Metadata Lookup for Shapes
1 parent d4952d5 commit 14edd57

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
@@ -2280,7 +2280,7 @@ static void installGetClassHook() {
22802280
unsigned SubstGenericParametersFromMetadata::
22812281
buildDescriptorPath(const ContextDescriptor *context,
22822282
Demangler &borrowFrom) const {
2283-
assert(sourceIsMetadata);
2283+
assert(sourceKind == SourceKind::Metadata);
22842284

22852285
// Terminating condition: we don't have a context.
22862286
if (!context)
@@ -2371,20 +2371,76 @@ buildEnvironmentPath(
23712371
return totalKeyParamCount;
23722372
}
23732373

2374+
unsigned SubstGenericParametersFromMetadata::buildShapePath(
2375+
const TargetExtendedExistentialTypeShape<InProcess> *shape) const {
2376+
unsigned totalParamCount = 0;
2377+
unsigned totalKeyParamCount = 0;
2378+
2379+
auto genSig = shape->getGeneralizationSignature();
2380+
if (!genSig.getParams().empty()) {
2381+
bool hasNonKeyGenericParams = false;
2382+
unsigned numKeyGenericParamsHere = 0;
2383+
for (const auto &gp : genSig.getParams()) {
2384+
if (gp.hasKeyArgument())
2385+
numKeyGenericParamsHere++;
2386+
else
2387+
hasNonKeyGenericParams = true;
2388+
}
2389+
totalParamCount += numKeyGenericParamsHere;
2390+
totalKeyParamCount += numKeyGenericParamsHere;
2391+
descriptorPath.push_back(PathElement{genSig.getParams(), totalParamCount,
2392+
/*numKeyGenericParamsInParent*/ 0,
2393+
numKeyGenericParamsHere,
2394+
hasNonKeyGenericParams});
2395+
}
2396+
2397+
const unsigned genSigParamCount = genSig.getParams().size();
2398+
auto reqSig = shape->getRequirementSignature();
2399+
assert(reqSig.getParams().size() > genSig.getParams().size());
2400+
{
2401+
bool hasNonKeyGenericParams = false;
2402+
unsigned numKeyGenericParamsHere = 0;
2403+
auto remainingParams = reqSig.getParams().drop_front(genSig.getParams().size());
2404+
for (const auto &gp : remainingParams) {
2405+
if (gp.hasKeyArgument())
2406+
numKeyGenericParamsHere++;
2407+
else
2408+
hasNonKeyGenericParams = true;
2409+
}
2410+
totalParamCount += numKeyGenericParamsHere;
2411+
totalKeyParamCount += numKeyGenericParamsHere;
2412+
descriptorPath.push_back(PathElement{remainingParams,
2413+
totalParamCount,
2414+
genSigParamCount,
2415+
numKeyGenericParamsHere,
2416+
hasNonKeyGenericParams});
2417+
}
2418+
2419+
return totalKeyParamCount;
2420+
}
2421+
23742422
void SubstGenericParametersFromMetadata::setup() const {
23752423
if (!descriptorPath.empty())
23762424
return;
23772425

2378-
if (sourceIsMetadata && baseContext) {
2426+
switch (sourceKind) {
2427+
case SourceKind::Metadata: {
2428+
assert(baseContext);
23792429
DemanglerForRuntimeTypeResolution<StackAllocatedDemangler<2048>> demangler;
23802430
numKeyGenericParameters = buildDescriptorPath(baseContext, demangler);
23812431
return;
23822432
}
2383-
2384-
if (!sourceIsMetadata && environment) {
2433+
case SourceKind::Environment: {
2434+
assert(environment);
23852435
numKeyGenericParameters = buildEnvironmentPath(environment);
23862436
return;
23872437
}
2438+
case SourceKind::Shape: {
2439+
assert(shape);
2440+
numKeyGenericParameters = buildShapePath(shape);
2441+
return;
2442+
}
2443+
}
23882444
}
23892445

23902446
const Metadata *

stdlib/public/runtime/Private.h

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

303308
union {
304309
const TargetContextDescriptor<InProcess> *baseContext;
305310
const TargetGenericEnvironment<InProcess> *environment;
311+
const TargetExtendedExistentialTypeShape<InProcess> *shape;
306312
};
307313

308314
/// The generic arguments.
@@ -344,31 +350,40 @@ class TypeInfo {
344350
unsigned buildEnvironmentPath(
345351
const TargetGenericEnvironment<InProcess> *environment) const;
346352

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

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

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

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

0 commit comments

Comments
 (0)