mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Handled some method slotting reentrancy issues
This commit is contained in:
parent
879ac7f989
commit
dd37d6c092
6 changed files with 55 additions and 21 deletions
|
@ -838,7 +838,7 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
type->mDirty = true;
|
type->mDirty = true;
|
||||||
|
|
||||||
bool wantDeleteType = (type->IsOnDemand()) && (deleteOnDemandTypes);
|
bool wantDeleteType = (type->IsOnDemand()) && (deleteOnDemandTypes);
|
||||||
|
@ -870,6 +870,8 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_ASSERT_REL(typeInst->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting);
|
||||||
|
|
||||||
// We need to verify lookups before we rebuild the type, because a type lookup change needs to count as a TypeDataChanged
|
// We need to verify lookups before we rebuild the type, because a type lookup change needs to count as a TypeDataChanged
|
||||||
VerifyTypeLookups(typeInst);
|
VerifyTypeLookups(typeInst);
|
||||||
|
|
||||||
|
|
|
@ -3604,7 +3604,15 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDbgDefine)
|
||||||
// isDefiningModule = true;
|
// isDefiningModule = true;
|
||||||
|
|
||||||
if ((isDefiningModule) || (type->IsValueType()))
|
if ((isDefiningModule) || (type->IsValueType()))
|
||||||
populateModule->PopulateType(type, BfPopulateType_DataAndMethods);
|
{
|
||||||
|
if ((typeInstance != NULL) && (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotting))
|
||||||
|
{
|
||||||
|
// Don't re-enter
|
||||||
|
BfLogSys(mModule->mSystem, "BfIRBuilder::CreateTypeDefinition avoided PopulateType BfPopulateType_DataAndMethods re-entry typeInst: %p\n", typeInstance);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
populateModule->PopulateType(type, BfPopulateType_DataAndMethods);
|
||||||
|
}
|
||||||
|
|
||||||
if ((!isDefiningModule) && (!type->IsUnspecializedType()) && (type->IsValueType()) && (mHasDebugInfo))
|
if ((!isDefiningModule) && (!type->IsUnspecializedType()) && (type->IsValueType()) && (mHasDebugInfo))
|
||||||
{
|
{
|
||||||
|
|
|
@ -11079,8 +11079,10 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
BfTypeInstance* attrTypeInst = NULL;
|
BfTypeInstance* attrTypeInst = NULL;
|
||||||
if (attrType == NULL)
|
if (attrType == NULL)
|
||||||
continue;
|
continue;
|
||||||
mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods);
|
|
||||||
attrTypeInst = attrType->ToTypeInstance();
|
attrTypeInst = attrType->ToTypeInstance();
|
||||||
|
if ((attrTypeInst != NULL) && (attrTypeInst->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting))
|
||||||
|
mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods);
|
||||||
|
|
||||||
if ((attrTypeInst == NULL) || (!TypeIsSubTypeOf(attrTypeInst, baseAttrTypeInst)) || (attrTypeInst->mAttributeData == NULL))
|
if ((attrTypeInst == NULL) || (!TypeIsSubTypeOf(attrTypeInst, baseAttrTypeInst)) || (attrTypeInst->mAttributeData == NULL))
|
||||||
{
|
{
|
||||||
Fail(StrFormat("'%s' is not an attribute class", TypeToString(attrType).c_str()), attributesDirective->mAttributeTypeRef); //CS0616
|
Fail(StrFormat("'%s' is not an attribute class", TypeToString(attrType).c_str()), attributesDirective->mAttributeTypeRef); //CS0616
|
||||||
|
@ -16315,8 +16317,8 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
|
||||||
addDeref = resolvedTypeRef->mSize;
|
addDeref = resolvedTypeRef->mSize;
|
||||||
}
|
}
|
||||||
else if ((methodInstance->WantsStructsAttribByVal()) && (!resolvedTypeRef->IsSizedArray()))
|
else if ((methodInstance->WantsStructsAttribByVal()) && (!resolvedTypeRef->IsSizedArray()))
|
||||||
{
|
{
|
||||||
mBfIRBuilder->PopulateType(resolvedTypeRef);
|
mBfIRBuilder->PopulateType(resolvedTypeRef, BfIRPopulateType_Full);
|
||||||
BF_ASSERT(resolvedTypeRef->mAlign > 0);
|
BF_ASSERT(resolvedTypeRef->mAlign > 0);
|
||||||
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_ByVal, mSystem->mPtrSize);
|
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_ByVal, mSystem->mPtrSize);
|
||||||
}
|
}
|
||||||
|
@ -23546,7 +23548,7 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doesMethodSignatureMatch)
|
if (doesMethodSignatureMatch)
|
||||||
{
|
{
|
||||||
usedMethod = true;
|
usedMethod = true;
|
||||||
|
@ -23587,15 +23589,15 @@ bool BfModule::SlotVirtualMethod(BfMethodInstance* methodInstance, BfAmbiguityCo
|
||||||
storeIFaceMethod = isBetter;
|
storeIFaceMethod = isBetter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storeIFaceMethod)
|
if (storeIFaceMethod)
|
||||||
{
|
{
|
||||||
if (methodInstance->GetNumGenericParams() != 0)
|
if (methodInstance->GetNumGenericParams() != 0)
|
||||||
_AddVirtualDecl(iMethodInst);
|
_AddVirtualDecl(iMethodInst);
|
||||||
*iMethodPtr = methodInstance;
|
*iMethodPtr = methodInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkMethodDef = checkMethodDef->mNextWithSameName;
|
checkMethodDef = checkMethodDef->mNextWithSameName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4426,7 +4426,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
|
|
||||||
CheckAddFailType();
|
CheckAddFailType();
|
||||||
|
|
||||||
BfLogSysM("Setting mNeedsMethodProcessing on %p\n", typeInstance);
|
BF_ASSERT_REL(typeInstance->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting);
|
||||||
|
|
||||||
|
BfLogSysM("Setting mNeedsMethodProcessing=true on %p\n", typeInstance);
|
||||||
typeInstance->mNeedsMethodProcessing = true;
|
typeInstance->mNeedsMethodProcessing = true;
|
||||||
typeInstance->mIsFinishingType = false;
|
typeInstance->mIsFinishingType = false;
|
||||||
|
|
||||||
|
@ -4830,7 +4832,17 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
{
|
{
|
||||||
if (typeInstance->IsSpecializedByAutoCompleteMethod())
|
if (typeInstance->IsSpecializedByAutoCompleteMethod())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotting)
|
||||||
|
{
|
||||||
|
BfLogSysM("DoTypeInstanceMethodProcessing %p re-entrancy exit\n", typeInstance);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BF_ASSERT_REL(typeInstance->mNeedsMethodProcessing);
|
||||||
|
BF_ASSERT_REL(typeInstance->mDefineState == BfTypeDefineState_Defined);
|
||||||
|
typeInstance->mDefineState = BfTypeDefineState_DefinedAndMethodsSlotting;
|
||||||
|
|
||||||
BF_ASSERT(typeInstance->mModule == this);
|
BF_ASSERT(typeInstance->mModule == this);
|
||||||
|
|
||||||
//TODO: This is new, make sure this is in the right place
|
//TODO: This is new, make sure this is in the right place
|
||||||
|
@ -4839,9 +4851,9 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
|
|
||||||
AutoDisallowYield disableYield(mSystem);
|
AutoDisallowYield disableYield(mSystem);
|
||||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
|
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
|
||||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
|
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCurMethodInstance, NULL);
|
||||||
|
|
||||||
BfLogSysM("DoTypeInstanceMethodProcessing: %p %s Revision:%d\n", typeInstance, TypeToString(typeInstance).c_str(), typeInstance->mRevision);
|
BfLogSysM("DoTypeInstanceMethodProcessing: %p %s Revision:%d DefineState:%d\n", typeInstance, TypeToString(typeInstance).c_str(), typeInstance->mRevision, typeInstance->mDefineState);
|
||||||
|
|
||||||
auto typeDef = typeInstance->mTypeDef;
|
auto typeDef = typeInstance->mTypeDef;
|
||||||
|
|
||||||
|
@ -4929,7 +4941,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
|
|
||||||
// Reserve empty entries
|
// Reserve empty entries
|
||||||
for (int methodIdx = 0; methodIdx < (int)interfaceTypeDef->mMethods.size(); methodIdx++)
|
for (int methodIdx = 0; methodIdx < (int)interfaceTypeDef->mMethods.size(); methodIdx++)
|
||||||
typeInstance->mInterfaceMethodTable.push_back(BfTypeInterfaceMethodEntry());
|
typeInstance->mInterfaceMethodTable.push_back(BfTypeInterfaceMethodEntry());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5288,6 +5300,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BF_ASSERT_REL(typeInstance->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted);
|
||||||
BfLogSysM("Starting DoTypeInstanceMethodProcessing %p GetMethodInstance pass. OnDemandMethods: %d\n", typeInstance, mOnDemandMethodCount);
|
BfLogSysM("Starting DoTypeInstanceMethodProcessing %p GetMethodInstance pass. OnDemandMethods: %d\n", typeInstance, mOnDemandMethodCount);
|
||||||
|
|
||||||
// Def passes. First non-overrides then overrides (for in-place overrides in methods)
|
// Def passes. First non-overrides then overrides (for in-place overrides in methods)
|
||||||
|
@ -5721,7 +5734,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
auto checkIFaceMethodInst = checkIFaceInst->mMethodInstanceGroups[checkIMethodIdx].mDefault;
|
auto checkIFaceMethodInst = checkIFaceInst->mMethodInstanceGroups[checkIMethodIdx].mDefault;
|
||||||
if ((checkIFaceMethodInst != NULL) && (checkIFaceMethodInst->mMethodDef->mIsOverride))
|
if ((checkIFaceMethodInst != NULL) && (checkIFaceMethodInst->mMethodDef->mIsOverride))
|
||||||
{
|
{
|
||||||
if (CompareMethodSignatures(checkIFaceMethodInst, ifaceMethodInst))
|
bool cmpResult = CompareMethodSignatures(checkIFaceMethodInst, ifaceMethodInst);
|
||||||
|
if (cmpResult)
|
||||||
{
|
{
|
||||||
bool isBetter = TypeIsSubTypeOf(checkIFaceInst, bestInterface);
|
bool isBetter = TypeIsSubTypeOf(checkIFaceInst, bestInterface);
|
||||||
bool isWorse = TypeIsSubTypeOf(bestInterface, checkIFaceInst);
|
bool isWorse = TypeIsSubTypeOf(bestInterface, checkIFaceInst);
|
||||||
|
@ -5819,6 +5833,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
methodString = MethodToString(ifaceMethodInst);
|
methodString = MethodToString(ifaceMethodInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutputDebugStrF("Failed in %s %p\n", mModuleName.c_str(), this);
|
||||||
|
|
||||||
BfTypeDeclaration* typeDecl = declTypeDef->mTypeDeclaration;
|
BfTypeDeclaration* typeDecl = declTypeDef->mTypeDeclaration;
|
||||||
BfError* error = Fail(StrFormat("'%s' does not implement interface member '%s'", TypeToString(typeInstance).c_str(), methodString.c_str()), typeDecl->mNameNode, true);
|
BfError* error = Fail(StrFormat("'%s' does not implement interface member '%s'", TypeToString(typeInstance).c_str(), methodString.c_str()), typeDecl->mNameNode, true);
|
||||||
if ((matchedMethod != NULL) && (error != NULL))
|
if ((matchedMethod != NULL) && (error != NULL))
|
||||||
|
@ -5880,7 +5896,9 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
mCompiler->mStats.mTypesPopulated++;
|
mCompiler->mStats.mTypesPopulated++;
|
||||||
mCompiler->UpdateCompletion();
|
mCompiler->UpdateCompletion();
|
||||||
|
|
||||||
BfLogSysM("Finished DoTypeInstanceMethodProcessing %p. OnDemandMethods: %d Virtual Size: %d\n", typeInstance, mOnDemandMethodCount, typeInstance->mVirtualMethodTable.size());
|
BF_ASSERT_REL(!typeInstance->mNeedsMethodProcessing);
|
||||||
|
|
||||||
|
BfLogSysM("Finished DoTypeInstanceMethodProcessing %p. OnDemandMethods: %d Virtual Size: %d InterfaceMethodTableSize: %d\n", typeInstance, mOnDemandMethodCount, typeInstance->mVirtualMethodTable.size(), typeInstance->mInterfaceMethodTable.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::RebuildMethods(BfTypeInstance* typeInstance)
|
void BfModule::RebuildMethods(BfTypeInstance* typeInstance)
|
||||||
|
@ -5888,6 +5906,9 @@ void BfModule::RebuildMethods(BfTypeInstance* typeInstance)
|
||||||
if (typeInstance->IsIncomplete())
|
if (typeInstance->IsIncomplete())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
BfLogSysM("RebuildMethods setting mNeedsMethodProcessing=true on %p\n", typeInstance);
|
||||||
|
|
||||||
|
BF_ASSERT_REL(typeInstance->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting);
|
||||||
typeInstance->mNeedsMethodProcessing = true;
|
typeInstance->mNeedsMethodProcessing = true;
|
||||||
typeInstance->mDefineState = BfTypeDefineState_Defined;
|
typeInstance->mDefineState = BfTypeDefineState_Defined;
|
||||||
typeInstance->mTypeIncomplete = true;
|
typeInstance->mTypeIncomplete = true;
|
||||||
|
|
|
@ -436,6 +436,7 @@ enum BfTypeDefineState : uint8
|
||||||
BfTypeDefineState_CEPostTypeInit,
|
BfTypeDefineState_CEPostTypeInit,
|
||||||
BfTypeDefineState_Defined,
|
BfTypeDefineState_Defined,
|
||||||
BfTypeDefineState_CEAfterFields,
|
BfTypeDefineState_CEAfterFields,
|
||||||
|
BfTypeDefineState_DefinedAndMethodsSlotting,
|
||||||
BfTypeDefineState_DefinedAndMethodsSlotted,
|
BfTypeDefineState_DefinedAndMethodsSlotted,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
|
|
||||||
#include "BeefySysLib/util/AllocDebug.h"
|
#include "BeefySysLib/util/AllocDebug.h"
|
||||||
|
|
||||||
|
#define STB_SPRINTF_DECORATE(name) BF_stbsp_##name
|
||||||
|
#include "../../third_party/stb/stb_sprintf.h"
|
||||||
|
|
||||||
USING_NS_BF;
|
USING_NS_BF;
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
@ -64,11 +67,8 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...)
|
||||||
|
|
||||||
va_list argList;
|
va_list argList;
|
||||||
va_start(argList, fmt);
|
va_start(argList, fmt);
|
||||||
#ifdef _WIN32
|
|
||||||
int numChars = _vsnprintf(lineStr + strOfs, maxChars, fmt, argList);
|
int numChars = BF_stbsp_vsnprintf(lineStr + strOfs, maxChars, fmt, argList);
|
||||||
#else
|
|
||||||
int numChars = vsnprintf(lineStr+ strOfs, maxChars, fmt, argList);
|
|
||||||
#endif
|
|
||||||
if (numChars <= maxChars)
|
if (numChars <= maxChars)
|
||||||
{
|
{
|
||||||
if (strOfs + numChars > 0)
|
if (strOfs + numChars > 0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue