mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
in order to work correctly for non-@objc protocols.
Language features like erasing concrete metatype values are also left for the future. Still, baby steps. The singleton ordinary metatype for existential types is still potentially useful; we allow it to be written as P.Protocol. I've been somewhat cavalier in making code accept AnyMetatypeType instead of a more specific type, and it's likely that a number of these places can and should be more restrictive. When T is an existential type, parse T.Type as an ExistentialMetatypeType instead of a MetatypeType. An existential metatype is the formal type \exists t:P . (t.Type) whereas the ordinary metatype is the formal type (\exists t:P . t).Type which is singleton. Our inability to express that difference was leading to an ever-increasing cascade of hacks where information is shadily passed behind the scenes in order to make various operations with static members of protocols work correctly. This patch takes the first step towards fixing that by splitting out existential metatypes and giving them a pointer representation. Eventually, we will need them to be able to carry protocol witness tables Swift SVN r15716
This commit is contained in:
@@ -324,6 +324,7 @@ swift::swift_dynamicCast(const void *object, const Metadata *targetType) {
|
||||
break;
|
||||
|
||||
case MetadataKind::Existential:
|
||||
case MetadataKind::ExistentialMetatype:
|
||||
case MetadataKind::Function:
|
||||
case MetadataKind::HeapArray:
|
||||
case MetadataKind::HeapLocalVariable:
|
||||
@@ -355,6 +356,7 @@ swift::swift_dynamicCastUnconditional(const void *object,
|
||||
break;
|
||||
|
||||
case MetadataKind::Existential:
|
||||
case MetadataKind::ExistentialMetatype:
|
||||
case MetadataKind::Function:
|
||||
case MetadataKind::HeapArray:
|
||||
case MetadataKind::HeapLocalVariable:
|
||||
@@ -390,6 +392,7 @@ swift::swift_dynamicCastIndirect(const OpaqueValue *value,
|
||||
break;
|
||||
}
|
||||
case MetadataKind::Existential:
|
||||
case MetadataKind::ExistentialMetatype:
|
||||
case MetadataKind::Function:
|
||||
case MetadataKind::HeapArray:
|
||||
case MetadataKind::HeapLocalVariable:
|
||||
@@ -404,6 +407,7 @@ swift::swift_dynamicCastIndirect(const OpaqueValue *value,
|
||||
break;
|
||||
|
||||
case MetadataKind::Existential:
|
||||
case MetadataKind::ExistentialMetatype:
|
||||
case MetadataKind::Function:
|
||||
case MetadataKind::HeapArray:
|
||||
case MetadataKind::HeapLocalVariable:
|
||||
@@ -441,6 +445,7 @@ swift::swift_dynamicCastIndirectUnconditional(const OpaqueValue *value,
|
||||
break;
|
||||
}
|
||||
case MetadataKind::Existential:
|
||||
case MetadataKind::ExistentialMetatype:
|
||||
case MetadataKind::Function:
|
||||
case MetadataKind::HeapArray:
|
||||
case MetadataKind::HeapLocalVariable:
|
||||
@@ -455,6 +460,7 @@ swift::swift_dynamicCastIndirectUnconditional(const OpaqueValue *value,
|
||||
break;
|
||||
|
||||
case MetadataKind::Existential:
|
||||
case MetadataKind::ExistentialMetatype:
|
||||
case MetadataKind::Function:
|
||||
case MetadataKind::HeapArray:
|
||||
case MetadataKind::HeapLocalVariable:
|
||||
@@ -1137,6 +1143,9 @@ namespace {
|
||||
/// The uniquing structure for metatype type metadata.
|
||||
static MetadataCache<MetatypeCacheEntry> MetatypeTypes;
|
||||
|
||||
/// The uniquing structure for existential metatype type metadata.
|
||||
static MetadataCache<MetatypeCacheEntry> ExistentialMetatypeTypes;
|
||||
|
||||
/// \brief Find the appropriate value witness table for the given type.
|
||||
static const ValueWitnessTable *
|
||||
getMetatypeValueWitnesses(const Metadata *instanceType) {
|
||||
@@ -1177,6 +1186,29 @@ swift::swift_getMetatypeMetadata(const Metadata *instanceMetadata) {
|
||||
return MetatypeTypes.add(entry)->getData();
|
||||
}
|
||||
|
||||
/// \brief Fetch a uniqued metadata for a metatype type.
|
||||
extern "C" const MetatypeMetadata *
|
||||
swift::swift_getExistentialMetatypeMetadata(const Metadata *instanceMetadata) {
|
||||
const size_t numGenericArgs = 1;
|
||||
|
||||
const void *args[] = { instanceMetadata };
|
||||
if (auto entry = ExistentialMetatypeTypes.find(args, numGenericArgs)) {
|
||||
return entry->getData();
|
||||
}
|
||||
|
||||
auto entry = MetatypeCacheEntry::allocate(args, numGenericArgs, 0);
|
||||
|
||||
// FIXME: the value witnesses should probably account for room for
|
||||
// protocol witness tables
|
||||
|
||||
auto metadata = entry->getData();
|
||||
metadata->setKind(MetadataKind::ExistentialMetatype);
|
||||
metadata->ValueWitnesses = &getUnmanagedPointerPointerValueWitnesses();
|
||||
metadata->InstanceType = instanceMetadata;
|
||||
|
||||
return ExistentialMetatypeTypes.add(entry)->getData();
|
||||
}
|
||||
|
||||
/*** Existential types ********************************************************/
|
||||
|
||||
namespace {
|
||||
@@ -2016,6 +2048,7 @@ Metadata::getNominalTypeDescriptor() const {
|
||||
case MetadataKind::Function:
|
||||
case MetadataKind::PolyFunction:
|
||||
case MetadataKind::Existential:
|
||||
case MetadataKind::ExistentialMetatype:
|
||||
case MetadataKind::Metatype:
|
||||
case MetadataKind::ObjCClassWrapper:
|
||||
case MetadataKind::HeapArray:
|
||||
@@ -2107,6 +2140,7 @@ static void defaultPrint(OpaqueValue *value, const Metadata *type) {
|
||||
case MetadataKind::Opaque:
|
||||
case MetadataKind::Function:
|
||||
case MetadataKind::Existential:
|
||||
case MetadataKind::ExistentialMetatype:
|
||||
case MetadataKind::Metatype:
|
||||
case MetadataKind::ObjCClassWrapper:
|
||||
// TODO
|
||||
|
||||
Reference in New Issue
Block a user