diff --git a/BeefLibs/corlib/src/Compiler.bf b/BeefLibs/corlib/src/Compiler.bf index 2ec01415..0206bfd3 100644 --- a/BeefLibs/corlib/src/Compiler.bf +++ b/BeefLibs/corlib/src/Compiler.bf @@ -37,7 +37,7 @@ namespace System public static extern String CallerProject; [LinkName("#CallerExpression")] - public static extern String[Int32.MaxValue] CallerExpression; + public static extern String[0x0FFFFFFF] CallerExpression; [LinkName("#ProjectName")] public static extern String ProjectName; diff --git a/IDE/mintest/minlib/src/System/Compiler.bf b/IDE/mintest/minlib/src/System/Compiler.bf index be3e3bdd..d53edb15 100644 --- a/IDE/mintest/minlib/src/System/Compiler.bf +++ b/IDE/mintest/minlib/src/System/Compiler.bf @@ -21,7 +21,7 @@ namespace System public static extern String CallerProject; [LinkName("#CallerExpression")] - public static extern String[Int32.MaxValue] CallerExpression; + public static extern String[0x0FFFFFFF] CallerExpression; [LinkName("#ProjectName")] public static extern String ProjectName; diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 12fe46e7..c0319530 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -1140,7 +1140,7 @@ void BfContext::RebuildDependentTypes(BfDependedType* dType) // (obviously) doesn't change the data layout of ClassC // Calls: non-cascading dependency, since it's independent of data layout ConstValue: non-cascading data change void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChange) -{ +{ BfLogSysM("TypeDataChanged %p\n", dType); auto rebuildFlag = isNonStaticDataChange ? BfTypeRebuildFlag_NonStaticChange : BfTypeRebuildFlag_StaticChange; @@ -1153,12 +1153,7 @@ void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChang { auto dependentType = depItr.mKey; auto dependencyFlags = depItr.mValue.mFlags; - - if (dependentType->mRevision == mCompiler->mRevision) - { - continue; - } - + auto dependentDType = dependentType->ToDependedType(); if (dependentDType != NULL) { @@ -1200,32 +1195,38 @@ void BfContext::TypeDataChanged(BfDependedType* dType, bool isNonStaticDataChang if (dependencyFlags & BfDependencyMap::DependencyFlag_ConstValue) { TypeDataChanged(dependentDType, false); - - + // The ConstValue dependency may be that dependentType used one of our consts as // a default value to a method param, so assume callsites need rebuilding if (dependentTypeInstance != NULL) TypeMethodSignaturesChanged(dependentTypeInstance); } - // We need to include DependencyFlag_ParamOrReturnValue because it could be a struct that changes its splatting ability - // We can't ONLY check against structs, though, because a type could change from a class to a struct - if (dependencyFlags & - (BfDependencyMap::DependencyFlag_ReadFields | BfDependencyMap::DependencyFlag_ParamOrReturnValue | - BfDependencyMap::DependencyFlag_LocalUsage | BfDependencyMap::DependencyFlag_MethodGenericArg | - BfDependencyMap::DependencyFlag_Allocates)) + if (dependentType->mRevision != mCompiler->mRevision) { - RebuildType(dependentType); + // We need to include DependencyFlag_ParamOrReturnValue because it could be a struct that changes its splatting ability + // We can't ONLY check against structs, though, because a type could change from a class to a struct + if (dependencyFlags & + (BfDependencyMap::DependencyFlag_ReadFields | BfDependencyMap::DependencyFlag_ParamOrReturnValue | + BfDependencyMap::DependencyFlag_LocalUsage | BfDependencyMap::DependencyFlag_MethodGenericArg | + BfDependencyMap::DependencyFlag_Allocates)) + { + RebuildType(dependentType); + } } } else { - // Not a type instance, probably something like a sized array - RebuildType(dependentType); + if (dependentType->mRevision != mCompiler->mRevision) + { + // Not a type instance, probably something like a sized array + RebuildType(dependentType); + } } } - - RebuildType(dType); + + if (dType->mRevision != mCompiler->mRevision) + RebuildType(dType); } void BfContext::TypeMethodSignaturesChanged(BfTypeInstance* typeInst) @@ -1242,21 +1243,19 @@ void BfContext::TypeMethodSignaturesChanged(BfTypeInstance* typeInst) auto dependentType = depItr.mKey; auto dependencyFlags = depItr.mValue.mFlags; - if (dependentType->mRevision == mCompiler->mRevision) + if (dependentType->mRevision != mCompiler->mRevision) { - continue; - } - - // We don't need to cascade rebuilding for method-based usage - just rebuild the type directly (unlike TypeDataChanged, which cascades) - if ((dependencyFlags & BfDependencyMap::DependencyFlag_Calls) || - (dependencyFlags & BfDependencyMap::DependencyFlag_VirtualCall) || - (dependencyFlags & BfDependencyMap::DependencyFlag_InlinedCall) || - (dependencyFlags & BfDependencyMap::DependencyFlag_MethodGenericArg) || - (dependencyFlags & BfDependencyMap::DependencyFlag_CustomAttribute) || - (dependencyFlags & BfDependencyMap::DependencyFlag_DerivedFrom) || - (dependencyFlags & BfDependencyMap::DependencyFlag_ImplementsInterface)) - { - RebuildType(dependentType); + // We don't need to cascade rebuilding for method-based usage - just rebuild the type directly (unlike TypeDataChanged, which cascades) + if ((dependencyFlags & BfDependencyMap::DependencyFlag_Calls) || + (dependencyFlags & BfDependencyMap::DependencyFlag_VirtualCall) || + (dependencyFlags & BfDependencyMap::DependencyFlag_InlinedCall) || + (dependencyFlags & BfDependencyMap::DependencyFlag_MethodGenericArg) || + (dependencyFlags & BfDependencyMap::DependencyFlag_CustomAttribute) || + (dependencyFlags & BfDependencyMap::DependencyFlag_DerivedFrom) || + (dependencyFlags & BfDependencyMap::DependencyFlag_ImplementsInterface)) + { + RebuildType(dependentType); + } } } } @@ -1271,12 +1270,16 @@ void BfContext::TypeInlineMethodInternalsChanged(BfTypeInstance* typeInst) for (auto& depItr : typeInst->mDependencyMap) { auto dependentType = depItr.mKey; + auto dependencyFlags = depItr.mValue.mFlags; - // We don't need to cascade rebuilding for method-based usage - just rebuild the type directly (unlike TypeDataChanged, which cascades) - if ((dependencyFlags & BfDependencyMap::DependencyFlag_InlinedCall) != 0) + if (dependentType->mRevision != mCompiler->mRevision) { - RebuildType(dependentType); + // We don't need to cascade rebuilding for method-based usage - just rebuild the type directly (unlike TypeDataChanged, which cascades) + if ((dependencyFlags & BfDependencyMap::DependencyFlag_InlinedCall) != 0) + { + RebuildType(dependentType); + } } } } @@ -1299,14 +1302,16 @@ void BfContext::TypeConstEvalChanged(BfTypeInstance* typeInst) auto depTypeInst = dependentType->ToTypeInstance(); if (depTypeInst != NULL) TypeConstEvalChanged(depTypeInst); - RebuildType(dependentType); + if (dependentType->mRevision != mCompiler->mRevision) + RebuildType(dependentType); } else if ((dependencyFlags & BfDependencyMap::DependencyFlag_ConstEvalConstField) != 0) { auto depTypeInst = dependentType->ToTypeInstance(); if (depTypeInst != NULL) TypeConstEvalFieldChanged(depTypeInst); - RebuildType(dependentType); + if (dependentType->mRevision != mCompiler->mRevision) + RebuildType(dependentType); } } } @@ -1328,7 +1333,8 @@ void BfContext::TypeConstEvalFieldChanged(BfTypeInstance* typeInst) auto depTypeInst = dependentType->ToTypeInstance(); if (depTypeInst != NULL) TypeConstEvalFieldChanged(depTypeInst); - RebuildType(dependentType); + if (dependentType->mRevision != mCompiler->mRevision) + RebuildType(dependentType); } } } diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 1bc23869..4a9b2e3b 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -899,8 +899,10 @@ void BfModule::TypeFailed(BfTypeInstance* typeInstance) } bool BfModule::CheckCircularDataError() -{ - bool hadError = false; +{ + // Find two loops of mCurTypeInstance. Just finding one loop can give some false errors. + + BfTypeState* circularTypeStateEnd = NULL; int checkIdx = 0; auto checkTypeState = mContext->mCurTypeState; @@ -908,7 +910,7 @@ bool BfModule::CheckCircularDataError() while (true) { if (checkTypeState == NULL) - return hadError; + return false; if (checkTypeState->mResolveKind == BfTypeState::ResolveKind_UnionInnerType) { @@ -919,30 +921,38 @@ bool BfModule::CheckCircularDataError() if (isPreBaseCheck) { if (checkTypeState->mPopulateType != BfPopulateType_Declaration) - return hadError; + return false; } else { if (checkTypeState->mPopulateType == BfPopulateType_Declaration) - return hadError; + return false; if ((checkIdx > 0) && (checkTypeState->mCurBaseTypeRef == NULL) && (checkTypeState->mCurAttributeTypeRef == NULL) && (checkTypeState->mCurFieldDef == NULL) && ((checkTypeState->mType == NULL) || (checkTypeState->mType->IsTypeInstance()))) - return hadError; + return false; } if ((checkTypeState->mType == mCurTypeInstance) && (checkIdx > 0)) - break; + { + if (circularTypeStateEnd == NULL) + circularTypeStateEnd = checkTypeState; + else + break; + } checkTypeState = checkTypeState->mPrevState; checkIdx++; } - + bool hadError = false; checkTypeState = mContext->mCurTypeState->mPrevState; while (true) { if (checkTypeState == NULL) return hadError; + if (checkTypeState == circularTypeStateEnd) + return hadError; + if (checkTypeState->mResolveKind == BfTypeState::ResolveKind_UnionInnerType) { // Skip over this to actual data references @@ -1222,7 +1232,16 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType } if (arrayType->mElementCount > 0) { - arrayType->mSize = (int)(arrayType->mElementType->GetStride() * arrayType->mElementCount); + arrayType->mSize = (int)(arrayType->mElementType->GetStride() * arrayType->mElementCount); + if (arrayType->mElementType->mSize > 0) + { + int64 maxElements = 0x7FFFFFFF / arrayType->mElementType->GetStride(); + if (arrayType->mElementCount > maxElements) + { + Fail(StrFormat("Array size overflow: %s", TypeToString(arrayType).c_str())); + arrayType->mSize = 0x7FFFFFFF; + } + } arrayType->mAlign = std::max((int32)arrayType->mElementType->mAlign, 1); } else if (arrayType->mElementCount < 0) @@ -1237,6 +1256,8 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType arrayType->mAlign = 1; } + BF_ASSERT(arrayType->mSize >= 0); + if (!typeFailed) arrayType->mWantsGCMarking = elementType->WantsGCMarking(); resolvedTypeRef->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotted; @@ -4874,7 +4895,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy FinishGenericParams(resolvedTypeRef); } - if (populateType == BfPopulateType_Data) + if (populateType <= BfPopulateType_Data) return; disableYield.Release(); @@ -4884,7 +4905,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy { if (typeInstance->mNeedsMethodProcessing) // May have been handled by GetRawMethodInstanceAtIdx above DoTypeInstanceMethodProcessing(typeInstance); - } + } } void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)