mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Start of compile-time function evaluation
This commit is contained in:
parent
350516fae3
commit
577e199dcd
17 changed files with 2437 additions and 29 deletions
|
@ -49,8 +49,6 @@ BuildCommandsOnRun = "IfFilesChanged"
|
|||
BuildCommandsOnCompile = "IfFilesChanged"
|
||||
BuildCommandsOnRun = "IfFilesChanged"
|
||||
|
||||
[ProjectFolder]
|
||||
|
||||
[[ProjectFolder.Items]]
|
||||
Type = "Folder"
|
||||
Name = "Backend"
|
||||
|
@ -351,6 +349,14 @@ Path = "Compiler/BfUtil.cpp"
|
|||
Type = "Source"
|
||||
Path = "Compiler/BfUtil.h"
|
||||
|
||||
[[ProjectFolder.Items.Items]]
|
||||
Type = "Source"
|
||||
Path = "Compiler/CeMachine.cpp"
|
||||
|
||||
[[ProjectFolder.Items.Items]]
|
||||
Type = "Source"
|
||||
Path = "Compiler/CeMachine.h"
|
||||
|
||||
[[ProjectFolder.Items]]
|
||||
Type = "Folder"
|
||||
Path = "Debugger"
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "BeefySysLib/util/BeefPerf.h"
|
||||
#include "../LLVMUtils.h"
|
||||
#include "BfNamespaceVisitor.h"
|
||||
#include "CeMachine.h"
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
|
@ -443,6 +444,10 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mReflectAttributeTypeDef = NULL;
|
||||
|
||||
mLastAutocompleteModule = NULL;
|
||||
|
||||
//if (isResolveOnly)
|
||||
//mCEMachine = NULL;
|
||||
mCEMachine = new CeMachine(this);
|
||||
}
|
||||
|
||||
BfCompiler::~BfCompiler()
|
||||
|
@ -451,6 +456,7 @@ BfCompiler::~BfCompiler()
|
|||
delete mHotData;
|
||||
delete mHotState;
|
||||
delete mHotResolveData;
|
||||
delete mCEMachine;
|
||||
}
|
||||
|
||||
bool BfCompiler::IsTypeAccessible(BfType* checkType, BfProject* curProject)
|
||||
|
@ -6411,6 +6417,9 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
else
|
||||
mContext->mUnreifiedModule->mIsReified = false;
|
||||
|
||||
if (mCEMachine != NULL)
|
||||
mCEMachine->CompileStarted();
|
||||
|
||||
if (mOptions.mAllowHotSwapping)
|
||||
{
|
||||
if (mHotData == NULL)
|
||||
|
|
|
@ -41,6 +41,7 @@ class BfAutoComplete;
|
|||
class BfMethodInstance;
|
||||
class BfSourceClassifier;
|
||||
class BfResolvePassData;
|
||||
class CeMachine;
|
||||
|
||||
enum BfCompileOnDemandKind
|
||||
{
|
||||
|
@ -173,7 +174,7 @@ public:
|
|||
|
||||
mExtraResolveChecks = false;
|
||||
#ifdef _DEBUG
|
||||
//mExtraResolveChecks = true;
|
||||
mExtraResolveChecks = false;
|
||||
#endif
|
||||
mMaxSplatRegs = 4;
|
||||
}
|
||||
|
@ -310,6 +311,7 @@ public:
|
|||
BfPassInstance* mPassInstance;
|
||||
FILE* mCompileLogFP;
|
||||
|
||||
CeMachine* mCEMachine;
|
||||
BfSystem* mSystem;
|
||||
bool mIsResolveOnly;
|
||||
BfResolvePassData* mResolvePassData;
|
||||
|
|
|
@ -36,6 +36,8 @@ BfConstResolver::BfConstResolver(BfModule* bfModule) : BfExprEvaluator(bfModule)
|
|||
|
||||
BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfConstResolveFlags flags)
|
||||
{
|
||||
mBfEvalExprFlags = (BfEvalExprFlags)(mBfEvalExprFlags | BfEvalExprFlags_ConstExpr);
|
||||
|
||||
// Handle the 'int[?] val = .(1, 2, 3)' case
|
||||
if ((flags & BfConstResolveFlag_ArrayInitSize) != 0)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "BfDeferEvalChecker.h"
|
||||
#include "BfVarDeclChecker.h"
|
||||
#include "BfFixits.h"
|
||||
#include "CeMachine.h"
|
||||
|
||||
#pragma warning(pop)
|
||||
#pragma warning(disable:4996)
|
||||
|
@ -4981,6 +4982,20 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
return result;
|
||||
}
|
||||
|
||||
if (mModule->mCompiler->mCEMachine != NULL)
|
||||
{
|
||||
if (mModule->mIsConstModule)
|
||||
{
|
||||
mModule->mCompiler->mCEMachine->QueueMethod(methodInstance);
|
||||
}
|
||||
else if ((mBfEvalExprFlags & BfEvalExprFlags_ConstExpr) != 0)
|
||||
{
|
||||
auto constRet = mModule->mCompiler->mCEMachine->Call(mModule, methodInstance, irArgs, CeEvalFlags_None);
|
||||
if (constRet)
|
||||
return constRet;
|
||||
}
|
||||
}
|
||||
|
||||
if (((!func) && (methodInstance->mIsUnspecialized)) || (mModule->mBfIRBuilder->mIgnoreWrites))
|
||||
{
|
||||
// We don't actually submit method calls for unspecialized methods
|
||||
|
@ -5205,6 +5220,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
|
|||
else
|
||||
{
|
||||
callInst = mModule->mBfIRBuilder->CreateCall(funcCallInst, irArgs);
|
||||
|
||||
if ((hasResult) && (!methodDef->mName.IsEmpty()) && (!methodInstance->mIsIntrinsic))
|
||||
mModule->mBfIRBuilder->SetName(callInst, methodDef->mName);
|
||||
}
|
||||
|
@ -11896,7 +11912,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
mModule->mCompiler->mResolvePassData->mGetSymbolReferenceKind = prevSymbolRefKind;
|
||||
}
|
||||
mModule->mBfIRBuilder->RestoreDebugLocation();
|
||||
if (mModule->mCompiler->IsSkippingExtraResolveChecks())
|
||||
if (mModule->IsSkippingExtraResolveChecks())
|
||||
closureFunc = BfIRFunction();
|
||||
|
||||
BfIRFunction dtorFunc;
|
||||
|
@ -11937,7 +11953,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
|
|||
// mModule->ProcessMethod(dtorMethodInstance);
|
||||
}
|
||||
mModule->mBfIRBuilder->RestoreDebugLocation();
|
||||
if (mModule->mCompiler->IsSkippingExtraResolveChecks())
|
||||
if (mModule->IsSkippingExtraResolveChecks())
|
||||
dtorFunc = BfIRFunction();
|
||||
|
||||
if (dtorMethodInstance->mIsReified)
|
||||
|
@ -13699,7 +13715,7 @@ BfModuleMethodInstance BfExprEvaluator::GetSelectedMethod(BfAstNode* targetSrc,
|
|||
{
|
||||
methodInstance = mModule->GetMethodInstance(curTypeInst, methodDef, resolvedGenericArguments, flags, foreignType);
|
||||
}
|
||||
if (mModule->mCompiler->IsSkippingExtraResolveChecks())
|
||||
if (mModule->IsSkippingExtraResolveChecks())
|
||||
{
|
||||
//BF_ASSERT(methodInstance.mFunc == NULL);
|
||||
}
|
||||
|
|
|
@ -1175,6 +1175,7 @@ BfIRBuilder::BfIRBuilder(BfModule* module) : BfIRConstHolder(module)
|
|||
mModule = module;
|
||||
mHasDebugLoc = false;
|
||||
mHasDebugInfo = false;
|
||||
mHasDebugLineInfo = false;
|
||||
mIRCodeGen = NULL;
|
||||
#ifdef BF_PLATFORM_WINDOWS
|
||||
mBeIRCodeGen = NULL;
|
||||
|
@ -4895,6 +4896,7 @@ void BfIRBuilder::CreateObjectAccessCheck(BfIRValue value, bool useAsm)
|
|||
void BfIRBuilder::DbgInit()
|
||||
{
|
||||
mHasDebugInfo = true;
|
||||
mHasDebugLineInfo = true;
|
||||
WriteCmd(BfIRCmd_DbgInit);
|
||||
NEW_CMD_INSERTED;
|
||||
}
|
||||
|
@ -4920,6 +4922,11 @@ bool BfIRBuilder::DbgHasInfo()
|
|||
return mHasDebugInfo;
|
||||
}
|
||||
|
||||
bool BfIRBuilder::DbgHasLineInfo()
|
||||
{
|
||||
return mHasDebugLineInfo;
|
||||
}
|
||||
|
||||
String BfIRBuilder::DbgGetStaticFieldName(BfFieldInstance* fieldInstance)
|
||||
{
|
||||
String fieldName;
|
||||
|
|
|
@ -920,6 +920,7 @@ public:
|
|||
BfIRBlock mInsertBlock;
|
||||
bool mHasDebugLoc;
|
||||
bool mHasDebugInfo;
|
||||
bool mHasDebugLineInfo;
|
||||
Dictionary<BfMethodInstance*, BfIRFunctionType> mMethodTypeMap;
|
||||
Dictionary<String, BfIRFunction> mFunctionMap;
|
||||
Dictionary<BfType*, BfIRPopulateType> mTypeMap;
|
||||
|
@ -1243,6 +1244,7 @@ public:
|
|||
void DbgInit();
|
||||
void DbgFinalize();
|
||||
bool DbgHasInfo();
|
||||
bool DbgHasLineInfo();
|
||||
String DbgGetStaticFieldName(BfFieldInstance* fieldInstance);
|
||||
void DbgAddPrefix(String& name);
|
||||
BfIRMDNode DbgCreateCompileUnit(int lang, const StringImpl& filename, const StringImpl& directory, const StringImpl& producer, bool isOptimized,
|
||||
|
|
|
@ -828,6 +828,7 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName)
|
|||
mIsReified = true;
|
||||
mReifyQueued = false;
|
||||
mIsSpecialModule = false;
|
||||
mIsConstModule = false;
|
||||
mIsScratchModule = false;
|
||||
mIsSpecializedMethodModuleRoot = false; // There may be mNextAltModules extending from this
|
||||
mHadBuildError = false;
|
||||
|
@ -996,7 +997,11 @@ void BfModule::FinishInit()
|
|||
|
||||
mHasFullDebugInfo = moduleOptions.mEmitDebugInfo == 1;
|
||||
|
||||
if ((!mCompiler->mIsResolveOnly) && (!mIsScratchModule) && (moduleOptions.mEmitDebugInfo != 0) && (mIsReified))
|
||||
if (mIsConstModule)
|
||||
mHasFullDebugInfo = false;
|
||||
|
||||
if (((!mCompiler->mIsResolveOnly) && (!mIsScratchModule) && (moduleOptions.mEmitDebugInfo != 0) && (mIsReified)) ||
|
||||
(mIsConstModule))
|
||||
{
|
||||
mBfIRBuilder->DbgInit();
|
||||
}
|
||||
|
@ -2357,7 +2362,7 @@ BfFileInstance* BfModule::GetFileFromNode(BfAstNode* astNode)
|
|||
|
||||
BfLogSysM("GetFileFromNode new file. Mod: %p FileInstance: %p Parser: %p\n", this, bfFileInstance, bfParser);
|
||||
|
||||
if ((mBfIRBuilder != NULL) && (mBfIRBuilder->DbgHasInfo()))
|
||||
if ((mBfIRBuilder != NULL) && (mBfIRBuilder->DbgHasLineInfo()))
|
||||
{
|
||||
String fileName = bfParser->mFileName;
|
||||
|
||||
|
@ -2435,7 +2440,7 @@ void BfModule::UpdateSrcPos(BfAstNode* astNode, BfSrcPosFlags flags, int debugLo
|
|||
}
|
||||
|
||||
//TODO: if we bail on the "mCurMethodState == NULL" case then we don't get it set during type declarations
|
||||
if (((flags & BfSrcPosFlag_NoSetDebugLoc) == 0) && (mBfIRBuilder->DbgHasInfo()) && (mCurMethodState != NULL))
|
||||
if (((flags & BfSrcPosFlag_NoSetDebugLoc) == 0) && (mBfIRBuilder->DbgHasLineInfo()) && (mCurMethodState != NULL))
|
||||
{
|
||||
int column = mCurFilePosition.mCurColumn + 1;
|
||||
if ((mCurMethodInstance != NULL) && (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_CtorCalcAppend))
|
||||
|
@ -2472,6 +2477,9 @@ void BfModule::UpdateSrcPos(BfAstNode* astNode, BfSrcPosFlags flags, int debugLo
|
|||
auto inlineAt = mCurMethodState->mCurScope->mDIInlinedAt;
|
||||
if (mCurMethodState->mCrossingMixin)
|
||||
inlineAt = BfIRMDNode();
|
||||
|
||||
if (!useDIScope)
|
||||
useDIScope = wantDIFile;
|
||||
mBfIRBuilder->SetCurrentDebugLocation(mCurFilePosition.mCurLine + 1, column, useDIScope, inlineAt);
|
||||
if ((flags & BfSrcPosFlag_Expression) == 0)
|
||||
mBfIRBuilder->CreateStatementStart();
|
||||
|
@ -2686,6 +2694,13 @@ void BfModule::SetFail()
|
|||
}
|
||||
}
|
||||
|
||||
bool BfModule::IsSkippingExtraResolveChecks()
|
||||
{
|
||||
if (mIsConstModule)
|
||||
return false;
|
||||
return mCompiler->IsSkippingExtraResolveChecks();
|
||||
}
|
||||
|
||||
BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPersistent)
|
||||
{
|
||||
BP_ZONE("BfModule::Fail");
|
||||
|
@ -3488,7 +3503,7 @@ BfModuleOptions BfModule::GetModuleOptions()
|
|||
while (headModule->mParentModule != NULL)
|
||||
headModule = headModule->mParentModule;
|
||||
|
||||
BF_ASSERT((headModule->mOwnedTypeInstances.size() > 0) || (mModuleName == "vdata"));
|
||||
BF_ASSERT((headModule->mOwnedTypeInstances.size() > 0) || (mModuleName == "vdata") || mIsSpecialModule);
|
||||
|
||||
if (headModule->mOwnedTypeInstances.size() > 0)
|
||||
{
|
||||
|
@ -9092,7 +9107,7 @@ bool BfModule::IsOptimized()
|
|||
bool BfModule::IsTargetingBeefBackend()
|
||||
{
|
||||
if (mProject == NULL)
|
||||
return false;
|
||||
return true;
|
||||
return GetModuleOptions().mOptLevel == BfOptLevel_OgPlus;
|
||||
}
|
||||
|
||||
|
@ -9679,7 +9694,7 @@ BfModule* BfModule::GetSpecializedMethodModule(const SizedArrayImpl<BfProject*>&
|
|||
|
||||
BfIRValue BfModule::CreateFunctionFrom(BfMethodInstance* methodInstance, bool tryExisting, bool isInlined)
|
||||
{
|
||||
if (mCompiler->IsSkippingExtraResolveChecks())
|
||||
if (IsSkippingExtraResolveChecks())
|
||||
return BfIRValue();
|
||||
|
||||
if (methodInstance->mMethodInstanceGroup->mOwner->IsInterface())
|
||||
|
@ -11953,7 +11968,7 @@ BfModuleMethodInstance BfModule::ReferenceExternalMethodInstance(BfMethodInstanc
|
|||
if ((mBfIRBuilder->mIgnoreWrites) || ((flags & BfGetMethodInstanceFlag_Unreified) != 0))
|
||||
return BfModuleMethodInstance(methodInstance, mBfIRBuilder->GetFakeVal());
|
||||
|
||||
if (mCompiler->IsSkippingExtraResolveChecks())
|
||||
if (IsSkippingExtraResolveChecks())
|
||||
return BfModuleMethodInstance(methodInstance, BfIRFunction());
|
||||
|
||||
if (methodInstance->mMethodDef->mMethodType == BfMethodType_Mixin)
|
||||
|
@ -12668,7 +12683,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
|||
}
|
||||
}
|
||||
|
||||
if (mCompiler->IsSkippingExtraResolveChecks())
|
||||
if (IsSkippingExtraResolveChecks())
|
||||
return BfModuleMethodInstance(methodInstance, BfIRFunction());
|
||||
else
|
||||
{
|
||||
|
@ -12892,7 +12907,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
|||
ProcessMethod(methodInstance);
|
||||
}
|
||||
|
||||
if (mCompiler->IsSkippingExtraResolveChecks())
|
||||
if (IsSkippingExtraResolveChecks())
|
||||
return BfModuleMethodInstance(methodInstance, BfIRFunction());
|
||||
|
||||
if (methodInstance->mDeclModule != this)
|
||||
|
@ -15089,13 +15104,13 @@ void BfModule::EmitDtorBody()
|
|||
if (checkBaseType->mTypeDef->mDtorDef != NULL)
|
||||
{
|
||||
auto dtorMethodInstance = GetMethodInstance(checkBaseType, checkBaseType->mTypeDef->mDtorDef, BfTypeVector());
|
||||
if (mCompiler->IsSkippingExtraResolveChecks())
|
||||
if (IsSkippingExtraResolveChecks())
|
||||
{
|
||||
// Nothing
|
||||
}
|
||||
else if (dtorMethodInstance.mMethodInstance->GetParamCount() == 0)
|
||||
{
|
||||
if ((!mCompiler->IsSkippingExtraResolveChecks()) && (!checkBaseType->IsUnspecializedType()))
|
||||
if ((!IsSkippingExtraResolveChecks()) && (!checkBaseType->IsUnspecializedType()))
|
||||
{
|
||||
auto basePtr = mBfIRBuilder->CreateBitCast(mCurMethodState->mLocals[0]->mValue, mBfIRBuilder->MapTypeInstPtr(checkBaseType));
|
||||
SizedArray<BfIRValue, 1> vals = { basePtr };
|
||||
|
@ -17932,6 +17947,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
|||
BfIRMDNode(), flags, IsOptimized(), llvmFunction, genericArgs, genericConstValueArgs);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
methodState.mDIFile = mCurFilePosition.mFileInstance->mDIFile;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -20351,6 +20370,7 @@ void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& man
|
|||
if (!mCurMethodInstance->mIRFunction)
|
||||
{
|
||||
BfLogSysM("Function collision from inner override erased prevFunc %p: %d\n", methodInstance, prevFunc.mId);
|
||||
if (!mIsConstModule)
|
||||
mBfIRBuilder->Func_SafeRename(prevFunc);
|
||||
}
|
||||
}
|
||||
|
@ -20374,6 +20394,7 @@ void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& man
|
|||
else
|
||||
{
|
||||
BfLogSysM("Function collision erased prevFunc %p: %d\n", methodInstance, prevFunc.mId);
|
||||
if (!mIsConstModule)
|
||||
mBfIRBuilder->Func_SafeRename(prevFunc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ enum BfEvalExprFlags
|
|||
BfEvalExprFlags_AllowNonConst = 0x10000,
|
||||
BfEvalExprFlags_StringInterpolateFormat = 0x20000,
|
||||
BfEvalExprFlags_NoLookupError = 0x40000,
|
||||
BfEvalExprFlags_ConstExpr = 0x80000,
|
||||
};
|
||||
|
||||
enum BfCastFlags
|
||||
|
@ -1442,6 +1443,7 @@ public:
|
|||
bool mWantsIRIgnoreWrites;
|
||||
bool mHasGenericMethods;
|
||||
bool mIsSpecialModule; // vdata, unspecialized, external
|
||||
bool mIsConstModule;
|
||||
bool mIsScratchModule;
|
||||
bool mIsSpecializedMethodModuleRoot;
|
||||
bool mIsModuleMutable; // Set to false after writing module to disk, can be set back to true after doing extension module
|
||||
|
@ -1472,6 +1474,7 @@ public:
|
|||
bool CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* memberOwner, BfProject* memberProject, BfProtection memberProtection, BfTypeInstance* lookupStartType);
|
||||
void SetElementType(BfAstNode* astNode, BfSourceElementType elementType);
|
||||
void SetFail();
|
||||
bool IsSkippingExtraResolveChecks();
|
||||
BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false);
|
||||
BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL);
|
||||
BfError* FailAfter(const StringImpl& error, BfAstNode* refNode);
|
||||
|
|
|
@ -11031,7 +11031,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
|
||||
SizedArray<BfIRValue, 1> args;
|
||||
exprEvaluator.PushArg(castedFromValue, args);
|
||||
operatorOut = exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, mCompiler->IsSkippingExtraResolveChecks() ? BfIRValue() : moduleMethodInstance.mFunc, false, args);
|
||||
operatorOut = exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, IsSkippingExtraResolveChecks() ? BfIRValue() : moduleMethodInstance.mFunc, false, args);
|
||||
if ((operatorOut.mType != NULL) && (operatorOut.mType->IsSelf()))
|
||||
{
|
||||
BF_ASSERT(IsInGeneric());
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "BfMangler.h"
|
||||
#include "BfConstResolver.h"
|
||||
#include "BfModule.h"
|
||||
#include "CeMachine.h"
|
||||
#include "BeefySysLib/util/BeefPerf.h"
|
||||
|
||||
#pragma warning(disable:4996)
|
||||
|
@ -557,6 +558,12 @@ BfMethodInstance::~BfMethodInstance()
|
|||
}
|
||||
|
||||
delete mMethodInfoEx;
|
||||
|
||||
if (mInCEMachine)
|
||||
{
|
||||
auto module = GetOwner()->mModule;
|
||||
module->mCompiler->mCEMachine->RemoveMethod(this);
|
||||
}
|
||||
}
|
||||
|
||||
BfImportKind BfMethodInstance::GetImportKind()
|
||||
|
|
|
@ -817,6 +817,7 @@ public:
|
|||
bool mHasMethodRefType:1;
|
||||
bool mDisallowCalling:1;
|
||||
bool mIsInnerOverride:1;
|
||||
bool mInCEMachine:1;
|
||||
BfMethodChainType mChainType;
|
||||
BfCallingConvention mCallingConvention;
|
||||
BfMethodInstanceGroup* mMethodInstanceGroup;
|
||||
|
@ -853,6 +854,7 @@ public:
|
|||
mHasMethodRefType = false;
|
||||
mDisallowCalling = false;
|
||||
mIsInnerOverride = false;
|
||||
mInCEMachine = false;
|
||||
mChainType = BfMethodChainType_None;
|
||||
mCallingConvention = BfCallingConvention_Unspecified;
|
||||
mMethodInstanceGroup = NULL;
|
||||
|
|
|
@ -3950,7 +3950,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
|
|||
if (!mCompiler->IsAutocomplete())
|
||||
AssertErrorState();
|
||||
}
|
||||
else if (!mCompiler->IsSkippingExtraResolveChecks())
|
||||
else if (!IsSkippingExtraResolveChecks())
|
||||
{
|
||||
BfMethodInstance* methodInstance = objectType->mVirtualMethodTable[mCompiler->GetVTableMethodOffset() + 0].mImplementingMethod;
|
||||
BF_ASSERT(methodInstance->mMethodDef->mName == "~this");
|
||||
|
@ -5998,7 +5998,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
|||
SizedArray<BfIRValue, 1> args;
|
||||
auto castedTarget = Cast(forEachStmt->mCollectionExpression, target, getEnumeratorMethod.mMethodInstance->GetOwner());
|
||||
exprEvaluator.PushThis(forEachStmt->mCollectionExpression, castedTarget, getEnumeratorMethod.mMethodInstance, args);
|
||||
itr = exprEvaluator.CreateCall(getEnumeratorMethod.mMethodInstance, mCompiler->IsSkippingExtraResolveChecks() ? BfIRValue() : getEnumeratorMethod.mFunc, false, args);
|
||||
itr = exprEvaluator.CreateCall(getEnumeratorMethod.mMethodInstance, IsSkippingExtraResolveChecks() ? BfIRValue() : getEnumeratorMethod.mFunc, false, args);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1990
IDEHelper/Compiler/CeMachine.cpp
Normal file
1990
IDEHelper/Compiler/CeMachine.cpp
Normal file
File diff suppressed because it is too large
Load diff
333
IDEHelper/Compiler/CeMachine.h
Normal file
333
IDEHelper/Compiler/CeMachine.h
Normal file
|
@ -0,0 +1,333 @@
|
|||
#pragma once
|
||||
|
||||
#include "BfSystem.h"
|
||||
#include "BfModule.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
class BfMethodInstance;
|
||||
class BeDbgLoc;
|
||||
class BeType;
|
||||
class BeValue;
|
||||
class BeInst;
|
||||
class BeDbgFile;
|
||||
class BePhiInst;
|
||||
class BeFunction;
|
||||
class BeSwitchInst;
|
||||
class CeMachine;
|
||||
class CeFunction;
|
||||
|
||||
#define CEOP_SIZED(OPNAME) \
|
||||
CeOp_##OPNAME##_8, \
|
||||
CeOp_##OPNAME##_16, \
|
||||
CeOp_##OPNAME##_32, \
|
||||
CeOp_##OPNAME##_64, \
|
||||
CeOp_##OPNAME##_X
|
||||
|
||||
#define CEOP_SIZED_NUMERIC(OPNAME) \
|
||||
CeOp_##OPNAME##_I8, \
|
||||
CeOp_##OPNAME##_I16, \
|
||||
CeOp_##OPNAME##_I32, \
|
||||
CeOp_##OPNAME##_I64
|
||||
|
||||
#define CEOP_SIZED_NUMERIC_PLUSF(OPNAME) \
|
||||
CeOp_##OPNAME##_I8, \
|
||||
CeOp_##OPNAME##_I16, \
|
||||
CeOp_##OPNAME##_I32, \
|
||||
CeOp_##OPNAME##_I64, \
|
||||
CeOp_##OPNAME##_F32, \
|
||||
CeOp_##OPNAME##_F64
|
||||
|
||||
enum CeOp : int16
|
||||
{
|
||||
CeOp_InvalidOp,
|
||||
CeOp_Ret,
|
||||
CeOp_Jmp,
|
||||
CeOp_JmpIf,
|
||||
CeOp_JmpIfNot,
|
||||
|
||||
CeOp_FrameAddr32,
|
||||
CeOp_FrameAddr64,
|
||||
|
||||
CEOP_SIZED(Const),
|
||||
CEOP_SIZED(Load),
|
||||
CEOP_SIZED(Store),
|
||||
CEOP_SIZED(Move),
|
||||
CEOP_SIZED(Push),
|
||||
|
||||
CeOp_AdjustSP,
|
||||
CeOp_Call,
|
||||
|
||||
CeOp_Conv_I32_I64,
|
||||
|
||||
CEOP_SIZED_NUMERIC_PLUSF(Add),
|
||||
CEOP_SIZED_NUMERIC_PLUSF(Cmp_EQ),
|
||||
CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT),
|
||||
|
||||
CEOP_SIZED_NUMERIC_PLUSF(Neg),
|
||||
|
||||
CeOp_COUNT
|
||||
};
|
||||
|
||||
struct CeEmitEntry
|
||||
{
|
||||
int mCodePos;
|
||||
int mFile;
|
||||
int mLine;
|
||||
int mColumn;
|
||||
};
|
||||
|
||||
class CeCallEntry
|
||||
{
|
||||
public:
|
||||
String mFunctionName;
|
||||
int mBindRevision;
|
||||
CeFunction* mFunction;
|
||||
|
||||
public:
|
||||
CeCallEntry()
|
||||
{
|
||||
mBindRevision = -1;
|
||||
mFunction = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class CeFunction
|
||||
{
|
||||
public:
|
||||
BfMethodInstance* mMethodInstance;
|
||||
String mName;
|
||||
bool mInitialized;
|
||||
bool mFailed;
|
||||
Array<uint8> mCode;
|
||||
Array<String> mFiles;
|
||||
Array<CeEmitEntry> mEmitTable;
|
||||
Array<CeCallEntry> mCallTable;
|
||||
String mGenError;
|
||||
int mFrameSize;
|
||||
|
||||
public:
|
||||
CeFunction()
|
||||
{
|
||||
mInitialized = false;
|
||||
mMethodInstance = NULL;
|
||||
mFailed = false;
|
||||
mFrameSize = 0;
|
||||
}
|
||||
};
|
||||
|
||||
enum CeEvalFlags
|
||||
{
|
||||
CeEvalFlags_None = 0
|
||||
};
|
||||
|
||||
enum CeOperandKind
|
||||
{
|
||||
CeOperandKind_None,
|
||||
CeOperandKind_FrameOfs,
|
||||
CeOperandKind_AllocaAddr,
|
||||
CeOperandKind_Block,
|
||||
};
|
||||
|
||||
class CeOperand
|
||||
{
|
||||
public:
|
||||
CeOperandKind mKind;
|
||||
union
|
||||
{
|
||||
int mFrameOfs;
|
||||
int mBlockIdx;
|
||||
};
|
||||
BeType* mType;
|
||||
|
||||
public:
|
||||
CeOperand()
|
||||
{
|
||||
mKind = CeOperandKind_None;
|
||||
mFrameOfs = 0;
|
||||
mType = NULL;
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return mKind != CeOperandKind_None;
|
||||
}
|
||||
};
|
||||
|
||||
#define BF_CE_STACK_SIZE 1024*1024
|
||||
|
||||
enum CeOperandInfoKind
|
||||
{
|
||||
CEOI_None,
|
||||
CEOI_FrameRef,
|
||||
CEOI_IMM8,
|
||||
CEOI_IMM16,
|
||||
CEOI_IMM32,
|
||||
CEOI_IMM64,
|
||||
CEOI_IMM_VAR,
|
||||
CEOI_JMPREL
|
||||
};
|
||||
|
||||
enum CeSizeClass
|
||||
{
|
||||
CeSizeClass_8,
|
||||
CeSizeClass_16,
|
||||
CeSizeClass_32,
|
||||
CeSizeClass_64,
|
||||
CeSizeClass_X,
|
||||
};
|
||||
|
||||
class CeDumpContext
|
||||
{
|
||||
|
||||
|
||||
public:
|
||||
CeFunction* mCeFunction;
|
||||
String mStr;
|
||||
uint8* mStart;
|
||||
uint8* mPtr;
|
||||
uint8* mEnd;
|
||||
|
||||
public:
|
||||
void DumpOperandInfo(CeOperandInfoKind operandInfoKind);
|
||||
|
||||
void Dump();
|
||||
};
|
||||
|
||||
struct CePhiOutgoing
|
||||
{
|
||||
BeValue* mPhiValue;
|
||||
BePhiInst* mPhiInst;
|
||||
int mPhiBlockIdx;
|
||||
};
|
||||
|
||||
class CeBlock
|
||||
{
|
||||
public:
|
||||
int mEmitOfs;
|
||||
Array<CePhiOutgoing> mPhiOutgoing;
|
||||
|
||||
public:
|
||||
CeBlock()
|
||||
{
|
||||
mEmitOfs = -1;
|
||||
}
|
||||
};
|
||||
|
||||
class CeJumpEntry
|
||||
{
|
||||
public:
|
||||
int mEmitPos;
|
||||
int mBlockIdx;
|
||||
};
|
||||
|
||||
class CeBuilder
|
||||
{
|
||||
public:
|
||||
CeMachine* mCeMachine;
|
||||
CeFunction* mCeFunction;
|
||||
BeFunction* mBeFunction;
|
||||
CeOperand mReturnVal;
|
||||
BeType* mIntPtrType;
|
||||
int mPtrSize;
|
||||
|
||||
String mError;
|
||||
BeDbgLoc* mCurDbgLoc;
|
||||
Array<CeBlock> mBlocks;
|
||||
Array<CeJumpEntry> mJumpTable;
|
||||
Dictionary<BeValue*, CeOperand> mValueToOperand;
|
||||
int mFrameSize;
|
||||
Dictionary<BeDbgFile*, int> mDbgFileMap;
|
||||
Dictionary<BeFunction*, int> mFunctionMap;
|
||||
|
||||
public:
|
||||
CeBuilder()
|
||||
{
|
||||
mPtrSize = 0;
|
||||
mCeFunction = NULL;
|
||||
mBeFunction = NULL;
|
||||
mCeMachine = NULL;
|
||||
mCurDbgLoc = NULL;
|
||||
mFrameSize = 0;
|
||||
}
|
||||
|
||||
void Fail(const StringImpl& error);
|
||||
|
||||
CeOperand FrameAlloc(BeType* type);
|
||||
CeOperand GetOperand(BeValue* value, bool allowAlloca = false);
|
||||
CeSizeClass GetSizeClass(int size);
|
||||
int GetCodePos();
|
||||
|
||||
void HandleParams();
|
||||
|
||||
void Emit(uint8 val);
|
||||
void Emit(CeOp val);
|
||||
void Emit(int32 val);
|
||||
void Emit(bool val);
|
||||
void Emit(void* ptr, int size);
|
||||
void EmitJump(CeOp op, const CeOperand& block);
|
||||
void EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx);
|
||||
|
||||
void EmitFrameOffset(const CeOperand& val);
|
||||
void FlushPhi(CeBlock* ceBlock, int targetBlockIdx);
|
||||
|
||||
void EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeOperand& rhs, CeOperand& result);
|
||||
void EmitUnaryOp(CeOp iOp, CeOp fOp, const CeOperand& val, CeOperand& result);
|
||||
void EmitSizedOp(CeOp op, const CeOperand& operand, CeOperand* result, bool allowNonStdSize);
|
||||
void Build();
|
||||
};
|
||||
|
||||
class CeFrame
|
||||
{
|
||||
public:
|
||||
CeFunction* mFunction;
|
||||
uint8* mStackPtr;
|
||||
uint8* mFramePtr;
|
||||
uint8* mInstPtr;
|
||||
|
||||
public:
|
||||
CeFrame()
|
||||
{
|
||||
mFunction = NULL;
|
||||
mStackPtr = NULL;
|
||||
mFramePtr = NULL;
|
||||
mInstPtr = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
class CeMachine
|
||||
{
|
||||
public:
|
||||
Dictionary<BfMethodInstance*, CeFunction*> mFunctions;
|
||||
Dictionary<String, CeFunction*> mNamedFunctionMap;
|
||||
BfCompiler* mCompiler;
|
||||
BfModule* mCeModule;
|
||||
int mRevision;
|
||||
|
||||
Array<CeFrame> mCallStack;
|
||||
Array<uint8> mMemory;
|
||||
uint8* mStackMin;
|
||||
Array<CeFunction*> mWorkQueue;
|
||||
|
||||
public:
|
||||
CeMachine(BfCompiler* compiler);
|
||||
~CeMachine();
|
||||
|
||||
void Init();
|
||||
void RemoveMethod(BfMethodInstance* methodInstance);
|
||||
int GetConstantSize(BfConstant* constant);
|
||||
void WriteConstant(uint8* ptr, BfConstant* constant);
|
||||
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
|
||||
bool Execute();
|
||||
|
||||
void PrepareFunction(CeFunction* methodInstance);
|
||||
void ProcessWorkQueue();
|
||||
CeFunction* GetFunction(BfMethodInstance* methodInstance);
|
||||
|
||||
public:
|
||||
void CompileStarted();
|
||||
void QueueMethod(BfMethodInstance* methodInstance);
|
||||
BfTypedValue Call(BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags);
|
||||
};
|
||||
|
||||
NS_BF_END
|
|
@ -331,6 +331,7 @@
|
|||
<ClCompile Include="Compiler\BfTargetTriple.cpp" />
|
||||
<ClCompile Include="Compiler\BfUtil.cpp" />
|
||||
<ClCompile Include="Compiler\BfVarDeclChecker.cpp" />
|
||||
<ClCompile Include="Compiler\CeMachine.cpp" />
|
||||
<ClCompile Include="Compiler\MemReporter.cpp" />
|
||||
<ClCompile Include="DbgMiniDump.cpp" />
|
||||
<ClCompile Include="Debugger.cpp" />
|
||||
|
@ -398,6 +399,7 @@
|
|||
<ClInclude Include="Compiler\BfCompiler.h" />
|
||||
<ClInclude Include="Compiler\BfUtil.h" />
|
||||
<ClInclude Include="Compiler\BfVarDeclChecker.h" />
|
||||
<ClInclude Include="Compiler\CeMachine.h" />
|
||||
<ClInclude Include="Compiler\MemReporter.h" />
|
||||
<ClInclude Include="DbgMiniDump.h" />
|
||||
<ClInclude Include="Debugger.h" />
|
||||
|
|
|
@ -208,6 +208,9 @@
|
|||
<ClCompile Include="Compiler\BfNamespaceVisitor.cpp">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Compiler\CeMachine.cpp">
|
||||
<Filter>Compiler</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Compiler\BfAst.h">
|
||||
|
@ -393,5 +396,8 @@
|
|||
<Filter>Compiler</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Compiler\BfNamespaceVisitor.h" />
|
||||
<ClInclude Include="Compiler\CeMachine.h">
|
||||
<Filter>Compiler</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
Loading…
Add table
Add a link
Reference in a new issue