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

Start of compile-time function evaluation

This commit is contained in:
Brian Fiete 2020-12-13 08:04:42 -08:00
parent 350516fae3
commit 577e199dcd
17 changed files with 2437 additions and 29 deletions

View file

@ -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"

View file

@ -29,6 +29,7 @@
#include "BeefySysLib/util/BeefPerf.h"
#include "../LLVMUtils.h"
#include "BfNamespaceVisitor.h"
#include "CeMachine.h"
#pragma warning(pop)
@ -357,7 +358,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
//mMaxInterfaceSlots = 16;
mMaxInterfaceSlots = -1;
mInterfaceSlotCountChanged = false;
mHSPreserveIdx = 0;
mCompileLogFP = NULL;
mWantsDeferMethodDecls = false;
@ -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)

View file

@ -41,6 +41,7 @@ class BfAutoComplete;
class BfMethodInstance;
class BfSourceClassifier;
class BfResolvePassData;
class CeMachine;
enum BfCompileOnDemandKind
{
@ -171,9 +172,9 @@ public:
mUseDebugBackingParams = true;
mAllocStackCount = 1;
mExtraResolveChecks = false;
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;

View file

@ -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)
{

View file

@ -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
@ -5182,7 +5197,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
if (returnType->IsComposite())
mModule->mBfIRBuilder->PopulateType(returnType);
BfIRValue callInst;
int callIRArgCount = (int)irArgs.size();
if (sret != NULL)
@ -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);
}

View file

@ -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;

View file

@ -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,

View file

@ -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;
@ -995,8 +996,12 @@ void BfModule::FinishInit()
}
mHasFullDebugInfo = moduleOptions.mEmitDebugInfo == 1;
if (mIsConstModule)
mHasFullDebugInfo = false;
if ((!mCompiler->mIsResolveOnly) && (!mIsScratchModule) && (moduleOptions.mEmitDebugInfo != 0) && (mIsReified))
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,7 +20370,8 @@ void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& man
if (!mCurMethodInstance->mIRFunction)
{
BfLogSysM("Function collision from inner override erased prevFunc %p: %d\n", methodInstance, prevFunc.mId);
mBfIRBuilder->Func_SafeRename(prevFunc);
if (!mIsConstModule)
mBfIRBuilder->Func_SafeRename(prevFunc);
}
}
else if (methodDef->mIsExtern)
@ -20374,7 +20394,8 @@ void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& man
else
{
BfLogSysM("Function collision erased prevFunc %p: %d\n", methodInstance, prevFunc.mId);
mBfIRBuilder->Func_SafeRename(prevFunc);
if (!mIsConstModule)
mBfIRBuilder->Func_SafeRename(prevFunc);
}
}
}

View file

@ -69,6 +69,7 @@ enum BfEvalExprFlags
BfEvalExprFlags_AllowNonConst = 0x10000,
BfEvalExprFlags_StringInterpolateFormat = 0x20000,
BfEvalExprFlags_NoLookupError = 0x40000,
BfEvalExprFlags_ConstExpr = 0x80000,
};
enum BfCastFlags
@ -1383,7 +1384,7 @@ public:
// SpecializedModules contain method specializations with types that come from other projects
Dictionary<Array<BfProject*>, BfModule*> mSpecializedMethodModules;
BfModule* mParentModule;
BfModule* mNextAltModule; // Linked
BfModule* mNextAltModule; // Linked
BfModuleOptions* mModuleOptions; // Only in altModules
BfSystem* mSystem;
@ -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);

View file

@ -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());

View file

@ -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)
@ -533,9 +534,9 @@ BfMethodInfoEx::~BfMethodInfoEx()
}
BfMethodInstance::~BfMethodInstance()
{
{
if (mHasMethodRefType)
{
{
auto module = GetOwner()->mModule;
if (!module->mContext->mDeleting)
{
@ -554,9 +555,15 @@ BfMethodInstance::~BfMethodInstance()
{
mHotMethod->mFlags = (BfHotDepDataFlags)(mHotMethod->mFlags & ~BfHotDepDataFlag_IsBound);
mHotMethod->Deref();
}
}
delete mMethodInfoEx;
if (mInCEMachine)
{
auto module = GetOwner()->mModule;
module->mCompiler->mCEMachine->RemoveMethod(this);
}
}
BfImportKind BfMethodInstance::GetImportKind()

View file

@ -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;

View file

@ -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);
}
}

File diff suppressed because it is too large Load diff

View 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

View file

@ -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" />

View file

@ -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>