mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Comptime reentrancy fixes, deleting rebuild, static field fixes
This commit is contained in:
parent
0bb273b898
commit
c5e2b78199
5 changed files with 145 additions and 57 deletions
|
@ -3464,20 +3464,25 @@ void BfModule::AddDependency(BfType* usedType, BfType* userType, BfDependencyMap
|
||||||
if (addType)
|
if (addType)
|
||||||
{
|
{
|
||||||
auto checkTypeInst = checkType->ToTypeInstance();
|
auto checkTypeInst = checkType->ToTypeInstance();
|
||||||
auto hotTypeVersion = checkTypeInst->mHotTypeData->GetLatestVersion();
|
if (checkTypeInst->mHotTypeData != NULL)
|
||||||
BF_ASSERT(hotTypeVersion != NULL);
|
{
|
||||||
|
auto hotTypeVersion = checkTypeInst->mHotTypeData->GetLatestVersion();
|
||||||
|
BF_ASSERT(hotTypeVersion != NULL);
|
||||||
|
if (hotTypeVersion != NULL)
|
||||||
|
{
|
||||||
|
bool isAllocation = ((flags & BfDependencyMap::DependencyFlag_Allocates) != 0);
|
||||||
|
if (((flags & BfDependencyMap::DependencyFlag_LocalUsage) != 0) &&
|
||||||
|
(checkType->IsComposite()))
|
||||||
|
isAllocation = true;
|
||||||
|
|
||||||
bool isAllocation = ((flags & BfDependencyMap::DependencyFlag_Allocates) != 0);
|
if (isAllocation)
|
||||||
if (((flags & BfDependencyMap::DependencyFlag_LocalUsage) != 0) &&
|
{
|
||||||
(checkType->IsComposite()))
|
mCurMethodState->mHotDataReferenceBuilder->mAllocatedData.Add(hotTypeVersion);
|
||||||
isAllocation = true;
|
}
|
||||||
|
else
|
||||||
if (isAllocation)
|
mCurMethodState->mHotDataReferenceBuilder->mUsedData.Add(hotTypeVersion);
|
||||||
{
|
}
|
||||||
mCurMethodState->mHotDataReferenceBuilder->mAllocatedData.Add(hotTypeVersion);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mCurMethodState->mHotDataReferenceBuilder->mUsedData.Add(hotTypeVersion);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6432,9 +6437,10 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fieldInstance->GetFieldDef()->mIsStatic)
|
else if (fieldInstance->GetFieldDef()->mIsStatic)
|
||||||
{
|
{
|
||||||
auto refVal = ReferenceStaticField(fieldInstance);
|
BfTypedValue refVal;
|
||||||
|
if (!mIsComptimeModule) // This can create circular reference issues for a `Self` static
|
||||||
|
refVal = ReferenceStaticField(fieldInstance);
|
||||||
if (refVal.mValue.IsConst())
|
if (refVal.mValue.IsConst())
|
||||||
{
|
{
|
||||||
auto constant = mBfIRBuilder->GetConstant(refVal.mValue);
|
auto constant = mBfIRBuilder->GetConstant(refVal.mValue);
|
||||||
|
|
|
@ -1178,11 +1178,6 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
else
|
else
|
||||||
resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
|
resolvedTypeRef->mTypeId = mCompiler->mCurTypeId++;
|
||||||
|
|
||||||
if (resolvedTypeRef->mTypeId == 2568)
|
|
||||||
{
|
|
||||||
NOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
|
while (resolvedTypeRef->mTypeId >= (int)mContext->mTypes.size())
|
||||||
mContext->mTypes.Add(NULL);
|
mContext->mTypes.Add(NULL);
|
||||||
mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
|
mContext->mTypes[resolvedTypeRef->mTypeId] = resolvedTypeRef;
|
||||||
|
@ -2158,6 +2153,9 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
|
||||||
|
|
||||||
auto result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_None, NULL);
|
auto result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_None, NULL);
|
||||||
|
|
||||||
|
if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||||
|
return;
|
||||||
|
|
||||||
if (typeInstance->mDefineState != BfTypeDefineState_CETypeInit)
|
if (typeInstance->mDefineState != BfTypeDefineState_CETypeInit)
|
||||||
{
|
{
|
||||||
// We populated before we could finish
|
// We populated before we could finish
|
||||||
|
@ -2438,6 +2436,9 @@ void BfModule::DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers)
|
||||||
ceEmitContext.mType = typeInstance;
|
ceEmitContext.mType = typeInstance;
|
||||||
ExecuteCEOnCompile(&ceEmitContext, typeInstance, BfCEOnCompileKind_TypeInit);
|
ExecuteCEOnCompile(&ceEmitContext, typeInstance, BfCEOnCompileKind_TypeInit);
|
||||||
hadNewMembers = (typeInstance->mTypeDef->mEmitParent != NULL);
|
hadNewMembers = (typeInstance->mTypeDef->mEmitParent != NULL);
|
||||||
|
|
||||||
|
if (ceEmitContext.mFailed)
|
||||||
|
TypeFailed(typeInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
|
void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
|
||||||
|
@ -3939,26 +3940,46 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tryCE = true;
|
||||||
if (typeInstance->mDefineState == BfTypeDefineState_CETypeInit)
|
if (typeInstance->mDefineState == BfTypeDefineState_CETypeInit)
|
||||||
{
|
{
|
||||||
if (populateType <= BfPopulateType_AllowStaticMethods)
|
if (populateType <= BfPopulateType_AllowStaticMethods)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
String error = "OnCompile const evaluation creates a data dependency during TypeInit";
|
int foundTypeCount = 0;
|
||||||
if (mCompiler->mCEMachine->mCurBuilder != NULL)
|
auto typeState = mContext->mCurTypeState;
|
||||||
|
while (typeState != NULL)
|
||||||
{
|
{
|
||||||
error += StrFormat(" during const-eval generation of '%s'", MethodToString(mCompiler->mCEMachine->mCurBuilder->mCeFunction->mMethodInstance).c_str());
|
if (typeState->mType == typeInstance)
|
||||||
|
{
|
||||||
|
foundTypeCount++;
|
||||||
|
if (foundTypeCount == 2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
typeState = typeState->mPrevState;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto refNode = typeDef->GetRefNode();
|
if ((foundTypeCount >= 2) || (typeInstance->mTypeDef->IsEmitted()))
|
||||||
Fail(error, refNode);
|
{
|
||||||
if ((mCompiler->mCEMachine->mCurContext != NULL) && (mCompiler->mCEMachine->mCurContext->mCurFrame != NULL))
|
String error = "OnCompile const evaluation creates a data dependency during TypeInit";
|
||||||
mCompiler->mCEMachine->mCurContext->Fail(*mCompiler->mCEMachine->mCurContext->mCurFrame, error);
|
if (mCompiler->mCEMachine->mCurBuilder != NULL)
|
||||||
else if (mCompiler->mCEMachine->mCurContext != NULL)
|
{
|
||||||
mCompiler->mCEMachine->mCurContext->Fail(error);
|
error += StrFormat(" during const-eval generation of '%s'", MethodToString(mCompiler->mCEMachine->mCurBuilder->mCeFunction->mMethodInstance).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto refNode = typeDef->GetRefNode();
|
||||||
|
Fail(error, refNode);
|
||||||
|
if ((mCompiler->mCEMachine->mCurContext != NULL) && (mCompiler->mCEMachine->mCurContext->mCurFrame != NULL))
|
||||||
|
mCompiler->mCEMachine->mCurContext->Fail(*mCompiler->mCEMachine->mCurContext->mCurFrame, error);
|
||||||
|
else if (mCompiler->mCEMachine->mCurContext != NULL)
|
||||||
|
mCompiler->mCEMachine->mCurContext->Fail(error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit)
|
|
||||||
{
|
if ((typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit) && (tryCE))
|
||||||
|
{
|
||||||
|
BF_ASSERT(!typeInstance->mTypeDef->IsEmitted());
|
||||||
|
|
||||||
typeInstance->mDefineState = BfTypeDefineState_CETypeInit;
|
typeInstance->mDefineState = BfTypeDefineState_CETypeInit;
|
||||||
bool hadNewMembers = false;
|
bool hadNewMembers = false;
|
||||||
DoCEEmit(typeInstance, hadNewMembers);
|
DoCEEmit(typeInstance, hadNewMembers);
|
||||||
|
@ -3991,9 +4012,17 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
{
|
{
|
||||||
if ((typeInstance->mCeTypeInfo->mHash != typeInstance->mCeTypeInfo->mNext->mHash) && (!typeInstance->mCeTypeInfo->mHash.IsZero()))
|
if ((typeInstance->mCeTypeInfo->mHash != typeInstance->mCeTypeInfo->mNext->mHash) && (!typeInstance->mCeTypeInfo->mHash.IsZero()))
|
||||||
{
|
{
|
||||||
|
int prevDeletedTypes = mCompiler->mStats.mTypesDeleted;
|
||||||
if (mCompiler->mIsResolveOnly)
|
if (mCompiler->mIsResolveOnly)
|
||||||
mCompiler->mNeedsFullRefresh = true;
|
mCompiler->mNeedsFullRefresh = true;
|
||||||
|
BfLogSysM("Type %p hash changed, rebuilding dependent types\n", typeInstance);
|
||||||
mContext->RebuildDependentTypes(typeInstance);
|
mContext->RebuildDependentTypes(typeInstance);
|
||||||
|
|
||||||
|
if (mCompiler->mStats.mTypesDeleted != prevDeletedTypes)
|
||||||
|
{
|
||||||
|
BfLogSysM("Type %p hash changed, rebuilding dependent types - updating after deleting types\n", typeInstance);
|
||||||
|
mContext->UpdateAfterDeletingTypes();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
typeInstance->mCeTypeInfo->mOnCompileMap = typeInstance->mCeTypeInfo->mNext->mOnCompileMap;
|
typeInstance->mCeTypeInfo->mOnCompileMap = typeInstance->mCeTypeInfo->mNext->mOnCompileMap;
|
||||||
typeInstance->mCeTypeInfo->mTypeIFaceMap = typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap;
|
typeInstance->mCeTypeInfo->mTypeIFaceMap = typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap;
|
||||||
|
@ -6205,6 +6234,15 @@ void BfModule::AddMethodToWorkList(BfMethodInstance* methodInstance)
|
||||||
auto typeInstance = methodInstance->GetOwner();
|
auto typeInstance = methodInstance->GetOwner();
|
||||||
|
|
||||||
BfMethodProcessRequest* methodProcessRequest = mContext->mMethodWorkList.Alloc();
|
BfMethodProcessRequest* methodProcessRequest = mContext->mMethodWorkList.Alloc();
|
||||||
|
if (mCompiler->mCompileState == BfCompiler::CompileState_Unreified)
|
||||||
|
{
|
||||||
|
if (methodInstance->mIsReified)
|
||||||
|
{
|
||||||
|
BfLogSysM("Marking method %d as unreified due to CompileState_Unreified\n", methodInstance);
|
||||||
|
methodInstance->mIsReified = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//BF_ASSERT(!methodInstance->mIsReified);
|
||||||
methodProcessRequest->mType = typeInstance;
|
methodProcessRequest->mType = typeInstance;
|
||||||
methodProcessRequest->mMethodInstance = methodInstance;
|
methodProcessRequest->mMethodInstance = methodInstance;
|
||||||
methodProcessRequest->mRevision = typeInstance->mRevision;
|
methodProcessRequest->mRevision = typeInstance->mRevision;
|
||||||
|
@ -9976,6 +10014,7 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
|
||||||
if (!inserted)
|
if (!inserted)
|
||||||
{
|
{
|
||||||
BF_ASSERT(resolvedEntry->mValue != NULL);
|
BF_ASSERT(resolvedEntry->mValue != NULL);
|
||||||
|
BF_ASSERT(!resolvedEntry->mValue->IsDeleting());
|
||||||
return ResolveTypeResult(typeRef, resolvedEntry->mValue, populateType, resolveFlags);
|
return ResolveTypeResult(typeRef, resolvedEntry->mValue, populateType, resolveFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1120,7 +1120,7 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme
|
||||||
if (checkBuilder->mInnerFunctionMap.TryGetValue(beFunction, &innerFunctionIdx))
|
if (checkBuilder->mInnerFunctionMap.TryGetValue(beFunction, &innerFunctionIdx))
|
||||||
{
|
{
|
||||||
auto innerFunction = checkBuilder->mCeFunction->mInnerFunctions[innerFunctionIdx];
|
auto innerFunction = checkBuilder->mCeFunction->mInnerFunctions[innerFunctionIdx];
|
||||||
if (!innerFunction->mInitialized)
|
if (innerFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
||||||
mCeMachine->PrepareFunction(innerFunction, checkBuilder);
|
mCeMachine->PrepareFunction(innerFunction, checkBuilder);
|
||||||
|
|
||||||
CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
|
CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
|
||||||
|
@ -1288,7 +1288,7 @@ void CeBuilder::Build()
|
||||||
auto methodInstance = mCeFunction->mMethodInstance;
|
auto methodInstance = mCeFunction->mMethodInstance;
|
||||||
|
|
||||||
if (methodInstance != NULL)
|
if (methodInstance != NULL)
|
||||||
{
|
{
|
||||||
BfMethodInstance dupMethodInstance;
|
BfMethodInstance dupMethodInstance;
|
||||||
dupMethodInstance.CopyFrom(methodInstance);
|
dupMethodInstance.CopyFrom(methodInstance);
|
||||||
auto methodDef = methodInstance->mMethodDef;
|
auto methodDef = methodInstance->mMethodDef;
|
||||||
|
@ -1313,7 +1313,9 @@ void CeBuilder::Build()
|
||||||
|
|
||||||
int startFunctionCount = (int)beModule->mFunctions.size();
|
int startFunctionCount = (int)beModule->mFunctions.size();
|
||||||
ProcessMethod(methodInstance, &dupMethodInstance);
|
ProcessMethod(methodInstance, &dupMethodInstance);
|
||||||
|
if (mCeFunction->mInitializeState == CeFunction::InitializeState_Initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!dupMethodInstance.mIRFunction)
|
if (!dupMethodInstance.mIRFunction)
|
||||||
{
|
{
|
||||||
mCeFunction->mFailed = true;
|
mCeFunction->mFailed = true;
|
||||||
|
@ -2855,6 +2857,7 @@ void CeBuilder::Build()
|
||||||
|
|
||||||
CeContext::CeContext()
|
CeContext::CeContext()
|
||||||
{
|
{
|
||||||
|
mPrevContext = NULL;
|
||||||
mCurEvalFlags = CeEvalFlags_None;
|
mCurEvalFlags = CeEvalFlags_None;
|
||||||
mCeMachine = NULL;
|
mCeMachine = NULL;
|
||||||
mReflectTypeIdOffset = -1;
|
mReflectTypeIdOffset = -1;
|
||||||
|
@ -2876,6 +2879,8 @@ CeContext::~CeContext()
|
||||||
|
|
||||||
BfError* CeContext::Fail(const StringImpl& error)
|
BfError* CeContext::Fail(const StringImpl& error)
|
||||||
{
|
{
|
||||||
|
if (mCurEmitContext != NULL)
|
||||||
|
mCurEmitContext->mFailed = true;
|
||||||
auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc, (mCurEvalFlags & CeEvalFlags_PersistantError) != 0);
|
auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc, (mCurEvalFlags & CeEvalFlags_PersistantError) != 0);
|
||||||
if (bfError == NULL)
|
if (bfError == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2885,6 +2890,8 @@ BfError* CeContext::Fail(const StringImpl& error)
|
||||||
|
|
||||||
BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
|
BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
|
||||||
{
|
{
|
||||||
|
if (mCurEmitContext != NULL)
|
||||||
|
mCurEmitContext->mFailed = true;
|
||||||
auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc,
|
auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc,
|
||||||
(mCurEvalFlags & CeEvalFlags_PersistantError) != 0,
|
(mCurEvalFlags & CeEvalFlags_PersistantError) != 0,
|
||||||
((mCurEvalFlags & CeEvalFlags_DeferIfNotOnlyError) != 0) && !mCurModule->mHadBuildError);
|
((mCurEvalFlags & CeEvalFlags_DeferIfNotOnlyError) != 0) && !mCurModule->mHadBuildError);
|
||||||
|
@ -2966,6 +2973,10 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
|
||||||
moreInfo->mLocation = location;
|
moreInfo->mLocation = location;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto moreInfo = passInstance->MoreInfo(err, mCeMachine->mCeModule->mCompiler->GetAutoComplete() != NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return bfError;
|
return bfError;
|
||||||
|
@ -3939,6 +3950,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
|
|
||||||
AutoTimer autoTimer(mCeMachine->mRevisionExecuteTime);
|
AutoTimer autoTimer(mCeMachine->mRevisionExecuteTime);
|
||||||
|
|
||||||
|
SetAndRestoreValue<CeContext*> curPrevContext(mPrevContext, mCeMachine->mCurContext);
|
||||||
SetAndRestoreValue<CeContext*> prevContext(mCeMachine->mCurContext, this);
|
SetAndRestoreValue<CeContext*> prevContext(mCeMachine->mCurContext, this);
|
||||||
SetAndRestoreValue<CeEvalFlags> prevEvalFlags(mCurEvalFlags, flags);
|
SetAndRestoreValue<CeEvalFlags> prevEvalFlags(mCurEvalFlags, flags);
|
||||||
SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
|
SetAndRestoreValue<BfAstNode*> prevTargetSrc(mCurTargetSrc, targetSrc);
|
||||||
|
@ -4042,13 +4054,24 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
bool added = false;
|
bool added = false;
|
||||||
CeFunction* ceFunction = mCeMachine->GetFunction(methodInstance, BfIRValue(), added);
|
CeFunction* ceFunction = mCeMachine->GetFunction(methodInstance, BfIRValue(), added);
|
||||||
|
|
||||||
if (ceFunction->mGenerating)
|
if (ceFunction->mInitializeState == CeFunction::InitializeState_Initializing_ReEntry)
|
||||||
{
|
{
|
||||||
Fail("Recursive var-inference");
|
String error = "Comptime method preparation recursion";
|
||||||
|
auto curContext = this;
|
||||||
|
while (curContext != NULL)
|
||||||
|
{
|
||||||
|
if (curContext->mCurMethodInstance != NULL)
|
||||||
|
error += StrFormat("\n %s", module->MethodToString(curContext->mCurMethodInstance).c_str());
|
||||||
|
|
||||||
|
curContext = curContext->mPrevContext;
|
||||||
|
if ((curContext != NULL) && (curContext->mCurMethodInstance == mCurMethodInstance))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Fail(error);
|
||||||
return BfTypedValue();
|
return BfTypedValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ceFunction->mInitialized)
|
if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
||||||
mCeMachine->PrepareFunction(ceFunction, NULL);
|
mCeMachine->PrepareFunction(ceFunction, NULL);
|
||||||
|
|
||||||
auto stackPtr = &mMemory[0] + BF_CE_STACK_SIZE;
|
auto stackPtr = &mMemory[0] + BF_CE_STACK_SIZE;
|
||||||
|
@ -4926,7 +4949,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
if (!checkFunction->mFailed)
|
if (!checkFunction->mFailed)
|
||||||
return true;
|
return true;
|
||||||
auto error = Fail(_GetCurFrame(), StrFormat("Method call '%s' failed", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
|
auto error = Fail(_GetCurFrame(), StrFormat("Method call preparation '%s' failed", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
|
||||||
if ((error != NULL) && (!checkFunction->mGenError.IsEmpty()))
|
if ((error != NULL) && (!checkFunction->mGenError.IsEmpty()))
|
||||||
mCeMachine->mCompiler->mPassInstance->MoreInfo("Comptime method generation error: " + checkFunction->mGenError);
|
mCeMachine->mCompiler->mPassInstance->MoreInfo("Comptime method generation error: " + checkFunction->mGenError);
|
||||||
return false;
|
return false;
|
||||||
|
@ -5394,7 +5417,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
bool added = false;
|
bool added = false;
|
||||||
ctorCallFunction = mCeMachine->GetFunction(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, added);
|
ctorCallFunction = mCeMachine->GetFunction(moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, added);
|
||||||
if (!ctorCallFunction->mInitialized)
|
if (ctorCallFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
||||||
mCeMachine->PrepareFunction(ctorCallFunction, NULL);
|
mCeMachine->PrepareFunction(ctorCallFunction, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5469,11 +5492,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
}
|
}
|
||||||
|
|
||||||
callEntry.mFunction = callEntry.mFunctionInfo->mCeFunction;
|
callEntry.mFunction = callEntry.mFunctionInfo->mCeFunction;
|
||||||
if (!callEntry.mFunction->mInitialized)
|
if (callEntry.mFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
||||||
{
|
{
|
||||||
auto curFrame = _GetCurFrame();
|
auto curFrame = _GetCurFrame();
|
||||||
SetAndRestoreValue<CeFrame*> prevFrame(mCurFrame, &curFrame);
|
SetAndRestoreValue<CeFrame*> prevFrame(mCurFrame, &curFrame);
|
||||||
BF_ASSERT(!callEntry.mFunction->mInitialized);
|
BF_ASSERT(callEntry.mFunction->mInitializeState < CeFunction::InitializeState_Initialized);
|
||||||
mCeMachine->PrepareFunction(callEntry.mFunction, NULL);
|
mCeMachine->PrepareFunction(callEntry.mFunction, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6912,7 +6935,7 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh;
|
||||||
}
|
}
|
||||||
|
|
||||||
ceFunction->mInitialized = true;
|
ceFunction->mInitializeState = CeFunction::InitializeState_Initialized;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6923,19 +6946,27 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
||||||
AutoTimer autoTimer(mRevisionExecuteTime);
|
AutoTimer autoTimer(mRevisionExecuteTime);
|
||||||
SetAndRestoreValue<CeFunction*> prevCEFunction(mPreparingFunction, ceFunction);
|
SetAndRestoreValue<CeFunction*> prevCEFunction(mPreparingFunction, ceFunction);
|
||||||
|
|
||||||
BF_ASSERT(!ceFunction->mInitialized);
|
BF_ASSERT(ceFunction->mInitializeState <= CeFunction::InitializeState_Initialized);
|
||||||
|
|
||||||
if (ceFunction->mFunctionKind == CeFunctionKind_NotSet)
|
if (ceFunction->mFunctionKind == CeFunctionKind_NotSet)
|
||||||
{
|
{
|
||||||
CheckFunctionKind(ceFunction);
|
CheckFunctionKind(ceFunction);
|
||||||
if (ceFunction->mInitialized)
|
if (ceFunction->mInitializeState == CeFunction::InitializeState_Initialized)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_ASSERT(!ceFunction->mInitialized);
|
BF_ASSERT(ceFunction->mInitializeState <= CeFunction::InitializeState_Initialized);
|
||||||
ceFunction->mInitialized = true;
|
if (ceFunction->mInitializeState == CeFunction::InitializeState_Initializing_ReEntry)
|
||||||
ceFunction->mGenerating = true;
|
{
|
||||||
|
//Fail("Function generation re-entry");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ceFunction->mInitializeState == CeFunction::InitializeState_Initializing)
|
||||||
|
ceFunction->mInitializeState = CeFunction::InitializeState_Initializing_ReEntry;
|
||||||
|
else
|
||||||
|
ceFunction->mInitializeState = CeFunction::InitializeState_Initializing;
|
||||||
|
|
||||||
CeBuilder ceBuilder;
|
CeBuilder ceBuilder;
|
||||||
SetAndRestoreValue<CeBuilder*> prevBuilder(mCurBuilder, &ceBuilder);
|
SetAndRestoreValue<CeBuilder*> prevBuilder(mCurBuilder, &ceBuilder);
|
||||||
ceBuilder.mParentBuilder = parentBuilder;
|
ceBuilder.mParentBuilder = parentBuilder;
|
||||||
|
@ -6944,7 +6975,7 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
|
||||||
ceBuilder.mCeFunction = ceFunction;
|
ceBuilder.mCeFunction = ceFunction;
|
||||||
ceBuilder.Build();
|
ceBuilder.Build();
|
||||||
|
|
||||||
ceFunction->mGenerating = false;
|
ceFunction->mInitializeState = CeFunction::InitializeState_Initialized;
|
||||||
|
|
||||||
/*if (!ceFunction->mCode.IsEmpty())
|
/*if (!ceFunction->mCode.IsEmpty())
|
||||||
{
|
{
|
||||||
|
@ -6980,8 +7011,8 @@ CeFunction* CeMachine::GetFunction(BfMethodInstance* methodInstance, BfIRValue f
|
||||||
CeFunction* ceFunction = NULL;
|
CeFunction* ceFunction = NULL;
|
||||||
if (!mFunctions.TryAdd(methodInstance, NULL, &functionInfoPtr))
|
if (!mFunctions.TryAdd(methodInstance, NULL, &functionInfoPtr))
|
||||||
{
|
{
|
||||||
ceFunctionInfo = *functionInfoPtr;
|
ceFunctionInfo = *functionInfoPtr;
|
||||||
BF_ASSERT(ceFunctionInfo->mCeFunction != NULL);
|
BF_ASSERT(ceFunctionInfo->mCeFunction != NULL);
|
||||||
return ceFunctionInfo->mCeFunction;
|
return ceFunctionInfo->mCeFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7048,7 +7079,7 @@ CeFunction* CeMachine::GetPreparedFunction(BfMethodInstance* methodInstance)
|
||||||
auto ceFunction = GetFunction(methodInstance, BfIRValue(), added);
|
auto ceFunction = GetFunction(methodInstance, BfIRValue(), added);
|
||||||
if (ceFunction == NULL)
|
if (ceFunction == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!ceFunction->mInitialized)
|
if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
||||||
PrepareFunction(ceFunction, NULL);
|
PrepareFunction(ceFunction, NULL);
|
||||||
return ceFunction;
|
return ceFunction;
|
||||||
}
|
}
|
||||||
|
|
|
@ -395,14 +395,22 @@ public:
|
||||||
|
|
||||||
class CeFunction
|
class CeFunction
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
enum InitializeState
|
||||||
|
{
|
||||||
|
InitializeState_None,
|
||||||
|
InitializeState_Initializing,
|
||||||
|
InitializeState_Initializing_ReEntry,
|
||||||
|
InitializeState_Initialized
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CeMachine* mCeMachine;
|
CeMachine* mCeMachine;
|
||||||
CeFunctionInfo* mCeFunctionInfo;
|
CeFunctionInfo* mCeFunctionInfo;
|
||||||
CeInnerFunctionInfo* mCeInnerFunctionInfo;
|
CeInnerFunctionInfo* mCeInnerFunctionInfo;
|
||||||
BfMethodInstance* mMethodInstance;
|
BfMethodInstance* mMethodInstance;
|
||||||
CeFunctionKind mFunctionKind;
|
CeFunctionKind mFunctionKind;
|
||||||
bool mGenerating;
|
InitializeState mInitializeState;
|
||||||
bool mInitialized;
|
|
||||||
bool mFailed;
|
bool mFailed;
|
||||||
bool mIsVarReturn;
|
bool mIsVarReturn;
|
||||||
Array<uint8> mCode;
|
Array<uint8> mCode;
|
||||||
|
@ -425,9 +433,8 @@ public:
|
||||||
mCeMachine = NULL;
|
mCeMachine = NULL;
|
||||||
mCeFunctionInfo = NULL;
|
mCeFunctionInfo = NULL;
|
||||||
mCeInnerFunctionInfo = NULL;
|
mCeInnerFunctionInfo = NULL;
|
||||||
mFunctionKind = CeFunctionKind_NotSet;
|
mFunctionKind = CeFunctionKind_NotSet;
|
||||||
mGenerating = false;
|
mInitializeState = InitializeState_None;
|
||||||
mInitialized = false;
|
|
||||||
mMethodInstance = NULL;
|
mMethodInstance = NULL;
|
||||||
mFailed = false;
|
mFailed = false;
|
||||||
mIsVarReturn = false;
|
mIsVarReturn = false;
|
||||||
|
@ -682,11 +689,13 @@ public:
|
||||||
BfMethodInstance* mMethodInstance;
|
BfMethodInstance* mMethodInstance;
|
||||||
String mEmitData;
|
String mEmitData;
|
||||||
String mExitEmitData;
|
String mExitEmitData;
|
||||||
|
bool mFailed;
|
||||||
|
|
||||||
CeEmitContext()
|
CeEmitContext()
|
||||||
{
|
{
|
||||||
mType = NULL;
|
mType = NULL;
|
||||||
mMethodInstance = NULL;
|
mMethodInstance = NULL;
|
||||||
|
mFailed = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -694,6 +703,7 @@ class CeContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CeMachine* mCeMachine;
|
CeMachine* mCeMachine;
|
||||||
|
CeContext* mPrevContext;
|
||||||
int mReflectTypeIdOffset;
|
int mReflectTypeIdOffset;
|
||||||
int mExecuteId;
|
int mExecuteId;
|
||||||
CeEvalFlags mCurEvalFlags;
|
CeEvalFlags mCurEvalFlags;
|
||||||
|
|
|
@ -84,6 +84,8 @@ namespace Tests
|
||||||
struct StructA
|
struct StructA
|
||||||
{
|
{
|
||||||
public int mA = 123;
|
public int mA = 123;
|
||||||
|
public static StructA sSA;
|
||||||
|
public const StructA cSA = .();
|
||||||
|
|
||||||
[OnCompile(.TypeInit), Comptime]
|
[OnCompile(.TypeInit), Comptime]
|
||||||
public static void Generate()
|
public static void Generate()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue