mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Serialization] Serialize archetypes as generic environment + interface type.
Rather than serializing the complete structure of all archetypes (which is completely redundant), serialize a reference to their owning generic environment as well as their interface type. The archetype itself will be reconsituted by mapping the interface type into that generic environment.
This commit is contained in:
@@ -1056,7 +1056,6 @@ ModuleFile::getGenericSignatureOrEnvironment(
|
||||
DeserializingEntityRAII deserializingEntity(*this);
|
||||
|
||||
SmallVector<GenericTypeParamType *, 4> paramTypes;
|
||||
SmallVector<uint64_t, 4> rawContextTypeIDs;
|
||||
{
|
||||
using namespace decls_block;
|
||||
|
||||
@@ -1081,15 +1080,9 @@ ModuleFile::getGenericSignatureOrEnvironment(
|
||||
ArrayRef<uint64_t> rawParamIDs;
|
||||
GenericEnvironmentLayout::readRecord(scratch, rawParamIDs);
|
||||
|
||||
if (rawParamIDs.size() % 2 != 0) {
|
||||
error();
|
||||
return result;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, n = rawParamIDs.size(); i != n; i += 2) {
|
||||
for (unsigned i = 0, n = rawParamIDs.size(); i != n; ++i) {
|
||||
auto paramTy = getType(rawParamIDs[i])->castTo<GenericTypeParamType>();
|
||||
paramTypes.push_back(paramTy);
|
||||
rawContextTypeIDs.push_back(rawParamIDs[i+1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1099,12 +1092,12 @@ ModuleFile::getGenericSignatureOrEnvironment(
|
||||
SILGenericEnvironmentLayout::readRecord(scratch, rawParamIDs);
|
||||
lastRecordOffset.reset();
|
||||
|
||||
if (rawParamIDs.size() % 3 != 0) {
|
||||
if (rawParamIDs.size() % 2 != 0) {
|
||||
error();
|
||||
return result;
|
||||
}
|
||||
|
||||
for (unsigned i = 0, n = rawParamIDs.size(); i != n; i += 3) {
|
||||
for (unsigned i = 0, n = rawParamIDs.size(); i != n; i += 2) {
|
||||
Identifier name = getIdentifier(rawParamIDs[i]);
|
||||
auto paramTy = getType(rawParamIDs[i+1])->castTo<GenericTypeParamType>();
|
||||
|
||||
@@ -1120,7 +1113,6 @@ ModuleFile::getGenericSignatureOrEnvironment(
|
||||
}
|
||||
|
||||
paramTypes.push_back(paramTy);
|
||||
rawContextTypeIDs.push_back(rawParamIDs[i+2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1157,17 +1149,9 @@ ModuleFile::getGenericSignatureOrEnvironment(
|
||||
|
||||
// Form the generic environment. Record it now so that deserialization of
|
||||
// the archetypes in the environment can refer to this environment.
|
||||
auto genericEnv = GenericEnvironment::getIncomplete(signature, nullptr);
|
||||
auto genericEnv = signature->createGenericEnvironment(*getAssociatedModule());
|
||||
envOrOffset = genericEnv;
|
||||
|
||||
// Fill in the interface type -> context type mappings to complete the
|
||||
// generic environment.
|
||||
// FIXME: Eventually, these mappings will go away.
|
||||
assert(paramTypes.size() == rawContextTypeIDs.size());
|
||||
for (unsigned i : indices(paramTypes))
|
||||
genericEnv->addMapping(paramTypes[i], getType(rawContextTypeIDs[i]));
|
||||
|
||||
// The generic environment is complete.
|
||||
return genericEnv;
|
||||
}
|
||||
|
||||
@@ -3066,14 +3050,14 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
|
||||
SmallVector<Requirement, 4> requirements;
|
||||
readGenericRequirements(requirements, DeclTypeCursor);
|
||||
|
||||
auto signature = GenericSignature::get(
|
||||
proto->getGenericEnvironment()->getGenericParams(), requirements);
|
||||
proto->setRequirementSignature(signature);
|
||||
|
||||
if (isImplicit)
|
||||
proto->setImplicit();
|
||||
proto->computeType();
|
||||
|
||||
auto signature = GenericSignature::get(
|
||||
{ proto->getProtocolSelfType() }, requirements);
|
||||
proto->setRequirementSignature(signature);
|
||||
|
||||
proto->setMemberLoader(this, DeclTypeCursor.GetCurrentBitNo());
|
||||
proto->setCircularityCheck(CircularityCheck::Checked);
|
||||
break;
|
||||
@@ -3874,97 +3858,27 @@ Type ModuleFile::getType(TypeID TID) {
|
||||
}
|
||||
|
||||
case decls_block::ARCHETYPE_TYPE: {
|
||||
uint8_t isPrimary;
|
||||
TypeID parentOrGenericEnvID;
|
||||
DeclID assocTypeOrNameID;
|
||||
TypeID superclassID;
|
||||
ArrayRef<uint64_t> rawConformanceIDs;
|
||||
GenericEnvironmentID envID;
|
||||
TypeID interfaceTypeID;
|
||||
|
||||
decls_block::ArchetypeTypeLayout::readRecord(scratch, isPrimary,
|
||||
parentOrGenericEnvID,
|
||||
assocTypeOrNameID,
|
||||
superclassID,
|
||||
rawConformanceIDs);
|
||||
decls_block::ArchetypeTypeLayout::readRecord(scratch, envID,
|
||||
interfaceTypeID);
|
||||
|
||||
GenericEnvironment *genericEnv = nullptr;
|
||||
ArchetypeType *parent = nullptr;
|
||||
if (isPrimary) {
|
||||
genericEnv = getGenericEnvironment(parentOrGenericEnvID);
|
||||
} else {
|
||||
parent = getType(parentOrGenericEnvID)->castTo<ArchetypeType>();
|
||||
}
|
||||
|
||||
Type superclass;
|
||||
superclass = getType(superclassID);
|
||||
|
||||
// TODO: Read layout.
|
||||
LayoutConstraint layout;
|
||||
|
||||
SmallVector<ProtocolDecl *, 4> conformances;
|
||||
for (DeclID protoID : rawConformanceIDs)
|
||||
conformances.push_back(cast<ProtocolDecl>(getDecl(protoID)));
|
||||
|
||||
// See if we triggered deserialization through our conformances.
|
||||
if (typeOrOffset.isComplete())
|
||||
break;
|
||||
|
||||
ArchetypeType *archetype;
|
||||
if (parent) {
|
||||
auto assocTypeDecl = cast<AssociatedTypeDecl>(getDecl(assocTypeOrNameID));
|
||||
archetype = ArchetypeType::getNew(ctx, parent, assocTypeDecl,
|
||||
conformances, superclass, layout);
|
||||
} else {
|
||||
archetype = ArchetypeType::getNew(ctx, genericEnv,
|
||||
getIdentifier(assocTypeOrNameID),
|
||||
conformances, superclass, layout);
|
||||
}
|
||||
|
||||
typeOrOffset = archetype;
|
||||
|
||||
// Read the associated type names.
|
||||
auto entry = DeclTypeCursor.advance();
|
||||
if (entry.Kind != llvm::BitstreamEntry::Record) {
|
||||
auto env = getGenericEnvironment(envID);
|
||||
if (!env) {
|
||||
error();
|
||||
break;
|
||||
}
|
||||
|
||||
scratch.clear();
|
||||
unsigned kind = DeclTypeCursor.readRecord(entry.ID, scratch);
|
||||
if (kind != decls_block::ARCHETYPE_NESTED_TYPE_NAMES) {
|
||||
error();
|
||||
break;
|
||||
}
|
||||
|
||||
ArrayRef<uint64_t> rawNameIDs;
|
||||
decls_block::ArchetypeNestedTypeNamesLayout::readRecord(scratch,
|
||||
rawNameIDs);
|
||||
|
||||
// Read the associated type ids.
|
||||
entry = DeclTypeCursor.advance();
|
||||
if (entry.Kind != llvm::BitstreamEntry::Record) {
|
||||
error();
|
||||
break;
|
||||
}
|
||||
Type interfaceType = getType(interfaceTypeID);
|
||||
Type contextType = env->mapTypeIntoContext(interfaceType);
|
||||
typeOrOffset = contextType;
|
||||
|
||||
SmallVector<uint64_t, 16> scratch2;
|
||||
kind = DeclTypeCursor.readRecord(entry.ID, scratch2);
|
||||
if (kind != decls_block::ARCHETYPE_NESTED_TYPES) {
|
||||
if (contextType->hasError()) {
|
||||
error();
|
||||
break;
|
||||
}
|
||||
|
||||
ArrayRef<uint64_t> rawTypeIDs;
|
||||
decls_block::ArchetypeNestedTypesLayout::readRecord(scratch2, rawTypeIDs);
|
||||
|
||||
// Build the nested types array.
|
||||
SmallVector<std::pair<Identifier, Type>, 4> nestedTypes;
|
||||
for_each(rawNameIDs, rawTypeIDs,
|
||||
[&](IdentifierID nameID, TypeID nestedID) {
|
||||
Type type = getType(nestedID);
|
||||
nestedTypes.push_back(std::make_pair(getIdentifier(nameID), type));
|
||||
});
|
||||
archetype->setNestedTypes(ctx, nestedTypes);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user