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:
John McCall
2014-04-01 00:38:28 +00:00
parent 83a830eb8a
commit f1180f5e6d
64 changed files with 883 additions and 256 deletions

View File

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