1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 03:28:20 +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;
if (mFreeIdx >= mFreeList.mSize)
mFreeIdx = 0;
while (true)
{
for (int itr = 0; itr < (int)mFreeList.size(); itr++)

View file

@ -2673,6 +2673,15 @@ void BeIRCodeGen::HandleNextCmd()
SetResult(curId, mBeModule->GetInsertBlock());
}
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:
{
CMD_PARAM(int32, typeId);

View file

@ -16364,11 +16364,33 @@ void BeMCContext::Generate(BeFunction* function)
auto mcLHS = GetOperand(castedInst->mLHS);
auto mcRHS = GetOperand(castedInst->mRHS);
auto valType = castedInst->mLHS->GetType();
auto mcInst = AllocInst(BeMCInstKind_Cmp, mcLHS, mcRHS);
auto cmpResultIdx = (int)mCmpResults.size();
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);
result.mKind = BeMCOperandKind_CmpResult;

View file

@ -2451,6 +2451,7 @@ String BeModule::ToString(BeFunction* wantFunc)
}
}
break;
DISPLAY_INST1(BeComptimeError, "ComptimeError", mError);
DISPLAY_INST1(BeComptimeGetType, "ComptimeGetType", mTypeId);
DISPLAY_INST1(BeComptimeGetReflectType, "ComptimeGetReflectType", 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
{
public:

View file

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

View file

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

View file

@ -21855,19 +21855,19 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
mModule->GetPrimitiveType(BfTypeCode_Boolean));
break;
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));
break;
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));
break;
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));
break;
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));
break;
case BfBinaryOp_Compare:
@ -21875,7 +21875,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
auto intType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
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);
if (ltConstant->mBool)
{
@ -21883,7 +21883,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
}
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);
if (rtConstant->mBool)
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))
{
auto leftIntValue = mModule->mBfIRBuilder->CreateNumericCast(convLeftValue, resultType->IsSignedInt(), BfTypeCode_IntPtr);
auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSignedInt(), BfTypeCode_IntPtr);
auto leftIntValue = mModule->mBfIRBuilder->CreateNumericCast(convLeftValue, resultType->IsSigned(), BfTypeCode_IntPtr);
auto rightIntValue = mModule->mBfIRBuilder->CreateNumericCast(convRightValue, resultType->IsSigned(), BfTypeCode_IntPtr);
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateSub(leftIntValue, rightIntValue), intType);
}
else
@ -21905,12 +21905,12 @@ void BfExprEvaluator::PerformBinaryOperation(BfType* resultType, BfIRValue convL
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->AddBlock(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->AddBlock(eqBlock);

View file

@ -4991,6 +4991,12 @@ void BfIRBuilder::Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage)
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 retVal = WriteCmd(BfIRCmd_Comptime_GetBfType, typeId, resultType);

View file

@ -287,6 +287,7 @@ enum BfIRCmd : uint8
BfIRCmd_Func_SafeRename,
BfIRCmd_Func_SetLinkage,
BfIRCmd_Comptime_Error,
BfIRCmd_Comptime_GetBfType,
BfIRCmd_Comptime_GetReflectType,
BfIRCmd_Comptime_DynamicCastCheck,
@ -1269,7 +1270,7 @@ public:
BfIRValue CreateRet(BfIRValue val);
BfIRValue CreateSetRet(BfIRValue val, int returnTypeId);
void CreateRetVoid();
void CreateUnreachable();
void CreateUnreachable();
void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr);
void Call_AddAttribute(BfIRValue callInst, int argIdx, BfIRAttribute attr, int arg);
void Func_AddAttribute(BfIRFunction func, int argIdx, BfIRAttribute attr);
@ -1279,6 +1280,7 @@ public:
void Func_SafeRename(BfIRFunction func);
void Func_SetLinkage(BfIRFunction func, BfIRLinkageType linkage);
void Comptime_Error(int errorKind);
BfIRValue Comptime_GetBfType(int typeId, BfIRType resultType);
BfIRValue Comptime_GetReflectType(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()
{
{
if (mProject == NULL)
return false;
if (mBfIRBuilder->mIgnoreWrites)
return false;
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);
AddBasicBlock(failBlock);
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)
if (mIsComptimeModule)
{
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);
AddBasicBlock(endBlock);

View file

@ -3978,7 +3978,7 @@ void BfModule::Visit(BfDeleteStatement* deleteStmt)
BF_ASSERT(methodInstance->mMethodDef->mName == "~this");
SizedArray<BfIRValue, 4> llvmArgs;
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))

View file

@ -81,6 +81,12 @@ struct CeOpInfo
{OPNAME "_I64", OPINFOA, OPINFOB, OPINFOC}, \
{OPNAME "_F32", 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[] =
{
@ -170,13 +176,13 @@ static CeOpInfo gOpInfo[] =
{"CeOp_Conv_F64_I64", 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_I16", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM16},
{"AddConst_I32", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM32},
{"AddConst_I64", CEOI_FrameRef, CEOI_FrameRef, CEOI_IMM64},
{"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("Sub", 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("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_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()
{
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())
{
BF_ASSERT(fOp != CeOp_InvalidOp);
if (lhs.mType->mSize == 4)
op = fOp;
else if (lhs.mType->mSize == 8)
@ -1193,7 +1285,6 @@ void CeBuilder::Build()
auto methodInstance = mCeFunction->mMethodInstance;
if (methodInstance != NULL)
{
BfMethodInstance dupMethodInstance;
@ -1968,10 +2059,12 @@ void CeBuilder::Build()
result = ptrValue;
result = FrameAlloc(elementPtrType);
Emit((CeOp)(CeOp_AddConst_I32));
EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
EmitFrameOffset(result);
EmitFrameOffset(ceVal);
Emit((int32)(ceIdx1.mImmediate * arrayType->mElementType->GetStride()));
if (mPtrSize == 8)
Emit((int32)0);
}
}
else
@ -2079,10 +2172,12 @@ void CeBuilder::Build()
if (byteOffset != 0)
{
result = FrameAlloc(elementPtrType);
Emit((CeOp)(CeOp_AddConst_I32));
EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
EmitFrameOffset(result);
EmitFrameOffset(ceVal);
Emit((int32)byteOffset);
if (mPtrSize == 8)
Emit((int32)0);
}
else
{
@ -2100,10 +2195,12 @@ void CeBuilder::Build()
if (byteOffset != 0)
{
result = FrameAlloc(ptrType);
Emit((CeOp)(CeOp_AddConst_I32));
EmitSizedOp(CeOp_AddConst_I8, mPtrSize);
EmitFrameOffset(result);
EmitFrameOffset(ceVal);
Emit((int32)byteOffset);
if (mPtrSize == 8)
Emit((int32)0);
}
}
else
@ -2353,6 +2450,9 @@ void CeBuilder::Build()
{
switch (intrin->mKind)
{
case BfIRIntrinsic_Abs:
EmitUnaryOp(CeOp_Abs_I8, CeOp_Abs_F32, GetOperand(castedInst->mArgs[0].mValue), result);
break;
case BfIRIntrinsic_Cast:
{
result = GetOperand(castedInst->mArgs[0].mValue);
@ -2371,9 +2471,24 @@ void CeBuilder::Build()
EmitFrameOffset(ceSize);
}
break;
case BfIRIntrinsic_AtomicFence:
// Nothing to do
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:
Emit(CeOp_Error);
Emit((int32)CeErrorKind_Intrinsic);
@ -2384,6 +2499,81 @@ void CeBuilder::Build()
{
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")
{
result = FrameAlloc(beFuncType->mReturnType);
@ -2441,6 +2631,8 @@ void CeBuilder::Build()
{
CeOperand thisOperand;
int stackAdjust = 0;
for (int argIdx = (int)castedInst->mArgs.size() - 1; argIdx >= 0; argIdx--)
{
auto& arg = castedInst->mArgs[argIdx];
@ -2448,15 +2640,13 @@ void CeBuilder::Build()
if (argIdx == 0)
thisOperand = ceArg;
EmitSizedOp(CeOp_Push_8, ceArg, NULL, true);
stackAdjust += ceArg.mType->mSize;
}
int stackAdjust = 0;
if (beFuncType->mReturnType->mSize > 0)
{
Emit(CeOp_AdjustSPConst);
Emit((int32)-beFuncType->mReturnType->mSize);
stackAdjust += beFuncType->mReturnType->mSize;
Emit((int32)-beFuncType->mReturnType->mSize);
}
if (!ceFunc)
@ -2552,6 +2742,13 @@ void CeBuilder::Build()
EmitFrameOffset(mcStackVal);
}
break;
case BeComptimeError::TypeId:
{
auto castedInst = (BeComptimeError*)inst;
Emit(CeOp_Error);
Emit(castedInst->mError);
}
break;
case BeComptimeGetType::TypeId:
{
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());
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);
}
else
else if (returnType->IsValuelessType())
{
returnValue = BfTypedValue(module->mBfIRBuilder->GetFakeVal(), returnType);
}
@ -4039,6 +4236,20 @@ BfTypedValue CeContext::Call(BfAstNode* targetSrc, BfModule* module, BfMethodIns
auto rhs = CE_GETINST(T); \
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) \
{ \
auto& result = CE_GETFRAME(T); \
@ -4176,8 +4387,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
CE_CHECKALLOC(size);
uint8* ptr = CeMalloc(size);
CeSetAddrVal(stackPtr + 0, ptr - memStart, ptrSize);
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Free)
{
@ -4185,8 +4394,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
bool success = CeFree(freeAddr);
if (!success)
_Fail("Invalid heap address");
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_FatalError)
{
@ -4228,6 +4435,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
return false;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_DynCheckFailed)
{
_Fail("Dynamic cast check failed");
return false;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite)
{
int32 ptrVal = *(int32*)((uint8*)stackPtr + 0);
@ -4237,15 +4449,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
String str;
str.Insert(0, strPtr, size);
OutputDebugStr(str);
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_DebugWrite_Int)
{
int32 intVal = *(int32*)((uint8*)stackPtr + 0);
OutputDebugStrF("Debug Val: %d\n", intVal);
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectType)
{
@ -4256,8 +4464,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
auto reflectType = GetReflectType(typeId);
_FixVariables();
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeById)
{
@ -4265,8 +4471,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
auto reflectType = GetReflectType(typeId);
_FixVariables();
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectTypeByName)
{
@ -4280,8 +4484,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
auto reflectType = GetReflectType(typeName);
_FixVariables();
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_GetReflectSpecializedType)
{
@ -4291,8 +4493,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
auto reflectType = GetReflectSpecializedType(typeAddr, typeSpan);
_FixVariables();
CeSetAddrVal(stackPtr + 0, reflectType, ptrSize);
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Type_GetCustomAttribute)
{
@ -4310,8 +4510,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
}
*(addr_ce*)(stackPtr + 0) = success;
handled = true;
return true;
}
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();
handled = true;
return true;
}
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];
handled = true;
return true;
}
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);
_FixVariables();
handled = true;
return true;
}
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);
_FixVariables();
handled = true;
return true;
}
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 + 4) = methodInstance->GetParamCount();
*(int16*)(stackPtr + 4+4) = methodInstance->GetMethodFlags();
handled = true;
return true;
*(int16*)(stackPtr + 4+4) = methodInstance->GetMethodFlags();
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetParamInfo)
{
@ -4422,9 +4610,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_FixVariables();
*(int32*)(stackPtr + 0) = methodInstance->GetParamType(paramIdx)->mTypeId;
*(int16*)(stackPtr + 4) = 0; // Flags
CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
handled = true;
return true;
CeSetAddrVal(stackPtr + 4+2, stringAddr, ptrSize);
}
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitTypeBody)
{
@ -4440,9 +4626,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid StringView");
return false;
}
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodEntry)
{
@ -4460,9 +4643,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid StringView");
return false;
}
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodExit)
{
@ -4479,9 +4659,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
_Fail("Invalid StringView");
return false;
}
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMixin)
{
@ -4494,9 +4671,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
}
mCurModule->CEMixin(mCurTargetSrc, emitStr);
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Sleep)
{
@ -4515,50 +4689,42 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
BfpThread_Sleep(sleepMS);
break;
}
handled = true;
return true;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSystem_GetTimeStamp)
{
int64& result = *(int64*)((uint8*)stackPtr + 0);
result = BfpSystem_GetTimeStamp();
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToLower)
{
int32& result = *(int32*)((uint8*)stackPtr + 0);
int32 val = *(int32*)((uint8*)stackPtr + 4);
result = utf8proc_tolower(val);
handled = true;
return true;
result = utf8proc_tolower(val);
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_ToUpper)
{
int32& result = *(int32*)((uint8*)stackPtr + 0);
int32 val = *(int32*)((uint8*)stackPtr + 4);
result = utf8proc_toupper(val);
handled = true;
return true;
result = utf8proc_toupper(val);
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLower)
{
int32& result = *(int32*)((uint8*)stackPtr + 0);
int32 val = *(int32*)((uint8*)stackPtr + 1);
result = utf8proc_category(val) == UTF8PROC_CATEGORY_LL;
handled = true;
return true;
result = utf8proc_category(val) == UTF8PROC_CATEGORY_LL;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsUpper)
{
int32& result = *(int32*)((uint8*)stackPtr + 0);
int32 val = *(int32*)((uint8*)stackPtr + 1);
result = utf8proc_category(val) == UTF8PROC_CATEGORY_LU;
handled = true;
return true;
result = utf8proc_category(val) == UTF8PROC_CATEGORY_LU;
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsWhiteSpace_EX)
{
int32& result = *(int32*)((uint8*)stackPtr + 0);
int32 val = *(int32*)((uint8*)stackPtr + 1);
auto cat = utf8proc_category(val);
result = (cat == UTF8PROC_CATEGORY_ZS) || (cat == UTF8PROC_CATEGORY_ZL) || (cat == UTF8PROC_CATEGORY_ZP);
handled = true;
return true;
result = (cat == UTF8PROC_CATEGORY_ZS) || (cat == UTF8PROC_CATEGORY_ZL) || (cat == UTF8PROC_CATEGORY_ZP);
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetterOrDigit)
{
@ -4579,9 +4745,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
break;
default:
result = false;
}
handled = true;
return true;
}
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsLetter)
{
@ -4599,9 +4763,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
break;
default:
result = false;
}
handled = true;
return true;
}
}
else if (checkFunction->mFunctionKind == CeFunctionKind_Char32_IsNumber)
{
@ -4617,13 +4779,69 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
break;
default:
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()));
return false;
char* strPtr = (char*)(memStart + strAddr);
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:
_Fail("Intrinsic not allowed");
break;
case CeErrorKind_ObjectDynCheckFailed:
_Fail("Dynamic cast check failed");
break;
default:
_Fail("Operation not allowed");
break;
@ -4838,6 +5059,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
break;
case CeOp_FrameAddr_64:
{
//if (instPtr - ceFunction->mCode.mVals == 0x9c1)
auto& result = CE_GETFRAME(int64);
auto addr = &CE_GETFRAME(uint8);
result = addr - memStart;
@ -5041,7 +5263,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
case CeOp_AdjustSPConst:
{
int32 adjust = CE_GETINST(int32);
stackPtr += adjust;
stackPtr += adjust;
}
break;
case CeOp_GetSP:
@ -5182,11 +5404,6 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
BF_ASSERT(memStart == mMemory.mVals);
auto callFunction = callEntry.mFunction;
if (callFunction->mMethodInstance->mMethodDef->mIsLocalMethod)
{
NOP;
}
if (needsFunctionIds)
*(int32*)(framePtr + resultFrameIdx) = callFunction->mId;
else
@ -5427,6 +5644,41 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
case CeOp_Conv_F64_F32:
CE_CAST(double, float);
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:
CEOP_BIN_CONST(+, int8);
break;
@ -5646,6 +5898,116 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
case CeOp_Shr_U64:
CEOP_BIN2(>> , uint64, uint8);
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:
CEOP_CMP(!= , int8);
break;
@ -6253,10 +6615,9 @@ CeErrorKind CeMachine::WriteConstant(CeConstStructData& data, BeConstant* constV
return CeErrorKind_None;
}
void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder)
void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
{
AutoTimer autoTimer(mRevisionExecuteTime);
SetAndRestoreValue<CeFunction*> prevCEFunction(mPreparingFunction, ceFunction);
ceFunction->mFunctionKind = CeFunctionKind_Normal;
if (ceFunction->mMethodInstance != NULL)
{
@ -6360,6 +6721,13 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
ceFunction->mFunctionKind = CeFunctionKind_Malloc;
else if (methodDef->mName == "Dbg_RawFree")
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))
{
@ -6380,11 +6748,72 @@ void CeMachine::PrepareFunction(CeFunction* ceFunction, CeBuilder* parentBuilder
else if (methodDef->mName == "get__IsNumer")
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;
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);
ceFunction->mInitialized = true;

View file

@ -32,6 +32,10 @@ class CeFunction;
CeOp_##OPNAME##_64, \
CeOp_##OPNAME##_X
#define CEOP_SIZED_FLOAT(OPNAME) \
CeOp_##OPNAME##_F32, \
CeOp_##OPNAME##_F64
#define CEOP_SIZED_NUMERIC(OPNAME) \
CeOp_##OPNAME##_I8, \
CeOp_##OPNAME##_I16, \
@ -58,7 +62,8 @@ enum CeErrorKind
CeErrorKind_Error,
CeErrorKind_GlobalVariable,
CeErrorKind_FunctionPointer,
CeErrorKind_Intrinsic
CeErrorKind_Intrinsic,
CeErrorKind_ObjectDynCheckFailed
};
enum CeOp : int16
@ -146,6 +151,7 @@ enum CeOp : int16
CeOp_Conv_F64_I64,
CeOp_Conv_F64_F32,
CEOP_SIZED_NUMERIC_PLUSF(Abs),
CEOP_SIZED_NUMERIC_PLUSF(AddConst),
CEOP_SIZED_NUMERIC_PLUSF(Add),
CEOP_SIZED_NUMERIC_PLUSF(Sub),
@ -160,7 +166,26 @@ enum CeOp : int16
CEOP_SIZED_NUMERIC(Shl),
CEOP_SIZED_NUMERIC(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_NE),
CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT),
@ -241,11 +266,13 @@ public:
enum CeFunctionKind
{
CeFunctionKind_NotSet,
CeFunctionKind_Normal,
CeFunctionKind_Extern,
CeFunctionKind_OOB,
CeFunctionKind_Malloc,
CeFunctionKind_Free,
CeFunctionKind_DynCheckFailed,
CeFunctionKind_FatalError,
CeFunctionKind_DebugWrite,
CeFunctionKind_DebugWrite_Int,
@ -260,12 +287,15 @@ enum CeFunctionKind
CeFunctionKind_Method_GetName,
CeFunctionKind_Method_GetInfo,
CeFunctionKind_Method_GetParamInfo,
CeFunctionKind_EmitTypeBody,
CeFunctionKind_EmitMethodEntry,
CeFunctionKind_EmitMethodExit,
CeFunctionKind_EmitMixin,
CeFunctionKind_BfpSystem_GetTimeStamp,
CeFunctionKind_Sleep,
CeFunctionKind_Char32_ToLower,
CeFunctionKind_Char32_ToUpper,
CeFunctionKind_Char32_IsLower,
@ -274,6 +304,30 @@ enum CeFunctionKind
CeFunctionKind_Char32_IsLetterOrDigit,
CeFunctionKind_Char32_IsLetter,
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
@ -369,7 +423,7 @@ public:
{
mCeFunctionInfo = NULL;
mCeInnerFunctionInfo = NULL;
mFunctionKind = CeFunctionKind_Normal;
mFunctionKind = CeFunctionKind_NotSet;
mGenerating = false;
mInitialized = false;
mMethodInstance = NULL;
@ -738,6 +792,7 @@ public:
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal, CeContext* ceContext);
void CheckFunctionKind(CeFunction* ceFunction);
void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);
void MapFunctionId(CeFunction* ceFunction);