Jelajahi Sumber

Fleshing out comptime debugging

Brian Fiete 3 tahun lalu
induk
melakukan
b334423106

+ 1 - 1
BeefLibs/corlib/src/Reflection/AttributeInfo.bf

@@ -93,7 +93,7 @@ namespace System.Reflection
 						.Double:
 						.Double:
 						let attrData = Decode!<int64>(data);
 						let attrData = Decode!<int64>(data);
 						args[argIdx] = scope:AttrBlock box attrData;
 						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);
 						let argTypeId = Decode!<int32>(data);
 						args[argIdx] = Type.[Friend]GetType((.)argTypeId);
 						args[argIdx] = Type.[Friend]GetType((.)argTypeId);
 					case (TypeCode)255:
 					case (TypeCode)255:

+ 9 - 0
BeefLibs/corlib/src/Runtime.bf

@@ -406,6 +406,9 @@ namespace System
 
 
 		public static void AddErrorHandler(ErrorHandler handler)
 		public static void AddErrorHandler(ErrorHandler handler)
 		{
 		{
+			if (Compiler.IsComptime)
+				return;
+
 			using (sMonitor.Val.Enter())
 			using (sMonitor.Val.Enter())
 			{
 			{
 				if (sErrorHandlers == null)
 				if (sErrorHandlers == null)
@@ -416,6 +419,9 @@ namespace System
 
 
 		public static Result<void> RemoveErrorHandler(ErrorHandler handler)
 		public static Result<void> RemoveErrorHandler(ErrorHandler handler)
 		{
 		{
+			if (Compiler.IsComptime)
+				return .Ok;
+
 			using (sMonitor.Val.Enter())
 			using (sMonitor.Val.Enter())
 			{
 			{
 				if (sErrorHandlers.RemoveStrict(handler))
 				if (sErrorHandlers.RemoveStrict(handler))
@@ -426,6 +432,9 @@ namespace System
 
 
 		public static ErrorHandlerResult CheckErrorHandlers(Error error)
 		public static ErrorHandlerResult CheckErrorHandlers(Error error)
 		{
 		{
+			if (Compiler.IsComptime)
+				return .ContinueFailure;
+
 			using (sMonitor.Val.Enter())
 			using (sMonitor.Val.Enter())
 			{
 			{
 				if (sInsideErrorHandler)
 				if (sInsideErrorHandler)

+ 2 - 0
BeefySysLib/BeefySysLib_static.vcxproj

@@ -864,6 +864,7 @@
     <ClCompile Include="util\CabUtil.cpp" />
     <ClCompile Include="util\CabUtil.cpp" />
     <ClCompile Include="util\CatmullRom.cpp" />
     <ClCompile Include="util\CatmullRom.cpp" />
     <ClCompile Include="util\ChunkedDataBuffer.cpp" />
     <ClCompile Include="util\ChunkedDataBuffer.cpp" />
+    <ClCompile Include="util\Compress.cpp" />
     <ClCompile Include="util\CubicFuncSpline.cpp" />
     <ClCompile Include="util\CubicFuncSpline.cpp" />
     <ClCompile Include="util\CubicSpline.cpp" />
     <ClCompile Include="util\CubicSpline.cpp" />
     <ClCompile Include="util\FileEnumerator.cpp" />
     <ClCompile Include="util\FileEnumerator.cpp" />
@@ -1025,6 +1026,7 @@
     <ClInclude Include="util\BSpline.h" />
     <ClInclude Include="util\BSpline.h" />
     <ClInclude Include="util\CabUtil.h" />
     <ClInclude Include="util\CabUtil.h" />
     <ClInclude Include="util\CatmullRom.h" />
     <ClInclude Include="util\CatmullRom.h" />
+    <ClInclude Include="util\Compress.h" />
     <ClInclude Include="util\CritSect.h" />
     <ClInclude Include="util\CritSect.h" />
     <ClInclude Include="util\CubicFuncSpline.h" />
     <ClInclude Include="util\CubicFuncSpline.h" />
     <ClInclude Include="util\CubicSpline.h" />
     <ClInclude Include="util\CubicSpline.h" />

+ 6 - 0
BeefySysLib/BeefySysLib_static.vcxproj.filters

@@ -572,6 +572,9 @@
     <ClCompile Include="util\Heap.cpp">
     <ClCompile Include="util\Heap.cpp">
       <Filter>src\util</Filter>
       <Filter>src\util</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="util\Compress.cpp">
+      <Filter>src\util</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClInclude Include="Common.h">
     <ClInclude Include="Common.h">
@@ -877,6 +880,9 @@
     <ClInclude Include="util\Heap.h">
     <ClInclude Include="util\Heap.h">
       <Filter>src\util</Filter>
       <Filter>src\util</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="util\Compress.h">
+      <Filter>src\util</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">
     <CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">

+ 1 - 1
IDE/src/IDEApp.bf

@@ -5644,7 +5644,7 @@ namespace IDE
 
 
             subMenu = root.AddMenuItem("&Build");
             subMenu = root.AddMenuItem("&Build");
 			AddMenuItem(subMenu, "&Build Workspace", "Build Workspace", new => UpdateMenuItem_HasWorkspace);
 			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", "Clean", new => UpdateMenuItem_DebugStopped_HasWorkspace);
             AddMenuItem(subMenu, "Clean Beef", "Clean Beef", new => UpdateMenuItem_DebugStopped_HasWorkspace);
             AddMenuItem(subMenu, "Clean Beef", "Clean Beef", new => UpdateMenuItem_DebugStopped_HasWorkspace);
 			//subMenu.AddMenuItem("Compile Current File", null, new (menu) => { CompileCurrentFile(); });
 			//subMenu.AddMenuItem("Compile Current File", null, new (menu) => { CompileCurrentFile(); });

+ 1 - 1
IDE/src/ui/HoverWatch.bf

@@ -796,7 +796,7 @@ namespace IDE.ui
 
 
 			//if (!vals[0].IsEmpty)
 			//if (!vals[0].IsEmpty)
             	String.NewOrSet!(valueSubItem.mLabel, vals[0]);
             	String.NewOrSet!(valueSubItem.mLabel, vals[0]);
-			if (vals[0] == "!sideeffects")
+			if ((vals[0] == "!sideeffects") || (vals[0] == "!incomplete"))
 			{
 			{
 				if (useListViewItem.mWatchRefreshButton == null)
 				if (useListViewItem.mWatchRefreshButton == null)
 				{
 				{

+ 6 - 9
IDE/src/ui/StatusBar.bf

@@ -246,6 +246,7 @@ namespace IDE.ui
         public override void Draw(Graphics g)        
         public override void Draw(Graphics g)        
         {
         {
             bool atError = gApp.mDebugger.GetRunState() == DebugManager.RunState.Exception;
             bool atError = gApp.mDebugger.GetRunState() == DebugManager.RunState.Exception;
+			var debugState = gApp.mDebugger.GetRunState();
 
 
             uint32 bkgColor = 0xFF404040;
             uint32 bkgColor = 0xFF404040;
             if (atError)
             if (atError)
@@ -321,13 +322,13 @@ namespace IDE.ui
 
 
 			float statusLabelPos = (int)GS!(-1.3f);
 			float statusLabelPos = (int)GS!(-1.3f);
 
 
-			if ((gApp.mDebugger?.mIsComptimeDebug == true) && (gApp.mDebugger.IsPaused()))
+			//completionPct = 0.4f;
+			if ((gApp.mDebugger?.mIsComptimeDebug == true) &&
+				((gApp.mDebugger.IsPaused()) || (debugState == .DebugEval)))
 			{
 			{
-			   completionPct = null;
+				g.DrawString("Debugging Comptime", GS!(200), statusLabelPos, FontAlign.Centered, GS!(120));
 			}
 			}
-
-			//completionPct = 0.4f;
-            if (completionPct.HasValue)
+            else if (completionPct.HasValue)
             {                
             {                
                 Rect completionRect = Rect(GS!(200), GS!(2), GS!(120), GS!(15));
                 Rect completionRect = Rect(GS!(200), GS!(2), GS!(120), GS!(15));
                 using (g.PushColor(0xFF000000))
                 using (g.PushColor(0xFF000000))
@@ -336,10 +337,6 @@ namespace IDE.ui
                 using (g.PushColor(0xFF00FF00))
                 using (g.PushColor(0xFF00FF00))
                     g.FillRect(completionRect.mX, completionRect.mY, completionRect.mWidth * completionPct.Value, completionRect.mHeight);
                     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()))
             else if ((gApp.mDebugger.mIsRunning) && (gApp.HaveSourcesChanged()))
             {
             {
                 Rect completionRect = Rect(GS!(200), GS!(1), GS!(120), GS!(17));
                 Rect completionRect = Rect(GS!(200), GS!(1), GS!(120), GS!(17));

+ 0 - 5
IDEHelper/Backend/BeCOFFObject.cpp

@@ -2207,11 +2207,6 @@ bool BeCOFFObject::Generate(BeModule* module, const StringImpl& fileName)
 
 
 void BeCOFFObject::Finish()
 void BeCOFFObject::Finish()
 {
 {
-	if (mBeModule->mModuleName.Contains("vdata"))
-	{
-		NOP;
-	}
-
 	BP_ZONE("BeCOFFObject::Finish");
 	BP_ZONE("BeCOFFObject::Finish");
 	//AutoPerf perf("BeCOFFObject::Finish", mPerfManager);
 	//AutoPerf perf("BeCOFFObject::Finish", mPerfManager);
 
 

+ 3 - 1
IDEHelper/Backend/BeIRCodeGen.cpp

@@ -2883,7 +2883,9 @@ void BeIRCodeGen::HandleNextCmd()
 	case BfIRCmd_DbgGetTypeInst:
 	case BfIRCmd_DbgGetTypeInst:
 		{
 		{
 			CMD_PARAM(int, typeId);
 			CMD_PARAM(int, typeId);
-			SetResult(curId, GetTypeEntry(typeId).mInstDIType);
+			auto result = GetTypeEntry(typeId).mInstDIType;
+			//BF_ASSERT(result);
+			SetResult(curId, result);
 		}
 		}
 		break;
 		break;
 	case BfIRCmd_DbgTrackDITypes:
 	case BfIRCmd_DbgTrackDITypes:

+ 1 - 1
IDEHelper/COFF.cpp

@@ -7172,7 +7172,7 @@ void TestPDB(const StringImpl& fileName, WinDebugger* debugger)
 	COFF coff(debugTarget);		
 	COFF coff(debugTarget);		
 	coff.mDebugger = debugger;
 	coff.mDebugger = debugger;
 	uint8 wantGuid[16];
 	uint8 wantGuid[16];
-	coff.LoadPDB(fileName, wantGuid, -1);
+	coff.TryLoadPDB(fileName, wantGuid, -1);
 	coff.ParseTypeData();
 	coff.ParseTypeData();
 	coff.CvParseIPI();
 	coff.CvParseIPI();
 	coff.ParseGlobalsData();
 	coff.ParseGlobalsData();

+ 1 - 1
IDEHelper/Compiler/BfAst.h

@@ -752,7 +752,7 @@ public:
 
 
 	bool IsNoValueType() const
 	bool IsNoValueType() const
 	{
 	{
-		return (mKind == BfTypedValueKind_NoValue);
+		return (mKind == BfTypedValueKind_NoValue) && (mType != NULL);
 	}
 	}
 
 
 	bool IsParams()
 	bool IsParams()

+ 23 - 5
IDEHelper/Compiler/BfAutoComplete.cpp

@@ -5,6 +5,8 @@
 #include "BfResolvePass.h"
 #include "BfResolvePass.h"
 #include "BfFixits.h"
 #include "BfFixits.h"
 #include "BfResolvedTypeUtils.h"
 #include "BfResolvedTypeUtils.h"
+#include "CeMachine.h"
+#include "CeDebugger.h"
 
 
 #define FTS_FUZZY_MATCH_IMPLEMENTATION
 #define FTS_FUZZY_MATCH_IMPLEMENTATION
 #include "../third_party/FtsFuzzyMatch.h"
 #include "../third_party/FtsFuzzyMatch.h"
@@ -274,7 +276,7 @@ int BfAutoComplete::GetCursorIdx(BfAstNode* node)
 	if (node == NULL)
 	if (node == NULL)
 		return -1;
 		return -1;
 
 
-	if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
+	if (!node->IsFromParser(mCompiler->mResolvePassData->mParser))
 		return -1;
 		return -1;
 
 
 	auto bfParser = node->GetSourceData()->ToParser();
 	auto bfParser = node->GetSourceData()->ToParser();
@@ -288,8 +290,8 @@ bool BfAutoComplete::IsAutocompleteNode(BfAstNode* node, int lengthAdd, int star
 {
 {
 	if (node == NULL)
 	if (node == NULL)
 		return false;
 		return false;
-
-	if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
+	
+	if (!node->IsFromParser(mCompiler->mResolvePassData->mParser))
 		return false;
 		return false;
 
 
 	auto bfParser = node->GetSourceData()->ToParser();
 	auto bfParser = node->GetSourceData()->ToParser();
@@ -311,7 +313,7 @@ bool BfAutoComplete::IsAutocompleteNode(BfAstNode* startNode, BfAstNode* endNode
 	if ((startNode == NULL) || (endNode == NULL))
 	if ((startNode == NULL) || (endNode == NULL))
 		return false;
 		return false;
 
 
-	if ((!mCompiler->mIsResolveOnly) || (!startNode->IsFromParser(mCompiler->mResolvePassData->mParser)))
+	if (!startNode->IsFromParser(mCompiler->mResolvePassData->mParser))
 		return false;
 		return false;
 
 
 	auto bfParser = startNode->GetSourceData()->ToParser();
 	auto bfParser = startNode->GetSourceData()->ToParser();
@@ -333,7 +335,7 @@ bool BfAutoComplete::IsAutocompleteLineNode(BfAstNode* node)
 	if (node == NULL)
 	if (node == NULL)
 		return false;
 		return false;
 
 
-	if ((!mCompiler->mIsResolveOnly) || (!node->IsFromParser(mCompiler->mResolvePassData->mParser)))
+	if (!node->IsFromParser(mCompiler->mResolvePassData->mParser))
 		return false;
 		return false;
 
 
 	auto bfParser = node->GetSourceData()->ToParser();
 	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;
 	BfMethodInstance* curMethodInstance = mModule->mCurMethodInstance;

+ 29 - 14
IDEHelper/Compiler/BfCompiler.cpp

@@ -30,6 +30,7 @@
 #include "../LLVMUtils.h"
 #include "../LLVMUtils.h"
 #include "BfNamespaceVisitor.h"
 #include "BfNamespaceVisitor.h"
 #include "CeMachine.h"
 #include "CeMachine.h"
+#include "CeDebugger.h"
 
 
 #pragma warning(pop)
 #pragma warning(pop)
 
 
@@ -479,15 +480,15 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
 	mLastAutocompleteModule = NULL;
 	mLastAutocompleteModule = NULL;
 
 
 	//if (isResolveOnly)
 	//if (isResolveOnly)
-	//mCEMachine = NULL;
-	mCEMachine = new CeMachine(this);
+	//mCeMachine = NULL;
+	mCeMachine = new CeMachine(this);
 	mCurCEExecuteId = -1;
 	mCurCEExecuteId = -1;
 }
 }
 
 
 BfCompiler::~BfCompiler()
 BfCompiler::~BfCompiler()
 {		
 {		
-	delete mCEMachine;
-	mCEMachine = NULL;
+	delete mCeMachine;
+	mCeMachine = NULL;
 	delete mContext;
 	delete mContext;
 	delete mHotData;
 	delete mHotData;
 	delete mHotState;	
 	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()
 void BfCompiler::HotCommit()
 {
 {
 	if (mHotState == NULL)
 	if (mHotState == NULL)
@@ -6668,8 +6683,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
 	else
 	else
 		mContext->mUnreifiedModule->mIsReified = false;
 		mContext->mUnreifiedModule->mIsReified = false;
 
 
-	if (mCEMachine != NULL)
-		mCEMachine->CompileStarted();
+	if (mCeMachine != NULL)
+		mCeMachine->CompileStarted();
 
 
 	if (mOptions.mAllowHotSwapping)
 	if (mOptions.mAllowHotSwapping)
 	{
 	{
@@ -7476,7 +7491,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
 	}
 	}
 	mCodeGen.ProcessErrors(mPassInstance, mCanceling);
 	mCodeGen.ProcessErrors(mPassInstance, mCanceling);
 
 
-	mCEMachine->CompileDone();
+	mCeMachine->CompileDone();
 
 
 	// This has to happen after codegen because we may delete modules that are referenced in codegen	
 	// This has to happen after codegen because we may delete modules that are referenced in codegen	
 	mContext->Cleanup();	
 	mContext->Cleanup();	
@@ -7541,9 +7556,9 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
 		numModulesWritten, (numModulesWritten != 1) ? "s" : "",
 		numModulesWritten, (numModulesWritten != 1) ? "s" : "",
 		numObjFilesWritten, (numObjFilesWritten != 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();	
 	BpLeave();	
@@ -7658,10 +7673,10 @@ void BfCompiler::Cancel()
 	mCanceling = true;
 	mCanceling = true;
 	mFastFinish = true;
 	mFastFinish = true;
 	mHadCancel = 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;
 		mFastFinish = true;
 	}
 	}
 	BfLogSysM("BfCompiler::Cancel\n");
 	BfLogSysM("BfCompiler::Cancel\n");
@@ -7671,8 +7686,8 @@ void BfCompiler::Cancel()
 void BfCompiler::RequestFastFinish()
 void BfCompiler::RequestFastFinish()
 {
 {
 	mFastFinish = true;
 	mFastFinish = true;
-	if (mCEMachine != NULL)
-		mCEMachine->mSpecialCheck = true;
+	if (mCeMachine != NULL)
+		mCeMachine->mSpecialCheck = true;
 	BfLogSysM("BfCompiler::RequestFastFinish\n");
 	BfLogSysM("BfCompiler::RequestFastFinish\n");
 	BpEvent("BfCompiler::RequestFastFinish", "");
 	BpEvent("BfCompiler::RequestFastFinish", "");
 }
 }

+ 3 - 1
IDEHelper/Compiler/BfCompiler.h

@@ -315,7 +315,7 @@ public:
 	BfPassInstance* mPassInstance;	
 	BfPassInstance* mPassInstance;	
 	FILE* mCompileLogFP;
 	FILE* mCompileLogFP;
 
 
-	CeMachine* mCEMachine;
+	CeMachine* mCeMachine;
 	int mCurCEExecuteId;
 	int mCurCEExecuteId;
 	BfSystem* mSystem;	
 	BfSystem* mSystem;	
 	bool mIsResolveOnly;
 	bool mIsResolveOnly;
@@ -507,6 +507,8 @@ public:
 	void AddDepsToRebuildTypeList(BfTypeInstance* typeInst, HashSet<BfTypeInstance*>& rebuildTypeInstList);
 	void AddDepsToRebuildTypeList(BfTypeInstance* typeInst, HashSet<BfTypeInstance*>& rebuildTypeInstList);
 	void CompileReified();
 	void CompileReified();
 	void PopulateReified();
 	void PopulateReified();
+	bool IsCePaused();
+	bool EnsureCeUnpaused(BfType* refType);
 
 
 	void HotCommit();	
 	void HotCommit();	
 	void HotResolve_Start(HotResolveFlags flags);
 	void HotResolve_Start(HotResolveFlags flags);

+ 2 - 2
IDEHelper/Compiler/BfContext.cpp

@@ -1719,14 +1719,14 @@ void BfContext::DeleteType(BfType* type, bool deferDepRebuilds)
 		for (auto& methodInstGroup : typeInst->mMethodInstanceGroups)
 		for (auto& methodInstGroup : typeInst->mMethodInstanceGroups)
 		{
 		{
 			if ((methodInstGroup.mDefault != NULL) && (methodInstGroup.mDefault->mInCEMachine))
 			if ((methodInstGroup.mDefault != NULL) && (methodInstGroup.mDefault->mInCEMachine))
-				mCompiler->mCEMachine->RemoveMethod(methodInstGroup.mDefault);
+				mCompiler->mCeMachine->RemoveMethod(methodInstGroup.mDefault);
 			if (methodInstGroup.mMethodSpecializationMap != NULL)
 			if (methodInstGroup.mMethodSpecializationMap != NULL)
 			{
 			{
 				for (auto& methodSpecializationItr : *methodInstGroup.mMethodSpecializationMap)
 				for (auto& methodSpecializationItr : *methodInstGroup.mMethodSpecializationMap)
 				{
 				{
 					auto methodInstance = methodSpecializationItr.mValue;
 					auto methodInstance = methodSpecializationItr.mValue;
 					if (methodInstance->mInCEMachine)
 					if (methodInstance->mInCEMachine)
-						mCompiler->mCEMachine->RemoveMethod(methodInstance);
+						mCompiler->mCeMachine->RemoveMethod(methodInstance);
 				}
 				}
 			}
 			}
 		}
 		}

+ 191 - 35
IDEHelper/Compiler/BfExprEvaluator.cpp

@@ -14,6 +14,7 @@
 #include "BeefySysLib/util/BeefPerf.h"
 #include "BeefySysLib/util/BeefPerf.h"
 #include "BfParser.h"
 #include "BfParser.h"
 #include "BfMangler.h"
 #include "BfMangler.h"
+#include "BfDemangler.h"
 #include "BfResolvePass.h"
 #include "BfResolvePass.h"
 #include "BfUtil.h"
 #include "BfUtil.h"
 #include "BfDeferEvalChecker.h"
 #include "BfDeferEvalChecker.h"
@@ -1647,8 +1648,9 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
 	
 	
 	BfMethodInstance* methodInstance = mModule->GetRawMethodInstance(typeInstance, checkMethod);
 	BfMethodInstance* methodInstance = mModule->GetRawMethodInstance(typeInstance, checkMethod);
 	if (methodInstance == NULL)
 	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;
 		return false;
 	}
 	}
 	BfMethodInstance* typeUnspecMethodInstance = mModule->GetUnspecializedMethodInstance(methodInstance, true);	
 	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)
 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 ceContext = ceDebugger->mCurDbgState->mCeContext;
 		auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame;
 		auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame;
 		if (activeFrame->mFunction->mDbgInfo != NULL)
 		if (activeFrame->mFunction->mDbgInfo != NULL)
@@ -4032,9 +4034,13 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
 			{
 			{
 				if (dbgVar.mName == findName)
 				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)
 	if (fieldInstance->mResolvedType == NULL)
 	{
 	{
-		BF_ASSERT((typeInstance->mTypeFailed) || (isResolvingFields));
+		if (mModule->mCompiler->EnsureCeUnpaused(typeInstance))
+		{
+			BF_ASSERT((typeInstance->mTypeFailed) || (isResolvingFields));
+		}
 		return BfTypedValue();
 		return BfTypedValue();
 	}
 	}
 
 
@@ -5234,6 +5243,15 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
 					mModule->PopulateType(curCheckType, BfPopulateType_Data);
 					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());
 				BF_ASSERT(field->mIdx < (int)curCheckType->mFieldInstances.size());
 				auto fieldInstance = &curCheckType->mFieldInstances[field->mIdx];
 				auto fieldInstance = &curCheckType->mFieldInstances[field->mIdx];
 				if (!fieldInstance->mFieldIncluded)
 				if (!fieldInstance->mFieldIncluded)
@@ -6034,7 +6052,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
 
 
 	bool forceBind = false;
 	bool forceBind = false;
 
 
-	if (mModule->mCompiler->mCEMachine != NULL)
+	if (mModule->mCompiler->mCeMachine != NULL)
 	{
 	{
 		bool doConstReturn = false;
 		bool doConstReturn = false;
 
 
@@ -6072,14 +6090,14 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
 				if ((mBfEvalExprFlags & BfEvalExprFlags_NoCeRebuildFlags) != 0)
 				if ((mBfEvalExprFlags & BfEvalExprFlags_NoCeRebuildFlags) != 0)
 					evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_NoRebuild);
 					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)
 					if ((ceDbgState->mDbgExpressionFlags & DwEvalExpressionFlag_AllowCalls) != 0)
 					{	
 					{	
 						ceDbgState->mHadSideEffects = true;
 						ceDbgState->mHadSideEffects = true;
 
 
-						SetAndRestoreValue<CeDebugger*> prevDebugger(mModule->mCompiler->mCEMachine->mDebugger, NULL);
+						//SetAndRestoreValue<CeDebugger*> prevDebugger(mModule->mCompiler->mCeMachine->mDebugger, NULL);
 
 
 						evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_DbgCall);
 						evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_DbgCall);
 						auto result = ceDbgState->mCeContext->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
 						auto result = ceDbgState->mCeContext->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType);
@@ -6093,7 +6111,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
 				}				
 				}				
 				else
 				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)
 					if (constRet)
 					{
 					{
 						auto constant = mModule->mBfIRBuilder->GetConstant(constRet.mValue);
 						auto constant = mModule->mBfIRBuilder->GetConstant(constRet.mValue);
@@ -6121,7 +6139,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
 			}
 			}
 			else
 			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;
 					auto bindFuncVal = bindResult.mFunc;
-					if (mModule->mCompiler->mOptions.mAllowHotSwapping)
+					if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!mModule->mIsComptimeModule))
 						bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
 						bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
 					auto callResult = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
 					auto callResult = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
 					auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
 					auto destCallingConv = mModule->GetIRCallingConvention(bindMethodInstance);
@@ -13022,7 +13040,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
 		}
 		}
 
 
 		auto bindFuncVal = bindResult.mFunc;
 		auto bindFuncVal = bindResult.mFunc;
-		if (mModule->mCompiler->mOptions.mAllowHotSwapping)
+		if ((mModule->mCompiler->mOptions.mAllowHotSwapping) && (!mModule->mIsComptimeModule))
 			bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
 			bindFuncVal = mModule->mBfIRBuilder->RemapBindFunction(bindFuncVal);
 		auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
 		auto callInst = mModule->mBfIRBuilder->CreateCall(bindFuncVal, irArgs);
 		if (GetStructRetIdx(bindMethodInstance) != -1)
 		if (GetStructRetIdx(bindMethodInstance) != -1)
@@ -13083,8 +13101,8 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
 			return;
 			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);
 			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);
 			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);
 		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();
 	}
 	}
 }
 }
 
 
@@ -16584,13 +16602,13 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
 	// We can't flush scope state because we extend params in as arbitrary values
 	// We can't flush scope state because we extend params in as arbitrary values
 	mModule->NewScopeState(true, false);
 	mModule->NewScopeState(true, false);
 
 
-	bool wantsDIData = (mModule->mBfIRBuilder->DbgHasInfo()) && (mModule->mHasFullDebugInfo);
+	bool wantsDIData = (mModule->mBfIRBuilder->DbgHasInfo()) && (mModule->mHasFullDebugInfo);			
 	DISubprogram* diFunction = NULL;
 	DISubprogram* diFunction = NULL;
 		
 		
 	int startLocalIdx = (int)mModule->mCurMethodState->mLocals.size();
 	int startLocalIdx = (int)mModule->mCurMethodState->mLocals.size();
 	int endLocalIdx = startLocalIdx;
 	int endLocalIdx = startLocalIdx;
 
 
-	if (wantsDIData)
+	if ((wantsDIData) || (mModule->mIsComptimeModule))
 	{		
 	{		
 		BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(methodInstance);
 		BfIRMDNode diFuncType = mModule->mBfIRBuilder->DbgCreateSubroutineType(methodInstance);
 
 
@@ -16609,7 +16627,10 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
 			String methodName = methodDef->mName;
 			String methodName = methodDef->mName;
 			methodName += "!";						
 			methodName += "!";						
 			BfMangler::Mangle(methodName, mModule->mCompiler->GetMangleKind(), methodInstance);
 			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());
 				defLine + 1, diFuncType, false, true, mModule->mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
 			scopeData.mAltDIFile = mModule->mCurFilePosition.mFileInstance->mDIFile;
 			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->UpdateSrcPos(methodDeclaration->mNameNode);
 				mModule->SetIllegalSrcPos();
 				mModule->SetIllegalSrcPos();
@@ -16767,7 +16788,7 @@ void BfExprEvaluator::InjectMixin(BfAstNode* targetSrc, BfTypedValue target, boo
 					else if (newLocalVar->mConstValue)
 					else if (newLocalVar->mConstValue)
 						value = newLocalVar->mConstValue;
 						value = newLocalVar->mConstValue;
 
 
-					auto aliasValue = mModule->mBfIRBuilder->CreateAliasValue(value);					
+					auto aliasValue = mModule->mBfIRBuilder->CreateAliasValue(value);
 					if (mModule->WantsLifetimes())
 					if (mModule->WantsLifetimes())
 						scopeData.mDeferredLifetimeEnds.Add(aliasValue);					
 						scopeData.mDeferredLifetimeEnds.Add(aliasValue);					
 
 
@@ -17559,11 +17580,11 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
 		{
 		{
 			if (targetFunctionName.StartsWith("__"))
 			if (targetFunctionName.StartsWith("__"))
 			{
 			{
-				auto ceDebugger = mModule->mCompiler->mCEMachine->mDebugger;
+				auto ceDebugger = mModule->mCompiler->mCeMachine->mDebugger;
 
 
 				auto _ResolveArg = [&](int argIdx, BfType* type = NULL)
 				auto _ResolveArg = [&](int argIdx, BfType* type = NULL)
 				{
 				{
-					if (argIdx >= args.mSize)
+					if ((argIdx < 0) || (argIdx >= args.mSize))
 						return BfTypedValue();
 						return BfTypedValue();
 					return mModule->CreateValueFromExpression(args[argIdx], type);
 					return mModule->CreateValueFromExpression(args[argIdx], type);
 				};
 				};
@@ -17597,6 +17618,141 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
 						return;
 						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)
 				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;
 						bool success = false;
 
 
 						if ((convVal.mValue.IsConst()) && (ptr.mValue.IsConst()))
 						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 constant = mModule->mBfIRBuilder->GetConstant(ptr.mValue);
 							auto valConstant = mModule->mBfIRBuilder->GetConstant(convVal.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)
 							if (!ceTypedVal)
 							{
 							{
 								mModule->Fail("Invalid assignment address", assignExpr);
 								mModule->Fail("Invalid assignment address", assignExpr);
 								return;
 								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)
 								if ((ceDbgState->mDbgExpressionFlags & DwEvalExpressionFlag_AllowSideEffects) != 0)
 								{
 								{
 									ceDbgState->mHadSideEffects = true;
 									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;
 										success = true;
 								}
 								}
 								else
 								else
@@ -20846,7 +21002,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
 					}*/
 					}*/
 
 
 					if (mModule->mIsComptimeModule)
 					if (mModule->mIsComptimeModule)
-						mModule->mCompiler->mCEMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc);
+						mModule->mCompiler->mCeMachine->QueueMethod(oobFunc.mMethodInstance, oobFunc.mFunc);
 
 
 					SizedArray<BfIRValue, 1> args;
 					SizedArray<BfIRValue, 1> args;
 					args.push_back(mModule->GetConstValue(0));
 					args.push_back(mModule->GetConstValue(0));

+ 110 - 51
IDEHelper/Compiler/BfModule.cpp

@@ -1737,8 +1737,8 @@ CeDbgState* BfModule::GetCeDbgState()
 {
 {
 	if (!mIsComptimeModule)
 	if (!mIsComptimeModule)
 		return NULL;
 		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;
 	return NULL;
 }
 }
 
 
@@ -2235,17 +2235,6 @@ bool BfModule::TryLocalVariableInit(BfLocalVariable* localVar)
 
 
 void BfModule::LocalVariableDone(BfLocalVariable* localVar, bool isMethodExit)
 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;
 	BfAstNode* localNameNode = localVar->mNameNode;
 	if (localVar->mIsThis)
 	if (localVar->mIsThis)
 	{
 	{
@@ -3076,19 +3065,26 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
 
 
 	//BF_ASSERT(refNode != NULL);
 	//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;
+
+			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;
 		}
 		}
-		
-		return NULL;
 	}
 	}
 
 
  	if (mCurMethodInstance != NULL)
  	if (mCurMethodInstance != NULL)
@@ -4439,8 +4435,8 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
 		else if (fieldDef->mIsConst)
 		else if (fieldDef->mIsConst)
 		{
 		{
 			int ceExecuteId = -1;
 			int ceExecuteId = -1;
-			if (mCompiler->mCEMachine != NULL)
-				ceExecuteId = mCompiler->mCEMachine->mExecuteId;
+			if (mCompiler->mCeMachine != NULL)
+				ceExecuteId = mCompiler->mCeMachine->mExecuteId;
 			
 			
 			BfTypeState typeState;			
 			BfTypeState typeState;			
 			typeState.mType = mCurTypeInstance;
 			typeState.mType = mCurTypeInstance;
@@ -4463,9 +4459,9 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance,
 				}
 				}
 				UpdateSrcPos(initializer);
 				UpdateSrcPos(initializer);
 				auto result = constResolver.Resolve(initializer, fieldType, resolveFlags);
 				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;
 						fieldInstance->mHadConstEval = true;
 				}
 				}
 				return result;
 				return result;
@@ -5502,7 +5498,7 @@ BfIRValue BfModule::CreateFieldData(BfFieldInstance* fieldInstance, int customAt
 {
 {
 	bool isComptimeArg = mBfIRBuilder->mIgnoreWrites;
 	bool isComptimeArg = mBfIRBuilder->mIgnoreWrites;
 	BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
 	BfFieldDef* fieldDef = fieldInstance->GetFieldDef();
-	
+
 	auto typeInstance = fieldInstance->mOwner;
 	auto typeInstance = fieldInstance->mOwner;
 	
 	
 	BfType* intType = GetPrimitiveType(BfTypeCode_Int32);
 	BfType* intType = GetPrimitiveType(BfTypeCode_Int32);
@@ -10000,6 +9996,8 @@ bool BfModule::IsOptimized()
 {	
 {	
 	if (mProject == NULL)
 	if (mProject == NULL)
 		return false;
 		return false;
+	if (mIsComptimeModule)
+		return false;
 	int optLevel = GetModuleOptions().mOptLevel;
 	int optLevel = GetModuleOptions().mOptLevel;
 	return (optLevel >= BfOptLevel_O1) && (optLevel <= BfOptLevel_O3);
 	return (optLevel >= BfOptLevel_O1) && (optLevel <= BfOptLevel_O3);
 }
 }
@@ -10012,11 +10010,15 @@ bool BfModule::IsTargetingBeefBackend()
 }
 }
 
 
 bool BfModule::WantsLifetimes()
 bool BfModule::WantsLifetimes()
-{	
-	if (mProject == NULL)
-		return false;
+{
 	if (mBfIRBuilder->mIgnoreWrites)
 	if (mBfIRBuilder->mIgnoreWrites)
 		return false;
 		return false;
+
+	if ((mIsComptimeModule) && (mBfIRBuilder->HasDebugLocation()))
+		return true;
+	else if (mProject == NULL)
+		return false;
+
 	return GetModuleOptions().mOptLevel == BfOptLevel_OgPlus;
 	return GetModuleOptions().mOptLevel == BfOptLevel_OgPlus;
 }
 }
 
 
@@ -10086,10 +10088,14 @@ void BfModule::EmitObjectAccessCheck(BfTypedValue typedVal)
 
 
 void BfModule::EmitEnsureInstructionAt()
 void BfModule::EmitEnsureInstructionAt()
 {
 {
-	if (mProject == NULL)
+	if (mBfIRBuilder->mIgnoreWrites)
 		return;
 		return;
 
 
-	if ((mBfIRBuilder->mIgnoreWrites) || (!mHasFullDebugInfo) || (IsOptimized()) || (mCompiler->mOptions.mOmitDebugHelpers))
+	if (mIsComptimeModule)
+	{
+		// Always add
+	}
+	else if ((mProject == NULL) || (!mHasFullDebugInfo) || (IsOptimized()) || (mCompiler->mOptions.mOmitDebugHelpers))
 		return;
 		return;
 
 
 	mBfIRBuilder->CreateEnsureInstructionAt();
 	mBfIRBuilder->CreateEnsureInstructionAt();
@@ -10476,6 +10482,15 @@ BfMethodInstance* BfModule::GetRawMethodInstanceAtIdx(BfTypeInstance* typeInstan
 		BF_ASSERT(typeInstance->mTypeDef->mMethods[methodIdx]->mName == assertName);
 		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];
 	auto& methodGroup = typeInstance->mMethodInstanceGroups[methodIdx];
 	if (methodGroup.mDefault == NULL)
 	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 ceContext = ceDebugger->mCurDbgState->mCeContext;
 				auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame;
 				auto activeFrame = ceDebugger->mCurDbgState->mActiveFrame;
 
 
 				auto ceTypedValue = ceDebugger->GetAddr(constantValue);
 				auto ceTypedValue = ceDebugger->GetAddr(constantValue);
 				if (ceTypedValue)
 				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)
 						if (data == NULL)
 						{
 						{
 							Fail("Invalid address", refNode);
 							Fail("Invalid address", refNode);
 							return GetDefaultTypedValue(typedValue.mType);
 							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(
 						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);
 					auto constVal = ceContext->CreateConstant(this, ceContext->mMemory.mVals + ceTypedValue.mAddr, typedValue.mType);
@@ -13474,7 +13493,7 @@ BfModule* BfModule::GetOrCreateMethodModule(BfMethodInstance* methodInstance)
 }
 }
 
 
 BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags, BfTypeInstance* foreignType)
 BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfMethodDef* methodDef, const BfTypeVector& methodGenericArguments, BfGetMethodInstanceFlags flags, BfTypeInstance* foreignType)
-{
+{	
 	if (methodDef->mMethodType == BfMethodType_Init)
 	if (methodDef->mMethodType == BfMethodType_Init)
 		return BfModuleMethodInstance();
 		return BfModuleMethodInstance();
 
 
@@ -13534,7 +13553,16 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
 				PopulateType(typeInst, BfPopulateType_AllowStaticMethods);
 				PopulateType(typeInst, BfPopulateType_AllowStaticMethods);
 		}
 		}
 		else
 		else
-			PopulateType(typeInst, BfPopulateType_Full);		
+			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;
 	bool tryModuleMethodLookup = false;
@@ -14134,6 +14162,12 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
 		
 		
 	if (methodInstance == NULL)
 	if (methodInstance == NULL)
 	{
 	{
+		if (!mCompiler->EnsureCeUnpaused(typeInst))
+		{
+			BfLogSysM("GetMethodInstance (methodInstance == NULL) bailing due to IsCePaused\n");
+			return BfModuleMethodInstance();
+		}
+
 		if (lookupMethodGenericArguments.size() == 0)
 		if (lookupMethodGenericArguments.size() == 0)
 		{
 		{
 			BF_ASSERT(methodInstGroup->mDefault == NULL);
 			BF_ASSERT(methodInstGroup->mDefault == NULL);
@@ -14586,7 +14620,7 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
 
 
 		if (mIsComptimeModule)
 		if (mIsComptimeModule)
 		{			
 		{			
-			mCompiler->mCEMachine->QueueStaticField(fieldInstance, staticVarName);
+			mCompiler->mCeMachine->QueueStaticField(fieldInstance, staticVarName);
 		}
 		}
 
 
 		PopulateType(typeType);
 		PopulateType(typeType);
@@ -14649,9 +14683,24 @@ void BfModule::MarkUsingThis()
 
 
 BfTypedValue BfModule::GetThis(bool markUsing)
 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;
 	auto useMethodState = mCurMethodState;
@@ -15028,7 +15077,7 @@ void BfModule::DoLocalVariableDebugInfo(BfLocalVariable* localVarDef, bool doAli
 					}
 					}
 					else
 					else
 					{
 					{
-						if ((IsTargetingBeefBackend()) && (doAliasValue))
+						if ((IsTargetingBeefBackend()) && (doAliasValue) && (!mIsComptimeModule))
 						{
 						{
 							diValue = mBfIRBuilder->CreateAliasValue(diValue);
 							diValue = mBfIRBuilder->CreateAliasValue(diValue);
 							mCurMethodState->mCurScope->mDeferredLifetimeEnds.Add(diValue);
 							mCurMethodState->mCurScope->mDeferredLifetimeEnds.Add(diValue);
@@ -15936,6 +15985,8 @@ BfType* BfModule::GetDelegateReturnType(BfType* delegateType)
 	auto typeInst = delegateType->ToTypeInstance();
 	auto typeInst = delegateType->ToTypeInstance();
 	PopulateType(typeInst, BfPopulateType_DataAndMethods);
 	PopulateType(typeInst, BfPopulateType_DataAndMethods);
 	BfMethodInstance* invokeMethodInstance = GetRawMethodInstanceAtIdx(typeInst->ToTypeInstance(), 0, "Invoke");
 	BfMethodInstance* invokeMethodInstance = GetRawMethodInstanceAtIdx(typeInst->ToTypeInstance(), 0, "Invoke");
+	if (invokeMethodInstance == NULL)
+		return GetPrimitiveType(BfTypeCode_Var);
 	return invokeMethodInstance->mReturnType;
 	return invokeMethodInstance->mReturnType;
 }
 }
 
 
@@ -16578,7 +16629,7 @@ void BfModule::EmitDtorBody()
 		
 		
 		auto dtorFunc = GetMethodByName(mContext->mBfObjectType, "~this");
 		auto dtorFunc = GetMethodByName(mContext->mBfObjectType, "~this");
 		if (mIsComptimeModule)
 		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));
 		auto basePtr = mBfIRBuilder->CreateBitCast(thisVal.mValue, mBfIRBuilder->MapTypeInstPtr(mContext->mBfObjectType));
 		SizedArray<BfIRValue, 1> vals = { basePtr };
 		SizedArray<BfIRValue, 1> vals = { basePtr };
 		result = mBfIRBuilder->CreateCall(dtorFunc.mFunc, vals);
 		result = mBfIRBuilder->CreateCall(dtorFunc.mFunc, vals);
@@ -16762,7 +16813,7 @@ void BfModule::EmitDtorBody()
 							SizedArray<BfIRValue, 1> vals = { basePtr };
 							SizedArray<BfIRValue, 1> vals = { basePtr };
 							auto callInst = mBfIRBuilder->CreateCall(dtorMethodInstance.mFunc, vals);
 							auto callInst = mBfIRBuilder->CreateCall(dtorMethodInstance.mFunc, vals);
 							if (mIsComptimeModule)
 							if (mIsComptimeModule)
-								mCompiler->mCEMachine->QueueMethod(dtorMethodInstance.mMethodInstance, dtorMethodInstance.mFunc);
+								mCompiler->mCeMachine->QueueMethod(dtorMethodInstance.mMethodInstance, dtorMethodInstance.mFunc);
 							mBfIRBuilder->SetCallCallingConv(callInst, GetIRCallingConvention(dtorMethodInstance.mMethodInstance));
 							mBfIRBuilder->SetCallCallingConv(callInst, GetIRCallingConvention(dtorMethodInstance.mMethodInstance));
 						}
 						}
 					}
 					}
@@ -17354,7 +17405,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
 				exprEvaluator.PushThis(NULL, GetThis(), moduleMethodInstance.mMethodInstance, irArgs);
 				exprEvaluator.PushThis(NULL, GetThis(), moduleMethodInstance.mMethodInstance, irArgs);
 				exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
 				exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
 				if (mIsComptimeModule)
 				if (mIsComptimeModule)
-					mCompiler->mCEMachine->QueueMethod(moduleMethodInstance);
+					mCompiler->mCeMachine->QueueMethod(moduleMethodInstance);
 
 
 				calledCtorNoBody = true;
 				calledCtorNoBody = true;
 			}
 			}
@@ -17416,7 +17467,11 @@ void BfModule::EmitCtorBody(bool& skipBody)
 						mCurMethodState->mCurScope->mDIInlinedAt = mBfIRBuilder->DbgGetCurrentLocation();
 						mCurMethodState->mCurScope->mDIInlinedAt = mBfIRBuilder->DbgGetCurrentLocation();
 						BF_ASSERT(mCurMethodState->mCurScope->mDIInlinedAt);
 						BF_ASSERT(mCurMethodState->mCurScope->mDIInlinedAt);
 						// mCurMethodState->mCurScope->mDIInlinedAt may still be null ifwe don't have an explicit ctor
 						// 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());
 							mCurFilePosition.mCurLine + 1, diFuncType, false, true, mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
 
 
 						UpdateSrcPos(node);
 						UpdateSrcPos(node);
@@ -17709,7 +17764,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
 				if (callingConv != BfIRCallingConv_CDecl)
 				if (callingConv != BfIRCallingConv_CDecl)
 					mBfIRBuilder->SetCallCallingConv(callInst, callingConv);				
 					mBfIRBuilder->SetCallCallingConv(callInst, callingConv);				
 				if (mIsComptimeModule)
 				if (mIsComptimeModule)
-					mCompiler->mCEMachine->QueueMethod(ctorBodyMethodInstance);
+					mCompiler->mCeMachine->QueueMethod(ctorBodyMethodInstance);
 			}
 			}
 
 
 			if (matchedMethod == NULL)
 			if (matchedMethod == NULL)
@@ -19667,7 +19722,9 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
 	bool wantsDIData = (mBfIRBuilder->DbgHasInfo()) && (!methodDef->IsEmptyPartial()) && (!mBfIRBuilder->mIgnoreWrites) && (mHasFullDebugInfo);
 	bool wantsDIData = (mBfIRBuilder->DbgHasInfo()) && (!methodDef->IsEmptyPartial()) && (!mBfIRBuilder->mIgnoreWrites) && (mHasFullDebugInfo);
 	if (methodDef->mMethodType == BfMethodType_Mixin)
 	if (methodDef->mMethodType == BfMethodType_Mixin)
 		wantsDIData = false;
 		wantsDIData = false;
-	
+	if (mCurTypeInstance->IsUnspecializedType())
+		wantsDIData = false;
+
 	if ((mCurTypeInstance->IsBoxed()) && (methodDef->mMethodType != BfMethodType_Ctor))
 	if ((mCurTypeInstance->IsBoxed()) && (methodDef->mMethodType != BfMethodType_Ctor))
 		wantsDIData = false;
 		wantsDIData = false;
 
 
@@ -22661,6 +22718,8 @@ void BfModule::StartMethodDeclaration(BfMethodInstance* methodInstance, BfMethod
 // methodDeclaration is NULL for default constructors
 // methodDeclaration is NULL for default constructors
 void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool isTemporaryFunc, bool addToWorkList)
 void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool isTemporaryFunc, bool addToWorkList)
 {
 {
+	BF_ASSERT((mCompiler->mCeMachine == NULL) || (!mCompiler->mCeMachine->mDbgPaused));
+
 	BP_ZONE("BfModule::DoMethodDeclaration");	
 	BP_ZONE("BfModule::DoMethodDeclaration");	
 
 
 	// We could trigger a DoMethodDeclaration from a const resolver or other location, so we reset it here
 	// We could trigger a DoMethodDeclaration from a const resolver or other location, so we reset it here

+ 8 - 1
IDEHelper/Compiler/BfModule.h

@@ -1273,6 +1273,13 @@ public:
 	{
 	{
 		return !(*this == other);
 		return !(*this == other);
 	}
 	}
+
+	BfModuleOptions()
+	{
+		mSIMDSetting = BfSIMDSetting_None;
+		mEmitDebugInfo = false;
+		mOptLevel = BfOptLevel_NotSet;
+	}
 };
 };
 
 
 struct BfGenericParamSource
 struct BfGenericParamSource
@@ -1543,7 +1550,7 @@ public:
 	void SetFail();
 	void SetFail();
 	void VerifyOnDemandMethods();
 	void VerifyOnDemandMethods();
 	bool IsSkippingExtraResolveChecks();
 	bool IsSkippingExtraResolveChecks();
-	bool AddErrorContext(StringImpl& errorString, BfAstNode* refNode, bool& isWhileSpecializing, bool isWarning);
+	bool AddErrorContext(StringImpl& errorString, BfAstNode* refNode, bool& isWhileSpecializing, bool isWarning);	
 	CeDbgState* GetCeDbgState();
 	CeDbgState* GetCeDbgState();
 	BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false, bool deferError = false);
 	BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false, bool deferError = false);
 	BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL);
 	BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL);

+ 41 - 28
IDEHelper/Compiler/BfModuleTypeUtils.cpp

@@ -2220,8 +2220,8 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
 		if (methodInstance == NULL)
 		if (methodInstance == NULL)
 			continue;
 			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);
 		BfIRValue attrVal =ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
 		for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
 		for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
@@ -2266,7 +2266,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
 
 
 		DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);			
 		DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);			
 		if (fieldInstance != NULL)
 		if (fieldInstance != NULL)
-			mCompiler->mCEMachine->mFieldInstanceSet.Add(fieldInstance);
+			mCompiler->mCeMachine->mFieldInstanceSet.Add(fieldInstance);
 		BfTypedValue result;
 		BfTypedValue result;
 		///
 		///
 		{
 		{
@@ -2274,7 +2274,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
 			result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_ForceReturnThis, NULL);
 			result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_ForceReturnThis, NULL);
 		}
 		}
 		if (fieldInstance != NULL)
 		if (fieldInstance != NULL)
-			mCompiler->mCEMachine->mFieldInstanceSet.Remove(fieldInstance);
+			mCompiler->mCeMachine->mFieldInstanceSet.Remove(fieldInstance);
 		if (result.mType == methodInstance->GetOwner())
 		if (result.mType == methodInstance->GetOwner())
 			prevAttrInstances[methodInstance->GetOwner()] = result.mValue;
 			prevAttrInstances[methodInstance->GetOwner()] = result.mValue;
 
 
@@ -2334,7 +2334,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
 			}
 			}
 		}
 		}
 
 
-		mCompiler->mCEMachine->ReleaseContext(ceContext);					
+		mCompiler->mCeMachine->ReleaseContext(ceContext);					
 	}
 	}
 }
 }
 
 
@@ -2391,7 +2391,10 @@ void BfModule::CEMixin(BfAstNode* refNode, const StringImpl& code)
 		auto diParentType = mBfIRBuilder->DbgGetTypeInst(mCurTypeInstance);
 		auto diParentType = mBfIRBuilder->DbgGetTypeInst(mCurTypeInstance);
 		if (!mBfIRBuilder->mIgnoreWrites)
 		if (!mBfIRBuilder->mIgnoreWrites)
 		{
 		{
-			String methodName = "Comptime_Mixin";						
+			String methodName = "Comptime_Mixin";				
+			String linkageName;
+			if (mIsComptimeModule)
+				linkageName = StrFormat("Comptime_Mixin:%llX", mCurMethodInstance);
 			mCurMethodState->mCurScope->mDIScope = mBfIRBuilder->DbgCreateFunction(diParentType, methodName, "", mCurFilePosition.mFileInstance->mDIFile,
 			mCurMethodState->mCurScope->mDIScope = mBfIRBuilder->DbgCreateFunction(diParentType, methodName, "", mCurFilePosition.mFileInstance->mDIFile,
 				defLine + 1, diFuncType, false, true, mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
 				defLine + 1, diFuncType, false, true, mCurFilePosition.mCurLine + 1, flags, false, BfIRValue());
 			mCurMethodState->mCurScope->mAltDIFile = mCurFilePosition.mFileInstance->mDIFile;
 			mCurMethodState->mCurScope->mAltDIFile = mCurFilePosition.mFileInstance->mDIFile;
@@ -2502,7 +2505,7 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
 		}
 		}
 		
 		
 		if (!wantsAttributes)
 		if (!wantsAttributes)
-			return;
+			continue;
 
 
 		auto customAttributes = GetCustomAttributes(methodDeclaration->mAttributes, BfAttributeTargets_Method);
 		auto customAttributes = GetCustomAttributes(methodDeclaration->mAttributes, BfAttributeTargets_Method);
 		defer({ delete customAttributes; });
 		defer({ delete customAttributes; });
@@ -2533,15 +2536,15 @@ void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance*
 			continue;
 			continue;
 		}
 		}
 
 
-		SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext);		
+		SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCeMachine->mCurEmitContext);		
 		if (onCompileKind == BfCEOnCompileKind_TypeInit)
 		if (onCompileKind == BfCEOnCompileKind_TypeInit)
 		{
 		{
-			mCompiler->mCEMachine->mCurEmitContext = ceEmitContext;
+			mCompiler->mCeMachine->mCurEmitContext = ceEmitContext;
 		}
 		}
 
 
 		DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);
 		DoPopulateType_CeCheckEnum(typeInstance, underlyingTypeDeferred);
 		auto methodInstance = GetRawMethodInstanceAtIdx(typeInstance, methodDef->mIdx);
 		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))
 		if ((onCompileKind == BfCEOnCompileKind_TypeDone) && (typeInstance->mDefineState > BfTypeDefineState_CETypeInit))
 		{
 		{
@@ -2670,8 +2673,8 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
 		if (applyMethodInstance == NULL)
 		if (applyMethodInstance == NULL)
 			continue;					
 			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);
 		BfIRValue attrVal = ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
 		for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
 		for (int baseIdx = 0; baseIdx < checkDepth; baseIdx++)
@@ -2707,7 +2710,7 @@ void BfModule::DoCEEmit(BfMethodInstance* methodInstance)
 				continue;
 				continue;
 		}
 		}
 
 
-		mCompiler->mCEMachine->mMethodInstanceSet.Add(methodInstance);
+		mCompiler->mCeMachine->mMethodInstanceSet.Add(methodInstance);
 		auto activeTypeDef = typeInstance->mTypeDef;			
 		auto activeTypeDef = typeInstance->mTypeDef;			
 				
 				
 		BfTypedValue result;
 		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)
 	if (populateType == BfPopulateType_Identity)
 		return;
 		return;
 
 
+	if ((populateType <= BfPopulateType_Data) && (resolvedTypeRef->mDefineState >= BfTypeDefineState_Defined))
+		return;
+	
 	auto typeInstance = resolvedTypeRef->ToTypeInstance();
 	auto typeInstance = resolvedTypeRef->ToTypeInstance();
 	auto typeDef = typeInstance->mTypeDef;	
 	auto typeDef = typeInstance->mTypeDef;	
 
 
@@ -3214,7 +3220,21 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 
 
 	if (typeInstance->mResolvingConstField)
 	if (typeInstance->mResolvingConstField)
 		return;
 		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 = [&]()
 	auto _CheckTypeDone = [&]()
 	{
 	{
 		if (typeInstance->mNeedsMethodProcessing)
 		if (typeInstance->mNeedsMethodProcessing)
@@ -3230,13 +3250,6 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 	};
 	};
 
 
 	if (_CheckTypeDone())
 	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;
 		return;
 
 
 	if (!resolvedTypeRef->IsValueType())
 	if (!resolvedTypeRef->IsValueType())
@@ -4482,17 +4495,17 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
 			if ((foundTypeCount >= 2) || (typeInstance->mTypeDef->IsEmitted()))
 			if ((foundTypeCount >= 2) || (typeInstance->mTypeDef->IsEmitted()))
 			{
 			{
 				String error = "OnCompile const evaluation creates a data dependency during TypeInit";
 				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();
 				auto refNode = typeDef->GetRefNode();
 				Fail(error, refNode);
 				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;
 				tryCE = false;
 			}
 			}
  		}
  		}
@@ -11900,7 +11913,7 @@ BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, const BfTypedValue& targe
 			}
 			}
 			bindFuncVal = methodRefMethod.mFunc;
 			bindFuncVal = methodRefMethod.mFunc;
 		}
 		}
-		if (mCompiler->mOptions.mAllowHotSwapping)
+		if ((mCompiler->mOptions.mAllowHotSwapping) && (!mIsComptimeModule))
 			bindFuncVal = mBfIRBuilder->RemapBindFunction(bindFuncVal);
 			bindFuncVal = mBfIRBuilder->RemapBindFunction(bindFuncVal);
 		return mBfIRBuilder->CreatePtrToInt(bindFuncVal, BfTypeCode_IntPtr);
 		return mBfIRBuilder->CreatePtrToInt(bindFuncVal, BfTypeCode_IntPtr);
 	}
 	}

+ 2 - 2
IDEHelper/Compiler/BfResolvedTypeUtils.cpp

@@ -617,8 +617,8 @@ void BfMethodInstance::Dispose(bool isDeleting)
 	if (mInCEMachine)
 	if (mInCEMachine)
 	{
 	{
 		auto module = GetOwner()->mModule;
 		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)
 	if (mMethodProcessRequest != NULL)

+ 2 - 2
IDEHelper/Compiler/BfStmtEvaluator.cpp

@@ -464,7 +464,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc
 		listEntry->mDynList.PushFront(deferredCallEntry);
 		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 int64Type = GetPrimitiveType(BfTypeCode_Int64);
 		auto moduleMethodInstance = deferredCallEntry->mModuleMethodInstance;
 		auto moduleMethodInstance = deferredCallEntry->mModuleMethodInstance;
@@ -511,7 +511,7 @@ bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfSc
 					diFieldTypes.push_back(memberType);
 					diFieldTypes.push_back(memberType);
 				}
 				}
 			}
 			}
-
+			
 			int diFlags = 0;
 			int diFlags = 0;
 			mBfIRBuilder->DbgMakePermanent(diForwardDecl, BfIRMDNode(), diFieldTypes);
 			mBfIRBuilder->DbgMakePermanent(diForwardDecl, BfIRMDNode(), diFieldTypes);
 			deferDIType = mBfIRBuilder->DbgCreatePointerType(diForwardDecl);
 			deferDIType = mBfIRBuilder->DbgCreatePointerType(diForwardDecl);

File diff ditekan karena terlalu besar
+ 537 - 171
IDEHelper/Compiler/CeDebugger.cpp


+ 59 - 9
IDEHelper/Compiler/CeDebugger.h

@@ -17,6 +17,15 @@ class CeFunction;
 class BfReducer;
 class BfReducer;
 class CeDebugger;
 class CeDebugger;
 class DebugVisualizerEntry;
 class DebugVisualizerEntry;
+class CeEvaluationContext;
+
+class CeBreakpointCondition
+{
+public:
+	CeEvaluationContext* mDbgEvaluationContext;
+	String mExpr;
+	~CeBreakpointCondition();
+};
 
 
 class CeBreakpoint : public Breakpoint
 class CeBreakpoint : public Breakpoint
 {
 {
@@ -24,6 +33,7 @@ public:
 	uintptr mCurBindAddr;
 	uintptr mCurBindAddr;
 	bool mHasBound;
 	bool mHasBound;
 	int mIdx;
 	int mIdx;
+	CeBreakpointCondition* mCondition;
 
 
 public:
 public:
 	CeBreakpoint()
 	CeBreakpoint()
@@ -31,8 +41,10 @@ public:
 		mCurBindAddr = 1;
 		mCurBindAddr = 1;
 		mHasBound = false;
 		mHasBound = false;
 		mIdx = -1;
 		mIdx = -1;
+		mCondition = NULL;
 	}
 	}
 
 
+	~CeBreakpoint();
 	virtual uintptr GetAddr() { return mCurBindAddr; }
 	virtual uintptr GetAddr() { return mCurBindAddr; }
 	virtual bool IsMemoryBreakpointBound() { return false; }
 	virtual bool IsMemoryBreakpointBound() { return false; }
 };
 };
@@ -98,7 +110,7 @@ public:
 	void Init(CeDebugger* winDebugger, const StringImpl& expr, CeFormatInfo* formatInfo = NULL, BfTypedValue contextValue = BfTypedValue());
 	void Init(CeDebugger* winDebugger, const StringImpl& expr, CeFormatInfo* formatInfo = NULL, BfTypedValue contextValue = BfTypedValue());
 	bool HasExpression();
 	bool HasExpression();
 	~CeEvaluationContext();
 	~CeEvaluationContext();
-	BfTypedValue EvaluateInContext(BfTypedValue contextTypedValue);
+	BfTypedValue EvaluateInContext(BfTypedValue contextTypedValue, CeDbgState* dbgState = NULL);	
 	String GetErrorStr();
 	String GetErrorStr();
 	bool HadError();
 	bool HadError();
 };
 };
@@ -110,17 +122,21 @@ public:
 	CeContext* mCeContext;
 	CeContext* mCeContext;
 	BfTypedValue mExplicitThis;
 	BfTypedValue mExplicitThis;
 	DwEvalExpressionFlags mDbgExpressionFlags;
 	DwEvalExpressionFlags mDbgExpressionFlags;
+	CeFormatInfo* mFormatInfo;
 	bool mHadSideEffects;
 	bool mHadSideEffects;
 	bool mBlockedSideEffects;
 	bool mBlockedSideEffects;
+	bool mReferencedIncompleteTypes;
 
 
 public:
 public:
 	CeDbgState()
 	CeDbgState()
 	{
 	{
 		mActiveFrame = NULL;
 		mActiveFrame = NULL;
 		mCeContext = NULL;
 		mCeContext = NULL;
+		mFormatInfo = NULL;
 		mDbgExpressionFlags = DwEvalExpressionFlag_None;
 		mDbgExpressionFlags = DwEvalExpressionFlag_None;
 		mHadSideEffects = false;
 		mHadSideEffects = false;
 		mBlockedSideEffects = false;
 		mBlockedSideEffects = false;
+		mReferencedIncompleteTypes = false;
 	}
 	}
 };
 };
 
 
@@ -128,6 +144,7 @@ class CePendingExpr
 {
 {
 public:
 public:
 	int mThreadId;
 	int mThreadId;
+	BfPassInstance* mPassInstance;
 	BfParser* mParser;
 	BfParser* mParser;
 	BfType* mExplitType;
 	BfType* mExplitType;
 	CeFormatInfo mFormatInfo;
 	CeFormatInfo mFormatInfo;
@@ -138,12 +155,21 @@ public:
 	int mCallStackIdx;
 	int mCallStackIdx;
 	String mResult;	
 	String mResult;	
 	int mIdleTicks;
 	int mIdleTicks;
-	String mException;
+	String mException;	
+	bool mDone;
 
 
 	CePendingExpr();
 	CePendingExpr();
 	~CePendingExpr();
 	~CePendingExpr();
 };
 };
 
 
+class CeDbgStackInfo
+{
+public:
+	int mFrameIdx;
+	int mScopeIdx;
+	int mInlinedFrom;
+};
+
 class CeFileInfo
 class CeFileInfo
 {
 {
 public:
 public:
@@ -182,7 +208,7 @@ public:
 
 
 struct CeTypedValue
 struct CeTypedValue
 {
 {
-	addr_ce mAddr;
+	int64 mAddr;
 	BfIRType mType;
 	BfIRType mType;
 
 
 	CeTypedValue()
 	CeTypedValue()
@@ -191,7 +217,7 @@ struct CeTypedValue
 		mType = BfIRType();
 		mType = BfIRType();
 	}
 	}
 
 
-	CeTypedValue(addr_ce addr, BfIRType type)
+	CeTypedValue(int64 addr, BfIRType type)
 	{
 	{
 		mAddr = addr;
 		mAddr = addr;
 		mType = type;
 		mType = type;
@@ -203,6 +229,13 @@ struct CeTypedValue
 	}
 	}
 };
 };
 
 
+enum CeTypeModKind
+{
+	CeTypeModKind_Normal,
+	CeTypeModKind_Const,
+	CeTypeModKind_ReadOnly
+};
+
 class CeDebugger : public Debugger
 class CeDebugger : public Debugger
 {
 {
 public:
 public:
@@ -212,8 +245,9 @@ public:
 	CePendingExpr* mDebugPendingExpr;
 	CePendingExpr* mDebugPendingExpr;
 	CeDbgState* mCurDbgState;	
 	CeDbgState* mCurDbgState;	
 	Array<CeBreakpoint*> mBreakpoints;
 	Array<CeBreakpoint*> mBreakpoints;
-	Dictionary<String, CeFileInfo*> mFileInfo;
+	Dictionary<String, CeFileInfo*> mFileInfo;	
 	Dictionary<int, CeDbgTypeInfo> mDbgTypeInfoMap;
 	Dictionary<int, CeDbgTypeInfo> mDbgTypeInfoMap;
+	Array<CeDbgStackInfo> mDbgCallStack;
 
 
 	CeEvaluationContext* mCurEvaluationContext;
 	CeEvaluationContext* mCurEvaluationContext;
 	CeBreakpoint* mActiveBreakpoint;
 	CeBreakpoint* mActiveBreakpoint;
@@ -221,11 +255,23 @@ public:
 	bool mBreakpointCacheDirty;	
 	bool mBreakpointCacheDirty;	
 	bool mBreakpointFramesDirty;
 	bool mBreakpointFramesDirty;
 	int mCurDisasmFuncId;
 	int mCurDisasmFuncId;
+	int mPendingActiveFrameOffset;
 
 
 public:
 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);
 	bool SetupStep(int frameIdx = 0);
-	CeFrame* GetFrame(int callStackIdx);
-	String EvaluateContinue(CePendingExpr* pendingExpr, BfPassInstance& bfPassInstance);
+	CeFrame* GetFrame(int callStackIdx);	
+	String DoEvaluate(CePendingExpr* pendingExpr, bool inCompilerThread);
 	String Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags);
 	String Evaluate(const StringImpl& expr, CeFormatInfo formatInfo, int callStackIdx, int cursorPos, int language, DwEvalExpressionFlags expressionFlags);
 	DwDisplayInfo* GetDisplayInfo(const StringImpl& referenceId);
 	DwDisplayInfo* GetDisplayInfo(const StringImpl& referenceId);
 	String GetMemberList(BfType* type, addr_ce addr, addr_ce addrInst, bool isStatic);
 	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 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);
 	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);
 	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);
 	CeTypedValue GetAddr(const BfTypedValue typeVal);
 	String ReadString(BfTypeCode charType, intptr addr, intptr maxLength, CeFormatInfo& formatInfo);
 	String ReadString(BfTypeCode charType, intptr addr, intptr maxLength, CeFormatInfo& formatInfo);
 	void ProcessEvalString(BfTypedValue useTypedValue, String& evalStr, String& displayString, CeFormatInfo& formatInfo, DebugVisualizerEntry* debugVis, bool limitLength);
 	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);
 	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 ClearBreakpointCache();
 	void UpdateBreakpointCache();
 	void UpdateBreakpointCache();
 	void UpdateBreakpointFrames();
 	void UpdateBreakpointFrames();
@@ -253,8 +300,11 @@ public:
 	void Continue();
 	void Continue();
 	CeDbgTypeInfo* GetDbgTypeInfo(int typeId);
 	CeDbgTypeInfo* GetDbgTypeInfo(int typeId);
 	CeDbgTypeInfo* GetDbgTypeInfo(BfIRType irType);
 	CeDbgTypeInfo* GetDbgTypeInfo(BfIRType irType);
+	int64 ValueToInt(addr_ce addr, BfType* type);
 	int64 ValueToInt(const BfTypedValue& typedVal);
 	int64 ValueToInt(const BfTypedValue& typedVal);
 	BfType* FindType(const StringImpl& name);
 	BfType* FindType(const StringImpl& name);
+	String TypeToString(const BfTypedValue& typedValue);
+	String TypeToString(BfType* type, CeTypeModKind typeModKind);
 
 
 public:
 public:
 	CeDebugger(DebugManager* debugManager, BfCompiler* bfCompiler);
 	CeDebugger(DebugManager* debugManager, BfCompiler* bfCompiler);

+ 459 - 106
IDEHelper/Compiler/CeMachine.cpp

@@ -96,6 +96,7 @@ struct CeOpInfo
 static CeOpInfo gOpInfo[] =
 static CeOpInfo gOpInfo[] =
 {
 {
 	{"InvalidOp"},
 	{"InvalidOp"},
+	{"Nop"},
 	{"DbgBreak"},
 	{"DbgBreak"},
 	{"Ret"},
 	{"Ret"},
 	{"SetRet", CEOI_None, CEOI_IMM32},
 	{"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()
 CeInternalData::~CeInternalData()
 {
 {
 	switch (mKind)
 	switch (mKind)
@@ -391,6 +421,19 @@ CeEmitEntry* CeFunction::FindEmitEntry(int instIdx, int* entryIdx)
 	return emitEntry;
 	return emitEntry;
 }
 }
 
 
+int CeFunction::SafeGetId()
+{
+	__try
+	{
+		return mId;
+	}
+	__except (EXCEPTION_EXECUTE_HANDLER)
+	{
+
+	}
+	return 0;
+}
+
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
 
 CeFunctionInfo::~CeFunctionInfo()
 CeFunctionInfo::~CeFunctionInfo()
@@ -643,7 +686,7 @@ void CeBuilder::Fail(const StringImpl& str)
 	if (!mCeFunction->mGenError.IsEmpty())
 	if (!mCeFunction->mGenError.IsEmpty())
 		return;
 		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)
 	if (mCurDbgLoc != NULL)
 	{
 	{
 		String filePath;
 		String filePath;
@@ -927,6 +970,51 @@ CeOperand CeBuilder::EmitConst(int64 val, int size)
 	return result;
 	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)
 CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImmediate)
 {
 {
 	if (value == NULL)
 	if (value == NULL)
@@ -1281,55 +1369,25 @@ CeOperand CeBuilder::GetOperand(BeValue* value, bool allowAlloca, bool allowImme
 	case BeFunction::TypeId:		
 	case BeFunction::TypeId:		
 		{
 		{
 			auto beFunction = (BeFunction*)value;
 			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)
 			if (allowImmediate)
 			{
 			{
 				CeOperand result;
 				CeOperand result;
 				result.mKind = CeOperandKind_CallTableIdx;
 				result.mKind = CeOperandKind_CallTableIdx;
-				result.mCallTableIdx = *callIdxPtr;
+				result.mCallTableIdx = callIdx;
 				return result;
 				return result;
 			}
 			}
 
 
+			BF_ASSERT(callIdx <= mCeFunction->mCallTable.mSize);
+
 			CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
 			CeOperand result = FrameAlloc(mCeMachine->GetBeContext()->GetPrimitiveType((sizeof(BfMethodInstance*) == 8) ? BeTypeCode_Int64 : BeTypeCode_Int32));
 			Emit(CeOp_GetMethod);
 			Emit(CeOp_GetMethod);
 			EmitFrameOffset(result);
 			EmitFrameOffset(result);
-			Emit((int32)*callIdxPtr);
+			Emit((int32)callIdx);
 			return result;
 			return result;
 		}
 		}
 		break;
 		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()
 void CeBuilder::HandleParams()
 {
 {
  	auto beModule = mBeFunction->mModule;
  	auto beModule = mBeFunction->mModule;
@@ -1480,6 +1552,10 @@ void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance
 
 
 void CeBuilder::Build()
 void CeBuilder::Build()
 {
 {
+	SetAndRestoreValue<CeDbgState*> prevDbgState;
+	if (mCeMachine->mDebugger != NULL)
+		prevDbgState.Init(mCeMachine->mDebugger->mCurDbgState, NULL);
+
 	auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
 	auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
 	auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
 	auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
 	auto beModule = irCodeGen->mBeModule;
 	auto beModule = irCodeGen->mBeModule;
@@ -1493,7 +1569,7 @@ void CeBuilder::Build()
 		BfMethodInstance dupMethodInstance;
 		BfMethodInstance dupMethodInstance;
 		dupMethodInstance.CopyFrom(methodInstance);
 		dupMethodInstance.CopyFrom(methodInstance);
 		auto methodDef = methodInstance->mMethodDef;
 		auto methodDef = methodInstance->mMethodDef;
-		
+
 		bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (methodInstance->GetOwner()->IsUnspecializedTypeVariation());				
 		bool isGenericVariation = (methodInstance->mIsUnspecializedVariation) || (methodInstance->GetOwner()->IsUnspecializedTypeVariation());				
 		int dependentGenericStartIdx = 0;
 		int dependentGenericStartIdx = 0;
 		if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) ||
 		if ((((methodInstance->mMethodInfoEx != NULL) && ((int)methodInstance->mMethodInfoEx->mMethodGenericArguments.size() > dependentGenericStartIdx)) ||
@@ -1510,7 +1586,7 @@ void CeBuilder::Build()
 		}
 		}
 		
 		
 		// Clear this so we can properly get QueueStaticField calls
 		// Clear this so we can properly get QueueStaticField calls
-		mCeMachine->mCeModule->mStaticFieldRefs.Clear();
+		mCeMachine->mCeModule->mStaticFieldRefs.Clear();		
 
 
 		int startFunctionCount = (int)beModule->mFunctions.size();
 		int startFunctionCount = (int)beModule->mFunctions.size();
 		ProcessMethod(methodInstance, &dupMethodInstance, true);			
 		ProcessMethod(methodInstance, &dupMethodInstance, true);			
@@ -1640,6 +1716,8 @@ void CeBuilder::Build()
 		}
 		}
 	}
 	}
 
 
+	int scopeIdx = -1;
+
 	// Primary instruction pass
 	// Primary instruction pass
 	BeDbgLoc* prevEmitDbgPos = NULL;
 	BeDbgLoc* prevEmitDbgPos = NULL;
 	bool inHeadAlloca = true;
 	bool inHeadAlloca = true;
@@ -1661,6 +1739,98 @@ void CeBuilder::Build()
 			int startCodePos = GetCodePos();
 			int startCodePos = GetCodePos();
 
 
 			mCurDbgLoc = inst->mDbgLoc;			
 			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();
 			int instType = inst->GetTypeId();
 
 
@@ -1676,11 +1846,9 @@ void CeBuilder::Build()
 			}
 			}
 
 
 			switch (instType)
 			switch (instType)
-			{
-			case BeEnsureInstructionAtInst::TypeId:
+			{			
 			case BeNopInst::TypeId:			
 			case BeNopInst::TypeId:			
-			case BeLifetimeStartInst::TypeId:
-			case BeLifetimeEndInst::TypeId:
+			case BeLifetimeStartInst::TypeId:			
 			case BeLifetimeExtendInst::TypeId:
 			case BeLifetimeExtendInst::TypeId:
 			case BeValueScopeStartInst::TypeId:
 			case BeValueScopeStartInst::TypeId:
 			case BeValueScopeEndInst::TypeId:
 			case BeValueScopeEndInst::TypeId:
@@ -3007,21 +3175,55 @@ void CeBuilder::Build()
 			case BeDbgDeclareInst::TypeId:
 			case BeDbgDeclareInst::TypeId:
 				{
 				{
 					auto castedInst = (BeDbgDeclareInst*)inst;
 					auto castedInst = (BeDbgDeclareInst*)inst;
-					auto mcValue = GetOperand(castedInst->mValue, true);
+					auto mcValue = GetOperand(castedInst->mValue, true);					
 
 
 					if (mCeFunction->mDbgInfo != NULL)
 					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))
 						{
 						{
-							CeDbgVariable dbgVariable;
+							mDbgVariableMap[castedInst->mValue] = mCeFunction->mDbgInfo->mVariables.mSize;
+
+							CeDbgVariable dbgVariable;							
 							dbgVariable.mName = castedInst->mDbgVar->mName;
 							dbgVariable.mName = castedInst->mDbgVar->mName;
 							dbgVariable.mValue = mcValue;
 							dbgVariable.mValue = mcValue;
 							dbgVariable.mType = mCeMachine->mCeModule->mContext->mTypes[dbgTypeId->mTypeId];
 							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);
 							mCeFunction->mDbgInfo->mVariables.Add(dbgVariable);
 						}
 						}
 					}
 					}
 				}
 				}
 				break;
 				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:
 			default:
 				Fail("Unhandled instruction");
 				Fail("Unhandled instruction");
 				return;
 				return;
@@ -3031,32 +3233,11 @@ void CeBuilder::Build()
 				mValueToOperand[inst] = result;
 				mValueToOperand[inst] = result;
 
 
 			if ((startCodePos != GetCodePos()) && (prevEmitDbgPos != mCurDbgLoc))
 			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;
 				CeEmitEntry emitEntry;
 				emitEntry.mCodePos = startCodePos;
 				emitEntry.mCodePos = startCodePos;
 				emitEntry.mScope = scopeIdx;
 				emitEntry.mScope = scopeIdx;
-				if (mCurDbgLoc != NULL)
+				if ((mCurDbgLoc != NULL) && (mCurDbgLoc->mLine != -1))
 				{
 				{
 					emitEntry.mLine = mCurDbgLoc->mLine;
 					emitEntry.mLine = mCurDbgLoc->mLine;
 					emitEntry.mColumn = mCurDbgLoc->mColumn;
 					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)
 	for (auto& jumpEntry : mJumpTable)
 	{
 	{
 		auto& ceBlock = mBlocks[jumpEntry.mBlockIdx];
 		auto& ceBlock = mBlocks[jumpEntry.mBlockIdx];
@@ -3091,9 +3279,14 @@ void CeBuilder::Build()
 		Fail("No method definition available");
 		Fail("No method definition available");
 		return;
 		return;
 	}
 	}
-
+	
 	if (mCeFunction->mGenError.IsEmpty())
 	if (mCeFunction->mGenError.IsEmpty())
 		mCeFunction->mFailed = false;
 		mCeFunction->mFailed = false;
+	else
+	{
+		NOP;
+	}
+
 	mCeFunction->mFrameSize = mFrameSize;	
 	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);
 	auto bfError = mCurModule->Fail(StrFormat("Unable to comptime %s", mCurModule->MethodToString(mCurMethodInstance).c_str()), mCurTargetSrc, (mCurEvalFlags & CeEvalFlags_PersistantError) != 0);
 	if (bfError == NULL)
 	if (bfError == NULL)
 		return NULL;
 		return NULL;
-	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;
 	return bfError;
 }
 }
 
 
@@ -3158,7 +3355,7 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
 
 
 		auto ceFunction = ceFrame->mFunction;		
 		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;
 		StringT<256> err;
 		if (isHeadEntry)
 		if (isHeadEntry)
 		{
 		{
@@ -3175,38 +3372,97 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
 			contextTypeInstance = contextMethodInstance->GetOwner();
 			contextTypeInstance = contextMethodInstance->GetOwner();
 		}
 		}
 
 
-		err += StrFormat("in comptime ");
-		
-		//
+		auto _AddCeMethodInstance = [&](BfMethodInstance* methodInstance)
 		{
 		{
 			SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, contextTypeInstance);
 			SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCeMachine->mCeModule->mCurTypeInstance, contextTypeInstance);
-			SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, contextMethodInstance);
-
-			if (ceFunction->mMethodInstance != NULL)
-				err += mCeMachine->mCeModule->MethodToString(ceFunction->mMethodInstance, BfMethodNameFlag_OmitParams);
-			else
-			{
-				err += mCeMachine->mCeModule->MethodToString(ceFunction->mCeInnerFunctionInfo->mOwner->mMethodInstance, BfMethodNameFlag_OmitParams);
-			}
-		}
+			SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mCeMachine->mCeModule->mCurMethodInstance, contextMethodInstance);			
+			err += mCeMachine->mCeModule->MethodToString(methodInstance, 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);
 			auto moreInfo = passInstance->MoreInfo(err, mCeMachine->mCeModule->mCompiler->GetAutoComplete() != NULL);
 			if ((moreInfo != NULL))
 			if ((moreInfo != NULL))
 			{
 			{
 				BfErrorLocation* location = new BfErrorLocation();
 				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;
 				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
 		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)
 	switch (constant->mTypeCode)
 	{
 	{
+	case BfTypeCode_None:
+		return true;
 	case BfTypeCode_Int8:
 	case BfTypeCode_Int8:
 	case BfTypeCode_UInt8:
 	case BfTypeCode_UInt8:
 	case BfTypeCode_Boolean:
 	case BfTypeCode_Boolean:
@@ -3966,12 +4224,21 @@ bool CeContext::WriteConstant(BfModule* module, addr_ce addr, BfConstant* consta
 
 
 	if (constant->mConstType == BfConstType_PtrToInt)
 	if (constant->mConstType == BfConstType_PtrToInt)
 	{
 	{
-		auto ptrToIntConst = (BfConstantPtrToInt*)constant;		
+		auto ptrToIntConst = (BfConstantPtrToInt*)constant;
 
 
 		auto constTarget = module->mBfIRBuilder->GetConstantById(ptrToIntConst->mTarget);
 		auto constTarget = module->mBfIRBuilder->GetConstantById(ptrToIntConst->mTarget);
 		return WriteConstant(module, addr, constTarget, type);
 		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)
 	if (constant->mConstType == BfConstType_BitCastNull)
 	{
 	{
 		BF_ASSERT(type->IsPointer() || type->IsObjectOrInterface());
 		BF_ASSERT(type->IsPointer() || type->IsObjectOrInterface());
@@ -4099,6 +4366,8 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
 
 
 		switch (typeCode)
 		switch (typeCode)
 		{
 		{
+		case BfTypeCode_None:
+			return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, 0);
 		case BfTypeCode_Int8:
 		case BfTypeCode_Int8:
 			CE_CREATECONST_CHECKPTR(ptr, sizeof(int8));
 			CE_CREATECONST_CHECKPTR(ptr, sizeof(int8));
 			return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(int8*)ptr);
 			return irBuilder->CreateConst(primType->mTypeDef->mTypeCode, *(int8*)ptr);
@@ -5091,6 +5360,8 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
 	ceFunction = CEFUNC; \
 	ceFunction = CEFUNC; \
 	framePtr = stackPtr; \
 	framePtr = stackPtr; \
 	stackPtr -= ceFunction->mFrameSize; \
 	stackPtr -= ceFunction->mFrameSize; \
+	if (isDebugging) \
+		memset(stackPtr, 0, ceFunction->mFrameSize); \
 	instPtr = &ceFunction->mCode[0]; \
 	instPtr = &ceFunction->mCode[0]; \
 	CE_CHECKSTACK();
 	CE_CHECKSTACK();
 
 
@@ -5164,6 +5435,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 	uint8* framePtr = startFramePtr;
 	uint8* framePtr = startFramePtr;
 	bool needsFunctionIds = ceModule->mSystem->mPtrSize != 8;
 	bool needsFunctionIds = ceModule->mSystem->mPtrSize != 8;
 	int32 ptrSize = ceModule->mSystem->mPtrSize;
 	int32 ptrSize = ceModule->mSystem->mPtrSize;
+	bool isDebugging = mCeMachine->mDebugger != NULL;
 
 
 	volatile bool* specialCheckPtr = &mCeMachine->mSpecialCheck;
 	volatile bool* specialCheckPtr = &mCeMachine->mSpecialCheck;
 	volatile bool* fastFinishPtr = &mCeMachine->mCompiler->mFastFinish;
 	volatile bool* fastFinishPtr = &mCeMachine->mCompiler->mFastFinish;
@@ -5193,21 +5465,72 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 	
 	
 	auto _DbgPause = [&]()
 	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->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++;
 		}
 		}
 	};
 	};
 
 
@@ -5280,7 +5603,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 			}
 			}
 			else if (checkFunction->mFunctionKind == CeFunctionKind_FatalError)
 			else if (checkFunction->mFunctionKind == CeFunctionKind_FatalError)
 			{
 			{
-				int32 strInstAddr = *(int32*)((uint8*)stackPtr + 0);
+				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: ";
 				String error = "Fatal Error: ";
 				GetStringFromAddr(strInstAddr, error);
 				GetStringFromAddr(strInstAddr, error);
@@ -6590,7 +6917,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 		if (!checkFunction->mFailed)		
 		if (!checkFunction->mFailed)		
 			return true;
 			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()));
 			_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()));
 		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:
 		OpSwitch:
 		switch (op)
 		switch (op)
 		{
 		{
+		case CeOp_Nop:
+			break;
 		case CeOp_DbgBreak:
 		case CeOp_DbgBreak:
 		{
 		{
 			bool foundBreakpoint = false;
 			bool foundBreakpoint = false;
+			bool skipInst = false;
 
 
 			if (mCeMachine->mDebugger != NULL)
 			if (mCeMachine->mDebugger != NULL)
 			{
 			{
@@ -6725,14 +7055,36 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
 				CeBreakpointBind* breakpointEntry = NULL;
 				CeBreakpointBind* breakpointEntry = NULL;
 				if (ceFunction->mBreakpoints.TryGetValue(instIdx, &breakpointEntry))
 				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;
 					op = breakpointEntry->mPrevOpCode;
+					// Keep us from an infinite loop if we set a breakpoint on a manual Break
+					skipInst = op == CeOp_DbgBreak;
+
 					foundBreakpoint = true;
 					foundBreakpoint = true;
+
+					if (!doBreak)
+					{
+						_FixVariables();
+						if (skipInst)
+							break;
+						goto OpSwitch;						
+					}
+
+					mCeMachine->mDebugger->mActiveBreakpoint = breakpointEntry->mBreakpoint;
 				}
 				}
 			}
 			}
 
 
 			_DbgPause();
 			_DbgPause();
 			if (mCeMachine->mStepState.mKind == CeStepState::Kind_Jmp)
 			if (mCeMachine->mStepState.mKind == CeStepState::Kind_Jmp)
 				goto SpecialCheck;
 				goto SpecialCheck;
+			if (skipInst)
+				break;
 			if (foundBreakpoint)
 			if (foundBreakpoint)
 				goto OpSwitch;
 				goto OpSwitch;
 		}
 		}
@@ -8182,7 +8534,8 @@ void CeMachine::Init()
 	mCeModule->mBfIRBuilder = new BfIRBuilder(mCeModule);
 	mCeModule->mBfIRBuilder = new BfIRBuilder(mCeModule);
 	mCeModule->mBfIRBuilder->mDbgVerifyCodeGen = true;
 	mCeModule->mBfIRBuilder->mDbgVerifyCodeGen = true;
 	mCeModule->FinishInit();
 	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->mBfIRBuilder->mIgnoreWrites = false;
 	mCeModule->mWantsIRIgnoreWrites = false;
 	mCeModule->mWantsIRIgnoreWrites = false;
 }
 }

+ 109 - 23
IDEHelper/Compiler/CeMachine.h

@@ -4,6 +4,7 @@
 #include "BfModule.h"
 #include "BfModule.h"
 #include "BeefySysLib/util/Heap.h"
 #include "BeefySysLib/util/Heap.h"
 #include "BeefySysLib/util/AllocDebug.h"
 #include "BeefySysLib/util/AllocDebug.h"
+#include "BfMangler.h"
 
 
 NS_BF_BEGIN
 NS_BF_BEGIN
 
 
@@ -71,6 +72,7 @@ enum CeErrorKind
 enum CeOp : int16
 enum CeOp : int16
 {
 {
 	CeOp_InvalidOp,
 	CeOp_InvalidOp,
+	CeOp_Nop,
 	CeOp_DbgBreak,
 	CeOp_DbgBreak,
 	CeOp_Ret,
 	CeOp_Ret,
 	CeOp_SetRetType,
 	CeOp_SetRetType,
@@ -260,6 +262,49 @@ struct CeEmitEntry
 	int mColumn;
 	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
 class CeFunctionInfo
 {
 {
 public:
 public:
@@ -540,10 +585,14 @@ public:
 
 
 class CeDbgVariable
 class CeDbgVariable
 {
 {
-public:
+public:	
 	String mName;
 	String mName;
 	CeOperand mValue;
 	CeOperand mValue;
 	BfType* mType;
 	BfType* mType;
+	int mScope;
+	bool mIsConst;
+	int mStartCodePos;
+	int mEndCodePos;
 };
 };
 
 
 class CeDbgFunctionInfo
 class CeDbgFunctionInfo
@@ -559,19 +608,6 @@ public:
 	CeBreakpoint* mBreakpoint;
 	CeBreakpoint* mBreakpoint;
 };
 };
 
 
-struct CeDbgScope
-{
-public:
-	String mFilePath;
-	int mInlinedAt;
-
-public:
-	CeDbgScope()
-	{
-		mInlinedAt = -1;
-	}
-};
-
 class CeFunction
 class CeFunction
 {
 {
 public:
 public:
@@ -594,8 +630,10 @@ public:
 	bool mIsVarReturn;
 	bool mIsVarReturn;
 	Array<uint8> mCode;	
 	Array<uint8> mCode;	
 	Array<CeDbgScope> mDbgScopes;
 	Array<CeDbgScope> mDbgScopes;
-	Array<CeEmitEntry> mEmitTable;
-	Array<CeCallEntry> mCallTable;
+	Array<CeDbgInlineEntry> mDbgInlineTable;
+	Array<CeDbgMethodRef> mDbgMethodRefTable;
+	Array<CeEmitEntry> mEmitTable;	
+	Array<CeCallEntry> mCallTable;	
 	Array<CeStringEntry> mStringTable;
 	Array<CeStringEntry> mStringTable;
 	Array<CeConstStructData> mConstStructTable;
 	Array<CeConstStructData> mConstStructTable;
 	Array<CeStaticFieldEntry> mStaticFieldTable;
 	Array<CeStaticFieldEntry> mStaticFieldTable;
@@ -631,6 +669,7 @@ public:
 	void Print();
 	void Print();
 	void UnbindBreakpoints();
 	void UnbindBreakpoints();
 	CeEmitEntry* FindEmitEntry(int loc, int* entryIdx = NULL);
 	CeEmitEntry* FindEmitEntry(int loc, int* entryIdx = NULL);
+	int SafeGetId();
 };
 };
 
 
 enum CeEvalFlags
 enum CeEvalFlags
@@ -738,6 +777,29 @@ public:
 	int mBlockIdx;
 	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
 class CeBuilder
 {
 {
 public:	
 public:	
@@ -755,14 +817,17 @@ public:
 	Array<CeJumpEntry> mJumpTable;
 	Array<CeJumpEntry> mJumpTable;
 	Dictionary<BeValue*, CeOperand> mValueToOperand;
 	Dictionary<BeValue*, CeOperand> mValueToOperand;
 	int mFrameSize;
 	int mFrameSize;
-	Dictionary<BeDbgFile*, int> mDbgFileMap;
+	Dictionary<BeDbgLoc*, int> mDbgInlineMap;
+	Dictionary<CeDbgInlineLookup, int> mDbgScopeMap;
+	Dictionary<CeDbgMethodRef, int> mDbgMethodRefMap;
 	Dictionary<BeFunction*, int> mFunctionMap;
 	Dictionary<BeFunction*, int> mFunctionMap;
 	Dictionary<int, int> mStringMap;
 	Dictionary<int, int> mStringMap;
 	Dictionary<BeConstant*, int> mConstDataMap;
 	Dictionary<BeConstant*, int> mConstDataMap;
 	Dictionary<BeFunction*, int> mInnerFunctionMap;
 	Dictionary<BeFunction*, int> mInnerFunctionMap;
 	Dictionary<BeGlobalVariable*, int> mStaticFieldMap;
 	Dictionary<BeGlobalVariable*, int> mStaticFieldMap;
-	Dictionary<String, BfFieldInstance*> mStaticFieldInstanceMap;		
-
+	Dictionary<String, BfFieldInstance*> mStaticFieldInstanceMap;
+	Dictionary<BeValue*, int> mDbgVariableMap;
+	
 public:
 public:
 	CeBuilder()
 	CeBuilder()
 	{
 	{
@@ -782,6 +847,9 @@ public:
 	CeErrorKind EmitConst(Array<uint8>& arr, BeConstant* constant);
 	CeErrorKind EmitConst(Array<uint8>& arr, BeConstant* constant);
 	CeOperand GetOperand(BeValue* value, bool allowAlloca = false, bool allowImmediate = false);
 	CeOperand GetOperand(BeValue* value, bool allowAlloca = false, bool allowImmediate = false);
 	CeSizeClass GetSizeClass(int size);
 	CeSizeClass GetSizeClass(int size);
+	int DbgCreateMethodRef(BfMethodInstance* methodInstance, const StringImpl& nameMod);
+
+	int GetCallTableIdx(BeFunction* beFunction, CeOperand* outOperand);
 	int GetCodePos();
 	int GetCodePos();
 
 
 	void HandleParams();
 	void HandleParams();
@@ -1011,7 +1079,8 @@ public:
 		Kind_StepInfo_Asm,
 		Kind_StepInfo_Asm,
 		Kind_StepOut,
 		Kind_StepOut,
 		Kind_StepOut_Asm,
 		Kind_StepOut_Asm,
-		Kind_Jmp
+		Kind_Jmp,
+		Kind_Evaluate
 	};
 	};
 
 
 	Kind mKind;	
 	Kind mKind;	
@@ -1035,8 +1104,7 @@ public:
 	Dictionary<int, CeFunction*> mFunctionIdMap; // Only used for 32-bit and debugging
 	Dictionary<int, CeFunction*> mFunctionIdMap; // Only used for 32-bit and debugging
 	Dictionary<BfType*, CeTypeInfo> mTypeInfoMap;
 	Dictionary<BfType*, CeTypeInfo> mTypeInfoMap;
 	HashSet<BfMethodInstance*> mMethodInstanceSet;
 	HashSet<BfMethodInstance*> mMethodInstanceSet;
-	HashSet<BfFieldInstance*> mFieldInstanceSet;
-	Array<BeFunction*> mFunctionList;
+	HashSet<BfFieldInstance*> mFieldInstanceSet;	
 		
 		
 	Array<CeContext*> mContextList;
 	Array<CeContext*> mContextList;
 
 
@@ -1090,7 +1158,7 @@ public:
 	CeFunction* GetPreparedFunction(BfMethodInstance* methodInstance);
 	CeFunction* GetPreparedFunction(BfMethodInstance* methodInstance);
 	CeTypeInfo* GetTypeInfo(BfType* type);
 	CeTypeInfo* GetTypeInfo(BfType* type);
 	BfMethodInstance* GetMethodInstance(int64 methodHandle);
 	BfMethodInstance* GetMethodInstance(int64 methodHandle);
-	BfFieldInstance* GetFieldInstance(int64 fieldHandle);
+	BfFieldInstance* GetFieldInstance(int64 fieldHandle);	
 
 
 public:
 public:
 	void CompileStarted();
 	void CompileStarted();
@@ -1119,4 +1187,22 @@ namespace std
 			return BeefHash<Beefy::String>()(key.mString) ^ (size_t)key.mKind;
 			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);
+		}
+	};
 }
 }

+ 8 - 1
IDEHelper/DbgExprEvaluator.cpp

@@ -7403,7 +7403,14 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue
 				}
 				}
 				else if ((arg.mType->mTypeCode == DbgType_i32) || (arg.mType->mTypeCode == DbgType_i64))
 				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
 				else
 				{
 				{

+ 1 - 1
IDEHelper/DebugManager.cpp

@@ -667,7 +667,7 @@ BF_EXPORT void BF_CALLTYPE Debugger_Create()
 	::AllowSetForegroundWindow(ASFW_ANY);
 	::AllowSetForegroundWindow(ASFW_ANY);
 #endif
 #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)
 BF_EXPORT void BF_CALLTYPE Debugger_SetCallbacks(void* callback)

+ 1 - 1
IDEHelper/WinDebugger.h

@@ -515,7 +515,7 @@ public:
 	int SetProtection(intptr address, int size, int prot);
 	int SetProtection(intptr address, int size, int prot);
 	void EnableMemCache();
 	void EnableMemCache();
 	void DisableMemCache();
 	void DisableMemCache();
-	template<typename T> T ReadMemory(intptr addr, bool local = false, bool* failed = NULL);	
+	template<typename T> T ReadMemory(intptr addr, bool local = false, bool* failed = NULL);
 	bool WriteInstructions(intptr address, void* src, uint64 length);
 	bool WriteInstructions(intptr address, void* src, uint64 length);
 	template<typename T> bool WriteMemory(intptr addr, T val);
 	template<typename T> bool WriteMemory(intptr addr, T val);
 	virtual DbgMemoryFlags GetMemoryFlags(intptr address) override;
 	virtual DbgMemoryFlags GetMemoryFlags(intptr address) override;

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini