1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22: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; String toolsetErrors;
for (auto project : mSystem->mProjects) for (auto project : mSystem->mProjects)
{ {
project->mDependencySet.Clear(); project->ClearCache();
if (project->mDisabled) if (project->mDisabled)
continue; continue;
if (project->mCodeGenOptions.mLTOType != BfLTOType_None) if (project->mCodeGenOptions.mLTOType != BfLTOType_None)

View file

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

View file

@ -12004,7 +12004,13 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
return false; 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 // We want to try to avoid triggering OnTypeInit for basic info
mModule->PopulateType(type, BfPopulateType_Interfaces_Direct); mModule->PopulateType(type, BfPopulateType_Interfaces_Direct);
@ -12286,7 +12292,10 @@ bool BfExprEvaluator::LookupTypeProp(BfTypeOfExpression* typeOfExpr, BfIdentifie
} }
} }
else else
{
success = false;
return false; return false;
}
} }
if ((type->IsGenericParam()) && (!mModule->mIsComptimeModule)) if ((type->IsGenericParam()) && (!mModule->mIsComptimeModule))

View file

@ -6128,7 +6128,7 @@ BfIRValue BfModule::GetTypeTypeData(BfType* type, BfCreateTypeDataContext& ctx,
typeFlags |= BfTypeFlags_SizedArray; typeFlags |= BfTypeFlags_SizedArray;
if (type->IsConstExprValue()) if (type->IsConstExprValue())
typeFlags |= BfTypeFlags_ConstExpr; typeFlags |= BfTypeFlags_ConstExpr;
if (type->IsSplattable()) if ((!wantsTypeDecl) && (type->IsSplattable()))
typeFlags |= BfTypeFlags_Splattable; typeFlags |= BfTypeFlags_Splattable;
if (type->IsUnion()) if (type->IsUnion())
typeFlags |= BfTypeFlags_Union; typeFlags |= BfTypeFlags_Union;
@ -6147,7 +6147,7 @@ BfIRValue BfModule::GetTypeTypeData(BfType* type, BfCreateTypeDataContext& ctx,
return typeTypeData; return typeTypeData;
} }
BfIRValue BfModule::CreateTypeDeclData(BfType* type) BfIRValue BfModule::CreateTypeDeclData(BfType* type, BfProject* curProject)
{ {
auto typeDeclType = ResolveTypeDef(mCompiler->mTypeTypeDeclDef)->ToTypeInstance(); auto typeDeclType = ResolveTypeDef(mCompiler->mTypeTypeDeclDef)->ToTypeInstance();
@ -6175,15 +6175,49 @@ BfIRValue BfModule::CreateTypeDeclData(BfType* type)
if (typeInst != NULL) if (typeInst != NULL)
baseType = typeInst->mBaseType; 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); BfIRValue objectData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(mContext->mBfObjectType, BfIRPopulateType_Full), typeValueParams);
SizedArray<BfIRValue, 9> typeDataParams = SizedArray<BfIRValue, 9> typeDataParams =
{ {
objectData, objectData,
GetConstValue(type->mTypeId, typeIdType), // mTypeId GetConstValue(type->mTypeId, typeIdType), // mTypeId
GetConstValue((baseType != NULL) ? baseType->mTypeId : 0, typeIdType), // mBaseTypeId
GetConstValue((outerType != NULL) ? outerType->mTypeId : 0, typeIdType), // mOuterTypeId GetConstValue((outerType != NULL) ? outerType->mTypeId : 0, typeIdType), // mOuterTypeId
GetConstValue(typeFlags, intType), // mTypeFlags GetConstValue(typeFlags, intType), // mTypeFlags
GetConstValue(typeCode, byteType), // mTypeCode GetConstValue(flags, byteType), // mFlags
GetConstValue(typeCode, byteType), // mTypeCode
}; };
FixConstValueParams(typeDeclType, typeDataParams); FixConstValueParams(typeDeclType, typeDataParams);
auto typeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(typeDeclType, BfIRPopulateType_Full), typeDataParams); auto typeData = mBfIRBuilder->CreateConstAgg_Value(mBfIRBuilder->MapTypeInst(typeDeclType, BfIRPopulateType_Full), typeDataParams);

View file

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

View file

@ -127,6 +127,7 @@ public:
DependencyFlag_VirtualCall = 0x2000000, DependencyFlag_VirtualCall = 0x2000000,
DependencyFlag_WeakReference = 0x4000000, // Keeps alive but won't rebuild DependencyFlag_WeakReference = 0x4000000, // Keeps alive but won't rebuild
DependencyFlag_ValueTypeSizeDep = 0x8000000, // IE: int32[DepType.cVal] DependencyFlag_ValueTypeSizeDep = 0x8000000, // IE: int32[DepType.cVal]
DependencyFlag_TypeSignature = 0x10000000,
DependencyFlag_DependentUsageMask = ~(DependencyFlag_UnspecializedType | DependencyFlag_MethodGenericArg | DependencyFlag_GenericArgRef) 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()); BfLogSysM("Deleting project %p %s\n", this, mName.c_str());
} }
void BfProject::ClearCache()
{
mDependencySet.Clear();
mDependencyKindDict.Clear();
}
bool BfProject::ContainsReference(BfProject* refProject) bool BfProject::ContainsReference(BfProject* refProject)
{ {
if (refProject->mDisabled) if (refProject->mDisabled)
@ -1131,6 +1137,41 @@ bool BfProject::HasDependency(BfProject* project)
return mDependencySet.Contains(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() BfErrorBase::~BfErrorBase()
@ -2480,6 +2521,21 @@ BfProject* BfSystem::GetProject(const StringImpl& projName)
return NULL; 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) BfTypeReference* BfSystem::GetTypeRefElement(BfTypeReference* typeRef)
{ {
if (auto elementedType = BfNodeDynCast<BfElementedTypeRef>(typeRef)) if (auto elementedType = BfNodeDynCast<BfElementedTypeRef>(typeRef))

View file

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

View file

@ -3598,11 +3598,13 @@ CeContext::CeContext()
mCallerActiveTypeDef = NULL; mCallerActiveTypeDef = NULL;
mCurExpectingType = NULL; mCurExpectingType = NULL;
mCurEmitContext = NULL; mCurEmitContext = NULL;
mTypeDeclState = NULL;
} }
CeContext::~CeContext() CeContext::~CeContext()
{ {
delete mHeap; delete mHeap;
delete mTypeDeclState;
BF_ASSERT(mInternalDataMap.IsEmpty()); 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) uint8* CeContext::CeMalloc(int size)
{ {
#ifdef CE_ENABLE_HEAP #ifdef CE_ENABLE_HEAP
@ -3878,12 +3885,22 @@ addr_ce CeContext::GetConstantData(BeConstant* constant)
return (addr_ce)(ptr - mMemory.mVals); return (addr_ce)(ptr - mMemory.mVals);
} }
addr_ce CeContext::GetReflectTypeDecl(int typeId) 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; addr_ce* addrPtr = NULL;
if (!mReflectDeclMap.TryAdd(typeId, NULL, &addrPtr)) if (!mTypeDeclState->mReflectDeclMap.TryAdd(typeId, NULL, &addrPtr))
return *addrPtr; return *addrPtr;
auto ceModule = mCeMachine->mCeModule; auto ceModule = mCeMachine->mCeModule;
SetAndRestoreValue<bool> ignoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, false); SetAndRestoreValue<bool> ignoreWrites(ceModule->mBfIRBuilder->mIgnoreWrites, false);
@ -3896,14 +3913,12 @@ addr_ce CeContext::GetReflectTypeDecl(int typeId)
auto bfType = mCeMachine->mCeModule->mContext->mTypes[typeId]; auto bfType = mCeMachine->mCeModule->mContext->mTypes[typeId];
if (bfType == NULL) if (bfType == NULL)
return 0; return 0;
if (bfType->mDefineState < BfTypeDefineState_HasInterfaces_Direct)
ceModule->PopulateType(bfType, BfPopulateType_Interfaces_Direct);
if (bfType->mDefineState < BfTypeDefineState_HasCustomAttributes) if (bfType->mDefineState < BfTypeDefineState_HasCustomAttributes)
ceModule->PopulateType(bfType, BfPopulateType_CustomAttributes); ceModule->PopulateType(bfType, BfPopulateType_CustomAttributes);
BfCreateTypeDataContext createTypeDataCtx; BfCreateTypeDataContext createTypeDataCtx;
auto irData = ceModule->CreateTypeDeclData(bfType); auto irData = ceModule->CreateTypeDeclData(bfType, mCurModule->mProject);
BeValue* beValue = NULL; BeValue* beValue = NULL;
if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData)) if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData))
@ -6112,29 +6127,68 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
addr_ce reflectType = 0; addr_ce reflectType = 0;
auto context = mCeMachine->mCeModule->mContext; auto context = mCeMachine->mCeModule->mContext;
if (mTypeDeclState == NULL)
mTypeDeclState = new CeTypeDeclState();
while (true) while (true)
{ {
typeId++; typeId++;
if (typeId >= mCeMachine->mCeModule->mContext->mTypes.mSize) if (typeId >= mCeMachine->mCeModule->mContext->mTypes.mSize)
break; {
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]; auto bfType = mCeMachine->mCeModule->mContext->mTypes[typeId];
if (bfType != NULL) if (bfType != NULL)
{ {
if (bfType->IsOnDemand()) if (bfType->IsOnDemand())
continue; continue;
if (bfType->IsBoxed()) if (bfType->IsBoxed())
continue; continue;
if (bfType->IsArray())
continue;
if (bfType->IsNullable())
continue;
auto bfTypeInst = bfType->ToTypeInstance(); auto bfTypeInst = bfType->ToTypeInstance();
if (bfTypeInst == NULL) if (bfTypeInst == NULL)
continue; continue;
if (bfTypeInst->mTypeDef->mTypeDeclaration == NULL) auto useTypeDef = bfTypeInst->mTypeDef;
continue; useTypeDef = useTypeDef->GetLatest();
if (!mTypeDeclState->mCheckedAllTypeDefs)
{
mTypeDeclState->mIteratedTypeDefs.Add(useTypeDef);
}
else
{
if (mTypeDeclState->mIteratedTypeDefs.Contains(useTypeDef))
continue;
}
if (bfTypeInst->IsGenericTypeInstance()) if (bfTypeInst->IsGenericTypeInstance())
{ {
@ -6142,13 +6196,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
continue; continue;
if (bfTypeInst->IsUnspecializedTypeVariation()) if (bfTypeInst->IsUnspecializedTypeVariation())
continue; continue;
} }
auto curProject = mCurModule->mProject;
auto declProject = bfTypeInst->mTypeDef->mProject;
if ((declProject != curProject) && (!curProject->HasDependency(declProject)))
continue;
reflectType = GetReflectTypeDecl(typeId); reflectType = GetReflectTypeDecl(typeId);
if (reflectType != 0) if (reflectType != 0)
@ -6159,6 +6207,26 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_FixVariables(); _FixVariables();
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); 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) else if (checkFunction->mFunctionKind == CeFunctionKind_HasDeclaredMember)
{ {
int32 typeId = *(int32*)((uint8*)stackPtr + 1); int32 typeId = *(int32*)((uint8*)stackPtr + 1);
@ -6176,7 +6244,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
BfType* type = GetBfType(typeId); BfType* type = GetBfType(typeId);
if ((type != NULL) && (type->IsTypeInstance())) if ((type != NULL) && (type->IsTypeInstance()))
{ {
AddTypeSigRebuild(type);
auto typeInst = type->ToTypeInstance(); auto typeInst = type->ToTypeInstance();
typeInst->mTypeDef->PopulateMemberSets(); typeInst->mTypeDef->PopulateMemberSets();
if (memberKind == 0) // Field if (memberKind == 0) // Field
@ -6307,6 +6376,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
bool success = false; bool success = false;
if (type != NULL) if (type != NULL)
{ {
AddTypeSigRebuild(type);
auto typeInst = type->ToTypeInstance(); auto typeInst = type->ToTypeInstance();
if (typeInst != NULL) if (typeInst != NULL)
success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeIdx, resultPtr); success = GetCustomAttribute(mCurModule, typeInst->mConstHolder, typeInst->mCustomAttributes, attributeIdx, resultPtr);
@ -6326,6 +6396,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
bool success = false; bool success = false;
if (type != NULL) if (type != NULL)
{ {
AddTypeSigRebuild(type);
auto typeInst = type->ToTypeInstance(); auto typeInst = type->ToTypeInstance();
if (typeInst != NULL) if (typeInst != NULL)
{ {
@ -6359,6 +6430,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid method instance"); _Fail("Invalid method instance");
return false; return false;
} }
AddTypeSigRebuild(methodInstance->GetOwner());
bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeIdx, resultPtr); bool success = GetCustomAttribute(mCurModule, methodInstance->GetOwner()->mConstHolder, methodInstance->GetCustomAttributes(), attributeIdx, resultPtr);
_FixVariables(); _FixVariables();
*(addr_ce*)(stackPtr + 0) = success; *(addr_ce*)(stackPtr + 0) = success;
@ -6372,6 +6444,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
addr_ce reflectType = 0; addr_ce reflectType = 0;
if (type != NULL) if (type != NULL)
{ {
AddTypeSigRebuild(type);
auto typeInst = type->ToTypeInstance(); auto typeInst = type->ToTypeInstance();
if (typeInst != NULL) if (typeInst != NULL)
{ {
@ -6394,6 +6467,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
addr_ce reflectType = 0; addr_ce reflectType = 0;
if (type != NULL) if (type != NULL)
{ {
AddTypeSigRebuild(type);
auto typeInst = type->ToTypeInstance(); auto typeInst = type->ToTypeInstance();
if (typeInst != NULL) if (typeInst != NULL)
{ {
@ -6428,6 +6502,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid method instance"); _Fail("Invalid method instance");
return false; return false;
} }
AddTypeSigRebuild(methodInstance->GetOwner());
auto attrType = GetCustomAttributeType(methodInstance->GetCustomAttributes(), attributeIdx); auto attrType = GetCustomAttributeType(methodInstance->GetCustomAttributes(), attributeIdx);
if (attrType != NULL) if (attrType != NULL)
CeSetAddrVal(stackPtr + 0, GetReflectType(attrType->mTypeId), ptrSize); CeSetAddrVal(stackPtr + 0, GetReflectType(attrType->mTypeId), ptrSize);
@ -6511,6 +6586,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
return false; return false;
} }
AddTypeSigRebuild(methodInstance->GetOwner());
int genericArgCount = 0; int genericArgCount = 0;
if (methodInstance->mMethodInfoEx != NULL) if (methodInstance->mMethodInfoEx != NULL)
genericArgCount = methodInstance->mMethodInfoEx->mMethodGenericArguments.mSize; genericArgCount = methodInstance->mMethodInfoEx->mMethodGenericArguments.mSize;
@ -9362,7 +9438,7 @@ CeMachine::~CeMachine()
delete mTempParser; delete mTempParser;
delete mTempReducer; delete mTempReducer;
delete mAppendAllocInfo; delete mAppendAllocInfo;
delete mCeModule; delete mCeModule;
auto _RemoveFunctionInfo = [&](CeFunctionInfo* functionInfo) auto _RemoveFunctionInfo = [&](CeFunctionInfo* functionInfo)
{ {
@ -9867,6 +9943,10 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
{ {
ceFunction->mFunctionKind = CeFunctionKind_GetReflectNextTypeDecl; ceFunction->mFunctionKind = CeFunctionKind_GetReflectNextTypeDecl;
} }
else if (methodDef->mName == "Comptime_Type_GetBaseType")
{
ceFunction->mFunctionKind = CeFunctionKind_GetBaseType;
}
else if (methodDef->mName == "Comptime_Type_HasDeclaredMember") else if (methodDef->mName == "Comptime_Type_HasDeclaredMember")
{ {
ceFunction->mFunctionKind = CeFunctionKind_HasDeclaredMember; ceFunction->mFunctionKind = CeFunctionKind_HasDeclaredMember;
@ -10488,7 +10568,8 @@ CeContext* CeMachine::AllocContext()
void CeMachine::ReleaseContext(CeContext* ceContext) void CeMachine::ReleaseContext(CeContext* ceContext)
{ {
ceContext->mStringMap.Clear(); ceContext->mStringMap.Clear();
ceContext->mReflectDeclMap.Clear(); delete ceContext->mTypeDeclState;
ceContext->mTypeDeclState = NULL;
ceContext->mReflectMap.Clear(); ceContext->mReflectMap.Clear();
ceContext->mConstDataMap.Clear(); ceContext->mConstDataMap.Clear();
ceContext->mMemory.Clear(); ceContext->mMemory.Clear();

View file

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