1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 03:52:19 +02:00

Comptime math and bug fixes

This commit is contained in:
Brian Fiete 2021-01-26 06:33:23 -08:00
parent 621fe99882
commit 61f54a4f88
14 changed files with 684 additions and 122 deletions

View file

@ -169,6 +169,8 @@ ContiguousHeap::AllocRef ContiguousHeap::Alloc(int size)
auto blockList = (ChList*)mMetadata; auto blockList = (ChList*)mMetadata;
if (mFreeIdx >= mFreeList.mSize)
mFreeIdx = 0;
while (true) while (true)
{ {
for (int itr = 0; itr < (int)mFreeList.size(); itr++) for (int itr = 0; itr < (int)mFreeList.size(); itr++)

View file

@ -2673,6 +2673,15 @@ void BeIRCodeGen::HandleNextCmd()
SetResult(curId, mBeModule->GetInsertBlock()); SetResult(curId, mBeModule->GetInsertBlock());
} }
break; break;
case BfIRCmd_Comptime_Error:
{
CMD_PARAM(int32, error);
auto inst = mBeModule->AllocInst<BeComptimeError>();
inst->mError = error;
SetResult(curId, inst);
}
break;
case BfIRCmd_Comptime_GetBfType: case BfIRCmd_Comptime_GetBfType:
{ {
CMD_PARAM(int32, typeId); CMD_PARAM(int32, typeId);

View file

@ -16364,11 +16364,33 @@ void BeMCContext::Generate(BeFunction* function)
auto mcLHS = GetOperand(castedInst->mLHS); auto mcLHS = GetOperand(castedInst->mLHS);
auto mcRHS = GetOperand(castedInst->mRHS); auto mcRHS = GetOperand(castedInst->mRHS);
auto valType = castedInst->mLHS->GetType();
auto mcInst = AllocInst(BeMCInstKind_Cmp, mcLHS, mcRHS); auto mcInst = AllocInst(BeMCInstKind_Cmp, mcLHS, mcRHS);
auto cmpResultIdx = (int)mCmpResults.size(); auto cmpResultIdx = (int)mCmpResults.size();
BeCmpResult cmpResult; BeCmpResult cmpResult;
cmpResult.mCmpKind = castedInst->mCmpKind; cmpResult.mCmpKind = castedInst->mCmpKind;
if (valType->IsFloat())
{
switch (cmpResult.mCmpKind)
{
case BeCmpKind_SLT:
cmpResult.mCmpKind = BeCmpKind_ULT;
break;
case BeCmpKind_SLE:
cmpResult.mCmpKind = BeCmpKind_ULE;
break;
case BeCmpKind_SGT:
cmpResult.mCmpKind = BeCmpKind_UGT;
break;
case BeCmpKind_SGE:
cmpResult.mCmpKind = BeCmpKind_UGE;
break;
}
}
mCmpResults.push_back(cmpResult); mCmpResults.push_back(cmpResult);
result.mKind = BeMCOperandKind_CmpResult; result.mKind = BeMCOperandKind_CmpResult;

View file

@ -2451,6 +2451,7 @@ String BeModule::ToString(BeFunction* wantFunc)
} }
} }
break; break;
DISPLAY_INST1(BeComptimeError, "ComptimeError", mError);
DISPLAY_INST1(BeComptimeGetType, "ComptimeGetType", mTypeId); DISPLAY_INST1(BeComptimeGetType, "ComptimeGetType", mTypeId);
DISPLAY_INST1(BeComptimeGetReflectType, "ComptimeGetReflectType", mTypeId); DISPLAY_INST1(BeComptimeGetReflectType, "ComptimeGetReflectType", mTypeId);
DISPLAY_INST2(BeComptimeDynamicCastCheck, "ComptimeDynamicCastCheck", mValue, mTypeId); DISPLAY_INST2(BeComptimeDynamicCastCheck, "ComptimeDynamicCastCheck", mValue, mTypeId);

View file

@ -1348,6 +1348,22 @@ public:
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
class BeComptimeError : public BeInst
{
public:
BE_VALUE_TYPE(BeComptimeError, BeInst);
public:
int mError;
public:
virtual void HashInst(BeHashContext& hashCtx) override
{
hashCtx.Mixin(TypeId);
hashCtx.Mixin(mError);
}
};
class BeComptimeGetType : public BeInst class BeComptimeGetType : public BeInst
{ {
public: public:

View file

@ -375,6 +375,8 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mBfObjectTypeDef = NULL; mBfObjectTypeDef = NULL;
mChar32TypeDef = NULL; mChar32TypeDef = NULL;
mDoubleTypeDef = NULL;
mMathTypeDef = NULL;
mArray1TypeDef = NULL; mArray1TypeDef = NULL;
mArray2TypeDef = NULL; mArray2TypeDef = NULL;
mArray3TypeDef = NULL; mArray3TypeDef = NULL;
@ -412,6 +414,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mInlineAttributeTypeDef = NULL; mInlineAttributeTypeDef = NULL;
mThreadTypeDef = NULL; mThreadTypeDef = NULL;
mInternalTypeDef = NULL; mInternalTypeDef = NULL;
mPlatformTypeDef = NULL;
mCompilerTypeDef = NULL; mCompilerTypeDef = NULL;
mDiagnosticsDebugTypeDef = NULL; mDiagnosticsDebugTypeDef = NULL;
mIDisposableTypeDef = NULL; mIDisposableTypeDef = NULL;
@ -6599,6 +6602,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
_GetRequiredType("System.Char8"); _GetRequiredType("System.Char8");
_GetRequiredType("System.Char16"); _GetRequiredType("System.Char16");
mChar32TypeDef = _GetRequiredType("System.Char32"); mChar32TypeDef = _GetRequiredType("System.Char32");
mDoubleTypeDef = _GetRequiredType("System.Double");
mMathTypeDef = _GetRequiredType("System.Math");
mBfObjectTypeDef = _GetRequiredType("System.Object"); mBfObjectTypeDef = _GetRequiredType("System.Object");
mArray1TypeDef = _GetRequiredType("System.Array1", 1); mArray1TypeDef = _GetRequiredType("System.Array1", 1);
@ -6639,6 +6644,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute"); mInlineAttributeTypeDef = _GetRequiredType("System.InlineAttribute");
mThreadTypeDef = _GetRequiredType("System.Threading.Thread"); mThreadTypeDef = _GetRequiredType("System.Threading.Thread");
mInternalTypeDef = _GetRequiredType("System.Internal"); mInternalTypeDef = _GetRequiredType("System.Internal");
mPlatformTypeDef = _GetRequiredType("System.Platform");
mCompilerTypeDef = _GetRequiredType("System.Compiler"); mCompilerTypeDef = _GetRequiredType("System.Compiler");
mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug"); mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug");
mIDisposableTypeDef = _GetRequiredType("System.IDisposable"); mIDisposableTypeDef = _GetRequiredType("System.IDisposable");

View file

@ -334,9 +334,11 @@ public:
CompileState mCompileState; CompileState mCompileState;
Array<BfVDataModule*> mVDataModules; Array<BfVDataModule*> mVDataModules;
BfTypeDef* mChar32TypeDef;
BfTypeDef* mBfObjectTypeDef; BfTypeDef* mBfObjectTypeDef;
BfTypeDef* mChar32TypeDef;
BfTypeDef* mDoubleTypeDef;
BfTypeDef* mMathTypeDef;
BfTypeDef* mArray1TypeDef; BfTypeDef* mArray1TypeDef;
BfTypeDef* mArray2TypeDef; BfTypeDef* mArray2TypeDef;
@ -364,6 +366,7 @@ public:
BfTypeDef* mThreadTypeDef; BfTypeDef* mThreadTypeDef;
BfTypeDef* mInternalTypeDef; BfTypeDef* mInternalTypeDef;
BfTypeDef* mPlatformTypeDef;
BfTypeDef* mCompilerTypeDef; BfTypeDef* mCompilerTypeDef;
BfTypeDef* mDiagnosticsDebugTypeDef; BfTypeDef* mDiagnosticsDebugTypeDef;
BfTypeDef* mIDisposableTypeDef; BfTypeDef* mIDisposableTypeDef;

View file

@ -21855,19 +21855,19 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
mModule->GetPrimitiveType(BfTypeCode_Boolean)); mModule->GetPrimitiveType(BfTypeCode_Boolean));
break; break;
case BfBinaryOp_LessThan: case BfBinaryOp_LessThan:
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSignedInt()), mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSigned()),
mModule->GetPrimitiveType(BfTypeCode_Boolean)); mModule->GetPrimitiveType(BfTypeCode_Boolean));
break; break;
case BfBinaryOp_LessThanOrEqual: case BfBinaryOp_LessThanOrEqual:
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLTE(convLeftValue, convRightValue, resultType->IsSignedInt()), mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpLTE(convLeftValue, convRightValue, resultType->IsSigned()),
mModule->GetPrimitiveType(BfTypeCode_Boolean)); mModule->GetPrimitiveType(BfTypeCode_Boolean));
break; break;
case BfBinaryOp_GreaterThan: case BfBinaryOp_GreaterThan:
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSignedInt()), mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSigned()),
mModule->GetPrimitiveType(BfTypeCode_Boolean)); mModule->GetPrimitiveType(BfTypeCode_Boolean));
break; break;
case BfBinaryOp_GreaterThanOrEqual: case BfBinaryOp_GreaterThanOrEqual:
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGTE(convLeftValue, convRightValue, resultType->IsSignedInt()), mResult = BfTypedValue(mModule->mBfIRBuilder->CreateCmpGTE(convLeftValue, convRightValue, resultType->IsSigned()),
mModule->GetPrimitiveType(BfTypeCode_Boolean)); mModule->GetPrimitiveType(BfTypeCode_Boolean));
break; break;
case BfBinaryOp_Compare: case BfBinaryOp_Compare:
@ -21875,7 +21875,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr); auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
if ((convLeftValue.IsConst()) && (convRightValue.IsConst())) if ((convLeftValue.IsConst()) && (convRightValue.IsConst()))
{ {
auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSignedInt()); auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSigned());
auto ltConstant = mModule->mBfIRBuilder->GetConstant(cmpLtVal); auto ltConstant = mModule->mBfIRBuilder->GetConstant(cmpLtVal);
if (ltConstant->mBool) if (ltConstant->mBool)
{ {
@ -21883,7 +21883,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
} }
else else
{ {
auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSignedInt()); auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSigned());
auto rtConstant = mModule->mBfIRBuilder->GetConstant(cmpGtVal); auto rtConstant = mModule->mBfIRBuilder->GetConstant(cmpGtVal);
if (rtConstant->mBool) if (rtConstant->mBool)
mResult = BfTypedValue(mModule->GetConstValue(1, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType); mResult = BfTypedValue(mModule->GetConstValue(1, mModule->GetPrimitiveType(BfTypeCode_IntPtr)), intType);
@ -21893,8 +21893,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
} }
else if ((resultType->IsIntegral()) && (resultType->mSize < intType->mSize)) else if ((resultType->IsIntegral()) && (resultType->mSize < intType->mSize))
{ {
auto leftIntValue = mModule->mBfIRBuilder->CreateNumericCast(convLeftValue, resultType->IsSignedInt(), BfTypeCode_IntPtr); auto leftIntValue = mModule->mBfIRBuilder->CreateNumericCast(convLeftValue, resultType->IsSigned(), BfTypeCode_IntPtr);
auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSignedInt(), BfTypeCode_IntPtr); auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSigned(), BfTypeCode_IntPtr);
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(leftIntValue, rightIntValue), intType); mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(leftIntValue, rightIntValue), intType);
} }
else else
@ -21905,12 +21905,12 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
auto startBlock = mModule->mBfIRBuilder->GetInsertBlock(); auto startBlock = mModule->mBfIRBuilder->GetInsertBlock();
auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSignedInt()); auto cmpLtVal = mModule->mBfIRBuilder->CreateCmpLT(convLeftValue, convRightValue, resultType->IsSigned());
mModule->mBfIRBuilder->CreateCondBr(cmpLtVal, endBlock, checkGtBlock); mModule->mBfIRBuilder->CreateCondBr(cmpLtVal, endBlock, checkGtBlock);
mModule->mBfIRBuilder->AddBlock(checkGtBlock); mModule->mBfIRBuilder->AddBlock(checkGtBlock);
mModule->mBfIRBuilder->SetInsertPoint(checkGtBlock); mModule->mBfIRBuilder->SetInsertPoint(checkGtBlock);
auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSignedInt()); auto cmpGtVal = mModule->mBfIRBuilder->CreateCmpGT(convLeftValue, convRightValue, resultType->IsSigned());
mModule->mBfIRBuilder->CreateCondBr(cmpGtVal, endBlock, eqBlock); mModule->mBfIRBuilder->CreateCondBr(cmpGtVal, endBlock, eqBlock);
mModule->mBfIRBuilder->AddBlock(eqBlock); mModule->mBfIRBuilder->AddBlock(eqBlock);

View file

@ -4991,6 +4991,12 @@ void BfIRBuilder::Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage)
NEW_CMD_INSERTED; NEW_CMD_INSERTED;
} }
void BfIRBuilder::Comptime_Error(int errorKind)
{
BfIRValue retVal = WriteCmd(BfIRCmd_Comptime_Error, errorKind);
NEW_CMD_INSERTED;
}
BfIRValue BfIRBuilder::Comptime_GetBfType(int typeId, BfIRType resultType) BfIRValue BfIRBuilder::Comptime_GetBfType(int typeId, BfIRType resultType)
{ {
BfIRValue retVal = WriteCmd(BfIRCmd_Comptime_GetBfType, typeId, resultType); BfIRValue retVal = WriteCmd(BfIRCmd_Comptime_GetBfType, typeId, resultType);

View file

@ -287,6 +287,7 @@ enum BfIRCmd : uint8
BfIRCmd_Func_SafeRename, BfIRCmd_Func_SafeRename,
BfIRCmd_Func_SetLinkage, BfIRCmd_Func_SetLinkage,
BfIRCmd_Comptime_Error,
BfIRCmd_Comptime_GetBfType, BfIRCmd_Comptime_GetBfType,
BfIRCmd_Comptime_GetReflectType, BfIRCmd_Comptime_GetReflectType,
BfIRCmd_Comptime_DynamicCastCheck, BfIRCmd_Comptime_DynamicCastCheck,
@ -1269,7 +1270,7 @@ public:
BfIRValue CreateRet(BfIRValue val); BfIRValue CreateRet(BfIRValue val);
BfIRValue CreateSetRet(BfIRValue val, int returnTypeId); BfIRValue CreateSetRet(BfIRValue val, int returnTypeId);
void CreateRetVoid(); void CreateRetVoid();
void CreateUnreachable(); void CreateUnreachable();
void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr); void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr);
void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr, int arg); void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr, int arg);
void Func_AddAttribute(BfIRFunction func, int argIdx, BfIRAttribute attr); void Func_AddAttribute(BfIRFunction func, int argIdx, BfIRAttribute attr);
@ -1279,6 +1280,7 @@ public:
void Func_SafeRename(BfIRFunction func); void Func_SafeRename(BfIRFunction func);
void Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage); void Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage);
void Comptime_Error(int errorKind);
BfIRValue Comptime_GetBfType(int typeId, BfIRType resultType); BfIRValue Comptime_GetBfType(int typeId, BfIRType resultType);
BfIRValue Comptime_GetReflectType(int typeId, BfIRType resultType); BfIRValue Comptime_GetReflectType(int typeId, BfIRType resultType);
BfIRValue Comptime_DynamicCastCheck(BfIRValue value, int typeId, BfIRType resultType); BfIRValue Comptime_DynamicCastCheck(BfIRValue value, int typeId, BfIRType resultType);

View file

@ -9322,9 +9322,11 @@ bool BfModule::IsTargetingBeefBackend()
} }
bool BfModule::WantsLifetimes() bool BfModule::WantsLifetimes()
{ {
if (mProject == NULL) if (mProject == NULL)
return false; return false;
if (mBfIRBuilder->mIgnoreWrites)
return false;
return GetModuleOptions().mOptLevel == BfOptLevel_OgPlus; return GetModuleOptions().mOptLevel == BfOptLevel_OgPlus;
} }
@ -9512,16 +9514,25 @@ void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool al
EmitDynamicCastCheck(typedVal, type, endBlock, failBlock, allowNull ? true : false); EmitDynamicCastCheck(typedVal, type, endBlock, failBlock, allowNull ? true : false);
AddBasicBlock(failBlock); AddBasicBlock(failBlock);
SizedArray<BfIRValue, 8> llvmArgs;
auto bitAddr = mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(mContext->mBfObjectType)); if (mIsComptimeModule)
llvmArgs.push_back(bitAddr);
llvmArgs.push_back(GetConstValue32(wantTypeId));
auto objDynCheck = GetInternalMethod("ObjectDynCheckFailed");
BF_ASSERT(objDynCheck);
if (objDynCheck)
{ {
auto callInst = mBfIRBuilder->CreateCall(objDynCheck.mFunc, llvmArgs); mBfIRBuilder->Comptime_Error(CeErrorKind_ObjectDynCheckFailed);
} }
else
{
SizedArray<BfIRValue, 8> llvmArgs;
auto bitAddr = mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(mContext->mBfObjectType));
llvmArgs.push_back(bitAddr);
llvmArgs.push_back(GetConstValue32(wantTypeId));
auto objDynCheck = GetInternalMethod("ObjectDynCheckFailed");
BF_ASSERT(objDynCheck);
if (objDynCheck)
{
auto callInst = mBfIRBuilder->CreateCall(objDynCheck.mFunc, llvmArgs);
}
}
mBfIRBuilder->CreateBr(endBlock); mBfIRBuilder->CreateBr(endBlock);
AddBasicBlock(endBlock); AddBasicBlock(endBlock);

View file

@ -3978,7 +3978,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
BF_ASSERT(methodInstance->mMethodDef->mName == "~this"); BF_ASSERT(methodInstance->mMethodDef->mName == "~this");
SizedArray<BfIRValue, 4> llvmArgs; SizedArray<BfIRValue, 4> llvmArgs;
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType))); llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(objectType)));
expressionEvaluator.CreateCall(deleteStmt->mDeleteToken, methodInstance, methodInstance->mIRFunction, false, llvmArgs); expressionEvaluator.CreateCall(deleteStmt->mDeleteToken, methodInstance, mBfIRBuilder->GetFakeVal(), false, llvmArgs);
} }
if ((deleteStmt->mTargetTypeToken != NULL) && (!isAppendDelete)) if ((deleteStmt->mTargetTypeToken != NULL) && (!isAppendDelete))

View file

@ -81,6 +81,12 @@ struct CeOpInfo
{OPNAME "_I64", OPINFOA, OPINFOB, OPINFOC}, \ {OPNAME "_I64", OPINFOA, OPINFOB, OPINFOC}, \
{OPNAME "_F32", OPINFOA, OPINFOB, OPINFOC}, \ {OPNAME "_F32", OPINFOA, OPINFOB, OPINFOC}, \
{OPNAME "_F64", OPINFOA, OPINFOB, OPINFOC} {OPNAME "_F64", OPINFOA, OPINFOB, OPINFOC}
#define CEOPINFO_SIZED_FLOAT_2(OPNAME, OPINFOA, OPINFOB) \
{OPNAME "_F32", OPINFOA, OPINFOB}, \
{OPNAME "_F64", OPINFOA, OPINFOB}
#define CEOPINFO_SIZED_FLOAT_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
{OPNAME "_F32", OPINFOA, OPINFOB, OPINFOC}, \
{OPNAME "_F64", OPINFOA, OPINFOB, OPINFOC}
static CeOpInfo gOpInfo[] = static CeOpInfo gOpInfo[] =
{ {
@ -170,13 +176,13 @@ static CeOpInfo gOpInfo[] =
{"CeOp_Conv_F64_I64", CEOI_FrameRef, CEOI_FrameRef}, {"CeOp_Conv_F64_I64", CEOI_FrameRef, CEOI_FrameRef},
{"CeOp_Conv_F64_F32", CEOI_FrameRef, CEOI_FrameRef}, {"CeOp_Conv_F64_F32", CEOI_FrameRef, CEOI_FrameRef},
CEOPINFO_SIZED_NUMERIC_PLUSF_2("Abs", CEOI_FrameRef, CEOI_FrameRef),
{"AddConst_I8", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM8}, {"AddConst_I8", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM8},
{"AddConst_I16", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM16}, {"AddConst_I16", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM16},
{"AddConst_I32", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32}, {"AddConst_I32", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32},
{"AddConst_I64", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM64}, {"AddConst_I64", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM64},
{"AddConst_F32", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMMF32}, {"AddConst_F32", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMMF32},
{"AddConst_F64", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMMF64}, {"AddConst_F64", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMMF64},
CEOPINFO_SIZED_NUMERIC_PLUSF_3("Add", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_PLUSF_3("Add", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_NUMERIC_PLUSF_3("Sub", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_PLUSF_3("Sub", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_NUMERIC_PLUSF_3("Mul", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_PLUSF_3("Mul", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
@ -190,6 +196,25 @@ static CeOpInfo gOpInfo[] =
CEOPINFO_SIZED_NUMERIC_3("Shl", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_3("Shl", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_NUMERIC_3("Shr", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_3("Shr", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_UNUMERIC_3("Shr", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_UNUMERIC_3("Shr", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Acos", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Asin", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Atan", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_3("Atan2", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Ceiling", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Cos", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Cosh", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Exp", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Floor", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Log", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Log10", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_3("Pow", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Round", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Sin", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Sinh", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Sqrt", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Tan", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_FLOAT_2("Tanh", CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_EQ", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_EQ", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_NE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef), CEOPINFO_SIZED_NUMERIC_PLUSF_3("Cmp_NE", CEOI_FrameRef, CEOI_FrameRef, CEOI_FrameRef),
@ -210,6 +235,72 @@ static_assert(BF_ARRAY_COUNT(gOpInfo) == (int)CeOp_COUNT, "gOpName incorrect siz
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
static int FloatToString(float d, char* outStr)
{
sprintf(outStr, "%1.9g", d);
int len = (int)strlen(outStr);
for (int i = 0; outStr[i] != 0; i++)
{
if (outStr[i] == '.')
{
int checkC = len - 1;
while (true)
{
char c = outStr[checkC];
if (c == '.')
{
return checkC;
}
else if (c != '0')
{
for (int j = i + 1; j <= checkC; j++)
if (outStr[j] == 'e')
return len;
return checkC + 1;
}
checkC--;
}
}
}
return len;
}
static int DoubleToString(double d, char* outStr)
{
sprintf(outStr, "%1.17g", d);
int len = (int)strlen(outStr);
for (int i = 0; outStr[i] != 0; i++)
{
if (outStr[i] == '.')
{
int checkC = len - 1;
while (true)
{
char c = outStr[checkC];
if (c == '.')
{
return checkC;
}
else if (c == 'e')
{
return len;
}
else if (c != '0')
{
for (int j = i + 1; j <= checkC; j++)
if (outStr[j] == 'e')
return len;
return checkC + 1;
}
checkC--;
}
}
}
return len;
}
//////////////////////////////////////////////////////////////////////////
CeFunction::~CeFunction() CeFunction::~CeFunction()
{ {
BF_ASSERT(mId == -1); BF_ASSERT(mId == -1);
@ -551,6 +642,7 @@ void CeBuilder::EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeO
} }
else if (lhs.mType->IsFloat()) else if (lhs.mType->IsFloat())
{ {
BF_ASSERT(fOp != CeOp_InvalidOp);
if (lhs.mType->mSize == 4) if (lhs.mType->mSize == 4)
op = fOp; op = fOp;
else if (lhs.mType->mSize == 8) else if (lhs.mType->mSize == 8)
@ -1193,7 +1285,6 @@ void CeBuilder::Build()
auto methodInstance = mCeFunction->mMethodInstance; auto methodInstance = mCeFunction->mMethodInstance;
if (methodInstance != NULL) if (methodInstance != NULL)
{ {
BfMethodInstance dupMethodInstance; BfMethodInstance dupMethodInstance;
@ -1968,10 +2059,12 @@ void CeBuilder::Build()
result = ptrValue; result = ptrValue;
result = FrameAlloc(elementPtrType); result = FrameAlloc(elementPtrType);
Emit((CeOp)(CeOp_AddConst_I32)); EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
EmitFrameOffset(result); EmitFrameOffset(result);
EmitFrameOffset(ceVal); EmitFrameOffset(ceVal);
Emit((int32)(ceIdx1.mImmediate * arrayType->mElementType->GetStride())); Emit((int32)(ceIdx1.mImmediate * arrayType->mElementType->GetStride()));
if (mPtrSize == 8)
Emit((int32)0);
} }
} }
else else
@ -2079,10 +2172,12 @@ void CeBuilder::Build()
if (byteOffset != 0) if (byteOffset != 0)
{ {
result = FrameAlloc(elementPtrType); result = FrameAlloc(elementPtrType);
Emit((CeOp)(CeOp_AddConst_I32)); EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
EmitFrameOffset(result); EmitFrameOffset(result);
EmitFrameOffset(ceVal); EmitFrameOffset(ceVal);
Emit((int32)byteOffset); Emit((int32)byteOffset);
if (mPtrSize == 8)
Emit((int32)0);
} }
else else
{ {
@ -2100,10 +2195,12 @@ void CeBuilder::Build()
if (byteOffset != 0) if (byteOffset != 0)
{ {
result = FrameAlloc(ptrType); result = FrameAlloc(ptrType);
Emit((CeOp)(CeOp_AddConst_I32)); EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
EmitFrameOffset(result); EmitFrameOffset(result);
EmitFrameOffset(ceVal); EmitFrameOffset(ceVal);
Emit((int32)byteOffset); Emit((int32)byteOffset);
if (mPtrSize == 8)
Emit((int32)0);
} }
} }
else else
@ -2353,6 +2450,9 @@ void CeBuilder::Build()
{ {
switch (intrin->mKind) switch (intrin->mKind)
{ {
case BfIRIntrinsic_Abs:
EmitUnaryOp(CeOp_Abs_I8, CeOp_Abs_F32, GetOperand(castedInst->mArgs[0].mValue), result);
break;
case BfIRIntrinsic_Cast: case BfIRIntrinsic_Cast:
{ {
result = GetOperand(castedInst->mArgs[0].mValue); result = GetOperand(castedInst->mArgs[0].mValue);
@ -2371,9 +2471,24 @@ void CeBuilder::Build()
EmitFrameOffset(ceSize); EmitFrameOffset(ceSize);
} }
break; break;
case BfIRIntrinsic_AtomicFence: case BfIRIntrinsic_AtomicFence:
// Nothing to do // Nothing to do
break; break;
case BfIRIntrinsic_AtomicAdd:
EmitBinaryOp(CeOp_Add_I8, CeOp_Add_F32, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result);
break;
case BfIRIntrinsic_AtomicOr:
EmitBinaryOp(CeOp_Or_I8, CeOp_InvalidOp, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result);
break;
case BfIRIntrinsic_AtomicSub:
EmitBinaryOp(CeOp_Sub_I8, CeOp_Sub_F32, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result);
break;
case BfIRIntrinsic_AtomicXor:
EmitBinaryOp(CeOp_Xor_I8, CeOp_InvalidOp, GetOperand(castedInst->mArgs[0].mValue), GetOperand(castedInst->mArgs[1].mValue), result);
break;
default: default:
Emit(CeOp_Error); Emit(CeOp_Error);
Emit((int32)CeErrorKind_Intrinsic); Emit((int32)CeErrorKind_Intrinsic);
@ -2384,6 +2499,81 @@ void CeBuilder::Build()
{ {
beFuncType = beFunction->GetFuncType(); beFuncType = beFunction->GetFuncType();
CeFunctionInfo* ceFunctionInfo = NULL;
mCeMachine->mNamedFunctionMap.TryGetValue(beFunction->mName, &ceFunctionInfo);
if (ceFunctionInfo != NULL)
{
CeOp ceOp = CeOp_InvalidOp;
if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_NotSet)
mCeMachine->CheckFunctionKind(ceFunctionInfo->mCeFunction);
if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Abs)
ceOp = CeOp_Abs_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Acos)
ceOp = CeOp_Acos_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Asin)
ceOp = CeOp_Asin_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Atan)
ceOp = CeOp_Atan_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Atan2)
ceOp = CeOp_Atan2_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Ceiling)
ceOp = CeOp_Ceiling_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Cos)
ceOp = CeOp_Cos_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Cosh)
ceOp = CeOp_Cosh_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Exp)
ceOp = CeOp_Exp_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Floor)
ceOp = CeOp_Floor_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Log)
ceOp = CeOp_Log_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Log10)
ceOp = CeOp_Log10_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Pow)
ceOp = CeOp_Pow_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Round)
ceOp = CeOp_Round_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Sin)
ceOp = CeOp_Sin_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Sinh)
ceOp = CeOp_Sinh_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Sqrt)
ceOp = CeOp_Sqrt_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Tan)
ceOp = CeOp_Tan_F32;
else if (ceFunctionInfo->mCeFunction->mFunctionKind == CeFunctionKind_Math_Tanh)
ceOp = CeOp_Tanh_F32;
if (ceOp != CeOp_InvalidOp)
{
if (beFuncType->mReturnType->mSize == 8)
ceOp = (CeOp)(ceOp + 1);
result = FrameAlloc(beFuncType->mReturnType);
if (beFuncType->mParams.size() == 1)
{
auto arg0 = GetOperand(castedInst->mArgs[0].mValue);
Emit(ceOp);
EmitFrameOffset(result);
EmitFrameOffset(arg0);
}
else
{
auto arg0 = GetOperand(castedInst->mArgs[0].mValue);
auto arg1 = GetOperand(castedInst->mArgs[1].mValue);
Emit(ceOp);
EmitFrameOffset(result);
EmitFrameOffset(arg0);
EmitFrameOffset(arg1);
}
break;
}
}
if (beFunction->mName == "malloc") if (beFunction->mName == "malloc")
{ {
result = FrameAlloc(beFuncType->mReturnType); result = FrameAlloc(beFuncType->mReturnType);
@ -2441,6 +2631,8 @@ void CeBuilder::Build()
{ {
CeOperand thisOperand; CeOperand thisOperand;
int stackAdjust = 0;
for (int argIdx = (int)castedInst->mArgs.size() - 1; argIdx >= 0; argIdx--) for (int argIdx = (int)castedInst->mArgs.size() - 1; argIdx >= 0; argIdx--)
{ {
auto& arg = castedInst->mArgs[argIdx]; auto& arg = castedInst->mArgs[argIdx];
@ -2448,15 +2640,13 @@ void CeBuilder::Build()
if (argIdx == 0) if (argIdx == 0)
thisOperand = ceArg; thisOperand = ceArg;
EmitSizedOp(CeOp_Push_8, ceArg, NULL, true); EmitSizedOp(CeOp_Push_8, ceArg, NULL, true);
stackAdjust += ceArg.mType->mSize;
} }
int stackAdjust = 0;
if (beFuncType->mReturnType->mSize > 0) if (beFuncType->mReturnType->mSize > 0)
{ {
Emit(CeOp_AdjustSPConst); Emit(CeOp_AdjustSPConst);
Emit((int32)-beFuncType->mReturnType->mSize); Emit((int32)-beFuncType->mReturnType->mSize);
stackAdjust += beFuncType->mReturnType->mSize;
} }
if (!ceFunc) if (!ceFunc)
@ -2552,6 +2742,13 @@ void CeBuilder::Build()
EmitFrameOffset(mcStackVal); EmitFrameOffset(mcStackVal);
} }
break; break;
case BeComptimeError::TypeId:
{
auto castedInst = (BeComptimeError*)inst;
Emit(CeOp_Error);
Emit(castedInst->mError);
}
break;
case BeComptimeGetType::TypeId: case BeComptimeGetType::TypeId:
{ {
auto castedInst = (BeComptimeGetType*)inst; auto castedInst = (BeComptimeGetType*)inst;
@ -2752,7 +2949,7 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str)
} }
} }
if (emitEntry != NULL) if ((emitEntry != NULL) && (emitEntry->mFile != -1))
err += StrFormat(" at line% d:%d in %s", emitEntry->mLine + 1, emitEntry->mColumn + 1, ceFunction->mFiles[emitEntry->mFile].c_str()); err += StrFormat(" at line% d:%d in %s", emitEntry->mLine + 1, emitEntry->mColumn + 1, ceFunction->mFiles[emitEntry->mFile].c_str());
auto moreInfo = passInstance->MoreInfo(err, mCeMachine->mCeModule->mCompiler->GetAutoComplete() != NULL); auto moreInfo = passInstance->MoreInfo(err, mCeMachine->mCeModule->mCompiler->GetAutoComplete() != NULL);
@ -3964,7 +4161,7 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
{ {
returnValue = BfTypedValue(module->mBfIRBuilder->CreateConstArrayZero(module->mBfIRBuilder->MapType(returnType)), returnType); returnValue = BfTypedValue(module->mBfIRBuilder->CreateConstArrayZero(module->mBfIRBuilder->MapType(returnType)), returnType);
} }
else else if (returnType->IsValuelessType())
{ {
returnValue = BfTypedValue(module->mBfIRBuilder->GetFakeVal(), returnType); returnValue = BfTypedValue(module->mBfIRBuilder->GetFakeVal(), returnType);
} }
@ -4039,6 +4236,20 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
auto rhs = CE_GETINST(T); \ auto rhs = CE_GETINST(T); \
result = lhs OP rhs; \ result = lhs OP rhs; \
} }
#define CEOP_UNARY_FUNC(OP, T) \
{ \
auto& result = CE_GETFRAME(T); \
auto lhs = CE_GETFRAME(T); \
result = OP(lhs); \
}
#define CEOP_BIN_FUNC(OP, T) \
{ \
auto& result = CE_GETFRAME(T); \
auto lhs = CE_GETFRAME(T); \
auto rhs = CE_GETFRAME(T); \
result = OP(lhs, rhs); \
}
#define CEOP_UNARY(OP, T) \ #define CEOP_UNARY(OP, T) \
{ \ { \
auto& result = CE_GETFRAME(T); \ auto& result = CE_GETFRAME(T); \
@ -4176,8 +4387,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
CE_CHECKALLOC(size); CE_CHECKALLOC(size);
uint8* ptr = CeMalloc(size); uint8* ptr = CeMalloc(size);
CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize); CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Free) else if (checkFunction->mFunctionKind == CeFunctionKind_Free)
{ {
@ -4185,8 +4394,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
bool success = CeFree(freeAddr); bool success = CeFree(freeAddr);
if (!success) if (!success)
_Fail("Invalid heap address"); _Fail("Invalid heap address");
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_FatalError) else if (checkFunction->mFunctionKind == CeFunctionKind_FatalError)
{ {
@ -4228,6 +4435,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
return false; return false;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_DynCheckFailed)
{
_Fail("Dynamic cast check failed");
return false;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite) else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite)
{ {
int32 ptrVal = *(int32*)((uint8*)stackPtr + 0); int32 ptrVal = *(int32*)((uint8*)stackPtr + 0);
@ -4237,15 +4449,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
String str; String str;
str.Insert(0, strPtr, size); str.Insert(0, strPtr, size);
OutputDebugStr(str); OutputDebugStr(str);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int) else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int)
{ {
int32 intVal = *(int32*)((uint8*)stackPtr + 0); int32 intVal = *(int32*)((uint8*)stackPtr + 0);
OutputDebugStrF("Debug Val: %d\n", intVal); OutputDebugStrF("Debug Val: %d\n", intVal);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType) else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
{ {
@ -4256,8 +4464,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
auto reflectType = GetReflectType(typeId); auto reflectType = GetReflectType(typeId);
_FixVariables(); _FixVariables();
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeById) else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeById)
{ {
@ -4265,8 +4471,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
auto reflectType = GetReflectType(typeId); auto reflectType = GetReflectType(typeId);
_FixVariables(); _FixVariables();
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeByName) else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeByName)
{ {
@ -4280,8 +4484,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
auto reflectType = GetReflectType(typeName); auto reflectType = GetReflectType(typeName);
_FixVariables(); _FixVariables();
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectSpecializedType) else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectSpecializedType)
{ {
@ -4291,8 +4493,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan); auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan);
_FixVariables(); _FixVariables();
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize); CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttribute) else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttribute)
{ {
@ -4310,8 +4510,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
} }
*(addr_ce*)(stackPtr + 0) = success; *(addr_ce*)(stackPtr + 0) = success;
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethodCount) else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethodCount)
{ {
@ -4325,8 +4523,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
} }
*(int32*)(stackPtr + 0) = (int)typeInfo->mMethodInstances.size(); *(int32*)(stackPtr + 0) = (int)typeInfo->mMethodInstances.size();
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethod) else if (checkFunction->mFunctionKind == CeFunctionKind_GetMethod)
{ {
@ -4346,8 +4542,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
} }
*(int64*)(stackPtr + 0) = (int64)(intptr)typeInfo->mMethodInstances[methodIdx]; *(int64*)(stackPtr + 0) = (int64)(intptr)typeInfo->mMethodInstances[methodIdx];
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Method_ToString) else if (checkFunction->mFunctionKind == CeFunctionKind_Method_ToString)
{ {
@ -4362,8 +4556,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
CeSetAddrVal(stackPtr + 0, GetString(mCeMachine->mCeModule->MethodToString(methodInstance)), ptrSize); CeSetAddrVal(stackPtr + 0, GetString(mCeMachine->mCeModule->MethodToString(methodInstance)), ptrSize);
_FixVariables(); _FixVariables();
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetName) else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetName)
{ {
@ -4378,8 +4570,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
CeSetAddrVal(stackPtr + 0, GetString(methodInstance->mMethodDef->mName), ptrSize); CeSetAddrVal(stackPtr + 0, GetString(methodInstance->mMethodDef->mName), ptrSize);
_FixVariables(); _FixVariables();
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetInfo) else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetInfo)
{ {
@ -4398,9 +4588,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
*(int32*)(stackPtr + 0) = methodInstance->mReturnType->mTypeId; *(int32*)(stackPtr + 0) = methodInstance->mReturnType->mTypeId;
*(int32*)(stackPtr + 4) = methodInstance->GetParamCount(); *(int32*)(stackPtr + 4) = methodInstance->GetParamCount();
*(int16*)(stackPtr + 4+4) = methodInstance->GetMethodFlags(); *(int16*)(stackPtr + 4+4) = methodInstance->GetMethodFlags();
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetParamInfo) else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetParamInfo)
{ {
@ -4422,9 +4610,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_FixVariables(); _FixVariables();
*(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId; *(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
*(int16*)(stackPtr + 4) = 0; // Flags *(int16*)(stackPtr + 4) = 0; // Flags
CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize); CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitTypeBody) else if (checkFunction->mFunctionKind == CeFunctionKind_EmitTypeBody)
{ {
@ -4440,9 +4626,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid StringView"); _Fail("Invalid StringView");
return false; return false;
} }
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodEntry) else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodEntry)
{ {
@ -4460,9 +4643,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid StringView"); _Fail("Invalid StringView");
return false; return false;
} }
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodExit) else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodExit)
{ {
@ -4479,9 +4659,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid StringView"); _Fail("Invalid StringView");
return false; return false;
} }
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMixin) else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMixin)
{ {
@ -4494,9 +4671,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
} }
mCurModule->CEMixin(mCurTargetSrc, emitStr); mCurModule->CEMixin(mCurTargetSrc, emitStr);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Sleep) else if (checkFunction->mFunctionKind == CeFunctionKind_Sleep)
{ {
@ -4515,50 +4689,42 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
BfpThread_Sleep(sleepMS); BfpThread_Sleep(sleepMS);
break; break;
} }
}
handled = true; else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSystem_GetTimeStamp)
return true; {
int64& result = *(int64*)((uint8*)stackPtr + 0);
result = BfpSystem_GetTimeStamp();
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToLower) else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToLower)
{ {
int32& result = *(int32*)((uint8*)stackPtr + 0); int32& result = *(int32*)((uint8*)stackPtr + 0);
int32 val = *(int32*)((uint8*)stackPtr + 4); int32 val = *(int32*)((uint8*)stackPtr + 4);
result = utf8proc_tolower(val); result = utf8proc_tolower(val);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToUpper) else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToUpper)
{ {
int32& result = *(int32*)((uint8*)stackPtr + 0); int32& result = *(int32*)((uint8*)stackPtr + 0);
int32 val = *(int32*)((uint8*)stackPtr + 4); int32 val = *(int32*)((uint8*)stackPtr + 4);
result = utf8proc_toupper(val); result = utf8proc_toupper(val);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLower) else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLower)
{ {
int32& result = *(int32*)((uint8*)stackPtr + 0); int32& result = *(int32*)((uint8*)stackPtr + 0);
int32 val = *(int32*)((uint8*)stackPtr + 1); int32 val = *(int32*)((uint8*)stackPtr + 1);
result = utf8proc_category(val) == UTF8PROC_CATEGORY_LL; result = utf8proc_category(val) == UTF8PROC_CATEGORY_LL;
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsUpper) else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsUpper)
{ {
int32& result = *(int32*)((uint8*)stackPtr + 0); int32& result = *(int32*)((uint8*)stackPtr + 0);
int32 val = *(int32*)((uint8*)stackPtr + 1); int32 val = *(int32*)((uint8*)stackPtr + 1);
result = utf8proc_category(val) == UTF8PROC_CATEGORY_LU; result = utf8proc_category(val) == UTF8PROC_CATEGORY_LU;
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsWhiteSpace_EX) else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsWhiteSpace_EX)
{ {
int32& result = *(int32*)((uint8*)stackPtr + 0); int32& result = *(int32*)((uint8*)stackPtr + 0);
int32 val = *(int32*)((uint8*)stackPtr + 1); int32 val = *(int32*)((uint8*)stackPtr + 1);
auto cat = utf8proc_category(val); auto cat = utf8proc_category(val);
result = (cat == UTF8PROC_CATEGORY_ZS) || (cat == UTF8PROC_CATEGORY_ZL) || (cat == UTF8PROC_CATEGORY_ZP); result = (cat == UTF8PROC_CATEGORY_ZS) || (cat == UTF8PROC_CATEGORY_ZL) || (cat == UTF8PROC_CATEGORY_ZP);
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetterOrDigit) else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetterOrDigit)
{ {
@ -4579,9 +4745,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
break; break;
default: default:
result = false; result = false;
} }
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetter) else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetter)
{ {
@ -4599,9 +4763,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
break; break;
default: default:
result = false; result = false;
} }
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsNumber) else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsNumber)
{ {
@ -4617,13 +4779,69 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
break; break;
default: default:
result = false; result = false;
} }
handled = true;
return true;
} }
else if (checkFunction->mFunctionKind == CeFunctionKind_Double_Strtod)
{
double& result = *(double*)((uint8*)stackPtr + 0);
addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 8);
addr_ce endAddr = *(addr_ce*)((uint8*)stackPtr + 8 + ptrSize);
addr_ce checkAddr = strAddr;
while (true)
{
if ((uintptr)checkAddr >= (uintptr)memSize)
{
checkAddr++;
break;
}
if (memStart[checkAddr] == 0)
break;
}
CE_CHECKADDR(strAddr, checkAddr - strAddr + 1);
Fail(_GetCurFrame(), StrFormat("Unable to invoke extern method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str())); char* strPtr = (char*)(memStart + strAddr);
return false; char** endPtr = NULL;
if (endAddr != NULL)
endPtr = (char**)(memStart + endAddr);
result = strtod(strPtr, endPtr);
if (endAddr != 0)
{
CE_CHECKADDR(endAddr, ptrSize);
CeSetAddrVal(endPtr, (uint8*)endPtr - memStart, ptrSize);
}
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Double_Ftoa)
{
int32& result = *(int32*)((uint8*)stackPtr + 0);
float val = *(float*)((uint8*)stackPtr + 4);
addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 4 + 4);
char str[256];
int count = sprintf(str, "%1.9f", val);
CE_CHECKADDR(strAddr, count + 1);
memcpy(memStart + strAddr, str, count + 1);
result = count;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Double_ToString)
{
int32& result = *(int32*)((uint8*)stackPtr + 0);
double val = *(double*)((uint8*)stackPtr + 4);
addr_ce strAddr = *(addr_ce*)((uint8*)stackPtr + 4 + 8);
char str[256];
int count = DoubleToString(val, str);
CE_CHECKADDR(strAddr, count + 1);
memcpy(memStart + strAddr, str, count + 1);
result = count;
}
else
{
Fail(_GetCurFrame(), StrFormat("Unable to invoke extern method '%s'", ceModule->MethodToString(checkFunction->mMethodInstance).c_str()));
return false;
}
handled = true;
return true;
} }
@ -4719,6 +4937,9 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
case CeErrorKind_Intrinsic: case CeErrorKind_Intrinsic:
_Fail("Intrinsic not allowed"); _Fail("Intrinsic not allowed");
break; break;
case CeErrorKind_ObjectDynCheckFailed:
_Fail("Dynamic cast check failed");
break;
default: default:
_Fail("Operation not allowed"); _Fail("Operation not allowed");
break; break;
@ -4838,6 +5059,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
break; break;
case CeOp_FrameAddr_64: case CeOp_FrameAddr_64:
{ {
//if (instPtr - ceFunction->mCode.mVals == 0x9c1)
auto& result = CE_GETFRAME(int64); auto& result = CE_GETFRAME(int64);
auto addr = &CE_GETFRAME(uint8); auto addr = &CE_GETFRAME(uint8);
result = addr - memStart; result = addr - memStart;
@ -5041,7 +5263,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
case CeOp_AdjustSPConst: case CeOp_AdjustSPConst:
{ {
int32 adjust = CE_GETINST(int32); int32 adjust = CE_GETINST(int32);
stackPtr += adjust; stackPtr += adjust;
} }
break; break;
case CeOp_GetSP: case CeOp_GetSP:
@ -5182,11 +5404,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
BF_ASSERT(memStart == mMemory.mVals); BF_ASSERT(memStart == mMemory.mVals);
auto callFunction = callEntry.mFunction; auto callFunction = callEntry.mFunction;
if (callFunction->mMethodInstance->mMethodDef->mIsLocalMethod)
{
NOP;
}
if (needsFunctionIds) if (needsFunctionIds)
*(int32*)(framePtr + resultFrameIdx) = callFunction->mId; *(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
else else
@ -5427,6 +5644,41 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
case CeOp_Conv_F64_F32: case CeOp_Conv_F64_F32:
CE_CAST(double, float); CE_CAST(double, float);
break; break;
case CeOp_Abs_I8:
{
auto& result = CE_GETFRAME(int8);
auto val = CE_GETFRAME(int8);
result = (val < 0) ? -val : val;
}
break;
case CeOp_Abs_I16:
{
auto& result = CE_GETFRAME(int16);
auto val = CE_GETFRAME(int16);
result = (val < 0) ? -val : val;
}
break;
case CeOp_Abs_I32:
{
auto& result = CE_GETFRAME(int32);
auto val = CE_GETFRAME(int32);
result = (val < 0) ? -val : val;
}
break;
case CeOp_Abs_I64:
{
auto& result = CE_GETFRAME(int64);
auto val = CE_GETFRAME(int64);
result = (val < 0) ? -val : val;
}
break;
case CeOp_Abs_F32:
CEOP_UNARY_FUNC(fabs, float);
break;
case CeOp_Abs_F64:
CEOP_UNARY_FUNC(fabs, double);
break;
case CeOp_AddConst_I8: case CeOp_AddConst_I8:
CEOP_BIN_CONST(+, int8); CEOP_BIN_CONST(+, int8);
break; break;
@ -5646,6 +5898,116 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
case CeOp_Shr_U64: case CeOp_Shr_U64:
CEOP_BIN2(>> , uint64, uint8); CEOP_BIN2(>> , uint64, uint8);
break; break;
case CeOp_Acos_F32:
CEOP_UNARY_FUNC(acosf, float);
break;
case CeOp_Acos_F64:
CEOP_UNARY_FUNC(acos, double);
break;
case CeOp_Asin_F32:
CEOP_UNARY_FUNC(asinf, float);
break;
case CeOp_Asin_F64:
CEOP_UNARY_FUNC(asin, double);
break;
case CeOp_Atan_F32:
CEOP_UNARY_FUNC(atanf, float);
break;
case CeOp_Atan_F64:
CEOP_UNARY_FUNC(atan, double);
break;
case CeOp_Atan2_F32:
CEOP_BIN_FUNC(atan2f, float);
break;
case CeOp_Atan2_F64:
CEOP_BIN_FUNC(atan2, double);
break;
case CeOp_Ceiling_F32:
CEOP_UNARY_FUNC(ceilf, float);
break;
case CeOp_Ceiling_F64:
CEOP_UNARY_FUNC(ceil, double);
break;
case CeOp_Cos_F32:
CEOP_UNARY_FUNC(cosf, float);
break;
case CeOp_Cos_F64:
CEOP_UNARY_FUNC(cos, double);
break;
case CeOp_Cosh_F32:
CEOP_UNARY_FUNC(coshf, float);
break;
case CeOp_Cosh_F64:
CEOP_UNARY_FUNC(cosh, double);
break;
case CeOp_Exp_F32:
CEOP_UNARY_FUNC(expf, float);
break;
case CeOp_Exp_F64:
CEOP_UNARY_FUNC(exp, double);
break;
case CeOp_Floor_F32:
CEOP_UNARY_FUNC(floorf, float);
break;
case CeOp_Floor_F64:
CEOP_UNARY_FUNC(floor, double);
break;
case CeOp_Log_F32:
CEOP_UNARY_FUNC(logf, float);
break;
case CeOp_Log_F64:
CEOP_UNARY_FUNC(log, double);
break;
case CeOp_Log10_F32:
CEOP_UNARY_FUNC(log10f, float);
break;
case CeOp_Log10_F64:
CEOP_UNARY_FUNC(log10, double);
break;
case CeOp_Pow_F32:
CEOP_BIN_FUNC(powf, float);
break;
case CeOp_Pow_F64:
CEOP_BIN_FUNC(pow, double);
break;
case CeOp_Round_F32:
CEOP_UNARY_FUNC(roundf, float);
break;
case CeOp_Round_F64:
CEOP_UNARY_FUNC(round, double);
break;
case CeOp_Sin_F32:
CEOP_UNARY_FUNC(sinf, float);
break;
case CeOp_Sin_F64:
CEOP_UNARY_FUNC(sin, double);
break;
case CeOp_Sinh_F32:
CEOP_UNARY_FUNC(sinhf, float);
break;
case CeOp_Sinh_F64:
CEOP_UNARY_FUNC(sinh, double);
break;
case CeOp_Sqrt_F32:
CEOP_UNARY_FUNC(sqrtf, float);
break;
case CeOp_Sqrt_F64:
CEOP_UNARY_FUNC(sqrt, double);
break;
case CeOp_Tan_F32:
CEOP_UNARY_FUNC(tanf, float);
break;
case CeOp_Tan_F64:
CEOP_UNARY_FUNC(tan, double);
break;
case CeOp_Tanh_F32:
CEOP_UNARY_FUNC(tanhf, float);
break;
case CeOp_Tanh_F64:
CEOP_UNARY_FUNC(tanh, double);
break;
case CeOp_Cmp_NE_I8: case CeOp_Cmp_NE_I8:
CEOP_CMP(!= , int8); CEOP_CMP(!= , int8);
break; break;
@ -6253,10 +6615,9 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV
return CeErrorKind_None; return CeErrorKind_None;
} }
void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder) void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
{ {
AutoTimer autoTimer(mRevisionExecuteTime); ceFunction->mFunctionKind = CeFunctionKind_Normal;
SetAndRestoreValue<CeFunction*> prevCEFunction(mPreparingFunction, ceFunction);
if (ceFunction->mMethodInstance != NULL) if (ceFunction->mMethodInstance != NULL)
{ {
@ -6360,6 +6721,13 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
ceFunction->mFunctionKind = CeFunctionKind_Malloc; ceFunction->mFunctionKind = CeFunctionKind_Malloc;
else if (methodDef->mName == "Dbg_RawFree") else if (methodDef->mName == "Dbg_RawFree")
ceFunction->mFunctionKind = CeFunctionKind_Free; ceFunction->mFunctionKind = CeFunctionKind_Free;
else if (methodDef->mName == "ObjectDynCheckFailed")
ceFunction->mFunctionKind = CeFunctionKind_DynCheckFailed;
}
else if (owner->IsInstanceOf(mCeModule->mCompiler->mPlatformTypeDef))
{
if (methodDef->mName == "BfpSystem_GetTimeStamp")
ceFunction->mFunctionKind = CeFunctionKind_BfpSystem_GetTimeStamp;
} }
else if (owner->IsInstanceOf(mCeModule->mCompiler->mChar32TypeDef)) else if (owner->IsInstanceOf(mCeModule->mCompiler->mChar32TypeDef))
{ {
@ -6380,11 +6748,72 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
else if (methodDef->mName == "get__IsNumer") else if (methodDef->mName == "get__IsNumer")
ceFunction->mFunctionKind = CeFunctionKind_Char32_IsNumber; ceFunction->mFunctionKind = CeFunctionKind_Char32_IsNumber;
} }
else if (owner->IsInstanceOf(mCeModule->mCompiler->mDoubleTypeDef))
{
if (methodDef->mName == "strtod")
ceFunction->mFunctionKind = CeFunctionKind_Double_Strtod;
else if (methodDef->mName == "ftoa")
ceFunction->mFunctionKind = CeFunctionKind_Double_Ftoa;
if (methodDef->mName == "ToString")
ceFunction->mFunctionKind = CeFunctionKind_Double_ToString;
}
else if (owner->IsInstanceOf(mCeModule->mCompiler->mMathTypeDef))
{
if (methodDef->mName == "Abs")
ceFunction->mFunctionKind = CeFunctionKind_Math_Abs;
if (methodDef->mName == "Acos")
ceFunction->mFunctionKind = CeFunctionKind_Math_Acos;
if (methodDef->mName == "Asin")
ceFunction->mFunctionKind = CeFunctionKind_Math_Asin;
if (methodDef->mName == "Atan")
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan;
if (methodDef->mName == "Atan2")
ceFunction->mFunctionKind = CeFunctionKind_Math_Atan2;
if (methodDef->mName == "Ceiling")
ceFunction->mFunctionKind = CeFunctionKind_Math_Ceiling;
if (methodDef->mName == "Cos")
ceFunction->mFunctionKind = CeFunctionKind_Math_Cos;
if (methodDef->mName == "Cosh")
ceFunction->mFunctionKind = CeFunctionKind_Math_Cosh;
if (methodDef->mName == "Exp")
ceFunction->mFunctionKind = CeFunctionKind_Math_Exp;
if (methodDef->mName == "Floor")
ceFunction->mFunctionKind = CeFunctionKind_Math_Floor;
if (methodDef->mName == "Log")
ceFunction->mFunctionKind = CeFunctionKind_Math_Log;
if (methodDef->mName == "Log10")
ceFunction->mFunctionKind = CeFunctionKind_Math_Log10;
if (methodDef->mName == "Mod")
ceFunction->mFunctionKind = CeFunctionKind_Math_Mod;
if (methodDef->mName == "Pow")
ceFunction->mFunctionKind = CeFunctionKind_Math_Pow;
if (methodDef->mName == "Round")
ceFunction->mFunctionKind = CeFunctionKind_Math_Round;
if (methodDef->mName == "Sin")
ceFunction->mFunctionKind = CeFunctionKind_Math_Sin;
if (methodDef->mName == "Sinh")
ceFunction->mFunctionKind = CeFunctionKind_Math_Sinh;
if (methodDef->mName == "Sqrt")
ceFunction->mFunctionKind = CeFunctionKind_Math_Sqrt;
if (methodDef->mName == "Tan")
ceFunction->mFunctionKind = CeFunctionKind_Math_Tan;
if (methodDef->mName == "Tanh")
ceFunction->mFunctionKind = CeFunctionKind_Math_Tanh;
}
ceFunction->mInitialized = true; ceFunction->mInitialized = true;
return; return;
} }
} }
}
void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder)
{
AutoTimer autoTimer(mRevisionExecuteTime);
SetAndRestoreValue<CeFunction*> prevCEFunction(mPreparingFunction, ceFunction);
if (ceFunction->mFunctionKind == CeFunctionKind_NotSet)
CheckFunctionKind(ceFunction);
BF_ASSERT(!ceFunction->mInitialized); BF_ASSERT(!ceFunction->mInitialized);
ceFunction->mInitialized = true; ceFunction->mInitialized = true;

View file

@ -32,6 +32,10 @@ class CeFunction;
CeOp_##OPNAME##_64, \ CeOp_##OPNAME##_64, \
CeOp_##OPNAME##_X CeOp_##OPNAME##_X
#define CEOP_SIZED_FLOAT(OPNAME) \
CeOp_##OPNAME##_F32, \
CeOp_##OPNAME##_F64
#define CEOP_SIZED_NUMERIC(OPNAME) \ #define CEOP_SIZED_NUMERIC(OPNAME) \
CeOp_##OPNAME##_I8, \ CeOp_##OPNAME##_I8, \
CeOp_##OPNAME##_I16, \ CeOp_##OPNAME##_I16, \
@ -58,7 +62,8 @@ enum CeErrorKind
CeErrorKind_Error, CeErrorKind_Error,
CeErrorKind_GlobalVariable, CeErrorKind_GlobalVariable,
CeErrorKind_FunctionPointer, CeErrorKind_FunctionPointer,
CeErrorKind_Intrinsic CeErrorKind_Intrinsic,
CeErrorKind_ObjectDynCheckFailed
}; };
enum CeOp : int16 enum CeOp : int16
@ -146,6 +151,7 @@ enum CeOp : int16
CeOp_Conv_F64_I64, CeOp_Conv_F64_I64,
CeOp_Conv_F64_F32, CeOp_Conv_F64_F32,
CEOP_SIZED_NUMERIC_PLUSF(Abs),
CEOP_SIZED_NUMERIC_PLUSF(AddConst), CEOP_SIZED_NUMERIC_PLUSF(AddConst),
CEOP_SIZED_NUMERIC_PLUSF(Add), CEOP_SIZED_NUMERIC_PLUSF(Add),
CEOP_SIZED_NUMERIC_PLUSF(Sub), CEOP_SIZED_NUMERIC_PLUSF(Sub),
@ -160,7 +166,26 @@ enum CeOp : int16
CEOP_SIZED_NUMERIC(Shl), CEOP_SIZED_NUMERIC(Shl),
CEOP_SIZED_NUMERIC(Shr), CEOP_SIZED_NUMERIC(Shr),
CEOP_SIZED_UNUMERIC(Shr), CEOP_SIZED_UNUMERIC(Shr),
CEOP_SIZED_FLOAT(Acos),
CEOP_SIZED_FLOAT(Asin),
CEOP_SIZED_FLOAT(Atan),
CEOP_SIZED_FLOAT(Atan2),
CEOP_SIZED_FLOAT(Ceiling),
CEOP_SIZED_FLOAT(Cos),
CEOP_SIZED_FLOAT(Cosh),
CEOP_SIZED_FLOAT(Exp),
CEOP_SIZED_FLOAT(Floor),
CEOP_SIZED_FLOAT(Log),
CEOP_SIZED_FLOAT(Log10),
CEOP_SIZED_FLOAT(Pow),
CEOP_SIZED_FLOAT(Round),
CEOP_SIZED_FLOAT(Sin),
CEOP_SIZED_FLOAT(Sinh),
CEOP_SIZED_FLOAT(Sqrt),
CEOP_SIZED_FLOAT(Tan),
CEOP_SIZED_FLOAT(Tanh),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_EQ), CEOP_SIZED_NUMERIC_PLUSF(Cmp_EQ),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_NE), CEOP_SIZED_NUMERIC_PLUSF(Cmp_NE),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT), CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT),
@ -241,11 +266,13 @@ public:
enum CeFunctionKind enum CeFunctionKind
{ {
CeFunctionKind_NotSet,
CeFunctionKind_Normal, CeFunctionKind_Normal,
CeFunctionKind_Extern, CeFunctionKind_Extern,
CeFunctionKind_OOB, CeFunctionKind_OOB,
CeFunctionKind_Malloc, CeFunctionKind_Malloc,
CeFunctionKind_Free, CeFunctionKind_Free,
CeFunctionKind_DynCheckFailed,
CeFunctionKind_FatalError, CeFunctionKind_FatalError,
CeFunctionKind_DebugWrite, CeFunctionKind_DebugWrite,
CeFunctionKind_DebugWrite_Int, CeFunctionKind_DebugWrite_Int,
@ -260,12 +287,15 @@ enum CeFunctionKind
CeFunctionKind_Method_GetName, CeFunctionKind_Method_GetName,
CeFunctionKind_Method_GetInfo, CeFunctionKind_Method_GetInfo,
CeFunctionKind_Method_GetParamInfo, CeFunctionKind_Method_GetParamInfo,
CeFunctionKind_EmitTypeBody, CeFunctionKind_EmitTypeBody,
CeFunctionKind_EmitMethodEntry, CeFunctionKind_EmitMethodEntry,
CeFunctionKind_EmitMethodExit, CeFunctionKind_EmitMethodExit,
CeFunctionKind_EmitMixin, CeFunctionKind_EmitMixin,
CeFunctionKind_BfpSystem_GetTimeStamp,
CeFunctionKind_Sleep, CeFunctionKind_Sleep,
CeFunctionKind_Char32_ToLower, CeFunctionKind_Char32_ToLower,
CeFunctionKind_Char32_ToUpper, CeFunctionKind_Char32_ToUpper,
CeFunctionKind_Char32_IsLower, CeFunctionKind_Char32_IsLower,
@ -274,6 +304,30 @@ enum CeFunctionKind
CeFunctionKind_Char32_IsLetterOrDigit, CeFunctionKind_Char32_IsLetterOrDigit,
CeFunctionKind_Char32_IsLetter, CeFunctionKind_Char32_IsLetter,
CeFunctionKind_Char32_IsNumber, CeFunctionKind_Char32_IsNumber,
CeFunctionKind_Double_Strtod,
CeFunctionKind_Double_Ftoa,
CeFunctionKind_Double_ToString,
CeFunctionKind_Math_Abs,
CeFunctionKind_Math_Acos,
CeFunctionKind_Math_Asin,
CeFunctionKind_Math_Atan,
CeFunctionKind_Math_Atan2,
CeFunctionKind_Math_Ceiling,
CeFunctionKind_Math_Cos,
CeFunctionKind_Math_Cosh,
CeFunctionKind_Math_Exp,
CeFunctionKind_Math_Floor,
CeFunctionKind_Math_Log,
CeFunctionKind_Math_Log10,
CeFunctionKind_Math_Mod,
CeFunctionKind_Math_Pow,
CeFunctionKind_Math_Round,
CeFunctionKind_Math_Sin,
CeFunctionKind_Math_Sinh,
CeFunctionKind_Math_Sqrt,
CeFunctionKind_Math_Tan,
CeFunctionKind_Math_Tanh,
}; };
class CeConstStructFixup class CeConstStructFixup
@ -369,7 +423,7 @@ public:
{ {
mCeFunctionInfo = NULL; mCeFunctionInfo = NULL;
mCeInnerFunctionInfo = NULL; mCeInnerFunctionInfo = NULL;
mFunctionKind = CeFunctionKind_Normal; mFunctionKind = CeFunctionKind_NotSet;
mGenerating = false; mGenerating = false;
mInitialized = false; mInitialized = false;
mMethodInstance = NULL; mMethodInstance = NULL;
@ -738,6 +792,7 @@ public:
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction); void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal, CeContext* ceContext); CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal, CeContext* ceContext);
void CheckFunctionKind(CeFunction* ceFunction);
void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder); void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);
void MapFunctionId(CeFunction* ceFunction); void MapFunctionId(CeFunction* ceFunction);