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:
John McCall 2019-02-05 16:15:59 -05:00
Родитель 570353aa42
Коммит 12c5e098e9
7 изменённых файлов: 90 добавлений и 68 удалений

Просмотреть файл

@ -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) {