mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Const string alloc fixes, large string fixes, mem range check fix
This commit is contained in:
parent
649aabcaee
commit
2f72311f1f
4 changed files with 95 additions and 28 deletions
|
@ -8473,7 +8473,7 @@ void BfModule::InitTypeInst(BfTypedValue typedValue, BfScopeData* scopeData, boo
|
||||||
|
|
||||||
BfIRValue vDataRef;
|
BfIRValue vDataRef;
|
||||||
if (!isAutocomplete)
|
if (!isAutocomplete)
|
||||||
{
|
{
|
||||||
vDataRef = GetClassVDataPtr(typeInstance);
|
vDataRef = GetClassVDataPtr(typeInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1282,6 +1282,12 @@ void CeBuilder::HandleParams()
|
||||||
void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance* dupMethodInstance)
|
void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance* dupMethodInstance)
|
||||||
{
|
{
|
||||||
SetAndRestoreValue<BfMethodState*> prevMethodStateInConstEval(mCeMachine->mCeModule->mCurMethodState, NULL);
|
SetAndRestoreValue<BfMethodState*> prevMethodStateInConstEval(mCeMachine->mCeModule->mCurMethodState, NULL);
|
||||||
|
BfAutoComplete* prevAutoComplete = NULL;
|
||||||
|
if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL)
|
||||||
|
{
|
||||||
|
prevAutoComplete = mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete;
|
||||||
|
mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
|
auto irCodeGen = mCeMachine->mCeModule->mBfIRBuilder->mBeIRCodeGen;
|
||||||
auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
|
auto irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
|
||||||
|
@ -1296,6 +1302,9 @@ void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance
|
||||||
mCeMachine->mCeModule->ProcessMethod(dupMethodInstance, true);
|
mCeMachine->mCeModule->ProcessMethod(dupMethodInstance, true);
|
||||||
irCodeGen->SetState(beState);
|
irCodeGen->SetState(beState);
|
||||||
irBuilder->SetState(irState);
|
irBuilder->SetState(irState);
|
||||||
|
|
||||||
|
if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL)
|
||||||
|
mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = prevAutoComplete;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CeBuilder::Build()
|
void CeBuilder::Build()
|
||||||
|
@ -1333,18 +1342,7 @@ void CeBuilder::Build()
|
||||||
mCeMachine->mCeModule->mStaticFieldRefs.Clear();
|
mCeMachine->mCeModule->mStaticFieldRefs.Clear();
|
||||||
|
|
||||||
int startFunctionCount = (int)beModule->mFunctions.size();
|
int startFunctionCount = (int)beModule->mFunctions.size();
|
||||||
///
|
ProcessMethod(methodInstance, &dupMethodInstance);
|
||||||
{
|
|
||||||
BfAutoComplete* prevAutoComplete = NULL;
|
|
||||||
if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL)
|
|
||||||
{
|
|
||||||
prevAutoComplete = mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete;
|
|
||||||
mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = NULL;
|
|
||||||
}
|
|
||||||
ProcessMethod(methodInstance, &dupMethodInstance);
|
|
||||||
if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL)
|
|
||||||
mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = prevAutoComplete;
|
|
||||||
}
|
|
||||||
if (mCeFunction->mInitializeState == CeFunction::InitializeState_Initialized)
|
if (mCeFunction->mInitializeState == CeFunction::InitializeState_Initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2905,6 +2903,7 @@ CeContext::CeContext()
|
||||||
mCeMachine = NULL;
|
mCeMachine = NULL;
|
||||||
mReflectTypeIdOffset = -1;
|
mReflectTypeIdOffset = -1;
|
||||||
mExecuteId = -1;
|
mExecuteId = -1;
|
||||||
|
mStackSize = -1;
|
||||||
|
|
||||||
mCurTargetSrc = NULL;
|
mCurTargetSrc = NULL;
|
||||||
mHeap = new ContiguousHeap();
|
mHeap = new ContiguousHeap();
|
||||||
|
@ -3045,7 +3044,7 @@ uint8* CeContext::CeMalloc(int size)
|
||||||
{
|
{
|
||||||
#ifdef CE_ENABLE_HEAP
|
#ifdef CE_ENABLE_HEAP
|
||||||
auto heapRef = mHeap->Alloc(size);
|
auto heapRef = mHeap->Alloc(size);
|
||||||
auto ceAddr = BF_CE_STACK_SIZE + heapRef;
|
auto ceAddr = mStackSize + heapRef;
|
||||||
int sizeDelta = (ceAddr + size) - mMemory.mSize;
|
int sizeDelta = (ceAddr + size) - mMemory.mSize;
|
||||||
if (sizeDelta > 0)
|
if (sizeDelta > 0)
|
||||||
mMemory.GrowUninitialized(sizeDelta);
|
mMemory.GrowUninitialized(sizeDelta);
|
||||||
|
@ -3058,7 +3057,7 @@ uint8* CeContext::CeMalloc(int size)
|
||||||
bool CeContext::CeFree(addr_ce addr)
|
bool CeContext::CeFree(addr_ce addr)
|
||||||
{
|
{
|
||||||
#ifdef CE_ENABLE_HEAP
|
#ifdef CE_ENABLE_HEAP
|
||||||
ContiguousHeap::AllocRef heapRef = addr - BF_CE_STACK_SIZE;
|
ContiguousHeap::AllocRef heapRef = addr - mStackSize;
|
||||||
return mHeap->Free(heapRef);
|
return mHeap->Free(heapRef);
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
|
@ -3747,6 +3746,19 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
||||||
charPtr = (char*)(instData + ptrOffset);
|
charPtr = (char*)(instData + ptrOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int64 allocSizeVal = *(int64*)(instData + allocSizeOffset);
|
||||||
|
if ((allocSizeVal & 0x4000000000000000LL) != 0)
|
||||||
|
{
|
||||||
|
int32 ptrVal = *(int32*)(instData + ptrOffset);
|
||||||
|
charPtr = (char*)(ptrVal + memStart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
charPtr = (char*)(instData + ptrOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CE_CREATECONST_CHECKPTR(charPtr, lenVal);
|
CE_CREATECONST_CHECKPTR(charPtr, lenVal);
|
||||||
String str(charPtr, lenVal);
|
String str(charPtr, lenVal);
|
||||||
|
@ -4130,7 +4142,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
||||||
mCeMachine->PrepareFunction(ceFunction, NULL);
|
mCeMachine->PrepareFunction(ceFunction, NULL);
|
||||||
|
|
||||||
auto stackPtr = &mMemory[0] + BF_CE_STACK_SIZE;
|
auto stackPtr = &mMemory[0] + mStackSize;
|
||||||
auto* memStart = &mMemory[0];
|
auto* memStart = &mMemory[0];
|
||||||
|
|
||||||
BfTypeInstance* thisType = methodInstance->GetOwner();
|
BfTypeInstance* thisType = methodInstance->GetOwner();
|
||||||
|
@ -4152,6 +4164,23 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
allocThisSize += appendSizeConstant->mInt32;
|
allocThisSize += appendSizeConstant->mInt32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allocThisSize >= mStackSize / 4)
|
||||||
|
{
|
||||||
|
// Resize stack a reasonable size
|
||||||
|
mStackSize = BF_ALIGN(allocThisSize, 0x100000) + BF_CE_DEFAULT_STACK_SIZE;
|
||||||
|
int64 memSize = mStackSize + BF_CE_DEFAULT_HEAP_SIZE;
|
||||||
|
if (memSize > BF_CE_MAX_MEMORY)
|
||||||
|
{
|
||||||
|
Fail("Return value too large (>2GB)");
|
||||||
|
return BfTypedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memSize > mMemory.mSize)
|
||||||
|
mMemory.Resize(memSize);
|
||||||
|
stackPtr = &mMemory[0] + mStackSize;
|
||||||
|
memStart = &mMemory[0];
|
||||||
|
}
|
||||||
|
|
||||||
stackPtr -= allocThisSize;
|
stackPtr -= allocThisSize;
|
||||||
auto allocThisPtr = stackPtr;
|
auto allocThisPtr = stackPtr;
|
||||||
memset(allocThisPtr, 0, allocThisSize);
|
memset(allocThisPtr, 0, allocThisSize);
|
||||||
|
@ -4168,6 +4197,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
{
|
{
|
||||||
stackPtr -= ceModule->mSystem->mPtrSize;
|
stackPtr -= ceModule->mSystem->mPtrSize;
|
||||||
memset(stackPtr, 0, ceModule->mSystem->mPtrSize);
|
memset(stackPtr, 0, ceModule->mSystem->mPtrSize);
|
||||||
|
*(addr_ce*)(stackPtr) = (addr_ce)(allocThisInstAddr + thisType->mInstSize);
|
||||||
allocAppendIdxAddr = stackPtr - memStart;
|
allocAppendIdxAddr = stackPtr - memStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4301,7 +4331,14 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
}
|
}
|
||||||
|
|
||||||
BfType* usedReturnType = returnType;
|
BfType* usedReturnType = returnType;
|
||||||
BfIRValue constVal = CreateConstant(module, retPtr, returnType, &usedReturnType);
|
BfIRValue constVal;
|
||||||
|
if (returnType->IsObject())
|
||||||
|
{
|
||||||
|
addr_ce retAddr = retPtr - memStart;
|
||||||
|
constVal = CreateConstant(module, (uint8*)&retAddr, returnType, &usedReturnType);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
constVal = CreateConstant(module, retPtr, returnType, &usedReturnType);
|
||||||
if (constVal)
|
if (constVal)
|
||||||
returnValue = BfTypedValue(constVal, usedReturnType);
|
returnValue = BfTypedValue(constVal, usedReturnType);
|
||||||
else
|
else
|
||||||
|
@ -4334,9 +4371,10 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CE_CHECKALLOC(SIZE) \
|
#define CE_CHECKALLOC(SIZE) \
|
||||||
if ((SIZE < 0) || (uintptr)memSize + (uintptr)SIZE > BF_CE_MAX_MEMORY) \
|
if ((SIZE < 0) || (SIZE >= 0x80000000LL) || ((uintptr)memSize + (uintptr)SIZE > BF_CE_MAX_MEMORY)) \
|
||||||
{ \
|
{ \
|
||||||
_Fail("Maximum memory size exceeded"); \
|
_Fail("Maximum memory size exceeded (2GB)"); \
|
||||||
|
return false; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// This check will fail for addresses < 64K (null pointer), or out-of-bounds
|
// This check will fail for addresses < 64K (null pointer), or out-of-bounds
|
||||||
|
@ -4347,7 +4385,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
return false; \
|
return false; \
|
||||||
}
|
}
|
||||||
#define CE_CHECKADDR(ADDR, SIZE) \
|
#define CE_CHECKADDR(ADDR, SIZE) \
|
||||||
if (((ADDR) - 0x10000) + (SIZE) > (memSize - 0x10000)) \
|
if (((ADDR) < 0x10000) || ((ADDR) + (SIZE) > memSize)) \
|
||||||
{ \
|
{ \
|
||||||
_Fail("Access violation"); \
|
_Fail("Access violation"); \
|
||||||
return false; \
|
return false; \
|
||||||
|
@ -4588,7 +4626,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
}
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_Malloc)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_Malloc)
|
||||||
{
|
{
|
||||||
int32 size = *(int32*)((uint8*)stackPtr + 4);
|
int64 size;
|
||||||
|
if (ptrSize == 4)
|
||||||
|
size = *(int32*)((uint8*)stackPtr + 4);
|
||||||
|
else
|
||||||
|
size = *(int64*)((uint8*)stackPtr + 8);
|
||||||
CE_CHECKALLOC(size);
|
CE_CHECKALLOC(size);
|
||||||
uint8* ptr = CeMalloc(size);
|
uint8* ptr = CeMalloc(size);
|
||||||
CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
|
CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
|
||||||
|
@ -4630,6 +4672,19 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
charPtr = (char*)(strInst + ptrOffset);
|
charPtr = (char*)(strInst + ptrOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int64 allocSizeVal = *(int64*)(strInst + allocSizeOffset);
|
||||||
|
if ((allocSizeVal & 0x4000000000000000LL) != 0)
|
||||||
|
{
|
||||||
|
int32 ptrVal = *(int32*)(strInst + ptrOffset);
|
||||||
|
charPtr = (char*)(ptrVal + memStart);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
charPtr = (char*)(strInst + ptrOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int32 ptrVal = *(int32*)(strInst + ptrOffset);
|
int32 ptrVal = *(int32*)(strInst + ptrOffset);
|
||||||
|
|
||||||
|
@ -4671,7 +4726,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
|
||||||
{
|
{
|
||||||
addr_ce objAddr = *(addr_ce*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
|
addr_ce objAddr = *(addr_ce*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
|
||||||
CE_CHECKADDR(addr_ce, 4);
|
CE_CHECKADDR(objAddr, 4);
|
||||||
int32 typeId = *(int32*)(objAddr + memStart);
|
int32 typeId = *(int32*)(objAddr + memStart);
|
||||||
|
|
||||||
auto reflectType = GetReflectType(typeId);
|
auto reflectType = GetReflectType(typeId);
|
||||||
|
@ -5370,6 +5425,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
int callCount = 0;
|
int callCount = 0;
|
||||||
int instIdx = 0;
|
int instIdx = 0;
|
||||||
|
|
||||||
|
CE_CHECKSTACK();
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (*fastFinishPtr)
|
if (*fastFinishPtr)
|
||||||
|
@ -5512,7 +5569,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
case CeOp_Malloc:
|
case CeOp_Malloc:
|
||||||
{
|
{
|
||||||
auto frameOfs = CE_GETINST(int32);
|
auto frameOfs = CE_GETINST(int32);
|
||||||
int32 size = CE_GETFRAME(int32);
|
int64 size;
|
||||||
|
if (ptrSize == 4)
|
||||||
|
size = CE_GETFRAME(int32);
|
||||||
|
else
|
||||||
|
size = CE_GETFRAME(int64);
|
||||||
CE_CHECKALLOC(size);
|
CE_CHECKALLOC(size);
|
||||||
uint8* mem = CeMalloc(size);
|
uint8* mem = CeMalloc(size);
|
||||||
_FixVariables();
|
_FixVariables();
|
||||||
|
@ -7632,7 +7693,8 @@ CeContext* CeMachine::AllocContext()
|
||||||
ceContext->mCurEmitContext = mCurEmitContext;
|
ceContext->mCurEmitContext = mCurEmitContext;
|
||||||
mCurEmitContext = NULL;
|
mCurEmitContext = NULL;
|
||||||
mExecuteId++;
|
mExecuteId++;
|
||||||
ceContext->mMemory.Resize(BF_CE_STACK_SIZE);
|
ceContext->mStackSize = BF_CE_DEFAULT_STACK_SIZE;
|
||||||
|
ceContext->mMemory.Resize(ceContext->mStackSize);
|
||||||
ceContext->mExecuteId = mExecuteId;
|
ceContext->mExecuteId = mExecuteId;
|
||||||
ceContext->mCurHandleId = 0;
|
ceContext->mCurHandleId = 0;
|
||||||
return ceContext;
|
return ceContext;
|
||||||
|
|
|
@ -547,10 +547,11 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BF_CE_STACK_SIZE 4*1024*1024
|
#define BF_CE_DEFAULT_STACK_SIZE 4*1024*1024
|
||||||
#define BF_CE_INITIAL_MEMORY BF_CE_STACK_SIZE + 128*1024
|
#define BF_CE_DEFAULT_HEAP_SIZE 128*1024
|
||||||
#define BF_CE_MAX_MEMORY 128*1024*1024
|
#define BF_CE_INITIAL_MEMORY BF_CE_DEFAULT_STACK_SIZE + BF_CE_DEFAULT_HEAP_SIZE
|
||||||
#define BF_CE_MAX_CARRYOVER_MEMORY BF_CE_STACK_SIZE * 2
|
#define BF_CE_MAX_MEMORY 0x7FFFFFFF
|
||||||
|
#define BF_CE_MAX_CARRYOVER_MEMORY BF_CE_DEFAULT_STACK_SIZE * 2
|
||||||
#define BF_CE_MAX_CARRYOVER_HEAP 1024*1024
|
#define BF_CE_MAX_CARRYOVER_HEAP 1024*1024
|
||||||
|
|
||||||
enum CeOperandInfoKind
|
enum CeOperandInfoKind
|
||||||
|
@ -812,6 +813,7 @@ public:
|
||||||
ContiguousHeap* mHeap;
|
ContiguousHeap* mHeap;
|
||||||
Array<CeFrame> mCallStack;
|
Array<CeFrame> mCallStack;
|
||||||
Array<uint8> mMemory;
|
Array<uint8> mMemory;
|
||||||
|
int mStackSize;
|
||||||
Dictionary<int, addr_ce> mStringMap;
|
Dictionary<int, addr_ce> mStringMap;
|
||||||
Dictionary<int, addr_ce> mReflectMap;
|
Dictionary<int, addr_ce> mReflectMap;
|
||||||
Dictionary<Val128, addr_ce> mConstDataMap;
|
Dictionary<Val128, addr_ce> mConstDataMap;
|
||||||
|
|
|
@ -231,6 +231,7 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
const String cTest0 = Compiler.ReadText("Test0.txt");
|
const String cTest0 = Compiler.ReadText("Test0.txt");
|
||||||
|
const String cTest1 = new String('A', 12);
|
||||||
const uint8[?] cTest0Binary = Compiler.ReadBinary("Test0.txt");
|
const uint8[?] cTest0Binary = Compiler.ReadBinary("Test0.txt");
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -275,6 +276,8 @@ namespace Tests
|
||||||
Test.Assert(serCtx.mStr == "x 10\ny 2\n");
|
Test.Assert(serCtx.mStr == "x 10\ny 2\n");
|
||||||
|
|
||||||
Test.Assert(cTest0 == "Test\n0");
|
Test.Assert(cTest0 == "Test\n0");
|
||||||
|
Test.Assert(cTest1 == "AAAAAAAAAAAA");
|
||||||
|
Test.Assert((Object)cTest1 == (Object)"AAAAAAAAAAAA");
|
||||||
Test.Assert((cTest0Binary[0] == (.)'T') && ((cTest0Binary.Count == 6) || (cTest0Binary.Count == 7)));
|
Test.Assert((cTest0Binary[0] == (.)'T') && ((cTest0Binary.Count == 6) || (cTest0Binary.Count == 7)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue