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

Improved CE TypeDeclaration handling, including proper rebuilding

This commit is contained in:
Brian Fiete 2025-01-15 09:59:47 -08:00
parent 25eb2a13a3
commit 5f4514211e
10 changed files with 266 additions and 38 deletions

View file

@ -7031,7 +7031,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
String toolsetErrors;
for (auto project : mSystem->mProjects)
{
project->mDependencySet.Clear();
project->ClearCache();
if (project->mDisabled)
continue;
if (project->mCodeGenOptions.mLTOType != BfLTOType_None)

View file

@ -1459,7 +1459,7 @@ void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChang
if (dependencyFlags &
(BfDependencyMap::DependencyFlag_ReadFields | BfDependencyMap::DependencyFlag_ParamOrReturnValue |
BfDependencyMap::DependencyFlag_LocalUsage | BfDependencyMap::DependencyFlag_MethodGenericArg |
BfDependencyMap::DependencyFlag_Allocates))
BfDependencyMap::DependencyFlag_Allocates | BfDependencyMap::DependencyFlag_TypeSignature))
{
RebuildType(dependentType);
}
@ -2243,6 +2243,8 @@ void BfContext::UpdateRevisedTypes()
bool rebuildAllFilesChanged = mCompiler->mRebuildChangedFileSet.Contains("*");
uint64 projectDepHash = 0;
// Do primary 'rebuild' scan
for (auto type : mResolvedTypes)
{
@ -2316,6 +2318,14 @@ void BfContext::UpdateRevisedTypes()
changed = true;
mCompiler->mRebuildFileSet.Add(kv.mKey.mString);
}
if (kv.mKey.mKind == CeRebuildKey::Kind_TypeDeclListHash)
{
if (projectDepHash == 0)
projectDepHash = mSystem->GetTypeDeclListHash();
if (kv.mValue.mInt != projectDepHash)
changed = true;
}
}
if (changed)

View file

@ -12004,7 +12004,13 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
return false;
}
mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
bool success = true;
defer(
{
if (success)
mModule->AddDependency(type, mModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeSignature);
});
// We want to try to avoid triggering OnTypeInit for basic info
mModule->PopulateType(type, BfPopulateType_Interfaces_Direct);
@ -12286,8 +12292,11 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
}
}
else
{
success = false;
return false;
}
}
if ((type->IsGenericParam()) && (!mModule->mIsComptimeModule))
{

View file

@ -6128,7 +6128,7 @@ BfIRValue BfModule::GetTypeTypeData(BfType* type, BfCreateTypeDataContext& ctx,
typeFlags |= BfTypeFlags_SizedArray;
if (type->IsConstExprValue())
typeFlags |= BfTypeFlags_ConstExpr;
if (type->IsSplattable())
if ((!wantsTypeDecl) && (type->IsSplattable()))
typeFlags |= BfTypeFlags_Splattable;
if (type->IsUnion())
typeFlags |= BfTypeFlags_Union;
@ -6147,7 +6147,7 @@ BfIRValue BfModule::GetTypeTypeData(BfType* type, BfCreateTypeDataContext& ctx,
return typeTypeData;
}
BfIRValue BfModule::CreateTypeDeclData(BfType* type)
BfIRValue BfModule::CreateTypeDeclData(BfType* type, BfProject* curProject)
{
auto typeDeclType = ResolveTypeDef(mCompiler->mTypeTypeDeclDef)->ToTypeInstance();
@ -6175,14 +6175,48 @@ BfIRValue BfModule::CreateTypeDeclData(BfType* type)
if (typeInst != NULL)
baseType = typeInst->mBaseType;
enum BfTypeDeclFlags
{
BfTypeDeclFlag_DeclaredInDependency = 1,
BfTypeDeclFlag_DeclaredInDependent = 2,
BfTypeDeclFlag_DeclaredInCurrent = 4,
BfTypeDeclFlag_AlwaysVisible = 8,
BfTypeDeclFlag_SometimesVisible = 0x10
};
int flags = 0;
if (typeInst != NULL)
{
auto declProject = typeInst->mTypeDef->mProject;
auto depKind = curProject->GetDependencyKind(declProject);
if (depKind == BfProject::DependencyKind_Identity)
{
flags |= BfTypeDeclFlag_DeclaredInCurrent | BfTypeDeclFlag_AlwaysVisible | BfTypeDeclFlag_SometimesVisible;
}
else if (depKind == BfProject::DependencyKind_Dependency)
{
flags |= BfTypeDeclFlag_DeclaredInDependency | BfTypeDeclFlag_AlwaysVisible | BfTypeDeclFlag_SometimesVisible;
}
else if (depKind == BfProject::DependencyKind_Dependent_Exclusive)
{
flags |= BfTypeDeclFlag_DeclaredInDependent | BfTypeDeclFlag_AlwaysVisible | BfTypeDeclFlag_SometimesVisible;
}
else if (depKind == BfProject::DependencyKind_Dependent_Shared)
{
flags |= BfTypeDeclFlag_DeclaredInDependent | BfTypeDeclFlag_SometimesVisible;
}
}
BfIRValue objectData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfObjectType, BfIRPopulateType_Full), typeValueParams);
SizedArray<BfIRValue, 9> typeDataParams =
{
objectData,
GetConstValue(type->mTypeId, typeIdType), // mTypeId
GetConstValue((baseType != NULL) ? baseType->mTypeId : 0, typeIdType), // mBaseTypeId
GetConstValue((outerType != NULL) ? outerType->mTypeId : 0, typeIdType), // mOuterTypeId
GetConstValue(typeFlags, intType), // mTypeFlags
GetConstValue(flags, byteType), // mFlags
GetConstValue(typeCode, byteType), // mTypeCode
};
FixConstValueParams(typeDeclType, typeDataParams);

View file

@ -2095,7 +2095,7 @@ public:
BfIRValue CreateFieldData(BfFieldInstance* fieldInstance, int customAttrIdx);
void CreateSlotOfs(BfTypeInstance* typeInstance);
BfIRValue GetTypeTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool needsTypeData, bool wantsTypeDecl, bool needsTypeNames, int& typeFlags, int& typeCode);
BfIRValue CreateTypeDeclData(BfType* type);
BfIRValue CreateTypeDeclData(BfType* type, BfProject* curProject);
BfIRValue CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData);
BfIRValue FixClassVData(BfIRValue value);

View file

@ -127,6 +127,7 @@ public:
DependencyFlag_VirtualCall = 0x2000000,
DependencyFlag_WeakReference = 0x4000000, // Keeps alive but won't rebuild
DependencyFlag_ValueTypeSizeDep = 0x8000000, // IE: int32[DepType.cVal]
DependencyFlag_TypeSignature = 0x10000000,
DependencyFlag_DependentUsageMask = ~(DependencyFlag_UnspecializedType | DependencyFlag_MethodGenericArg | DependencyFlag_GenericArgRef)
};

View file

@ -1091,6 +1091,12 @@ BfProject::~BfProject()
BfLogSysM("Deleting project %p %s\n", this, mName.c_str());
}
void BfProject::ClearCache()
{
mDependencySet.Clear();
mDependencyKindDict.Clear();
}
bool BfProject::ContainsReference(BfProject* refProject)
{
if (refProject->mDisabled)
@ -1131,6 +1137,41 @@ bool BfProject::HasDependency(BfProject* project)
return mDependencySet.Contains(project);
}
BfProject::DependencyKind BfProject::GetDependencyKind(BfProject* project)
{
DependencyKind* depKindPtr = NULL;
if (mDependencyKindDict.TryAdd(project, NULL, &depKindPtr))
{
*depKindPtr = DependencyKind_None;
if (project == this)
{
*depKindPtr = DependencyKind_Identity;
}
else if (HasDependency(project))
{
*depKindPtr = DependencyKind_Dependency;
}
else if (project->HasDependency(this))
{
*depKindPtr = DependencyKind_Dependent_Exclusive;
for (auto checkProject : mSystem->mProjects)
{
if ((checkProject == this) || (checkProject == project) || (checkProject->mDisabled))
continue;
if (checkProject->HasDependency(this))
{
if (!checkProject->HasDependency(project))
{
*depKindPtr = DependencyKind_Dependent_Shared;
}
}
}
}
}
return *depKindPtr;
}
//////////////////////////////////////////////////////////////////////////
BfErrorBase::~BfErrorBase()
@ -2480,6 +2521,21 @@ BfProject* BfSystem::GetProject(const StringImpl& projName)
return NULL;
}
uint64 BfSystem::GetTypeDeclListHash()
{
HashContext hashCtx;
for (auto project : mProjects)
{
hashCtx.MixinStr(project->mName);
hashCtx.Mixin(project->mDisabled);
hashCtx.Mixin(project->mDependencies.mSize);
for (auto dep : project->mDependencies)
hashCtx.Mixin(dep->mIdx);
}
hashCtx.Mixin(mTypeDefs.mRevision);
return hashCtx.Finish128().mLow;
}
BfTypeReference* BfSystem::GetTypeRefElement(BfTypeReference* typeRef)
{
if (auto elementedType = BfNodeDynCast<BfElementedTypeRef>(typeRef))

View file

@ -1404,6 +1404,15 @@ public:
DeleteStage_AwaitingRefs,
};
enum DependencyKind
{
DependencyKind_None,
DependencyKind_Dependency,
DependencyKind_Identity,
DependencyKind_Dependent_Exclusive,
DependencyKind_Dependent_Shared
};
public:
BfSystem* mSystem;
String mName;
@ -1425,6 +1434,7 @@ public:
HashSet<BfModule*> mUsedModules;
HashSet<BfType*> mReferencedTypeData;
HashSet<BfProject*> mDependencySet;
Dictionary<BfProject*, DependencyKind> mDependencyKindDict;
Val128 mBuildConfigHash;
Val128 mVDataConfigHash;
@ -1435,10 +1445,12 @@ public:
BfProject();
~BfProject();
void ClearCache();
bool ContainsReference(BfProject* refProject);
bool ReferencesOrReferencedBy(BfProject* refProject);
bool IsTestProject();
bool HasDependency(BfProject* project);
DependencyKind GetDependencyKind(BfProject* project);
};
//CDH TODO move these out to separate header if list gets big/unwieldy
@ -1864,6 +1876,7 @@ public:
BfParser* CreateParser(BfProject* bfProject);
BfCompiler* CreateCompiler(bool isResolveOnly);
BfProject* GetProject(const StringImpl& projName);
uint64 GetTypeDeclListHash();
BfTypeReference* GetTypeRefElement(BfTypeReference* typeRef);
BfTypeDef* FilterDeletedTypeDef(BfTypeDef* typeDef);

