mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 19:48:20 +02:00
Support for comptime file IO and process creation
This commit is contained in:
parent
045e706600
commit
ce4b6e04de
19 changed files with 726 additions and 89 deletions
|
@ -2,6 +2,7 @@ using System.Reflection;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
|
@ -306,5 +307,21 @@ namespace System
|
||||||
if (Compiler.IsComptime)
|
if (Compiler.IsComptime)
|
||||||
Comptime_EmitMixin(text);
|
Comptime_EmitMixin(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public static Span<uint8> ReadBinary(StringView path)
|
||||||
|
{
|
||||||
|
List<uint8> data = scope .();
|
||||||
|
File.ReadAll(path, data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public static String ReadText(StringView path)
|
||||||
|
{
|
||||||
|
String data = scope .();
|
||||||
|
File.ReadAllText(path, data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,5 +106,24 @@ namespace System.Diagnostics
|
||||||
if (gIsDebuggerPresent)
|
if (gIsDebuggerPresent)
|
||||||
Break();
|
Break();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void WriteMemory(Span<uint8> mem)
|
||||||
|
{
|
||||||
|
String str = scope .();
|
||||||
|
for (int i < mem.Length)
|
||||||
|
{
|
||||||
|
if ((i != 0) && (i % 16 == 0))
|
||||||
|
str.Append('\n');
|
||||||
|
str.AppendF($" {mem.[Friend]mPtr[i]:X2}");
|
||||||
|
}
|
||||||
|
str.Append('\n');
|
||||||
|
Write(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void WriteMemory<T>(T result)
|
||||||
|
{
|
||||||
|
#unwarn
|
||||||
|
WriteMemory(.((.)&result, sizeof(T)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,9 @@ namespace System
|
||||||
|
|
||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
return;
|
||||||
|
|
||||||
#if BF_PLATFORM_WINDOWS
|
#if BF_PLATFORM_WINDOWS
|
||||||
bool isWinSrv()
|
bool isWinSrv()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2909,6 +2909,12 @@ BFP_EXPORT intptr BFP_CALLTYPE BfpFile_Read(BfpFile* file, void* buffer, intptr
|
||||||
//TODO: this doesn't set file stream location. It only works for streams like pipes, sockets, etc
|
//TODO: this doesn't set file stream location. It only works for streams like pipes, sockets, etc
|
||||||
if (::ReadFileEx(file->mHandle, buffer, (uint32)size, &overlapped, OverlappedReadComplete))
|
if (::ReadFileEx(file->mHandle, buffer, (uint32)size, &overlapped, OverlappedReadComplete))
|
||||||
{
|
{
|
||||||
|
if (file->mAsyncData == NULL)
|
||||||
|
{
|
||||||
|
OUTRESULT(BfpFileResult_InvalidParameter);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!file->mAsyncData->WaitAndResetEvent(timeoutMS))
|
if (!file->mAsyncData->WaitAndResetEvent(timeoutMS))
|
||||||
{
|
{
|
||||||
::CancelIoEx(file->mHandle, &overlapped);
|
::CancelIoEx(file->mHandle, &overlapped);
|
||||||
|
|
|
@ -624,6 +624,16 @@ public:
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static StringImpl MakeRef(const char* charPtr, intptr length)
|
||||||
|
{
|
||||||
|
StringImpl str;
|
||||||
|
// This is just a ref - called when we pass a literal to a method (for example)
|
||||||
|
str.mPtr = (char*)charPtr;
|
||||||
|
str.mLength = (int_strsize)length;
|
||||||
|
str.mAllocSizeAndFlags = str.mLength | StrPtrFlag;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
static StringImpl MakeRef(const StringView& strView)
|
static StringImpl MakeRef(const StringView& strView)
|
||||||
{
|
{
|
||||||
StringImpl str;
|
StringImpl str;
|
||||||
|
|
|
@ -51,7 +51,7 @@ namespace IDE.Compiler
|
||||||
static extern char8* BfSystem_GetNamespaceSearch(void* bfSystem, char8* typeName, void* project);
|
static extern char8* BfSystem_GetNamespaceSearch(void* bfSystem, char8* typeName, void* project);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void* BfSystem_CreateProject(void* bfSystem, char8* projectName);
|
static extern void* BfSystem_CreateProject(void* bfSystem, char8* projectName, char8* projectDir);
|
||||||
|
|
||||||
[CallingConvention(.Stdcall), CLink]
|
[CallingConvention(.Stdcall), CLink]
|
||||||
static extern void BfSystem_ClearTypeOptions(void* bfSystem);
|
static extern void BfSystem_ClearTypeOptions(void* bfSystem);
|
||||||
|
@ -142,7 +142,7 @@ namespace IDE.Compiler
|
||||||
{
|
{
|
||||||
using (mMonitor.Enter())
|
using (mMonitor.Enter())
|
||||||
{
|
{
|
||||||
var bfProject = CreateProject(project.mProjectName);
|
var bfProject = CreateProject(project.mProjectName, project.mProjectDir);
|
||||||
mProjectMap[project] = bfProject;
|
mProjectMap[project] = bfProject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,10 +188,10 @@ namespace IDE.Compiler
|
||||||
outNamespaceSearch.Append(namespaceSearch);
|
outNamespaceSearch.Append(namespaceSearch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BfProject CreateProject(String projectName)
|
public BfProject CreateProject(String projectName, String projectDir)
|
||||||
{
|
{
|
||||||
BfProject project = new BfProject();
|
BfProject project = new BfProject();
|
||||||
project.mNativeBfProject = BfSystem_CreateProject(mNativeBfSystem, projectName);
|
project.mNativeBfProject = BfSystem_CreateProject(mNativeBfSystem, projectName, projectDir);
|
||||||
return project;
|
return project;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9167,6 +9167,13 @@ namespace IDE
|
||||||
bool doCompile = false;
|
bool doCompile = false;
|
||||||
if (lastCompileHadMessages)
|
if (lastCompileHadMessages)
|
||||||
doCompile = true;
|
doCompile = true;
|
||||||
|
|
||||||
|
bool needsComptime = true;
|
||||||
|
for (var project in mWorkspace.mProjects)
|
||||||
|
{
|
||||||
|
//Set needsComptime
|
||||||
|
}
|
||||||
|
|
||||||
if ((!workspaceOptions.mIncrementalBuild) && (!lastCompileHadMessages))
|
if ((!workspaceOptions.mIncrementalBuild) && (!lastCompileHadMessages))
|
||||||
{
|
{
|
||||||
tryQueueFiles = false;
|
tryQueueFiles = false;
|
||||||
|
@ -9177,6 +9184,9 @@ namespace IDE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needsComptime)
|
||||||
|
tryQueueFiles = true;
|
||||||
|
|
||||||
if (hotProject != null)
|
if (hotProject != null)
|
||||||
{
|
{
|
||||||
mWorkspace.mHadHotCompileSinceLastFullCompile = true;
|
mWorkspace.mHadHotCompileSinceLastFullCompile = true;
|
||||||
|
@ -9210,6 +9220,9 @@ namespace IDE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (needsComptime)
|
||||||
|
doCompile = true;
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
bfCompiler.QueueDeletePassInstance(passInstance);
|
bfCompiler.QueueDeletePassInstance(passInstance);
|
||||||
|
|
|
@ -2927,7 +2927,7 @@ void BfCompiler::GenerateDynCastData()
|
||||||
|
|
||||||
void BfCompiler::UpdateRevisedTypes()
|
void BfCompiler::UpdateRevisedTypes()
|
||||||
{
|
{
|
||||||
BfLogSysM("UpdateRevisedTypes\n");
|
BfLogSysM("BfCompiler::UpdateRevisedTypes\n");
|
||||||
BP_ZONE("BfCompiler::UpdateRevisedTypes");
|
BP_ZONE("BfCompiler::UpdateRevisedTypes");
|
||||||
|
|
||||||
// See if we have any name conflicts and remove those
|
// See if we have any name conflicts and remove those
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "BfSourceClassifier.h"
|
#include "BfSourceClassifier.h"
|
||||||
#include "BfAutoComplete.h"
|
#include "BfAutoComplete.h"
|
||||||
#include "BfResolvePass.h"
|
#include "BfResolvePass.h"
|
||||||
|
#include "CeMachine.h"
|
||||||
|
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
|
|
||||||
|
@ -1850,6 +1851,7 @@ void BfContext::PreUpdateRevisedTypes()
|
||||||
void BfContext::UpdateRevisedTypes()
|
void BfContext::UpdateRevisedTypes()
|
||||||
{
|
{
|
||||||
BP_ZONE("BfContext::UpdateRevisedTypes");
|
BP_ZONE("BfContext::UpdateRevisedTypes");
|
||||||
|
BfLogSysM("BfContext::UpdateRevisedTypes\n");
|
||||||
|
|
||||||
int wantPtrSize;
|
int wantPtrSize;
|
||||||
if ((mCompiler->mOptions.mMachineType == BfMachineType_x86) |
|
if ((mCompiler->mOptions.mMachineType == BfMachineType_x86) |
|
||||||
|
@ -1889,6 +1891,9 @@ void BfContext::UpdateRevisedTypes()
|
||||||
bool wantsDebugInfo = (mCompiler->mOptions.mEmitDebugInfo);
|
bool wantsDebugInfo = (mCompiler->mOptions.mEmitDebugInfo);
|
||||||
|
|
||||||
Array<BfTypeInstance*> defStateChangedQueue;
|
Array<BfTypeInstance*> defStateChangedQueue;
|
||||||
|
Array<BfTypeInstance*> defEmitParentCheckQueue;
|
||||||
|
|
||||||
|
Dictionary<String, uint64> lastWriteTimeMap;
|
||||||
|
|
||||||
// Do primary 'rebuild' scan
|
// Do primary 'rebuild' scan
|
||||||
for (auto type : mResolvedTypes)
|
for (auto type : mResolvedTypes)
|
||||||
|
@ -1918,19 +1923,7 @@ void BfContext::UpdateRevisedTypes()
|
||||||
auto typeDef = typeInst->mTypeDef;
|
auto typeDef = typeInst->mTypeDef;
|
||||||
|
|
||||||
if (typeDef->mEmitParent != NULL)
|
if (typeDef->mEmitParent != NULL)
|
||||||
{
|
defEmitParentCheckQueue.Add(typeInst);
|
||||||
if (typeDef->mDefState == BfTypeDef::DefState_Deleted)
|
|
||||||
{
|
|
||||||
typeInst->mTypeDef = typeDef->mEmitParent;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto emitTypeDef = typeDef;
|
|
||||||
typeDef = typeDef->mEmitParent;
|
|
||||||
if (typeDef->mNextRevision != NULL)
|
|
||||||
emitTypeDef->mDefState = BfTypeDef::DefState_EmittedDirty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeDef->mProject->mDisabled)
|
if (typeDef->mProject->mDisabled)
|
||||||
{
|
{
|
||||||
|
@ -1948,6 +1941,31 @@ void BfContext::UpdateRevisedTypes()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeInst->mCeTypeInfo != NULL)
|
||||||
|
{
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
for (auto& kv : typeInst->mCeTypeInfo->mRebuildMap)
|
||||||
|
{
|
||||||
|
if (kv.mKey.mKind == CeRebuildKey::Kind_File)
|
||||||
|
{
|
||||||
|
String* keyPtr = NULL;
|
||||||
|
uint64* valuePtr = NULL;
|
||||||
|
if (lastWriteTimeMap.TryAdd(kv.mKey.mString, &keyPtr, &valuePtr))
|
||||||
|
{
|
||||||
|
*valuePtr = BfpFile_GetTime_LastWrite(kv.mKey.mString.c_str());
|
||||||
|
}
|
||||||
|
if (*valuePtr != kv.mValue.mInt)
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
{
|
||||||
|
RebuildType(typeInst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((typeInst->mHotTypeData != NULL) && (!mCompiler->IsHotCompile()))
|
if ((typeInst->mHotTypeData != NULL) && (!mCompiler->IsHotCompile()))
|
||||||
{
|
{
|
||||||
if (typeInst->mHotTypeData->GetLatestVersion()->mDeclHotCompileIdx != 0)
|
if (typeInst->mHotTypeData->GetLatestVersion()->mDeclHotCompileIdx != 0)
|
||||||
|
@ -2042,6 +2060,31 @@ void BfContext::UpdateRevisedTypes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto typeInst : defEmitParentCheckQueue)
|
||||||
|
{
|
||||||
|
if (typeInst->IsDeleting())
|
||||||
|
continue;
|
||||||
|
auto typeDef = typeInst->mTypeDef;
|
||||||
|
if (typeDef->mEmitParent != NULL)
|
||||||
|
{
|
||||||
|
if (typeDef->mDefState == BfTypeDef::DefState_Deleted)
|
||||||
|
{
|
||||||
|
BfLogSysM("Type %p typeDef %p deleted, setting to emitParent %p\n", typeInst, typeDef, typeDef->mEmitParent);
|
||||||
|
typeInst->mTypeDef = typeDef->mEmitParent;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto emitTypeDef = typeDef;
|
||||||
|
typeDef = typeDef->mEmitParent;
|
||||||
|
if (typeDef->mNextRevision != NULL)
|
||||||
|
{
|
||||||
|
BfLogSysM("Type %p typeDef %p emitparent %p has next revision, setting emittedDirty\n", typeInst, emitTypeDef, typeDef);
|
||||||
|
emitTypeDef->mDefState = BfTypeDef::DefState_EmittedDirty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
{
|
{
|
||||||
AutoCrit autoCrit(mSystem->mDataLock);
|
AutoCrit autoCrit(mSystem->mDataLock);
|
||||||
|
|
|
@ -14543,8 +14543,10 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
{
|
{
|
||||||
if (typeInstance->IsObject())
|
if (typeInstance->IsObject())
|
||||||
{
|
{
|
||||||
|
bool hasRealtimeLeakCheck = (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck) && (!IsComptime());
|
||||||
|
|
||||||
bool wantsCtorClear = true;
|
bool wantsCtorClear = true;
|
||||||
if (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck)
|
if (hasRealtimeLeakCheck)
|
||||||
{
|
{
|
||||||
// Dbg_ObjectAlloc clears internally so we don't need to call CtorClear for those
|
// Dbg_ObjectAlloc clears internally so we don't need to call CtorClear for those
|
||||||
if ((!isStackAlloc) && (!allocTarget.mCustomAllocator) && (allocTarget.mScopedInvocationTarget == NULL))
|
if ((!isStackAlloc) && (!allocTarget.mCustomAllocator) && (allocTarget.mScopedInvocationTarget == NULL))
|
||||||
|
@ -14566,7 +14568,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!mModule->mIsComptimeModule) && (isStackAlloc) && (mModule->mCompiler->mOptions.mEnableRealtimeLeakCheck))
|
if ((!mModule->mIsComptimeModule) && (isStackAlloc) && (hasRealtimeLeakCheck))
|
||||||
{
|
{
|
||||||
BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
|
BfMethodInstance* markMethod = mModule->GetRawMethodByName(mModule->mContext->mBfObjectType, "GCMarkMembers");
|
||||||
BF_ASSERT(markMethod != NULL);
|
BF_ASSERT(markMethod != NULL);
|
||||||
|
|
|
@ -1189,7 +1189,10 @@ void BfModule::PopulateType(BfType* resolvedTypeRef, BfPopulateType populateType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BfLogSysM("PopulateType: %p %s populateType:%d ResolveOnly:%d Reified:%d AutoComplete:%d Ctx:%p Mod:%p TypeId:%d\n", resolvedTypeRef, TypeToString(resolvedTypeRef, BfTypeNameFlags_None).c_str(), populateType, mCompiler->mIsResolveOnly, mIsReified, mCompiler->IsAutocomplete(), mContext, this, resolvedTypeRef->mTypeId);
|
BfTypeDef* typeDef = NULL;
|
||||||
|
if (typeInstance != NULL)
|
||||||
|
typeDef = typeInstance->mTypeDef;
|
||||||
|
BfLogSysM("PopulateType: %p %s populateType:%d ResolveOnly:%d Reified:%d AutoComplete:%d Ctx:%p Mod:%p TypeId:%d TypeDef:%p\n", resolvedTypeRef, TypeToString(resolvedTypeRef, BfTypeNameFlags_None).c_str(), populateType, mCompiler->mIsResolveOnly, mIsReified, mCompiler->IsAutocomplete(), mContext, this, resolvedTypeRef->mTypeId, typeDef);
|
||||||
|
|
||||||
BF_ASSERT(!resolvedTypeRef->IsDeleting());
|
BF_ASSERT(!resolvedTypeRef->IsDeleting());
|
||||||
}
|
}
|
||||||
|
@ -2167,11 +2170,6 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
|
||||||
args.Add(attrVal);
|
args.Add(attrVal);
|
||||||
args.Add(mBfIRBuilder->CreateTypeOf(typeInstance));
|
args.Add(mBfIRBuilder->CreateTypeOf(typeInstance));
|
||||||
|
|
||||||
//TESTING
|
|
||||||
// mCompiler->mCEMachine->ReleaseContext(ceContext);
|
|
||||||
// ceContext = mCompiler->mCEMachine->AllocContext();
|
|
||||||
// ceContext->mMemory.mSize = ceContext->mMemory.mAllocSize;
|
|
||||||
|
|
||||||
auto result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_None, NULL);
|
auto result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_None, NULL);
|
||||||
|
|
||||||
if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
|
if (typeInstance->mDefineState == BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||||
|
@ -3732,6 +3730,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
if (typeInstance->mTypeDef != innerTypeInst->mTypeDef)
|
if (typeInstance->mTypeDef != innerTypeInst->mTypeDef)
|
||||||
{
|
{
|
||||||
// Rebuild with proper typedef (generally from inner type comptime emission)
|
// Rebuild with proper typedef (generally from inner type comptime emission)
|
||||||
|
BfLogSysM("Boxed type %p overriding typeDef to %p from inner type %p\n", typeInstance, innerTypeInst->mTypeDef, innerType);
|
||||||
typeInstance->mTypeDef = innerTypeInst->mTypeDef;
|
typeInstance->mTypeDef = innerTypeInst->mTypeDef;
|
||||||
DoPopulateType(resolvedTypeRef, populateType);
|
DoPopulateType(resolvedTypeRef, populateType);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1823,23 +1823,7 @@ public:
|
||||||
String mEmitData;
|
String mEmitData;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BfCeTypeInfo
|
class BfCeTypeInfo;
|
||||||
{
|
|
||||||
public:
|
|
||||||
Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap;
|
|
||||||
Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap;
|
|
||||||
Array<int> mPendingInterfaces;
|
|
||||||
Val128 mHash;
|
|
||||||
bool mFailed;
|
|
||||||
BfCeTypeInfo* mNext;
|
|
||||||
|
|
||||||
public:
|
|
||||||
BfCeTypeInfo()
|
|
||||||
{
|
|
||||||
mFailed = false;
|
|
||||||
mNext = NULL;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Instance of struct or class
|
// Instance of struct or class
|
||||||
class BfTypeInstance : public BfDependedType
|
class BfTypeInstance : public BfDependedType
|
||||||
|
|
|
@ -4159,11 +4159,12 @@ BF_EXPORT const char* BF_CALLTYPE BfSystem_GetNamespaceSearch(BfSystem* bfSystem
|
||||||
return outString.c_str();
|
return outString.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
BF_EXPORT BfProject* BF_CALLTYPE BfSystem_CreateProject(BfSystem* bfSystem, const char* projectName)
|
BF_EXPORT BfProject* BF_CALLTYPE BfSystem_CreateProject(BfSystem* bfSystem, const char* projectName, const char* projectDir)
|
||||||
{
|
{
|
||||||
AutoCrit autoCrit(bfSystem->mDataLock);
|
AutoCrit autoCrit(bfSystem->mDataLock);
|
||||||
BfProject* bfProject = new BfProject();
|
BfProject* bfProject = new BfProject();
|
||||||
bfProject->mName = projectName;
|
bfProject->mName = projectName;
|
||||||
|
bfProject->mDirectory = projectDir;
|
||||||
bfProject->mSystem = bfSystem;
|
bfProject->mSystem = bfSystem;
|
||||||
bfProject->mIdx = (int)bfSystem->mProjects.size();
|
bfProject->mIdx = (int)bfSystem->mProjects.size();
|
||||||
bfSystem->mProjects.push_back(bfProject);
|
bfSystem->mProjects.push_back(bfProject);
|
||||||
|
|
|
@ -1180,6 +1180,7 @@ public:
|
||||||
BfSystem* mSystem;
|
BfSystem* mSystem;
|
||||||
String mName;
|
String mName;
|
||||||
String mSafeName;
|
String mSafeName;
|
||||||
|
String mDirectory;
|
||||||
Array<BfProject*> mDependencies;
|
Array<BfProject*> mDependencies;
|
||||||
BfTargetType mTargetType;
|
BfTargetType mTargetType;
|
||||||
BfCodeGenOptions mCodeGenOptions;
|
BfCodeGenOptions mCodeGenOptions;
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
#include "BfReducer.h"
|
#include "BfReducer.h"
|
||||||
#include "BfExprEvaluator.h"
|
#include "BfExprEvaluator.h"
|
||||||
#include "../Backend/BeIRCodeGen.h"
|
#include "../Backend/BeIRCodeGen.h"
|
||||||
|
#include "BeefySysLib/platform/PlatformHelper.h"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#include "BeefySysLib/third_party/utf8proc/utf8proc.h"
|
#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()
|
CeFunction::~CeFunction()
|
||||||
{
|
{
|
||||||
BF_ASSERT(mId == -1);
|
BF_ASSERT(mId == -1);
|
||||||
|
@ -1316,6 +1336,11 @@ void CeBuilder::Build()
|
||||||
if (mCeFunction->mInitializeState == CeFunction::InitializeState_Initialized)
|
if (mCeFunction->mInitializeState == CeFunction::InitializeState_Initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (methodInstance->mMethodDef->mName == "DecodeToUTF8")
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dupMethodInstance.mIRFunction)
|
if (!dupMethodInstance.mIRFunction)
|
||||||
{
|
{
|
||||||
mCeFunction->mFailed = true;
|
mCeFunction->mFailed = true;
|
||||||
|
@ -2886,6 +2911,7 @@ CeContext::CeContext()
|
||||||
CeContext::~CeContext()
|
CeContext::~CeContext()
|
||||||
{
|
{
|
||||||
delete mHeap;
|
delete mHeap;
|
||||||
|
BF_ASSERT(mInternalDataMap.IsEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
BfError* CeContext::Fail(const StringImpl& error)
|
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)
|
uint8* CeContext::CeMalloc(int size)
|
||||||
{
|
{
|
||||||
#ifdef CE_ENABLE_HEAP
|
#ifdef CE_ENABLE_HEAP
|
||||||
|
@ -4308,6 +4345,59 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
return false; \
|
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_GETINST(T) *((T*)(instPtr += sizeof(T)) - 1)
|
||||||
#define CE_GETFRAME(T) *(T*)(framePtr + *((int32*)(instPtr += sizeof(int32)) - 1))
|
#define CE_GETFRAME(T) *(T*)(framePtr + *((int32*)(instPtr += sizeof(int32)) - 1))
|
||||||
#define CEOP_BIN(OP, T) \
|
#define CEOP_BIN(OP, T) \
|
||||||
|
@ -4422,7 +4512,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
|
||||||
instPtr = &ceFunction->mCode[0]; \
|
instPtr = &ceFunction->mCode[0]; \
|
||||||
CE_CHECKSTACK();
|
CE_CHECKSTACK();
|
||||||
|
|
||||||
static void CeSetAddrVal(void* ptr, addr_ce val, int32 ptrSize)
|
static void CeSetAddrVal(void* ptr, int64 val, int32 ptrSize)
|
||||||
{
|
{
|
||||||
if (ptrSize == 4)
|
if (ptrSize == 4)
|
||||||
*(int32*)(ptr) = (int32)val;
|
*(int32*)(ptr) = (int32)val;
|
||||||
|
@ -4558,10 +4648,18 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
OutputDebugStr(str);
|
OutputDebugStr(str);
|
||||||
}
|
}
|
||||||
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int)
|
||||||
|
{
|
||||||
|
if (ceModule->mSystem->mPtrSize == 4)
|
||||||
{
|
{
|
||||||
int32 intVal = *(int32*)((uint8*)stackPtr + 0);
|
int32 intVal = *(int32*)((uint8*)stackPtr + 0);
|
||||||
OutputDebugStrF("Debug Val: %d\n", intVal);
|
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)
|
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);
|
||||||
|
@ -4921,6 +5019,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
}
|
}
|
||||||
if (memStart[checkAddr] == 0)
|
if (memStart[checkAddr] == 0)
|
||||||
break;
|
break;
|
||||||
|
checkAddr++;
|
||||||
}
|
}
|
||||||
CE_CHECKADDR(strAddr, checkAddr - strAddr + 1);
|
CE_CHECKADDR(strAddr, checkAddr - strAddr + 1);
|
||||||
|
|
||||||
|
@ -4959,6 +5058,280 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
memcpy(memStart + strAddr, str, count + 1);
|
memcpy(memStart + strAddr, str, count + 1);
|
||||||
result = count;
|
result = count;
|
||||||
}
|
}
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
Fail(_GetCurFrame(), StrFormat("Unable to invoke extern method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
|
Fail(_GetCurFrame(), StrFormat("Unable to invoke extern method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
|
||||||
|
@ -5005,6 +5378,17 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
++instIdx;
|
++instIdx;
|
||||||
|
|
||||||
|
if (instIdx >= /*0xBC0*/0xBA0)
|
||||||
|
{
|
||||||
|
NOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (instIdx == 0x444)
|
||||||
|
// {
|
||||||
|
// _CrtCheckMemory();
|
||||||
|
// NOP;
|
||||||
|
// }
|
||||||
|
|
||||||
CeOp op = CE_GETINST(CeOp);
|
CeOp op = CE_GETINST(CeOp);
|
||||||
switch (op)
|
switch (op)
|
||||||
{
|
{
|
||||||
|
@ -5580,7 +5964,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
|
|
||||||
auto valueType = bfType->ToTypeInstance();
|
auto valueType = bfType->ToTypeInstance();
|
||||||
if (valueType->mVirtualMethodTable.IsEmpty())
|
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 methodInstance = (BfMethodInstance*)valueType->mVirtualMethodTable[virtualIdx].mImplementingMethod;
|
||||||
|
|
||||||
auto callFunction = mCeMachine->GetPreparedFunction(methodInstance);
|
auto callFunction = mCeMachine->GetPreparedFunction(methodInstance);
|
||||||
|
@ -6338,6 +6727,8 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
_Fail("Unhandled op");
|
_Fail("Unhandled op");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//BF_ASSERT(_CrtCheckMemory() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -6893,6 +7284,34 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
||||||
{
|
{
|
||||||
if (methodDef->mName == "BfpSystem_GetTimeStamp")
|
if (methodDef->mName == "BfpSystem_GetTimeStamp")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_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))
|
else if (owner->IsInstanceOf(mCeModule->mCompiler->mChar32TypeDef))
|
||||||
{
|
{
|
||||||
|
@ -6926,43 +7345,43 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
||||||
{
|
{
|
||||||
if (methodDef->mName == "Abs")
|
if (methodDef->mName == "Abs")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Abs;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Abs;
|
||||||
if (methodDef->mName == "Acos")
|
else if (methodDef->mName == "Acos")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Acos;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Acos;
|
||||||
if (methodDef->mName == "Asin")
|
else if (methodDef->mName == "Asin")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Asin;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Asin;
|
||||||
if (methodDef->mName == "Atan")
|
else if (methodDef->mName == "Atan")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan;
|
||||||
if (methodDef->mName == "Atan2")
|
else if (methodDef->mName == "Atan2")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan2;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan2;
|
||||||
if (methodDef->mName == "Ceiling")
|
else if (methodDef->mName == "Ceiling")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Ceiling;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Ceiling;
|
||||||
if (methodDef->mName == "Cos")
|
else if (methodDef->mName == "Cos")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Cos;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Cos;
|
||||||
if (methodDef->mName == "Cosh")
|
else if (methodDef->mName == "Cosh")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Cosh;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Cosh;
|
||||||
if (methodDef->mName == "Exp")
|
else if (methodDef->mName == "Exp")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Exp;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Exp;
|
||||||
if (methodDef->mName == "Floor")
|
else if (methodDef->mName == "Floor")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Floor;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Floor;
|
||||||
if (methodDef->mName == "Log")
|
else if (methodDef->mName == "Log")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Log;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Log;
|
||||||
if (methodDef->mName == "Log10")
|
else if (methodDef->mName == "Log10")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Log10;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Log10;
|
||||||
if (methodDef->mName == "Mod")
|
else if (methodDef->mName == "Mod")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Mod;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Mod;
|
||||||
if (methodDef->mName == "Pow")
|
else if (methodDef->mName == "Pow")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Pow;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Pow;
|
||||||
if (methodDef->mName == "Round")
|
else if (methodDef->mName == "Round")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Round;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Round;
|
||||||
if (methodDef->mName == "Sin")
|
else if (methodDef->mName == "Sin")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Sin;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Sin;
|
||||||
if (methodDef->mName == "Sinh")
|
else if (methodDef->mName == "Sinh")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Sinh;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Sinh;
|
||||||
if (methodDef->mName == "Sqrt")
|
else if (methodDef->mName == "Sqrt")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Sqrt;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Sqrt;
|
||||||
if (methodDef->mName == "Tan")
|
else if (methodDef->mName == "Tan")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Tan;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Tan;
|
||||||
if (methodDef->mName == "Tanh")
|
else if (methodDef->mName == "Tanh")
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh;
|
ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7219,6 +7638,7 @@ CeContext* CeMachine::AllocContext()
|
||||||
mExecuteId++;
|
mExecuteId++;
|
||||||
ceContext->mMemory.Resize(BF_CE_STACK_SIZE);
|
ceContext->mMemory.Resize(BF_CE_STACK_SIZE);
|
||||||
ceContext->mExecuteId = mExecuteId;
|
ceContext->mExecuteId = mExecuteId;
|
||||||
|
ceContext->mCurHandleId = 0;
|
||||||
return ceContext;
|
return ceContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7237,6 +7657,9 @@ void CeMachine::ReleaseContext(CeContext* ceContext)
|
||||||
mCurEmitContext = ceContext->mCurEmitContext;
|
mCurEmitContext = ceContext->mCurEmitContext;
|
||||||
ceContext->mCurEmitContext = NULL;
|
ceContext->mCurEmitContext = NULL;
|
||||||
mContextList.Add(ceContext);
|
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)
|
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);
|
ReleaseContext(ceContext);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -264,6 +264,37 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CeInternalData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Kind
|
||||||
|
{
|
||||||
|
Kind_None,
|
||||||
|
Kind_File,
|
||||||
|
Kind_FindFileData,
|
||||||
|
Kind_Spawn
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Kind mKind;
|
||||||
|
bool mReleased;
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
BfpFile* mFile;
|
||||||
|
BfpFindFileData* mFindFileData;
|
||||||
|
BfpSpawn* mSpawn;
|
||||||
|
};
|
||||||
|
|
||||||
|
CeInternalData()
|
||||||
|
{
|
||||||
|
mKind = Kind_None;
|
||||||
|
mReleased = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
~CeInternalData();
|
||||||
|
};
|
||||||
|
|
||||||
enum CeFunctionKind
|
enum CeFunctionKind
|
||||||
{
|
{
|
||||||
CeFunctionKind_NotSet,
|
CeFunctionKind_NotSet,
|
||||||
|
@ -294,6 +325,21 @@ enum CeFunctionKind
|
||||||
CeFunctionKind_EmitMethodExit,
|
CeFunctionKind_EmitMethodExit,
|
||||||
CeFunctionKind_EmitMixin,
|
CeFunctionKind_EmitMixin,
|
||||||
|
|
||||||
|
CeFunctionKind_BfpFile_Close,
|
||||||
|
CeFunctionKind_BfpFile_Create,
|
||||||
|
CeFunctionKind_BfpFile_Flush,
|
||||||
|
CeFunctionKind_BfpFile_GetFileSize,
|
||||||
|
CeFunctionKind_BfpFile_Read,
|
||||||
|
CeFunctionKind_BfpFile_Release,
|
||||||
|
CeFunctionKind_BfpFile_Seek,
|
||||||
|
CeFunctionKind_BfpFile_Truncate,
|
||||||
|
CeFunctionKind_BfpFile_Write,
|
||||||
|
CeFunctionKind_BfpSpawn_Create,
|
||||||
|
CeFunctionKind_BfpSpawn_GetStdHandles,
|
||||||
|
CeFunctionKind_BfpSpawn_Kill,
|
||||||
|
CeFunctionKind_BfpSpawn_Release,
|
||||||
|
CeFunctionKind_BfpSpawn_WaitFor,
|
||||||
|
|
||||||
CeFunctionKind_BfpSystem_GetTimeStamp,
|
CeFunctionKind_BfpSystem_GetTimeStamp,
|
||||||
CeFunctionKind_Sleep,
|
CeFunctionKind_Sleep,
|
||||||
|
|
||||||
|
@ -683,6 +729,34 @@ public:
|
||||||
BfIRValue mAppendSizeValue;
|
BfIRValue mAppendSizeValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CeRebuildKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Kind
|
||||||
|
{
|
||||||
|
Kind_None,
|
||||||
|
Kind_File
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Kind mKind;
|
||||||
|
String mString;
|
||||||
|
|
||||||
|
bool operator==(const CeRebuildKey& other) const
|
||||||
|
{
|
||||||
|
return (mKind == other.mKind) && (mString == other.mString);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CeRebuildValue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
union
|
||||||
|
{
|
||||||
|
uint64 mInt;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
class CeEmitContext
|
class CeEmitContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -706,6 +780,25 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BfCeTypeInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap;
|
||||||
|
Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap;
|
||||||
|
Array<int> mPendingInterfaces;
|
||||||
|
Dictionary<CeRebuildKey, CeRebuildValue> mRebuildMap;
|
||||||
|
Val128 mHash;
|
||||||
|
bool mFailed;
|
||||||
|
BfCeTypeInfo* mNext;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BfCeTypeInfo()
|
||||||
|
{
|
||||||
|
mFailed = false;
|
||||||
|
mNext = NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class CeContext
|
class CeContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -724,7 +817,8 @@ public:
|
||||||
Dictionary<Val128, addr_ce> mConstDataMap;
|
Dictionary<Val128, addr_ce> mConstDataMap;
|
||||||
HashSet<int> mStaticCtorExecSet;
|
HashSet<int> mStaticCtorExecSet;
|
||||||
Dictionary<String, CeStaticFieldInfo> mStaticFieldMap;
|
Dictionary<String, CeStaticFieldInfo> mStaticFieldMap;
|
||||||
Dictionary<void*, addr_ce> mMemToCtxMap;
|
Dictionary<int, CeInternalData*> mInternalDataMap;
|
||||||
|
int mCurHandleId;
|
||||||
|
|
||||||
BfMethodInstance* mCurMethodInstance;
|
BfMethodInstance* mCurMethodInstance;
|
||||||
BfType* mCurExpectingType;
|
BfType* mCurExpectingType;
|
||||||
|
@ -740,6 +834,7 @@ public:
|
||||||
BfError* Fail(const StringImpl& error);
|
BfError* Fail(const StringImpl& error);
|
||||||
BfError* Fail(const CeFrame& curFrame, const StringImpl& error);
|
BfError* Fail(const CeFrame& curFrame, const StringImpl& error);
|
||||||
|
|
||||||
|
void AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value);
|
||||||
uint8* CeMalloc(int size);
|
uint8* CeMalloc(int size);
|
||||||
bool CeFree(addr_ce addr);
|
bool CeFree(addr_ce addr);
|
||||||
addr_ce CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr);
|
addr_ce CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr);
|
||||||
|
@ -838,3 +933,15 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_BF_END
|
NS_BF_END
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template <>
|
||||||
|
struct hash<Beefy::CeRebuildKey>
|
||||||
|
{
|
||||||
|
size_t operator()(const Beefy::CeRebuildKey& key) const
|
||||||
|
{
|
||||||
|
return BeefHash<Beefy::String>()(key.mString) ^ (size_t)key.mKind;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
2
IDEHelper/Tests/Test0.txt
Normal file
2
IDEHelper/Tests/Test0.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Test
|
||||||
|
0
|
|
@ -229,6 +229,9 @@ namespace Tests
|
||||||
GC.Mark!((*ptr));
|
GC.Mark!((*ptr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const String cTest0 = Compiler.ReadText("Test0.txt");
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -269,6 +272,8 @@ namespace Tests
|
||||||
SerializationContext serCtx = scope .();
|
SerializationContext serCtx = scope .();
|
||||||
iSer.Serialize(serCtx);
|
iSer.Serialize(serCtx);
|
||||||
Test.Assert(serCtx.mStr == "x 10\ny 2\n");
|
Test.Assert(serCtx.mStr == "x 10\ny 2\n");
|
||||||
|
|
||||||
|
Test.Assert(cTest0 == "Test\n0");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue