1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 12:32:20 +02:00

Extensive runtime refactor to reduce generated executable sizes

This commit is contained in:
Brian Fiete 2024-03-16 07:23:29 -04:00
parent 4e750a7e1a
commit ddd9b1b218
74 changed files with 2514 additions and 717 deletions

View file

@ -1220,7 +1220,7 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
Array<BfType*> vdataTypeList;
HashSet<BfModule*> usedModuleSet;
HashSet<BfType*> reflectTypeSet;
HashSet<BfType*> reflectSkipTypeSet;
HashSet<BfType*> reflectFieldTypeSet;
vdataHashCtx.MixinStr(project->mStartupObject);
@ -1398,20 +1398,49 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
bool madeBfTypeData = false;
auto typeDefType = mContext->mBfTypeType;
bool needsTypeList = bfModule->IsMethodImplementedAndReified(typeDefType, "GetType");
bool needsFullTypeList = bfModule->IsMethodImplementedAndReified(typeDefType, "GetType");
bool needsTypeList = needsFullTypeList || bfModule->IsMethodImplementedAndReified(typeDefType, "GetType_");
bool needsObjectTypeData = needsTypeList || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "RawGetType") || bfModule->IsMethodImplementedAndReified(vdataContext->mBfObjectType, "GetType");
bool needsTypeNames = bfModule->IsMethodImplementedAndReified(typeDefType, "GetName") || bfModule->IsMethodImplementedAndReified(typeDefType, "GetFullName");
bool needsStringLiteralList = (mOptions.mAllowHotSwapping) || (bfModule->IsMethodImplementedAndReified(stringType, "Intern")) || (bfModule->IsMethodImplementedAndReified(stringViewType, "Intern"));
Dictionary<int, int> usedStringIdMap;
BfCreateTypeDataContext createTypeDataCtx;
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectTypeInstanceTypeDef));
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectSpecializedGenericType));
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectUnspecializedGenericType));
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectArrayType));
reflectTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectGenericParamType));
if (!needsTypeList)
{
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mTypeTypeDef));
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectTypeInstanceTypeDef));
}
if (!needsFullTypeList)
{
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectSpecializedGenericType));
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectUnspecializedGenericType));
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectConstExprType));
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectArrayType));
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectGenericParamType));
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectPointerType));
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectSizedArrayType));
reflectSkipTypeSet.Add(vdataContext->mUnreifiedModule->ResolveTypeDef(mReflectRefType));
}
HashSet<BfType*> boxeeSet;
for (auto type : vdataTypeList)
{
auto typeInst = type->ToTypeInstance();
if ((!type->IsReified()) || (type->IsUnspecializedType()))
continue;
if (type->IsBoxed())
boxeeSet.Add(typeInst->GetUnderlyingType());
}
int usedTypeCount = 0;
HashSet<BfType*> vDataTypeSet;
SmallVector<BfIRValue, 256> typeDataVector;
Array<BfType*> usedTypeDataVector;
for (auto type : vdataTypeList)
{
if (type->IsTypeAlias())
@ -1425,9 +1454,12 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
if ((typeInst != NULL) && (!typeInst->IsReified()) && (!typeInst->IsUnspecializedType()))
continue;
bool needsTypeData = (needsTypeList) || ((type->IsObject()) && (needsObjectTypeData));
bool needsTypeData = (needsFullTypeList) || ((type->IsObject()) && (needsObjectTypeData));
bool needsVData = (type->IsObject()) && (typeInst->HasBeenInstantiated());
if ((needsObjectTypeData) && (boxeeSet.Contains(typeInst)))
needsTypeData = true;
bool forceReflectFields = false;
if (bfModule->mProject->mReferencedTypeData.Contains(type))
@ -1437,8 +1469,16 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
forceReflectFields = true;
}
BfIRValue typeVariable;
if (reflectSkipTypeSet.Contains(type))
{
if (!bfModule->mProject->mReferencedTypeData.Contains(type))
{
needsTypeData = false;
needsVData = false;
}
}
BfIRValue typeVariable;
if ((needsTypeData) || (needsVData))
{
if (reflectFieldTypeSet.Contains(type))
@ -1446,14 +1486,25 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
needsTypeData = true;
forceReflectFields = true;
}
else if (reflectTypeSet.Contains(type))
/*else if (reflectTypeSet.Contains(type))
{
needsTypeData = true;
needsVData = true;
}
}*/
typeVariable = bfModule->CreateTypeData(type, usedStringIdMap, forceReflectFields, needsTypeData, needsTypeNames, needsVData);
if (needsVData)
vDataTypeSet.Add(type);
typeVariable = bfModule->CreateTypeData(type, createTypeDataCtx, forceReflectFields, needsTypeData, needsTypeNames, needsVData);
if (typeVariable)
usedTypeDataVector.Add(type);
}
else if ((type->IsInterface()) && (typeInst->mSlotNum >= 0))
{
bfModule->CreateSlotOfs(typeInst);
}
usedTypeCount++;
type->mDirty = false;
if (needsTypeList)
@ -1573,13 +1624,13 @@ void BfCompiler::CreateVData(BfVDataModule* bfModule)
BfMangler::MangleStaticFieldName(stringsVariableName, GetMangleKind(), stringType->ToTypeInstance(), "sIdStringLiterals", stringPtrType);
Array<BfIRValue> stringList;
stringList.Resize(usedStringIdMap.size());
for (auto& kv : usedStringIdMap)
stringList.Resize(createTypeDataCtx.mUsedStringIdMap.size());
for (auto& kv : createTypeDataCtx.mUsedStringIdMap)
{
stringList[kv.mValue] = bfModule->mStringObjectPool[kv.mKey];
}
BfIRType stringArrayType = bfModule->mBfIRBuilder->GetSizedArrayType(stringPtrIRType, (int)usedStringIdMap.size());
BfIRType stringArrayType = bfModule->mBfIRBuilder->GetSizedArrayType(stringPtrIRType, (int)createTypeDataCtx.mUsedStringIdMap.size());
auto stringArray = bfModule->mBfIRBuilder->CreateConstAgg_Value(stringArrayType, stringList);
auto stringArrayVar = bfModule->mBfIRBuilder->CreateGlobalVariable(stringArrayType, true, BfIRLinkageType_External, stringArray, stringsVariableName);
@ -3994,10 +4045,10 @@ void BfCompiler::VisitSourceExteriorNodes()
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(usingDirective->mTypeRef))
{
mContext->mScratchModule->ResolveTypeRefAllowUnboundGenerics(usingDirective->mTypeRef, BfPopulateType_Identity);
mContext->mScratchModule->ResolveTypeRefAllowUnboundGenerics(usingDirective->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_NoReify);
}
else
mContext->mScratchModule->ResolveTypeRef(usingDirective->mTypeRef, BfPopulateType_Identity);
mContext->mScratchModule->ResolveTypeRef(usingDirective->mTypeRef, BfPopulateType_Identity, BfResolveTypeRefFlag_NoReify);
if ((mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL))
mResolvePassData->mAutoComplete->CheckTypeRef(usingDirective->mTypeRef, false, false);
@ -5608,12 +5659,19 @@ void BfCompiler::ClearBuildCache()
}
}
int BfCompiler::GetVDataPrefixDataCount()
{
return (mSystem->mPtrSize == 4) ? 2 : 1;
}
int BfCompiler::GetDynCastVDataCount()
{
int dynElements = 1 + mMaxInterfaceSlots;
return ((dynElements * 4) + mSystem->mPtrSize - 1) / mSystem->mPtrSize;
}
bool BfCompiler::IsAutocomplete()
{
return (mResolvePassData != NULL) && (mResolvePassData->mAutoComplete != NULL);
@ -7177,6 +7235,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mActionTypeDef = _GetRequiredType("System.Action");
mEnumTypeDef = _GetRequiredType("System.Enum");
mFriendAttributeTypeDef = _GetRequiredType("System.FriendAttribute");
mNoStaticCtorAttributeTypeDef = _GetRequiredType("System.NoStaticCtorAttribute");
mComptimeAttributeTypeDef = _GetRequiredType("System.ComptimeAttribute");
mConstEvalAttributeTypeDef = _GetRequiredType("System.ConstEvalAttribute");
mNoExtensionAttributeTypeDef = _GetRequiredType("System.NoExtensionAttribute");

View file

@ -442,6 +442,7 @@ public:
BfTypeDef* mDisableChecksAttributeTypeDef;
BfTypeDef* mDisableObjectAccessChecksAttributeTypeDef;
BfTypeDef* mFriendAttributeTypeDef;
BfTypeDef* mNoStaticCtorAttributeTypeDef;
BfTypeDef* mComptimeAttributeTypeDef;
BfTypeDef* mConstEvalAttributeTypeDef;
BfTypeDef* mNoExtensionAttributeTypeDef;
@ -501,6 +502,7 @@ public:
void MarkStringPool(BfIRConstHolder* constHolder, BfIRValue irValue);
void ClearUnusedStringPoolEntries();
void ClearBuildCache();
int GetVDataPrefixDataCount();
int GetDynCastVDataCount();
bool IsAutocomplete();
bool IsDataResolvePass();

View file

@ -420,55 +420,74 @@ bool BfContext::ProcessWorkList(bool onlyReifiedTypes, bool onlyReifiedMethods)
didWork = true;
}
for (int workIdx = 0; workIdx < (int)mPopulateTypeWorkList.size(); workIdx++)
for (int populatePass = 0; populatePass < 2; populatePass++)
{
//BP_ZONE("PWL_PopulateType");
if (IsCancellingAndYield())
break;
auto workItemRef = mPopulateTypeWorkList[workIdx];
if (workItemRef == NULL)
for (int workIdx = 0; workIdx < (int)mPopulateTypeWorkList.size(); workIdx++)
{
workIdx = mPopulateTypeWorkList.RemoveAt(workIdx);
continue;
}
//BP_ZONE("PWL_PopulateType");
if (IsCancellingAndYield())
break;
if (!mMidCompileWorkList.IsEmpty())
{
// Let these mid-compiles occur as soon as possible
break;
}
BfType* type = workItemRef->mType;
bool rebuildType = workItemRef->mRebuildType;
auto workItemRef = mPopulateTypeWorkList[workIdx];
if (workItemRef == NULL)
{
workIdx = mPopulateTypeWorkList.RemoveAt(workIdx);
continue;
}
if ((onlyReifiedTypes) && (!type->IsReified()))
{
continue;
}
BfType* type = workItemRef->mType;
bool rebuildType = workItemRef->mRebuildType;
auto typeInst = type->ToTypeInstance();
if ((typeInst != NULL) && (resolveParser != NULL))
{
if (!typeInst->mTypeDef->GetLatest()->HasSource(resolveParser))
if ((onlyReifiedTypes) && (!type->IsReified()))
{
continue;
}
// We want to resolve type aliases first, allowing possible mMidCompileWorkList entries
int wantPass = type->IsTypeAlias() ? 0 : 1;
if (populatePass != wantPass)
continue;
auto typeInst = type->ToTypeInstance();
if ((typeInst != NULL) && (resolveParser != NULL))
{
if (!typeInst->mTypeDef->GetLatest()->HasSource(resolveParser))
{
continue;
}
}
workIdx = mPopulateTypeWorkList.RemoveAt(workIdx);
if (rebuildType)
RebuildType(type);
BF_ASSERT(this == type->mContext);
auto useModule = type->GetModule();
if (useModule == NULL)
{
if (mCompiler->mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude)
useModule = mScratchModule;
else
useModule = mUnreifiedModule;
}
if (!type->IsDeleting())
useModule->PopulateType(type, BfPopulateType_Full);
mCompiler->mStats.mQueuedTypesProcessed++;
mCompiler->UpdateCompletion();
didWork = true;
}
}
workIdx = mPopulateTypeWorkList.RemoveAt(workIdx);
if (rebuildType)
RebuildType(type);
BF_ASSERT(this == type->mContext);
auto useModule = type->GetModule();
if (useModule == NULL)
{
if (mCompiler->mOptions.mCompileOnDemandKind == BfCompileOnDemandKind_AlwaysInclude)
useModule = mScratchModule;
else
useModule = mUnreifiedModule;
}
if (!type->IsDeleting())
useModule->PopulateType(type, BfPopulateType_Full);
mCompiler->mStats.mQueuedTypesProcessed++;
mCompiler->UpdateCompletion();
didWork = true;
if ((!mMidCompileWorkList.IsEmpty()) && (didWork))
{
// Let the mid-compile occur ASAP
continue;
}
for (int workIdx = 0; workIdx < (int)mTypeRefVerifyWorkList.size(); workIdx++)
@ -1984,6 +2003,7 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
}
else if (dependentTypeInst != NULL)
{
mGhostDependencies.Add(type);
// This keeps us from crashing from accessing deleted types on subsequent compiles
mFailTypes.TryAdd(dependentTypeInst, BfFailKind_Normal);
}
@ -2396,6 +2416,38 @@ void BfContext::UpdateRevisedTypes()
}
}
// Handle these "mid-compiles" now so we handle them as early-stage
BfParser* resolveParser = NULL;
if ((mCompiler->mResolvePassData != NULL) && (!mCompiler->mResolvePassData->mParsers.IsEmpty()))
resolveParser = mCompiler->mResolvePassData->mParsers[0];
for (int workIdx = 0; workIdx < (int)mMidCompileWorkList.size(); workIdx++)
{
auto workItemRef = mMidCompileWorkList[workIdx];
if (workItemRef == NULL)
{
workIdx = mMidCompileWorkList.RemoveAt(workIdx);
continue;
}
BfType* type = workItemRef->mType;
String reason = workItemRef->mReason;
auto typeInst = type->ToTypeInstance();
if ((typeInst != NULL) && (resolveParser != NULL))
{
if (!typeInst->mTypeDef->GetLatest()->HasSource(resolveParser))
{
continue;
}
}
workIdx = mMidCompileWorkList.RemoveAt(workIdx);
BfLogSysM("Handling prior-revision MidCompile on type %s in early-stage UpdateRevisedTypes\n", type);
RebuildDependentTypes(type->ToDependedType());
//RebuildDependentTypes_MidCompile(type->ToDependedType(), reason);
}
for (auto typeInst : defEmitParentCheckQueue)
{
if (typeInst->IsDeleting())
@ -2675,6 +2727,8 @@ void BfContext::UpdateRevisedTypes()
RebuildType(type);
}
}
BfLogSysM("BfContext::UpdateRevisedTypes done.\n");
}
void BfContext::VerifyTypeLookups(BfTypeInstance* typeInst)
@ -3459,6 +3513,7 @@ void BfContext::Cleanup()
}
}
mTypeGraveyard.Clear();
mGhostDependencies.Clear();
if (!mDeletingModules.IsEmpty())
{

View file

@ -382,6 +382,7 @@ public:
BfModule* mScratchModule;
BfModule* mUnreifiedModule;
HashSet<String> mUsedModuleNames;
HashSet<BfType*> mGhostDependencies; // We couldn't properly rebuild our dependencies
Dictionary<BfProject*, BfModule*> mProjectModule;
Array<BfModule*> mModules;
Array<BfModule*> mDeletingModules;

View file

@ -5206,7 +5206,12 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe
}
else if (fieldDef->mIsStatic)
{
mModule->CheckStaticAccess(typeInstance);
if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
(!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
{
mModule->CheckStaticAccess(typeInstance);
}
auto retVal = mModule->ReferenceStaticField(fieldInstance);
bool isStaticCtor = (mModule->mCurMethodInstance != NULL) &&
(mModule->mCurMethodInstance->mMethodDef->IsCtorOrInit()) &&
@ -6684,7 +6689,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
#endif
int vExtOfs = typeInst->GetOrigImplBaseVTableSize();
vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, 1 + mModule->mCompiler->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots);
vDataIdx = mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, mModule->mCompiler->GetVDataPrefixDataCount() + mModule->mCompiler->GetDynCastVDataCount() + mModule->mCompiler->mMaxInterfaceSlots);
vDataIdx = mModule->mBfIRBuilder->CreateAdd(vDataIdx, mModule->mBfIRBuilder->CreateConst(BfTypeCode_Int32, vExtOfs));
BfIRValue extendPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, vDataIdx);
vDataPtr = mModule->mBfIRBuilder->CreateLoad(extendPtr);
@ -7601,7 +7607,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
}
else
{
mModule->CheckStaticAccess(methodInstance->mMethodInstanceGroup->mOwner);
if (prevBindResult.mPrevVal == NULL)
{
if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
(!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
{
mModule->CheckStaticAccess(methodInstance->mMethodInstanceGroup->mOwner);
}
}
if (target)
{
@ -8613,7 +8626,16 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
// the type has been initialized
auto targetTypeInst = target.mType->ToTypeInstance();
if (targetTypeInst != NULL)
mModule->CheckStaticAccess(targetTypeInst);
{
if (prevBindResult.mPrevVal == NULL)
{
if ((mModule->mAttributeState == NULL) || (mModule->mAttributeState->mCustomAttributes == NULL) ||
(!mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef)))
{
mModule->CheckStaticAccess(targetTypeInst);
}
}
}
}
if (methodInstance->mReturnType == NULL)
@ -12535,7 +12557,7 @@ void BfExprEvaluator::Visit(BfCheckTypeExpression* checkTypeExpr)
void BfExprEvaluator::Visit(BfDynamicCastExpression* dynCastExpr)
{
auto targetValue = mModule->CreateValueFromExpression(dynCastExpr->mTarget);
auto targetType = mModule->ResolveTypeRefAllowUnboundGenerics(dynCastExpr->mTypeRef, BfPopulateType_Data, false);
auto targetType = mModule->ResolveTypeRefAllowUnboundGenerics(dynCastExpr->mTypeRef, BfPopulateType_Data, BfResolveTypeRefFlag_None, false);
auto autoComplete = GetAutoComplete();
if (autoComplete != NULL)
@ -18843,6 +18865,10 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
checkedKind = BfCheckedKind_Unchecked;
mModule->mAttributeState->mUsed = true;
}
if (mModule->mAttributeState->mCustomAttributes->Contains(mModule->mCompiler->mNoStaticCtorAttributeTypeDef))
{
mModule->mAttributeState->mUsed = true;
}
}
if ((isCascade) && (cascadeOperatorToken != NULL) && ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0))
@ -20967,7 +20993,7 @@ void BfExprEvaluator::InitializedSizedArray(BfSizedArrayType* arrayType, BfToken
}
elementValue = mModule->LoadOrAggregateValue(elementValue);
if (!elementValue.mValue.IsConst())
if (!elemPtrValue.IsConst())
mModule->mBfIRBuilder->CreateAlignedStore(elementValue.mValue, elemPtrValue, checkArrayType->mElementType->mAlign);
}
}

View file

@ -5391,6 +5391,8 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou
mClassVDataRefs.TryGetValue(typeInstance, &globalVariablePtr);
int numElements = 1;
if (mSystem->mPtrSize == 4)
numElements++;
if ((outNumElements != NULL) || (globalVariablePtr == NULL))
{
@ -5432,11 +5434,6 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou
if (outMangledName != NULL)
*outMangledName = classVDataName;
/*if (itr != mClassVDataRefs.end())
{
globalVariable = itr->second;
}*/
BfIRValue globalVariable;
if (globalVariablePtr != NULL)
{
@ -5937,7 +5934,21 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt
return result;
}
BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData)
void BfModule::CreateSlotOfs(BfTypeInstance* typeInstance)
{
int virtSlotIdx = -1;
if ((typeInstance != NULL) && (typeInstance->mSlotNum >= 0))
virtSlotIdx = typeInstance->mSlotNum + mCompiler->GetVDataPrefixDataCount() + mCompiler->GetDynCastVDataCount();
// For interfaces we ONLY emit the slot num
StringT<512> slotVarName;
BfMangler::MangleStaticFieldName(slotVarName, mCompiler->GetMangleKind(), typeInstance, "sBfSlotOfs");
auto intType = GetPrimitiveType(BfTypeCode_Int32);
auto slotNumVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(intType), true, BfIRLinkageType_External,
GetConstValue32(virtSlotIdx), slotVarName);
}
BfIRValue BfModule::CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData)
{
if ((IsHotCompile()) && (!type->mDirty))
return BfIRValue();
@ -6004,13 +6015,18 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
if ((!mTypeDataRefs.ContainsKey(typeDataSource)) && (typeDataSource != type) && (!mIsComptimeModule))
{
CreateTypeData(typeDataSource, usedStringIdMap, false, true, needsTypeNames, true);
CreateTypeData(typeDataSource, ctx, false, true, needsTypeNames, true);
}
typeTypeData = CreateClassVDataGlobal(typeDataSource);
ctx.mReflectTypeSet.Add(typeDataSource);
}
else
typeTypeData = CreateClassVDataGlobal(typeInstanceType->ToTypeInstance());
{
//typeTypeData = CreateClassVDataGlobal(typeInstanceType->ToTypeInstance());
typeTypeData = mBfIRBuilder->CreateConstNull();
}
BfType* longType = GetPrimitiveType(BfTypeCode_Int64);
BfType* intType = GetPrimitiveType(BfTypeCode_Int32);
@ -6119,7 +6135,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
int virtSlotIdx = -1;
if ((typeInstance != NULL) && (typeInstance->mSlotNum >= 0))
virtSlotIdx = typeInstance->mSlotNum + 1 + mCompiler->GetDynCastVDataCount();
virtSlotIdx = typeInstance->mSlotNum + mCompiler->GetVDataPrefixDataCount() + mCompiler->GetDynCastVDataCount();
int memberDataOffset = 0;
if (type->IsInterface())
memberDataOffset = virtSlotIdx * mSystem->mPtrSize;
@ -6316,18 +6332,13 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
String classVDataName;
if (typeInstance->mSlotNum >= 0)
{
// For interfaces we ONLY emit the slot num
StringT<512> slotVarName;
BfMangler::MangleStaticFieldName(slotVarName, mCompiler->GetMangleKind(), typeInstance, "sBfSlotOfs");
auto intType = GetPrimitiveType(BfTypeCode_Int32);
auto slotNumVar = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(intType), true, BfIRLinkageType_External,
GetConstValue32(virtSlotIdx), slotVarName);
CreateSlotOfs(typeInstance);
}
else if ((typeInstance->IsObject()) && (!typeInstance->IsUnspecializedType()) && (needsVData))
{
int dynCastDataElems = 0;
int numElements = 1;
int vDataOfs = 1; // The number of intptrs before the iface slot map
int vDataOfs = mCompiler->GetVDataPrefixDataCount(); // The number of intptrs before the iface slot map
numElements += mCompiler->mMaxInterfaceSlots;
if (!typeInstance->IsInterface())
{
@ -6342,7 +6353,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
classVDataVar = CreateClassVDataGlobal(typeInstance, &expectNumElements, &classVDataName);
}
vData.push_back(BfIRValue()); // Type*
for (int i = 0; i < mCompiler->GetVDataPrefixDataCount(); i++)
vData.push_back(BfIRValue()); // Type
SizedArray<BfIRValue, 1> extVTableData;
@ -6752,6 +6764,9 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
// Force override of GetHashCode so we use the pointer address as the hash code
for (auto& checkIFace : checkTypeInst->mInterfaces)
{
if (checkIFace.mStartVirtualIdx < 0)
continue;
for (int methodIdx = 0; methodIdx < (int)checkIFace.mInterfaceType->mMethodInstanceGroups.size(); methodIdx++)
{
BfIRValue pushValue;
@ -6976,7 +6991,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
for (auto arg : attr->mCtorArgs)
{
auto argType = ctorMethodInstance->GetParamType(argIdx);
EncodeAttributeData(typeInstance, argType, arg, data, usedStringIdMap);
EncodeAttributeData(typeInstance, argType, arg, data, ctx.mUsedStringIdMap);
argIdx++;
}
@ -7494,7 +7509,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
}
else
{
vDataIdx = 1 + mCompiler->GetDynCastVDataCount() + mCompiler->mMaxInterfaceSlots;
vDataIdx = mCompiler->GetVDataPrefixDataCount() + mCompiler->GetDynCastVDataCount() + mCompiler->mMaxInterfaceSlots;
if ((mCompiler->mOptions.mHasVDataExtender) && (mCompiler->IsHotCompile()))
{
auto typeInst = defaultMethod->mMethodInstanceGroup->mOwner;
@ -7560,7 +7575,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
BfIRType interfaceDataPtrType = mBfIRBuilder->GetPointerTo(mBfIRBuilder->MapType(reflectInterfaceDataType));
Array<bool> wantsIfaceMethod;
bool wantsIfaceMethods = false;
if (typeInstance->mInterfaces.IsEmpty())
if ((typeInstance->mInterfaces.IsEmpty()) || (!needsTypeData))
interfaceDataPtr = mBfIRBuilder->CreateConstNull(interfaceDataPtrType);
else
{
@ -7802,7 +7817,22 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
{
BF_ASSERT(!classVDataName.IsEmpty());
vData[0] = mBfIRBuilder->CreateBitCast(typeDataVar, voidPtrIRType);
//vData[0] = mBfIRBuilder->CreateBitCast(typeDataVar, voidPtrIRType);
int unboxedTypeId = type->mTypeId;
if (type->IsBoxed())
unboxedTypeId = type->GetUnderlyingType()->mTypeId;
if (mSystem->mPtrSize == 4)
{
vData[0] = mBfIRBuilder->CreateIntToPtr(GetConstValue(type->mTypeId, intPtrType), voidPtrIRType);
vData[1] = mBfIRBuilder->CreateIntToPtr(GetConstValue(unboxedTypeId, intPtrType), voidPtrIRType);
}
else
{
vData[0] = mBfIRBuilder->CreateIntToPtr(GetConstValue(((int64)unboxedTypeId << 32) | type->mTypeId, intPtrType), voidPtrIRType);
}
auto classVDataConstDataType = mBfIRBuilder->GetSizedArrayType(voidPtrIRType, (int)vData.size());
auto classVDataConstData = mBfIRBuilder->CreateConstAgg_Value(classVDataConstDataType, vData);
@ -10459,18 +10489,24 @@ void BfModule::EmitObjectAccessCheck(BfTypedValue typedVal)
mBfIRBuilder->CreateObjectAccessCheck(typedVal.mValue, !IsOptimized());
}
void BfModule::EmitEnsureInstructionAt()
bool BfModule::WantsDebugHelpers()
{
if (mBfIRBuilder->mIgnoreWrites)
return;
return false;
if (mIsComptimeModule)
{
// Always add
}
else if ((mProject == NULL) || (!mHasFullDebugInfo) || (IsOptimized()) || (mCompiler->mOptions.mOmitDebugHelpers))
return;
return false;
return true;
}
void BfModule::EmitEnsureInstructionAt()
{
if (!WantsDebugHelpers())
return;
mBfIRBuilder->CreateEnsureInstructionAt();
}
@ -10549,7 +10585,7 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar
targetType = GetWrappedStructType(targetType);
AddDependency(targetType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ExprTypeReference);
int inheritanceIdOfs = mSystem->mPtrSize;
int inheritanceIdOfs = mSystem->mPtrSize * mCompiler->GetVDataPrefixDataCount();
vDataPtr = irb->CreateAdd(vDataPtr, irb->CreateConst(BfTypeCode_IntPtr, inheritanceIdOfs));
vDataPtr = irb->CreateIntToPtr(vDataPtr, irb->MapType(int32PtrType));
BfIRValue objInheritanceId = irb->CreateLoad(vDataPtr);
@ -11107,6 +11143,9 @@ BfModuleMethodInstance BfModule::GetMethodInstanceAtIdx(BfTypeInstance* typeInst
PopulateType(typeInstance, BfPopulateType_DataAndMethods);
if (methodIdx >= typeInstance->mMethodInstanceGroups.mSize)
return BfModuleMethodInstance();
auto methodInstance = typeInstance->mMethodInstanceGroups[methodIdx].mDefault;
BfMethodDef* methodDef = NULL;
@ -14003,7 +14042,7 @@ BfModule* BfModule::GetOrCreateMethodModule(BfMethodInstance* methodInstance)
return declareModule;
}
BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags, BfTypeInstance* foreignType)
BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags, BfTypeInstance* foreignType, BfModule* referencingModule)
{
if (methodDef->mMethodType == BfMethodType_Init)
return BfModuleMethodInstance();
@ -14129,6 +14168,8 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
instModule->mReifyQueued = true;
}
BfLogSysM("REIFIED(GetMethodInstance QueueSpecializationRequest): %s %s MethodDef:%p RefModule:%s RefMethod:%p\n", TypeToString(typeInst).c_str(), methodDef->mName.c_str(), methodDef, mModuleName.c_str(), mCurMethodInstance);
// This ensures that the method will actually be created when it gets reified
BfMethodSpecializationRequest* specializationRequest = mContext->mMethodSpecializationWorkList.Alloc();
specializationRequest->mFromModule = typeInst->mModule;
@ -14154,7 +14195,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
// Not extern
// Create the instance in the proper module and then create a reference in this one
moduleMethodInst = instModule->GetMethodInstance(typeInst, methodDef, methodGenericArguments, defFlags, foreignType);
moduleMethodInst = instModule->GetMethodInstance(typeInst, methodDef, methodGenericArguments, defFlags, foreignType, this);
if (!moduleMethodInst)
return moduleMethodInst;
tryModuleMethodLookup = true;
@ -14549,8 +14590,18 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
/*if ((!mCompiler->mIsResolveOnly) && (!isReified))
BF_ASSERT(!methodInstance->mIsReified);*/
if ((!mCompiler->mIsResolveOnly) && (isReified))
{
auto refModule = referencingModule;
if (refModule == NULL)
refModule = this;
BfLogSysM("REIFIED(GetMethodInstance Reference): %s MethodDef:%p MethodInst:%p RefModule:%s RefMethod:%p\n", methodInstance->mMethodDef->mName.c_str(), methodDef, methodInstance, refModule->mModuleName.c_str(), refModule->mCurMethodInstance);
}
if (methodInstance->mIsReified != isReified)
{
BfLogSysM("GetMethodInstance %p Decl_AwaitingReference setting reified to %d\n", methodInstance, isReified);
}
if ((!isReified) &&
((methodInstance->mDeclModule == NULL) || (!methodInstance->mDeclModule->mIsModuleMutable)))
@ -14975,6 +15026,9 @@ BfIRValue BfModule::GetInterfaceSlotNum(BfTypeInstance* ifaceType)
globalValue = mBfIRBuilder->CreateGlobalVariable(mBfIRBuilder->MapType(intType), true, BfIRLinkageType_External, value, slotVarName);
mInterfaceSlotRefs[ifaceType] = globalValue;
// Make sure we reify
PopulateType(ifaceType, BfPopulateType_Declaration);
AddDependency(ifaceType, mCurTypeInstance, BfDependencyMap::DependencyFlag_StaticValue);
}
return mBfIRBuilder->CreateAlignedLoad(globalValue/*, "slotOfs"*/, 4);
@ -20087,6 +20141,26 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
if (mAwaitingInitFinish)
FinishInit();
if ((methodInstance->mIsReified) && (!mCompiler->mIsResolveOnly))
{
BfLogSysM("REIFIED(ProcessMethod): %s %p Module: %s\n", methodInstance->mMethodDef->mName.c_str(), methodInstance, mModuleName.c_str());
}
// Reify types that are actually used - they don't get reified during method declaration
if ((!mCompiler->mIsResolveOnly) && (mIsReified))
{
auto _CheckType = [&](BfType* type)
{
if (!type->IsReified())
PopulateType(type, BfPopulateType_Declaration);
};
_CheckType(methodInstance->mReturnType);
for (auto& param : methodInstance->mParams)
{
_CheckType(param.mResolvedType);
}
}
if (!methodInstance->mIsReified)
BF_ASSERT(!mIsReified);
@ -22047,8 +22121,11 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
if ((retVal) && (!retVal.mType->IsVar()) && (expectingType != NULL))
{
mCurMethodState->mHadReturn = true;
retVal = LoadOrAggregateValue(retVal);
EmitReturn(retVal);
if (!mCurMethodState->mLeftBlockUncond)
{
retVal = LoadOrAggregateValue(retVal);
EmitReturn(retVal);
}
}
}
}
@ -23719,6 +23796,8 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
BfTypeState typeState(mCurTypeInstance);
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
BfModule* resolveModule = mContext->mUnreifiedModule;
if (mCompiler->IsAutocomplete())
prevIsCapturingMethodMatchInfo.Init(mCompiler->mResolvePassData->mAutoComplete->mIsCapturingMethodMatchInfo, false);
@ -23963,7 +24042,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
mIgnoreErrors = false;
}
BfResolveTypeRefFlags flags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric);
BfResolveTypeRefFlags flags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric | BfResolveTypeRefFlag_NoReify);
if ((((methodInstance->mComptimeFlags & BfComptimeFlag_ConstEval) != 0) || (methodInstance->mIsAutocompleteMethod))
&& (methodDef->mReturnTypeRef->IsA<BfVarTypeReference>()))
@ -24055,14 +24134,14 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
{
BfTypeUtils::SplatIterate([&](BfType* checkType)
{
PopulateType(checkType, BfPopulateType_Data);
resolveModule->PopulateType(checkType, BfPopulateType_Data);
}, thisType);
}
}
else
{
thisType = mCurTypeInstance;
PopulateType(thisType, BfPopulateType_Declaration);
resolveModule->PopulateType(thisType, BfPopulateType_Declaration);
}
}
@ -24137,7 +24216,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
bool wasGenericParam = false;
if (resolvedParamType == NULL)
{
BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue);
BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef | BfResolveTypeRefFlag_AllowRefGeneric | BfResolveTypeRefFlag_AllowGenericMethodParamConstValue | BfResolveTypeRefFlag_NoReify);
if (paramDef->mParamKind == BfParamKind_ExplicitThis)
resolveFlags = (BfResolveTypeRefFlags)(resolveFlags | BfResolveTypeRefFlag_NoWarnOnMut);
resolvedParamType = ResolveTypeRef(paramDef->mTypeRef, BfPopulateType_Declaration, resolveFlags);
@ -24388,7 +24467,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
}
int argIdx = 0;
PopulateType(methodInstance->mReturnType, BfPopulateType_Data);
resolveModule->PopulateType(methodInstance->mReturnType, BfPopulateType_Data);
if ((!methodDef->mIsStatic) && (!methodDef->mHasExplicitThis))
{
int thisIdx = methodDef->mHasExplicitThis ? 0 : -1;
@ -24428,7 +24507,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
}
else if ((checkType->IsComposite()) && (methodInstance->AllowsSplatting(paramIdx)))
{
PopulateType(checkType, BfPopulateType_Data);
resolveModule->PopulateType(checkType, BfPopulateType_Data);
if (checkType->IsSplattable())
{
bool isSplat = false;
@ -24569,7 +24648,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
{
auto paramType = methodInstance->GetParamType(paramIdx);
if (paramType->IsComposite())
PopulateType(paramType, BfPopulateType_Data);
resolveModule->PopulateType(paramType, BfPopulateType_Data);
if (!methodInstance->IsParamSkipped(paramIdx))
{
@ -24588,7 +24667,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
if (methodInstance->mIsUnspecializedVariation)
return;
PopulateType(resolvedReturnType, BfPopulateType_Data);
resolveModule->PopulateType(resolvedReturnType, BfPopulateType_Data);
auto retLLVMType = mBfIRBuilder->MapType(resolvedReturnType);
if (resolvedReturnType->IsValuelessType())
retLLVMType = mBfIRBuilder->GetPrimitiveType(BfTypeCode_None);
@ -26023,21 +26102,24 @@ void BfModule::DbgFinish()
if (mBfIRBuilder->DbgHasInfo())
{
bool needForceLinking = false;
for (auto& ownedType : mOwnedTypeInstances)
if (WantsDebugHelpers())
{
bool hasConfirmedReference = false;
for (auto& methodInstGroup : ownedType->mMethodInstanceGroups)
for (auto& ownedType : mOwnedTypeInstances)
{
if ((methodInstGroup.IsImplemented()) && (methodInstGroup.mDefault != NULL) &&
(!methodInstGroup.mDefault->mMethodDef->mIsStatic) && (methodInstGroup.mDefault->mIsReified) && (!methodInstGroup.mDefault->mAlwaysInline) &&
((methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || (methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_Referenced)) &&
(methodInstGroup.mHasEmittedReference))
bool hasConfirmedReference = false;
for (auto& methodInstGroup : ownedType->mMethodInstanceGroups)
{
hasConfirmedReference = true;
if ((methodInstGroup.IsImplemented()) && (methodInstGroup.mDefault != NULL) &&
(!methodInstGroup.mDefault->mMethodDef->mIsStatic) && (methodInstGroup.mDefault->mIsReified) && (!methodInstGroup.mDefault->mAlwaysInline) &&
((methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_AlwaysInclude) || (methodInstGroup.mOnDemandKind == BfMethodOnDemandKind_Referenced)) &&
(methodInstGroup.mHasEmittedReference))
{
hasConfirmedReference = true;
}
}
if ((!hasConfirmedReference) || (ownedType->IsBoxed()))
needForceLinking = true;
}
if ((!hasConfirmedReference) || (ownedType->IsBoxed()))
needForceLinking = true;
}
if ((needForceLinking) && (mProject->mCodeGenOptions.mAsmKind == BfAsmKind_None))
@ -26153,7 +26235,7 @@ bool BfModule::Finish()
codeGenOptions.mWriteLLVMIR = mCompiler->mOptions.mWriteIR;
codeGenOptions.mWriteObj = mCompiler->mOptions.mGenerateObj;
codeGenOptions.mWriteBitcode = mCompiler->mOptions.mGenerateBitcode;
codeGenOptions.mVirtualMethodOfs = 1 + mCompiler->GetDynCastVDataCount() + mCompiler->mMaxInterfaceSlots;
codeGenOptions.mVirtualMethodOfs = mCompiler->GetVDataPrefixDataCount() + mCompiler->GetDynCastVDataCount() + mCompiler->mMaxInterfaceSlots;
codeGenOptions.mDynSlotOfs = mSystem->mPtrSize - mCompiler->GetDynCastVDataCount() * 4;
mCompiler->mStats.mIRBytes += mBfIRBuilder->mStream.GetSize();

View file

@ -158,6 +158,12 @@ enum BfLocalVarAssignKind : int8
BfLocalVarAssignKind_Unconditional = 2
};
struct BfCreateTypeDataContext
{
Dictionary<int, int> mUsedStringIdMap;
HashSet<BfTypeInstance*> mReflectTypeSet;
};
class BfLocalVariable
{
public:
@ -1740,6 +1746,7 @@ public:
bool HasExecutedOutput();
void SkipObjectAccessCheck(BfTypedValue typedVal);
void EmitObjectAccessCheck(BfTypedValue typedVal);
bool WantsDebugHelpers();
void EmitEnsureInstructionAt();
void EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* targetType, BfIRBlock trueBlock, BfIRBlock falseBlock, bool nullSucceeds = false);
void EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull);
@ -1966,7 +1973,7 @@ public:
bool ValidateTypeWildcard(BfAstNode* typeRef, bool isAttributeRef);
void GetDelegateTypeRefAttributes(BfDelegateTypeRef* delegateTypeRef, BfCallingConvention& callingConvention);
BfType* ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0, int numGenericArgs = 0);
BfType* ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, bool resolveGenericParam = true);
BfType* ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0, bool resolveGenericParam = true);
BfType* ResolveTypeRef_Type(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
BfType* ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfAstNode*>* genericArgs, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = (BfResolveTypeRefFlags)0);
BfType* ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType = BfPopulateType_Data, BfResolveTypeRefFlags resolveFlags = BfResolveTypeRefFlag_None);
@ -2062,7 +2069,7 @@ public:
void SetMethodDependency(BfMethodInstance* methodInstance);
BfModuleMethodInstance ReferenceExternalMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
BfModule* GetOrCreateMethodModule(BfMethodInstance* methodInstance);
BfModuleMethodInstance GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None, BfTypeInstance* foreignType = NULL);
BfModuleMethodInstance GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None, BfTypeInstance* foreignType = NULL, BfModule* referencingModule = NULL);
BfModuleMethodInstance GetMethodInstance(BfMethodInstance* methodInstance, BfGetMethodInstanceFlags flags = BfGetMethodInstanceFlag_None);
BfMethodInstance* GetOuterMethodInstance(BfMethodInstance* methodInstance); // Only useful for local methods
void SetupMethodIdHash(BfMethodInstance* methodInstance);
@ -2075,7 +2082,8 @@ public:
BfIRValue CreateTypeDataRef(BfType* type);
void EncodeAttributeData(BfTypeInstance* typeInstance, BfType* argType, BfIRValue arg, SizedArrayImpl<uint8>& data, Dictionary<int, int>& usedStringIdMap);
BfIRValue CreateFieldData(BfFieldInstance* fieldInstance, int customAttrIdx);
BfIRValue CreateTypeData(BfType* type, Dictionary<int, int>& usedStringIdMap, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData);
void CreateSlotOfs(BfTypeInstance* typeInstance);
BfIRValue CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, bool forceReflectFields, bool needsTypeData, bool needsTypeNames, bool needsVData);
BfIRValue FixClassVData(BfIRValue value);
public:

View file

@ -410,7 +410,7 @@ bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* ge
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, mIgnoreErrors || ignoreErrors);
genericTypeInst->mGenericTypeInfo->mValidatedGenericConstraints = true;
if (!genericTypeInst->mGenericTypeInfo->mFinishedGenericParams)
PopulateType(genericTypeInst, BfPopulateType_Interfaces_All);
mContext->mUnreifiedModule->PopulateType(genericTypeInst, BfPopulateType_Interfaces_All);
if (genericTypeInst->IsTypeAlias())
{
@ -418,7 +418,7 @@ bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* ge
if ((underlyingType != NULL) && (underlyingType->IsGenericTypeInstance()))
{
auto underlyingGenericType = underlyingType->ToGenericTypeInstance();
PopulateType(underlyingType, BfPopulateType_Declaration);
mContext->mUnreifiedModule->PopulateType(underlyingType, BfPopulateType_Declaration);
bool result = ValidateGenericConstraints(typeRef, underlyingGenericType, ignoreErrors);
if (underlyingGenericType->mGenericTypeInfo->mHadValidateErrors)
genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
@ -441,7 +441,7 @@ bool BfModule::ValidateGenericConstraints(BfAstNode* typeRef, BfTypeInstance* ge
{
startGenericParamIdx = typeDef->mOuterType->mGenericParamDefs.mSize + typeDef->mOuterType->mExternalConstraints.mSize;
auto outerType = GetOuterType(genericTypeInst);
PopulateType(outerType, BfPopulateType_Declaration);
mContext->mUnreifiedModule->PopulateType(outerType, BfPopulateType_Declaration);
if ((outerType->mGenericTypeInfo != NULL) && (outerType->mGenericTypeInfo->mHadValidateErrors))
genericTypeInst->mGenericTypeInfo->mHadValidateErrors = true;
}
@ -802,6 +802,11 @@ void BfModule::InitType(BfType* resolvedTypeRef, BfPopulateType populateType)
return;
}
if ((typeInst != NULL) && (typeInst->mIsReified) && (!mCompiler->mIsResolveOnly))
{
BfLogSysM("REIFIED(InitType): %s Type:%p FromModule:%s FromMethod:%p\n", TypeToString(resolvedTypeRef).c_str(), resolvedTypeRef, mModuleName.c_str(), prevMethodInstance.mPrevVal);
}
BfLogSysM("%p InitType: %s Type: %p TypeDef: %p Revision:%d\n", mContext, TypeToString(resolvedTypeRef).c_str(), resolvedTypeRef, (typeInst != NULL) ? typeInst->mTypeDef : NULL, mCompiler->mRevision);
// When we're autocomplete, we can't do the method processing so we have to add this type to the type work list
@ -1212,6 +1217,14 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
canFastReify = false;
}
if (!mCompiler->mIsResolveOnly)
{
for (auto ownedTypes : typeModule->mOwnedTypeInstances)
{
BfLogSysM("REIFIED(PopulateType-Reference): %s %p FromModule:%s FromMethod: %p\n", TypeToString(ownedTypes).c_str(), ownedTypes, mModuleName.c_str(), mCurMethodInstance);
}
}
if (canFastReify)
{
BfLogSysM("Setting reified type %p in module %p in PopulateType on module awaiting finish\n", resolvedTypeRef, typeModule);
@ -1292,7 +1305,17 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
SetAndRestoreValue<BfMethodState*> prevMethodState(mCurMethodState, NULL);
BF_ASSERT((resolvedTypeRef->mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) == 0);
if ((resolvedTypeRef->mRebuildFlags & (BfTypeRebuildFlag_Deleted | BfTypeRebuildFlag_DeleteQueued)) != 0)
{
if (mContext->mGhostDependencies.Contains(resolvedTypeRef))
{
// Not a nice state, but we should be able to recover
return;
}
InternalError("Attempting PopulateType on deleted type");
return;
}
bool isNew = resolvedTypeRef->mDefineState == BfTypeDefineState_Undefined;
if (isNew)
@ -8268,7 +8291,7 @@ BfType* BfModule::ResolveTypeDef(BfTypeDef* typeDef, BfPopulateType populateType
auto typeDefTypeRef = mContext->mTypeDefTypeRefPool.Get();
typeDefTypeRef->mTypeDef = typeDef;
auto resolvedtypeDefType = ResolveTypeRef(typeDefTypeRef, populateType);
auto resolvedtypeDefType = ResolveTypeRef(typeDefTypeRef, populateType, resolveFlags);
if (resolvedtypeDefType == NULL)
{
mContext->mTypeDefTypeRefPool.GiveBack(typeDefTypeRef);
@ -11347,7 +11370,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
}
}
return ResolveTypeResult(typeRef, ResolveTypeDef(typeDef, genericArgs, populateType), populateType, resolveFlags);
return ResolveTypeResult(typeRef, ResolveTypeDef(typeDef, genericArgs, populateType, resolveFlags), populateType, resolveFlags);
}
}
}
@ -12635,7 +12658,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
return ResolveTypeResult(typeRef, NULL, populateType, resolveFlags);
}
BfType* BfModule::ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType, bool resolveGenericParam)
BfType* BfModule::ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, BfPopulateType populateType, BfResolveTypeRefFlags resolveFlags, bool resolveGenericParam)
{
if (auto genericTypeRef = BfNodeDynCast<BfGenericInstanceTypeRef>(typeRef))
{
@ -12648,7 +12671,7 @@ BfType* BfModule::ResolveTypeRefAllowUnboundGenerics(BfTypeReference* typeRef, B
BfTypeVector typeVector;
for (int i = 0; i < (int)genericTypeDef->mGenericParamDefs.size(); i++)
typeVector.push_back(GetGenericParamType(BfGenericParamKind_Type, i));
auto result = ResolveTypeDef(genericTypeDef, typeVector, populateType);
auto result = ResolveTypeDef(genericTypeDef, typeVector, populateType, resolveFlags);
if ((result != NULL) && (genericTypeRef->mCommas.size() + 1 != genericTypeDef->mGenericParamDefs.size()))
{
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, result->ToTypeInstance());

View file

@ -1270,11 +1270,12 @@ bool BfMethodInstance::WasGenericParam(int paramIdx)
bool BfMethodInstance::IsParamSkipped(int paramIdx)
{
auto resolveModule = GetModule()->mContext->mUnreifiedModule;
if (paramIdx == -1)
return false;
BfType* paramType = GetParamType(paramIdx);
if ((paramType->CanBeValuelessType()) && (paramType->IsDataIncomplete()))
GetModule()->PopulateType(paramType, BfPopulateType_Data);
resolveModule->PopulateType(paramType, BfPopulateType_Data);
if ((paramType->IsValuelessType()) && (!paramType->IsMethodRef()))
return true;
return false;
@ -1344,7 +1345,7 @@ int BfMethodInstance::DbgGetVirtualMethodNum()
module->HadSlotCountDependency();
int vDataIdx = -1;
vDataIdx = 1 + module->mCompiler->mMaxInterfaceSlots;
vDataIdx = module->mCompiler->GetVDataPrefixDataCount() + module->mCompiler->mMaxInterfaceSlots;
vDataIdx += module->mCompiler->GetDynCastVDataCount();
if ((module->mCompiler->mOptions.mHasVDataExtender) && (module->mCompiler->IsHotCompile()))
{
@ -1375,7 +1376,9 @@ int BfMethodInstance::DbgGetVirtualMethodNum()
void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType, SizedArrayImpl<BfIRType>& paramTypes, bool forceStatic)
{
module->PopulateType(mReturnType);
BfModule* resolveModule = module->mContext->mUnreifiedModule;
resolveModule->PopulateType(mReturnType);
BfTypeCode loweredReturnTypeCode = BfTypeCode_None;
BfTypeCode loweredReturnTypeCode2 = BfTypeCode_None;
@ -1459,7 +1462,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
else
{
if ((checkType->IsComposite()) && (checkType->IsIncomplete()))
module->PopulateType(checkType, BfPopulateType_Data);
resolveModule->PopulateType(checkType, BfPopulateType_Data);
if (checkType->IsMethodRef())
{
@ -1492,7 +1495,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
}
if (checkType->CanBeValuelessType())
module->PopulateType(checkType, BfPopulateType_Data);
resolveModule->PopulateType(checkType, BfPopulateType_Data);
if ((checkType->IsValuelessType()) && (!checkType->IsMethodRef()))
continue;

View file

@ -6714,12 +6714,18 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
PopulateType(itrInterface, BfPopulateType_Full_Force);
getNextMethodInst = GetMethodByName(itrInterface, "GetNext");
}
BF_ASSERT(getNextMethodInst);
nextResult = BfTypedValue(CreateAlloca(getNextMethodInst.mMethodInstance->mReturnType), getNextMethodInst.mMethodInstance->mReturnType, true);
if (nextResult.mType->IsGenericTypeInstance())
if (getNextMethodInst)
{
nextEmbeddedType = ((BfTypeInstance*)nextResult.mType)->mGenericTypeInfo->mTypeGenericArguments[0];
nextResult = BfTypedValue(CreateAlloca(getNextMethodInst.mMethodInstance->mReturnType), getNextMethodInst.mMethodInstance->mReturnType, true);
if (nextResult.mType->IsGenericTypeInstance())
{
nextEmbeddedType = ((BfTypeInstance*)nextResult.mType)->mGenericTypeInfo->mTypeGenericArguments[0];
}
}
else
{
InternalError("Failed to find GetNext");
}
}
if (nextEmbeddedType == NULL)

View file

@ -3865,8 +3865,8 @@ addr_ce CeContext::GetReflectType(int typeId)
if (bfType->mDefineState != BfTypeDefineState_CETypeInit)
ceModule->PopulateType(bfType, BfPopulateType_DataAndMethods);
Dictionary<int, int> usedStringMap;
auto irData = ceModule->CreateTypeData(bfType, usedStringMap, true, true, true, false);
BfCreateTypeDataContext createTypeDataCtx;
auto irData = ceModule->CreateTypeData(bfType, createTypeDataCtx, true, true, true, false);
BeValue* beValue = NULL;
if (auto constant = mCeMachine->mCeModule->mBfIRBuilder->GetConstant(irData))