View file

@ -3598,11 +3598,13 @@ CeContext::CeContext()
mCallerActiveTypeDef = NULL;
mCurExpectingType = NULL;
mCurEmitContext = NULL;
mTypeDeclState = NULL;
}
CeContext::~CeContext()
{
delete mHeap;
delete mTypeDeclState;
BF_ASSERT(mInternalDataMap.IsEmpty());
}
@ -3814,6 +3816,11 @@ void CeContext::AddFileRebuild(const StringImpl& path)
}
}
void CeContext::AddTypeSigRebuild(BfType* type)
{
mCurModule->AddDependency(type, mCurModule->mCurTypeInstance, BfDependencyMap::DependencyFlag_TypeSignature);
}
uint8* CeContext::CeMalloc(int size)
{
#ifdef CE_ENABLE_HEAP
@ -3878,11 +3885,21 @@ addr_ce CeContext::GetConstantData(BeConstant* constant)
return (addr_ce)(ptr - mMemory.mVals);
}
addr_ce CeContext::GetReflectTypeDecl(int typeId)
{
if (mTypeDeclState == NULL)
mTypeDeclState = new CeTypeDeclState();
if (mTypeDeclState->mReflectDeclMap.IsEmpty())
{
CeRebuildKey rebuildKey;
rebuildKey.mKind = CeRebuildKey::Kind_TypeDeclListHash;
CeRebuildValue rebuildValue;
rebuildValue.mInt = mCeMachine->mCompiler->mSystem->GetTypeDeclListHash();
AddRebuild(rebuildKey, rebuildValue);
}
addr_ce* addrPtr = NULL;
if (!mReflectDeclMap.TryAdd(typeId, NULL, &addrPtr))
if (!mTypeDeclState->mReflectDeclMap.TryAdd(typeId, NULL, &addrPtr))
return *addrPtr;
auto ceModule = mCeMachine->mCeModule;
@ -3897,13 +3914,11 @@ addr_ce CeContext::GetReflectTypeDecl(int typeId)
if (bfType == NULL)
return 0;
if (bfType->mDefineState < BfTypeDefineState_HasInterfaces_Direct)
ceModule->PopulateType(bfType, BfPopulateType_Interfaces_Direct);
if (bfType->mDefineState < BfTypeDefineState_HasCustomAttributes)
ceModule->PopulateType(bfType, BfPopulateType_CustomAttributes);
BfCreateTypeDataContext createTypeDataCtx;
auto irData = ceModule->CreateTypeDeclData(bfType);
auto irData = ceModule->CreateTypeDeclData(bfType, mCurModule->mProject);
BeValue* beValue = NULL;
if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData))
@ -6112,11 +6127,45 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
addr_ce reflectType = 0;
auto context = mCeMachine->mCeModule->mContext;
if (mTypeDeclState == NULL)
mTypeDeclState = new CeTypeDeclState();
while (true)
{
typeId++;
if (typeId >= mCeMachine->mCeModule->mContext->mTypes.mSize)
{
int foundTypeCount = 0;
if (!mTypeDeclState->mCheckedAllTypeDefs)
{
mTypeDeclState->mCheckedAllTypeDefs = true;
for (auto typeDef : ceModule->mSystem->mTypeDefs)
{
if ((typeDef->mIsPartial) && (!typeDef->mIsCombinedPartial))
continue;
if (typeDef->mTypeCode == BfTypeCode_TypeAlias)
continue;
if (typeDef->mTypeDeclaration == NULL)
continue;
if (mTypeDeclState->mIteratedTypeDefs.Contains(typeDef))
continue;
int lastTypeId = mCeMachine->mCompiler->mCurTypeId;
auto resolvedType = mCeMachine->mCeModule->ResolveTypeDef(typeDef, BfPopulateType_Identity);
if ((resolvedType != NULL) && (resolvedType->IsTypeInstance()))
{
if (resolvedType->mDefineState == BfTypeDefineState_Undefined)
foundTypeCount++;
}
}
}
if (foundTypeCount > 0)
typeId = 0;
else
break;
}
auto bfType = mCeMachine->mCeModule->mContext->mTypes[typeId];
if (bfType != NULL)
{
@ -6124,17 +6173,22 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
continue;
if (bfType->IsBoxed())
continue;
if (bfType->IsArray())
continue;
if (bfType->IsNullable())
continue;
auto bfTypeInst = bfType->ToTypeInstance();
if (bfTypeInst == NULL)
continue;
if (bfTypeInst->mTypeDef->mTypeDeclaration == NULL)
auto useTypeDef = bfTypeInst->mTypeDef;
useTypeDef = useTypeDef->GetLatest();
if (!mTypeDeclState->mCheckedAllTypeDefs)
{
mTypeDeclState->mIteratedTypeDefs.Add(useTypeDef);
}
else
{
if (mTypeDeclState->mIteratedTypeDefs.Contains(useTypeDef))
continue;
}
if (bfTypeInst->IsGenericTypeInstance())
{
@ -6144,12 +6198,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
continue;
}
auto curProject = mCurModule->mProject;
auto declProject = bfTypeInst->mTypeDef->mProject;
if ((declProject != curProject) && (!curProject->HasDependency(declProject)))
continue;
reflectType = GetReflectTypeDecl(typeId);
if (reflectType != 0)
break;
@ -6159,6 +6207,26 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_FixVariables();
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
}
else if (checkFunction->mFunctionKind == CeFunctionKind_GetBaseType)
{
int32 typeId = *(int32*)((uint8*)stackPtr + 4);
int baseTypeId = 0;
BfType* type = GetBfType(typeId);
if (type != NULL)
{
AddTypeSigRebuild(type);
if (auto typeInst = type->ToTypeInstance())
{
if (type->mDefineState < BfTypeDefineState_HasCustomAttributes)
ceModule->PopulateType(type, BfPopulateType_CustomAttributes);
if (typeInst->mBaseType != NULL)
baseTypeId = typeInst->mBaseType->mTypeId;
}
}
*(addr_ce*)(stackPtr + 0) = baseTypeId;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_HasDeclaredMember)
{
int32 typeId = *(int32*)((uint8*)stackPtr + 1);
@ -6177,6 +6245,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
BfType* type = GetBfType(typeId);
if ((type != NULL) && (type->IsTypeInstance()))
{
AddTypeSigRebuild(type);
auto typeInst = type->ToTypeInstance();
typeInst->mTypeDef->PopulateMemberSets();
if (memberKind == 0) // Field
@ -6307,6 +6376,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
bool success = false;
if (type != NULL)
{
AddTypeSigRebuild(type);
auto typeInst = type->ToTypeInstance();
if (typeInst != NULL)
success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeIdx, resultPtr);
@ -6326,6 +6396,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
bool success = false;
if (type != NULL)
{
AddTypeSigRebuild(type);
auto typeInst = type->ToTypeInstance();
if (typeInst != NULL)
{
@ -6359,6 +6430,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid method instance");
return false;
}
AddTypeSigRebuild(methodInstance->GetOwner());
bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeIdx, resultPtr);
_FixVariables();
*(addr_ce*)(stackPtr + 0) = success;
@ -6372,6 +6444,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
addr_ce reflectType = 0;
if (type != NULL)
{
AddTypeSigRebuild(type);
auto typeInst = type->ToTypeInstance();
if (typeInst != NULL)
{
@ -6394,6 +6467,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
addr_ce reflectType = 0;
if (type != NULL)
{
AddTypeSigRebuild(type);
auto typeInst = type->ToTypeInstance();
if (typeInst != NULL)
{
@ -6428,6 +6502,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid method instance");
return false;
}
AddTypeSigRebuild(methodInstance->GetOwner());
auto attrType = GetCustomAttributeType(methodInstance->GetCustomAttributes(), attributeIdx);
if (attrType != NULL)
CeSetAddrVal(stackPtr + 0, GetReflectType(attrType->mTypeId), ptrSize);
@ -6511,6 +6586,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
return false;
}
AddTypeSigRebuild(methodInstance->GetOwner());
int genericArgCount = 0;
if (methodInstance->mMethodInfoEx != NULL)
genericArgCount = methodInstance->mMethodInfoEx->mMethodGenericArguments.mSize;
@ -9867,6 +9943,10 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
{
ceFunction->mFunctionKind = CeFunctionKind_GetReflectNextTypeDecl;
}
else if (methodDef->mName == "Comptime_Type_GetBaseType")
{
ceFunction->mFunctionKind = CeFunctionKind_GetBaseType;
}
else if (methodDef->mName == "Comptime_Type_HasDeclaredMember")
{
ceFunction->mFunctionKind = CeFunctionKind_HasDeclaredMember;
@ -10488,7 +10568,8 @@ CeContext* CeMachine::AllocContext()
void CeMachine::ReleaseContext(CeContext* ceContext)
{
ceContext->mStringMap.Clear();
ceContext->mReflectDeclMap.Clear();
delete ceContext->mTypeDeclState;
ceContext->mTypeDeclState = NULL;
ceContext->mReflectMap.Clear();
ceContext->mConstDataMap.Clear();
ceContext->mMemory.Clear();

View file

@ -432,6 +432,7 @@ enum CeFunctionKind
CeFunctionKind_GetReflectTypeDeclById,
CeFunctionKind_GetReflectTypeDeclByName,
CeFunctionKind_GetReflectNextTypeDecl,
CeFunctionKind_GetBaseType,
CeFunctionKind_HasDeclaredMember,
CeFunctionKind_GetReflectType,
CeFunctionKind_GetReflectTypeById,
@ -957,16 +958,24 @@ public:
{
Kind_None,
Kind_File,
Kind_Directory
Kind_Directory,
Kind_TypeDeclListHash,
};
public:
Kind mKind;
String mString;
int mInt;
CeRebuildKey()
{
mKind = Kind_None;
mInt = 0;
}
bool operator==(const CeRebuildKey& other) const
{
return (mKind == other.mKind) && (mString == other.mString);
return (mKind == other.mKind) && (mString == other.mString) && (mInt == other.mInt);
}
};
@ -1095,6 +1104,20 @@ public:
}
};
class CeTypeDeclState
{
public:
Dictionary<int, addr_ce> mReflectDeclMap;
HashSet<BfTypeDef*> mIteratedTypeDefs;
bool mCheckedAllTypeDefs;
public:
CeTypeDeclState()
{
mCheckedAllTypeDefs = false;
}
};
class CeContext
{
public:
@ -1111,7 +1134,7 @@ public:
int mStackSize;
Dictionary<int, addr_ce> mStringMap;
Dictionary<int, addr_ce> mReflectMap;
Dictionary<int, addr_ce> mReflectDeclMap;
CeTypeDeclState* mTypeDeclState;
Dictionary<Val128, addr_ce> mConstDataMap;
HashSet<int> mStaticCtorExecSet;
Dictionary<String, CeStaticFieldInfo> mStaticFieldMap;
@ -1140,6 +1163,7 @@ public:
void CalcWorkingDir();
void FixRelativePath(StringImpl& path);
bool AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value);
void AddTypeSigRebuild(BfType* type);
void AddFileRebuild(const StringImpl& filePath);
uint8* CeMalloc(int size);
bool CeFree(addr_ce addr);