mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Fleshing out comptime debugging
This commit is contained in:
parent
ff2e40e3bf
commit
b334423106
28 changed files with 2079 additions and 780 deletions
|
@ -93,7 +93,7 @@ namespace System.Reflection
|
|||
.Double:
|
||||
let attrData = Decode!<int64>(data);
|
||||
args[argIdx] = scope:AttrBlock box attrData;
|
||||
case (TypeCode)typeof(TypeCode).MaxValue + 8: //BfConstType_TypeOf
|
||||
case (TypeCode)typeof(TypeCode).MaxValue + 9: //BfConstType_TypeOf
|
||||
let argTypeId = Decode!<int32>(data);
|
||||
args[argIdx] = Type.[Friend]GetType((.)argTypeId);
|
||||
case (TypeCode)255:
|
||||
|
|
|
@ -406,6 +406,9 @@ namespace System
|
|||
|
||||
public static void AddErrorHandler(ErrorHandler handler)
|
||||
{
|
||||
if (Compiler.IsComptime)
|
||||
return;
|
||||
|
||||
using (sMonitor.Val.Enter())
|
||||
{
|
||||
if (sErrorHandlers == null)
|
||||
|
@ -416,6 +419,9 @@ namespace System
|
|||
|
||||
public static Result<void> RemoveErrorHandler(ErrorHandler handler)
|
||||
{
|
||||
if (Compiler.IsComptime)
|
||||
return .Ok;
|
||||
|
||||
using (sMonitor.Val.Enter())
|
||||
{
|
||||
if (sErrorHandlers.RemoveStrict(handler))
|
||||
|
@ -426,6 +432,9 @@ namespace System
|
|||
|
||||
public static ErrorHandlerResult CheckErrorHandlers(Error error)
|
||||
{
|
||||
if (Compiler.IsComptime)
|
||||
return .ContinueFailure;
|
||||
|
||||
using (sMonitor.Val.Enter())
|
||||
{
|
||||
if (sInsideErrorHandler)
|
||||
|
|
|
@ -864,6 +864,7 @@
|
|||
<ClCompile Include="util\CabUtil.cpp" />
|
||||
<ClCompile Include="util\CatmullRom.cpp" />
|
||||
<ClCompile Include="util\ChunkedDataBuffer.cpp" />
|
||||
<ClCompile Include="util\Compress.cpp" />
|
||||
<ClCompile Include="util\CubicFuncSpline.cpp" />
|
||||
<ClCompile Include="util\CubicSpline.cpp" />
|
||||
<ClCompile Include="util\FileEnumerator.cpp" />
|
||||
|
@ -1025,6 +1026,7 @@
|
|||
<ClInclude Include="util\BSpline.h" />
|
||||
<ClInclude Include="util\CabUtil.h" />
|
||||
<ClInclude Include="util\CatmullRom.h" />
|
||||
<ClInclude Include="util\Compress.h" />
|
||||
<ClInclude Include="util\CritSect.h" />
|
||||
<ClInclude Include="util\CubicFuncSpline.h" />
|
||||
<ClInclude Include="util\CubicSpline.h" />
|
||||
|
|
|
@ -572,6 +572,9 @@
|
|||
<ClCompile Include="util\Heap.cpp">
|
||||
<Filter>src\util</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="util\Compress.cpp">
|
||||
<Filter>src\util</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Common.h">
|
||||
|
@ -877,6 +880,9 @@
|
|||
<ClInclude Include="util\Heap.h">
|
||||
<Filter>src\util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util\Compress.h">
|
||||
<Filter>src\util</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">
|
||||
|
|
|
@ -5644,7 +5644,7 @@ namespace IDE
|
|||
|
||||
subMenu = root.AddMenuItem("&Build");
|
||||
AddMenuItem(subMenu, "&Build Workspace", "Build Workspace", new => UpdateMenuItem_HasWorkspace);
|
||||
AddMenuItem(subMenu, "&Debug Comptime", "Debug Comptime", new => UpdateMenuItem_HasWorkspace);
|
||||
AddMenuItem(subMenu, "&Debug Comptime", "Debug Comptime", new => UpdateMenuItem_DebugStopped_HasWorkspace);
|
||||
AddMenuItem(subMenu, "&Clean", "Clean", new => UpdateMenuItem_DebugStopped_HasWorkspace);
|
||||
AddMenuItem(subMenu, "Clean Beef", "Clean Beef", new => UpdateMenuItem_DebugStopped_HasWorkspace);
|
||||
//subMenu.AddMenuItem("Compile Current File", null, new (menu) => { CompileCurrentFile(); });
|
||||
|
|
|
@ -796,7 +796,7 @@ namespace IDE.ui
|
|||
|
||||
//if (!vals[0].IsEmpty)
|
||||
String.NewOrSet!(valueSubItem.mLabel, vals[0]);
|
||||
if (vals[0] == "!sideeffects")
|
||||
if ((vals[0] == "!sideeffects") || (vals[0] == "!incomplete"))
|
||||
{
|
||||
if (useListViewItem.mWatchRefreshButton == null)
|
||||
{
|
||||
|
|
|
@ -246,6 +246,7 @@ namespace IDE.ui
|
|||
public override void Draw(Graphics g)
|
||||
{
|
||||
bool atError = gApp.mDebugger.GetRunState() == DebugManager.RunState.Exception;
|
||||
var debugState = gApp.mDebugger.GetRunState();
|
||||
|
||||
uint32 bkgColor = 0xFF404040;
|
||||
if (atError)
|
||||
|
@ -321,13 +322,13 @@ namespace IDE.ui
|
|||
|
||||
float statusLabelPos = (int)GS!(-1.3f);
|
||||
|
||||
if ((gApp.mDebugger?.mIsComptimeDebug == true) && (gApp.mDebugger.IsPaused()))
|
||||
{
|
||||
completionPct = null;
|
||||
}
|
||||
|
||||
//completionPct = 0.4f;
|
||||
if (completionPct.HasValue)
|
||||
if ((gApp.mDebugger?.mIsComptimeDebug == true) &&
|
||||
((gApp.mDebugger.IsPaused()) || (debugState == .DebugEval)))
|
||||
{
|
||||
g.DrawString("Debugging Comptime", GS!(200), statusLabelPos, FontAlign.Centered, GS!(120));
|
||||
}
|
||||
else if (completionPct.HasValue)
|
||||
{
|
||||
Rect completionRect = Rect(GS!(200), GS!(2), GS!(120), GS!(15));
|
||||
using (g.PushColor(0xFF000000))
|
||||
|
@ -336,10 +337,6 @@ namespace IDE.ui
|
|||
using (g.PushColor(0xFF00FF00))
|
||||
g.FillRect(completionRect.mX, completionRect.mY, completionRect.mWidth * completionPct.Value, completionRect.mHeight);
|
||||
}
|
||||
else if ((gApp.mDebugger?.mIsComptimeDebug == true) && (gApp.mDebugger.IsPaused()))
|
||||
{
|
||||
g.DrawString("Debugging Comptime", GS!(200), statusLabelPos, FontAlign.Centered, GS!(120));
|
||||
}
|
||||
else if ((gApp.mDebugger.mIsRunning) && (gApp.HaveSourcesChanged()))
|
||||
{
|
||||
Rect completionRect = Rect(GS!(200), GS!(1), GS!(120), GS!(17));
|
||||
|
|
|
@ -2207,11 +2207,6 @@ bool BeCOFFObject::Generate(BeModule* module, const StringImpl& fileName)
|
|||
|
||||
void BeCOFFObject::Finish()
|
||||
{
|
||||
if (mBeModule->mModuleName.Contains("vdata"))
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
BP_ZONE("BeCOFFObject::Finish");
|
||||
//AutoPerf perf("BeCOFFObject::Finish", mPerfManager);
|
||||
|
||||
|
|
|
@ -2883,7 +2883,9 @@ void BeIRCodeGen::HandleNextCmd()
|
|||
case BfIRCmd_DbgGetTypeInst:
|
||||
{
|
||||
CMD_PARAM(int, typeId);
|
||||
SetResult(curId, GetTypeEntry(typeId).mInstDIType);
|
||||
auto result = GetTypeEntry(typeId).mInstDIType;
|
||||
//BF_ASSERT(result);
|
||||
SetResult(curId, result);
|
||||
}
|
||||
break;
|
||||
case BfIRCmd_DbgTrackDITypes:
|
||||
|
|
|
@ -7172,7 +7172,7 @@ void TestPDB(const StringImpl& fileName, WinDebugger* debugger)
|
|||
COFF coff(debugTarget);
|
||||
coff.mDebugger = debugger;
|
||||
uint8 wantGuid[16];
|
||||
coff.LoadPDB(fileName, wantGuid, -1);
|
||||
coff.TryLoadPDB(fileName, wantGuid, -1);
|
||||
coff.ParseTypeData();
|
||||
coff.CvParseIPI();
|
||||
coff.ParseGlobalsData();
|
||||
|
|
|
@ -752,7 +752,7 @@ public:
|
|||
|
||||
bool IsNoValueType() const
|
||||
{
|
||||
return (mKind == BfTypedValueKind_NoValue);
|
||||
return (mKind == BfTypedValueKind_NoValue) && (mType != NULL);
|
||||
}
|
||||
|
||||
bool IsParams()
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "BfResolvePass.h"
|
||||
#include "BfFixits.h"
|
||||
#include "BfResolvedTypeUtils.h"
|
||||
#include "CeMachine.h"
|
||||
#include "CeDebugger.h"
|
||||
|
||||
#define FTS_FUZZY_MATCH_IMPLEMENTATION
|
||||
#include "../third_party/FtsFuzzyMatch.h"
|
||||
|
@ -274,7 +276,7 @@ int BfAutoComplete::GetCursorIdx(BfAstNode* node)
|
|||
if (node == NULL)
|
||||
return -1;
|
||||
|
||||
if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
|
||||
if (!node->IsFromParser(mCompiler->mResolvePassData->mParser))
|
||||
return -1;
|
||||
|
||||
auto bfParser = node->GetSourceData()->ToParser();
|
||||
|
@ -289,7 +291,7 @@ bool BfAutoComplete::IsAutocompleteNode(BfAstNode* node, int lengthAdd, int star
|
|||
if (node == NULL)
|
||||
return false;
|
||||
|
||||
if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
|
||||
if (!node->IsFromParser(mCompiler->mResolvePassData->mParser))
|
||||
return false;
|
||||
|
||||
auto bfParser = node->GetSourceData()->ToParser();
|
||||
|
@ -311,7 +313,7 @@ bool BfAutoComplete::IsAutocompleteNode(BfAstNode* startNode, BfAstNode* endNode
|
|||
if ((startNode == NULL) || (endNode == NULL))
|
||||
return false;
|
||||
|
||||
if ((!mCompiler->mIsResolveOnly) || (!startNode->IsFromParser(mCompiler->mResolvePassData->mParser)))
|
||||
if (!startNode->IsFromParser(mCompiler->mResolvePassData->mParser))
|
||||
return false;
|
||||
|
||||
auto bfParser = startNode->GetSourceData()->ToParser();
|
||||
|
@ -333,7 +335,7 @@ bool BfAutoComplete::IsAutocompleteLineNode(BfAstNode* node)
|
|||
if (node == NULL)
|
||||
return false;
|
||||
|
||||
if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
|
||||
if (!node->IsFromParser(mCompiler->mResolvePassData->mParser))
|
||||
return false;
|
||||
|
||||
auto bfParser = node->GetSourceData()->ToParser();
|
||||
|
@ -1555,6 +1557,22 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
|
|||
}
|
||||
}
|
||||
|
||||
if (auto ceDbgState = mModule->GetCeDbgState())
|
||||
{
|
||||
auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger;
|
||||
auto ceContext = ceDebugger->mCurDbgState->mCeContext;
|
||||
auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame;
|
||||
if (activeFrame->mFunction->mDbgInfo != NULL)
|
||||
{
|
||||
int instIdx = activeFrame->GetInstIdx();
|
||||
for (auto& dbgVar : activeFrame->mFunction->mDbgInfo->mVariables)
|
||||
{
|
||||
if ((instIdx >= dbgVar.mStartCodePos) && (instIdx < dbgVar.mEndCodePos))
|
||||
AddEntry(AutoCompleteEntry(GetTypeName(dbgVar.mType), dbgVar.mName), filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BfMethodInstance* curMethodInstance = mModule->mCurMethodInstance;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "../LLVMUtils.h"
|
||||
#include "BfNamespaceVisitor.h"
|
||||
#include "CeMachine.h"
|
||||
#include "CeDebugger.h"
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
|
@ -479,15 +480,15 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
|
|||
mLastAutocompleteModule = NULL;
|
||||
|
||||
//if (isResolveOnly)
|
||||
//mCEMachine = NULL;
|
||||
mCEMachine = new CeMachine(this);
|
||||
//mCeMachine = NULL;
|
||||
mCeMachine = new CeMachine(this);
|
||||
mCurCEExecuteId = -1;
|
||||
}
|
||||
|
||||
BfCompiler::~BfCompiler()
|
||||
{
|
||||
delete mCEMachine;
|
||||
mCEMachine = NULL;
|
||||
delete mCeMachine;
|
||||
mCeMachine = NULL;
|
||||
delete mContext;
|
||||
delete mHotData;
|
||||
delete mHotState;
|
||||
|
@ -5749,6 +5750,20 @@ void BfCompiler::PopulateReified()
|
|||
}
|
||||
}
|
||||
|
||||
bool BfCompiler::IsCePaused()
|
||||
{
|
||||
return (mCeMachine != NULL) && (mCeMachine->mDbgPaused);
|
||||
}
|
||||
|
||||
bool BfCompiler::EnsureCeUnpaused(BfType* refType)
|
||||
{
|
||||
if ((mCeMachine == NULL) || (!mCeMachine->mDbgPaused))
|
||||
return true;
|
||||
mCeMachine->mDebugger->mCurDbgState->mReferencedIncompleteTypes = true;
|
||||
//mPassInstance->Fail(StrFormat("Use of incomplete type '%s'", mCeMachine->mCeModule->TypeToString(refType).c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
void BfCompiler::HotCommit()
|
||||
{
|
||||
if (mHotState == NULL)
|
||||
|
@ -6668,8 +6683,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
else
|
||||
mContext->mUnreifiedModule->mIsReified = false;
|
||||
|
||||
if (mCEMachine != NULL)
|
||||
mCEMachine->CompileStarted();
|
||||
if (mCeMachine != NULL)
|
||||
mCeMachine->CompileStarted();
|
||||
|
||||
if (mOptions.mAllowHotSwapping)
|
||||
{
|
||||
|
@ -7476,7 +7491,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
}
|
||||
mCodeGen.ProcessErrors(mPassInstance, mCanceling);
|
||||
|
||||
mCEMachine->CompileDone();
|
||||
mCeMachine->CompileDone();
|
||||
|
||||
// This has to happen after codegen because we may delete modules that are referenced in codegen
|
||||
mContext->Cleanup();
|
||||
|
@ -7541,9 +7556,9 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
|
|||
numModulesWritten, (numModulesWritten != 1) ? "s" : "",
|
||||
numObjFilesWritten, (numObjFilesWritten != 1) ? "s" : ""));
|
||||
|
||||
if ((mCEMachine != NULL) && (!mIsResolveOnly) && (mCEMachine->mRevisionExecuteTime > 0))
|
||||
if ((mCeMachine != NULL) && (!mIsResolveOnly) && (mCeMachine->mRevisionExecuteTime > 0))
|
||||
{
|
||||
mPassInstance->OutputLine(StrFormat(":med Comptime execution time: %0.2fs", mCEMachine->mRevisionExecuteTime / 1000.0f));
|
||||
mPassInstance->OutputLine(StrFormat(":med Comptime execution time: %0.2fs", mCeMachine->mRevisionExecuteTime / 1000.0f));
|
||||
}
|
||||
|
||||
BpLeave();
|
||||
|
@ -7658,10 +7673,10 @@ void BfCompiler::Cancel()
|
|||
mCanceling = true;
|
||||
mFastFinish = true;
|
||||
mHadCancel = true;
|
||||
if (mCEMachine != NULL)
|
||||
if (mCeMachine != NULL)
|
||||
{
|
||||
AutoCrit autoCrit(mCEMachine->mCritSect);
|
||||
mCEMachine->mSpecialCheck = true;
|
||||
AutoCrit autoCrit(mCeMachine->mCritSect);
|
||||
mCeMachine->mSpecialCheck = true;
|
||||
mFastFinish = true;
|
||||
}
|
||||
BfLogSysM("BfCompiler::Cancel\n");
|
||||
|
@ -7671,8 +7686,8 @@ void BfCompiler::Cancel()
|
|||
void BfCompiler::RequestFastFinish()
|
||||
{
|
||||
mFastFinish = true;
|
||||
if (mCEMachine != NULL)
|
||||
mCEMachine->mSpecialCheck = true;
|
||||
if (mCeMachine != NULL)
|
||||
mCeMachine->mSpecialCheck = true;
|
||||
BfLogSysM("BfCompiler::RequestFastFinish\n");
|
||||
BpEvent("BfCompiler::RequestFastFinish", "");
|
||||
}
|
||||
|
|
|
@ -315,7 +315,7 @@ public:
|
|||
BfPassInstance* mPassInstance;
|
||||
FILE* mCompileLogFP;
|
||||
|
||||
CeMachine* mCEMachine;
|
||||
CeMachine* mCeMachine;
|
||||
int mCurCEExecuteId;
|
||||
BfSystem* mSystem;
|
||||
bool mIsResolveOnly;
|
||||
|
@ -507,6 +507,8 @@ public:
|
|||
void AddDepsToRebuildTypeList(BfTypeInstance* typeInst, HashSet<BfTypeInstance*>& rebuildTypeInstList);
|
||||
void CompileReified();
|
||||
void PopulateReified();
|
||||
bool IsCePaused();
|
||||
bool EnsureCeUnpaused(BfType* refType);
|
||||
|
||||
void HotCommit();
|
||||
void HotResolve_Start(HotResolveFlags flags);
|
||||
|
|
|
@ -1719,14 +1719,14 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
|
|||
for (auto& methodInstGroup : typeInst->mMethodInstanceGroups)
|
||||
{
|
||||
if ((methodInstGroup.mDefault != NULL) && (methodInstGroup.mDefault->mInCEMachine))
|
||||
mCompiler->mCEMachine->RemoveMethod(methodInstGroup.mDefault);
|
||||
mCompiler->mCeMachine->RemoveMethod(methodInstGroup.mDefault);
|
||||
if (methodInstGroup.mMethodSpecializationMap != NULL)
|
||||
{
|
||||
for (auto& methodSpecializationItr : *methodInstGroup.mMethodSpecializationMap)
|
||||
{
|
||||
auto methodInstance = methodSpecializationItr.mValue;
|
||||
if (methodInstance->mInCEMachine)
|
||||
mCompiler->mCEMachine->RemoveMethod(methodInstance);
|
||||
mCompiler->mCeMachine->RemoveMethod(methodInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "BeefySysLib/util/BeefPerf.h"
|
||||
#include "BfParser.h"
|
||||
#include "BfMangler.h"
|
||||
#include "BfDemangler.h"
|
||||
#include "BfResolvePass.h"
|
||||
#include "BfUtil.h"
|
||||
#include "BfDeferEvalChecker.h"
|
||||
|
@ -1648,7 +1649,8 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
|||
BfMethodInstance* methodInstance = mModule->GetRawMethodInstance(typeInstance, checkMethod);
|
||||
if (methodInstance == NULL)
|
||||
{
|
||||
BFMODULE_FATAL(mModule, "Failed to get raw method in BfMethodMatcher::CheckMethod");
|
||||
if (!mModule->mCompiler->IsCePaused())
|
||||
BFMODULE_FATAL(mModule, "Failed to get raw method in BfMethodMatcher::CheckMethod");
|
||||
return false;
|
||||
}
|
||||
BfMethodInstance* typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(methodInstance, true);
|
||||
|
@ -4020,9 +4022,9 @@ BfTypedValue BfExprEvaluator::LoadLocal(BfLocalVariable* varDecl, bool allowRef)
|
|||
|
||||
BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringImpl& findName, bool ignoreInitialError, bool* hadError)
|
||||
{
|
||||
if ((mModule->mCompiler->mCEMachine != NULL) && (mModule->mCompiler->mCEMachine->mDebugger != NULL) && (mModule->mCompiler->mCEMachine->mDebugger->mCurDbgState != NULL))
|
||||
if ((mModule->mCompiler->mCeMachine != NULL) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
|
||||
{
|
||||
auto ceDebugger = mModule->mCompiler->mCEMachine->mDebugger;
|
||||
auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger;
|
||||
auto ceContext = ceDebugger->mCurDbgState->mCeContext;
|
||||
auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame;
|
||||
if (activeFrame->mFunction->mDbgInfo != NULL)
|
||||
|
@ -4032,9 +4034,13 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
|
|||
{
|
||||
if (dbgVar.mName == findName)
|
||||
{
|
||||
if (dbgVar.mValue.mKind == CeOperandKind_AllocaAddr)
|
||||
if ((dbgVar.mValue.mKind == CeOperandKind_AllocaAddr) || (dbgVar.mValue.mKind == CeOperandKind_FrameOfs))
|
||||
{
|
||||
return BfTypedValue(mModule->mBfIRBuilder->CreateConstAggCE(mModule->mBfIRBuilder->MapType(dbgVar.mType), activeFrame->mFrameAddr + dbgVar.mValue.mFrameOfs), dbgVar.mType, true);
|
||||
if ((instIdx >= dbgVar.mStartCodePos) && (instIdx < dbgVar.mEndCodePos))
|
||||
{
|
||||
return BfTypedValue(mModule->mBfIRBuilder->CreateConstAggCE(mModule->mBfIRBuilder->MapType(dbgVar.mType), activeFrame->mFrameAddr + dbgVar.mValue.mFrameOfs),
|
||||
dbgVar.mType, dbgVar.mIsConst ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4699,7 +4705,10 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe
|
|||
|
||||
if (fieldInstance->mResolvedType == NULL)
|
||||
{
|
||||
BF_ASSERT((typeInstance->mTypeFailed) || (isResolvingFields));
|
||||
if (mModule->mCompiler->EnsureCeUnpaused(typeInstance))
|
||||
{
|
||||
BF_ASSERT((typeInstance->mTypeFailed) || (isResolvingFields));
|
||||
}
|
||||
return BfTypedValue();
|
||||
}
|
||||
|
||||
|
@ -5234,6 +5243,15 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
|||
mModule->PopulateType(curCheckType, BfPopulateType_Data);
|
||||
}
|
||||
|
||||
if (field->mIdx >= (int)curCheckType->mFieldInstances.size())
|
||||
{
|
||||
if (mModule->mCompiler->EnsureCeUnpaused(curCheckType))
|
||||
{
|
||||
BF_DBG_FATAL("OOB in DoLookupField");
|
||||
}
|
||||
return mModule->GetDefaultTypedValue(mModule->GetPrimitiveType(BfTypeCode_Var));
|
||||
}
|
||||
|
||||
BF_ASSERT(field->mIdx < (int)curCheckType->mFieldInstances.size());
|
||||
auto fieldInstance = &curCheckType->mFieldInstances[field->mIdx];
|
||||
if (!fieldInstance->mFieldIncluded)
|
||||
|
@ -6034,7 +6052,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
|
||||
bool forceBind = false;
|
||||
|
||||
if (mModule->mCompiler->mCEMachine != NULL)
|
||||
if (mModule->mCompiler->mCeMachine != NULL)
|
||||
{
|
||||
bool doConstReturn = false;
|
||||
|
||||
|
@ -6072,14 +6090,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
if ((mBfEvalExprFlags & BfEvalExprFlags_NoCeRebuildFlags) != 0)
|
||||
evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_NoRebuild);
|
||||
|
||||
if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCEMachine->mDebugger != NULL) && (mModule->mCompiler->mCEMachine->mDebugger->mCurDbgState != NULL))
|
||||
if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
|
||||
{
|
||||
auto ceDbgState = mModule->mCompiler->mCEMachine->mDebugger->mCurDbgState;
|
||||
auto ceDbgState = mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState;
|
||||
if ((ceDbgState->mDbgExpressionFlags & DwEvalExpressionFlag_AllowCalls) != 0)
|
||||
{
|
||||
ceDbgState->mHadSideEffects = true;
|
||||
|
||||
SetAndRestoreValue<CeDebugger*> prevDebugger(mModule->mCompiler->mCEMachine->mDebugger, NULL);
|
||||
//SetAndRestoreValue<CeDebugger*> prevDebugger(mModule->mCompiler->mCeMachine->mDebugger, NULL);
|
||||
|
||||
evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_DbgCall);
|
||||
auto result = ceDbgState->mCeContext->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
|
||||
|
@ -6093,7 +6111,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
}
|
||||
else
|
||||
{
|
||||
auto constRet = mModule->mCompiler->mCEMachine->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
|
||||
auto constRet = mModule->mCompiler->mCeMachine->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
|
||||
if (constRet)
|
||||
{
|
||||
auto constant = mModule->mBfIRBuilder->GetConstant(constRet.mValue);
|
||||
|
@ -6121,7 +6139,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
|
|||
}
|
||||
else
|
||||
{
|
||||
mModule->mCompiler->mCEMachine->QueueMethod(methodInstance, func);
|
||||
mModule->mCompiler->mCeMachine->QueueMethod(methodInstance, func);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12678,7 +12696,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
}
|
||||
|
||||
auto bindFuncVal = bindResult.mFunc;
|
||||
if (mModule->mCompiler->mOptions.mAllowHotSwapping)
|
||||
if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!mModule->mIsComptimeModule))
|
||||
bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
|
||||
auto callResult = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
|
||||
auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
|
||||
|
@ -13022,7 +13040,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
}
|
||||
|
||||
auto bindFuncVal = bindResult.mFunc;
|
||||
if (mModule->mCompiler->mOptions.mAllowHotSwapping)
|
||||
if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!mModule->mIsComptimeModule))
|
||||
bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
|
||||
auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
|
||||
if (GetStructRetIdx(bindMethodInstance) != -1)
|
||||
|
@ -13083,7 +13101,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!bindResult.mMethodInstance->mMethodDef->mIsVirtual))
|
||||
if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!bindResult.mMethodInstance->mMethodDef->mIsVirtual) && (!mModule->mIsComptimeModule))
|
||||
{
|
||||
funcValue = mModule->mBfIRBuilder->RemapBindFunction(funcValue);
|
||||
}
|
||||
|
@ -15349,9 +15367,9 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
{
|
||||
allocValue = mModule->AllocFromType(resolvedTypeRef, allocTarget, appendSizeValue, BfIRValue(), 0, BfAllocFlags_None, allocAlign);
|
||||
}
|
||||
if (((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && (mModule->mCompiler->mCEMachine != NULL))
|
||||
if (((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && (mModule->mCompiler->mCeMachine != NULL))
|
||||
{
|
||||
mModule->mCompiler->mCEMachine->SetAppendAllocInfo(mModule, allocValue, appendSizeValue);
|
||||
mModule->mCompiler->mCeMachine->SetAppendAllocInfo(mModule, allocValue, appendSizeValue);
|
||||
}
|
||||
mResult = BfTypedValue(allocValue, resultType);
|
||||
}
|
||||
|
@ -15480,9 +15498,9 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
}
|
||||
}
|
||||
|
||||
if (((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && (mModule->mCompiler->mCEMachine != NULL))
|
||||
if (((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0) && (mModule->mCompiler->mCeMachine != NULL))
|
||||
{
|
||||
mModule->mCompiler->mCEMachine->ClearAppendAllocInfo();
|
||||
mModule->mCompiler->mCeMachine->ClearAppendAllocInfo();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16590,7 +16608,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
int startLocalIdx = (int)mModule->mCurMethodState->mLocals.size();
|
||||
int endLocalIdx = startLocalIdx;
|
||||
|
||||
if (wantsDIData)
|
||||
if ((wantsDIData) || (mModule->mIsComptimeModule))
|
||||
{
|
||||
BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(methodInstance);
|
||||
|
||||
|
@ -16609,7 +16627,10 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
String methodName = methodDef->mName;
|
||||
methodName += "!";
|
||||
BfMangler::Mangle(methodName, mModule->mCompiler->GetMangleKind(), methodInstance);
|
||||
curMethodState->mCurScope->mDIScope = mModule->mBfIRBuilder->DbgCreateFunction(diParentType, methodName, "", mModule->mCurFilePosition.mFileInstance->mDIFile,
|
||||
String linkageName;
|
||||
if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mCurBuilder != NULL))
|
||||
linkageName = StrFormat("%d", mModule->mCompiler->mCeMachine->mCurBuilder->DbgCreateMethodRef(methodInstance, ""));
|
||||
curMethodState->mCurScope->mDIScope = mModule->mBfIRBuilder->DbgCreateFunction(diParentType, methodName, linkageName, mModule->mCurFilePosition.mFileInstance->mDIFile,
|
||||
defLine + 1, diFuncType, false, true, mModule->mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
|
||||
scopeData.mAltDIFile = mModule->mCurFilePosition.mFileInstance->mDIFile;
|
||||
}
|
||||
|
@ -16739,7 +16760,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
|
|||
{
|
||||
//
|
||||
}
|
||||
else if (mModule->IsTargetingBeefBackend())
|
||||
else if ((mModule->IsTargetingBeefBackend()) && (!mModule->mIsComptimeModule))
|
||||
{
|
||||
mModule->UpdateSrcPos(methodDeclaration->mNameNode);
|
||||
mModule->SetIllegalSrcPos();
|
||||
|
@ -17559,11 +17580,11 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
{
|
||||
if (targetFunctionName.StartsWith("__"))
|
||||
{
|
||||
auto ceDebugger = mModule->mCompiler->mCEMachine->mDebugger;
|
||||
auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger;
|
||||
|
||||
auto _ResolveArg = [&](int argIdx, BfType* type = NULL)
|
||||
{
|
||||
if (argIdx >= args.mSize)
|
||||
if ((argIdx < 0) || (argIdx >= args.mSize))
|
||||
return BfTypedValue();
|
||||
return mModule->CreateValueFromExpression(args[argIdx], type);
|
||||
};
|
||||
|
@ -17597,6 +17618,141 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if ((targetFunctionName == "__cast") || (targetFunctionName == "__bitcast"))
|
||||
{
|
||||
BfType* type = NULL;
|
||||
String typeName;
|
||||
for (int argIdx = 0; argIdx < args.mSize - 1; argIdx++)
|
||||
{
|
||||
auto arg = _ResolveArg(argIdx);
|
||||
if (!arg)
|
||||
continue;
|
||||
if (arg.mType->IsInstanceOf(mModule->mCompiler->mStringTypeDef))
|
||||
{
|
||||
auto strPtr = mModule->GetStringPoolString(arg.mValue, mModule->mBfIRBuilder);
|
||||
if (strPtr != NULL)
|
||||
{
|
||||
if ((type != NULL) && (*strPtr == "*"))
|
||||
{
|
||||
type = mModule->CreatePointerType(type);
|
||||
}
|
||||
else
|
||||
typeName += *strPtr;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg.mType->IsInteger())
|
||||
{
|
||||
int64 intVal = ceDebugger->ValueToInt(arg);
|
||||
if (typeName.IsEmpty())
|
||||
{
|
||||
auto typeType = mModule->ResolveTypeDef(mModule->mCompiler->mTypeTypeDef)->ToTypeInstance();
|
||||
auto fieldDef = typeType->mTypeDef->GetFieldByName("mTypeId");
|
||||
if (fieldDef != NULL)
|
||||
{
|
||||
int typeId = ceDebugger->ReadMemory<int>((intptr)intVal + typeType->mFieldInstances[fieldDef->mIdx].mDataOffset);
|
||||
type = mModule->mContext->FindTypeById(typeId);
|
||||
}
|
||||
}
|
||||
else
|
||||
typeName += StrFormat("%lld", intVal);
|
||||
}
|
||||
}
|
||||
|
||||
auto fromTypedVal = _ResolveArg(args.mSize - 1);
|
||||
|
||||
if (!typeName.IsEmpty())
|
||||
type = ceDebugger->FindType(typeName);
|
||||
|
||||
if (type != NULL)
|
||||
{
|
||||
if (targetFunctionName == "__bitcast")
|
||||
{
|
||||
if ((type->IsObjectOrInterface()) || (type->IsPointer()))
|
||||
{
|
||||
auto ceAddrVal = ceDebugger->GetAddr(fromTypedVal);
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIntToPtr(ceAddrVal.mAddr, mModule->mBfIRBuilder->MapType(type)), type);
|
||||
}
|
||||
else
|
||||
{
|
||||
Array<uint8> memArr;
|
||||
memArr.Resize(BF_MAX(type->mSize, fromTypedVal.mType->mSize));
|
||||
mModule->mBfIRBuilder->WriteConstant(fromTypedVal.mValue, memArr.mVals, fromTypedVal.mType);
|
||||
auto newVal = mModule->mBfIRBuilder->ReadConstant(memArr.mVals, type);
|
||||
mResult = BfTypedValue(newVal, type);
|
||||
}
|
||||
}
|
||||
else
|
||||
mResult = mModule->Cast(target, fromTypedVal, type, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_SilentFail));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (targetFunctionName == "__stringView")
|
||||
{
|
||||
auto ptrVal = _ResolveArg(0);
|
||||
auto sizeVal = _ResolveArg(1);
|
||||
|
||||
if (ceDbgState->mFormatInfo != NULL)
|
||||
ceDbgState->mFormatInfo->mOverrideCount = (int)ceDebugger->ValueToInt(sizeVal);
|
||||
|
||||
mResult = ptrVal;
|
||||
return;
|
||||
}
|
||||
else if ((targetFunctionName == "__funcName") || (targetFunctionName == "__funcTarget"))
|
||||
{
|
||||
auto addrVal = _ResolveArg(0);
|
||||
auto ceAddrVal = ceDebugger->GetAddr(addrVal);
|
||||
|
||||
CeFunction* ceFunction = NULL;
|
||||
int functionId = 0;
|
||||
if (mModule->mSystem->mPtrSize == 4)
|
||||
{
|
||||
functionId = (int)addrVal;
|
||||
}
|
||||
else
|
||||
{
|
||||
CeFunction* checkCeFunction = (CeFunction*)ceAddrVal.mAddr;
|
||||
functionId = checkCeFunction->SafeGetId();
|
||||
}
|
||||
|
||||
if (mModule->mCompiler->mCeMachine->mFunctionIdMap.TryGetValue(functionId, &ceFunction))
|
||||
{
|
||||
BfMethodInstance* methodInstance = ceFunction->mMethodInstance;
|
||||
if (methodInstance != NULL)
|
||||
{
|
||||
if (targetFunctionName == "__funcTarget")
|
||||
{
|
||||
BfType* targetType = methodInstance->GetOwner();
|
||||
if (targetType->IsValueType())
|
||||
targetType = mModule->CreatePointerType(targetType);
|
||||
|
||||
auto targetVal = _ResolveArg(1);
|
||||
auto ceTargetVal = ceDebugger->GetAddr(targetVal);
|
||||
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateIntToPtr(ceTargetVal.mAddr, mModule->mBfIRBuilder->MapType(targetType)), targetType);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
mResult = BfTypedValue(mModule->GetStringObjectValue(mModule->MethodToString(methodInstance)),
|
||||
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if ((ceFunction->mCeInnerFunctionInfo != NULL) && (targetFunctionName == "__funcName"))
|
||||
{
|
||||
mResult = BfTypedValue(mModule->GetStringObjectValue(BfDemangler::Demangle(ceFunction->mCeInnerFunctionInfo->mName, DbgLanguage_Beef)),
|
||||
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetFunctionName == "__funcTarget")
|
||||
mResult = _ResolveArg(1);
|
||||
else
|
||||
mResult = addrVal;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19475,9 +19631,9 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
|
|||
}
|
||||
else if (!alreadyWritten)
|
||||
{
|
||||
if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCEMachine->mDebugger != NULL) && (mModule->mCompiler->mCEMachine->mDebugger->mCurDbgState != NULL))
|
||||
if ((mModule->mIsComptimeModule) && (mModule->mCompiler->mCeMachine->mDebugger != NULL) && (mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
|
||||
{
|
||||
auto ceDbgState = mModule->mCompiler->mCEMachine->mDebugger->mCurDbgState;
|
||||
auto ceDbgState = mModule->mCompiler->mCeMachine->mDebugger->mCurDbgState;
|
||||
bool success = false;
|
||||
|
||||
if ((convVal.mValue.IsConst()) && (ptr.mValue.IsConst()))
|
||||
|
@ -19485,20 +19641,20 @@ void BfExprEvaluator::PerformAssignment(BfAssignmentExpression* assignExpr, bool
|
|||
auto constant = mModule->mBfIRBuilder->GetConstant(ptr.mValue);
|
||||
auto valConstant = mModule->mBfIRBuilder->GetConstant(convVal.mValue);
|
||||
|
||||
auto ceTypedVal = mModule->mCompiler->mCEMachine->mDebugger->GetAddr(constant);
|
||||
auto ceTypedVal = mModule->mCompiler->mCeMachine->mDebugger->GetAddr(constant);
|
||||
if (!ceTypedVal)
|
||||
{
|
||||
mModule->Fail("Invalid assignment address", assignExpr);
|
||||
return;
|
||||
}
|
||||
|
||||
auto ceContext = mModule->mCompiler->mCEMachine->mCurContext;
|
||||
if (ceContext->CheckMemory(ceTypedVal.mAddr, convVal.mType->mSize))
|
||||
auto ceContext = mModule->mCompiler->mCeMachine->mCurContext;
|
||||
if (ceContext->CheckMemory((addr_ce)ceTypedVal.mAddr, convVal.mType->mSize))
|
||||
{
|
||||
if ((ceDbgState->mDbgExpressionFlags & DwEvalExpressionFlag_AllowSideEffects) != 0)
|
||||
{
|
||||
ceDbgState->mHadSideEffects = true;
|
||||
if (ceContext->WriteConstant(mModule, ceTypedVal.mAddr, valConstant, convVal.mType))
|
||||
if (ceContext->WriteConstant(mModule, (addr_ce)ceTypedVal.mAddr, valConstant, convVal.mType))
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
|
@ -20846,7 +21002,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
|
|||
}*/
|
||||
|
||||
if (mModule->mIsComptimeModule)
|
||||
mModule->mCompiler->mCEMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc);
|
||||
mModule->mCompiler->mCeMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc);
|
||||
|
||||
SizedArray<BfIRValue, 1> args;
|
||||
args.push_back(mModule->GetConstValue(0));
|
||||
|
|
|
@ -1737,8 +1737,8 @@ CeDbgState* BfModule::GetCeDbgState()
|
|||
{
|
||||
if (!mIsComptimeModule)
|
||||
return NULL;
|
||||
if ((mCompiler->mCEMachine != NULL) && (mCompiler->mCEMachine->mDebugger != NULL))
|
||||
return mCompiler->mCEMachine->mDebugger->mCurDbgState;
|
||||
if ((mCompiler->mCeMachine != NULL) && (mCompiler->mCeMachine->mDebugger != NULL))
|
||||
return mCompiler->mCeMachine->mDebugger->mCurDbgState;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2235,17 +2235,6 @@ bool BfModule::TryLocalVariableInit(BfLocalVariable* localVar)
|
|||
|
||||
void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit)
|
||||
{
|
||||
//if (localVar->mAddr == NULL)
|
||||
|
||||
/*if ((localVar->mValue) && (!localVar->mAddr) && (IsTargetingBeefBackend()))
|
||||
{
|
||||
if ((!localVar->mValue.IsConst()) && (!localVar->mValue.IsArg()) && (!localVar->mValue.IsFake()))
|
||||
{
|
||||
if (mCurMethodInstance->mMethodDef->mName == "FuncA")
|
||||
mBfIRBuilder->CreateLifetimeEnd(localVar->mValue);
|
||||
}
|
||||
}*/
|
||||
|
||||
BfAstNode* localNameNode = localVar->mNameNode;
|
||||
if (localVar->mIsThis)
|
||||
{
|
||||
|
@ -3076,19 +3065,26 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
|||
|
||||
//BF_ASSERT(refNode != NULL);
|
||||
|
||||
if ((mIsComptimeModule) && (!mCompiler->mCEMachine->mDbgPaused))
|
||||
if (mIsComptimeModule)
|
||||
{
|
||||
mHadBuildError = true;
|
||||
|
||||
if ((mCompiler->mCEMachine->mCurContext != NULL) && (mCompiler->mCEMachine->mCurContext->mCurTargetSrc != NULL))
|
||||
if (auto ceDbgState = GetCeDbgState())
|
||||
{
|
||||
BfError* bfError = mCompiler->mPassInstance->Fail("Comptime method generation had errors", mCompiler->mCEMachine->mCurContext->mCurTargetSrc);
|
||||
if (bfError != NULL)
|
||||
mCompiler->mPassInstance->MoreInfo(error, refNode);
|
||||
return bfError;
|
||||
// Follow normal fail path
|
||||
}
|
||||
else
|
||||
{
|
||||
mHadBuildError = true;
|
||||
|
||||
return NULL;
|
||||
if ((mCompiler->mCeMachine->mCurContext != NULL) && (mCompiler->mCeMachine->mCurContext->mCurTargetSrc != NULL))
|
||||
{
|
||||
BfError* bfError = mCompiler->mPassInstance->Fail("Comptime method generation had errors", mCompiler->mCeMachine->mCurContext->mCurTargetSrc);
|
||||
if (bfError != NULL)
|
||||
mCompiler->mPassInstance->MoreInfo(error, refNode);
|
||||
return bfError;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (mCurMethodInstance != NULL)
|
||||
|
@ -4439,8 +4435,8 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
|
|||
else if (fieldDef->mIsConst)
|
||||
{
|
||||
int ceExecuteId = -1;
|
||||
if (mCompiler->mCEMachine != NULL)
|
||||
ceExecuteId = mCompiler->mCEMachine->mExecuteId;
|
||||
if (mCompiler->mCeMachine != NULL)
|
||||
ceExecuteId = mCompiler->mCeMachine->mExecuteId;
|
||||
|
||||
BfTypeState typeState;
|
||||
typeState.mType = mCurTypeInstance;
|
||||
|
@ -4463,9 +4459,9 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
|
|||
}
|
||||
UpdateSrcPos(initializer);
|
||||
auto result = constResolver.Resolve(initializer, fieldType, resolveFlags);
|
||||
if ((mCompiler->mCEMachine != NULL) && (fieldInstance != NULL))
|
||||
if ((mCompiler->mCeMachine != NULL) && (fieldInstance != NULL))
|
||||
{
|
||||
if (mCompiler->mCEMachine->mExecuteId != ceExecuteId)
|
||||
if (mCompiler->mCeMachine->mExecuteId != ceExecuteId)
|
||||
fieldInstance->mHadConstEval = true;
|
||||
}
|
||||
return result;
|
||||
|
@ -10000,6 +9996,8 @@ bool BfModule::IsOptimized()
|
|||
{
|
||||
if (mProject == NULL)
|
||||
return false;
|
||||
if (mIsComptimeModule)
|
||||
return false;
|
||||
int optLevel = GetModuleOptions().mOptLevel;
|
||||
return (optLevel >= BfOptLevel_O1) && (optLevel <= BfOptLevel_O3);
|
||||
}
|
||||
|
@ -10013,10 +10011,14 @@ bool BfModule::IsTargetingBeefBackend()
|
|||
|
||||
bool BfModule::WantsLifetimes()
|
||||
{
|
||||
if (mProject == NULL)
|
||||
return false;
|
||||
if (mBfIRBuilder->mIgnoreWrites)
|
||||
return false;
|
||||
|
||||
if ((mIsComptimeModule) && (mBfIRBuilder->HasDebugLocation()))
|
||||
return true;
|
||||
else if (mProject == NULL)
|
||||
return false;
|
||||
|
||||
return GetModuleOptions().mOptLevel == BfOptLevel_OgPlus;
|
||||
}
|
||||
|
||||
|
@ -10086,10 +10088,14 @@ void BfModule::EmitObjectAccessCheck(BfTypedValue typedVal)
|
|||
|
||||
void BfModule::EmitEnsureInstructionAt()
|
||||
{
|
||||
if (mProject == NULL)
|
||||
if (mBfIRBuilder->mIgnoreWrites)
|
||||
return;
|
||||
|
||||
if ((mBfIRBuilder->mIgnoreWrites) || (!mHasFullDebugInfo) || (IsOptimized()) || (mCompiler->mOptions.mOmitDebugHelpers))
|
||||
if (mIsComptimeModule)
|
||||
{
|
||||
// Always add
|
||||
}
|
||||
else if ((mProject == NULL) || (!mHasFullDebugInfo) || (IsOptimized()) || (mCompiler->mOptions.mOmitDebugHelpers))
|
||||
return;
|
||||
|
||||
mBfIRBuilder->CreateEnsureInstructionAt();
|
||||
|
@ -10476,6 +10482,15 @@ BfMethodInstance* BfModule::GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstan
|
|||
BF_ASSERT(typeInstance->mTypeDef->mMethods[methodIdx]->mName == assertName);
|
||||
}
|
||||
|
||||
if (methodIdx >= typeInstance->mMethodInstanceGroups.mSize)
|
||||
{
|
||||
if (mCompiler->EnsureCeUnpaused(typeInstance))
|
||||
{
|
||||
BF_FATAL("OOB in GetRawMethodInstanceAtIdx");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
auto& methodGroup = typeInstance->mMethodInstanceGroups[methodIdx];
|
||||
if (methodGroup.mDefault == NULL)
|
||||
{
|
||||
|
@ -12464,27 +12479,31 @@ BfTypedValue BfModule::LoadValue(BfTypedValue typedValue, BfAstNode* refNode, bo
|
|||
}
|
||||
}
|
||||
|
||||
if ((mIsComptimeModule) && (mCompiler->mCEMachine->mDebugger != NULL) && (mCompiler->mCEMachine->mDebugger->mCurDbgState != NULL))
|
||||
if ((mIsComptimeModule) && (mCompiler->mCeMachine->mDebugger != NULL) && (mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
|
||||
{
|
||||
auto ceDebugger = mCompiler->mCEMachine->mDebugger;
|
||||
auto ceDebugger = mCompiler->mCeMachine->mDebugger;
|
||||
auto ceContext = ceDebugger->mCurDbgState->mCeContext;
|
||||
auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame;
|
||||
|
||||
auto ceTypedValue = ceDebugger->GetAddr(constantValue);
|
||||
if (ceTypedValue)
|
||||
{
|
||||
if ((typedValue.mType->IsObjectOrInterface()) || (typedValue.mType->IsPointer()))
|
||||
if ((typedValue.mType->IsObjectOrInterface()) || (typedValue.mType->IsPointer()) || (typedValue.mType->IsRef()))
|
||||
{
|
||||
void* data = ceContext->GetMemoryPtr(ceTypedValue.mAddr, sizeof(addr_ce));
|
||||
void* data = ceContext->GetMemoryPtr((addr_ce)ceTypedValue.mAddr, sizeof(addr_ce));
|
||||
if (data == NULL)
|
||||
{
|
||||
Fail("Invalid address", refNode);
|
||||
return GetDefaultTypedValue(typedValue.mType);
|
||||
}
|
||||
|
||||
addr_ce dataAddr = *(addr_ce*)data;
|
||||
uint64 dataAddr;
|
||||
if (mSystem->mPtrSize == 4)
|
||||
dataAddr = *(uint32*)data;
|
||||
else
|
||||
dataAddr = *(uint64*)data;
|
||||
return BfTypedValue(mBfIRBuilder->CreateIntToPtr(
|
||||
mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)dataAddr), mBfIRBuilder->MapType(typedValue.mType)), typedValue.mType);
|
||||
mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, dataAddr), mBfIRBuilder->MapType(typedValue.mType)), typedValue.mType);
|
||||
}
|
||||
|
||||
auto constVal = ceContext->CreateConstant(this, ceContext->mMemory.mVals + ceTypedValue.mAddr, typedValue.mType);
|
||||
|
@ -13535,6 +13554,15 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
|||
}
|
||||
else
|
||||
PopulateType(typeInst, BfPopulateType_Full);
|
||||
|
||||
if (typeInst->mDefineState < BfTypeDefineState_Defined)
|
||||
{
|
||||
if (!mCompiler->EnsureCeUnpaused(typeInst))
|
||||
{
|
||||
BfLogSysM("GetMethodInstance (DefineState < BfTypeDefineState_Defined)) bailing due to IsCePaused\n");
|
||||
return BfModuleMethodInstance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool tryModuleMethodLookup = false;
|
||||
|
@ -14134,6 +14162,12 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
|||
|
||||
if (methodInstance == NULL)
|
||||
{
|
||||
if (!mCompiler->EnsureCeUnpaused(typeInst))
|
||||
{
|
||||
BfLogSysM("GetMethodInstance (methodInstance == NULL) bailing due to IsCePaused\n");
|
||||
return BfModuleMethodInstance();
|
||||
}
|
||||
|
||||
if (lookupMethodGenericArguments.size() == 0)
|
||||
{
|
||||
BF_ASSERT(methodInstGroup->mDefault == NULL);
|
||||
|
@ -14586,7 +14620,7 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
|
|||
|
||||
if (mIsComptimeModule)
|
||||
{
|
||||
mCompiler->mCEMachine->QueueStaticField(fieldInstance, staticVarName);
|
||||
mCompiler->mCeMachine->QueueStaticField(fieldInstance, staticVarName);
|
||||
}
|
||||
|
||||
PopulateType(typeType);
|
||||
|
@ -14649,9 +14683,24 @@ void BfModule::MarkUsingThis()
|
|||
|
||||
BfTypedValue BfModule::GetThis(bool markUsing)
|
||||
{
|
||||
if ((mIsComptimeModule) && (mCompiler->mCEMachine->mDebugger != NULL) && (mCompiler->mCEMachine->mDebugger->mCurDbgState != NULL))
|
||||
if ((mIsComptimeModule) && (mCompiler->mCeMachine->mDebugger != NULL) && (mCompiler->mCeMachine->mDebugger->mCurDbgState != NULL))
|
||||
{
|
||||
return mCompiler->mCEMachine->mDebugger->mCurDbgState->mExplicitThis;
|
||||
if (mCompiler->mCeMachine->mDebugger->mCurDbgState->mExplicitThis)
|
||||
return mCompiler->mCeMachine->mDebugger->mCurDbgState->mExplicitThis;
|
||||
|
||||
auto ceDebugger = mCompiler->mCeMachine->mDebugger;
|
||||
auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame;
|
||||
if ((activeFrame != NULL) && (activeFrame->mFunction->mDbgInfo != NULL))
|
||||
{
|
||||
for (auto& dbgVar : activeFrame->mFunction->mDbgInfo->mVariables)
|
||||
{
|
||||
if (dbgVar.mName == "this")
|
||||
return BfTypedValue(mBfIRBuilder->CreateConstAggCE(mBfIRBuilder->MapType(dbgVar.mType), activeFrame->mFrameAddr + dbgVar.mValue.mFrameOfs), dbgVar.mType,
|
||||
dbgVar.mIsConst ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
|
||||
}
|
||||
}
|
||||
|
||||
return BfTypedValue();
|
||||
}
|
||||
|
||||
auto useMethodState = mCurMethodState;
|
||||
|
@ -15028,7 +15077,7 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((IsTargetingBeefBackend()) && (doAliasValue))
|
||||
if ((IsTargetingBeefBackend()) && (doAliasValue) && (!mIsComptimeModule))
|
||||
{
|
||||
diValue = mBfIRBuilder->CreateAliasValue(diValue);
|
||||
mCurMethodState->mCurScope->mDeferredLifetimeEnds.Add(diValue);
|
||||
|
@ -15936,6 +15985,8 @@ BfType* BfModule::GetDelegateReturnType(BfType* delegateType)
|
|||
auto typeInst = delegateType->ToTypeInstance();
|
||||
PopulateType(typeInst, BfPopulateType_DataAndMethods);
|
||||
BfMethodInstance* invokeMethodInstance = GetRawMethodInstanceAtIdx(typeInst->ToTypeInstance(), 0, "Invoke");
|
||||
if (invokeMethodInstance == NULL)
|
||||
return GetPrimitiveType(BfTypeCode_Var);
|
||||
return invokeMethodInstance->mReturnType;
|
||||
}
|
||||
|
||||
|
@ -16578,7 +16629,7 @@ void BfModule::EmitDtorBody()
|
|||
|
||||
auto dtorFunc = GetMethodByName(mContext->mBfObjectType, "~this");
|
||||
if (mIsComptimeModule)
|
||||
mCompiler->mCEMachine->QueueMethod(dtorFunc.mMethodInstance, dtorFunc.mFunc);
|
||||
mCompiler->mCeMachine->QueueMethod(dtorFunc.mMethodInstance, dtorFunc.mFunc);
|
||||
auto basePtr = mBfIRBuilder->CreateBitCast(thisVal.mValue, mBfIRBuilder->MapTypeInstPtr(mContext->mBfObjectType));
|
||||
SizedArray<BfIRValue, 1> vals = { basePtr };
|
||||
result = mBfIRBuilder->CreateCall(dtorFunc.mFunc, vals);
|
||||
|
@ -16762,7 +16813,7 @@ void BfModule::EmitDtorBody()
|
|||
SizedArray<BfIRValue, 1> vals = { basePtr };
|
||||
auto callInst = mBfIRBuilder->CreateCall(dtorMethodInstance.mFunc, vals);
|
||||
if (mIsComptimeModule)
|
||||
mCompiler->mCEMachine->QueueMethod(dtorMethodInstance.mMethodInstance, dtorMethodInstance.mFunc);
|
||||
mCompiler->mCeMachine->QueueMethod(dtorMethodInstance.mMethodInstance, dtorMethodInstance.mFunc);
|
||||
mBfIRBuilder->SetCallCallingConv(callInst, GetIRCallingConvention(dtorMethodInstance.mMethodInstance));
|
||||
}
|
||||
}
|
||||
|
@ -17354,7 +17405,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
|||
exprEvaluator.PushThis(NULL, GetThis(), moduleMethodInstance.mMethodInstance, irArgs);
|
||||
exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
|
||||
if (mIsComptimeModule)
|
||||
mCompiler->mCEMachine->QueueMethod(moduleMethodInstance);
|
||||
mCompiler->mCeMachine->QueueMethod(moduleMethodInstance);
|
||||
|
||||
calledCtorNoBody = true;
|
||||
}
|
||||
|
@ -17416,7 +17467,11 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
|||
mCurMethodState->mCurScope->mDIInlinedAt = mBfIRBuilder->DbgGetCurrentLocation();
|
||||
BF_ASSERT(mCurMethodState->mCurScope->mDIInlinedAt);
|
||||
// mCurMethodState->mCurScope->mDIInlinedAt may still be null ifwe don't have an explicit ctor
|
||||
mCurMethodState->mCurScope->mDIScope = mBfIRBuilder->DbgCreateFunction(mBfIRBuilder->DbgGetTypeInst(mCurTypeInstance), "this$initFields", "", mCurFilePosition.mFileInstance->mDIFile,
|
||||
|
||||
String linkageName;
|
||||
if ((mIsComptimeModule) && (mCompiler->mCeMachine->mCurBuilder != NULL))
|
||||
linkageName = StrFormat("%d", mCompiler->mCeMachine->mCurBuilder->DbgCreateMethodRef(mCurMethodInstance, "$initFields"));
|
||||
mCurMethodState->mCurScope->mDIScope = mBfIRBuilder->DbgCreateFunction(mBfIRBuilder->DbgGetTypeInst(mCurTypeInstance), "this$initFields", linkageName, mCurFilePosition.mFileInstance->mDIFile,
|
||||
mCurFilePosition.mCurLine + 1, diFuncType, false, true, mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
|
||||
|
||||
UpdateSrcPos(node);
|
||||
|
@ -17709,7 +17764,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
|||
if (callingConv != BfIRCallingConv_CDecl)
|
||||
mBfIRBuilder->SetCallCallingConv(callInst, callingConv);
|
||||
if (mIsComptimeModule)
|
||||
mCompiler->mCEMachine->QueueMethod(ctorBodyMethodInstance);
|
||||
mCompiler->mCeMachine->QueueMethod(ctorBodyMethodInstance);
|
||||
}
|
||||
|
||||
if (matchedMethod == NULL)
|
||||
|
@ -19667,6 +19722,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
|
|||
bool wantsDIData = (mBfIRBuilder->DbgHasInfo()) && (!methodDef->IsEmptyPartial()) && (!mBfIRBuilder->mIgnoreWrites) && (mHasFullDebugInfo);
|
||||
if (methodDef->mMethodType == BfMethodType_Mixin)
|
||||
wantsDIData = false;
|
||||
if (mCurTypeInstance->IsUnspecializedType())
|
||||
wantsDIData = false;
|
||||
|
||||
if ((mCurTypeInstance->IsBoxed()) && (methodDef->mMethodType != BfMethodType_Ctor))
|
||||
wantsDIData = false;
|
||||
|
@ -22661,6 +22718,8 @@ void BfModule::StartMethodDeclaration(BfMethodInstance* methodInstance, BfMethod
|
|||
// methodDeclaration is NULL for default constructors
|
||||
void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool isTemporaryFunc, bool addToWorkList)
|
||||
{
|
||||
BF_ASSERT((mCompiler->mCeMachine == NULL) || (!mCompiler->mCeMachine->mDbgPaused));
|
||||
|
||||
BP_ZONE("BfModule::DoMethodDeclaration");
|
||||
|
||||
// We could trigger a DoMethodDeclaration from a const resolver or other location, so we reset it here
|
||||
|
|
|
@ -1273,6 +1273,13 @@ public:
|
|||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
BfModuleOptions()
|
||||
{
|
||||
mSIMDSetting = BfSIMDSetting_None;
|
||||
mEmitDebugInfo = false;
|
||||
mOptLevel = BfOptLevel_NotSet;
|
||||
}
|
||||
};
|
||||
|
||||
struct BfGenericParamSource
|
||||
|
|
|
@ -2220,8 +2220,8 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
|
|||
if (methodInstance == NULL)
|
||||
continue;
|
||||
|
||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, ceEmitContext);
|
||||
auto ceContext = mCompiler->mCEMachine->AllocContext();
|
||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCeMachine->mCurEmitContext, ceEmitContext);
|
||||
auto ceContext = mCompiler->mCeMachine->AllocContext();
|
||||
|
||||
BfIRValue attrVal =ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
|
||||
for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
|
||||
|
@ -2266,7 +2266,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
|
|||
|
||||
DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);
|
||||
if (fieldInstance != NULL)
|
||||
mCompiler->mCEMachine->mFieldInstanceSet.Add(fieldInstance);
|
||||
mCompiler->mCeMachine->mFieldInstanceSet.Add(fieldInstance);
|
||||
BfTypedValue result;
|
||||
///
|
||||
{
|
||||
|
@ -2274,7 +2274,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
|
|||
result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_ForceReturnThis, NULL);
|
||||
}
|
||||
if (fieldInstance != NULL)
|
||||
mCompiler->mCEMachine->mFieldInstanceSet.Remove(fieldInstance);
|
||||
mCompiler->mCeMachine->mFieldInstanceSet.Remove(fieldInstance);
|
||||
if (result.mType == methodInstance->GetOwner())
|
||||
prevAttrInstances[methodInstance->GetOwner()] = result.mValue;
|
||||
|
||||
|
@ -2334,7 +2334,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
|
|||
}
|
||||
}
|
||||
|
||||
mCompiler->mCEMachine->ReleaseContext(ceContext);
|
||||
mCompiler->mCeMachine->ReleaseContext(ceContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2392,6 +2392,9 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
|
|||
if (!mBfIRBuilder->mIgnoreWrites)
|
||||
{
|
||||
String methodName = "Comptime_Mixin";
|
||||
String linkageName;
|
||||
if (mIsComptimeModule)
|
||||
linkageName = StrFormat("Comptime_Mixin:%llX", mCurMethodInstance);
|
||||
mCurMethodState->mCurScope->mDIScope = mBfIRBuilder->DbgCreateFunction(diParentType, methodName, "", mCurFilePosition.mFileInstance->mDIFile,
|
||||
defLine + 1, diFuncType, false, true, mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
|
||||
mCurMethodState->mCurScope->mAltDIFile = mCurFilePosition.mFileInstance->mDIFile;
|
||||
|
@ -2502,7 +2505,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
|
|||
}
|
||||
|
||||
if (!wantsAttributes)
|
||||
return;
|
||||
continue;
|
||||
|
||||
auto customAttributes = GetCustomAttributes(methodDeclaration->mAttributes, BfAttributeTargets_Method);
|
||||
defer({ delete customAttributes; });
|
||||
|
@ -2533,15 +2536,15 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
|
|||
continue;
|
||||
}
|
||||
|
||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext);
|
||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCeMachine->mCurEmitContext);
|
||||
if (onCompileKind == BfCEOnCompileKind_TypeInit)
|
||||
{
|
||||
mCompiler->mCEMachine->mCurEmitContext = ceEmitContext;
|
||||
mCompiler->mCeMachine->mCurEmitContext = ceEmitContext;
|
||||
}
|
||||
|
||||
DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);
|
||||
auto methodInstance = GetRawMethodInstanceAtIdx(typeInstance, methodDef->mIdx);
|
||||
auto result = mCompiler->mCEMachine->Call(methodDef->GetRefNode(), this, methodInstance, {}, (CeEvalFlags)(CeEvalFlags_PersistantError | CeEvalFlags_DeferIfNotOnlyError), NULL);
|
||||
auto result = mCompiler->mCeMachine->Call(methodDef->GetRefNode(), this, methodInstance, {}, (CeEvalFlags)(CeEvalFlags_PersistantError | CeEvalFlags_DeferIfNotOnlyError), NULL);
|
||||
|
||||
if ((onCompileKind == BfCEOnCompileKind_TypeDone) && (typeInstance->mDefineState > BfTypeDefineState_CETypeInit))
|
||||
{
|
||||
|
@ -2670,8 +2673,8 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
|
|||
if (applyMethodInstance == NULL)
|
||||
continue;
|
||||
|
||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, &ceEmitContext);
|
||||
auto ceContext = mCompiler->mCEMachine->AllocContext();
|
||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCeMachine->mCurEmitContext, &ceEmitContext);
|
||||
auto ceContext = mCompiler->mCeMachine->AllocContext();
|
||||
|
||||
BfIRValue attrVal = ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
|
||||
for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
|
||||
|
@ -2707,7 +2710,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
|
|||
continue;
|
||||
}
|
||||
|
||||
mCompiler->mCEMachine->mMethodInstanceSet.Add(methodInstance);
|
||||
mCompiler->mCeMachine->mMethodInstanceSet.Add(methodInstance);
|
||||
auto activeTypeDef = typeInstance->mTypeDef;
|
||||
|
||||
BfTypedValue result;
|
||||
|
@ -2783,7 +2786,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
|
|||
}
|
||||
}
|
||||
|
||||
mCompiler->mCEMachine->ReleaseContext(ceContext);
|
||||
mCompiler->mCeMachine->ReleaseContext(ceContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3184,6 +3187,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
if (populateType == BfPopulateType_Identity)
|
||||
return;
|
||||
|
||||
if ((populateType <= BfPopulateType_Data) && (resolvedTypeRef->mDefineState >= BfTypeDefineState_Defined))
|
||||
return;
|
||||
|
||||
auto typeInstance = resolvedTypeRef->ToTypeInstance();
|
||||
auto typeDef = typeInstance->mTypeDef;
|
||||
|
||||
|
@ -3215,6 +3221,20 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
if (typeInstance->mResolvingConstField)
|
||||
return;
|
||||
|
||||
// Partial population break out point
|
||||
if ((populateType >= BfPopulateType_Identity) && (populateType <= BfPopulateType_IdentityNoRemapAlias))
|
||||
return;
|
||||
|
||||
if ((populateType <= BfPopulateType_AllowStaticMethods) && (typeInstance->mDefineState >= BfTypeDefineState_HasInterfaces))
|
||||
return;
|
||||
|
||||
if (!mCompiler->EnsureCeUnpaused(resolvedTypeRef))
|
||||
{
|
||||
// We need to avoid comptime reentry when the ceDebugger is paused
|
||||
BfLogSysM("DoPopulateType %p bailing due to IsCePaused\n", resolvedTypeRef);
|
||||
return;
|
||||
}
|
||||
|
||||
auto _CheckTypeDone = [&]()
|
||||
{
|
||||
if (typeInstance->mNeedsMethodProcessing)
|
||||
|
@ -3232,13 +3252,6 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
if (_CheckTypeDone())
|
||||
return;
|
||||
|
||||
// Partial population break out point
|
||||
if ((populateType >= BfPopulateType_Identity) && (populateType <= BfPopulateType_IdentityNoRemapAlias))
|
||||
return;
|
||||
|
||||
if ((populateType <= BfPopulateType_AllowStaticMethods) && (typeInstance->mDefineState >= BfTypeDefineState_HasInterfaces))
|
||||
return;
|
||||
|
||||
if (!resolvedTypeRef->IsValueType())
|
||||
{
|
||||
resolvedTypeRef->mSize = typeInstance->mAlign = mSystem->mPtrSize;
|
||||
|
@ -4482,17 +4495,17 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
|||
if ((foundTypeCount >= 2) || (typeInstance->mTypeDef->IsEmitted()))
|
||||
{
|
||||
String error = "OnCompile const evaluation creates a data dependency during TypeInit";
|
||||
if (mCompiler->mCEMachine->mCurBuilder != NULL)
|
||||
if (mCompiler->mCeMachine->mCurBuilder != NULL)
|
||||
{
|
||||
error += StrFormat(" during const-eval generation of '%s'", MethodToString(mCompiler->mCEMachine->mCurBuilder->mCeFunction->mMethodInstance).c_str());
|
||||
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);
|
||||
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);
|
||||
tryCE = false;
|
||||
}
|
||||
}
|
||||
|
@ -11900,7 +11913,7 @@ BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, const BfTypedValue& targe
|
|||
}
|
||||
bindFuncVal = methodRefMethod.mFunc;
|
||||
}
|
||||
if (mCompiler->mOptions.mAllowHotSwapping)
|
||||
if ((mCompiler->mOptions.mAllowHotSwapping) && (!mIsComptimeModule))
|
||||
bindFuncVal = mBfIRBuilder->RemapBindFunction(bindFuncVal);
|
||||
return mBfIRBuilder->CreatePtrToInt(bindFuncVal, BfTypeCode_IntPtr);
|
||||
}
|
||||
|
|
|
@ -617,8 +617,8 @@ void BfMethodInstance::Dispose(bool isDeleting)
|
|||
if (mInCEMachine)
|
||||
{
|
||||
auto module = GetOwner()->mModule;
|
||||
if (module->mCompiler->mCEMachine != NULL)
|
||||
module->mCompiler->mCEMachine->RemoveMethod(this);
|
||||
if (module->mCompiler->mCeMachine != NULL)
|
||||
module->mCompiler->mCeMachine->RemoveMethod(this);
|
||||
}
|
||||
|
||||
if (mMethodProcessRequest != NULL)
|
||||
|
|
|
@ -464,7 +464,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc
|
|||
listEntry->mDynList.PushFront(deferredCallEntry);
|
||||
}
|
||||
|
||||
if ((mBfIRBuilder->DbgHasInfo()) && (mCompiler->mOptions.mEmitDebugInfo) && (mCurMethodState->mCurScope->mDIScope))
|
||||
if ((mBfIRBuilder->DbgHasInfo()) && (mHasFullDebugInfo) && (mCompiler->mOptions.mEmitDebugInfo) && (mCurMethodState->mCurScope->mDIScope))
|
||||
{
|
||||
auto int64Type = GetPrimitiveType(BfTypeCode_Int64);
|
||||
auto moduleMethodInstance = deferredCallEntry->mModuleMethodInstance;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -17,6 +17,15 @@ class CeFunction;
|
|||
class BfReducer;
|
||||
class CeDebugger;
|
||||
class DebugVisualizerEntry;
|
||||
class CeEvaluationContext;
|
||||
|
||||
class CeBreakpointCondition
|
||||
{
|
||||
public:
|
||||
CeEvaluationContext* mDbgEvaluationContext;
|
||||
String mExpr;
|
||||
~CeBreakpointCondition();
|
||||
};
|
||||
|
||||
class CeBreakpoint : public Breakpoint
|
||||
{
|
||||
|
@ -24,6 +33,7 @@ public:
|
|||
uintptr mCurBindAddr;
|
||||
bool mHasBound;
|
||||
int mIdx;
|
||||
CeBreakpointCondition* mCondition;
|
||||
|
||||
public:
|
||||
CeBreakpoint()
|
||||
|
@ -31,8 +41,10 @@ public:
|
|||
mCurBindAddr = 1;
|
||||
mHasBound = false;
|
||||
mIdx = -1;
|
||||
mCondition = NULL;
|
||||
}
|
||||
|
||||
~CeBreakpoint();
|
||||
virtual uintptr GetAddr() { return mCurBindAddr; }
|
||||
virtual bool IsMemoryBreakpointBound() { return false; }
|
||||
};
|
||||
|
@ -98,7 +110,7 @@ public:
|
|||
void Init(CeDebugger* winDebugger, const StringImpl& expr, CeFormatInfo* formatInfo = NULL, BfTypedValue contextValue = BfTypedValue());
|
||||
bool HasExpression();
|
||||
~CeEvaluationContext();
|
||||
BfTypedValue EvaluateInContext(BfTypedValue contextTypedValue);
|
||||
BfTypedValue EvaluateInContext(BfTypedValue contextTypedValue, CeDbgState* dbgState = NULL);
|
||||
String GetErrorStr();
|
||||
bool HadError();
|
||||
};
|
||||
|
@ -110,17 +122,21 @@ public:
|
|||
CeContext* mCeContext;
|
||||
BfTypedValue mExplicitThis;
|
||||
DwEvalExpressionFlags mDbgExpressionFlags;
|
||||
CeFormatInfo* mFormatInfo;
|
||||
bool mHadSideEffects;
|
||||
bool mBlockedSideEffects;
|
||||
bool mReferencedIncompleteTypes;
|
||||
|
||||
public:
|
||||
CeDbgState()
|
||||
{
|
||||
mActiveFrame = NULL;
|
||||
mCeContext = NULL;
|
||||
mFormatInfo = NULL;
|
||||
mDbgExpressionFlags = DwEvalExpressionFlag_None;
|
||||
mHadSideEffects = false;
|
||||
mBlockedSideEffects = false;
|
||||
mReferencedIncompleteTypes = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -128,6 +144,7 @@ class CePendingExpr
|
|||
{
|
||||
public:
|
||||
int mThreadId;
|
||||
BfPassInstance* mPassInstance;
|
||||
BfParser* mParser;
|
||||
BfType* mExplitType;
|
||||
CeFormatInfo mFormatInfo;
|
||||
|
@ -139,11 +156,20 @@ public:
|
|||
String mResult;
|
||||
int mIdleTicks;
|
||||
String mException;
|
||||
bool mDone;
|
||||
|
||||
CePendingExpr();
|
||||
~CePendingExpr();
|
||||
};
|
||||
|
||||
class CeDbgStackInfo
|
||||
{
|
||||
public:
|
||||
int mFrameIdx;
|
||||
int mScopeIdx;
|
||||
int mInlinedFrom;
|
||||
};
|
||||
|
||||
class CeFileInfo
|
||||
{
|
||||
public:
|
||||
|
@ -182,7 +208,7 @@ public:
|
|||
|
||||
struct CeTypedValue
|
||||
{
|
||||
addr_ce mAddr;
|
||||
int64 mAddr;
|
||||
BfIRType mType;
|
||||
|
||||
CeTypedValue()
|
||||
|
@ -191,7 +217,7 @@ struct CeTypedValue
|
|||
mType = BfIRType();
|
||||
}
|
||||
|
||||
CeTypedValue(addr_ce addr, BfIRType type)
|
||||
CeTypedValue(int64 addr, BfIRType type)
|
||||
{
|
||||
mAddr = addr;
|
||||
mType = type;
|
||||
|
@ -203,6 +229,13 @@ struct CeTypedValue
|
|||
}
|
||||
};
|
||||
|
||||
enum CeTypeModKind
|
||||
{
|
||||
CeTypeModKind_Normal,
|
||||
CeTypeModKind_Const,
|
||||
CeTypeModKind_ReadOnly
|
||||
};
|
||||
|
||||
class CeDebugger : public Debugger
|
||||
{
|
||||
public:
|
||||
|
@ -214,6 +247,7 @@ public:
|
|||
Array<CeBreakpoint*> mBreakpoints;
|
||||
Dictionary<String, CeFileInfo*> mFileInfo;
|
||||
Dictionary<int, CeDbgTypeInfo> mDbgTypeInfoMap;
|
||||
Array<CeDbgStackInfo> mDbgCallStack;
|
||||
|
||||
CeEvaluationContext* mCurEvaluationContext;
|
||||
CeBreakpoint* mActiveBreakpoint;
|
||||
|
@ -221,11 +255,23 @@ public:
|
|||
bool mBreakpointCacheDirty;
|
||||
bool mBreakpointFramesDirty;
|
||||
int mCurDisasmFuncId;
|
||||
int mPendingActiveFrameOffset;
|
||||
|
||||
public:
|
||||
template<typename T> T ReadMemory(intptr addr, bool* failed = NULL)
|
||||
{
|
||||
T val;
|
||||
memset(&val, 0, sizeof(T));
|
||||
bool success = ReadMemory(addr, (int)sizeof(T), &val);
|
||||
if (failed != NULL)
|
||||
*failed = !success;
|
||||
return val;
|
||||
}
|
||||
|
||||
bool CheckConditionalBreakpoint(CeBreakpoint* breakpoint);
|
||||
bool SetupStep(int frameIdx = 0);
|
||||
CeFrame* GetFrame(int callStackIdx);
|
||||
String EvaluateContinue(CePendingExpr* pendingExpr, BfPassInstance& bfPassInstance);
|
||||
String DoEvaluate(CePendingExpr* pendingExpr, bool inCompilerThread);
|
||||
String Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags);
|
||||
DwDisplayInfo* GetDisplayInfo(const StringImpl& referenceId);
|
||||
String GetMemberList(BfType* type, addr_ce addr, addr_ce addrInst, bool isStatic);
|
||||
|
@ -239,12 +285,13 @@ public:
|
|||
String GetDictionaryItems(DebugVisualizerEntry* debugVis, BfTypedValue dictValue, int bucketIdx, int nodeIdx, int& count, String* outContinuationData);
|
||||
String GetTreeItems(DebugVisualizerEntry* debugVis, Array<addr_ce>& parentList, BfType*& valueType, BfTypedValue& curNode, int count, String* outContinuationData);
|
||||
bool EvalCondition(DebugVisualizerEntry* debugVis, BfTypedValue typedVal, CeFormatInfo& formatInfo, const StringImpl& condition, const Array<String>& dbgVisWildcardCaptures, String& errorStr);
|
||||
CeTypedValue GetAddr(BfConstant* constant);
|
||||
CeTypedValue GetAddr(BfConstant* constant, BfType* type = NULL);
|
||||
CeTypedValue GetAddr(const BfTypedValue typeVal);
|
||||
String ReadString(BfTypeCode charType, intptr addr, intptr maxLength, CeFormatInfo& formatInfo);
|
||||
void ProcessEvalString(BfTypedValue useTypedValue, String& evalStr, String& displayString, CeFormatInfo& formatInfo, DebugVisualizerEntry* debugVis, bool limitLength);
|
||||
String TypedValueToString(const BfTypedValue& typedValue, const StringImpl& expr, CeFormatInfo& formatFlags, bool fullPrecision = false);
|
||||
String TypedValueToString(const BfTypedValue& typedValue, const StringImpl& expr, CeFormatInfo& formatFlags, bool fullPrecision = false, CeTypeModKind typeModKind = CeTypeModKind_Normal);
|
||||
void HandleCustomExpandedItems(String& retVal, DebugVisualizerEntry* debugVis, BfTypedValue typedValue, addr_ce addr, addr_ce addrInst, Array<String>& dbgVisWildcardCaptures, CeFormatInfo& formatInfo);
|
||||
String GetAutocompleteOutput(BfAutoComplete& autoComplete);
|
||||
void ClearBreakpointCache();
|
||||
void UpdateBreakpointCache();
|
||||
void UpdateBreakpointFrames();
|
||||
|
@ -253,8 +300,11 @@ public:
|
|||
void Continue();
|
||||
CeDbgTypeInfo* GetDbgTypeInfo(int typeId);
|
||||
CeDbgTypeInfo* GetDbgTypeInfo(BfIRType irType);
|
||||
int64 ValueToInt(addr_ce addr, BfType* type);
|
||||
int64 ValueToInt(const BfTypedValue& typedVal);
|
||||
BfType* FindType(const StringImpl& name);
|
||||
String TypeToString(const BfTypedValue& typedValue);
|
||||
String TypeToString(BfType* type, CeTypeModKind typeModKind);
|
||||
|
||||
public:
|
||||
CeDebugger(DebugManager* debugManager, BfCompiler* bfCompiler);
|
||||
|
|
|
@ -96,6 +96,7 @@ struct CeOpInfo
|
|||
static CeOpInfo gOpInfo[] =
|
||||
{
|
||||
{"InvalidOp"},
|
||||
{"Nop"},
|
||||
{"DbgBreak"},
|
||||
{"Ret"},
|
||||
{"SetRet", CEOI_None, CEOI_IMM32},
|
||||
|
@ -307,6 +308,35 @@ static int DoubleToString(double d, char* outStr)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
String CeDbgMethodRef::ToString()
|
||||
{
|
||||
if (!mMethodRef)
|
||||
return mNameMod;
|
||||
|
||||
BfMethodInstance* methodInstance = mMethodRef;
|
||||
auto module = methodInstance->GetOwner()->mModule;
|
||||
|
||||
String name = module->MethodToString(methodInstance);
|
||||
if (!mNameMod.IsEmpty())
|
||||
{
|
||||
for (int i = 1; i < (int)name.length(); i++)
|
||||
{
|
||||
if (name[i] == '(')
|
||||
{
|
||||
char prevC = name[i - 1];
|
||||
if ((::isalnum((uint8)prevC)) || (prevC == '_'))
|
||||
{
|
||||
name.Insert(i, mNameMod);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CeInternalData::~CeInternalData()
|
||||
{
|
||||
switch (mKind)
|
||||
|
@ -391,6 +421,19 @@ CeEmitEntry* CeFunction::FindEmitEntry(int instIdx, int* entryIdx)
|
|||
return emitEntry;
|
||||
}
|
||||
|
||||
int CeFunction::SafeGetId()
|
||||
{
|
||||
__try
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CeFunctionInfo::~CeFunctionInfo()
|
||||
|
@ -643,7 +686,7 @@ void CeBuilder::Fail(const StringImpl& str)
|
|||
if (!mCeFunction->mGenError.IsEmpty())
|
||||
return;
|
||||
|
||||
String errStr = StrFormat("Failure during const code generation of %s: %s", mBeFunction->mName.c_str(), str.c_str());
|
||||
String errStr = StrFormat("Failure during comptime generation of %s: %s", mBeFunction->mName.c_str(), str.c_str());
|
||||
if (mCurDbgLoc != NULL)
|
||||
{
|
||||
String filePath;
|
||||
|
@ -927,6 +970,51 @@ CeOperand CeBuilder::EmitConst(int64 val, int size)
|
|||
return result;
|
||||
}
|
||||
|
||||
int CeBuilder::GetCallTableIdx(BeFunction* beFunction, CeOperand* outOperand)
|
||||
{
|
||||
int* callIdxPtr = NULL;
|
||||
if (mFunctionMap.TryAdd(beFunction, NULL, &callIdxPtr))
|
||||
{
|
||||
CeFunctionInfo* ceFunctionInfo = NULL;
|
||||
mCeMachine->mNamedFunctionMap.TryGetValue(beFunction->mName, &ceFunctionInfo);
|
||||
if (ceFunctionInfo != NULL)
|
||||
ceFunctionInfo->mRefCount++;
|
||||
else
|
||||
{
|
||||
if (outOperand != NULL)
|
||||
{
|
||||
auto checkBuilder = this;
|
||||
if (checkBuilder->mParentBuilder != NULL)
|
||||
checkBuilder = checkBuilder->mParentBuilder;
|
||||
|
||||
int innerFunctionIdx = 0;
|
||||
if (checkBuilder->mInnerFunctionMap.TryGetValue(beFunction, &innerFunctionIdx))
|
||||
{
|
||||
auto innerFunction = checkBuilder->mCeFunction->mInnerFunctions[innerFunctionIdx];
|
||||
if (innerFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
||||
mCeMachine->PrepareFunction(innerFunction, checkBuilder);
|
||||
|
||||
CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
|
||||
Emit(CeOp_GetMethod_Inner);
|
||||
EmitFrameOffset(result);
|
||||
Emit((int32)innerFunctionIdx);
|
||||
|
||||
*outOperand = result;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Fail(StrFormat("Unable to locate method %s", beFunction->mName.c_str()));
|
||||
}
|
||||
|
||||
CeCallEntry callEntry;
|
||||
callEntry.mFunctionInfo = ceFunctionInfo;
|
||||
*callIdxPtr = (int)mCeFunction->mCallTable.size();
|
||||
mCeFunction->mCallTable.Add(callEntry);
|
||||
}
|
||||
return *callIdxPtr;
|
||||
}
|
||||
|
||||
CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImmediate)
|
||||
{
|
||||
if (value == NULL)
|
||||
|
@ -1281,55 +1369,25 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme
|
|||
case BeFunction::TypeId:
|
||||
{
|
||||
auto beFunction = (BeFunction*)value;
|
||||
|
||||
int* callIdxPtr = NULL;
|
||||
if (mFunctionMap.TryAdd(beFunction, NULL, &callIdxPtr))
|
||||
{
|
||||
CeFunctionInfo* ceFunctionInfo = NULL;
|
||||
mCeMachine->mNamedFunctionMap.TryGetValue(beFunction->mName, &ceFunctionInfo);
|
||||
if (ceFunctionInfo != NULL)
|
||||
ceFunctionInfo->mRefCount++;
|
||||
else
|
||||
{
|
||||
auto checkBuilder = this;
|
||||
if (checkBuilder->mParentBuilder != NULL)
|
||||
checkBuilder = checkBuilder->mParentBuilder;
|
||||
|
||||
int innerFunctionIdx = 0;
|
||||
if (checkBuilder->mInnerFunctionMap.TryGetValue(beFunction, &innerFunctionIdx))
|
||||
{
|
||||
auto innerFunction = checkBuilder->mCeFunction->mInnerFunctions[innerFunctionIdx];
|
||||
if (innerFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
||||
mCeMachine->PrepareFunction(innerFunction, checkBuilder);
|
||||
|
||||
CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
|
||||
Emit(CeOp_GetMethod_Inner);
|
||||
EmitFrameOffset(result);
|
||||
Emit((int32)innerFunctionIdx);
|
||||
return result;
|
||||
}
|
||||
|
||||
Fail(StrFormat("Unable to locate method %s", beFunction->mName.c_str()));
|
||||
}
|
||||
|
||||
CeCallEntry callEntry;
|
||||
callEntry.mFunctionInfo = ceFunctionInfo;
|
||||
*callIdxPtr = (int)mCeFunction->mCallTable.size();
|
||||
mCeFunction->mCallTable.Add(callEntry);
|
||||
}
|
||||
CeOperand operand;
|
||||
int callIdx = GetCallTableIdx(beFunction, &operand);
|
||||
if (operand)
|
||||
return operand;
|
||||
|
||||
if (allowImmediate)
|
||||
{
|
||||
CeOperand result;
|
||||
result.mKind = CeOperandKind_CallTableIdx;
|
||||
result.mCallTableIdx = *callIdxPtr;
|
||||
result.mCallTableIdx = callIdx;
|
||||
return result;
|
||||
}
|
||||
|
||||
BF_ASSERT(callIdx <= mCeFunction->mCallTable.mSize);
|
||||
|
||||
CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
|
||||
Emit(CeOp_GetMethod);
|
||||
EmitFrameOffset(result);
|
||||
Emit((int32)*callIdxPtr);
|
||||
Emit((int32)callIdx);
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
|
@ -1399,6 +1457,20 @@ CeSizeClass CeBuilder::GetSizeClass(int size)
|
|||
}
|
||||
}
|
||||
|
||||
int CeBuilder::DbgCreateMethodRef(BfMethodInstance* methodInstance, const StringImpl& nameMod)
|
||||
{
|
||||
CeDbgMethodRef dbgMethodRef;
|
||||
dbgMethodRef.mNameMod = nameMod;
|
||||
dbgMethodRef.mMethodRef = methodInstance;
|
||||
int* valuePtr = NULL;
|
||||
if (mDbgMethodRefMap.TryAdd(dbgMethodRef, NULL, &valuePtr))
|
||||
{
|
||||
*valuePtr = mCeFunction->mDbgMethodRefTable.mSize;
|
||||
mCeFunction->mDbgMethodRefTable.Add(dbgMethodRef);
|
||||
}
|
||||
return *valuePtr;
|
||||
}
|
||||
|
||||
void CeBuilder::HandleParams()
|
||||
{
|
||||
auto beModule = mBeFunction->mModule;
|
||||
|
@ -1480,6 +1552,10 @@ void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance
|
|||
|
||||
void CeBuilder::Build()
|
||||
{
|
||||
SetAndRestoreValue<CeDbgState*> prevDbgState;
|
||||
if (mCeMachine->mDebugger != NULL)
|
||||
prevDbgState.Init(mCeMachine->mDebugger->mCurDbgState, NULL);
|
||||
|
||||
auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
|
||||
auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
|
||||
auto beModule = irCodeGen->mBeModule;
|
||||
|
@ -1640,6 +1716,8 @@ void CeBuilder::Build()
|
|||
}
|
||||
}
|
||||
|
||||
int scopeIdx = -1;
|
||||
|
||||
// Primary instruction pass
|
||||
BeDbgLoc* prevEmitDbgPos = NULL;
|
||||
bool inHeadAlloca = true;
|
||||
|
@ -1662,6 +1740,98 @@ void CeBuilder::Build()
|
|||
|
||||
mCurDbgLoc = inst->mDbgLoc;
|
||||
|
||||
if ((prevEmitDbgPos != mCurDbgLoc) && (mCurDbgLoc != NULL))
|
||||
{
|
||||
auto _GetScope = [&](BeMDNode* mdNode, int inlinedAt)
|
||||
{
|
||||
BeDbgFile* dbgFile;
|
||||
BeDbgFunction* dbgFunc = NULL;
|
||||
String nameAdd;
|
||||
|
||||
while (auto dbgLexicalBlock = BeValueDynCast<BeDbgLexicalBlock>(mdNode))
|
||||
mdNode = dbgLexicalBlock->mScope;
|
||||
|
||||
if (dbgFunc = BeValueDynCast<BeDbgFunction>(mdNode))
|
||||
{
|
||||
dbgFile = dbgFunc->mFile;
|
||||
}
|
||||
else if (auto dbgLoc = BeValueDynCast<BeDbgLoc>(mdNode))
|
||||
dbgFile = dbgLoc->GetDbgFile();
|
||||
else
|
||||
dbgFile = BeValueDynCast<BeDbgFile>(mdNode);
|
||||
|
||||
int* valuePtr = NULL;
|
||||
CeDbgInlineLookup lookupPair(dbgFile, inlinedAt);
|
||||
if (mDbgScopeMap.TryAdd(lookupPair, NULL, &valuePtr))
|
||||
{
|
||||
int scopeIdx = (int)mCeFunction->mDbgScopes.size();
|
||||
String filePath = dbgFile->mDirectory;
|
||||
filePath.Append(DIR_SEP_CHAR);
|
||||
filePath += dbgFile->mFileName;
|
||||
CeDbgScope dbgScope;
|
||||
dbgScope.mFilePath = filePath;
|
||||
dbgScope.mInlinedAt = inlinedAt;
|
||||
dbgScope.mMethodVal = -1;
|
||||
|
||||
if (dbgFunc != NULL)
|
||||
{
|
||||
if (dbgFunc->mValue == NULL)
|
||||
{
|
||||
if (!dbgFunc->mLinkageName.IsEmpty())
|
||||
{
|
||||
int methodRefIdx = atoi(dbgFunc->mLinkageName.c_str());
|
||||
dbgScope.mMethodVal = methodRefIdx | CeDbgScope::MethodValFlag_MethodRef;
|
||||
}
|
||||
else
|
||||
{
|
||||
CeDbgMethodRef dbgMethodRef;
|
||||
dbgMethodRef.mNameMod = dbgFunc->mName;
|
||||
|
||||
int* valuePtr = NULL;
|
||||
if (mDbgMethodRefMap.TryAdd(dbgMethodRef, NULL, &valuePtr))
|
||||
{
|
||||
*valuePtr = mCeFunction->mDbgMethodRefTable.mSize;
|
||||
mCeFunction->mDbgMethodRefTable.Add(dbgMethodRef);
|
||||
}
|
||||
dbgScope.mMethodVal = *valuePtr | CeDbgScope::MethodValFlag_MethodRef;
|
||||
}
|
||||
}
|
||||
else if (dbgFunc->mValue != mBeFunction)
|
||||
dbgScope.mMethodVal = GetCallTableIdx(dbgFunc->mValue, NULL);
|
||||
}
|
||||
|
||||
mCeFunction->mDbgScopes.Add(dbgScope);
|
||||
*valuePtr = scopeIdx;
|
||||
return scopeIdx;
|
||||
}
|
||||
else
|
||||
return *valuePtr;
|
||||
};
|
||||
|
||||
std::function<int(BeDbgLoc*)> _GetInlinedScope = [&](BeDbgLoc* dbgLoc)
|
||||
{
|
||||
if (dbgLoc == NULL)
|
||||
return -1;
|
||||
int* valuePtr = NULL;
|
||||
if (mDbgInlineMap.TryAdd(dbgLoc, NULL, &valuePtr))
|
||||
{
|
||||
CeDbgInlineEntry inlineEntry;
|
||||
inlineEntry.mLine = dbgLoc->mLine;
|
||||
inlineEntry.mColumn = dbgLoc->mColumn;
|
||||
|
||||
auto inlinedAt = _GetInlinedScope(dbgLoc->mDbgInlinedAt);
|
||||
inlineEntry.mScope = _GetScope(dbgLoc->mDbgScope, inlinedAt);
|
||||
|
||||
*valuePtr = mCeFunction->mDbgInlineTable.mSize;
|
||||
mCeFunction->mDbgInlineTable.Add(inlineEntry);
|
||||
}
|
||||
return *valuePtr;
|
||||
};
|
||||
|
||||
int inlinedAt = _GetInlinedScope(mCurDbgLoc->mDbgInlinedAt);
|
||||
scopeIdx = _GetScope(mCurDbgLoc->mDbgScope, inlinedAt);
|
||||
}
|
||||
|
||||
int instType = inst->GetTypeId();
|
||||
|
||||
switch (instType)
|
||||
|
@ -1677,10 +1847,8 @@ void CeBuilder::Build()
|
|||
|
||||
switch (instType)
|
||||
{
|
||||
case BeEnsureInstructionAtInst::TypeId:
|
||||
case BeNopInst::TypeId:
|
||||
case BeLifetimeStartInst::TypeId:
|
||||
case BeLifetimeEndInst::TypeId:
|
||||
case BeLifetimeExtendInst::TypeId:
|
||||
case BeValueScopeStartInst::TypeId:
|
||||
case BeValueScopeEndInst::TypeId:
|
||||
|
@ -3011,17 +3179,51 @@ void CeBuilder::Build()
|
|||
|
||||
if (mCeFunction->mDbgInfo != NULL)
|
||||
{
|
||||
if (auto dbgTypeId = BeValueDynCast<BeDbgTypeId>(castedInst->mDbgVar->mType))
|
||||
bool isConst = false;
|
||||
|
||||
auto beType = castedInst->mDbgVar->mType;
|
||||
if (auto dbgConstType = BeValueDynCast<BeDbgConstType>(beType))
|
||||
{
|
||||
isConst = true;
|
||||
beType = dbgConstType->mElement;
|
||||
}
|
||||
|
||||
if (auto dbgTypeId = BeValueDynCast<BeDbgTypeId>(beType))
|
||||
{
|
||||
mDbgVariableMap[castedInst->mValue] = mCeFunction->mDbgInfo->mVariables.mSize;
|
||||
|
||||
CeDbgVariable dbgVariable;
|
||||
dbgVariable.mName = castedInst->mDbgVar->mName;
|
||||
dbgVariable.mValue = mcValue;
|
||||
dbgVariable.mType = mCeMachine->mCeModule->mContext->mTypes[dbgTypeId->mTypeId];
|
||||
dbgVariable.mScope = scopeIdx;
|
||||
dbgVariable.mIsConst = isConst;
|
||||
dbgVariable.mStartCodePos = mCeFunction->mCode.mSize;
|
||||
dbgVariable.mEndCodePos = -1;
|
||||
mCeFunction->mDbgInfo->mVariables.Add(dbgVariable);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BeLifetimeEndInst::TypeId:
|
||||
{
|
||||
auto castedInst = (BeLifetimeEndInst*)inst;
|
||||
int varIdx = 0;
|
||||
if (mDbgVariableMap.TryGetValue(castedInst->mPtr, &varIdx))
|
||||
{
|
||||
auto dbgVar = &mCeFunction->mDbgInfo->mVariables[varIdx];
|
||||
dbgVar->mEndCodePos = mCeFunction->mCode.mSize;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BeEnsureInstructionAtInst::TypeId:
|
||||
{
|
||||
if (mCeMachine->mDebugger != NULL)
|
||||
{
|
||||
Emit(CeOp_Nop);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Fail("Unhandled instruction");
|
||||
return;
|
||||
|
@ -3032,31 +3234,10 @@ void CeBuilder::Build()
|
|||
|
||||
if ((startCodePos != GetCodePos()) && (prevEmitDbgPos != mCurDbgLoc))
|
||||
{
|
||||
int scopeIdx = -1;
|
||||
BeDbgFile* dbgFile = NULL;
|
||||
if (mCurDbgLoc != NULL)
|
||||
{
|
||||
auto dbgFile = mCurDbgLoc->GetDbgFile();
|
||||
int* valuePtr = NULL;
|
||||
if (mDbgFileMap.TryAdd(dbgFile, NULL, &valuePtr))
|
||||
{
|
||||
scopeIdx = (int)mCeFunction->mDbgScopes.size();
|
||||
String filePath = dbgFile->mDirectory;
|
||||
filePath.Append(DIR_SEP_CHAR);
|
||||
filePath += dbgFile->mFileName;
|
||||
CeDbgScope dbgScope;
|
||||
dbgScope.mFilePath = filePath;
|
||||
mCeFunction->mDbgScopes.Add(dbgScope);
|
||||
*valuePtr = scopeIdx;
|
||||
}
|
||||
else
|
||||
scopeIdx = *valuePtr;
|
||||
}
|
||||
|
||||
CeEmitEntry emitEntry;
|
||||
emitEntry.mCodePos = startCodePos;
|
||||
emitEntry.mScope = scopeIdx;
|
||||
if (mCurDbgLoc != NULL)
|
||||
if ((mCurDbgLoc != NULL) && (mCurDbgLoc->mLine != -1))
|
||||
{
|
||||
emitEntry.mLine = mCurDbgLoc->mLine;
|
||||
emitEntry.mColumn = mCurDbgLoc->mColumn;
|
||||
|
@ -3080,6 +3261,13 @@ void CeBuilder::Build()
|
|||
}
|
||||
}
|
||||
|
||||
if (mCeFunction->mDbgInfo != NULL)
|
||||
{
|
||||
for (auto& dbgVar : mCeFunction->mDbgInfo->mVariables)
|
||||
if (dbgVar.mEndCodePos == -1)
|
||||
dbgVar.mEndCodePos = mCeFunction->mCode.mSize;
|
||||
}
|
||||
|
||||
for (auto& jumpEntry : mJumpTable)
|
||||
{
|
||||
auto& ceBlock = mBlocks[jumpEntry.mBlockIdx];
|
||||
|
@ -3094,6 +3282,11 @@ void CeBuilder::Build()
|
|||
|
||||
if (mCeFunction->mGenError.IsEmpty())
|
||||
mCeFunction->mFailed = false;
|
||||
else
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
mCeFunction->mFrameSize = mFrameSize;
|
||||
}
|
||||
|
||||
|
@ -3135,7 +3328,11 @@ BfError* CeContext::Fail(const StringImpl& error)
|
|||
auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc, (mCurEvalFlags & CeEvalFlags_PersistantError) != 0);
|
||||
if (bfError == NULL)
|
||||
return NULL;
|
||||
mCeMachine->mCompiler->mPassInstance->MoreInfo(error, mCeMachine->mCompiler->GetAutoComplete() != NULL);
|
||||
|
||||
bool forceQueue = mCeMachine->mCompiler->GetAutoComplete() != NULL;
|
||||
if ((mCeMachine->mDebugger != NULL) && (mCeMachine->mDebugger->mCurDbgState != NULL))
|
||||
forceQueue = true;
|
||||
mCeMachine->mCompiler->mPassInstance->MoreInfo(error, forceQueue);
|
||||
return bfError;
|
||||
}
|
||||
|
||||
|
@ -3158,7 +3355,7 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
|
|||
|
||||
auto ceFunction = ceFrame->mFunction;
|
||||
|
||||
CeEmitEntry* emitEntry = ceFunction->FindEmitEntry(ceFrame->mInstPtr - &ceFunction->mCode[0] - 1);
|
||||
CeEmitEntry* emitEntry = ceFunction->FindEmitEntry(ceFrame->mInstPtr - ceFunction->mCode.mVals - 1);
|
||||
StringT<256> err;
|
||||
if (isHeadEntry)
|
||||
{
|
||||
|
@ -3175,38 +3372,97 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
|
|||
contextTypeInstance = contextMethodInstance->GetOwner();
|
||||
}
|
||||
|
||||
err += StrFormat("in comptime ");
|
||||
|
||||
//
|
||||
auto _AddCeMethodInstance = [&](BfMethodInstance* methodInstance)
|
||||
{
|
||||
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, contextTypeInstance);
|
||||
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, contextMethodInstance);
|
||||
err += mCeMachine->mCeModule->MethodToString(methodInstance, BfMethodNameFlag_OmitParams);
|
||||
};
|
||||
|
||||
if (ceFunction->mMethodInstance != NULL)
|
||||
err += mCeMachine->mCeModule->MethodToString(ceFunction->mMethodInstance, BfMethodNameFlag_OmitParams);
|
||||
else
|
||||
{
|
||||
err += mCeMachine->mCeModule->MethodToString(ceFunction->mCeInnerFunctionInfo->mOwner->mMethodInstance, BfMethodNameFlag_OmitParams);
|
||||
}
|
||||
}
|
||||
|
||||
if ((emitEntry != NULL) && (emitEntry->mScope != -1))
|
||||
auto _AddError = [&](const StringImpl& filePath, int line, int column)
|
||||
{
|
||||
err += StrFormat(" at line% d:%d in %s", emitEntry->mLine + 1, emitEntry->mColumn + 1, ceFunction->mDbgScopes[emitEntry->mScope].mFilePath.c_str());
|
||||
err += StrFormat(" at line% d:%d in %s", line + 1, column + 1, filePath.c_str());
|
||||
|
||||
auto moreInfo = passInstance->MoreInfo(err, mCeMachine->mCeModule->mCompiler->GetAutoComplete() != NULL);
|
||||
if ((moreInfo != NULL))
|
||||
{
|
||||
BfErrorLocation* location = new BfErrorLocation();
|
||||
location->mFile = ceFunction->mDbgScopes[emitEntry->mScope].mFilePath;
|
||||
location->mLine = emitEntry->mLine;
|
||||
location->mColumn = emitEntry->mColumn;
|
||||
location->mFile = filePath;
|
||||
location->mLine = line;
|
||||
location->mColumn = column;
|
||||
moreInfo->mLocation = location;
|
||||
}
|
||||
};
|
||||
|
||||
if (emitEntry != NULL)
|
||||
{
|
||||
int scopeIdx = emitEntry->mScope;
|
||||
int prevInlineIdx = -1;
|
||||
while (scopeIdx != -1)
|
||||
{
|
||||
err += StrFormat("in comptime ");
|
||||
|
||||
int line = emitEntry->mLine;
|
||||
int column = emitEntry->mColumn;
|
||||
String fileName;
|
||||
|
||||
if (prevInlineIdx != -1)
|
||||
{
|
||||
auto dbgInlineInfo = &ceFunction->mDbgInlineTable[prevInlineIdx];
|
||||
line = dbgInlineInfo->mLine;
|
||||
column = dbgInlineInfo->mColumn;
|
||||
}
|
||||
|
||||
CeDbgScope* ceScope = &ceFunction->mDbgScopes[scopeIdx];
|
||||
if (ceScope->mMethodVal == -1)
|
||||
{
|
||||
if (ceFunction->mMethodInstance != NULL)
|
||||
_AddCeMethodInstance(ceFunction->mMethodInstance);
|
||||
else
|
||||
_AddCeMethodInstance(ceFunction->mCeInnerFunctionInfo->mOwner->mMethodInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ceScope->mMethodVal & CeDbgScope::MethodValFlag_MethodRef) != 0)
|
||||
{
|
||||
auto dbgMethodRef = &ceFunction->mDbgMethodRefTable[ceScope->mMethodVal & CeDbgScope::MethodValFlag_IdxMask];
|
||||
err += dbgMethodRef->ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto callTableEntry = &ceFunction->mCallTable[ceScope->mMethodVal];
|
||||
_AddCeMethodInstance(callTableEntry->mFunctionInfo->mMethodInstance);
|
||||
}
|
||||
}
|
||||
|
||||
_AddError(ceFunction->mDbgScopes[emitEntry->mScope].mFilePath, line, column);
|
||||
|
||||
if (ceScope->mInlinedAt == -1)
|
||||
break;
|
||||
auto inlineInfo = &ceFrame->mFunction->mDbgInlineTable[ceScope->mInlinedAt];
|
||||
scopeIdx = inlineInfo->mScope;
|
||||
prevInlineIdx = ceScope->mInlinedAt;
|
||||
|
||||
err.Clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto moreInfo = passInstance->MoreInfo(err, mCeMachine->mCeModule->mCompiler->GetAutoComplete() != NULL);
|
||||
err += StrFormat("in comptime ");
|
||||
|
||||
if (ceFunction->mMethodInstance != NULL)
|
||||
_AddCeMethodInstance(ceFunction->mMethodInstance);
|
||||
else
|
||||
_AddCeMethodInstance(ceFunction->mCeInnerFunctionInfo->mOwner->mMethodInstance);
|
||||
|
||||
if ((emitEntry != NULL) && (emitEntry->mScope != -1))
|
||||
{
|
||||
_AddError(ceFunction->mDbgScopes[emitEntry->mScope].mFilePath, emitEntry->mLine, emitEntry->mColumn);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto moreInfo = passInstance->MoreInfo(err, mCeMachine->mCeModule->mCompiler->GetAutoComplete() != NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3694,6 +3950,8 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
|||
|
||||
switch (constant->mTypeCode)
|
||||
{
|
||||
case BfTypeCode_None:
|
||||
return true;
|
||||
case BfTypeCode_Int8:
|
||||
case BfTypeCode_UInt8:
|
||||
case BfTypeCode_Boolean:
|
||||
|
@ -3972,6 +4230,15 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
|
|||
return WriteConstant(module, addr, constTarget, type);
|
||||
}
|
||||
|
||||
if (constant->mConstType == BfConstType_IntToPtr)
|
||||
{
|
||||
auto ptrToIntConst = (BfConstantIntToPtr*)constant;
|
||||
|
||||
auto intType = mCeMachine->mCeModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||
auto constTarget = module->mBfIRBuilder->GetConstantById(ptrToIntConst->mTarget);
|
||||
return WriteConstant(module, addr, constTarget, intType);
|
||||
}
|
||||
|
||||
if (constant->mConstType == BfConstType_BitCastNull)
|
||||
{
|
||||
BF_ASSERT(type->IsPointer() || type->IsObjectOrInterface());
|
||||
|
@ -4099,6 +4366,8 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
|
||||
switch (typeCode)
|
||||
{
|
||||
case BfTypeCode_None:
|
||||
return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, 0);
|
||||
case BfTypeCode_Int8:
|
||||
CE_CREATECONST_CHECKPTR(ptr, sizeof(int8));
|
||||
return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(int8*)ptr);
|
||||
|
@ -5091,6 +5360,8 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
ceFunction = CEFUNC; \
|
||||
framePtr = stackPtr; \
|
||||
stackPtr -= ceFunction->mFrameSize; \
|
||||
if (isDebugging) \
|
||||
memset(stackPtr, 0, ceFunction->mFrameSize); \
|
||||
instPtr = &ceFunction->mCode[0]; \
|
||||
CE_CHECKSTACK();
|
||||
|
||||
|
@ -5164,6 +5435,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
uint8* framePtr = startFramePtr;
|
||||
bool needsFunctionIds = ceModule->mSystem->mPtrSize != 8;
|
||||
int32 ptrSize = ceModule->mSystem->mPtrSize;
|
||||
bool isDebugging = mCeMachine->mDebugger != NULL;
|
||||
|
||||
volatile bool* specialCheckPtr = &mCeMachine->mSpecialCheck;
|
||||
volatile bool* fastFinishPtr = &mCeMachine->mCompiler->mFastFinish;
|
||||
|
@ -5193,21 +5465,72 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
|
||||
auto _DbgPause = [&]()
|
||||
{
|
||||
if (mCeMachine->mDebugger != NULL)
|
||||
int itr = 0;
|
||||
while (mCeMachine->mDebugger != NULL)
|
||||
{
|
||||
mCeMachine->mCritSect.Lock();
|
||||
mCallStack.Add(_GetCurFrame());
|
||||
mCeMachine->mDbgPaused = true;
|
||||
mCeMachine->mCritSect.Unlock();
|
||||
if (mCeMachine->mDbgPaused)
|
||||
{
|
||||
// This indicates a missed breakpoint, we should try to avoid this
|
||||
// Re-entrancy can cause this, from populating a type during cedebugger autocomplete
|
||||
OutputDebugStrF("CeMachine DbgPause reentry\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CePendingExpr* prevPendingExpr = NULL;
|
||||
|
||||
///
|
||||
{
|
||||
AutoCrit autoCrit(mCeMachine->mCritSect);
|
||||
|
||||
if ((mCeMachine->mDebugger->mDebugPendingExpr != NULL) && (itr == 0))
|
||||
{
|
||||
// Abandon evaluating expression
|
||||
prevPendingExpr = mCeMachine->mDebugger->mDebugPendingExpr;
|
||||
mCeMachine->mDebugger->mDebugPendingExpr = NULL;
|
||||
}
|
||||
|
||||
if (itr == 0)
|
||||
mCallStack.Add(_GetCurFrame());
|
||||
mCeMachine->mDbgPaused = true;
|
||||
}
|
||||
|
||||
|
||||
mCeMachine->mDebugEvent.WaitFor();
|
||||
|
||||
mCeMachine->mCritSect.Lock();
|
||||
mCeMachine->mDbgPaused = false;
|
||||
mCallStack.pop_back();
|
||||
mCeMachine->mCritSect.Unlock();
|
||||
CePendingExpr* pendingExpr = NULL;
|
||||
|
||||
_FixVariables();
|
||||
///
|
||||
{
|
||||
AutoCrit autoCrit(mCeMachine->mCritSect);
|
||||
mCeMachine->mDbgPaused = false;
|
||||
|
||||
if (mCeMachine->mStepState.mKind != CeStepState::Kind_Evaluate)
|
||||
{
|
||||
mCallStack.pop_back();
|
||||
_FixVariables();
|
||||
break;
|
||||
}
|
||||
|
||||
mCeMachine->mStepState.mKind = CeStepState::Kind_None;
|
||||
String result;
|
||||
if (mCeMachine->mDebugger->mDebugPendingExpr != NULL)
|
||||
pendingExpr = mCeMachine->mDebugger->mDebugPendingExpr;
|
||||
}
|
||||
|
||||
if (pendingExpr == NULL)
|
||||
continue;;
|
||||
|
||||
pendingExpr->mResult = mCeMachine->mDebugger->DoEvaluate(pendingExpr, true);
|
||||
|
||||
///
|
||||
{
|
||||
AutoCrit autoCrit(mCeMachine->mCritSect);
|
||||
pendingExpr->mDone = true;
|
||||
if (pendingExpr != mCeMachine->mDebugger->mDebugPendingExpr)
|
||||
delete pendingExpr;
|
||||
}
|
||||
|
||||
itr++;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5281,6 +5604,10 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
else if (checkFunction->mFunctionKind == CeFunctionKind_FatalError)
|
||||
{
|
||||
int32 strInstAddr = *(int32*)((uint8*)stackPtr + 0);
|
||||
int32 stackOffset = *(int32*)(stackPtr + ceModule->mSystem->mPtrSize);
|
||||
|
||||
if (mCeMachine->mDebugger != NULL)
|
||||
mCeMachine->mDebugger->mPendingActiveFrameOffset = stackOffset;
|
||||
|
||||
String error = "Fatal Error: ";
|
||||
GetStringFromAddr(strInstAddr, error);
|
||||
|
@ -6590,7 +6917,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
if (!checkFunction->mFailed)
|
||||
return true;
|
||||
|
||||
if (mCeMachine->mDebugger != NULL)
|
||||
if ((mCeMachine->mDebugger != NULL) && (!mCallStack.IsEmpty()))
|
||||
_Fail(StrFormat("Attempting to call failed method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
|
||||
|
||||
auto error = Fail(_GetCurFrame(), StrFormat("Method call preparation '%s' failed", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
|
||||
|
@ -6714,9 +7041,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
OpSwitch:
|
||||
switch (op)
|
||||
{
|
||||
case CeOp_Nop:
|
||||
break;
|
||||
case CeOp_DbgBreak:
|
||||
{
|
||||
bool foundBreakpoint = false;
|
||||
bool skipInst = false;
|
||||
|
||||
if (mCeMachine->mDebugger != NULL)
|
||||
{
|
||||
|
@ -6725,14 +7055,36 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
CeBreakpointBind* breakpointEntry = NULL;
|
||||
if (ceFunction->mBreakpoints.TryGetValue(instIdx, &breakpointEntry))
|
||||
{
|
||||
bool doBreak = false;
|
||||
|
||||
mCallStack.Add(_GetCurFrame());
|
||||
if (mCeMachine->mDebugger->CheckConditionalBreakpoint(breakpointEntry->mBreakpoint))
|
||||
doBreak = true;
|
||||
mCallStack.pop_back();
|
||||
|
||||
op = breakpointEntry->mPrevOpCode;
|
||||
// Keep us from an infinite loop if we set a breakpoint on a manual Break
|
||||
skipInst = op == CeOp_DbgBreak;
|
||||
|
||||
foundBreakpoint = true;
|
||||
|
||||
if (!doBreak)
|
||||
{
|
||||
_FixVariables();
|
||||
if (skipInst)
|
||||
break;
|
||||
goto OpSwitch;
|
||||
}
|
||||
|
||||
mCeMachine->mDebugger->mActiveBreakpoint = breakpointEntry->mBreakpoint;
|
||||
}
|
||||
}
|
||||
|
||||
_DbgPause();
|
||||
if (mCeMachine->mStepState.mKind == CeStepState::Kind_Jmp)
|
||||
goto SpecialCheck;
|
||||
if (skipInst)
|
||||
break;
|
||||
if (foundBreakpoint)
|
||||
goto OpSwitch;
|
||||
}
|
||||
|
@ -8182,7 +8534,8 @@ void CeMachine::Init()
|
|||
mCeModule->mBfIRBuilder = new BfIRBuilder(mCeModule);
|
||||
mCeModule->mBfIRBuilder->mDbgVerifyCodeGen = true;
|
||||
mCeModule->FinishInit();
|
||||
mCeModule->mBfIRBuilder->mHasDebugInfo = mDebugger != NULL; // We will still have line info even if this is false
|
||||
mCeModule->mBfIRBuilder->mHasDebugInfo = true;
|
||||
mCeModule->mHasFullDebugInfo = mDebugger != NULL;
|
||||
mCeModule->mBfIRBuilder->mIgnoreWrites = false;
|
||||
mCeModule->mWantsIRIgnoreWrites = false;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "BfModule.h"
|
||||
#include "BeefySysLib/util/Heap.h"
|
||||
#include "BeefySysLib/util/AllocDebug.h"
|
||||
#include "BfMangler.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
|
@ -71,6 +72,7 @@ enum CeErrorKind
|
|||
enum CeOp : int16
|
||||
{
|
||||
CeOp_InvalidOp,
|
||||
CeOp_Nop,
|
||||
CeOp_DbgBreak,
|
||||
CeOp_Ret,
|
||||
CeOp_SetRetType,
|
||||
|
@ -260,6 +262,49 @@ struct CeEmitEntry
|
|||
int mColumn;
|
||||
};
|
||||
|
||||
struct CeDbgMethodRef
|
||||
{
|
||||
BfMethodRef mMethodRef;
|
||||
String mNameMod;
|
||||
|
||||
String ToString();
|
||||
|
||||
bool operator==(const CeDbgMethodRef& second) const
|
||||
{
|
||||
return (mMethodRef == second.mMethodRef) && (mNameMod == second.mNameMod);
|
||||
}
|
||||
};
|
||||
|
||||
struct CeDbgScope
|
||||
{
|
||||
public:
|
||||
enum MethodValFlag
|
||||
{
|
||||
MethodValFlag_MethodRef = 0x40000000,
|
||||
MethodValFlag_IdxMask = 0x3FFFFFFF
|
||||
};
|
||||
|
||||
public:
|
||||
String mFilePath;
|
||||
BfMethodRef mMethodRef;
|
||||
int mInlinedAt;
|
||||
int mMethodVal; // call table idx or methodRef idx, depending on MethodValFlag_MethodRef
|
||||
|
||||
public:
|
||||
CeDbgScope()
|
||||
{
|
||||
mInlinedAt = -1;
|
||||
mMethodVal = -1;
|
||||
}
|
||||
};
|
||||
|
||||
struct CeDbgInlineEntry
|
||||
{
|
||||
int mScope;
|
||||
int mLine;
|
||||
int mColumn;
|
||||
};
|
||||
|
||||
class CeFunctionInfo
|
||||
{
|
||||
public:
|
||||
|
@ -544,6 +589,10 @@ public:
|
|||
String mName;
|
||||
CeOperand mValue;
|
||||
BfType* mType;
|
||||
int mScope;
|
||||
bool mIsConst;
|
||||
int mStartCodePos;
|
||||
int mEndCodePos;
|
||||
};
|
||||
|
||||
class CeDbgFunctionInfo
|
||||
|
@ -559,19 +608,6 @@ public:
|
|||
CeBreakpoint* mBreakpoint;
|
||||
};
|
||||
|
||||
struct CeDbgScope
|
||||
{
|
||||
public:
|
||||
String mFilePath;
|
||||
int mInlinedAt;
|
||||
|
||||
public:
|
||||
CeDbgScope()
|
||||
{
|
||||
mInlinedAt = -1;
|
||||
}
|
||||
};
|
||||
|
||||
class CeFunction
|
||||
{
|
||||
public:
|
||||
|
@ -594,6 +630,8 @@ public:
|
|||
bool mIsVarReturn;
|
||||
Array<uint8> mCode;
|
||||
Array<CeDbgScope> mDbgScopes;
|
||||
Array<CeDbgInlineEntry> mDbgInlineTable;
|
||||
Array<CeDbgMethodRef> mDbgMethodRefTable;
|
||||
Array<CeEmitEntry> mEmitTable;
|
||||
Array<CeCallEntry> mCallTable;
|
||||
Array<CeStringEntry> mStringTable;
|
||||
|
@ -631,6 +669,7 @@ public:
|
|||
void Print();
|
||||
void UnbindBreakpoints();
|
||||
CeEmitEntry* FindEmitEntry(int loc, int* entryIdx = NULL);
|
||||
int SafeGetId();
|
||||
};
|
||||
|
||||
enum CeEvalFlags
|
||||
|
@ -738,6 +777,29 @@ public:
|
|||
int mBlockIdx;
|
||||
};
|
||||
|
||||
struct CeDbgInlineLookup
|
||||
{
|
||||
BeDbgFile* mDbgFile;
|
||||
int mInlineAtIdx;
|
||||
|
||||
CeDbgInlineLookup(BeDbgFile* dbgFile, int inlineAtIdx)
|
||||
{
|
||||
mDbgFile = dbgFile;
|
||||
mInlineAtIdx = inlineAtIdx;
|
||||
}
|
||||
|
||||
CeDbgInlineLookup()
|
||||
{
|
||||
mDbgFile = NULL;
|
||||
mInlineAtIdx = -1;
|
||||
}
|
||||
|
||||
bool operator==(const CeDbgInlineLookup& second) const
|
||||
{
|
||||
return (mDbgFile == second.mDbgFile) && (mDbgFile == second.mDbgFile);
|
||||
}
|
||||
};
|
||||
|
||||
class CeBuilder
|
||||
{
|
||||
public:
|
||||
|
@ -755,13 +817,16 @@ public:
|
|||
Array<CeJumpEntry> mJumpTable;
|
||||
Dictionary<BeValue*, CeOperand> mValueToOperand;
|
||||
int mFrameSize;
|
||||
Dictionary<BeDbgFile*, int> mDbgFileMap;
|
||||
Dictionary<BeDbgLoc*, int> mDbgInlineMap;
|
||||
Dictionary<CeDbgInlineLookup, int> mDbgScopeMap;
|
||||
Dictionary<CeDbgMethodRef, int> mDbgMethodRefMap;
|
||||
Dictionary<BeFunction*, int> mFunctionMap;
|
||||
Dictionary<int, int> mStringMap;
|
||||
Dictionary<BeConstant*, int> mConstDataMap;
|
||||
Dictionary<BeFunction*, int> mInnerFunctionMap;
|
||||
Dictionary<BeGlobalVariable*, int> mStaticFieldMap;
|
||||
Dictionary<String, BfFieldInstance*> mStaticFieldInstanceMap;
|
||||
Dictionary<BeValue*, int> mDbgVariableMap;
|
||||
|
||||
public:
|
||||
CeBuilder()
|
||||
|
@ -782,6 +847,9 @@ public:
|
|||
CeErrorKind EmitConst(Array<uint8>& arr, BeConstant* constant);
|
||||
CeOperand GetOperand(BeValue* value, bool allowAlloca = false, bool allowImmediate = false);
|
||||
CeSizeClass GetSizeClass(int size);
|
||||
int DbgCreateMethodRef(BfMethodInstance* methodInstance, const StringImpl& nameMod);
|
||||
|
||||
int GetCallTableIdx(BeFunction* beFunction, CeOperand* outOperand);
|
||||
int GetCodePos();
|
||||
|
||||
void HandleParams();
|
||||
|
@ -1011,7 +1079,8 @@ public:
|
|||
Kind_StepInfo_Asm,
|
||||
Kind_StepOut,
|
||||
Kind_StepOut_Asm,
|
||||
Kind_Jmp
|
||||
Kind_Jmp,
|
||||
Kind_Evaluate
|
||||
};
|
||||
|
||||
Kind mKind;
|
||||
|
@ -1036,7 +1105,6 @@ public:
|
|||
Dictionary<BfType*, CeTypeInfo> mTypeInfoMap;
|
||||
HashSet<BfMethodInstance*> mMethodInstanceSet;
|
||||
HashSet<BfFieldInstance*> mFieldInstanceSet;
|
||||
Array<BeFunction*> mFunctionList;
|
||||
|
||||
Array<CeContext*> mContextList;
|
||||
|
||||
|
@ -1119,4 +1187,22 @@ namespace std
|
|||
return BeefHash<Beefy::String>()(key.mString) ^ (size_t)key.mKind;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<Beefy::CeDbgInlineLookup>
|
||||
{
|
||||
size_t operator()(const Beefy::CeDbgInlineLookup& key) const
|
||||
{
|
||||
return (intptr)key.mDbgFile ^ (intptr)key.mInlineAtIdx;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hash<Beefy::CeDbgMethodRef>
|
||||
{
|
||||
size_t operator()(const Beefy::CeDbgMethodRef& key) const
|
||||
{
|
||||
return BeefHash<Beefy::BfMethodRef>()(key.mMethodRef) ^ BeefHash<Beefy::String>()(key.mNameMod);
|
||||
}
|
||||
};
|
||||
}
|
|
@ -7403,7 +7403,14 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue
|
|||
}
|
||||
else if ((arg.mType->mTypeCode == DbgType_i32) || (arg.mType->mTypeCode == DbgType_i64))
|
||||
{
|
||||
typeName += BfTypeUtils::HashEncode64(arg.mInt64);
|
||||
if (typeName.IsEmpty())
|
||||
{
|
||||
// Fake this int as a type pointer
|
||||
arg.mSrcAddress = arg.mUInt64;
|
||||
BeefTypeToString(arg, typeName);
|
||||
}
|
||||
else
|
||||
typeName += BfTypeUtils::HashEncode64(arg.mInt64);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -667,7 +667,7 @@ BF_EXPORT void BF_CALLTYPE Debugger_Create()
|
|||
::AllowSetForegroundWindow(ASFW_ANY);
|
||||
#endif
|
||||
|
||||
//BeefyDbg64::TestPDB("c:\\temp\\dedkeni.pdb", (BeefyDbg64::WinDebugger*)gDebugManager->mDebugger64);
|
||||
//BeefyDbg64::TestPDB("C:/Beef/IDE/dist/IDEHelper64_d.pdb", (BeefyDbg64::WinDebugger*)gDebugManager->mDebugger64);
|
||||
}
|
||||
|
||||
BF_EXPORT void BF_CALLTYPE Debugger_SetCallbacks(void* callback)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue