mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Circular data detection fix, TypeDataChanged rebuild fix
This commit is contained in:
parent
617cdcbede
commit
5674bf80c0
4 changed files with 80 additions and 53 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue