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

Deleted type protection in EmitGCMarkValue, RequestExtraCompile feature

This commit is contained in:
Brian Fiete 2025-02-19 12:01:06 -08:00
parent 6e0cabf8aa
commit 471897a150
6 changed files with 81 additions and 1 deletions

View file

@ -355,6 +355,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mHasRequiredTypes = false;
mNeedsFullRefresh = false;
mFastFinish = false;
mExtraCompileRequested = false;
mHasQueuedTypeRebuilds = false;
mIsResolveOnly = isResolveOnly;
mResolvePassData = NULL;
@ -7182,6 +7183,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mOutputDirectory = outputDirectory;
mSystem->StartYieldSection();
mExtraCompileRequested = false;
mFastFinish = false;
mHasQueuedTypeRebuilds = false;
mCanceling = false;
@ -8082,7 +8084,23 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
bool BfCompiler::Compile(const StringImpl& outputDirectory)
{
bool success = DoCompile(outputDirectory);
int passIdx = 0;
bool success = false;
while (true)
{
auto passState = mPassInstance->GetState();
success = DoCompile(outputDirectory);
if (!mExtraCompileRequested)
break;
mPassInstance->RestoreState(passState);
if (passIdx == 1)
break;
passIdx++;
}
if (!success)
return false;
if (mPassInstance->HasFailed())
@ -8132,6 +8150,11 @@ void BfCompiler::RequestFastFinish()
BpEvent("BfCompiler::RequestFastFinish", "");
}
void BfCompiler::RequestExtraCompile()
{
mExtraCompileRequested = true;
}
//#define WANT_COMPILE_LOG
void BfCompiler::CompileLog(const char* fmt ...)

View file

@ -334,6 +334,7 @@ public:
bool mHasRequiredTypes;
bool mNeedsFullRefresh;
bool mFastFinish;
bool mExtraCompileRequested;
bool mHasQueuedTypeRebuilds; // Infers we had a fast finish that requires a type rebuild
bool mHadCancel;
bool mWantsDeferMethodDecls;
@ -545,6 +546,7 @@ public:
void GetSymbolReferences();
void Cancel();
void RequestFastFinish();
void RequestExtraCompile();
String GetTypeDefList(bool includeLocation);
String GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeInst, const StringImpl& generatorMethodName, const StringImpl* args);
void HandleGeneratorErrors(StringImpl& result);

View file

@ -5646,6 +5646,7 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe
if (fieldInstance->mDataIdx < 0)
{
mModule->mCompiler->RequestExtraCompile();
mModule->InternalError("LoadField field DataIdx<0 where InstSize>0");
mModule->DeferRebuildType(typeInstance);
return mModule->GetDefaultTypedValue(resolvedFieldType);

View file

@ -4730,6 +4730,7 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
if (fieldType->IsDeleting())
{
mCompiler->RequestExtraCompile();
InternalError("Field using deleted type", fieldDef->GetRefNode());
}
else if (fieldType->IsVar())
@ -11264,6 +11265,7 @@ BfMethodInstance* BfModule::GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstan
{
if (typeInstance->IsDeleting())
{
mCompiler->RequestExtraCompile();
InternalError("GetRawMethodInstanceAtIdx for deleted type", typeInstance->mTypeDef->GetRefNode());
return NULL;
}
@ -20301,6 +20303,13 @@ void BfModule::EmitGCMarkValue(BfTypedValue& thisValue, BfType* checkType, int m
if (!checkType->WantsGCMarking())
return;
if (checkType->IsDeleting())
{
mCompiler->RequestExtraCompile();
InternalError("EmitGCMarkValue deleted type");
return;
}
auto typeInstance = checkType->ToTypeInstance();
bool callMarkMethod = false;

View file

@ -1223,6 +1223,37 @@ BfPassInstance::~BfPassInstance()
delete bfError;
}
BfPassInstance::StateInfo BfPassInstance::GetState()
{
StateInfo stateInfo;
stateInfo.mOutStreamSize = (int)mOutStream.mSize;
stateInfo.mErrorsSize = mErrors.mSize;
stateInfo.mWarningCount = mWarningCount;
stateInfo.mDeferredErrorCount = mDeferredErrorCount;
stateInfo.mFailedIdx = mFailedIdx;
stateInfo.mWarnIdx = mWarnIdx;
return stateInfo;
}
void BfPassInstance::RestoreState(StateInfo stateInfo)
{
while (mOutStream.mSize > stateInfo.mOutStreamSize)
mOutStream.pop_back();
while (mErrors.mSize > stateInfo.mErrorsSize)
{
auto error = mErrors.back();
mErrors.pop_back();
mErrorSet.Remove(error);
delete error;
}
mWarningCount = stateInfo.mWarningCount;
mDeferredErrorCount = stateInfo.mDeferredErrorCount;
mFailedIdx = stateInfo.mFailedIdx;
mWarnIdx = stateInfo.mWarnIdx;
}
void BfPassInstance::ClearErrors()
{
mFailedIdx = 0;

View file

@ -1594,6 +1594,17 @@ public:
class BfPassInstance
{
public:
struct StateInfo
{
int mOutStreamSize;
int mErrorsSize;
int mWarningCount;
int mDeferredErrorCount;
int mFailedIdx;
int mWarnIdx;
};
public:
const int sMaxDisplayErrors = 100;
const int sMaxErrors = 1000;
@ -1636,6 +1647,9 @@ public:
~BfPassInstance();
StateInfo GetState();
void RestoreState(StateInfo stateInfo);
void ClearErrors();
bool HasFailed();
bool HasMessages();