diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 1505f259..01291c77 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -5078,12 +5078,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* if (mModule->mCompiler->mCEMachine != NULL) { - if ((mModule->mIsConstModule) && (!methodInstance->mReturnType->IsVar())) - { - mModule->mCompiler->mCEMachine->QueueMethod(methodInstance, func); - } - else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0) - { + bool doConstReturn = false; + + if ((mBfEvalExprFlags & BfEvalExprFlags_ConstEval) != 0) + { if (mFunctionBindResult != NULL) { forceBind = true; @@ -5091,6 +5089,10 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* else if ((mBfEvalExprFlags & BfEvalExprFlags_InCascade) != 0) { mModule->Fail("Const evaluation not allowed with cascade operator", targetSrc); + } + else if (methodInstance->mIsUnspecialized) + { + doConstReturn = true; } else { @@ -5101,7 +5103,34 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* BF_ASSERT(!constRet.mType->IsVar()); return constRet; } + } + } + else if (mModule->mIsConstModule) + { + if (methodInstance->mIsUnspecialized) + { + doConstReturn = true; } + else + { + mModule->mCompiler->mCEMachine->QueueMethod(methodInstance, func); + } + } + + if (doConstReturn) + { + if ((returnType->IsVar()) && (mExpectingType != NULL)) + returnType = mExpectingType; + if (returnType->IsRef()) + { + return _GetDefaultReturnValue(); + } + else + { + return mModule->GetDefaultTypedValue(returnType, true, BfDefaultValueKind_Undef); + } + + return _GetDefaultReturnValue(); } } diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 1d658ff3..cbb6f08f 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -1655,7 +1655,6 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD initValue = constResolver.Resolve(varDecl->mInitializer, resolvedType, BfConstResolveFlag_RemapFromStringId); if (!initValue) initValue = GetDefaultTypedValue(resolvedType); - } else if (varDecl->mInitializer->IsA()) { diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 8b8cff1b..2ade984a 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -2714,13 +2714,27 @@ BfError* CeMachine::Fail(const CeFrame& curFrame, const StringImpl& str) err = str; err += " "; } - - err += StrFormat("in const evaluation of "); - if (ceFunction->mMethodInstance != NULL) - err += mCeModule->MethodToString(ceFunction->mMethodInstance, BfMethodNameFlag_OmitParams); - else + + auto contextMethodInstance = mCurModule->mCurMethodInstance; + if (stackIdx > 1) { - err += mCeModule->MethodToString(ceFunction->mCeInnerFunctionInfo->mOwner->mMethodInstance, BfMethodNameFlag_OmitParams); + auto func = mCallStack[stackIdx - 1].mFunction; + contextMethodInstance = func->mCeFunctionInfo->mMethodInstance; + } + + err += StrFormat("in const evaluation of "); + + // + { + SetAndRestoreValue prevTypeInstance(mCeModule->mCurTypeInstance, (contextMethodInstance != NULL) ? contextMethodInstance->GetOwner() : NULL); + SetAndRestoreValue prevMethodInstance(mCeModule->mCurMethodInstance, contextMethodInstance); + + if (ceFunction->mMethodInstance != NULL) + err += mCeModule->MethodToString(ceFunction->mMethodInstance, BfMethodNameFlag_OmitParams); + else + { + err += mCeModule->MethodToString(ceFunction->mCeInnerFunctionInfo->mOwner->mMethodInstance, BfMethodNameFlag_OmitParams); + } } if (emitEntry != NULL) @@ -2831,6 +2845,8 @@ addr_ce CeMachine::GetReflectType(int typeId) if (!mReflectMap.TryAdd(typeId, NULL, &addrPtr)) return *addrPtr; + SetAndRestoreValue ignoreWrites(mCeModule->mBfIRBuilder->mIgnoreWrites, false); + if (mCeModule->mContext->mBfTypeType == NULL) mCeModule->mContext->ReflectInit(); @@ -2981,9 +2997,12 @@ void CeMachine::DerefMethodInfo(CeFunctionInfo* ceFunctionInfo) return; BF_ASSERT(ceFunctionInfo->mMethodInstance == NULL); - auto itr = mNamedFunctionMap.Find(ceFunctionInfo->mName); - if (itr->mValue == ceFunctionInfo) - mNamedFunctionMap.Remove(itr); + if (!ceFunctionInfo->mName.IsEmpty()) + { + auto itr = mNamedFunctionMap.Find(ceFunctionInfo->mName); + if (itr->mValue == ceFunctionInfo) + mNamedFunctionMap.Remove(itr); + } delete ceFunctionInfo; }