Requestify the mangling-to-metadata APIs.
Note that I've called out a couple of suspicious places where we are requesting abstract metadata for superclasses but probably need to be requesting something more complete.
This commit is contained in:
Родитель
570353aa42
Коммит
12c5e098e9
|
@ -145,17 +145,19 @@ OVERRIDE_KEYPATH(getKeyPath, const HeapObject *, , , swift::,
|
|||
(const void *pattern, const void *arguments),
|
||||
(pattern, arguments))
|
||||
|
||||
OVERRIDE_METADATALOOKUP(getTypeByMangledNode, TypeInfo, , , swift::,
|
||||
(Demangler &demangler,
|
||||
OVERRIDE_METADATALOOKUP(getTypeByMangledNode, TypeInfo, , SWIFT_CC(swift), swift::,
|
||||
(MetadataRequest request,
|
||||
Demangler &demangler,
|
||||
Demangle::NodePointer node,
|
||||
SubstGenericParameterFn substGenericParam,
|
||||
SubstDependentWitnessTableFn substWitnessTable),
|
||||
(demangler, node, substGenericParam, substWitnessTable))
|
||||
OVERRIDE_METADATALOOKUP(getTypeByMangledName, TypeInfo, , , swift::,
|
||||
(StringRef typeName,
|
||||
(request, demangler, node, substGenericParam, substWitnessTable))
|
||||
OVERRIDE_METADATALOOKUP(getTypeByMangledName, TypeInfo, , SWIFT_CC(swift), swift::,
|
||||
(MetadataRequest request,
|
||||
StringRef typeName,
|
||||
SubstGenericParameterFn substGenericParam,
|
||||
SubstDependentWitnessTableFn substWitnessTable),
|
||||
(typeName, substGenericParam, substWitnessTable))
|
||||
(request, typeName, substGenericParam, substWitnessTable))
|
||||
|
||||
OVERRIDE_WITNESSTABLE(getAssociatedTypeWitnessSlow, MetadataResponse,
|
||||
SWIFT_RUNTIME_STDLIB_INTERNAL, SWIFT_CC(swift), swift::,
|
||||
|
|
|
@ -2596,8 +2596,12 @@ swift::swift_initClassMetadata(ClassMetadata *self,
|
|||
StringRef superclassName =
|
||||
Demangle::makeSymbolicMangledNameStringRef(superclassNameBase);
|
||||
SubstGenericParametersFromMetadata substitutions(self);
|
||||
const Metadata *superclass =
|
||||
swift_getTypeByMangledName(superclassName, substitutions, substitutions);
|
||||
MetadataRequest request(/*FIXME*/MetadataState::Abstract,
|
||||
/*non-blocking*/ false);
|
||||
MetadataResponse response =
|
||||
swift_getTypeByMangledName(request, superclassName,
|
||||
substitutions, substitutions).getResponse();
|
||||
auto superclass = response.Value;
|
||||
if (!superclass) {
|
||||
fatalError(0,
|
||||
"failed to demangle superclass of %s from mangled name '%s'\n",
|
||||
|
@ -2686,8 +2690,12 @@ swift::swift_updateClassMetadata(ClassMetadata *self,
|
|||
StringRef superclassName =
|
||||
Demangle::makeSymbolicMangledNameStringRef(superclassNameBase);
|
||||
SubstGenericParametersFromMetadata substitutions(self);
|
||||
const Metadata *superclass =
|
||||
swift_getTypeByMangledName(superclassName, substitutions, substitutions);
|
||||
MetadataRequest request(/*FIXME*/MetadataState::Abstract,
|
||||
/*non-blocking*/ false);
|
||||
MetadataResponse response =
|
||||
swift_getTypeByMangledName(request, superclassName,
|
||||
substitutions, substitutions).getResponse();
|
||||
const Metadata *superclass = response.Value;
|
||||
if (!superclass) {
|
||||
fatalError(0,
|
||||
"failed to demangle superclass of %s from mangled name '%s'\n",
|
||||
|
@ -4192,12 +4200,12 @@ swift_getAssociatedTypeWitnessSlowImpl(
|
|||
Demangle::makeSymbolicMangledNameStringRef(mangledNameBase);
|
||||
|
||||
// Demangle the associated type.
|
||||
const Metadata *assocTypeMetadata;
|
||||
MetadataResponse response;
|
||||
if (inProtocolContext) {
|
||||
// The protocol's Self is the only generic parameter that can occur in the
|
||||
// type.
|
||||
assocTypeMetadata =
|
||||
swift_getTypeByMangledName(mangledName,
|
||||
response =
|
||||
swift_getTypeByMangledName(request, mangledName,
|
||||
[conformingType](unsigned depth, unsigned index) -> const Metadata * {
|
||||
if (depth == 0 && index == 0)
|
||||
return conformingType;
|
||||
|
@ -4214,7 +4222,7 @@ swift_getAssociatedTypeWitnessSlowImpl(
|
|||
return swift_getAssociatedConformanceWitness(wtable, conformingType,
|
||||
type, reqBase,
|
||||
dependentDescriptor);
|
||||
});
|
||||
}).getResponse();
|
||||
} else {
|
||||
// The generic parameters in the associated type name are those of the
|
||||
// conforming type.
|
||||
|
@ -4224,9 +4232,10 @@ swift_getAssociatedTypeWitnessSlowImpl(
|
|||
auto originalConformingType = findConformingSuperclass(conformingType,
|
||||
conformance);
|
||||
SubstGenericParametersFromMetadata substitutions(originalConformingType);
|
||||
assocTypeMetadata = swift_getTypeByMangledName(mangledName, substitutions,
|
||||
substitutions);
|
||||
response = swift_getTypeByMangledName(request, mangledName, substitutions,
|
||||
substitutions).getResponse();
|
||||
}
|
||||
auto assocTypeMetadata = response.Value;
|
||||
|
||||
if (!assocTypeMetadata) {
|
||||
auto conformingTypeNameInfo = swift_getTypeName(conformingType, true);
|
||||
|
@ -4242,13 +4251,9 @@ swift_getAssociatedTypeWitnessSlowImpl(
|
|||
mangledName.str().c_str());
|
||||
}
|
||||
|
||||
|
||||
assert((uintptr_t(assocTypeMetadata) &
|
||||
ProtocolRequirementFlags::AssociatedTypeMangledNameBit) == 0);
|
||||
|
||||
// Check the metadata state.
|
||||
auto response = swift_checkMetadataState(request, assocTypeMetadata);
|
||||
|
||||
// If the metadata was completed, record it in the witness table.
|
||||
if (response.State == MetadataState::Complete) {
|
||||
reinterpret_cast<const void**>(wtable)[witnessIndex] = assocTypeMetadata;
|
||||
|
@ -4970,10 +4975,11 @@ void swift::verifyMangledNameRoundtrip(const Metadata *metadata) {
|
|||
|
||||
auto mangledName = Demangle::mangleNode(node);
|
||||
auto result =
|
||||
swift_getTypeByMangledName(
|
||||
swift_getTypeByMangledName(MetadataState::Abstract,
|
||||
mangledName,
|
||||
[](unsigned, unsigned){ return nullptr; },
|
||||
[](const Metadata *, unsigned) { return nullptr; });
|
||||
[](const Metadata *, unsigned) { return nullptr; })
|
||||
.getMetadata();
|
||||
if (metadata != result)
|
||||
swift::warning(RuntimeErrorFlagNone,
|
||||
"Metadata mangled name failed to roundtrip: %p -> %s -> %p\n",
|
||||
|
|
|
@ -1208,18 +1208,30 @@ public:
|
|||
|
||||
}
|
||||
|
||||
SWIFT_CC(swift)
|
||||
static TypeInfo swift_getTypeByMangledNodeImpl(
|
||||
MetadataRequest request,
|
||||
Demangler &demangler,
|
||||
Demangle::NodePointer node,
|
||||
SubstGenericParameterFn substGenericParam,
|
||||
SubstDependentWitnessTableFn substWitnessTable) {
|
||||
// TODO: propagate the request down to the builder instead of calling
|
||||
// swift_checkMetadataState after the fact.
|
||||
DecodedMetadataBuilder builder(demangler, substGenericParam,
|
||||
substWitnessTable);
|
||||
auto type = Demangle::decodeMangledType(builder, node);
|
||||
return {type, builder.getReferenceOwnership()};
|
||||
if (!type) {
|
||||
return {MetadataResponse{nullptr, MetadataState::Complete},
|
||||
TypeReferenceOwnership()};
|
||||
}
|
||||
|
||||
return {swift_checkMetadataState(request, type),
|
||||
builder.getReferenceOwnership()};
|
||||
}
|
||||
|
||||
TypeInfo swift_getTypeByMangledNameImpl(
|
||||
SWIFT_CC(swift)
|
||||
static TypeInfo swift_getTypeByMangledNameImpl(
|
||||
MetadataRequest request,
|
||||
StringRef typeName,
|
||||
SubstGenericParameterFn substGenericParam,
|
||||
SubstDependentWitnessTableFn substWitnessTable) {
|
||||
|
@ -1267,7 +1279,7 @@ TypeInfo swift_getTypeByMangledNameImpl(
|
|||
return TypeInfo();
|
||||
}
|
||||
|
||||
return swift_getTypeByMangledNode(demangler, node, substGenericParam,
|
||||
return swift_getTypeByMangledNode(request, demangler, node, substGenericParam,
|
||||
substWitnessTable);
|
||||
}
|
||||
|
||||
|
@ -1280,11 +1292,8 @@ swift_getTypeByMangledNameInEnvironment(
|
|||
const void * const *genericArgs) {
|
||||
llvm::StringRef typeName(typeNameStart, typeNameLength);
|
||||
SubstGenericParametersFromMetadata substitutions(environment, genericArgs);
|
||||
auto metadata = swift_getTypeByMangledName(typeName, substitutions,
|
||||
substitutions);
|
||||
if (!metadata) return nullptr;
|
||||
|
||||
return swift_checkMetadataState(MetadataState::Complete, metadata).Value;
|
||||
return swift_getTypeByMangledName(MetadataState::Complete, typeName,
|
||||
substitutions, substitutions).getMetadata();
|
||||
}
|
||||
|
||||
SWIFT_CC(swift) SWIFT_RUNTIME_EXPORT
|
||||
|
@ -1296,11 +1305,8 @@ swift_getTypeByMangledNameInContext(
|
|||
const void * const *genericArgs) {
|
||||
llvm::StringRef typeName(typeNameStart, typeNameLength);
|
||||
SubstGenericParametersFromMetadata substitutions(context, genericArgs);
|
||||
auto metadata = swift_getTypeByMangledName(typeName, substitutions,
|
||||
substitutions);
|
||||
if (!metadata) return nullptr;
|
||||
|
||||
return swift_checkMetadataState(MetadataState::Complete, metadata).Value;
|
||||
return swift_getTypeByMangledName(MetadataState::Complete, typeName,
|
||||
substitutions, substitutions).getMetadata();
|
||||
}
|
||||
|
||||
/// Demangle a mangled name, but don't allow symbolic references.
|
||||
|
@ -1314,10 +1320,8 @@ swift_stdlib_getTypeByMangledNameUntrusted(const char *typeNameStart,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto metadata = swift_getTypeByMangledName(typeName, {}, {});
|
||||
if (!metadata) return nullptr;
|
||||
|
||||
return swift_checkMetadataState(MetadataState::Complete, metadata).Value;
|
||||
return swift_getTypeByMangledName(MetadataState::Complete, typeName,
|
||||
{}, {}).getMetadata();
|
||||
}
|
||||
|
||||
#if SWIFT_OBJC_INTEROP
|
||||
|
@ -1637,8 +1641,9 @@ void swift::gatherWrittenGenericArgs(
|
|||
SubstGenericParametersFromWrittenArgs substitutions(allGenericArgs,
|
||||
genericParamCounts);
|
||||
allGenericArgs[*lhsFlatIndex] =
|
||||
swift_getTypeByMangledName(req.getMangledTypeName(), substitutions,
|
||||
substitutions);
|
||||
swift_getTypeByMangledName(MetadataState::Abstract,
|
||||
req.getMangledTypeName(), substitutions,
|
||||
substitutions).getMetadata();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,16 +55,22 @@ public:
|
|||
/// since we don't represent ownership attributes in the metadata
|
||||
/// itself related info has to be bundled with it.
|
||||
class TypeInfo {
|
||||
const Metadata *Type;
|
||||
MetadataResponse Response;
|
||||
TypeReferenceOwnership ReferenceOwnership;
|
||||
|
||||
public:
|
||||
TypeInfo() : Type(nullptr), ReferenceOwnership() {}
|
||||
TypeInfo()
|
||||
: Response{nullptr, MetadataState::Abstract}, ReferenceOwnership() {}
|
||||
|
||||
TypeInfo(MetadataResponse response, TypeReferenceOwnership ownership)
|
||||
: Response(response), ReferenceOwnership(ownership) {}
|
||||
|
||||
// FIXME: remove this constructor and require a response in all cases.
|
||||
TypeInfo(const Metadata *type, TypeReferenceOwnership ownership)
|
||||
: Type(type), ReferenceOwnership(ownership) {}
|
||||
: Response{type, MetadataState::Abstract}, ReferenceOwnership(ownership) {}
|
||||
|
||||
operator const Metadata *() { return Type; }
|
||||
const Metadata *getMetadata() const { return Response.Value; }
|
||||
MetadataResponse getResponse() const { return Response; }
|
||||
|
||||
bool isWeak() const { return ReferenceOwnership.isWeak(); }
|
||||
bool isUnowned() const { return ReferenceOwnership.isUnowned(); }
|
||||
|
@ -322,7 +328,9 @@ public:
|
|||
/// given a particular generic parameter specified by depth/index.
|
||||
/// \p substWitnessTable Function that provides witness tables given a
|
||||
/// particular dependent conformance index.
|
||||
SWIFT_CC(swift)
|
||||
TypeInfo swift_getTypeByMangledNode(
|
||||
MetadataRequest request,
|
||||
Demangler &demangler,
|
||||
Demangle::NodePointer node,
|
||||
SubstGenericParameterFn substGenericParam,
|
||||
|
@ -334,7 +342,9 @@ public:
|
|||
/// given a particular generic parameter specified by depth/index.
|
||||
/// \p substWitnessTable Function that provides witness tables given a
|
||||
/// particular dependent conformance index.
|
||||
SWIFT_CC(swift)
|
||||
TypeInfo swift_getTypeByMangledName(
|
||||
MetadataRequest request,
|
||||
StringRef typeName,
|
||||
SubstGenericParameterFn substGenericParam,
|
||||
SubstDependentWitnessTableFn substWitnessTable);
|
||||
|
|
|
@ -635,8 +635,9 @@ bool swift::_checkGenericRequirements(
|
|||
|
||||
// Resolve the subject generic parameter.
|
||||
const Metadata *subjectType =
|
||||
swift_getTypeByMangledName(req.getParam(), substGenericParam,
|
||||
substWitnessTable);
|
||||
swift_getTypeByMangledName(MetadataState::Abstract,
|
||||
req.getParam(), substGenericParam,
|
||||
substWitnessTable).getMetadata();
|
||||
if (!subjectType)
|
||||
return true;
|
||||
|
||||
|
@ -660,8 +661,9 @@ bool swift::_checkGenericRequirements(
|
|||
case GenericRequirementKind::SameType: {
|
||||
// Demangle the second type under the given substitutions.
|
||||
auto otherType =
|
||||
swift_getTypeByMangledName(req.getMangledTypeName(), substGenericParam,
|
||||
substWitnessTable);
|
||||
swift_getTypeByMangledName(MetadataState::Abstract,
|
||||
req.getMangledTypeName(), substGenericParam,
|
||||
substWitnessTable).getMetadata();
|
||||
if (!otherType) return true;
|
||||
|
||||
assert(!req.getFlags().hasExtraArgument());
|
||||
|
@ -687,8 +689,9 @@ bool swift::_checkGenericRequirements(
|
|||
case GenericRequirementKind::BaseClass: {
|
||||
// Demangle the base type under the given substitutions.
|
||||
auto baseType =
|
||||
swift_getTypeByMangledName(req.getMangledTypeName(), substGenericParam,
|
||||
substWitnessTable);
|
||||
swift_getTypeByMangledName(MetadataState::Complete,
|
||||
req.getMangledTypeName(), substGenericParam,
|
||||
substWitnessTable).getMetadata();
|
||||
if (!baseType) return true;
|
||||
|
||||
// Check whether it's dynamically castable, which works as a superclass
|
||||
|
|
|
@ -312,7 +312,7 @@ getFieldAt(const Metadata *base, unsigned index) {
|
|||
(int)typeName.length, typeName.data);
|
||||
return {"unknown",
|
||||
FieldType()
|
||||
.withType(TypeInfo(&METADATA_SYM(EMPTY_TUPLE_MANGLING), {}))
|
||||
.withType(&METADATA_SYM(EMPTY_TUPLE_MANGLING))
|
||||
.withIndirect(false)
|
||||
.withWeak(false)};
|
||||
};
|
||||
|
@ -336,20 +336,15 @@ getFieldAt(const Metadata *base, unsigned index) {
|
|||
auto typeName = field.getMangledTypeName(0);
|
||||
|
||||
SubstGenericParametersFromMetadata substitutions(base);
|
||||
auto typeInfo = swift_getTypeByMangledName(typeName, substitutions,
|
||||
auto typeInfo = swift_getTypeByMangledName(MetadataState::Complete,
|
||||
typeName, substitutions,
|
||||
substitutions);
|
||||
|
||||
// Complete the type metadata before returning it to the caller.
|
||||
if (typeInfo) {
|
||||
typeInfo = TypeInfo(swift_checkMetadataState(MetadataState::Complete,
|
||||
typeInfo).Value,
|
||||
typeInfo.getReferenceOwnership());
|
||||
}
|
||||
|
||||
// If demangling the type failed, pretend it's an empty type instead with
|
||||
// a log message.
|
||||
if (typeInfo == nullptr) {
|
||||
typeInfo = TypeInfo(&METADATA_SYM(EMPTY_TUPLE_MANGLING), {});
|
||||
if (!typeInfo.getMetadata()) {
|
||||
typeInfo = TypeInfo({&METADATA_SYM(EMPTY_TUPLE_MANGLING),
|
||||
MetadataState::Complete}, {});
|
||||
missing_reflection_metadata_warning(
|
||||
"warning: the Swift runtime was unable to demangle the type "
|
||||
"of field '%*s'. the mangled type name is '%*s'. this field will "
|
||||
|
@ -359,7 +354,7 @@ getFieldAt(const Metadata *base, unsigned index) {
|
|||
}
|
||||
|
||||
return {name, FieldType()
|
||||
.withType(typeInfo)
|
||||
.withType(typeInfo.getMetadata())
|
||||
.withIndirect(field.isIndirectCase())
|
||||
.withWeak(typeInfo.isWeak())};
|
||||
}
|
||||
|
|
|
@ -175,14 +175,15 @@ TEST_F(CompatibilityOverrideTest, test_swift_conformsToSwiftProtocol) {
|
|||
|
||||
TEST_F(CompatibilityOverrideTest, test_swift_getTypeByMangledNode) {
|
||||
Demangler demangler;
|
||||
auto Result = swift_getTypeByMangledNode(demangler, nullptr, nullptr,
|
||||
nullptr);
|
||||
ASSERT_EQ((const Metadata *)Result, nullptr);
|
||||
auto Result = swift_getTypeByMangledNode(MetadataState::Abstract,
|
||||
demangler, nullptr, nullptr,nullptr);
|
||||
ASSERT_EQ(Result.getMetadata(), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(CompatibilityOverrideTest, test_swift_getTypeByMangledName) {
|
||||
auto Result = swift_getTypeByMangledName("", nullptr, nullptr);
|
||||
ASSERT_EQ((const Metadata *)Result, nullptr);
|
||||
auto Result = swift_getTypeByMangledName(MetadataState::Abstract,
|
||||
"", nullptr, nullptr);
|
||||
ASSERT_EQ(Result.getMetadata(), nullptr);
|
||||
}
|
||||
|
||||
TEST_F(CompatibilityOverrideTest, test_swift_getAssociatedTypeWitnessSlow) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче