1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Fixed type generic arg and PopulateType dependency bugs

This commit is contained in:
Brian Fiete 2022-06-02 07:06:31 -07:00
parent a77a95b71b
commit 7e94abe43a
5 changed files with 77 additions and 41 deletions

View file

@ -907,25 +907,30 @@ void BfContext::ValidateDependencies()
// BfLogSysM("ValidateDependencies\n");
//
// bool deletedNewTypes = false;
// auto itr = mResolvedTypes.begin();
// while (itr != mResolvedTypes.end())
// for (auto type : mResolvedTypes)
// {
// auto type = itr.mCurEntry->mValue;
// if ((type->IsGenericTypeInstance()) && (type->mDefineState > BfTypeDefineState_Undefined))
// if (type->IsDeleting())
// continue;
//
// if (type->IsGenericTypeInstance())
// {
// // We can't contain deleted generic arguments without being deleted ourselves
// BfTypeInstance* genericType = (BfTypeInstance*)type;
//
// for (auto genericTypeArg : genericType->mTypeGenericArguments)
// for (auto genericTypeArg : genericType->mGenericTypeInfo->mTypeGenericArguments)
// {
// auto depType = genericTypeArg->ToDependedType();
// if (depType != NULL)
// BF_ASSERT((!genericTypeArg->IsDeleting()));
//
// auto argDepType = genericTypeArg->ToDependedType();
// if (argDepType != NULL)
// {
// BF_ASSERT(depType->mDependencyMap.mTypeSet.ContainsKey(type));
// BfDependencyMap::DependencyEntry* depEntry = NULL;
// argDepType->mDependencyMap.mTypeSet.TryGetValue(type, &depEntry);
// BF_ASSERT(depEntry != NULL);
// BF_ASSERT((depEntry->mFlags & BfDependencyMap::DependencyFlag_TypeGenericArg) != 0);
// }
// }
// }
// ++itr;
// }
#endif
}
@ -979,6 +984,11 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
{
BfLogSysM("Setting revision. Type: %p Revision: %d\n", typeInst, mCompiler->mRevision);
typeInst->mRevision = mCompiler->mRevision;
if (typeInst->IsGenericTypeInstance())
{
BfLogSysM("Setting BfTypeRebuildFlag_PendingGenericArgDep for type %p\n", typeInst);
typeInst->mRebuildFlags = (BfTypeRebuildFlags)(typeInst->mRebuildFlags | BfTypeRebuildFlag_PendingGenericArgDep);
}
}
if ((typeInst->IsTypeAlias()) != (typeInst->mTypeDef->mTypeCode == BfTypeCode_TypeAlias))
@ -1970,6 +1980,15 @@ void BfContext::UpdateAfterDeletingTypes()
for (auto genericTypeArg : genericType->mGenericTypeInfo->mTypeGenericArguments)
{
BF_ASSERT((!genericTypeArg->IsDeleting()));
auto argDepType = genericTypeArg->ToDependedType();
if (argDepType != NULL)
{
BfDependencyMap::DependencyEntry* depEntry = NULL;
argDepType->mDependencyMap.mTypeSet.TryGetValue(type, &depEntry);
BF_ASSERT(depEntry != NULL);
BF_ASSERT((depEntry->mFlags & BfDependencyMap::DependencyFlag_TypeGenericArg) != 0);
}
}
}
#endif
@ -2176,7 +2195,7 @@ void BfContext::UpdateRevisedTypes()
}
// Clear flags we don't want to propagate
typeInst->mRebuildFlags = (BfTypeRebuildFlags)(typeInst->mRebuildFlags & BfTypeRebuildFlag_UnderlyingTypeDeferred);
typeInst->mRebuildFlags = (BfTypeRebuildFlags)(typeInst->mRebuildFlags & (BfTypeRebuildFlag_UnderlyingTypeDeferred | BfTypeRebuildFlag_PendingGenericArgDep));
if (typeDef->mIsPartial)
{

View file

@ -1143,6 +1143,14 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
if ((populateType == BfPopulateType_Declaration) && (resolvedTypeRef->mDefineState >= BfTypeDefineState_Declared))
return;
if ((resolvedTypeRef->mRebuildFlags & BfTypeRebuildFlag_PendingGenericArgDep) != 0)
{
BfLogSysM("PopulateType handling BfTypeRebuildFlag_PendingGenericArgDep for type %p\n", resolvedTypeRef);
// Reinit dependencies
resolvedTypeRef->mRebuildFlags = (BfTypeRebuildFlags)(resolvedTypeRef->mRebuildFlags & ~BfTypeRebuildFlag_PendingGenericArgDep);
DoPopulateType_SetGenericDependencies(resolvedTypeRef->ToTypeInstance());
}
// Are we "demanding" to reify a type that is currently resolve-only?
if ((mIsReified) && (populateType >= BfPopulateType_Declaration))
{
@ -1256,19 +1264,11 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
auto typeInstance = resolvedTypeRef->ToTypeInstance();
CheckInjectNewRevision(typeInstance);
BF_ASSERT((resolvedTypeRef->mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) == 0);
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
/*BfTypeRebuildFlags allowedFlags = (BfTypeRebuildFlags)(BfTypeRebuildFlag_AddedToWorkList | BfTypeRebuildFlag_AwaitingReference | BfTypeRebuildFlag_UnderlyingTypeDeferred);
if ((resolvedTypeRef->mRebuildFlags & ~allowedFlags) != 0)
{
// BfContext::UpdateAfterDeletingTypes should clear out all flags except for the Deleted flag
// If this type was deleted then we should never be able to reach PopulateType here.
// This may happen if dependent types were not properly rebuilt when a used type
// was deleted.
auto hadFlags = resolvedTypeRef->mRebuildFlags;
BF_ASSERT((resolvedTypeRef->mRebuildFlags & ~allowedFlags) == 0);
resolvedTypeRef->mRebuildFlags = (BfTypeRebuildFlags)(resolvedTypeRef->mRebuildFlags & ~allowedFlags);
}*/
BF_ASSERT((resolvedTypeRef->mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) == 0);
bool isNew = resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined;
if (isNew)
@ -3076,15 +3076,31 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
void BfModule::DoPopulateType_SetGenericDependencies(BfTypeInstance* genericTypeInstance)
{
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, genericTypeInstance);
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
// Add generic dependencies if needed
for (auto genericType : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
for (auto genericArgType : genericTypeInstance->mGenericTypeInfo->mTypeGenericArguments)
{
if (genericType->IsPrimitiveType())
genericType = GetWrappedStructType(genericType);
if (genericType != NULL)
if (genericArgType->IsPrimitiveType())
genericArgType = GetWrappedStructType(genericArgType);
if (genericArgType != NULL)
{
AddDependency(genericType, genericTypeInstance, BfDependencyMap::DependencyFlag_TypeGenericArg);
BfLogSysM("Adding generic dependency of %p for type %p\n", genericType, genericTypeInstance);
AddDependency(genericArgType, genericTypeInstance, BfDependencyMap::DependencyFlag_TypeGenericArg);
BfLogSysM("Adding generic dependency of %p for type %p revision %d\n", genericArgType, genericTypeInstance, genericTypeInstance->mRevision);
#ifdef _DEBUG
// auto argDepType = genericArgType->ToDependedType();
// if (argDepType != NULL)
// {
// BfDependencyMap::DependencyEntry* depEntry = NULL;
// argDepType->mDependencyMap.mTypeSet.TryGetValue(genericTypeInstance, &depEntry);
// BF_ASSERT(depEntry != NULL);
// BF_ASSERT(depEntry->mRevision == genericTypeInstance->mRevision);
// BF_ASSERT((depEntry->mFlags & BfDependencyMap::DependencyFlag_TypeGenericArg) != 0);
// }
#endif
}
}
if ((genericTypeInstance->IsSpecializedType()) &&

View file

@ -117,7 +117,7 @@ bool BfDependencyMap::AddUsedBy(BfType* dependentType, BfDependencyMap::Dependen
{
if ((dependencyEntry->mFlags & flags) == flags)
return false;
dependencyEntry->mFlags = (BfDependencyMap::DependencyFlags)(dependencyEntry->mFlags | flags);
dependencyEntry->mFlags = (DependencyFlags)(dependencyEntry->mFlags | flags);
return true;
}
}

View file

@ -447,6 +447,7 @@ enum BfTypeRebuildFlags
BfTypeRebuildFlag_RebuildQueued = 0x20000,
BfTypeRebuildFlag_ConstEvalCancelled = 0x40000,
BfTypeRebuildFlag_ChangedMidCompile = 0x80000,
BfTypeRebuildFlag_PendingGenericArgDep = 0x100000
};
class BfTypeDIReplaceCallback;