1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Handled some method slotting reentrancy issues

This commit is contained in:
Brian Fiete 2021-08-02 10:44:39 -07:00
parent 879ac7f989
commit dd37d6c092
6 changed files with 55 additions and 21 deletions

View file

@ -870,6 +870,8 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
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
VerifyTypeLookups(typeInst);

View file

@ -3604,7 +3604,15 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDbgDefine)
// isDefiningModule = true;
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))
{

View file

@ -11079,8 +11079,10 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
BfTypeInstance* attrTypeInst = NULL;
if (attrType == NULL)
continue;
mContext->mUnreifiedModule->PopulateType(attrType, BfPopulateType_DataAndMethods);
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))
{
Fail(StrFormat("'%s' is not an attribute class", TypeToString(attrType).c_str()), attributesDirective->mAttributeTypeRef); //CS0616
@ -16316,7 +16318,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
}
else if ((methodInstance->WantsStructsAttribByVal()) && (!resolvedTypeRef->IsSizedArray()))
{
mBfIRBuilder->PopulateType(resolvedTypeRef);
mBfIRBuilder->PopulateType(resolvedTypeRef, BfIRPopulateType_Full);
BF_ASSERT(resolvedTypeRef->mAlign > 0);
mBfIRBuilder->Func_AddAttribute(func, argIdx + 1, BfIRAttribute_ByVal, mSystem->mPtrSize);
}

View file

@ -4426,7 +4426,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
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->mIsFinishingType = false;
@ -4831,6 +4833,16 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
if (typeInstance->IsSpecializedByAutoCompleteMethod())
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);
//TODO: This is new, make sure this is in the right place
@ -4841,7 +4853,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
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;
@ -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);
// 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;
if ((checkIFaceMethodInst != NULL) && (checkIFaceMethodInst->mMethodDef->mIsOverride))
{
if (CompareMethodSignatures(checkIFaceMethodInst, ifaceMethodInst))
bool cmpResult = CompareMethodSignatures(checkIFaceMethodInst, ifaceMethodInst);
if (cmpResult)
{
bool isBetter = TypeIsSubTypeOf(checkIFaceInst, bestInterface);
bool isWorse = TypeIsSubTypeOf(bestInterface, checkIFaceInst);
@ -5819,6 +5833,8 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
methodString = MethodToString(ifaceMethodInst);
}
OutputDebugStrF("Failed in %s %p\n", mModuleName.c_str(), this);
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);
if ((matchedMethod != NULL) && (error != NULL))
@ -5880,7 +5896,9 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
mCompiler->mStats.mTypesPopulated++;
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)
@ -5888,6 +5906,9 @@ void BfModule::RebuildMethods(BfTypeInstance* typeInstance)
if (typeInstance->IsIncomplete())
return;
BfLogSysM("RebuildMethods setting mNeedsMethodProcessing=true on %p\n", typeInstance);
BF_ASSERT_REL(typeInstance->mDefineState != BfTypeDefineState_DefinedAndMethodsSlotting);
typeInstance->mNeedsMethodProcessing = true;
typeInstance->mDefineState = BfTypeDefineState_Defined;
typeInstance->mTypeIncomplete = true;

View file

@ -436,6 +436,7 @@ enum BfTypeDefineState : uint8
BfTypeDefineState_CEPostTypeInit,
BfTypeDefineState_Defined,
BfTypeDefineState_CEAfterFields,
BfTypeDefineState_DefinedAndMethodsSlotting,
BfTypeDefineState_DefinedAndMethodsSlotted,
};

View file

@ -13,6 +13,9 @@
#include "BeefySysLib/util/AllocDebug.h"
#define STB_SPRINTF_DECORATE(name) BF_stbsp_##name
#include "../../third_party/stb/stb_sprintf.h"
USING_NS_BF;
using namespace llvm;
@ -64,11 +67,8 @@ void Beefy::DoBfLog(int fileIdx, const char* fmt ...)
va_list argList;
va_start(argList, fmt);
#ifdef _WIN32
int numChars = _vsnprintf(lineStr + strOfs, maxChars, fmt, argList);
#else
int numChars = vsnprintf(lineStr+ strOfs, maxChars, fmt, argList);
#endif
int numChars = BF_stbsp_vsnprintf(lineStr + strOfs, maxChars, fmt, argList);
if (numChars <= maxChars)
{
if (strOfs + numChars > 0)