|
@@ -6,6 +6,8 @@
|
|
|
#include "BfReducer.h"
|
|
|
#include "BfExprEvaluator.h"
|
|
|
#include "../Backend/BeIRCodeGen.h"
|
|
|
+#include "BeefySysLib/platform/PlatformHelper.h"
|
|
|
+
|
|
|
extern "C"
|
|
|
{
|
|
|
#include "BeefySysLib/third_party/utf8proc/utf8proc.h"
|
|
@@ -301,6 +303,24 @@ static int DoubleToString(double d, char* outStr)
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
+CeInternalData::~CeInternalData()
|
|
|
+{
|
|
|
+ switch (mKind)
|
|
|
+ {
|
|
|
+ case Kind_File:
|
|
|
+ BfpFile_Release(mFile);
|
|
|
+ break;
|
|
|
+ case Kind_FindFileData:
|
|
|
+ BfpFindFileData_Release(mFindFileData);
|
|
|
+ break;
|
|
|
+ case Kind_Spawn:
|
|
|
+ BfpSpawn_Release(mSpawn);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//////////////////////////////////////////////////////////////////////////
|
|
|
+
|
|
|
CeFunction::~CeFunction()
|
|
|
{
|
|
|
BF_ASSERT(mId == -1);
|
|
@@ -1316,6 +1336,11 @@ void CeBuilder::Build()
|
|
|
if (mCeFunction->mInitializeState == CeFunction::InitializeState_Initialized)
|
|
|
return;
|
|
|
|
|
|
+ if (methodInstance->mMethodDef->mName == "DecodeToUTF8")
|
|
|
+ {
|
|
|
+ NOP;
|
|
|
+ }
|
|
|
+
|
|
|
if (!dupMethodInstance.mIRFunction)
|
|
|
{
|
|
|
mCeFunction->mFailed = true;
|
|
@@ -2886,6 +2911,7 @@ CeContext::CeContext()
|
|
|
CeContext::~CeContext()
|
|
|
{
|
|
|
delete mHeap;
|
|
|
+ BF_ASSERT(mInternalDataMap.IsEmpty());
|
|
|
}
|
|
|
|
|
|
BfError* CeContext::Fail(const StringImpl& error)
|
|
@@ -2996,6 +3022,17 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
+void CeContext::AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value)
|
|
|
+{
|
|
|
+ if (mCurModule == NULL)
|
|
|
+ return;
|
|
|
+ if (mCurModule->mCurTypeInstance == NULL)
|
|
|
+ return;
|
|
|
+ if (mCurModule->mCurTypeInstance->mCeTypeInfo == NULL)
|
|
|
+ mCurModule->mCurTypeInstance->mCeTypeInfo = new BfCeTypeInfo();
|
|
|
+ mCurModule->mCurTypeInstance->mCeTypeInfo->mRebuildMap[key] = value;
|
|
|
+}
|
|
|
+
|
|
|
uint8* CeContext::CeMalloc(int size)
|
|
|
{
|
|
|
#ifdef CE_ENABLE_HEAP
|
|
@@ -4308,6 +4345,59 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|
|
return false; \
|
|
|
}
|
|
|
|
|
|
+#define CE_CHECKADDR_STR(STRNAME, ADDR) \
|
|
|
+ { \
|
|
|
+ addr_ce checkAddr = ADDR; \
|
|
|
+ while (true) \
|
|
|
+ { \
|
|
|
+ if ((uintptr)checkAddr >= (uintptr)memSize) \
|
|
|
+ { \
|
|
|
+ break; \
|
|
|
+ } \
|
|
|
+ if (memStart[checkAddr] == 0) \
|
|
|
+ { \
|
|
|
+ CE_CHECKADDR(ADDR, checkAddr - ADDR + 1); \
|
|
|
+ STRNAME = String::MakeRef((char*)memStart + ADDR, checkAddr - ADDR + 1); \
|
|
|
+ break; \
|
|
|
+ } \
|
|
|
+ checkAddr++; \
|
|
|
+ } \
|
|
|
+ }
|
|
|
+
|
|
|
+#define CE_GET_INTERNAL(VAR, ID, KIND) \
|
|
|
+ if (!mInternalDataMap.TryGetValue((int)ID, &VAR)) \
|
|
|
+ { \
|
|
|
+ _Fail("Invalid internal resource id"); \
|
|
|
+ return false; \
|
|
|
+ } \
|
|
|
+ if (VAR->mKind != KIND) \
|
|
|
+ { \
|
|
|
+ _Fail("Invalid internal resource kind"); \
|
|
|
+ return false; \
|
|
|
+ } \
|
|
|
+ if (VAR->mReleased) \
|
|
|
+ { \
|
|
|
+ _Fail("Resource already released"); \
|
|
|
+ return false; \
|
|
|
+ }
|
|
|
+
|
|
|
+#define CE_REMOVE_INTERNAL(VAR, ID, KIND) \
|
|
|
+ if (!mInternalDataMap.Remove((int)ID, &VAR)) \
|
|
|
+ { \
|
|
|
+ _Fail("Invalid internal resource id"); \
|
|
|
+ return false; \
|
|
|
+ } \
|
|
|
+ if (VAR->mKind != KIND) \
|
|
|
+ { \
|
|
|
+ _Fail("Invalid internal resource kind"); \
|
|
|
+ return false; \
|
|
|
+ } \
|
|
|
+ if (VAR->mReleased) \
|
|
|
+ { \
|
|
|
+ _Fail("Resource already released"); \
|
|
|
+ return false; \
|
|
|
+ }
|
|
|
+
|
|
|
#define CE_GETINST(T) *((T*)(instPtr += sizeof(T)) - 1)
|
|
|
#define CE_GETFRAME(T) *(T*)(framePtr + *((int32*)(instPtr += sizeof(int32)) - 1))
|
|
|
#define CEOP_BIN(OP, T) \
|
|
@@ -4422,7 +4512,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|
|
instPtr = &ceFunction->mCode[0]; \
|
|
|
CE_CHECKSTACK();
|
|
|
|
|
|
-static void CeSetAddrVal(void* ptr, addr_ce val, int32 ptrSize)
|
|
|
+static void CeSetAddrVal(void* ptr, int64 val, int32 ptrSize)
|
|
|
{
|
|
|
if (ptrSize == 4)
|
|
|
*(int32*)(ptr) = (int32)val;
|
|
@@ -4559,8 +4649,16 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|
|
}
|
|
|
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int)
|
|
|
{
|
|
|
- int32 intVal = *(int32*)((uint8*)stackPtr + 0);
|
|
|
- OutputDebugStrF("Debug Val: %d\n", intVal);
|
|
|
+ if (ceModule->mSystem->mPtrSize == 4)
|
|
|
+ {
|
|
|
+ int32 intVal = *(int32*)((uint8*)stackPtr + 0);
|
|
|
+ OutputDebugStrF("Debug Val: %d\n", intVal);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ int64 intVal = *(int64*)((uint8*)stackPtr + 0);
|
|
|
+ OutputDebugStrF("Debug Val: %lld\n", intVal);
|
|
|
+ }
|
|
|
}
|
|
|
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
|
|
|
{
|
|
@@ -4911,7 +5009,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|
|
addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 8);
|
|
|
addr_ce endAddr = *(addr_ce*)((uint8*)stackPtr + 8 + ptrSize);
|
|
|
|
|
|
- addr_ce checkAddr = strAddr;
|
|
|
+ addr_ce checkAddr = strAddr;
|
|
|
while (true)
|
|
|
{
|
|
|
if ((uintptr)checkAddr >= (uintptr)memSize)
|
|
@@ -4921,10 +5019,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|
|
}
|
|
|
if (memStart[checkAddr] == 0)
|
|
|
break;
|
|
|
+ checkAddr++;
|
|
|
}
|
|
|
CE_CHECKADDR(strAddr, checkAddr - strAddr + 1);
|
|
|
|
|
|
- char* strPtr = (char*)(memStart + strAddr);
|
|
|
+ char* strPtr = (char*)(memStart + strAddr);
|
|
|
char** endPtr = NULL;
|
|
|
if (endAddr != NULL)
|
|
|
endPtr = (char**)(memStart + endAddr);
|
|
@@ -4959,7 +5058,281 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|
|
memcpy(memStart + strAddr, str, count + 1);
|
|
|
result = count;
|
|
|
}
|
|
|
- else
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Close)
|
|
|
+ {
|
|
|
+ addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
|
|
|
+ addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
|
|
+
|
|
|
+ CE_CHECKADDR(outResultAddr, 4);
|
|
|
+
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
|
|
+ BfpFile_Close(internalData->mFile, (BfpFileResult*)(memStart + outResultAddr));
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Create)
|
|
|
+ {
|
|
|
+ void* resultPtr = ((uint8*)stackPtr + 0);
|
|
|
+ addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
|
|
+ int createKind = *(int*)((uint8*)stackPtr + ptrSize + ptrSize);
|
|
|
+ int createFlags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + 4);
|
|
|
+ int createFileAttrs = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + 4 + 4);
|
|
|
+ addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + 4 + 4 + 4);
|
|
|
+
|
|
|
+ String path;
|
|
|
+ CE_CHECKADDR_STR(path, nameAddr);
|
|
|
+ CE_CHECKADDR(outResultAddr, 4);
|
|
|
+
|
|
|
+ BfProject* activeProject = NULL;
|
|
|
+ auto activeTypeDef = mCurModule->GetActiveTypeDef();
|
|
|
+ if (activeTypeDef != NULL)
|
|
|
+ activeProject = activeTypeDef->mProject;
|
|
|
+ if (activeProject != NULL)
|
|
|
+ path = GetAbsPath(path, activeProject->mDirectory);
|
|
|
+
|
|
|
+ auto bfpFile = BfpFile_Create(path.c_str(), (BfpFileCreateKind)createKind, (BfpFileCreateFlags)createFlags, (BfpFileAttributes)createFileAttrs, (BfpFileResult*)(memStart + outResultAddr));
|
|
|
+ if (bfpFile != NULL)
|
|
|
+ {
|
|
|
+ if ((createKind == BfpFileCreateKind_OpenExisting) || (createKind == BfpFileCreateKind_OpenAlways))
|
|
|
+ {
|
|
|
+ auto timeStamp = BfpFile_GetTime_LastWrite(path.c_str());
|
|
|
+ if (timeStamp != 0)
|
|
|
+ {
|
|
|
+ CeRebuildKey rebuildKey;
|
|
|
+ rebuildKey.mKind = CeRebuildKey::Kind_File;
|
|
|
+ rebuildKey.mString = path;
|
|
|
+
|
|
|
+ CeRebuildValue rebuildValue;
|
|
|
+ rebuildValue.mInt = timeStamp;
|
|
|
+
|
|
|
+ AddRebuild(rebuildKey, rebuildValue);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ CeInternalData* internalData = new CeInternalData();
|
|
|
+ internalData->mKind = CeInternalData::Kind_File;
|
|
|
+ internalData->mFile = bfpFile;
|
|
|
+ mInternalDataMap[++mCurHandleId] = internalData;
|
|
|
+ CeSetAddrVal(resultPtr, mCurHandleId, ptrSize);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ CeSetAddrVal(resultPtr, 0, ptrSize);
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Flush)
|
|
|
+ {
|
|
|
+ addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
|
|
+ BfpFile_Flush(internalData->mFile);
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetFileSize)
|
|
|
+ {
|
|
|
+ int64& result = *(int64*)((uint8*)stackPtr + 0);
|
|
|
+ addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 8);
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
|
|
+ result = BfpFile_GetFileSize(internalData->mFile);
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Read)
|
|
|
+ {
|
|
|
+ void* resultPtr = ((uint8*)stackPtr + 0);
|
|
|
+ addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
|
|
+ addr_ce bufferPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
|
|
|
+ intptr bufferSize = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
|
|
|
+ int timeoutMS = *(int32*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
|
|
|
+ addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
|
|
|
+
|
|
|
+ CE_CHECKADDR(bufferPtr, bufferSize);
|
|
|
+ CE_CHECKADDR(outResultAddr, 4);
|
|
|
+
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
|
|
+ int64 result = BfpFile_Read(internalData->mFile, memStart + bufferPtr, bufferSize, timeoutMS, (BfpFileResult*)(memStart + outResultAddr));
|
|
|
+ CeSetAddrVal(resultPtr, result, ptrSize);
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Release)
|
|
|
+ {
|
|
|
+ addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
|
|
|
+
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_REMOVE_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
|
|
+ delete internalData;
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Seek)
|
|
|
+ {
|
|
|
+ int64& result = *(int64*)((uint8*)stackPtr + 0);
|
|
|
+ addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 8);
|
|
|
+ int64 offset = *(int64*)((uint8*)stackPtr + 8 + ptrSize);
|
|
|
+ int seekKind = *(int*)((uint8*)stackPtr + 8 + ptrSize + 8);
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
|
|
+ result = BfpFile_Seek(internalData->mFile, offset, (BfpFileSeekKind)seekKind);
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Truncate)
|
|
|
+ {
|
|
|
+ addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + 0);
|
|
|
+ addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
|
|
+
|
|
|
+ CE_CHECKADDR(outResultAddr, 4);
|
|
|
+
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
|
|
+ BfpFile_Truncate(internalData->mFile, (BfpFileResult*)(memStart + outResultAddr));
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_Write)
|
|
|
+ {
|
|
|
+ void* resultPtr = ((uint8*)stackPtr + 0);
|
|
|
+ addr_ce fileId = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
|
|
+ addr_ce bufferPtr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
|
|
|
+ intptr bufferSize = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
|
|
|
+ int timeoutMS = *(int32*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
|
|
|
+ addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
|
|
|
+
|
|
|
+ CE_CHECKADDR(bufferPtr, bufferSize);
|
|
|
+ CE_CHECKADDR(outResultAddr, 4);
|
|
|
+
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)fileId, CeInternalData::Kind_File);
|
|
|
+ int64 result = BfpFile_Write(internalData->mFile, memStart + bufferPtr, bufferSize, timeoutMS, (BfpFileResult*)(memStart + outResultAddr));
|
|
|
+ CeSetAddrVal(resultPtr, result, ptrSize);
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Create)
|
|
|
+ {
|
|
|
+ void* resultPtr = ((uint8*)stackPtr + 0);
|
|
|
+ addr_ce targetPathAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
|
|
+ addr_ce argsAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
|
|
|
+ addr_ce workingDirAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
|
|
|
+ addr_ce envAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize);
|
|
|
+ int flags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
|
|
|
+ addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize);
|
|
|
+
|
|
|
+ String targetPath;
|
|
|
+ CE_CHECKADDR_STR(targetPath, targetPathAddr);
|
|
|
+ String args;
|
|
|
+ CE_CHECKADDR_STR(args, argsAddr);
|
|
|
+ String workingDir;
|
|
|
+ CE_CHECKADDR_STR(workingDir, workingDirAddr);
|
|
|
+ String env;
|
|
|
+ CE_CHECKADDR_STR(env, envAddr);
|
|
|
+ CE_CHECKADDR(outResultAddr, 4);
|
|
|
+
|
|
|
+ BfProject* activeProject = NULL;
|
|
|
+ auto activeTypeDef = mCurModule->GetActiveTypeDef();
|
|
|
+ if (activeTypeDef != NULL)
|
|
|
+ activeProject = activeTypeDef->mProject;
|
|
|
+ if (activeProject != NULL)
|
|
|
+ targetPath = GetAbsPath(targetPath, activeProject->mDirectory);
|
|
|
+
|
|
|
+ auto bfpSpawn = BfpSpawn_Create(targetPath.c_str(), args.c_str(), workingDir.c_str(), env.c_str(), (BfpSpawnFlags)flags, (BfpSpawnResult*)(memStart + outResultAddr));
|
|
|
+ if (bfpSpawn != NULL)
|
|
|
+ {
|
|
|
+ CeInternalData* internalData = new CeInternalData();
|
|
|
+ internalData->mKind = CeInternalData::Kind_Spawn;
|
|
|
+ internalData->mSpawn = bfpSpawn;
|
|
|
+ mInternalDataMap[++mCurHandleId] = internalData;
|
|
|
+ CeSetAddrVal(resultPtr, mCurHandleId, ptrSize);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ CeSetAddrVal(resultPtr, 0, ptrSize);
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_GetStdHandles)
|
|
|
+ {
|
|
|
+ addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
|
|
|
+ addr_ce outStdInAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize);
|
|
|
+ addr_ce outStdOutAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize);
|
|
|
+ addr_ce outStdErrAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
|
|
|
+
|
|
|
+ CE_CHECKADDR(outStdInAddr, ptrSize);
|
|
|
+ CE_CHECKADDR(outStdOutAddr, ptrSize);
|
|
|
+ CE_CHECKADDR(outStdErrAddr, ptrSize);
|
|
|
+
|
|
|
+ BfpFile* outStdIn = NULL;
|
|
|
+ BfpFile* outStdOut = NULL;
|
|
|
+ BfpFile* outStdErr = NULL;
|
|
|
+
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
|
|
|
+ BfpSpawn_GetStdHandles(internalData->mSpawn,
|
|
|
+ (outStdInAddr != 0) ? &outStdIn : NULL,
|
|
|
+ (outStdOutAddr != 0) ? &outStdOut : NULL,
|
|
|
+ (outStdErrAddr != 0) ? &outStdErr : NULL);
|
|
|
+
|
|
|
+ auto _SetHandle = [&](addr_ce addr, BfpFile* file)
|
|
|
+ {
|
|
|
+ if (addr == 0)
|
|
|
+ return;
|
|
|
+ if (file != NULL)
|
|
|
+ {
|
|
|
+ CeInternalData* internalData = new CeInternalData();
|
|
|
+ internalData->mKind = CeInternalData::Kind_File;
|
|
|
+ internalData->mFile = file;
|
|
|
+ mInternalDataMap[++mCurHandleId] = internalData;
|
|
|
+ CeSetAddrVal(memStart + addr, mCurHandleId, ptrSize);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ _SetHandle(outStdInAddr, outStdIn);
|
|
|
+ _SetHandle(outStdOutAddr, outStdOut);
|
|
|
+ _SetHandle(outStdErrAddr, outStdErr);
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Kill)
|
|
|
+ {
|
|
|
+ addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
|
|
|
+ int exitCode = *(int*)((uint8*)stackPtr + ptrSize);
|
|
|
+ int killFlags = *(int*)((uint8*)stackPtr + ptrSize + ptrSize);
|
|
|
+ addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize);
|
|
|
+
|
|
|
+ CE_CHECKADDR(outResultAddr, 4);
|
|
|
+
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
|
|
|
+ BfpSpawn_Kill(internalData->mSpawn, exitCode, (BfpKillFlags)killFlags, (BfpSpawnResult*)(memStart + outResultAddr));
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Release)
|
|
|
+ {
|
|
|
+ addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 0);
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
|
|
|
+ internalData->mReleased = true;
|
|
|
+ }
|
|
|
+ else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_WaitFor)
|
|
|
+ {
|
|
|
+ bool& result = *(bool*)((uint8*)stackPtr + 0);
|
|
|
+ addr_ce spawnId = *(addr_ce*)((uint8*)stackPtr + 1);
|
|
|
+ int waitMS = *(int*)((uint8*)stackPtr + 1 + ptrSize);
|
|
|
+ addr_ce outExitCodeAddr = *(addr_ce*)((uint8*)stackPtr + 1 + ptrSize + ptrSize);
|
|
|
+ addr_ce outResultAddr = *(addr_ce*)((uint8*)stackPtr + 1 + ptrSize + ptrSize + ptrSize);
|
|
|
+
|
|
|
+ CE_CHECKADDR(outExitCodeAddr, ptrSize);
|
|
|
+ CE_CHECKADDR(outResultAddr, 4);
|
|
|
+
|
|
|
+ CeInternalData* internalData = NULL;
|
|
|
+ CE_GET_INTERNAL(internalData, (int)spawnId, CeInternalData::Kind_Spawn);
|
|
|
+
|
|
|
+ int timeLeft = waitMS;
|
|
|
+ do
|
|
|
+ {
|
|
|
+ if (*fastFinishPtr)
|
|
|
+ {
|
|
|
+ result = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ int waitTime = 20;
|
|
|
+ if (timeLeft >= 0)
|
|
|
+ {
|
|
|
+ waitTime = BF_MIN(timeLeft, 20);
|
|
|
+ timeLeft -= waitTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ int outExitCode = 0;
|
|
|
+ result = BfpSpawn_WaitFor(internalData->mSpawn, waitTime, &outExitCode, (BfpSpawnResult*)(memStart + outResultAddr));
|
|
|
+ if (result)
|
|
|
+ break;
|
|
|
+ if (waitTime == 0)
|
|
|
+ break;
|
|
|
+ } while (true);
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
Fail(_GetCurFrame(), StrFormat("Unable to invoke extern method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
|
|
|
return false;
|
|
@@ -5005,6 +5378,17 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|
|
|
|
|
++instIdx;
|
|
|
|
|
|
+ if (instIdx >= /*0xBC0*/0xBA0)
|
|
|
+ {
|
|
|
+ NOP;
|
|
|
+ }
|
|
|
+
|
|
|
+// if (instIdx == 0x444)
|
|
|
+// {
|
|
|
+// _CrtCheckMemory();
|
|
|
+// NOP;
|
|
|
+// }
|
|
|
+
|
|
|
CeOp op = CE_GETINST(CeOp);
|
|
|
switch (op)
|
|
|
{
|
|
@@ -5580,7 +5964,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|
|
|
|
|
auto valueType = bfType->ToTypeInstance();
|
|
|
if (valueType->mVirtualMethodTable.IsEmpty())
|
|
|
- ceModule->PopulateType(valueType, BfPopulateType_DataAndMethods);
|
|
|
+ ceModule->PopulateType(valueType, BfPopulateType_Full_Force);
|
|
|
+ if (valueType->mVirtualMethodTable.IsEmpty())
|
|
|
+ {
|
|
|
+ _Fail("Empty virtual table");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
auto methodInstance = (BfMethodInstance*)valueType->mVirtualMethodTable[virtualIdx].mImplementingMethod;
|
|
|
|
|
|
auto callFunction = mCeMachine->GetPreparedFunction(methodInstance);
|
|
@@ -6338,6 +6727,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|
|
_Fail("Unhandled op");
|
|
|
return false;
|
|
|
}
|
|
|
+
|
|
|
+ //BF_ASSERT(_CrtCheckMemory() != 0);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
@@ -6359,7 +6750,7 @@ CeMachine::CeMachine(BfCompiler* compiler)
|
|
|
mCurBuilder = NULL;
|
|
|
mPreparingFunction = NULL;
|
|
|
|
|
|
- mCurEmitContext = NULL;
|
|
|
+ mCurEmitContext = NULL;
|
|
|
|
|
|
mAppendAllocInfo = NULL;
|
|
|
mTempParser = NULL;
|
|
@@ -6893,6 +7284,34 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
|
|
{
|
|
|
if (methodDef->mName == "BfpSystem_GetTimeStamp")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_GetTimeStamp;
|
|
|
+ else if (methodDef->mName == "BfpFile_Close")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Close;
|
|
|
+ else if (methodDef->mName == "BfpFile_Create")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Create;
|
|
|
+ else if (methodDef->mName == "BfpFile_Flush")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Flush;
|
|
|
+ else if (methodDef->mName == "BfpFile_GetFileSize")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpFile_GetFileSize;
|
|
|
+ else if (methodDef->mName == "BfpFile_Read")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Read;
|
|
|
+ else if (methodDef->mName == "BfpFile_Release")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Release;
|
|
|
+ else if (methodDef->mName == "BfpFile_Seek")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Seek;
|
|
|
+ else if (methodDef->mName == "BfpFile_Truncate")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Truncate;
|
|
|
+ else if (methodDef->mName == "BfpFile_Write")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpFile_Write;
|
|
|
+ else if (methodDef->mName == "BfpSpawn_Create")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Create;
|
|
|
+ else if (methodDef->mName == "BfpSpawn_GetStdHandles")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_GetStdHandles;
|
|
|
+ else if (methodDef->mName == "BfpSpawn_Kill")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Kill;
|
|
|
+ else if (methodDef->mName == "BfpSpawn_Release")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_Release;
|
|
|
+ else if (methodDef->mName == "BfpSpawn_WaitFor")
|
|
|
+ ceFunction->mFunctionKind = CeFunctionKind_BfpSpawn_WaitFor;
|
|
|
}
|
|
|
else if (owner->IsInstanceOf(mCeModule->mCompiler->mChar32TypeDef))
|
|
|
{
|
|
@@ -6926,45 +7345,45 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
|
|
{
|
|
|
if (methodDef->mName == "Abs")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Abs;
|
|
|
- if (methodDef->mName == "Acos")
|
|
|
+ else if (methodDef->mName == "Acos")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Acos;
|
|
|
- if (methodDef->mName == "Asin")
|
|
|
+ else if (methodDef->mName == "Asin")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Asin;
|
|
|
- if (methodDef->mName == "Atan")
|
|
|
+ else if (methodDef->mName == "Atan")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan;
|
|
|
- if (methodDef->mName == "Atan2")
|
|
|
+ else if (methodDef->mName == "Atan2")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan2;
|
|
|
- if (methodDef->mName == "Ceiling")
|
|
|
+ else if (methodDef->mName == "Ceiling")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Ceiling;
|
|
|
- if (methodDef->mName == "Cos")
|
|
|
+ else if (methodDef->mName == "Cos")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Cos;
|
|
|
- if (methodDef->mName == "Cosh")
|
|
|
+ else if (methodDef->mName == "Cosh")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Cosh;
|
|
|
- if (methodDef->mName == "Exp")
|
|
|
+ else if (methodDef->mName == "Exp")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Exp;
|
|
|
- if (methodDef->mName == "Floor")
|
|
|
+ else if (methodDef->mName == "Floor")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Floor;
|
|
|
- if (methodDef->mName == "Log")
|
|
|
+ else if (methodDef->mName == "Log")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Log;
|
|
|
- if (methodDef->mName == "Log10")
|
|
|
+ else if (methodDef->mName == "Log10")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Log10;
|
|
|
- if (methodDef->mName == "Mod")
|
|
|
+ else if (methodDef->mName == "Mod")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Mod;
|
|
|
- if (methodDef->mName == "Pow")
|
|
|
+ else if (methodDef->mName == "Pow")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Pow;
|
|
|
- if (methodDef->mName == "Round")
|
|
|
+ else if (methodDef->mName == "Round")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Round;
|
|
|
- if (methodDef->mName == "Sin")
|
|
|
+ else if (methodDef->mName == "Sin")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Sin;
|
|
|
- if (methodDef->mName == "Sinh")
|
|
|
+ else if (methodDef->mName == "Sinh")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Sinh;
|
|
|
- if (methodDef->mName == "Sqrt")
|
|
|
+ else if (methodDef->mName == "Sqrt")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Sqrt;
|
|
|
- if (methodDef->mName == "Tan")
|
|
|
+ else if (methodDef->mName == "Tan")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Tan;
|
|
|
- if (methodDef->mName == "Tanh")
|
|
|
+ else if (methodDef->mName == "Tanh")
|
|
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh;
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
ceFunction->mInitializeState = CeFunction::InitializeState_Initialized;
|
|
|
return;
|
|
@@ -7214,11 +7633,12 @@ CeContext* CeMachine::AllocContext()
|
|
|
ceContext->mMemory.Reserve(BF_CE_INITIAL_MEMORY);
|
|
|
}
|
|
|
|
|
|
- ceContext->mCurEmitContext = mCurEmitContext;
|
|
|
- mCurEmitContext = NULL;
|
|
|
+ ceContext->mCurEmitContext = mCurEmitContext;
|
|
|
+ mCurEmitContext = NULL;
|
|
|
mExecuteId++;
|
|
|
ceContext->mMemory.Resize(BF_CE_STACK_SIZE);
|
|
|
ceContext->mExecuteId = mExecuteId;
|
|
|
+ ceContext->mCurHandleId = 0;
|
|
|
return ceContext;
|
|
|
}
|
|
|
|
|
@@ -7234,9 +7654,12 @@ void CeMachine::ReleaseContext(CeContext* ceContext)
|
|
|
ceContext->mStaticFieldMap.Clear();
|
|
|
ceContext->mHeap->Clear(BF_CE_MAX_CARRYOVER_HEAP);
|
|
|
ceContext->mReflectTypeIdOffset = -1;
|
|
|
- mCurEmitContext = ceContext->mCurEmitContext;
|
|
|
- ceContext->mCurEmitContext = NULL;
|
|
|
+ mCurEmitContext = ceContext->mCurEmitContext;
|
|
|
+ ceContext->mCurEmitContext = NULL;
|
|
|
mContextList.Add(ceContext);
|
|
|
+ for (auto kv : ceContext->mInternalDataMap)
|
|
|
+ delete kv.mValue;
|
|
|
+ ceContext->mInternalDataMap.Clear();
|
|
|
}
|
|
|
|
|
|
BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType)
|
|
@@ -7246,3 +7669,5 @@ BfTypedValue CeMachine::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
|
|
ReleaseContext(ceContext);
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+
|