1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

CTFE updates, including heap support

This commit is contained in:
Brian Fiete 2020-12-17 04:51:05 -08:00
parent 792d92d014
commit 6bb363fb4b
29 changed files with 3050 additions and 595 deletions

View file

@ -36,6 +36,8 @@ namespace System.Diagnostics
[CallingConvention(.Cdecl)] [CallingConvention(.Cdecl)]
static extern void Write(char8* str, int strLen); static extern void Write(char8* str, int strLen);
[CallingConvention(.Cdecl)]
static extern void Write(int val);
public static void Write(String line) public static void Write(String line)
{ {

View file

@ -1932,6 +1932,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
<ClCompile Include="util\CubicFuncSpline.cpp" /> <ClCompile Include="util\CubicFuncSpline.cpp" />
<ClCompile Include="util\CubicSpline.cpp" /> <ClCompile Include="util\CubicSpline.cpp" />
<ClCompile Include="util\Hash.cpp" /> <ClCompile Include="util\Hash.cpp" />
<ClCompile Include="util\Heap.cpp" />
<ClCompile Include="util\MappedFile.cpp" /> <ClCompile Include="util\MappedFile.cpp" />
<ClCompile Include="util\Matrix4.cpp" /> <ClCompile Include="util\Matrix4.cpp" />
<ClCompile Include="util\PerfTimer.cpp" /> <ClCompile Include="util\PerfTimer.cpp" />
@ -2159,6 +2160,7 @@ copy /y "$(OutDir)$(TargetName).lib" "$(SolutionDir)\BeefLibs\Beefy2D\dist\"</Co
<ClInclude Include="util\DLIList.h" /> <ClInclude Include="util\DLIList.h" />
<ClInclude Include="util\Hash.h" /> <ClInclude Include="util\Hash.h" />
<ClInclude Include="util\HashSet.h" /> <ClInclude Include="util\HashSet.h" />
<ClInclude Include="util\Heap.h" />
<ClInclude Include="util\MappedFile.h" /> <ClInclude Include="util\MappedFile.h" />
<ClInclude Include="util\Matrix4.h" /> <ClInclude Include="util\Matrix4.h" />
<ClInclude Include="util\MultiHashSet.h" /> <ClInclude Include="util\MultiHashSet.h" />

View file

@ -704,6 +704,9 @@
<ClCompile Include="platform\win\DInputManager.cpp"> <ClCompile Include="platform\win\DInputManager.cpp">
<Filter>src\platform\win</Filter> <Filter>src\platform\win</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="util\Heap.cpp">
<Filter>src\util</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Common.h"> <ClInclude Include="Common.h">
@ -1069,6 +1072,9 @@
<ClInclude Include="platform\win\DInputManager.h"> <ClInclude Include="platform\win\DInputManager.h">
<Filter>src\platform\win</Filter> <Filter>src\platform\win</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="util\Heap.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">

View file

@ -868,6 +868,7 @@
<ClCompile Include="util\CubicSpline.cpp" /> <ClCompile Include="util\CubicSpline.cpp" />
<ClCompile Include="util\FileEnumerator.cpp" /> <ClCompile Include="util\FileEnumerator.cpp" />
<ClCompile Include="util\Hash.cpp" /> <ClCompile Include="util\Hash.cpp" />
<ClCompile Include="util\Heap.cpp" />
<ClCompile Include="util\Json.cpp" /> <ClCompile Include="util\Json.cpp" />
<ClCompile Include="util\MappedFile.cpp" /> <ClCompile Include="util\MappedFile.cpp" />
<ClCompile Include="util\Matrix4.cpp" /> <ClCompile Include="util\Matrix4.cpp" />
@ -1029,6 +1030,7 @@
<ClInclude Include="util\CubicSpline.h" /> <ClInclude Include="util\CubicSpline.h" />
<ClInclude Include="util\FileEnumerator.h" /> <ClInclude Include="util\FileEnumerator.h" />
<ClInclude Include="util\Hash.h" /> <ClInclude Include="util\Hash.h" />
<ClInclude Include="util\Heap.h" />
<ClInclude Include="util\Json.h" /> <ClInclude Include="util\Json.h" />
<ClInclude Include="util\MappedFile.h" /> <ClInclude Include="util\MappedFile.h" />
<ClInclude Include="util\Matrix4.h" /> <ClInclude Include="util\Matrix4.h" />

View file

@ -569,6 +569,9 @@
<Filter>src\util</Filter> <Filter>src\util</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="util\ThreadPool.cpp" /> <ClCompile Include="util\ThreadPool.cpp" />
<ClCompile Include="util\Heap.cpp">
<Filter>src\util</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Common.h"> <ClInclude Include="Common.h">
@ -871,6 +874,9 @@
<ClInclude Include="util\ThreadPool.h"> <ClInclude Include="util\ThreadPool.h">
<Filter>src\util</Filter> <Filter>src\util</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="util\Heap.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">

View file

@ -1156,6 +1156,9 @@ void CrashCatcher::Crash(const StringImpl& str)
{ {
}*/ }*/
for (auto func : CrashCatcher::Get()->mCrashInfoFuncs)
func();
exit(1); exit(1);
} }

View file

@ -2,6 +2,8 @@
//#define BP_ALLOC_TRACK //#define BP_ALLOC_TRACK
#include <cstdint>
#ifdef BF_PLATFORM_WINDOWS #ifdef BF_PLATFORM_WINDOWS
#define _CRTDBG_MAP_ALLOC #define _CRTDBG_MAP_ALLOC
@ -87,4 +89,29 @@ void BpDump();
#endif #endif
void* StompAlloc(int size); void* StompAlloc(int size);
void StompFree(void* addr); void StompFree(void* addr);
template <typename T>
class AllocatorStomp
{
public:
T* allocate(intptr_t count)
{
return (T*)StompAlloc((int)(sizeof(T) * count));
}
void deallocate(T* ptr)
{
StompFree(ptr);
}
void* rawAllocate(intptr_t size)
{
return StompAlloc((int)size);
}
void rawDeallocate(void* ptr)
{
StompFree(ptr);
}
};

335
BeefySysLib/util/Heap.cpp Normal file
View file

@ -0,0 +1,335 @@
#include "Heap.h"
#include "DLIList.h"
USING_NS_BF;
//////////////////////////////////////////////////////////////////////////
#define CH_REL_TO_ABS(VAL) ((ChBlock*)((uint8*)mMetadata + (VAL)))
#define CH_REL_TO_ABS(VAL) ((ChBlock*)((uint8*)mMetadata + (VAL)))
#define CH_ABS_TO_REL(VAL) (int)((uint8*)(VAL) - (uint8*)mMetadata)
enum ChBlockKind
{
ChBlockKind_Bad = 0xBEEF0BAD,
ChBlockKind_Unused = 0xBEEF1212,
ChBlockKind_Used = 0xBEEF2323,
ChBlockKind_Merged = 0xBEEF3434,
};
struct ChBlock
{
ContiguousHeap::AllocRef mPrev;
ContiguousHeap::AllocRef mNext;
int mSize;
ChBlockKind mKind;
ChBlock()
{
mPrev = -1;
mNext = -1;
mSize = 0;
mKind = ChBlockKind_Bad;
}
};
class ChList
{
public:
void* mMetadata;
int32 mHead;
int32 mTail;
public:
ChList()
{
mHead = -1;
mTail = -1;
}
void Size()
{
int size = 0;
int checkNode = mHead;
while (checkNode != NULL)
{
size++;
checkNode = CH_REL_TO_ABS(checkNode)->mNext;
}
}
void PushBack(int node)
{
BF_ASSERT(CH_REL_TO_ABS(node)->mNext == -1);
if (mHead == -1)
mHead = node;
else
{
CH_REL_TO_ABS(mTail)->mNext = node;
CH_REL_TO_ABS(node)->mPrev = mTail;
}
mTail = node;
}
void AddAfter(int refNode, int newNode)
{
int32 prevNext = CH_REL_TO_ABS(refNode)->mNext;
CH_REL_TO_ABS(refNode)->mNext = newNode;
CH_REL_TO_ABS(newNode)->mPrev = refNode;
CH_REL_TO_ABS(newNode)->mNext = prevNext;
if (prevNext != -1)
CH_REL_TO_ABS(prevNext)->mPrev = newNode;
if (refNode == mTail)
mTail = newNode;
}
void Remove(int node)
{
if (CH_REL_TO_ABS(node)->mPrev == -1)
{
mHead = CH_REL_TO_ABS(node)->mNext;
if (mHead != -1)
CH_REL_TO_ABS(mHead)->mPrev = -1;
}
else
CH_REL_TO_ABS(CH_REL_TO_ABS(node)->mPrev)->mNext = CH_REL_TO_ABS(node)->mNext;
if (CH_REL_TO_ABS(node)->mNext == -1)
{
mTail = CH_REL_TO_ABS(node)->mPrev;
if (mTail != -1)
CH_REL_TO_ABS(mTail)->mNext = -1;
}
else
CH_REL_TO_ABS(CH_REL_TO_ABS(node)->mNext)->mPrev = CH_REL_TO_ABS(node)->mPrev;
CH_REL_TO_ABS(node)->mPrev = -1;
CH_REL_TO_ABS(node)->mNext = -1;
}
bool IsEmpty()
{
return mHead == -1;
}
};
//////////////////////////////////////////////////////////////////////////
ContiguousHeap::ContiguousHeap()
{
mMetadata = NULL;
mMemorySize = 0;
mBlockDataOfs = 0;
mFreeIdx = 0;
}
ContiguousHeap::~ContiguousHeap()
{
free(mMetadata);
}
void ContiguousHeap::Clear(int maxAllocSize)
{
if (mBlockDataOfs == 0)
return;
mBlockDataOfs = 0;
mFreeList.Clear();
if ((mMemorySize != -1) && (mMemorySize > maxAllocSize))
{
free(mMetadata);
mMetadata = NULL;
mMemorySize = 0;
return;
}
auto blockList = (ChList*)mMetadata;
if (blockList->mHead != -1)
{
auto block = CH_REL_TO_ABS(blockList->mHead);
while (block != NULL)
{
block->mKind = ChBlockKind_Bad;
block = CH_REL_TO_ABS(block->mNext);
}
}
blockList->mHead = -1;
blockList->mTail = -1;
}
ContiguousHeap::AllocRef ContiguousHeap::Alloc(int size)
{
if (size == 0)
return 0;
size = BF_ALIGN(size, 16);
auto blockList = (ChList*)mMetadata;
while (true)
{
for (int itr = 0; itr < (int)mFreeList.size(); itr++)
{
auto block = (ChBlock*)((uint8*)mMetadata + mFreeList[mFreeIdx]);
if (block->mKind == ChBlockKind_Merged)
{
itr--;
if (mFreeIdx >= mFreeList.mSize)
mFreeIdx = 0;
block->mKind = (ChBlockKind)0;
mFreeList.RemoveAtFast(mFreeIdx);
continue;
}
BF_ASSERT(block->mKind == ChBlockKind_Unused);
if (block->mSize >= size)
{
mFreeList.RemoveAtFast(mFreeIdx);
if (block->mSize >= size + 64)
{
// Split block
auto newBlock = new ((uint8*)block + size) ChBlock();
newBlock->mSize = block->mSize - size;
newBlock->mKind = ChBlockKind_Unused;
blockList->AddAfter(CH_ABS_TO_REL(block), CH_ABS_TO_REL(newBlock));
block->mSize = size;
mFreeList.Add(CH_ABS_TO_REL(newBlock));
}
block->mKind = ChBlockKind_Used;
return CH_ABS_TO_REL(block);
}
mFreeIdx = (mFreeIdx + 1) % mFreeList.mSize;
}
int wantSize = BF_MAX(mMemorySize + mMemorySize / 2, mMemorySize + BF_MAX(size, 64 * 1024));
mMetadata = realloc(mMetadata, wantSize);
memset((uint8*)mMetadata + mMemorySize, 0, wantSize - mMemorySize);
blockList = (ChList*)mMetadata;
mMemorySize = wantSize;
if (mBlockDataOfs == 0)
{
blockList = new (mMetadata) ChList();
mBlockDataOfs = sizeof(ChList);
}
blockList->mMetadata = mMetadata;
auto block = new ((uint8*)mMetadata + mBlockDataOfs) ChBlock();
block->mSize = mMemorySize - mBlockDataOfs;
block->mKind = ChBlockKind_Unused;
mBlockDataOfs += block->mSize;
blockList->PushBack(CH_ABS_TO_REL(block));
mFreeList.Add(CH_ABS_TO_REL(block));
}
}
bool ContiguousHeap::Free(AllocRef ref)
{
if ((ref < 0) || (ref > mMemorySize - sizeof(ChBlock)))
return false;
auto blockList = (ChList*)mMetadata;
auto block = CH_REL_TO_ABS(ref);
if (block->mKind != ChBlockKind_Used)
return false;
int headAccSize = 0;
auto mergeHead = block;
while (mergeHead->mPrev != -1)
{
auto checkBlock = CH_REL_TO_ABS(mergeHead->mPrev);
if (checkBlock->mKind != ChBlockKind_Unused)
break;
headAccSize += mergeHead->mSize;
// Mark PREVIOUS as merged, only leave the current alive
mergeHead->mKind = ChBlockKind_Merged;
blockList->Remove(CH_ABS_TO_REL(mergeHead));
mergeHead = checkBlock;
}
int tailAccSize = 0;
if (mergeHead->mNext != -1)
{
auto mergeTail = CH_REL_TO_ABS(mergeHead->mNext);
while (mergeTail->mKind == ChBlockKind_Unused)
{
ChBlock* nextBlock = NULL;
if (mergeTail->mNext != -1)
nextBlock = CH_REL_TO_ABS(mergeTail->mNext);
tailAccSize += mergeTail->mSize;
mergeTail->mKind = ChBlockKind_Merged;
blockList->Remove(CH_ABS_TO_REL(mergeTail));
if (nextBlock == NULL)
break;
mergeTail = nextBlock;
}
}
mergeHead->mSize += tailAccSize + headAccSize;
if ((mergeHead->mKind != ChBlockKind_Unused) && (mergeHead->mKind != ChBlockKind_Merged))
{
// If it were MERGED that means it's still in the free list
mFreeList.Add(CH_ABS_TO_REL(mergeHead));
}
mergeHead->mKind = ChBlockKind_Unused;
return true;
}
void ContiguousHeap::DebugDump()
{
String str = "Heap Dump:\n";
auto blockList = (ChList*)mMetadata;
if (blockList->mHead != -1)
{
int totalSize = 0;
auto block = CH_REL_TO_ABS(blockList->mHead);
while (block != NULL)
{
str += StrFormat("@%d: %d ", CH_ABS_TO_REL(block), block->mSize);
switch (block->mKind)
{
case ChBlockKind_Unused:
str += "Unused";
break;
case ChBlockKind_Used:
str += "Used";
break;
case ChBlockKind_Merged:
str += "Merged";
break;
default:
str += "??????";
}
str += "\n";
totalSize += block->mSize;
if (block->mNext == -1)
break;
block = CH_REL_TO_ABS(block->mNext);
}
str += StrFormat("Sum: %d Allocated: %d\n", totalSize, mMemorySize);
}
str += "\nFree List:\n";
for (auto val : mFreeList)
str += StrFormat("@%d\n", val);
str += "\n";
OutputDebugStrF(str.c_str());
}

32
BeefySysLib/util/Heap.h Normal file
View file

@ -0,0 +1,32 @@
#pragma once
#include "../Common.h"
NS_BF_BEGIN
class ContiguousHeap
{
public:
typedef int AllocRef;
public:
void* mMetadata;
int mMemorySize;
int mBlockDataOfs;
Array<AllocRef> mFreeList;
int mFreeIdx;
public:
ContiguousHeap();
virtual ~ContiguousHeap();
void Clear(int maxAllocSize = -1);
AllocRef Alloc(int size);
bool Free(AllocRef ref);
void DebugDump();
};
NS_BF_END

View file

@ -141,7 +141,7 @@ namespace IDE.Compiler
{ {
char8* fileName = null; char8* fileName = null;
char8* errorStr = BfPassInstance_Error_GetMoreInfoData(mNativeBfPassInstance, errorIdx, moreInfoIdx, out fileName, out bfError.mSrcStart, out bfError.mSrcEnd, char8* errorStr = BfPassInstance_Error_GetMoreInfoData(mNativeBfPassInstance, errorIdx, moreInfoIdx, out fileName, out bfError.mSrcStart, out bfError.mSrcEnd,
getLine ? &bfError.mLine : null, getLine ? &bfError.mColumn : null); &bfError.mLine, &bfError.mColumn);
Debug.Assert(bfError.mFilePath == null); Debug.Assert(bfError.mFilePath == null);
if (fileName != null) if (fileName != null)
bfError.mFilePath = new String(fileName); bfError.mFilePath = new String(fileName);

View file

@ -1054,13 +1054,25 @@ namespace IDE
if (var sourceViewPanel = GetActiveSourceViewPanel(true)) if (var sourceViewPanel = GetActiveSourceViewPanel(true))
sourceViewPanel.RecordHistoryLocation(); sourceViewPanel.RecordHistoryLocation();
int32 charIdx = int32.Parse(cmds[2]).GetValueOrDefault(); StringView loc = cmds[2];
int32 charIdx = int32.Parse(loc).GetValueOrDefault();
if (charIdx < 0) if (charIdx < 0)
return; return;
var sourceViewPanel = ShowSourceFile(cmds[1], null, SourceShowType.Temp); var sourceViewPanel = ShowSourceFile(cmds[1], null, SourceShowType.Temp);
if (sourceViewPanel == null) if (sourceViewPanel == null)
return; return;
var editWidgetContent = sourceViewPanel.mEditWidget.mEditWidgetContent; var editWidgetContent = sourceViewPanel.mEditWidget.mEditWidgetContent;
int colonIdx = loc.IndexOf(':');
if (colonIdx != -1)
{
int line = int.Parse(loc.Substring(0, colonIdx)).GetValueOrDefault();
int column = int.Parse(loc.Substring(colonIdx + 1)).GetValueOrDefault();
charIdx = (.)editWidgetContent.GetTextIdx(line, column);
}
if (charIdx < 0)
return;
int line; int line;
int lineChar; int lineChar;
editWidgetContent.GetLineCharAtIdx(charIdx, out line, out lineChar); editWidgetContent.GetLineCharAtIdx(charIdx, out line, out lineChar);

View file

@ -4966,7 +4966,12 @@ namespace IDE.ui
{ {
for (var moreInfo in bestError.mMoreInfo) for (var moreInfo in bestError.mMoreInfo)
{ {
showMouseoverString.AppendF("\n@{0}\t{1}\t{2}", moreInfo.mFilePath, moreInfo.mSrcStart, moreInfo.mError); if ((moreInfo.mSrcStart == -1) && (moreInfo.mSrcStart == -1) && (moreInfo.mLine != -1))
{
showMouseoverString.AppendF("\n@{}\t{}:{}\t{}", moreInfo.mFilePath, moreInfo.mLine, moreInfo.mColumn, moreInfo.mError);
}
else
showMouseoverString.AppendF("\n@{0}\t{1}\t{2}", moreInfo.mFilePath, moreInfo.mSrcStart, moreInfo.mError);
} }
} }
} }

View file

@ -889,6 +889,9 @@ void BeIRCodeGen::Read(BeValue*& beValue)
beValue = result.mBeValue; beValue = result.mBeValue;
BE_MEM_END("ParamType_StreamId"); BE_MEM_END("ParamType_StreamId");
} }
if (beValue != NULL)
beValue->mRefCount++;
} }
void BeIRCodeGen::Read(BeConstant*& llvmConstant) void BeIRCodeGen::Read(BeConstant*& llvmConstant)
@ -922,6 +925,8 @@ void BeIRCodeGen::Read(BeFunction*& beFunc)
BF_ASSERT(BeValueDynCast<BeFunction>(result.mBeValue)); BF_ASSERT(BeValueDynCast<BeFunction>(result.mBeValue));
beFunc = (BeFunction*)result.mBeValue; beFunc = (BeFunction*)result.mBeValue;
BE_MEM_END("BeFunction"); BE_MEM_END("BeFunction");
beFunc->mRefCount++;
} }
void BeIRCodeGen::Read(BeBlock*& beBlock) void BeIRCodeGen::Read(BeBlock*& beBlock)
@ -932,6 +937,8 @@ void BeIRCodeGen::Read(BeBlock*& beBlock)
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Block); BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Block);
beBlock = (BeBlock*)result.mBeType; beBlock = (BeBlock*)result.mBeType;
BE_MEM_END("BeBlock"); BE_MEM_END("BeBlock");
beBlock->mRefCount++;
} }
void BeIRCodeGen::Read(BeMDNode*& llvmMD) void BeIRCodeGen::Read(BeMDNode*& llvmMD)
@ -947,6 +954,8 @@ void BeIRCodeGen::Read(BeMDNode*& llvmMD)
BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Metadata); BF_ASSERT(result.mKind == BeIRCodeGenEntryKind_Metadata);
llvmMD = result.mBeMetadata; llvmMD = result.mBeMetadata;
BE_MEM_END("BeMDNode"); BE_MEM_END("BeMDNode");
llvmMD->mRefCount++;
} }
void BeIRCodeGen::HandleNextCmd() void BeIRCodeGen::HandleNextCmd()
@ -2522,9 +2531,62 @@ void BeIRCodeGen::HandleNextCmd()
auto inst = mBeModule->AllocInst<BeObjectAccessCheckInst>(); auto inst = mBeModule->AllocInst<BeObjectAccessCheckInst>();
inst->mValue = val; inst->mValue = val;
SetResult(curId, mBeModule->GetInsertBlock()); SetResult(curId, mBeModule->GetInsertBlock());
} }
break; break;
case BfIRCmd_ConstEval_GetBfType:
{
CMD_PARAM(int32, typeId);
CMD_PARAM(BeType*, resultType);
auto inst = mBeModule->AllocInst<BeConstEvalGetType>();
inst->mTypeId = typeId;
inst->mResultType = resultType;
SetResult(curId, inst);
}
break;
case BfIRCmd_ConstEval_DynamicCastCheck:
{
CMD_PARAM(BeValue*, value);
CMD_PARAM(int32, typeId);
CMD_PARAM(BeType*, resultType);
auto inst = mBeModule->AllocInst<BeConstEvalDynamicCastCheck>();
inst->mValue = value;
inst->mTypeId = typeId;
inst->mResultType = resultType;
SetResult(curId, inst);
}
break;
case BfIRCmd_ConstEval_GetVirtualFunc:
{
CMD_PARAM(BeValue*, value);
CMD_PARAM(int32, virtualTableIdx);
CMD_PARAM(BeType*, resultType);
auto inst = mBeModule->AllocInst<BeConstEvalGetVirtualFunc>();
inst->mValue = value;
inst->mVirtualTableIdx = virtualTableIdx;
inst->mResultType = resultType;
SetResult(curId, inst);
}
break;
case BfIRCmd_ConstEval_GetInterfaceFunc:
{
CMD_PARAM(BeValue*, value);
CMD_PARAM(int32, ifaceTypeId);
CMD_PARAM(int32, virtualTableIdx);
CMD_PARAM(BeType*, resultType);
auto inst = mBeModule->AllocInst<BeConstEvalGetInterfaceFunc>();
inst->mValue = value;
inst->mIFaceTypeId = ifaceTypeId;
inst->mVirtualTableIdx = virtualTableIdx;
inst->mResultType = resultType;
SetResult(curId, inst);
}
break;
case BfIRCmd_DbgInit: case BfIRCmd_DbgInit:
{ {
/*mDIBuilder = new BeDIBuilder(*mBeModule); */ /*mDIBuilder = new BeDIBuilder(*mBeModule); */

View file

@ -1723,6 +1723,13 @@ void BeDbgFile::ToString(String& str)
str = '\\'; str = '\\';
} }
void BeDbgFile::GetFilePath(String& outStr)
{
outStr.Append(mDirectory);
outStr.Append(DIR_SEP_CHAR);
outStr.Append(mFileName);
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
BeModule::BeModule(const StringImpl& moduleName, BeContext* context) BeModule::BeModule(const StringImpl& moduleName, BeContext* context)
@ -2442,6 +2449,10 @@ String BeModule::ToString(BeFunction* wantFunc)
} }
} }
break; break;
DISPLAY_INST1(BeConstEvalGetType, "ConstEvalGetType", mTypeId);
DISPLAY_INST2(BeConstEvalDynamicCastCheck, "ConstEvalDynamicCastCheck", mValue, mTypeId);
DISPLAY_INST2(BeConstEvalGetVirtualFunc, "ConstEvalGetVirtualFunc", mValue, mVirtualTableIdx);
DISPLAY_INST3(BeConstEvalGetInterfaceFunc, "ConstEvalGetInterfaceFunc", mValue, mIFaceTypeId, mVirtualTableIdx);
default: default:
BF_FATAL("Notimpl"); BF_FATAL("Notimpl");
str += "<UNKNOWN INST>"; str += "<UNKNOWN INST>";

View file

@ -208,10 +208,12 @@ public:
#ifdef _DEBUG #ifdef _DEBUG
bool mLifetimeEnded; bool mLifetimeEnded;
bool mWasRemoved; bool mWasRemoved;
int mRefCount;
BeValue() BeValue()
{ {
mLifetimeEnded = false; mLifetimeEnded = false;
mWasRemoved = false; mWasRemoved = false;
mRefCount = 0;
} }
#endif #endif
@ -264,6 +266,16 @@ T* BeValueDynCast(BeValue* value)
return (T*)result; return (T*)result;
} }
template <typename T>
T* BeValueDynCastExact(BeValue* value)
{
if (value == NULL)
return NULL;
if (value->GetTypeId() != T::TypeId)
return NULL;
return (T*)value;
}
class BeBlock; class BeBlock;
class BeInst; class BeInst;
class BeModule; class BeModule;
@ -1320,6 +1332,106 @@ public:
} }
}; };
//////////////////////////////////////////////////////////////////////////
class BeConstEvalGetType : public BeInst
{
public:
BE_VALUE_TYPE(BeConstEvalGetType, BeInst);
public:
int mTypeId;
BeType* mResultType;
public:
virtual BeType* GetType() override
{
return mResultType;
}
virtual void HashInst(BeHashContext& hashCtx) override
{
hashCtx.Mixin(TypeId);
hashCtx.Mixin(mTypeId);
}
};
class BeConstEvalDynamicCastCheck : public BeInst
{
public:
BE_VALUE_TYPE(BeConstEvalDynamicCastCheck, BeInst);
public:
BeValue* mValue;
int mTypeId;
BeType* mResultType;
public:
virtual BeType* GetType() override
{
return mResultType;
}
virtual void HashInst(BeHashContext& hashCtx) override
{
hashCtx.Mixin(TypeId);
mValue->HashReference(hashCtx);
hashCtx.Mixin(mTypeId);
}
};
class BeConstEvalGetVirtualFunc : public BeInst
{
public:
BE_VALUE_TYPE(BeConstEvalGetVirtualFunc, BeInst);
public:
BeValue* mValue;
int mVirtualTableIdx;
BeType* mResultType;
public:
virtual BeType* GetType() override
{
return mResultType;
}
virtual void HashInst(BeHashContext& hashCtx) override
{
hashCtx.Mixin(TypeId);
mValue->HashReference(hashCtx);
hashCtx.Mixin(mVirtualTableIdx);
}
};
class BeConstEvalGetInterfaceFunc : public BeInst
{
public:
BE_VALUE_TYPE(BeConstEvalGetInterfaceFunc, BeInst);
public:
BeValue* mValue;
int mIFaceTypeId;
int mVirtualTableIdx;
BeType* mResultType;
public:
virtual BeType* GetType() override
{
return mResultType;
}
virtual void HashInst(BeHashContext& hashCtx) override
{
hashCtx.Mixin(TypeId);
mValue->HashReference(hashCtx);
hashCtx.Mixin(mIFaceTypeId);
hashCtx.Mixin(mVirtualTableIdx);
}
};
//////////////////////////////////////////////////////////////////////////
class BeArgument : public BeValue class BeArgument : public BeValue
{ {
public: public:
@ -2007,6 +2119,7 @@ public:
int mIdx; int mIdx;
void ToString(String& str); void ToString(String& str);
void GetFilePath(String& outStr);
virtual void HashContent(BeHashContext& hashCtx) override virtual void HashContent(BeHashContext& hashCtx) override
{ {
@ -2175,6 +2288,8 @@ public:
BeRetInst* CreateRet(BeValue* value); BeRetInst* CreateRet(BeValue* value);
BeCallInst* CreateCall(BeValue* func, const SizedArrayImpl<BeValue*>& args); BeCallInst* CreateCall(BeValue* func, const SizedArrayImpl<BeValue*>& args);
BeConstant* GetConstant(BeType* type, double floatVal); BeConstant* GetConstant(BeType* type, double floatVal);
BeConstant* GetConstant(BeType* type, int64 intVal); BeConstant* GetConstant(BeType* type, int64 intVal);
BeConstant* GetConstant(BeType* type, bool boolVal); BeConstant* GetConstant(BeType* type, bool boolVal);

View file

@ -406,6 +406,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mGenericIRefEnumeratorTypeDef = NULL; mGenericIRefEnumeratorTypeDef = NULL;
mInlineAttributeTypeDef = NULL; mInlineAttributeTypeDef = NULL;
mInternalTypeDef = NULL; mInternalTypeDef = NULL;
mDiagnosticsDebugTypeDef = NULL;
mIDisposableTypeDef = NULL; mIDisposableTypeDef = NULL;
mIPrintableTypeDef = NULL; mIPrintableTypeDef = NULL;
mIHashableTypeDef = NULL; mIHashableTypeDef = NULL;
@ -452,11 +453,12 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
BfCompiler::~BfCompiler() BfCompiler::~BfCompiler()
{ {
delete mCEMachine;
mCEMachine = NULL;
delete mContext; delete mContext;
delete mHotData; delete mHotData;
delete mHotState; delete mHotState;
delete mHotResolveData; delete mHotResolveData;
delete mCEMachine;
} }
bool BfCompiler::IsTypeAccessible(BfType* checkType, BfProject* curProject) bool BfCompiler::IsTypeAccessible(BfType* checkType, BfProject* curProject)
@ -6580,6 +6582,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mGenericIRefEnumeratorTypeDef = _GetRequiredType("System.Collections.IRefEnumerator", 1); mGenericIRefEnumeratorTypeDef = _GetRequiredType("System.Collections.IRefEnumerator", 1);
mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute"); mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute");
mInternalTypeDef = _GetRequiredType("System.Internal"); mInternalTypeDef = _GetRequiredType("System.Internal");
mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug");
mIDisposableTypeDef = _GetRequiredType("System.IDisposable"); mIDisposableTypeDef = _GetRequiredType("System.IDisposable");
mIPrintableTypeDef = _GetRequiredType("System.IPrintable"); mIPrintableTypeDef = _GetRequiredType("System.IPrintable");
mIHashableTypeDef = _GetRequiredType("System.IHashable"); mIHashableTypeDef = _GetRequiredType("System.IHashable");

View file

@ -356,6 +356,7 @@ public:
BfTypeDef* mGenericIRefEnumeratorTypeDef; BfTypeDef* mGenericIRefEnumeratorTypeDef;
BfTypeDef* mInternalTypeDef; BfTypeDef* mInternalTypeDef;
BfTypeDef* mDiagnosticsDebugTypeDef;
BfTypeDef* mIDisposableTypeDef; BfTypeDef* mIDisposableTypeDef;
BfTypeDef* mIPrintableTypeDef; BfTypeDef* mIPrintableTypeDef;
BfTypeDef* mIHashableTypeDef; BfTypeDef* mIHashableTypeDef;

View file

@ -2756,12 +2756,17 @@ void BfContext::Cleanup()
// Can't clean up LLVM types, they are allocated with a bump allocator // Can't clean up LLVM types, they are allocated with a bump allocator
RemoveInvalidFailTypes(); RemoveInvalidFailTypes();
// Clean up deleted BfTypes
// These need to get deleted before the modules because we access mModule in the MethodInstance dtors
for (auto type : mTypeGraveyard)
{
BF_ASSERT(type->mRebuildFlags & BfTypeRebuildFlag_Deleted);
delete type;
}
mTypeGraveyard.Clear();
for (auto module : mDeletingModules) for (auto module : mDeletingModules)
{ {
// auto itr = std::find(mFinishedModuleWorkList.begin(), mFinishedModuleWorkList.end(), module);
// if (itr != mFinishedModuleWorkList.end())
// mFinishedModuleWorkList.erase(itr);
int idx = (int)mFinishedModuleWorkList.IndexOf(module); int idx = (int)mFinishedModuleWorkList.IndexOf(module);
if (idx != -1) if (idx != -1)
mFinishedModuleWorkList.RemoveAt(idx); mFinishedModuleWorkList.RemoveAt(idx);
@ -2773,14 +2778,7 @@ void BfContext::Cleanup()
delete module; delete module;
} }
mDeletingModules.Clear(); mDeletingModules.Clear();
// Clean up deleted BfTypes
for (auto type : mTypeGraveyard)
{
BF_ASSERT(type->mRebuildFlags & BfTypeRebuildFlag_Deleted);
delete type;
}
mTypeGraveyard.Clear();
for (auto typeDef : mTypeDefGraveyard) for (auto typeDef : mTypeDefGraveyard)
delete typeDef; delete typeDef;
mTypeDefGraveyard.Clear(); mTypeDefGraveyard.Clear();

View file

@ -5025,18 +5025,29 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance*
if (methodInstance->mMethodInstanceGroup->mOwner->IsInterface()) if (methodInstance->mMethodInstanceGroup->mOwner->IsInterface())
{ {
// IFace dispatch if (mModule->mIsConstModule)
auto ifaceTypeInst = methodInstance->mMethodInstanceGroup->mOwner; {
BfIRValue slotOfs = mModule->GetInterfaceSlotNum(methodInstance->mMethodInstanceGroup->mOwner); funcCallInst = mModule->mBfIRBuilder->ConstEval_GetInterfaceFunc(irArgs[0], methodInstance->mMethodInstanceGroup->mOwner->mTypeId, methodInstance->mVirtualTableIdx, funcPtrType1);
}
else
{
// IFace dispatch
auto ifaceTypeInst = methodInstance->mMethodInstanceGroup->mOwner;
BfIRValue slotOfs = mModule->GetInterfaceSlotNum(methodInstance->mMethodInstanceGroup->mOwner);
auto vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType4); auto vDataPtrPtr = mModule->mBfIRBuilder->CreateBitCast(irArgs[0], funcPtrType4);
auto vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr/*, "vtable"*/)); auto vDataPtr = mModule->FixClassVData(mModule->mBfIRBuilder->CreateLoad(vDataPtrPtr/*, "vtable"*/));
auto ifacePtrPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, slotOfs/*, "iface"*/); auto ifacePtrPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(vDataPtr, slotOfs/*, "iface"*/);
auto ifacePtr = mModule->mBfIRBuilder->CreateLoad(ifacePtrPtr); auto ifacePtr = mModule->mBfIRBuilder->CreateLoad(ifacePtrPtr);
auto funcPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(ifacePtr, methodInstance->mVirtualTableIdx/*, "vfn"*/); auto funcPtr = mModule->mBfIRBuilder->CreateInBoundsGEP(ifacePtr, methodInstance->mVirtualTableIdx/*, "vfn"*/);
funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr); funcCallInst = mModule->mBfIRBuilder->CreateLoad(funcPtr);
}
}
else if (mModule->mIsConstModule)
{
funcCallInst = mModule->mBfIRBuilder->ConstEval_GetVirtualFunc(irArgs[0], methodInstance->mVirtualTableIdx, funcPtrType1);
} }
else else
{ {
@ -6435,7 +6446,7 @@ SplatArgs(lookupVal, irArgs);
if (!argValue) if (!argValue)
{ {
if ((argValues[argExprIdx].mArgFlags & BfArgFlag_StringInterpolateArg) != 0) if ((argExprIdx < (int)argValues.size()) && ((argValues[argExprIdx].mArgFlags & BfArgFlag_StringInterpolateArg) != 0))
{ {
BfAstNode* errorRef = NULL; BfAstNode* errorRef = NULL;
int checkIdx = argExprIdx - 1; int checkIdx = argExprIdx - 1;
@ -12761,7 +12772,8 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
} }
// Actually leave it alone? // Actually leave it alone?
if ((isUninit) && (mModule->IsOptimized())) if ((isUninit) &&
((mModule->IsOptimized()) || (mModule->mIsConstModule) || (mModule->mBfIRBuilder->mIgnoreWrites)))
return; return;
bool doClear = true; bool doClear = true;
@ -18223,7 +18235,8 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
} }
} }
} }
else if ((mModule->HasCompiledOutput()) && (wantsChecks)) else if (((mModule->HasCompiledOutput()) || (mModule->mIsConstModule)) &&
(wantsChecks))
{ {
if (checkedKind == BfCheckedKind_NotSet) if (checkedKind == BfCheckedKind_NotSet)
checkedKind = mModule->GetDefaultCheckedKind(); checkedKind = mModule->GetDefaultCheckedKind();
@ -18254,6 +18267,9 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
OutputDebugStrF("-OOB %d %d\n", oobFunc.mFunc.mId, oobFunc.mFunc.mFlags); OutputDebugStrF("-OOB %d %d\n", oobFunc.mFunc.mId, oobFunc.mFunc.mFlags);
}*/ }*/
if (mModule->mIsConstModule)
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));
mModule->mBfIRBuilder->CreateCall(oobFunc.mFunc, args); mModule->mBfIRBuilder->CreateCall(oobFunc.mFunc, args);

View file

@ -3117,6 +3117,7 @@ void BfIRBuilder::CreateTypeDefinition(BfType* type, bool forceDbgDefine)
auto& fieldInst = boxedType->mFieldInstances.back(); auto& fieldInst = boxedType->mFieldInstances.back();
auto elementType = fieldInst.mResolvedType; auto elementType = fieldInst.mResolvedType;
populateModule->PopulateType(elementType, BfPopulateType_Data);
if (!elementType->IsValuelessType()) if (!elementType->IsValuelessType())
{ {
@ -3872,8 +3873,20 @@ BfIRValue BfIRBuilder::CreateMul(BfIRValue lhs, BfIRValue rhs)
BfIRValue BfIRBuilder::CreateDiv(BfIRValue lhs, BfIRValue rhs, bool isSigned) BfIRValue BfIRBuilder::CreateDiv(BfIRValue lhs, BfIRValue rhs, bool isSigned)
{ {
if ((lhs.IsConst()) && (rhs.IsConst())) if ((lhs.IsConst()) && (rhs.IsConst()))
{ {
BINOP_APPLY(lhs, rhs, /); auto constLHS = GetConstantById(lhs.mId);
auto constRHS = GetConstantById(rhs.mId);
if ((constLHS->mTypeCode == BfTypeCode_Float) || (constLHS->mTypeCode == BfTypeCode_Double))
{
double fVal = constLHS->mDouble / constRHS->mDouble;
return CreateConst(constLHS->mTypeCode, fVal);
}
if (constRHS->mInt64 != 0)
{
INT_BINOP_APPLY(constLHS, constRHS, /);
}
} }
auto retVal = WriteCmd(isSigned ? BfIRCmd_SDiv : BfIRCmd_UDiv, lhs, rhs); auto retVal = WriteCmd(isSigned ? BfIRCmd_SDiv : BfIRCmd_UDiv, lhs, rhs);
@ -3887,10 +3900,17 @@ BfIRValue BfIRBuilder::CreateRem(BfIRValue lhs, BfIRValue rhs, bool isSigned)
{ {
auto constLHS = GetConstantById(lhs.mId); auto constLHS = GetConstantById(lhs.mId);
auto constRHS = GetConstantById(rhs.mId); auto constRHS = GetConstantById(rhs.mId);
INT_BINOP_APPLY(constLHS, constRHS, %);
double fVal = fmod(constLHS->mDouble, constRHS->mDouble); if ((constLHS->mTypeCode == BfTypeCode_Float) || (constLHS->mTypeCode == BfTypeCode_Double))
return CreateConst(constLHS->mTypeCode, fVal); {
double fVal = fmod(constLHS->mDouble, constRHS->mDouble);
return CreateConst(constLHS->mTypeCode, fVal);
}
if (constRHS->mInt64 != 0)
{
INT_BINOP_APPLY(constLHS, constRHS, %);
}
} }
auto retVal = WriteCmd(isSigned ? BfIRCmd_SRem : BfIRCmd_URem, lhs, rhs); auto retVal = WriteCmd(isSigned ? BfIRCmd_SRem : BfIRCmd_URem, lhs, rhs);
@ -4779,6 +4799,34 @@ void BfIRBuilder::Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage)
NEW_CMD_INSERTED; NEW_CMD_INSERTED;
} }
BfIRValue BfIRBuilder::ConstEval_GetBfType(int typeId, BfIRType resultType)
{
BfIRValue retVal = WriteCmd(BfIRCmd_ConstEval_GetBfType, typeId, resultType);
NEW_CMD_INSERTED;
return retVal;
}
BfIRValue BfIRBuilder::ConstEval_DynamicCastCheck(BfIRValue value, int typeId, BfIRType resultType)
{
BfIRValue retVal = WriteCmd(BfIRCmd_ConstEval_DynamicCastCheck, value, typeId, resultType);
NEW_CMD_INSERTED;
return retVal;
}
BfIRValue BfIRBuilder::ConstEval_GetVirtualFunc(BfIRValue value, int virtualTableId, BfIRType resultType)
{
BfIRValue retVal = WriteCmd(BfIRCmd_ConstEval_GetVirtualFunc, value, virtualTableId, resultType);
NEW_CMD_INSERTED;
return retVal;
}
BfIRValue BfIRBuilder::ConstEval_GetInterfaceFunc(BfIRValue value, int typeId, int virtualTableId, BfIRType resultType)
{
BfIRValue retVal = WriteCmd(BfIRCmd_ConstEval_GetInterfaceFunc, value, typeId, virtualTableId, resultType);
NEW_CMD_INSERTED;
return retVal;
}
void BfIRBuilder::SaveDebugLocation() void BfIRBuilder::SaveDebugLocation()
{ {
if (!mIgnoreWrites) if (!mIgnoreWrites)

View file

@ -281,6 +281,11 @@ enum BfIRCmd : uint8
BfIRCmd_Func_SafeRename, BfIRCmd_Func_SafeRename,
BfIRCmd_Func_SetLinkage, BfIRCmd_Func_SetLinkage,
BfIRCmd_ConstEval_GetBfType,
BfIRCmd_ConstEval_DynamicCastCheck,
BfIRCmd_ConstEval_GetVirtualFunc,
BfIRCmd_ConstEval_GetInterfaceFunc,
BfIRCmd_SaveDebugLocation, BfIRCmd_SaveDebugLocation,
BfIRCmd_RestoreDebugLocation, BfIRCmd_RestoreDebugLocation,
BfIRCmd_DupDebugLocation, BfIRCmd_DupDebugLocation,
@ -1224,6 +1229,11 @@ public:
void Func_SafeRename(BfIRFunction func); void Func_SafeRename(BfIRFunction func);
void Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage); void Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage);
BfIRValue ConstEval_GetBfType(int typeId, BfIRType resultType);
BfIRValue ConstEval_DynamicCastCheck(BfIRValue value, int typeId, BfIRType resultType);
BfIRValue ConstEval_GetVirtualFunc(BfIRValue value, int virtualTableId, BfIRType resultType);
BfIRValue ConstEval_GetInterfaceFunc(BfIRValue value, int typeId, int virtualTableId, BfIRType resultType);
void SaveDebugLocation(); void SaveDebugLocation();
void RestoreDebugLocation(); void RestoreDebugLocation();
void DupDebugLocation(); void DupDebugLocation();

View file

@ -24,6 +24,7 @@
#include "BfIRCodeGen.h" #include "BfIRCodeGen.h"
#include "BfDefBuilder.h" #include "BfDefBuilder.h"
#include "BfDeferEvalChecker.h" #include "BfDeferEvalChecker.h"
#include "CeMachine.h"
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
@ -1532,7 +1533,7 @@ BfIRValue BfModule::CreateStringObjectValue(const StringImpl& str, int stringId,
auto lenByteCount = stringTypeInst->mFieldInstances[0].mResolvedType->mSize; auto lenByteCount = stringTypeInst->mFieldInstances[0].mResolvedType->mSize;
typeValueParams.clear(); typeValueParams.clear();
typeValueParams.push_back(objData); typeValueParams.push_back(objData);
if (lenByteCount == 4) if (lenByteCount == 4)
{ {
typeValueParams.push_back(GetConstValue32((int)str.length())); // mLength typeValueParams.push_back(GetConstValue32((int)str.length())); // mLength
@ -1928,8 +1929,7 @@ void BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* r
//TODO: In the future we could be smarter about statically determining that our value hasn't escaped and eliding this //TODO: In the future we could be smarter about statically determining that our value hasn't escaped and eliding this
if (mayEscape) if (mayEscape)
{ {
if ((!IsOptimized()) && (!mIsConstModule) && (!val.mType->IsValuelessType()) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly))
if ((!IsOptimized()) && (!val.mType->IsValuelessType()) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly))
{ {
auto nullPtrType = GetPrimitiveType(BfTypeCode_NullPtr); auto nullPtrType = GetPrimitiveType(BfTypeCode_NullPtr);
bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData); bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData);
@ -1945,7 +1945,10 @@ void BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* r
else else
{ {
SizedArray<BfIRValue, 1> llvmArgs; SizedArray<BfIRValue, 1> llvmArgs;
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType))); if (IsTargetingBeefBackend())
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
else
llvmArgs.push_back(val.mValue);
llvmArgs.push_back(GetConstValue(val.mType->mSize)); llvmArgs.push_back(GetConstValue(val.mType->mSize));
llvmArgs.push_back(GetConstValue32(val.mType->mAlign)); llvmArgs.push_back(GetConstValue32(val.mType->mAlign));
if (arraySize) if (arraySize)
@ -2029,7 +2032,7 @@ bool BfModule::TryLocalVariableInit(BfLocalVariable* localVar)
if (!fieldDef->mDeclaringType->IsExtension()) if (!fieldDef->mDeclaringType->IsExtension())
return false; return false;
if ((fieldInstance.mDataIdx != -1) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly)) if ((fieldInstance.mDataIdx != -1) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly) && (!mIsConstModule))
{ {
auto curInsertBlock = mBfIRBuilder->GetInsertBlock(); auto curInsertBlock = mBfIRBuilder->GetInsertBlock();
@ -2724,6 +2727,12 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
//BF_ASSERT(refNode != NULL); //BF_ASSERT(refNode != NULL);
if (mIsConstModule)
{
mHadBuildError = true;
return NULL;
}
if (mCurMethodInstance != NULL) if (mCurMethodInstance != NULL)
mCurMethodInstance->mHasFailed = true; mCurMethodInstance->mHasFailed = true;
@ -4706,6 +4715,8 @@ BfIRValue BfModule::CreateClassVDataGlobal(BfTypeInstance* typeInstance, int* ou
BfIRValue BfModule::GetClassVDataPtr(BfTypeInstance* typeInstance) BfIRValue BfModule::GetClassVDataPtr(BfTypeInstance* typeInstance)
{ {
auto classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef); auto classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef);
if (mIsConstModule)
return mBfIRBuilder->ConstEval_GetBfType(typeInstance->mTypeId, mBfIRBuilder->MapType(CreatePointerType(classVDataType)));
return mBfIRBuilder->CreateBitCast(CreateClassVDataGlobal(typeInstance), mBfIRBuilder->MapType(CreatePointerType(classVDataType))); return mBfIRBuilder->CreateBitCast(CreateClassVDataGlobal(typeInstance), mBfIRBuilder->MapType(CreatePointerType(classVDataType)));
} }
@ -6728,7 +6739,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
BfIRValue BfModule::FixClassVData(BfIRValue value) BfIRValue BfModule::FixClassVData(BfIRValue value)
{ {
if (!mCompiler->mOptions.mObjectHasDebugFlags) if ((!mCompiler->mOptions.mObjectHasDebugFlags) || (mIsConstModule))
return value; return value;
auto intptrValue = mBfIRBuilder->CreatePtrToInt(value, BfTypeCode_IntPtr); auto intptrValue = mBfIRBuilder->CreatePtrToInt(value, BfTypeCode_IntPtr);
auto maskedValue = mBfIRBuilder->CreateAnd(intptrValue, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)~0xFFULL)); auto maskedValue = mBfIRBuilder->CreateAnd(intptrValue, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, (uint64)~0xFFULL));
@ -8025,7 +8036,7 @@ void BfModule::InitTypeInst(BfTypedValue typedValue, BfScopeData* scopeData, boo
auto destAddr = mBfIRBuilder->CreateBitCast(vObjectAddr, mBfIRBuilder->MapType(ptrPtrType)); auto destAddr = mBfIRBuilder->CreateBitCast(vObjectAddr, mBfIRBuilder->MapType(ptrPtrType));
if (!isAutocomplete) if (!isAutocomplete)
{ {
if (mCompiler->mOptions.mObjectHasDebugFlags) if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
{ {
auto objectPtr = mBfIRBuilder->CreateBitCast(destAddr, mBfIRBuilder->MapType(mContext->mBfObjectType)); auto objectPtr = mBfIRBuilder->CreateBitCast(destAddr, mBfIRBuilder->MapType(mContext->mBfObjectType));
@ -8414,8 +8425,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
BfIRValue allocaInst; BfIRValue allocaInst;
BfIRValue result; BfIRValue result;
if ((typeInstance == NULL) || (typeInstance->mIsCRepr)) if ((typeInstance == NULL) || (typeInstance->mIsCRepr))
{ {
sizeValue = mBfIRBuilder->CreateMul(GetConstValue(typeSize), arraySize);
allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(type), arraySize); allocaInst = mBfIRBuilder->CreateAlloca(mBfIRBuilder->MapType(type), arraySize);
result = allocaInst; result = allocaInst;
} }
@ -8450,28 +8460,32 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
bool isConstSize = arraySize.IsConst(); bool isConstSize = arraySize.IsConst();
BfIRBlock clearBlock; BfIRBlock clearBlock;
BfIRBlock contBlock; BfIRBlock contBlock;
bool wantsDeinit = ((!IsOptimized()) && (!mIsConstModule) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly));
if (!isConstSize) if (wantsDeinit)
{ {
clearBlock = mBfIRBuilder->CreateBlock("clear"); if (!isConstSize)
contBlock = mBfIRBuilder->CreateBlock("clearCont"); {
mBfIRBuilder->CreateCondBr(mBfIRBuilder->CreateCmpNE(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0)), clearBlock, contBlock); clearBlock = mBfIRBuilder->CreateBlock("clear");
contBlock = mBfIRBuilder->CreateBlock("clearCont");
mBfIRBuilder->CreateCondBr(mBfIRBuilder->CreateCmpNE(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0)), clearBlock, contBlock);
mBfIRBuilder->AddBlock(clearBlock); mBfIRBuilder->AddBlock(clearBlock);
mBfIRBuilder->SetInsertPoint(clearBlock); mBfIRBuilder->SetInsertPoint(clearBlock);
}
AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
if (!isConstSize)
{
mBfIRBuilder->CreateBr(contBlock);
mBfIRBuilder->AddBlock(contBlock);
mBfIRBuilder->SetInsertPoint(contBlock);
}
} }
}
AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
if (!isConstSize)
{
mBfIRBuilder->CreateBr(contBlock);
mBfIRBuilder->AddBlock(contBlock);
mBfIRBuilder->SetInsertPoint(contBlock);
}
}
//InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
return result; return result;
} }
@ -8707,6 +8721,8 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
auto typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx); auto typeOptions = mSystem->GetTypeOptions(typeInstance->mTypeOptionsIdx);
stackCount = BfTypeOptions::Apply(stackCount, typeOptions->mAllocStackTraceDepth); stackCount = BfTypeOptions::Apply(stackCount, typeOptions->mAllocStackTraceDepth);
} }
if (mIsConstModule)
stackCount = 0;
if (!sizeValue) if (!sizeValue)
sizeValue = GetConstValue(typeInstance->mInstSize); sizeValue = GetConstValue(typeInstance->mInstSize);
@ -8777,7 +8793,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
{ {
if (hasCustomAllocator) if (hasCustomAllocator)
result = AllocBytes(allocTarget.mRefNode, allocTarget, typeInstance, sizeValue, GetConstValue(typeInstance->mInstAlign), (BfAllocFlags)(BfAllocFlags_ZeroMemory | BfAllocFlags_NoDefaultToMalloc)); result = AllocBytes(allocTarget.mRefNode, allocTarget, typeInstance, sizeValue, GetConstValue(typeInstance->mInstAlign), (BfAllocFlags)(BfAllocFlags_ZeroMemory | BfAllocFlags_NoDefaultToMalloc));
else if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mCompiler->mOptions.mDebugAlloc)) else if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mCompiler->mOptions.mDebugAlloc) && (!mIsConstModule))
{ {
SizedArray<BfIRValue, 4> llvmArgs; SizedArray<BfIRValue, 4> llvmArgs;
llvmArgs.push_back(sizeValue); llvmArgs.push_back(sizeValue);
@ -8790,7 +8806,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
if (result) if (result)
{ {
if (mCompiler->mOptions.mObjectHasDebugFlags) if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
{ {
auto objectPtr = mBfIRBuilder->CreateBitCast(result, mBfIRBuilder->MapTypeInstPtr(mContext->mBfObjectType)); auto objectPtr = mBfIRBuilder->CreateBitCast(result, mBfIRBuilder->MapTypeInstPtr(mContext->mBfObjectType));
SizedArray<BfIRValue, 4> llvmArgs; SizedArray<BfIRValue, 4> llvmArgs;
@ -8828,7 +8844,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
auto classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef); auto classVDataType = ResolveTypeDef(mCompiler->mClassVDataTypeDef);
auto vData = mBfIRBuilder->CreateBitCast(vDataRef, mBfIRBuilder->MapTypeInstPtr(classVDataType->ToTypeInstance())); auto vData = mBfIRBuilder->CreateBitCast(vDataRef, mBfIRBuilder->MapTypeInstPtr(classVDataType->ToTypeInstance()));
if (mCompiler->mOptions.mObjectHasDebugFlags) if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
{ {
SizedArray<BfIRValue, 4> llvmArgs; SizedArray<BfIRValue, 4> llvmArgs;
llvmArgs.push_back(vData); llvmArgs.push_back(vData);
@ -8844,7 +8860,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
SizedArray<BfIRValue, 4> llvmArgs; SizedArray<BfIRValue, 4> llvmArgs;
llvmArgs.push_back(sizeValue); llvmArgs.push_back(sizeValue);
BfIRFunction irFunc; BfIRFunction irFunc;
if (mCompiler->mOptions.mDebugAlloc) if ((mCompiler->mOptions.mDebugAlloc) && (!mIsConstModule))
{ {
auto moduleMethodInstance = GetInternalMethod("Dbg_RawObjectAlloc", 1); auto moduleMethodInstance = GetInternalMethod("Dbg_RawObjectAlloc", 1);
irFunc = moduleMethodInstance.mFunc; irFunc = moduleMethodInstance.mFunc;
@ -9062,7 +9078,7 @@ BfIRValue BfModule::AppendAllocFromType(BfType* type, BfIRValue appendSizeValue,
auto curThis = GetThis(); auto curThis = GetThis();
BfIRValue newFlags; BfIRValue newFlags;
if (mCompiler->mOptions.mObjectHasDebugFlags) if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
{ {
auto thisFlagsPtr = mBfIRBuilder->CreateBitCast(curThis.mValue, ptrType); auto thisFlagsPtr = mBfIRBuilder->CreateBitCast(curThis.mValue, ptrType);
auto thisFlags = mBfIRBuilder->CreateLoad(thisFlagsPtr); auto thisFlags = mBfIRBuilder->CreateLoad(thisFlagsPtr);
@ -9078,7 +9094,7 @@ BfIRValue BfModule::AppendAllocFromType(BfType* type, BfIRValue appendSizeValue,
auto srcVal = mBfIRBuilder->CreateBitCast(vDataRef, ptrType); auto srcVal = mBfIRBuilder->CreateBitCast(vDataRef, ptrType);
mBfIRBuilder->CreateStore(srcVal, destAddr); mBfIRBuilder->CreateStore(srcVal, destAddr);
if (mCompiler->mOptions.mObjectHasDebugFlags) if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
{ {
auto flagsPtr = mBfIRBuilder->CreateBitCast(destAddr, ptrType); auto flagsPtr = mBfIRBuilder->CreateBitCast(destAddr, ptrType);
mBfIRBuilder->CreateStore(newFlags, flagsPtr); mBfIRBuilder->CreateStore(newFlags, flagsPtr);
@ -9129,7 +9145,7 @@ void BfModule::SkipObjectAccessCheck(BfTypedValue typedVal)
if ((mBfIRBuilder->mIgnoreWrites) || (!typedVal.mType->IsObjectOrInterface()) || (mCurMethodState == NULL) || (mCurMethodState->mIgnoreObjectAccessCheck)) if ((mBfIRBuilder->mIgnoreWrites) || (!typedVal.mType->IsObjectOrInterface()) || (mCurMethodState == NULL) || (mCurMethodState->mIgnoreObjectAccessCheck))
return; return;
if (!mCompiler->mOptions.mObjectHasDebugFlags) if ((!mCompiler->mOptions.mObjectHasDebugFlags) || (mIsConstModule))
return; return;
if ((typedVal.mValue.mFlags & BfIRValueFlags_Value) == 0) if ((typedVal.mValue.mFlags & BfIRValueFlags_Value) == 0)
@ -9143,7 +9159,7 @@ void BfModule::EmitObjectAccessCheck(BfTypedValue typedVal)
if ((mBfIRBuilder->mIgnoreWrites) || (!typedVal.mType->IsObjectOrInterface()) || (mCurMethodState == NULL) || (mCurMethodState->mIgnoreObjectAccessCheck)) if ((mBfIRBuilder->mIgnoreWrites) || (!typedVal.mType->IsObjectOrInterface()) || (mCurMethodState == NULL) || (mCurMethodState->mIgnoreObjectAccessCheck))
return; return;
if (!mCompiler->mOptions.mObjectHasDebugFlags) if ((!mCompiler->mOptions.mObjectHasDebugFlags) || (mIsConstModule))
return; return;
if (typedVal.mValue.IsConst()) if (typedVal.mValue.IsConst())
@ -9187,8 +9203,17 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar
{ {
if (mBfIRBuilder->mIgnoreWrites) if (mBfIRBuilder->mIgnoreWrites)
return; // Nothing needed here return; // Nothing needed here
auto irb = mBfIRBuilder; auto irb = mBfIRBuilder;
if (mIsConstModule)
{
auto callResult = mBfIRBuilder->ConstEval_DynamicCastCheck(targetValue.mValue, targetType->mTypeId, mBfIRBuilder->MapType(mContext->mBfObjectType));
auto cmpResult = mBfIRBuilder->CreateCmpNE(callResult, GetDefaultValue(mContext->mBfObjectType));
irb->CreateCondBr(cmpResult, trueBlock, falseBlock);
return;
}
auto checkBB = irb->CreateBlock("as.check"); auto checkBB = irb->CreateBlock("as.check");
auto isNull = irb->CreateIsNull(targetValue.mValue); auto isNull = irb->CreateIsNull(targetValue.mValue);
mBfIRBuilder->CreateCondBr(isNull, nullSucceeds ? trueBlock : falseBlock, checkBB); mBfIRBuilder->CreateCondBr(isNull, nullSucceeds ? trueBlock : falseBlock, checkBB);
@ -9212,7 +9237,6 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar
irArgs.push_back(objectParam); irArgs.push_back(objectParam);
irArgs.push_back(GetConstValue32(targetType->mTypeId)); irArgs.push_back(GetConstValue32(targetType->mTypeId));
auto callResult = exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs); auto callResult = exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs);
auto resultType = ResolveTypeDef(mSystem->mTypeBool);
auto cmpResult = mBfIRBuilder->CreateCmpNE(callResult.mValue, GetDefaultValue(callResult.mType)); auto cmpResult = mBfIRBuilder->CreateCmpNE(callResult.mValue, GetDefaultValue(callResult.mType));
irb->CreateCondBr(cmpResult, trueBlock, falseBlock); irb->CreateCondBr(cmpResult, trueBlock, falseBlock);
} }
@ -9221,7 +9245,7 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar
AddBasicBlock(checkBB); AddBasicBlock(checkBB);
BfIRValue vDataPtr = irb->CreateBitCast(targetValue.mValue, irb->MapType(intPtrType)); BfIRValue vDataPtr = irb->CreateBitCast(targetValue.mValue, irb->MapType(intPtrType));
vDataPtr = irb->CreateLoad(vDataPtr); vDataPtr = irb->CreateLoad(vDataPtr);
if (mCompiler->mOptions.mObjectHasDebugFlags) if ((mCompiler->mOptions.mObjectHasDebugFlags) && (!mIsConstModule))
vDataPtr = irb->CreateAnd(vDataPtr, irb->CreateConst(BfTypeCode_IntPtr, (uint64)~0xFFULL)); vDataPtr = irb->CreateAnd(vDataPtr, irb->CreateConst(BfTypeCode_IntPtr, (uint64)~0xFFULL));
if (targetType->IsInterface()) if (targetType->IsInterface())
@ -13531,13 +13555,13 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo
BF_ASSERT(rootMethodState->mCurLocalVarId >= 0); BF_ASSERT(rootMethodState->mCurLocalVarId >= 0);
localVarDef->mLocalVarId = rootMethodState->mCurLocalVarId++; localVarDef->mLocalVarId = rootMethodState->mCurLocalVarId++;
} }
if ((localVarDef->mNameNode != NULL) && (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL)) if ((localVarDef->mNameNode != NULL) && (mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mAutoComplete != NULL) && (!mIsConstModule))
mCompiler->mResolvePassData->mAutoComplete->CheckLocalDef(localVarDef->mNameNode, localVarDef); mCompiler->mResolvePassData->mAutoComplete->CheckLocalDef(localVarDef->mNameNode, localVarDef);
if ((localVarDef->mNameNode != NULL) && (mCurMethodInstance != NULL)) if ((localVarDef->mNameNode != NULL) && (mCurMethodInstance != NULL))
{ {
bool isClosureProcessing = (mCurMethodState->mClosureState != NULL) && (!mCurMethodState->mClosureState->mCapturing); bool isClosureProcessing = (mCurMethodState->mClosureState != NULL) && (!mCurMethodState->mClosureState->mCapturing);
if ((!isClosureProcessing) && (mCompiler->mResolvePassData != NULL) && (localVarDef->mNameNode != NULL)) if ((!isClosureProcessing) && (mCompiler->mResolvePassData != NULL) && (localVarDef->mNameNode != NULL) && (!mIsConstModule))
mCompiler->mResolvePassData->HandleLocalReference(localVarDef->mNameNode, rootMethodState->mMethodInstance->GetOwner()->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, localVarDef->mLocalVarId); mCompiler->mResolvePassData->HandleLocalReference(localVarDef->mNameNode, rootMethodState->mMethodInstance->GetOwner()->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, localVarDef->mLocalVarId);
} }
@ -14513,7 +14537,7 @@ BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArr
{ {
BP_ZONE("BfModule::TryConstCalcAppend"); BP_ZONE("BfModule::TryConstCalcAppend");
if (mCompiler->mIsResolveOnly) if ((mCompiler->mIsResolveOnly) && (!mIsConstModule))
return BfTypedValue(); return BfTypedValue();
// We want to regenerate all ctor calls when the method internals change // We want to regenerate all ctor calls when the method internals change
@ -14798,7 +14822,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
// This method never throws errors - it relies on the proper ctor actually throwing the errors // This method never throws errors - it relies on the proper ctor actually throwing the errors
void BfModule::EmitCtorCalcAppend() void BfModule::EmitCtorCalcAppend()
{ {
if (mCompiler->mIsResolveOnly) if ((mCompiler->mIsResolveOnly) && (!mIsConstModule))
return; return;
auto methodDef = mCurMethodInstance->mMethodDef; auto methodDef = mCurMethodInstance->mMethodDef;
@ -14939,6 +14963,8 @@ void BfModule::EmitDtorBody()
// Fall through to Object::~this call // Fall through to Object::~this call
auto dtorFunc = GetMethodByName(mContext->mBfObjectType, "~this"); auto dtorFunc = GetMethodByName(mContext->mBfObjectType, "~this");
if (mIsConstModule)
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);
@ -15115,6 +15141,8 @@ void BfModule::EmitDtorBody()
auto basePtr = mBfIRBuilder->CreateBitCast(mCurMethodState->mLocals[0]->mValue, mBfIRBuilder->MapTypeInstPtr(checkBaseType)); auto basePtr = mBfIRBuilder->CreateBitCast(mCurMethodState->mLocals[0]->mValue, mBfIRBuilder->MapTypeInstPtr(checkBaseType));
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 (mIsConstModule)
mCompiler->mCEMachine->QueueMethod(dtorMethodInstance.mMethodInstance, dtorMethodInstance.mFunc);
mBfIRBuilder->SetCallCallingConv(callInst, GetIRCallingConvention(dtorMethodInstance.mMethodInstance)); mBfIRBuilder->SetCallCallingConv(callInst, GetIRCallingConvention(dtorMethodInstance.mMethodInstance));
} }
} }
@ -15649,6 +15677,8 @@ void BfModule::EmitCtorBody(bool& skipBody)
SizedArray<BfIRValue, 1> irArgs; SizedArray<BfIRValue, 1> irArgs;
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 (mIsConstModule)
mCompiler->mCEMachine->QueueMethod(moduleMethodInstance);
calledCtorNoBody = true; calledCtorNoBody = true;
} }
@ -15984,6 +16014,8 @@ void BfModule::EmitCtorBody(bool& skipBody)
auto callingConv = GetIRCallingConvention(ctorBodyMethodInstance.mMethodInstance); auto callingConv = GetIRCallingConvention(ctorBodyMethodInstance.mMethodInstance);
if (callingConv != BfIRCallingConv_CDecl) if (callingConv != BfIRCallingConv_CDecl)
mBfIRBuilder->SetCallCallingConv(callInst, callingConv); mBfIRBuilder->SetCallCallingConv(callInst, callingConv);
if (mIsConstModule)
mCompiler->mCEMachine->QueueMethod(ctorBodyMethodInstance);
} }
if (matchedMethod == NULL) if (matchedMethod == NULL)
@ -20384,7 +20416,8 @@ void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& man
// We can have a collision of names when we have generic methods that differ only in // We can have a collision of names when we have generic methods that differ only in
// their constraints, but they should only collide in their unspecialized form // their constraints, but they should only collide in their unspecialized form
// since only one will be chosen for a given concrete type // since only one will be chosen for a given concrete type
mCurMethodInstance->mMangleWithIdx = true; if (!mIsConstModule)
mCurMethodInstance->mMangleWithIdx = true;
mangledName.Clear(); mangledName.Clear();
BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), mCurMethodInstance); BfMangler::Mangle(mangledName, mCompiler->GetMangleKind(), mCurMethodInstance);
prevFunc = mBfIRBuilder->GetFunction(mangledName); prevFunc = mBfIRBuilder->GetFunction(mangledName);

View file

@ -535,6 +535,13 @@ BfMethodInfoEx::~BfMethodInfoEx()
BfMethodInstance::~BfMethodInstance() BfMethodInstance::~BfMethodInstance()
{ {
if (mInCEMachine)
{
auto module = GetOwner()->mModule;
if (module->mCompiler->mCEMachine != NULL)
module->mCompiler->mCEMachine->RemoveMethod(this);
}
if (mHasMethodRefType) if (mHasMethodRefType)
{ {
auto module = GetOwner()->mModule; auto module = GetOwner()->mModule;
@ -557,13 +564,7 @@ BfMethodInstance::~BfMethodInstance()
mHotMethod->Deref(); mHotMethod->Deref();
} }
delete mMethodInfoEx; delete mMethodInfoEx;
if (mInCEMachine)
{
auto module = GetOwner()->mModule;
module->mCompiler->mCEMachine->RemoveMethod(this);
}
} }
BfImportKind BfMethodInstance::GetImportKind() BfImportKind BfMethodInstance::GetImportKind()

View file

@ -55,7 +55,8 @@ enum BfMethodNameFlags : uint8
BfMethodNameFlag_None = 0, BfMethodNameFlag_None = 0,
BfMethodNameFlag_ResolveGenericParamNames = 1, BfMethodNameFlag_ResolveGenericParamNames = 1,
BfMethodNameFlag_OmitTypeName = 2, BfMethodNameFlag_OmitTypeName = 2,
BfMethodNameFlag_IncludeReturnType = 4 BfMethodNameFlag_IncludeReturnType = 4,
BfMethodNameFlag_OmitParams = 8
}; };
enum BfGetMethodInstanceFlags : uint16 enum BfGetMethodInstanceFlags : uint16
@ -1416,7 +1417,7 @@ public:
mMethodRefFlags = BfMethodRefFlag_None; mMethodRefFlags = BfMethodRefFlag_None;
} }
BfMethodRef(BfMethodInstance* methodInstance); BfMethodRef(BfMethodInstance* methodInstance);
operator BfMethodInstance*() const; operator BfMethodInstance*() const;
bool IsNull() { return mTypeInstance == NULL; }; bool IsNull() { return mTypeInstance == NULL; };

View file

@ -42,7 +42,8 @@ USING_NS_BF;
bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scopeData) bool BfModule::AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scopeData)
{ {
if (((mCompiler->mIsResolveOnly) || (mBfIRBuilder->mIgnoreWrites)) && (deferredCallEntry->mDeferredBlock == NULL)) if ((((mCompiler->mIsResolveOnly) && (!mIsConstModule)) ||
(mBfIRBuilder->mIgnoreWrites)) && (deferredCallEntry->mDeferredBlock == NULL))
{ {
// For resolve entries, we only keep deferred blocks because we need to process them later so we can // For resolve entries, we only keep deferred blocks because we need to process them later so we can
// resolve inside of them. This is also required for lambda bind scan-pass // resolve inside of them. This is also required for lambda bind scan-pass
@ -782,7 +783,7 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz
void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks) void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks)
{ {
if ((mCompiler->mIsResolveOnly) && (deferredCallEntry.mHandlerCount > 0)) if ((mCompiler->mIsResolveOnly) && (!mIsConstModule) && (deferredCallEntry.mHandlerCount > 0))
{ {
// We only want to process deferred blocks once, otherwise it could significantly slow down autocompletion // We only want to process deferred blocks once, otherwise it could significantly slow down autocompletion
return; return;

View file

@ -928,6 +928,7 @@ bool BfProject::IsTestProject()
BfErrorBase::~BfErrorBase() BfErrorBase::~BfErrorBase()
{ {
delete mLocation;
} }
void BfErrorBase::SetSource(BfPassInstance* passInstance, BfSourceData* source) void BfErrorBase::SetSource(BfPassInstance* passInstance, BfSourceData* source)
@ -1598,9 +1599,8 @@ BfError* BfPassInstance::WarnAfter(int warningNumber, const StringImpl& warning,
return WarnAt(warningNumber, warning, refNode->GetSourceData(), refNode->GetSrcEnd()); return WarnAt(warningNumber, warning, refNode->GetSourceData(), refNode->GetSrcEnd());
} }
BfError* BfPassInstance::MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags) BfMoreInfo* BfPassInstance::MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags)
{ {
String msgPrefix;
if (!mLastWasDisplayed) if (!mLastWasDisplayed)
{ {
if (mLastWasAdded) if (mLastWasAdded)
@ -1612,25 +1612,20 @@ BfError* BfPassInstance::MoreInfoAt(const StringImpl& info, BfSourceData* bfSour
moreInfo->mSrcStart = srcIdx; moreInfo->mSrcStart = srcIdx;
moreInfo->mSrcEnd = srcIdx + srcLen; moreInfo->mSrcEnd = srcIdx + srcLen;
if (lastError->mIsWarning)
msgPrefix = ":warn";
else
msgPrefix = ":error";
lastError->mMoreInfo.push_back(moreInfo); lastError->mMoreInfo.push_back(moreInfo);
return moreInfo;
} }
return NULL; return NULL;
} }
String msgPrefix;
MessageAt(msgPrefix, " > " + info, bfSource, srcIdx, srcLen, flags); MessageAt(msgPrefix, " > " + info, bfSource, srcIdx, srcLen, flags);
return NULL; return NULL;
} }
BfError* BfPassInstance::MoreInfo(const StringImpl& info) BfMoreInfo* BfPassInstance::MoreInfo(const StringImpl& info)
{ {
String outText;
if (!mLastWasDisplayed) if (!mLastWasDisplayed)
{ {
if (mLastWasAdded) if (mLastWasAdded)
@ -1642,23 +1637,21 @@ BfError* BfPassInstance::MoreInfo(const StringImpl& info)
moreInfo->mSrcStart = -1; moreInfo->mSrcStart = -1;
moreInfo->mSrcEnd = -1; moreInfo->mSrcEnd = -1;
if (lastError->mIsWarning)
outText = ":warn ";
else
outText = ":error ";
lastError->mMoreInfo.push_back(moreInfo); lastError->mMoreInfo.push_back(moreInfo);
return moreInfo;
} }
return NULL; return NULL;
} }
String outText;
outText += " > ";
outText += info; outText += info;
OutputLine(outText); OutputLine(outText);
return NULL; return NULL;
} }
BfError* BfPassInstance::MoreInfo(const StringImpl& info, BfAstNode* refNode) BfMoreInfo* BfPassInstance::MoreInfo(const StringImpl& info, BfAstNode* refNode)
{ {
if (refNode == NULL) if (refNode == NULL)
return MoreInfo(info); return MoreInfo(info);
@ -1666,7 +1659,7 @@ BfError* BfPassInstance::MoreInfo(const StringImpl& info, BfAstNode* refNode)
return MoreInfoAt(info, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength()); return MoreInfoAt(info, refNode->GetSourceData(), refNode->GetSrcStart(), refNode->GetSrcLength());
} }
BfError* BfPassInstance::MoreInfoAfter(const StringImpl& info, BfAstNode* refNode) BfMoreInfo* BfPassInstance::MoreInfoAfter(const StringImpl& info, BfAstNode* refNode)
{ {
return MoreInfoAt(info, refNode->GetSourceData(), refNode->GetSrcEnd(), 1); return MoreInfoAt(info, refNode->GetSourceData(), refNode->GetSrcEnd(), 1);
} }
@ -3486,6 +3479,14 @@ BF_EXPORT const char* BF_CALLTYPE BfPassInstance_GetErrorData(BfPassInstance* bf
} }
} }
} }
if (bfError->mLocation != NULL)
{
fileName = (char*)bfError->mLocation->mFile.c_str();
*outLine = bfError->mLocation->mLine;
*outColumn = bfError->mLocation->mColumn;
}
outSrcStart = bfError->mSrcStart; outSrcStart = bfError->mSrcStart;
outSrcEnd = bfError->mSrcEnd; outSrcEnd = bfError->mSrcEnd;
outMoreInfoCount = (int)bfError->mMoreInfo.size(); outMoreInfoCount = (int)bfError->mMoreInfo.size();
@ -3504,6 +3505,16 @@ BF_EXPORT const char* BfPassInstance_Error_GetMoreInfoData(BfPassInstance* bfPas
fileName = (char*)srcFileName->c_str(); fileName = (char*)srcFileName->c_str();
} }
} }
if (moreInfo->mLocation != NULL)
{
fileName = (char*)moreInfo->mLocation->mFile.c_str();
if (outLine != NULL)
*outLine = moreInfo->mLocation->mLine;
if (outColumn != NULL)
*outColumn = moreInfo->mLocation->mColumn;
}
srcStart = moreInfo->mSrcStart; srcStart = moreInfo->mSrcStart;
srcEnd = moreInfo->mSrcEnd; srcEnd = moreInfo->mSrcEnd;
return moreInfo->mInfo.c_str(); return moreInfo->mInfo.c_str();

View file

@ -1122,6 +1122,14 @@ enum BfWarning
BfWarning_C4554_PossiblePrecedenceError = 4554 BfWarning_C4554_PossiblePrecedenceError = 4554
}; };
class BfErrorLocation
{
public:
String mFile;
int mLine;
int mColumn;
};
class BfErrorBase class BfErrorBase
{ {
public: public:
@ -1129,7 +1137,8 @@ public:
bool mIsDeferred; bool mIsDeferred;
BfSourceData* mSource; BfSourceData* mSource;
int mSrcStart; int mSrcStart;
int mSrcEnd; int mSrcEnd;
BfErrorLocation* mLocation;
public: public:
BfErrorBase() BfErrorBase()
@ -1139,6 +1148,7 @@ public:
mSource = NULL; mSource = NULL;
mSrcStart = -1; mSrcStart = -1;
mSrcEnd = -1; mSrcEnd = -1;
mLocation = NULL;
} }
~BfErrorBase(); ~BfErrorBase();
@ -1278,10 +1288,10 @@ public:
BfError* Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode); BfError* Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
BfError* WarnAfter(int warningNumber, const StringImpl& warning, BfAstNode* refNode); BfError* WarnAfter(int warningNumber, const StringImpl& warning, BfAstNode* refNode);
BfError* MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags = BfFailFlag_None); BfMoreInfo* MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags = BfFailFlag_None);
BfError* MoreInfo(const StringImpl& info); BfMoreInfo* MoreInfo(const StringImpl& info);
BfError* MoreInfo(const StringImpl& info, BfAstNode* refNode); BfMoreInfo* MoreInfo(const StringImpl& info, BfAstNode* refNode);
BfError* MoreInfoAfter(const StringImpl& info, BfAstNode* refNode); BfMoreInfo* MoreInfoAfter(const StringImpl& info, BfAstNode* refNode);
BfError* FailAt(const StringImpl& error, BfSourceData* bfSource, int srcIdx, int srcLen = 1, BfFailFlags flags = BfFailFlag_None); BfError* FailAt(const StringImpl& error, BfSourceData* bfSource, int srcIdx, int srcLen = 1, BfFailFlags flags = BfFailFlag_None);
BfError* FailAfterAt(const StringImpl& error, BfSourceData* bfSource, int srcIdx); BfError* FailAfterAt(const StringImpl& error, BfSourceData* bfSource, int srcIdx);

File diff suppressed because it is too large Load diff

View file

@ -2,6 +2,8 @@
#include "BfSystem.h" #include "BfSystem.h"
#include "BfModule.h" #include "BfModule.h"
#include "BeefySysLib/util/Heap.h"
#include "BeefySysLib/util/AllocDebug.h"
NS_BF_BEGIN NS_BF_BEGIN
@ -19,6 +21,8 @@ class BeSwitchInst;
class CeMachine; class CeMachine;
class CeFunction; class CeFunction;
typedef int addr_ce;
#define CEOP_SIZED(OPNAME) \ #define CEOP_SIZED(OPNAME) \
CeOp_##OPNAME##_8, \ CeOp_##OPNAME##_8, \
CeOp_##OPNAME##_16, \ CeOp_##OPNAME##_16, \
@ -32,6 +36,12 @@ class CeFunction;
CeOp_##OPNAME##_I32, \ CeOp_##OPNAME##_I32, \
CeOp_##OPNAME##_I64 CeOp_##OPNAME##_I64
#define CEOP_SIZED_UNUMERIC(OPNAME) \
CeOp_##OPNAME##_U8, \
CeOp_##OPNAME##_U16, \
CeOp_##OPNAME##_U32, \
CeOp_##OPNAME##_U64
#define CEOP_SIZED_NUMERIC_PLUSF(OPNAME) \ #define CEOP_SIZED_NUMERIC_PLUSF(OPNAME) \
CeOp_##OPNAME##_I8, \ CeOp_##OPNAME##_I8, \
CeOp_##OPNAME##_I16, \ CeOp_##OPNAME##_I16, \
@ -40,6 +50,14 @@ class CeFunction;
CeOp_##OPNAME##_F32, \ CeOp_##OPNAME##_F32, \
CeOp_##OPNAME##_F64 CeOp_##OPNAME##_F64
enum CeErrorKind
{
CeErrorKind_None,
CeErrorKind_GlobalVariable,
CeErrorKind_FunctionPointer,
CeErrorKind_Intrinsic
};
enum CeOp : int16 enum CeOp : int16
{ {
CeOp_InvalidOp, CeOp_InvalidOp,
@ -48,6 +66,16 @@ enum CeOp : int16
CeOp_JmpIf, CeOp_JmpIf,
CeOp_JmpIfNot, CeOp_JmpIfNot,
CeOp_Error,
CeOp_DynamicCastCheck,
CeOp_GetString,
CeOp_Malloc,
CeOp_Free,
CeOp_MemSet,
CeOp_MemSet_Const,
CeOp_MemCpy,
CeOp_FrameAddr_32, CeOp_FrameAddr_32,
CeOp_FrameAddr_64, CeOp_FrameAddr_64,
@ -60,25 +88,82 @@ enum CeOp : int16
CEOP_SIZED(Pop), CEOP_SIZED(Pop),
CeOp_AdjustSP, CeOp_AdjustSP,
CeOp_AdjustSPNeg,
CeOp_AdjustSPConst,
CeOp_GetSP,
CeOp_SetSP,
CeOp_Call, CeOp_Call,
CeOp_Call_Virt,
CeOp_Call_IFace,
CeOp_Conv_I8_I16,
CeOp_Conv_I8_I32,
CeOp_Conv_I8_I64,
CeOp_Conv_I8_F32,
CeOp_Conv_I8_F64,
CeOp_Conv_I16_I32,
CeOp_Conv_I16_I64,
CeOp_Conv_I16_F32,
CeOp_Conv_I16_F64,
CeOp_Conv_I32_I64, CeOp_Conv_I32_I64,
CeOp_Conv_I32_F32,
CeOp_Conv_I32_F64,
CeOp_Conv_I64_F32,
CeOp_Conv_I64_F64,
CeOp_Conv_U8_U16,
CeOp_Conv_U8_U32,
CeOp_Conv_U8_U64,
CeOp_Conv_U8_F32,
CeOp_Conv_U8_F64,
CeOp_Conv_U16_U32,
CeOp_Conv_U16_U64,
CeOp_Conv_U16_F32,
CeOp_Conv_U16_F64,
CeOp_Conv_U32_U64,
CeOp_Conv_U32_F32,
CeOp_Conv_U32_F64,
CeOp_Conv_U64_F32,
CeOp_Conv_U64_F64,
CeOp_Conv_F32_I8,
CeOp_Conv_F32_I16,
CeOp_Conv_F32_I32,
CeOp_Conv_F32_I64,
CeOp_Conv_F32_F64,
CeOp_Conv_F64_I8,
CeOp_Conv_F64_I16,
CeOp_Conv_F64_I32,
CeOp_Conv_F64_I64,
CeOp_Conv_F64_F32,
CEOP_SIZED_NUMERIC_PLUSF(AddConst), CEOP_SIZED_NUMERIC_PLUSF(AddConst),
CEOP_SIZED_NUMERIC_PLUSF(Add), CEOP_SIZED_NUMERIC_PLUSF(Add),
CEOP_SIZED_NUMERIC_PLUSF(Sub), CEOP_SIZED_NUMERIC_PLUSF(Sub),
CEOP_SIZED_NUMERIC_PLUSF(Mul), CEOP_SIZED_NUMERIC_PLUSF(Mul),
CEOP_SIZED_NUMERIC_PLUSF(SDiv), CEOP_SIZED_NUMERIC_PLUSF(Div),
CEOP_SIZED_NUMERIC(UDiv), CEOP_SIZED_UNUMERIC(Div),
CEOP_SIZED_NUMERIC_PLUSF(SMod), CEOP_SIZED_NUMERIC_PLUSF(Mod),
CEOP_SIZED_NUMERIC(UMod), CEOP_SIZED_UNUMERIC(Mod),
CEOP_SIZED_NUMERIC(And),
CEOP_SIZED_NUMERIC(Or),
CEOP_SIZED_NUMERIC(Xor),
CEOP_SIZED_NUMERIC(Shl),
CEOP_SIZED_NUMERIC(Shr),
CEOP_SIZED_UNUMERIC(Shr),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_EQ), CEOP_SIZED_NUMERIC_PLUSF(Cmp_EQ),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_NE),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT), CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT),
CEOP_SIZED_NUMERIC(Cmp_ULT), CEOP_SIZED_NUMERIC(Cmp_ULT),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLE), CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLE),
CEOP_SIZED_NUMERIC(Cmp_ULE), CEOP_SIZED_NUMERIC(Cmp_ULE),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_SGT),
CEOP_SIZED_NUMERIC(Cmp_UGT),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_SGE),
CEOP_SIZED_NUMERIC(Cmp_UGE),
CEOP_SIZED_NUMERIC_PLUSF(Neg), CEOP_SIZED_NUMERIC_PLUSF(Neg),
CeOp_Not_I1,
CEOP_SIZED_NUMERIC(Not),
CeOp_COUNT CeOp_COUNT
}; };
@ -91,43 +176,95 @@ struct CeEmitEntry
int mColumn; int mColumn;
}; };
class CeFunctionInfo
{
public:
String mName;
BfMethodInstance* mMethodInstance;
BfMethodRef mMethodRef;
CeFunction* mCeFunction;
int mRefCount;
public:
CeFunctionInfo()
{
mMethodInstance = NULL;
mCeFunction = NULL;
mRefCount = 0;
}
};
class CeCallEntry class CeCallEntry
{ {
public: public:
String mFunctionName; CeFunctionInfo* mFunctionInfo;
int mBindRevision; int mBindRevision;
CeFunction* mFunction; CeFunction* mFunction;
public: public:
CeCallEntry() CeCallEntry()
{ {
mFunctionInfo = NULL;
mBindRevision = -1; mBindRevision = -1;
mFunction = NULL; mFunction = NULL;
} }
}; };
class CeStringEntry
{
public:
int mStringId;
int mBindExecuteId;
addr_ce mStringAddr;
public:
CeStringEntry()
{
mStringId = -1;
mBindExecuteId = -1;
mStringAddr = 0;
}
};
enum CeFunctionKind
{
CeFunctionKind_Normal,
CeFunctionKind_Extern,
CeFunctionKind_OOB,
CeFunctionKind_FatalError,
CeFunctionKind_DebugWrite,
CeFunctionKind_DebugWrite_Int,
};
class CeFunction class CeFunction
{ {
public: public:
CeFunctionInfo* mCeFunctionInfo;
BfMethodInstance* mMethodInstance; BfMethodInstance* mMethodInstance;
String mName; CeFunctionKind mFunctionKind;
bool mInitialized; bool mInitialized;
bool mFailed; bool mFailed;
Array<uint8> mCode; Array<uint8> mCode;
Array<String> mFiles; Array<String> mFiles;
Array<CeEmitEntry> mEmitTable; Array<CeEmitEntry> mEmitTable;
Array<CeCallEntry> mCallTable; Array<CeCallEntry> mCallTable;
Array<CeStringEntry> mStringTable;
Array<BfType*> mTypeTable;
String mGenError; String mGenError;
int mFrameSize; int mFrameSize;
public: public:
CeFunction() CeFunction()
{ {
mCeFunctionInfo = NULL;
mFunctionKind = CeFunctionKind_Normal;
mInitialized = false; mInitialized = false;
mMethodInstance = NULL; mMethodInstance = NULL;
mFailed = false; mFailed = false;
mFrameSize = 0; mFrameSize = 0;
} }
~CeFunction();
}; };
enum CeEvalFlags enum CeEvalFlags
@ -176,6 +313,7 @@ public:
}; };
#define BF_CE_STACK_SIZE 1024*1024 #define BF_CE_STACK_SIZE 1024*1024
#define BF_CE_MAX_MEMORY 128*1024*1024
enum CeOperandInfoKind enum CeOperandInfoKind
{ {
@ -247,7 +385,7 @@ public:
class CeBuilder class CeBuilder
{ {
public: public:
CeMachine* mCeMachine; CeMachine* mCeMachine;
CeFunction* mCeFunction; CeFunction* mCeFunction;
BeFunction* mBeFunction; BeFunction* mBeFunction;
CeOperand mReturnVal; CeOperand mReturnVal;
@ -262,6 +400,7 @@ public:
int mFrameSize; int mFrameSize;
Dictionary<BeDbgFile*, int> mDbgFileMap; Dictionary<BeDbgFile*, int> mDbgFileMap;
Dictionary<BeFunction*, int> mFunctionMap; Dictionary<BeFunction*, int> mFunctionMap;
Dictionary<int, int> mStringMap;
public: public:
CeBuilder() CeBuilder()
@ -277,14 +416,16 @@ public:
void Fail(const StringImpl& error); void Fail(const StringImpl& error);
CeOperand FrameAlloc(BeType* type); CeOperand FrameAlloc(BeType* type);
CeOperand EmitConst(int64 val, int size);
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 GetCodePos(); int GetCodePos();
void HandleParams(); void HandleParams();
void Emit(uint8 val); void Emit(uint8 val);
void Emit(CeOp val); void Emit(CeOp val);
void EmitSizedOp(CeOp val, int size);
void Emit(int32 val); void Emit(int32 val);
void Emit(int64 val); void Emit(int64 val);
void Emit(bool val); void Emit(bool val);
@ -305,35 +446,42 @@ class CeFrame
{ {
public: public:
CeFunction* mFunction; CeFunction* mFunction;
uint8* mStackPtr; addr_ce mStackAddr;
uint8* mFramePtr; addr_ce mFrameAddr;
uint8* mInstPtr; uint8* mInstPtr;
public: public:
CeFrame() CeFrame()
{ {
mFunction = NULL; mFunction = NULL;
mStackPtr = NULL; mStackAddr = NULL;
mFramePtr = NULL; mFrameAddr = NULL;
mInstPtr = NULL; mInstPtr = NULL;
} }
}; };
class CeFunctionRef
{
//CeFunction* ;
};
class CeMachine class CeMachine
{ {
public: public:
Dictionary<BfMethodInstance*, CeFunction*> mFunctions; Dictionary<BfMethodInstance*, CeFunctionInfo*> mFunctions;
Dictionary<String, CeFunction*> mNamedFunctionMap; Dictionary<String, CeFunctionInfo*> mNamedFunctionMap;
BfCompiler* mCompiler; BfCompiler* mCompiler;
BfModule* mCeModule; BfModule* mCeModule;
int mRevision; int mRevision;
int mExecuteId;
Array<CeFrame> mCallStack;
Array<uint8> mMemory;
uint8* mStackMin;
ContiguousHeap* mHeap;
Array<CeFrame> mCallStack;
Array<uint8> mMemory;
Dictionary<int, addr_ce> mStringMap;
BfAstNode* mCurTargetSrc; BfAstNode* mCurTargetSrc;
BfModule* mCurModule; BfModule* mCurModule;
public: public:
CeMachine(BfCompiler* compiler); CeMachine(BfCompiler* compiler);
@ -342,8 +490,12 @@ public:
BfError* Fail(const CeFrame& curFrame, const StringImpl& error); BfError* Fail(const CeFrame& curFrame, const StringImpl& error);
void Init(); void Init();
uint8* CeMalloc(int size);
bool CeFree(addr_ce addr);
BeContext* GetBeContext(); BeContext* GetBeContext();
BeModule* GetBeModule(); BeModule* GetBeModule();
void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo);
void RemoveMethod(BfMethodInstance* methodInstance); void RemoveMethod(BfMethodInstance* methodInstance);
int GetConstantSize(BfConstant* constant); int GetConstantSize(BfConstant* constant);
void WriteConstant(uint8* ptr, BfConstant* constant); void WriteConstant(uint8* ptr, BfConstant* constant);
@ -352,10 +504,12 @@ public:
void PrepareFunction(CeFunction* methodInstance); void PrepareFunction(CeFunction* methodInstance);
CeFunction* GetFunction(BfMethodInstance* methodInstance, BfIRValue func, bool& added); CeFunction* GetFunction(BfMethodInstance* methodInstance, BfIRValue func, bool& added);
CeFunction* GetPreparedFunction(BfMethodInstance* methodInstance);
public: public:
void CompileStarted(); void CompileStarted();
void QueueMethod(BfMethodInstance* methodInstance, BfIRValue func); void QueueMethod(BfMethodInstance* methodInstance, BfIRValue func);
void QueueMethod(BfModuleMethodInstance moduleMethodInstance);
BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags); BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags);
}; };