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;
|
||||
if (!isAutocomplete)
|
||||
{
|
||||
{
|
||||
vDataRef = GetClassVDataPtr(typeInstance);
|
||||
}
|
||||
|
||||
|
|
|
@ -1282,6 +1282,12 @@ void CeBuilder::HandleParams()
|
|||
void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance* dupMethodInstance)
|
||||
{
|
||||
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 irBuilder = mCeMachine->mCeModule->mBfIRBuilder;
|
||||
|
@ -1296,6 +1302,9 @@ void CeBuilder::ProcessMethod(BfMethodInstance* methodInstance, BfMethodInstance
|
|||
mCeMachine->mCeModule->ProcessMethod(dupMethodInstance, true);
|
||||
irCodeGen->SetState(beState);
|
||||
irBuilder->SetState(irState);
|
||||
|
||||
if (mCeMachine->mCeModule->mCompiler->mResolvePassData != NULL)
|
||||
mCeMachine->mCeModule->mCompiler->mResolvePassData->mAutoComplete = prevAutoComplete;
|
||||
}
|
||||
|
||||
void CeBuilder::Build()
|
||||
|
@ -1333,18 +1342,7 @@ void CeBuilder::Build()
|
|||
mCeMachine->mCeModule->mStaticFieldRefs.Clear();
|
||||
|
||||
int startFunctionCount = (int)beModule->mFunctions.size();
|
||||
///
|
||||
{
|
||||
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;
|
||||
}
|
||||
ProcessMethod(methodInstance, &dupMethodInstance);
|
||||
if (mCeFunction->mInitializeState == CeFunction::InitializeState_Initialized)
|
||||
return;
|
||||
|
||||
|
@ -2905,6 +2903,7 @@ CeContext::CeContext()
|
|||
mCeMachine = NULL;
|
||||
mReflectTypeIdOffset = -1;
|
||||
mExecuteId = -1;
|
||||
mStackSize = -1;
|
||||
|
||||
mCurTargetSrc = NULL;
|
||||
mHeap = new ContiguousHeap();
|
||||
|
@ -3045,7 +3044,7 @@ uint8* CeContext::CeMalloc(int size)
|
|||
{
|
||||
#ifdef CE_ENABLE_HEAP
|
||||
auto heapRef = mHeap->Alloc(size);
|
||||
auto ceAddr = BF_CE_STACK_SIZE + heapRef;
|
||||
auto ceAddr = mStackSize + heapRef;
|
||||
int sizeDelta = (ceAddr + size) - mMemory.mSize;
|
||||
if (sizeDelta > 0)
|
||||
mMemory.GrowUninitialized(sizeDelta);
|
||||
|
@ -3058,7 +3057,7 @@ uint8* CeContext::CeMalloc(int size)
|
|||
bool CeContext::CeFree(addr_ce addr)
|
||||
{
|
||||
#ifdef CE_ENABLE_HEAP
|
||||
ContiguousHeap::AllocRef heapRef = addr - BF_CE_STACK_SIZE;
|
||||
ContiguousHeap::AllocRef heapRef = addr - mStackSize;
|
||||
return mHeap->Free(heapRef);
|
||||
#else
|
||||
return true;
|
||||
|
@ -3747,6 +3746,19 @@ BfIRValue CeContext::CreateConstant(BfModule* module, uint8* ptr, BfType* bfType
|
|||
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);
|
||||
String str(charPtr, lenVal);
|
||||
|
@ -4130,7 +4142,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
if (ceFunction->mInitializeState < CeFunction::InitializeState_Initialized)
|
||||
mCeMachine->PrepareFunction(ceFunction, NULL);
|
||||
|
||||
auto stackPtr = &mMemory[0] + BF_CE_STACK_SIZE;
|
||||
auto stackPtr = &mMemory[0] + mStackSize;
|
||||
auto* memStart = &mMemory[0];
|
||||
|
||||
BfTypeInstance* thisType = methodInstance->GetOwner();
|
||||
|
@ -4152,6 +4164,23 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
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;
|
||||
auto allocThisPtr = stackPtr;
|
||||
memset(allocThisPtr, 0, allocThisSize);
|
||||
|
@ -4168,6 +4197,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
{
|
||||
stackPtr -= ceModule->mSystem->mPtrSize;
|
||||
memset(stackPtr, 0, ceModule->mSystem->mPtrSize);
|
||||
*(addr_ce*)(stackPtr) = (addr_ce)(allocThisInstAddr + thisType->mInstSize);
|
||||
allocAppendIdxAddr = stackPtr - memStart;
|
||||
}
|
||||
|
||||
|
@ -4301,7 +4331,14 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
}
|
||||
|
||||
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)
|
||||
returnValue = BfTypedValue(constVal, usedReturnType);
|
||||
else
|
||||
|
@ -4334,9 +4371,10 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
}
|
||||
|
||||
#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
|
||||
|
@ -4347,7 +4385,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|||
return false; \
|
||||
}
|
||||
#define CE_CHECKADDR(ADDR, SIZE) \
|
||||
if (((ADDR) - 0x10000) + (SIZE) > (memSize - 0x10000)) \
|
||||
if (((ADDR) < 0x10000) || ((ADDR) + (SIZE) > memSize)) \
|
||||
{ \
|
||||
_Fail("Access violation"); \
|
||||
return false; \
|
||||
|
@ -4588,7 +4626,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
}
|
||||
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);
|
||||
uint8* ptr = CeMalloc(size);
|
||||
CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
|
||||
|
@ -4630,6 +4672,19 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
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);
|
||||
|
||||
|
@ -4671,7 +4726,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
|
||||
{
|
||||
addr_ce objAddr = *(addr_ce*)((uint8*)stackPtr + ceModule->mSystem->mPtrSize);
|
||||
CE_CHECKADDR(addr_ce, 4);
|
||||
CE_CHECKADDR(objAddr, 4);
|
||||
int32 typeId = *(int32*)(objAddr + memStart);
|
||||
|
||||
auto reflectType = GetReflectType(typeId);
|
||||
|
@ -5370,6 +5425,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
int callCount = 0;
|
||||
int instIdx = 0;
|
||||
|
||||
CE_CHECKSTACK();
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (*fastFinishPtr)
|
||||
|
@ -5512,7 +5569,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
case CeOp_Malloc:
|
||||
{
|
||||
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);
|
||||
uint8* mem = CeMalloc(size);
|
||||
_FixVariables();
|
||||
|
@ -7632,7 +7693,8 @@ CeContext* CeMachine::AllocContext()
|
|||
ceContext->mCurEmitContext = mCurEmitContext;
|
||||
mCurEmitContext = NULL;
|
||||
mExecuteId++;
|
||||
ceContext->mMemory.Resize(BF_CE_STACK_SIZE);
|
||||
ceContext->mStackSize = BF_CE_DEFAULT_STACK_SIZE;
|
||||
ceContext->mMemory.Resize(ceContext->mStackSize);
|
||||
ceContext->mExecuteId = mExecuteId;
|
||||
ceContext->mCurHandleId = 0;
|
||||
return ceContext;
|
||||
|
|
|
@ -547,10 +547,11 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#define BF_CE_STACK_SIZE 4*1024*1024
|
||||
#define BF_CE_INITIAL_MEMORY BF_CE_STACK_SIZE + 128*1024
|
||||
#define BF_CE_MAX_MEMORY 128*1024*1024
|
||||
#define BF_CE_MAX_CARRYOVER_MEMORY BF_CE_STACK_SIZE * 2
|
||||
#define BF_CE_DEFAULT_STACK_SIZE 4*1024*1024
|
||||
#define BF_CE_DEFAULT_HEAP_SIZE 128*1024
|
||||
#define BF_CE_INITIAL_MEMORY BF_CE_DEFAULT_STACK_SIZE + BF_CE_DEFAULT_HEAP_SIZE
|
||||
#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
|
||||
|
||||
enum CeOperandInfoKind
|
||||
|
@ -812,6 +813,7 @@ public:
|
|||
ContiguousHeap* mHeap;
|
||||
Array<CeFrame> mCallStack;
|
||||
Array<uint8> mMemory;
|
||||
int mStackSize;
|
||||
Dictionary<int, addr_ce> mStringMap;
|
||||
Dictionary<int, addr_ce> mReflectMap;
|
||||
Dictionary<Val128, addr_ce> mConstDataMap;
|
||||
|
|
|
@ -231,6 +231,7 @@ namespace Tests
|
|||
}
|
||||
|
||||
const String cTest0 = Compiler.ReadText("Test0.txt");
|
||||
const String cTest1 = new String('A', 12);
|
||||
const uint8[?] cTest0Binary = Compiler.ReadBinary("Test0.txt");
|
||||
|
||||
[Test]
|
||||
|
@ -275,6 +276,8 @@ namespace Tests
|
|||
Test.Assert(serCtx.mStr == "x 10\ny 2\n");
|
||||
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue