2020-12-13 08:04:42 -08:00
# include "CeMachine.h"
# include "BfModule.h"
# include "BfCompiler.h"
# include "BfIRBuilder.h"
2021-01-11 09:41:43 -08:00
# include "BfParser.h"
# include "BfReducer.h"
# include "BfExprEvaluator.h"
2021-12-20 12:03:09 -05:00
# include "BfResolvePass.h"
2020-12-14 10:20:44 -08:00
# include "../Backend/BeIRCodeGen.h"
2021-12-20 09:39:39 -05:00
# include "BeefySysLib/platform/PlatformHelper.h"
2020-12-19 14:19:33 -08:00
extern " C "
{
# include "BeefySysLib/third_party/utf8proc/utf8proc.h"
}
2020-12-13 08:04:42 -08:00
2020-12-17 04:51:05 -08:00
# define CE_ENABLE_HEAP
2020-12-13 08:04:42 -08:00
2020-12-17 04:51:05 -08:00
USING_NS_BF ;
2020-12-13 08:04:42 -08:00
2020-12-22 04:50:37 -08:00
enum CeOpInfoFlag
{
CeOpInfoFlag_None ,
CeOpInfoFlag_SizeX ,
} ;
2020-12-13 08:04:42 -08:00
struct CeOpInfo
{
const char * mName ;
CeOperandInfoKind mResultKind ;
CeOperandInfoKind mOperandA ;
CeOperandInfoKind mOperandB ;
CeOperandInfoKind mOperandC ;
2020-12-22 04:50:37 -08:00
CeOpInfoFlag mFlags ;
2020-12-13 08:04:42 -08:00
} ;
2020-12-14 03:50:28 -08:00
# define CEOPINFO_SIZED_1(OPNAME, OPINFOA) \
2020-12-14 10:20:44 -08:00
{ OPNAME " _8 " , OPINFOA } , \
{ OPNAME " _16 " , OPINFOA } , \
{ OPNAME " _32 " , OPINFOA } , \
{ OPNAME " _64 " , OPINFOA } , \
2020-12-22 04:50:37 -08:00
{ OPNAME " _X " , OPINFOA , CEOI_None , CEOI_None , CEOI_None , CeOpInfoFlag_SizeX }
2020-12-14 03:50:28 -08:00
2020-12-13 08:04:42 -08:00
# define CEOPINFO_SIZED_2(OPNAME, OPINFOA, OPINFOB) \
2020-12-14 10:20:44 -08:00
{ OPNAME " _8 " , OPINFOA , OPINFOB } , \
{ OPNAME " _16 " , OPINFOA , OPINFOB } , \
{ OPNAME " _32 " , OPINFOA , OPINFOB } , \
{ OPNAME " _64 " , OPINFOA , OPINFOB } , \
2020-12-22 04:50:37 -08:00
{ OPNAME " _X " , OPINFOA , OPINFOB , CEOI_None , CEOI_None , CeOpInfoFlag_SizeX }
2020-12-13 08:04:42 -08:00
# define CEOPINFO_SIZED_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
2020-12-14 10:20:44 -08:00
{ OPNAME " _8 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _16 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _32 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _64 " , OPINFOA , OPINFOB , OPINFOC } , \
2020-12-22 04:50:37 -08:00
{ OPNAME " _X " , OPINFOA , OPINFOB , OPINFOC , CEOI_None , CeOpInfoFlag_SizeX }
2020-12-13 08:04:42 -08:00
2020-12-17 04:51:05 -08:00
# define CEOPINFO_SIZED_NUMERIC_2(OPNAME, OPINFOA, OPINFOB) \
{ OPNAME " _I8 " , OPINFOA , OPINFOB } , \
{ OPNAME " _I16 " , OPINFOA , OPINFOB } , \
{ OPNAME " _I32 " , OPINFOA , OPINFOB } , \
{ OPNAME " _I64 " , OPINFOA , OPINFOB }
2020-12-13 08:04:42 -08:00
# define CEOPINFO_SIZED_NUMERIC_PLUSF_2(OPNAME, OPINFOA, OPINFOB) \
2020-12-14 10:20:44 -08:00
{ OPNAME " _I8 " , OPINFOA , OPINFOB } , \
{ OPNAME " _I16 " , OPINFOA , OPINFOB } , \
{ OPNAME " _I32 " , OPINFOA , OPINFOB } , \
{ OPNAME " _I64 " , OPINFOA , OPINFOB } , \
{ OPNAME " _F32 " , OPINFOA , OPINFOB } , \
{ OPNAME " _F64 " , OPINFOA , OPINFOB }
2020-12-14 03:50:28 -08:00
# define CEOPINFO_SIZED_NUMERIC_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
2020-12-14 10:20:44 -08:00
{ OPNAME " _I8 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _I16 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _I32 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _I64 " , OPINFOA , OPINFOB , OPINFOC }
2020-12-17 04:51:05 -08:00
# define CEOPINFO_SIZED_UNUMERIC_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
{ OPNAME " _U8 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _U16 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _U32 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _U64 " , OPINFOA , OPINFOB , OPINFOC }
2020-12-13 08:04:42 -08:00
# define CEOPINFO_SIZED_NUMERIC_PLUSF_3(OPNAME, OPINFOA, OPINFOB, OPINFOC) \
2020-12-14 10:20:44 -08:00
{ OPNAME " _I8 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _I16 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _I32 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _I64 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _F32 " , OPINFOA , OPINFOB , OPINFOC } , \
{ OPNAME " _F64 " , OPINFOA , OPINFOB , OPINFOC }
2021-01-26 06:33:23 -08:00
# 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 }
2020-12-13 08:04:42 -08:00
static CeOpInfo gOpInfo [ ] =
{
{ " InvalidOp " } ,
{ " Ret " } ,
2020-12-30 13:24:13 -08:00
{ " SetRet " , CEOI_None , CEOI_IMM32 } ,
2020-12-13 08:04:42 -08:00
{ " Jmp " , CEOI_None , CEOI_JMPREL } ,
{ " JmpIf " , CEOI_None , CEOI_JMPREL , CEOI_FrameRef } ,
{ " JmpIfNot " , CEOI_None , CEOI_JMPREL , CEOI_FrameRef } ,
2020-12-17 04:51:05 -08:00
{ " Error " , CEOI_None , CEOI_IMM32 } ,
{ " DynamicCastCheck " , CEOI_FrameRef , CEOI_FrameRef , CEOI_IMM32 } ,
2020-12-19 14:19:33 -08:00
{ " GetReflectType " , CEOI_FrameRef , CEOI_IMM32 } ,
2020-12-17 04:51:05 -08:00
{ " GetString " , CEOI_FrameRef , CEOI_IMM32 } ,
{ " Malloc " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " Free " , CEOI_None , CEOI_FrameRef } ,
{ " MemSet " , CEOI_None , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef } ,
{ " MemSet_Const " , CEOI_None , CEOI_FrameRef , CEOI_IMM8 , CEOI_IMM32 } ,
{ " MemCpy " , CEOI_None , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef } ,
2020-12-14 10:20:44 -08:00
{ " FrameAddr_32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " FrameAddr_64 " , CEOI_FrameRef , CEOI_FrameRef } ,
2020-12-19 14:19:33 -08:00
{ " FrameAddrOfs_32 " , CEOI_FrameRef , CEOI_FrameRef , CEOI_IMM32 } ,
2020-12-22 04:50:37 -08:00
{ " ConstData " , CEOI_FrameRef , CEOI_IMM32 } ,
{ " ConstDataRef " , CEOI_FrameRef , CEOI_IMM32 } ,
2020-12-19 14:19:33 -08:00
{ " Zero " , CEOI_None , CEOI_FrameRef , CEOI_IMM32 } ,
2020-12-13 08:04:42 -08:00
{ " Const_8 " , CEOI_FrameRef , CEOI_IMM8 } ,
{ " Const_16 " , CEOI_FrameRef , CEOI_IMM16 } ,
{ " Const_32 " , CEOI_FrameRef , CEOI_IMM32 } ,
{ " Const_64 " , CEOI_FrameRef , CEOI_IMM64 } ,
{ " Const_X " , CEOI_FrameRef , CEOI_IMM_VAR } ,
CEOPINFO_SIZED_2 ( " Load " , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_3 ( " Store " , CEOI_None , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_3 ( " Move " , CEOI_None , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_2 ( " Push " , CEOI_None , CEOI_FrameRef ) ,
2020-12-14 03:50:28 -08:00
CEOPINFO_SIZED_1 ( " Pop " , CEOI_FrameRef ) ,
2020-12-13 08:04:42 -08:00
{ " AdjustSP " , CEOI_None , CEOI_FrameRef } ,
2020-12-17 04:51:05 -08:00
{ " AdjustSPNeg " , CEOI_None , CEOI_FrameRef } ,
{ " AdjustSPConst " , CEOI_None , CEOI_IMM32 } ,
{ " CeOp_GetSP " , CEOI_FrameRef } ,
{ " CeOp_SetSP " , CEOI_None , CEOI_FrameRef } ,
2020-12-19 14:19:33 -08:00
{ " GetStaticField " , CEOI_FrameRef , CEOI_IMM32 } ,
{ " GetMethod " , CEOI_FrameRef , CEOI_IMM32 } ,
{ " GetMethod_Inner " , CEOI_FrameRef , CEOI_IMM32 } ,
{ " GetMethod_Virt " , CEOI_FrameRef , CEOI_FrameRef , CEOI_IMM32 } ,
{ " GetMethod_IFace " , CEOI_FrameRef , CEOI_FrameRef , CEOI_IMM32 , CEOI_IMM32 } ,
{ " Call " , CEOI_None , CEOI_FrameRef } ,
2020-12-17 04:51:05 -08:00
{ " CeOp_Conv_I8_I16 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I8_I32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I8_I64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I8_F32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I8_F64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I16_I32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I16_I64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I16_F32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I16_F64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I32_I64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I32_F32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I32_F64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I64_F32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_I64_F64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U8_U16 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U8_U32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U8_U64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U8_F32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U8_F64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U16_U32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U16_U64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U16_F32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U16_F64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U32_U64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U32_F32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U32_F64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U64_F32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_U64_F64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_F32_I8 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_F32_I16 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_F32_I32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_F32_I64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_F32_F64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_F64_I8 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_F64_I16 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_F64_I32 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_F64_I64 " , CEOI_FrameRef , CEOI_FrameRef } ,
{ " CeOp_Conv_F64_F32 " , CEOI_FrameRef , CEOI_FrameRef } ,
2021-01-26 06:33:23 -08:00
CEOPINFO_SIZED_NUMERIC_PLUSF_2 ( " Abs " , CEOI_FrameRef , CEOI_FrameRef ) ,
2020-12-14 10:20:44 -08:00
{ " 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 } ,
2021-01-26 06:33:23 -08:00
{ " AddConst_F64 " , CEOI_FrameRef , CEOI_FrameRef , CEOI_IMMF64 } ,
2020-12-13 08:04:42 -08:00
CEOPINFO_SIZED_NUMERIC_PLUSF_3 ( " Add " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
2020-12-14 03:50:28 -08:00
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 ( " SDiv " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_NUMERIC_3 ( " UDiv " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_NUMERIC_PLUSF_3 ( " SMod " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_NUMERIC_3 ( " UMod " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
2020-12-17 04:51:05 -08:00
CEOPINFO_SIZED_NUMERIC_3 ( " And " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_NUMERIC_3 ( " Or " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_NUMERIC_3 ( " Xor " , 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_UNUMERIC_3 ( " Shr " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
2021-01-26 06:33:23 -08:00
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 ) ,
2020-12-14 03:50:28 -08:00
2020-12-13 08:04:42 -08:00
CEOPINFO_SIZED_NUMERIC_PLUSF_3 ( " Cmp_EQ " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
2020-12-17 04:51:05 -08:00
CEOPINFO_SIZED_NUMERIC_PLUSF_3 ( " Cmp_NE " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
2020-12-13 08:04:42 -08:00
CEOPINFO_SIZED_NUMERIC_PLUSF_3 ( " Cmp_SLT " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
2020-12-14 03:50:28 -08:00
CEOPINFO_SIZED_NUMERIC_3 ( " Cmp_ULT " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_NUMERIC_PLUSF_3 ( " Cmp_SLE " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_NUMERIC_3 ( " Cmp_ULE " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
2020-12-17 04:51:05 -08:00
CEOPINFO_SIZED_NUMERIC_PLUSF_3 ( " Cmp_SGT " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_NUMERIC_3 ( " Cmp_UGT " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_NUMERIC_PLUSF_3 ( " Cmp_SGE " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
CEOPINFO_SIZED_NUMERIC_3 ( " Cmp_UGE " , CEOI_FrameRef , CEOI_FrameRef , CEOI_FrameRef ) ,
2020-12-13 08:04:42 -08:00
CEOPINFO_SIZED_NUMERIC_PLUSF_2 ( " Neg " , CEOI_FrameRef , CEOI_FrameRef ) ,
2020-12-17 04:51:05 -08:00
{ " Not_I1 " , CEOI_FrameRef , CEOI_FrameRef } ,
CEOPINFO_SIZED_NUMERIC_2 ( " Not " , CEOI_FrameRef , CEOI_FrameRef ) ,
2020-12-13 08:04:42 -08:00
} ;
static_assert ( BF_ARRAY_COUNT ( gOpInfo ) = = ( int ) CeOp_COUNT , " gOpName incorrect size " ) ;
2020-12-17 04:51:05 -08:00
//////////////////////////////////////////////////////////////////////////
2021-01-26 06:33:23 -08:00
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 ;
}
//////////////////////////////////////////////////////////////////////////
2021-12-20 09:39:39 -05:00
CeInternalData : : ~ CeInternalData ( )
{
switch ( mKind )
{
case Kind_File :
BfpFile_Release ( mFile ) ;
break ;
case Kind_FindFileData :
BfpFindFileData_Release ( mFindFileData ) ;
break ;
case Kind_Spawn :
BfpSpawn_Release ( mSpawn ) ;
break ;
}
}
//////////////////////////////////////////////////////////////////////////
2020-12-17 04:51:05 -08:00
CeFunction : : ~ CeFunction ( )
{
2020-12-23 11:27:46 -08:00
BF_ASSERT ( mId = = - 1 ) ;
2020-12-19 14:19:33 -08:00
for ( auto innerFunc : mInnerFunctions )
2020-12-31 11:47:34 -08:00
delete innerFunc ;
delete mCeInnerFunctionInfo ;
2021-02-01 13:55:29 -08:00
BfLogSys ( mCeMachine - > mCompiler - > mSystem , " CeFunction::~CeFunction %p \n " , this ) ;
2020-12-17 04:51:05 -08:00
}
2020-12-13 08:04:42 -08:00
2021-01-11 09:41:43 -08:00
void CeFunction : : Print ( )
{
CeDumpContext dumpCtx ;
dumpCtx . mCeFunction = this ;
dumpCtx . mStart = & mCode [ 0 ] ;
dumpCtx . mPtr = dumpCtx . mStart ;
dumpCtx . mEnd = dumpCtx . mPtr + mCode . mSize ;
dumpCtx . Dump ( ) ;
String methodName ;
if ( mMethodInstance ! = NULL )
methodName = mMethodInstance - > GetOwner ( ) - > mModule - > MethodToString ( mMethodInstance ) ;
OutputDebugStrF ( " Code for %s: \n %s \n " , methodName . c_str ( ) , dumpCtx . mStr . c_str ( ) ) ;
}
2020-12-13 08:04:42 -08:00
//////////////////////////////////////////////////////////////////////////
2020-12-23 08:53:38 -08:00
CeFunctionInfo : : ~ CeFunctionInfo ( )
{
delete mCeFunction ;
}
//////////////////////////////////////////////////////////////////////////
2020-12-13 08:04:42 -08:00
# define CE_GET(T) *((T*)(mPtr += sizeof(T)) - 1)
void CeDumpContext : : DumpOperandInfo ( CeOperandInfoKind operandInfoKind )
{
switch ( operandInfoKind )
{
case CEOI_FrameRef :
{
int32 addr = CE_GET ( int32 ) ;
char str [ 64 ] ;
if ( addr > = 0 )
sprintf ( str , " FR+0x%X " , addr ) ;
else
sprintf ( str , " FR-0x%X " , - addr ) ;
mStr + = str ;
}
break ;
case CEOI_IMM8 :
{
int32 val = CE_GET ( int8 ) ;
char str [ 64 ] ;
sprintf ( str , " %d " , val ) ;
mStr + = str ;
}
break ;
case CEOI_IMM16 :
{
int32 val = CE_GET ( int16 ) ;
char str [ 64 ] ;
sprintf ( str , " %d " , val ) ;
mStr + = str ;
}
break ;
case CEOI_IMM32 :
{
int32 val = CE_GET ( int32 ) ;
char str [ 64 ] ;
sprintf ( str , " %d " , val ) ;
mStr + = str ;
}
break ;
case CEOI_IMM64 :
{
int64 val = CE_GET ( int64 ) ;
char str [ 64 ] ;
2021-01-13 09:24:15 -08:00
sprintf ( str , " %lld " , ( long long ) val ) ;
2020-12-13 08:04:42 -08:00
mStr + = str ;
}
break ;
case CEOI_IMM_VAR :
{
mStr + = ' [ ' ;
int32 size = CE_GET ( int32 ) ;
for ( int i = 0 ; i < size ; i + + )
{
if ( i ! = 0 )
mStr + = " , " ;
uint8 val = CE_GET ( uint8 ) ;
char str [ 64 ] ;
sprintf ( str , " %X " , val ) ;
mStr + = str ;
}
mStr + = ' ] ' ;
}
break ;
case CEOI_JMPREL :
{
int32 val = CE_GET ( int32 ) ;
char str [ 64 ] ;
sprintf ( str , " JMP:%04X " , ( int32 ) ( val + ( mPtr - mStart ) ) ) ;
mStr + = str ;
}
break ;
}
}
void CeDumpContext : : Dump ( )
{
if ( ! mCeFunction - > mGenError . IsEmpty ( ) )
mStr + = StrFormat ( " Gen Error: %s \n " , mCeFunction - > mGenError . c_str ( ) ) ;
mStr + = StrFormat ( " Frame Size: %d \n " , mCeFunction - > mFrameSize ) ;
uint8 * start = mPtr ;
int curEmitIdx = 0 ;
CeEmitEntry * curEmitEntry = NULL ;
while ( mPtr < mEnd )
{
int ofs = mPtr - start ;
2020-12-17 04:51:05 -08:00
while ( ( curEmitIdx < mCeFunction - > mEmitTable . mSize - 1 ) & & ( ofs > = mCeFunction - > mEmitTable [ curEmitIdx + 1 ] . mCodePos ) )
2020-12-13 08:04:42 -08:00
curEmitIdx + + ;
if ( curEmitIdx < mCeFunction - > mEmitTable . mSize )
curEmitEntry = & mCeFunction - > mEmitTable [ curEmitIdx ] ;
CeOp op = CE_GET ( CeOp ) ;
CeOpInfo & opInfo = gOpInfo [ op ] ;
mStr + = StrFormat ( " %04X: " , ofs ) ;
2020-12-22 04:50:37 -08:00
int32 sizeX = - 1 ;
if ( ( opInfo . mFlags & CeOpInfoFlag_SizeX ) ! = 0 )
{
sizeX = CE_GET ( int ) ;
}
2020-12-13 08:04:42 -08:00
if ( opInfo . mResultKind ! = CEOI_None )
{
DumpOperandInfo ( opInfo . mResultKind ) ;
mStr + = " = " ;
}
mStr + = opInfo . mName ;
2020-12-22 04:50:37 -08:00
if ( sizeX ! = - 1 )
{
mStr + = StrFormat ( " :%d " , sizeX ) ;
}
2020-12-13 08:04:42 -08:00
if ( opInfo . mOperandA ! = CEOI_None )
{
mStr + = " " ;
DumpOperandInfo ( opInfo . mOperandA ) ;
}
if ( opInfo . mOperandB ! = CEOI_None )
{
mStr + = " , " ;
DumpOperandInfo ( opInfo . mOperandB ) ;
}
if ( opInfo . mOperandC ! = CEOI_None )
{
mStr + = " , " ;
DumpOperandInfo ( opInfo . mOperandC ) ;
}
if ( ( curEmitEntry ! = NULL ) & & ( curEmitEntry - > mFile ! = - 1 ) )
{
mStr + = StrFormat ( " @%d[%s:%d] " , curEmitIdx , GetFileName ( mCeFunction - > mFiles [ curEmitEntry - > mFile ] ) . c_str ( ) ,
curEmitEntry - > mLine + 1 , curEmitEntry - > mColumn + 1 ) ;
}
mStr + = " \n " ;
}
}
//////////////////////////////////////////////////////////////////////////
void CeBuilder : : Fail ( const StringImpl & str )
{
if ( ! mCeFunction - > mGenError . IsEmpty ( ) )
return ;
String errStr = StrFormat ( " Failure during const code generation of %s: %s " , mBeFunction - > mName . c_str ( ) , str . c_str ( ) ) ;
if ( mCurDbgLoc ! = NULL )
2020-12-17 04:51:05 -08:00
{
String filePath ;
mCurDbgLoc - > GetDbgFile ( ) - > GetFilePath ( filePath ) ;
errStr + = StrFormat ( " at line %d:%d in %s " , mCurDbgLoc - > mLine + 1 , mCurDbgLoc - > mColumn + 1 , filePath . c_str ( ) ) ;
}
2020-12-13 08:04:42 -08:00
mCeFunction - > mGenError = errStr ;
}
void CeBuilder : : Emit ( uint8 val )
{
mCeFunction - > mCode . Add ( ( uint8 ) val ) ;
}
void CeBuilder : : Emit ( CeOp val )
{
* ( CeOp * ) mCeFunction - > mCode . GrowUninitialized ( sizeof ( CeOp ) ) = val ;
}
2020-12-17 04:51:05 -08:00
void CeBuilder : : EmitSizedOp ( CeOp val , int size )
{
2020-12-19 14:19:33 -08:00
CeSizeClass sizeClass = GetSizeClass ( size ) ;
Emit ( ( CeOp ) ( val + sizeClass ) ) ;
if ( sizeClass = = CeSizeClass_X )
Emit ( ( int32 ) size ) ;
2020-12-17 04:51:05 -08:00
}
2020-12-13 08:04:42 -08:00
void CeBuilder : : Emit ( int32 val )
{
* ( int32 * ) mCeFunction - > mCode . GrowUninitialized ( 4 ) = val ;
}
2020-12-14 10:20:44 -08:00
void CeBuilder : : Emit ( int64 val )
{
* ( int64 * ) mCeFunction - > mCode . GrowUninitialized ( 8 ) = val ;
}
2020-12-13 08:04:42 -08:00
void CeBuilder : : Emit ( bool val )
{
BF_FATAL ( " Invalid emit " ) ;
}
void CeBuilder : : Emit ( void * ptr , int size )
{
memcpy ( mCeFunction - > mCode . GrowUninitialized ( size ) , ptr , size ) ;
}
2020-12-19 14:19:33 -08:00
void CeBuilder : : EmitZeroes ( int size )
{
for ( int i = 0 ; i < size ; i + + )
Emit ( ( uint8 ) 0 ) ;
}
2020-12-13 08:04:42 -08:00
void CeBuilder : : EmitJump ( CeOp op , const CeOperand & block )
{
BF_ASSERT ( block . mKind = = CeOperandKind_Block ) ;
Emit ( op ) ;
CeJumpEntry jumpEntry ;
jumpEntry . mBlockIdx = block . mBlockIdx ;
jumpEntry . mEmitPos = GetCodePos ( ) ;
mJumpTable . Add ( jumpEntry ) ;
Emit ( ( int32 ) 0 ) ;
}
void CeBuilder : : EmitBinarySwitchSection ( BeSwitchInst * switchInst , int startIdx , int endIdx )
{
// This is an empirically determined binary switching limit
if ( endIdx - startIdx > = 18 )
{
// int gteLabel = mCurLabelIdx++;
//
// auto mcDefaultBlock = GetOperand(switchInst->mDefaultBlock);
//
// int midIdx = startIdx + (endIdx - startIdx) / 2;
// auto& switchCase = switchInst->mCases[midIdx];
// auto switchBlock = GetOperand(switchCase.mBlock);
// auto mcValue = GetOperand(switchInst->mValue);
// auto valueType = GetType(mcValue);
//
// AllocInst(BeMCInstKind_Cmp, mcValue, GetOperand(switchCase.mValue));
// AllocInst(BeMCInstKind_CondBr, BeMCOperand::FromLabel(gteLabel), BeMCOperand::FromCmpKind(BeCmpKind_SGE));
// switchBlock.mBlock->AddPred(mActiveBlock);
//
// CreateBinarySwitchSection(switchInst, startIdx, midIdx);
// AllocInst(BeMCInstKind_Br, mcDefaultBlock);
// CreateLabel(-1, gteLabel);
// CreateBinarySwitchSection(switchInst, midIdx, endIdx);
// return;
}
for ( int caseIdx = startIdx ; caseIdx < endIdx ; caseIdx + + )
{
auto & switchCase = switchInst - > mCases [ caseIdx ] ;
auto switchBlock = GetOperand ( switchCase . mBlock ) ;
auto mcValue = GetOperand ( switchInst - > mValue ) ;
CeOperand result ;
EmitBinaryOp ( CeOp_Cmp_EQ_I8 , CeOp_Cmp_EQ_F32 , mcValue , GetOperand ( switchCase . mValue ) , result ) ;
EmitJump ( CeOp_JmpIf , switchBlock ) ;
EmitFrameOffset ( result ) ;
}
}
int CeBuilder : : GetCodePos ( )
{
return ( int ) mCeFunction - > mCode . size ( ) ;
}
void CeBuilder : : EmitFrameOffset ( const CeOperand & val )
{
BF_ASSERT ( val . mKind = = CeOperandKind_FrameOfs ) ;
Emit ( ( int32 ) val . mFrameOfs ) ;
}
void CeBuilder : : FlushPhi ( CeBlock * ceBlock , int targetBlockIdx )
{
for ( int i = 0 ; i < ( int ) ceBlock - > mPhiOutgoing . size ( ) ; i + + )
{
auto & phiOutgoing = ceBlock - > mPhiOutgoing [ i ] ;
if ( phiOutgoing . mPhiBlockIdx = = targetBlockIdx )
{
auto targetPhi = GetOperand ( phiOutgoing . mPhiInst ) ;
auto mcVal = GetOperand ( phiOutgoing . mPhiValue ) ;
EmitSizedOp ( CeOp_Move_8 , mcVal , NULL , true ) ;
EmitFrameOffset ( targetPhi ) ;
ceBlock - > mPhiOutgoing . RemoveAt ( i ) ;
break ;
}
}
}
void CeBuilder : : EmitBinaryOp ( CeOp iOp , CeOp fOp , const CeOperand & lhs , const CeOperand & rhs , CeOperand & result )
{
CeOp op = iOp ;
2020-12-17 04:51:05 -08:00
if ( lhs . mType - > IsIntable ( ) )
2020-12-13 08:04:42 -08:00
{
if ( lhs . mType - > mSize = = 1 )
op = iOp ;
else if ( lhs . mType - > mSize = = 2 )
op = ( CeOp ) ( iOp + 1 ) ;
else if ( lhs . mType - > mSize = = 4 )
op = ( CeOp ) ( iOp + 2 ) ;
else if ( lhs . mType - > mSize = = 8 )
op = ( CeOp ) ( iOp + 3 ) ;
else
Fail ( " Invalid int operand size " ) ;
}
else if ( lhs . mType - > IsFloat ( ) )
{
2021-01-26 06:33:23 -08:00
BF_ASSERT ( fOp ! = CeOp_InvalidOp ) ;
2020-12-13 08:04:42 -08:00
if ( lhs . mType - > mSize = = 4 )
op = fOp ;
else if ( lhs . mType - > mSize = = 8 )
op = ( CeOp ) ( fOp + 1 ) ;
else
Fail ( " Invalid float operand size " ) ;
}
else
Fail ( " Invalid binary operand " ) ;
Emit ( op ) ;
2020-12-19 14:19:33 -08:00
if ( ! result )
result = FrameAlloc ( lhs . mType ) ;
2020-12-13 08:04:42 -08:00
EmitFrameOffset ( result ) ;
EmitFrameOffset ( lhs ) ;
EmitFrameOffset ( rhs ) ;
}
void CeBuilder : : EmitUnaryOp ( CeOp iOp , CeOp fOp , const CeOperand & val , CeOperand & result )
{
CeOp op = iOp ;
2020-12-17 04:51:05 -08:00
if ( val . mType - > IsIntable ( ) )
2020-12-13 08:04:42 -08:00
{
if ( val . mType - > mSize = = 1 )
op = iOp ;
else if ( val . mType - > mSize = = 2 )
op = ( CeOp ) ( iOp + 1 ) ;
else if ( val . mType - > mSize = = 4 )
op = ( CeOp ) ( iOp + 2 ) ;
else if ( val . mType - > mSize = = 8 )
op = ( CeOp ) ( iOp + 3 ) ;
else
Fail ( " Invalid int operand size " ) ;
}
else if ( val . mType - > IsFloat ( ) )
{
if ( val . mType - > mSize = = 4 )
op = fOp ;
else if ( val . mType - > mSize = = 8 )
op = ( CeOp ) ( fOp + 1 ) ;
else
Fail ( " Invalid float operand size " ) ;
}
else
Fail ( " Invalid unary operand " ) ;
Emit ( op ) ;
result = FrameAlloc ( val . mType ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( val ) ;
}
void CeBuilder : : EmitSizedOp ( CeOp baseOp , const CeOperand & operand , CeOperand * outResult , bool allowNonStdSize )
{
bool isStdSize = true ;
2020-12-23 11:27:46 -08:00
CeOp op = CeOp_InvalidOp ;
2020-12-13 08:04:42 -08:00
if ( operand . mType - > mSize = = 1 )
op = baseOp ;
else if ( operand . mType - > mSize = = 2 )
op = ( CeOp ) ( baseOp + 1 ) ;
else if ( operand . mType - > mSize = = 4 )
op = ( CeOp ) ( baseOp + 2 ) ;
else if ( operand . mType - > mSize = = 8 )
op = ( CeOp ) ( baseOp + 3 ) ;
else
{
isStdSize = false ;
op = ( CeOp ) ( baseOp + 4 ) ;
}
Emit ( op ) ;
if ( ! isStdSize )
{
if ( ! allowNonStdSize )
Fail ( " Invalid operand size " ) ;
Emit ( ( int32 ) operand . mType - > mSize ) ;
}
2020-12-14 03:50:28 -08:00
if ( outResult ! = NULL )
{
* outResult = FrameAlloc ( operand . mType ) ;
EmitFrameOffset ( * outResult ) ;
}
2020-12-13 08:04:42 -08:00
EmitFrameOffset ( operand ) ;
}
CeOperand CeBuilder : : FrameAlloc ( BeType * type )
{
mFrameSize + = type - > mSize ;
CeOperand result ;
result . mKind = CeOperandKind_FrameOfs ;
result . mFrameOfs = - mFrameSize ;
result . mType = type ;
return result ;
}
2020-12-17 04:51:05 -08:00
CeOperand CeBuilder : : EmitConst ( int64 val , int size )
{
BeType * type = mIntPtrType ;
switch ( size )
{
case 1 :
type = mCeMachine - > GetBeContext ( ) - > GetPrimitiveType ( BeTypeCode_Int8 ) ;
break ;
case 2 :
type = mCeMachine - > GetBeContext ( ) - > GetPrimitiveType ( BeTypeCode_Int16 ) ;
break ;
case 4 :
type = mCeMachine - > GetBeContext ( ) - > GetPrimitiveType ( BeTypeCode_Int32 ) ;
break ;
case 8 :
type = mCeMachine - > GetBeContext ( ) - > GetPrimitiveType ( BeTypeCode_Int64 ) ;
break ;
default :
Fail ( " Bad const size " ) ;
}
auto result = FrameAlloc ( type ) ;
EmitSizedOp ( CeOp_Const_8 , type - > mSize ) ;
EmitFrameOffset ( result ) ;
Emit ( & val , size ) ;
return result ;
}
2020-12-14 03:50:28 -08:00
CeOperand CeBuilder : : GetOperand ( BeValue * value , bool allowAlloca , bool allowImmediate )
2020-12-13 08:04:42 -08:00
{
if ( value = = NULL )
return CeOperand ( ) ;
2020-12-17 04:51:05 -08:00
BeType * errorType = mIntPtrType ;
CeErrorKind errorKind = CeErrorKind_None ;
2020-12-13 08:04:42 -08:00
switch ( value - > GetTypeId ( ) )
{
case BeGlobalVariable : : TypeId :
{
2020-12-17 04:51:05 -08:00
auto globalVar = ( BeGlobalVariable * ) value ;
if ( globalVar - > mName . StartsWith ( " __bfStrObj " ) )
{
int stringId = atoi ( globalVar - > mName . c_str ( ) + 10 ) ;
int * stringTableIdxPtr = NULL ;
if ( mStringMap . TryAdd ( stringId , NULL , & stringTableIdxPtr ) )
{
* stringTableIdxPtr = ( int ) mCeFunction - > mStringTable . size ( ) ;
CeStringEntry ceStringEntry ;
ceStringEntry . mStringId = stringId ;
mCeFunction - > mStringTable . Add ( ceStringEntry ) ;
}
auto result = FrameAlloc ( mCeMachine - > GetBeContext ( ) - > GetPointerTo ( globalVar - > mType ) ) ;
Emit ( CeOp_GetString ) ;
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) * stringTableIdxPtr ) ;
return result ;
}
else if ( globalVar - > mName . StartsWith ( " __bfStrData " ) )
{
int stringId = atoi ( globalVar - > mName . c_str ( ) + 11 ) ;
int * stringTableIdxPtr = NULL ;
if ( mStringMap . TryAdd ( stringId , NULL , & stringTableIdxPtr ) )
{
* stringTableIdxPtr = ( int ) mCeFunction - > mStringTable . size ( ) ;
CeStringEntry ceStringEntry ;
ceStringEntry . mStringId = stringId ;
mCeFunction - > mStringTable . Add ( ceStringEntry ) ;
}
auto result = FrameAlloc ( mCeMachine - > GetBeContext ( ) - > GetPointerTo ( globalVar - > mType ) ) ;
Emit ( CeOp_GetString ) ;
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) * stringTableIdxPtr ) ;
BfTypeInstance * stringTypeInst = ( BfTypeInstance * ) mCeMachine - > mCeModule - > ResolveTypeDef (
mCeMachine - > mCeModule - > mCompiler - > mStringTypeDef , BfPopulateType_Data ) ;
Emit ( CeOp_AddConst_I32 ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) stringTypeInst - > mInstSize ) ;
return result ;
}
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
BfFieldInstance * * fieldInstancePtr = NULL ;
if ( mStaticFieldInstanceMap . TryGetValue ( globalVar - > mName , & fieldInstancePtr ) )
{
2020-12-19 14:19:33 -08:00
int * staticFieldTableIdxPtr = NULL ;
if ( mStaticFieldMap . TryAdd ( globalVar , NULL , & staticFieldTableIdxPtr ) )
{
CeStaticFieldEntry staticFieldEntry ;
2021-01-11 09:41:43 -08:00
staticFieldEntry . mTypeId = ( * fieldInstancePtr ) - > mOwner - > mTypeId ;
2020-12-19 14:19:33 -08:00
staticFieldEntry . mName = globalVar - > mName ;
staticFieldEntry . mSize = globalVar - > mType - > mSize ;
* staticFieldTableIdxPtr = ( int ) mCeFunction - > mStaticFieldTable . size ( ) ;
mCeFunction - > mStaticFieldTable . Add ( staticFieldEntry ) ;
}
auto result = FrameAlloc ( mCeMachine - > GetBeContext ( ) - > GetPointerTo ( globalVar - > mType ) ) ;
Emit ( CeOp_GetStaticField ) ;
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) * staticFieldTableIdxPtr ) ;
return result ;
}
if ( globalVar - > mInitializer ! = NULL )
2020-12-22 04:50:37 -08:00
{
auto result = GetOperand ( globalVar - > mInitializer , false , true ) ;
if ( result . mKind = = CeOperandKind_ConstStructTableIdx )
{
auto & constTableEntry = mCeFunction - > mConstStructTable [ result . mStructTableIdx ] ;
auto ptrType = mCeMachine - > GetBeContext ( ) - > GetPointerTo ( globalVar - > mType ) ;
auto dataResult = FrameAlloc ( ptrType ) ;
Emit ( CeOp_ConstDataRef ) ;
EmitFrameOffset ( dataResult ) ;
Emit ( ( int32 ) result . mCallTableIdx ) ;
return dataResult ;
}
return result ;
}
2020-12-19 14:19:33 -08:00
2020-12-17 04:51:05 -08:00
errorKind = CeErrorKind_GlobalVariable ;
errorType = mCeMachine - > GetBeContext ( ) - > GetPointerTo ( globalVar - > mType ) ;
2020-12-13 08:04:42 -08:00
}
break ;
case BeCastConstant : : TypeId :
{
2020-12-14 10:20:44 -08:00
auto constant = ( BeCastConstant * ) value ;
CeOperand mcOperand ;
2020-12-17 04:51:05 -08:00
auto result = GetOperand ( constant - > mTarget ) ;
result . mType = constant - > mType ;
return result ;
2020-12-13 08:04:42 -08:00
}
break ;
case BeConstant : : TypeId :
{
uint64 u64Val = 0 ;
float fVal = 0 ;
void * dataPtr = NULL ;
int dataSize = 0 ;
auto constant = ( BeConstant * ) value ;
CeOperand mcOperand ;
switch ( constant - > mType - > mTypeCode )
{
case BeTypeCode_Int8 :
case BeTypeCode_Int16 :
case BeTypeCode_Int32 :
2020-12-14 03:50:28 -08:00
case BeTypeCode_Int64 :
if ( allowImmediate )
{
CeOperand result ;
result . mKind = CeOperandKind_Immediate ;
result . mImmediate = constant - > mInt32 ;
result . mType = constant - > mType ;
return result ;
}
case BeTypeCode_Boolean :
2020-12-13 08:04:42 -08:00
case BeTypeCode_Double :
dataPtr = & constant - > mUInt64 ;
dataSize = constant - > mType - > mSize ;
break ;
case BeTypeCode_Float :
fVal = ( float ) constant - > mDouble ;
dataPtr = & fVal ;
dataSize = 4 ;
break ;
case BeTypeCode_Pointer :
{
if ( constant - > mTarget = = NULL )
{
dataPtr = & u64Val ;
dataSize = mPtrSize ;
}
else
{
2020-12-19 14:19:33 -08:00
auto relTo = GetOperand ( constant - > mTarget ) ;
if ( relTo )
{
auto result = relTo ;
result . mType = constant - > mType ;
return result ;
}
// if (relTo.mKind == CeOperandKind_Immediate_Null)
// {
// mcOperand.mKind = CeOperandKind_Immediate_Null;
// mcOperand.mType = constant->mType;
// return mcOperand;
// }
//
// mcOperand = AllocVirtualReg(constant->mType);
// auto vregInfo = GetVRegInfo(mcOperand);
// vregInfo->mDefOnFirstUse = true;
// vregInfo->mRelTo = relTo;
// vregInfo->mIsExpr = true;
//
//return mcOperand;
2020-12-13 08:04:42 -08:00
}
}
break ;
2020-12-14 03:50:28 -08:00
case BeTypeCode_Struct :
case BeTypeCode_SizedArray :
case BeTypeCode_Vector :
{
auto beType = constant - > mType ;
auto result = FrameAlloc ( beType ) ;
Emit ( CeOp_Zero ) ;
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) beType - > mSize ) ;
return result ;
}
//mcOperand.mImmediate = constant->mInt64;
//mcOperand.mKind = CeOperandKind_Immediate_i64;
break ;
2020-12-13 08:04:42 -08:00
// default:
// Fail("Unhandled constant type");
}
2020-12-14 03:50:28 -08:00
if ( dataSize ! = 0 )
2020-12-13 08:04:42 -08:00
{
auto beType = constant - > mType ;
auto result = FrameAlloc ( beType ) ;
CeSizeClass sizeClass = GetSizeClass ( dataSize ) ;
Emit ( ( CeOp ) ( CeOp_Const_8 + sizeClass ) ) ;
EmitFrameOffset ( result ) ;
if ( sizeClass = = CeSizeClass_X )
Emit ( ( int32 ) dataSize ) ;
2020-12-14 03:50:28 -08:00
if ( dataPtr ! = 0 )
Emit ( dataPtr , dataSize ) ;
else
{
for ( int i = 0 ; i < dataSize ; i + + )
Emit ( ( uint8 ) 0 ) ;
}
2020-12-13 08:04:42 -08:00
return result ;
}
}
break ;
case BeStructConstant : : TypeId :
{
2020-12-19 14:19:33 -08:00
int * constDataPtr = NULL ;
auto structConstant = ( BeStructConstant * ) value ;
if ( mConstDataMap . TryAdd ( structConstant , NULL , & constDataPtr ) )
{
CeConstStructData constStructData ;
2020-12-22 04:50:37 -08:00
constStructData . mQueueFixups = true ;
2021-01-11 09:41:43 -08:00
errorKind = mCeMachine - > WriteConstant ( constStructData , structConstant , NULL ) ;
2020-12-19 14:19:33 -08:00
if ( errorKind = = CeErrorKind_None )
{
* constDataPtr = ( int ) mCeFunction - > mConstStructTable . size ( ) ;
mCeFunction - > mConstStructTable . Add ( constStructData ) ;
}
else
{
* constDataPtr = - 1 ;
2020-12-22 04:50:37 -08:00
}
2020-12-19 14:19:33 -08:00
}
if ( * constDataPtr ! = - 1 )
{
2020-12-22 04:50:37 -08:00
if ( ! allowImmediate )
{
auto result = FrameAlloc ( structConstant - > mType ) ;
Emit ( CeOp_ConstData ) ;
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) * constDataPtr ) ;
return result ;
}
else
{
CeOperand result ;
result . mKind = CeOperandKind_ConstStructTableIdx ;
result . mCallTableIdx = * constDataPtr ;
result . mType = structConstant - > mType ;
return result ;
}
2020-12-19 14:19:33 -08:00
}
else
{
errorKind = CeErrorKind_GlobalVariable ;
}
2020-12-13 08:04:42 -08:00
}
2020-12-19 14:19:33 -08:00
break ;
2020-12-13 08:04:42 -08:00
case BeGEPConstant : : TypeId :
{
2020-12-17 04:51:05 -08:00
auto gepConstant = ( BeGEPConstant * ) value ;
auto mcVal = GetOperand ( gepConstant - > mTarget ) ;
BePointerType * ptrType = ( BePointerType * ) mcVal . mType ;
BF_ASSERT ( ptrType - > mTypeCode = = BeTypeCode_Pointer ) ;
auto result = mcVal ;
// We assume we never do both an idx0 and idx1 at once. Fix if we change that.
int64 byteOffset = 0 ;
BeType * elementType = NULL ;
byteOffset + = gepConstant - > mIdx0 * ptrType - > mElementType - > mSize ;
if ( ptrType - > mElementType - > mTypeCode = = BeTypeCode_Struct )
{
BeStructType * structType = ( BeStructType * ) ptrType - > mElementType ;
auto & structMember = structType - > mMembers [ gepConstant - > mIdx1 ] ;
elementType = structMember . mType ;
byteOffset = structMember . mByteOffset ;
}
else
{
BF_ASSERT ( ptrType - > mElementType - > mTypeCode = = BeTypeCode_SizedArray ) ;
auto arrayType = ( BeSizedArrayType * ) ptrType - > mElementType ;
elementType = arrayType - > mElementType ;
2021-01-18 14:09:16 -08:00
byteOffset = gepConstant - > mIdx1 * elementType - > GetStride ( ) ;
2020-12-17 04:51:05 -08:00
}
auto elementPtrType = mCeMachine - > GetBeContext ( ) - > GetPointerTo ( elementType ) ;
result = FrameAlloc ( elementPtrType ) ;
EmitSizedOp ( CeOp_AddConst_I8 , mPtrSize ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( mcVal ) ;
Emit ( & byteOffset , mPtrSize ) ;
2021-01-18 14:09:16 -08:00
2020-12-17 04:51:05 -08:00
return result ;
2020-12-13 08:04:42 -08:00
}
break ;
case BeExtractValueConstant : : TypeId :
{
// Note: this only handles zero-aggregates
2020-12-19 14:19:33 -08:00
auto extractConstant = ( BeExtractValueConstant * ) value ;
auto elementType = extractConstant - > GetType ( ) ;
auto mcVal = GetOperand ( extractConstant - > mTarget ) ;
BeConstant beConstant ;
beConstant . mType = elementType ;
beConstant . mUInt64 = 0 ;
return GetOperand ( & beConstant ) ;
2020-12-13 08:04:42 -08:00
}
break ;
2020-12-19 14:19:33 -08:00
case BeFunction : : TypeId :
{
auto beFunction = ( BeFunction * ) value ;
int * callIdxPtr = NULL ;
if ( mFunctionMap . TryAdd ( beFunction , NULL , & callIdxPtr ) )
{
CeFunctionInfo * ceFunctionInfo = NULL ;
mCeMachine - > mNamedFunctionMap . TryGetValue ( beFunction - > mName , & ceFunctionInfo ) ;
if ( ceFunctionInfo ! = NULL )
ceFunctionInfo - > mRefCount + + ;
else
{
auto checkBuilder = this ;
if ( checkBuilder - > mParentBuilder ! = NULL )
checkBuilder = checkBuilder - > mParentBuilder ;
int innerFunctionIdx = 0 ;
if ( checkBuilder - > mInnerFunctionMap . TryGetValue ( beFunction , & innerFunctionIdx ) )
{
auto innerFunction = checkBuilder - > mCeFunction - > mInnerFunctions [ innerFunctionIdx ] ;
2021-11-26 08:59:46 -08:00
if ( innerFunction - > mInitializeState < CeFunction : : InitializeState_Initialized )
2020-12-19 14:19:33 -08:00
mCeMachine - > PrepareFunction ( innerFunction , checkBuilder ) ;
CeOperand result = FrameAlloc ( mCeMachine - > GetBeContext ( ) - > GetPrimitiveType ( ( sizeof ( BfMethodInstance * ) = = 8 ) ? BeTypeCode_Int64 : BeTypeCode_Int32 ) ) ;
Emit ( CeOp_GetMethod_Inner ) ;
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) innerFunctionIdx ) ;
return result ;
}
Fail ( StrFormat ( " Unable to locate method %s " , beFunction - > mName . c_str ( ) ) ) ;
}
CeCallEntry callEntry ;
callEntry . mFunctionInfo = ceFunctionInfo ;
* callIdxPtr = ( int ) mCeFunction - > mCallTable . size ( ) ;
mCeFunction - > mCallTable . Add ( callEntry ) ;
}
if ( allowImmediate )
{
CeOperand result ;
result . mKind = CeOperandKind_CallTableIdx ;
result . mCallTableIdx = * callIdxPtr ;
return result ;
}
CeOperand result = FrameAlloc ( mCeMachine - > GetBeContext ( ) - > GetPrimitiveType ( ( sizeof ( BfMethodInstance * ) = = 8 ) ? BeTypeCode_Int64 : BeTypeCode_Int32 ) ) ;
Emit ( CeOp_GetMethod ) ;
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) * callIdxPtr ) ;
return result ;
2020-12-13 08:04:42 -08:00
}
break ;
case BeCallInst : : TypeId :
{
// auto callInst = (BeCallInst*)value;
// if (callInst->mInlineResult != NULL)
// return GetOperand(callInst->mInlineResult);
}
break ;
}
CeOperand * operandPtr = NULL ;
mValueToOperand . TryGetValue ( value , & operandPtr ) ;
2020-12-17 04:51:05 -08:00
if ( errorKind ! = CeErrorKind_None )
{
Emit ( CeOp_Error ) ;
Emit ( ( int32 ) errorKind ) ;
}
else
2020-12-13 08:04:42 -08:00
{
if ( operandPtr = = NULL )
{
BeDumpContext dumpCtx ;
String str ;
dumpCtx . ToString ( str , value ) ;
Fail ( StrFormat ( " Unable to find bevalue for operand: %s " , str . c_str ( ) ) ) ;
}
}
if ( operandPtr = = NULL )
{
2020-12-17 04:51:05 -08:00
return FrameAlloc ( errorType ) ;
2020-12-13 08:04:42 -08:00
}
auto operand = * operandPtr ;
if ( ( operand . mKind = = CeOperandKind_AllocaAddr ) & & ( ! allowAlloca ) )
{
auto irCodeGen = mCeMachine - > mCeModule - > mBfIRBuilder - > mBeIRCodeGen ;
2020-12-14 10:20:44 -08:00
auto ptrType = mCeMachine - > GetBeContext ( ) - > GetPointerTo ( operand . mType ) ;
auto result = FrameAlloc ( ptrType ) ;
Emit ( ( mPtrSize = = 4 ) ? CeOp_FrameAddr_32 : CeOp_FrameAddr_64 ) ;
2020-12-13 08:04:42 -08:00
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) operand . mFrameOfs ) ;
return result ;
}
return operand ;
}
CeSizeClass CeBuilder : : GetSizeClass ( int size )
{
switch ( size )
{
case 1 :
return CeSizeClass_8 ;
case 2 :
return CeSizeClass_16 ;
case 4 :
return CeSizeClass_32 ;
case 8 :
return CeSizeClass_64 ;
default :
return CeSizeClass_X ;
}
}
void CeBuilder : : HandleParams ( )
{
auto beModule = mBeFunction - > mModule ;
// int regIdxOfs = 0;
// int paramOfs = 0;
auto retType = mBeFunction - > GetFuncType ( ) - > mReturnType ;
int frameOffset = 0 ;
2020-12-30 13:24:13 -08:00
if ( mCeFunction - > mMaxReturnSize > 0 )
2020-12-13 08:04:42 -08:00
{
mReturnVal . mKind = CeOperandKind_AllocaAddr ;
mReturnVal . mFrameOfs = frameOffset ;
2020-12-30 13:24:13 -08:00
frameOffset + = mCeFunction - > mMaxReturnSize ;
2020-12-13 08:04:42 -08:00
}
int paramOfs = 0 ;
//for (int paramIdx = (int)mBeFunction->mParams.size() - 1; paramIdx >= 0; paramIdx--)
for ( int paramIdx = 0 ; paramIdx < mBeFunction - > mParams . size ( ) ; paramIdx + + )
{
auto funcType = mBeFunction - > GetFuncType ( ) ;
auto & typeParam = funcType - > mParams [ paramIdx + paramOfs ] ;
auto & param = mBeFunction - > mParams [ paramIdx + paramOfs ] ;
auto beArg = beModule - > GetArgument ( paramIdx + paramOfs ) ;
auto paramType = typeParam . mType ;
CeOperand ceOperand ;
ceOperand . mKind = CeOperandKind_FrameOfs ;
ceOperand . mFrameOfs = frameOffset ;
ceOperand . mType = paramType ;
frameOffset + = paramType - > mSize ;
mValueToOperand [ beArg ] = ceOperand ;
}
}
2021-01-05 13:50:57 -08:00
void CeBuilder : : ProcessMethod ( BfMethodInstance * methodInstance , BfMethodInstance * dupMethodInstance )
{
2021-01-13 05:09:09 -08:00
SetAndRestoreValue < BfMethodState * > prevMethodStateInConstEval ( mCeMachine - > mCeModule - > mCurMethodState , NULL ) ;
2021-12-20 15:07:38 -05:00
BfAutoComplete * prevAutoComplete = NULL ;
if ( mCeMachine - > mCeModule - > mCompiler - > mResolvePassData ! = NULL )
{
prevAutoComplete = mCeMachine - > mCeModule - > mCompiler - > mResolvePassData - > mAutoComplete ;
mCeMachine - > mCeModule - > mCompiler - > mResolvePassData - > mAutoComplete = NULL ;
}
2021-01-13 05:09:09 -08:00
2021-01-05 13:50:57 -08:00
auto irCodeGen = mCeMachine - > mCeModule - > mBfIRBuilder - > mBeIRCodeGen ;
auto irBuilder = mCeMachine - > mCeModule - > mBfIRBuilder ;
auto beModule = irCodeGen - > mBeModule ;
dupMethodInstance - > mIsReified = true ;
dupMethodInstance - > mInCEMachine = false ; // Only have the original one
mCeMachine - > mCeModule - > mHadBuildError = false ;
auto irState = irBuilder - > GetState ( ) ;
auto beState = irCodeGen - > GetState ( ) ;
mCeMachine - > mCeModule - > ProcessMethod ( dupMethodInstance , true ) ;
irCodeGen - > SetState ( beState ) ;
irBuilder - > SetState ( irState ) ;
2021-12-20 15:07:38 -05:00
if ( mCeMachine - > mCeModule - > mCompiler - > mResolvePassData ! = NULL )
mCeMachine - > mCeModule - > mCompiler - > mResolvePassData - > mAutoComplete = prevAutoComplete ;
2021-01-05 13:50:57 -08:00
}
2020-12-13 08:04:42 -08:00
void CeBuilder : : Build ( )
2020-12-14 10:20:44 -08:00
{
2020-12-19 14:19:33 -08:00
auto irCodeGen = mCeMachine - > mCeModule - > mBfIRBuilder - > mBeIRCodeGen ;
2020-12-30 13:24:13 -08:00
auto irBuilder = mCeMachine - > mCeModule - > mBfIRBuilder ;
2020-12-19 14:19:33 -08:00
auto beModule = irCodeGen - > mBeModule ;
2020-12-13 08:04:42 -08:00
mCeFunction - > mFailed = true ;
auto methodInstance = mCeFunction - > mMethodInstance ;
2020-12-17 04:51:05 -08:00
2020-12-19 14:19:33 -08:00
if ( methodInstance ! = NULL )
2021-12-11 09:08:42 -08:00
{
2021-01-05 13:50:57 -08:00
BfMethodInstance dupMethodInstance ;
dupMethodInstance . CopyFrom ( methodInstance ) ;
2020-12-19 14:19:33 -08:00
auto methodDef = methodInstance - > mMethodDef ;
2020-12-13 08:04:42 -08:00
2021-01-05 13:50:57 -08:00
bool isGenericVariation = ( methodInstance - > mIsUnspecializedVariation ) | | ( methodInstance - > GetOwner ( ) - > IsUnspecializedTypeVariation ( ) ) ;
int dependentGenericStartIdx = 0 ;
if ( ( ( ( methodInstance - > mMethodInfoEx ! = NULL ) & & ( ( int ) methodInstance - > mMethodInfoEx - > mMethodGenericArguments . size ( ) > dependentGenericStartIdx ) ) | |
( ( methodInstance - > GetOwner ( ) - > IsGenericTypeInstance ( ) ) & & ( ! isGenericVariation ) & & ( ! methodInstance - > mMethodDef - > mIsLocalMethod ) ) ) )
{
auto unspecializedMethodInstance = mCeMachine - > mCeModule - > GetUnspecializedMethodInstance ( methodInstance , ! methodInstance - > mMethodDef - > mIsLocalMethod ) ;
if ( ! unspecializedMethodInstance - > mHasBeenProcessed )
{
BfMethodInstance dupUnspecMethodInstance ;
dupUnspecMethodInstance . CopyFrom ( unspecializedMethodInstance ) ;
ProcessMethod ( unspecializedMethodInstance , & dupUnspecMethodInstance ) ;
dupMethodInstance . GetMethodInfoEx ( ) - > mGenericTypeBindings = dupUnspecMethodInstance . mMethodInfoEx - > mGenericTypeBindings ;
}
}
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
// Clear this so we can properly get QueueStaticField calls
mCeMachine - > mCeModule - > mStaticFieldRefs . Clear ( ) ;
2020-12-19 14:19:33 -08:00
int startFunctionCount = ( int ) beModule - > mFunctions . size ( ) ;
2021-12-20 15:07:38 -05:00
ProcessMethod ( methodInstance , & dupMethodInstance ) ;
2021-11-26 08:59:46 -08:00
if ( mCeFunction - > mInitializeState = = CeFunction : : InitializeState_Initialized )
return ;
2020-12-19 14:19:33 -08:00
if ( ! dupMethodInstance . mIRFunction )
{
mCeFunction - > mFailed = true ;
return ;
2021-01-05 13:50:57 -08:00
}
mBeFunction = ( BeFunction * ) irCodeGen - > GetBeValue ( dupMethodInstance . mIRFunction . mId ) ;
2020-12-19 14:19:33 -08:00
mIntPtrType = irCodeGen - > mBeContext - > GetPrimitiveType ( ( mPtrSize = = 4 ) ? BeTypeCode_Int32 : BeTypeCode_Int64 ) ;
for ( int funcIdx = startFunctionCount ; funcIdx < ( int ) beModule - > mFunctions . size ( ) ; funcIdx + + )
{
auto beFunction = beModule - > mFunctions [ funcIdx ] ;
if ( beFunction = = mBeFunction )
continue ;
if ( beFunction - > mBlocks . IsEmpty ( ) )
continue ;
2020-12-23 11:27:46 -08:00
CeFunction * innerFunction = new CeFunction ( ) ;
2021-02-01 13:55:29 -08:00
innerFunction - > mCeMachine = mCeMachine ;
2020-12-30 13:24:13 -08:00
innerFunction - > mIsVarReturn = beFunction - > mIsVarReturn ;
2020-12-19 14:19:33 -08:00
innerFunction - > mCeInnerFunctionInfo = new CeInnerFunctionInfo ( ) ;
innerFunction - > mCeInnerFunctionInfo - > mName = beFunction - > mName ;
innerFunction - > mCeInnerFunctionInfo - > mBeFunction = beFunction ;
innerFunction - > mCeInnerFunctionInfo - > mOwner = mCeFunction ;
mInnerFunctionMap [ beFunction ] = ( int ) mCeFunction - > mInnerFunctions . size ( ) ;
mCeFunction - > mInnerFunctions . Add ( innerFunction ) ;
2020-12-23 11:27:46 -08:00
mCeMachine - > MapFunctionId ( innerFunction ) ;
2020-12-19 14:19:33 -08:00
}
if ( ! mCeFunction - > mCeFunctionInfo - > mName . IsEmpty ( ) )
{
BF_ASSERT ( mCeFunction - > mCeFunctionInfo - > mName = = mBeFunction - > mName ) ;
}
else
{
mCeFunction - > mCeFunctionInfo - > mName = mBeFunction - > mName ;
mCeMachine - > mNamedFunctionMap [ mCeFunction - > mCeFunctionInfo - > mName ] = mCeFunction - > mCeFunctionInfo ;
}
if ( mCeMachine - > mCeModule - > mHadBuildError )
{
mCeFunction - > mGenError = " Method had errors " ;
mCeMachine - > mCeModule - > mHadBuildError = false ;
return ;
}
2020-12-17 04:51:05 -08:00
}
else
{
2020-12-19 14:19:33 -08:00
BF_ASSERT ( mCeFunction - > mCeInnerFunctionInfo ! = NULL ) ;
mBeFunction = mCeFunction - > mCeInnerFunctionInfo - > mBeFunction ;
BF_ASSERT ( mBeFunction ! = NULL ) ;
mCeFunction - > mCeInnerFunctionInfo - > mBeFunction = NULL ;
2020-12-17 04:51:05 -08:00
}
2020-12-13 08:04:42 -08:00
SetAndRestoreValue < BeFunction * > prevBeFunction ( beModule - > mActiveFunction , mBeFunction ) ;
// Create blocks
for ( int blockIdx = 0 ; blockIdx < ( int ) mBeFunction - > mBlocks . size ( ) ; blockIdx + + )
{
auto beBlock = mBeFunction - > mBlocks [ blockIdx ] ;
CeBlock ceBlock ;
mBlocks . Add ( ceBlock ) ;
CeOperand ceOperand ;
ceOperand . mKind = CeOperandKind_Block ;
ceOperand . mBlockIdx = blockIdx ;
mValueToOperand [ beBlock ] = ceOperand ;
}
// Instruction pre-pass
for ( int blockIdx = 0 ; blockIdx < ( int ) mBeFunction - > mBlocks . size ( ) ; blockIdx + + )
{
auto beBlock = mBeFunction - > mBlocks [ blockIdx ] ;
auto & ceBlock = mBlocks [ blockIdx ] ;
for ( int instIdx = 0 ; instIdx < ( int ) beBlock - > mInstructions . size ( ) ; instIdx + + )
{
auto inst = beBlock - > mInstructions [ instIdx ] ;
int instType = inst - > GetTypeId ( ) ;
switch ( instType )
{
case BePhiInst : : TypeId :
{
auto castedInst = ( BePhiInst * ) inst ;
auto resultType = castedInst - > GetType ( ) ;
auto phiResult = FrameAlloc ( resultType ) ;
mValueToOperand [ castedInst ] = phiResult ;
for ( auto & phiIncoming : castedInst - > mIncoming )
{
auto incomingBlockOpr = GetOperand ( phiIncoming - > mBlock ) ;
auto & incomingBlock = mBlocks [ incomingBlockOpr . mBlockIdx ] ;
CePhiOutgoing phiOutgoing ;
phiOutgoing . mPhiValue = phiIncoming - > mValue ;
phiOutgoing . mPhiInst = castedInst ;
phiOutgoing . mPhiBlockIdx = blockIdx ;
incomingBlock . mPhiOutgoing . Add ( phiOutgoing ) ;
}
}
break ;
2020-12-30 13:24:13 -08:00
case BeRetInst : : TypeId :
case BeSetRetInst : : TypeId :
{
auto castedInst = ( BeRetInst * ) inst ;
if ( castedInst - > mRetValue ! = NULL )
{
auto retType = castedInst - > mRetValue - > GetType ( ) ;
mCeFunction - > mMaxReturnSize = BF_MAX ( retType - > mSize , mCeFunction - > mMaxReturnSize ) ;
}
}
break ;
2020-12-13 08:04:42 -08:00
}
}
}
// Primary instruction pass
BeDbgLoc * prevEmitDbgPos = NULL ;
bool inHeadAlloca = true ;
for ( int blockIdx = 0 ; blockIdx < ( int ) mBeFunction - > mBlocks . size ( ) ; blockIdx + + )
{
auto beBlock = mBeFunction - > mBlocks [ blockIdx ] ;
auto ceBlock = & mBlocks [ blockIdx ] ;
ceBlock - > mEmitOfs = GetCodePos ( ) ;
if ( blockIdx = = 0 )
HandleParams ( ) ;
for ( int instIdx = 0 ; instIdx < ( int ) beBlock - > mInstructions . size ( ) ; instIdx + + )
{
auto inst = beBlock - > mInstructions [ instIdx ] ;
CeOperand result ;
int startCodePos = GetCodePos ( ) ;
mCurDbgLoc = inst - > mDbgLoc ;
int instType = inst - > GetTypeId ( ) ;
switch ( instType )
{
case BeAllocaInst : : TypeId :
case BeNumericCastInst : : TypeId :
case BeBitCastInst : : TypeId :
break ;
default :
inHeadAlloca = false ;
break ;
}
switch ( instType )
{
case BeEnsureInstructionAtInst : : TypeId :
case BeNopInst : : TypeId :
case BeDbgDeclareInst : : TypeId :
case BeLifetimeStartInst : : TypeId :
case BeLifetimeEndInst : : TypeId :
case BeLifetimeExtendInst : : TypeId :
case BeValueScopeStartInst : : TypeId :
case BeValueScopeEndInst : : TypeId :
2020-12-17 04:51:05 -08:00
case BeValueScopeRetainInst : : TypeId :
2021-01-09 04:20:45 -08:00
case BeComptimeGetVirtualFunc : : TypeId :
case BeComptimeGetInterfaceFunc : : TypeId :
2020-12-13 08:04:42 -08:00
break ;
case BeUnreachableInst : : TypeId :
Emit ( CeOp_InvalidOp ) ;
break ;
2020-12-17 04:51:05 -08:00
case BeUndefValueInst : : TypeId :
{
auto castedInst = ( BeUndefValueInst * ) inst ;
result = FrameAlloc ( castedInst - > mType ) ;
}
break ;
2020-12-13 08:04:42 -08:00
case BeAllocaInst : : TypeId :
{
auto castedInst = ( BeAllocaInst * ) inst ;
2020-12-17 04:51:05 -08:00
CeOperand ceSize ;
ceSize . mKind = CeOperandKind_Immediate ;
ceSize . mImmediate = castedInst - > mType - > mSize ;
ceSize . mType = mIntPtrType ;
2020-12-13 08:04:42 -08:00
bool isAligned16 = false ;
int align = castedInst - > mAlign ;
BeType * allocType = castedInst - > mType ;
2020-12-17 04:51:05 -08:00
bool preservedVolatiles = false ;
if ( castedInst - > mArraySize ! = NULL )
{
auto mcArraySize = GetOperand ( castedInst - > mArraySize , false , true ) ;
if ( mcArraySize . IsImmediate ( ) )
{
ceSize . mImmediate = ceSize . mImmediate * mcArraySize . mImmediate ;
}
else
{
inHeadAlloca = false ;
if ( ceSize . mImmediate = = 1 )
{
ceSize = mcArraySize ;
}
else
{
ceSize = EmitConst ( ceSize . mImmediate , mcArraySize . mType - > mSize ) ;
EmitSizedOp ( CeOp_Mul_I8 , ceSize . mType - > mSize ) ;
EmitFrameOffset ( ceSize ) ;
EmitFrameOffset ( ceSize ) ;
EmitFrameOffset ( mcArraySize ) ;
}
}
}
2020-12-13 08:04:42 -08:00
if ( inHeadAlloca )
{
2020-12-17 04:51:05 -08:00
BF_ASSERT ( ceSize . mKind = = CeOperandKind_Immediate ) ;
mFrameSize + = ceSize . mImmediate ;
2020-12-13 08:04:42 -08:00
result . mKind = CeOperandKind_AllocaAddr ;
result . mFrameOfs = - mFrameSize ;
2020-12-17 04:51:05 -08:00
result . mType = castedInst - > mType ;
2020-12-13 08:04:42 -08:00
}
else
{
2020-12-17 04:51:05 -08:00
if ( ceSize . mKind = = CeOperandKind_Immediate )
{
Emit ( CeOp_AdjustSPConst ) ;
Emit ( ( int32 ) - ceSize . mImmediate ) ;
}
else
{
Emit ( CeOp_AdjustSPNeg ) ;
EmitFrameOffset ( ceSize ) ;
}
auto ptrType = beModule - > mContext - > GetPointerTo ( allocType ) ;
result = FrameAlloc ( ptrType ) ;
Emit ( CeOp_GetSP ) ;
EmitFrameOffset ( result ) ;
2020-12-13 08:04:42 -08:00
}
}
break ;
case BeLoadInst : : TypeId :
{
auto castedInst = ( BeLoadInst * ) inst ;
auto ceTarget = GetOperand ( castedInst - > mTarget , true ) ;
if ( ceTarget . mKind = = CeOperandKind_AllocaAddr )
{
2020-12-17 04:51:05 -08:00
if ( inst - > mRefCount < = 1 )
{
result = ceTarget ;
result . mKind = CeOperandKind_FrameOfs ;
}
else
{
ceTarget . mKind = CeOperandKind_FrameOfs ;
result = FrameAlloc ( ceTarget . mType ) ;
EmitSizedOp ( CeOp_Move_8 , ceTarget , NULL , true ) ;
Emit ( ( int32 ) result . mFrameOfs ) ;
}
2020-12-13 08:04:42 -08:00
}
else
{
BF_ASSERT ( ceTarget . mType - > IsPointer ( ) ) ;
auto pointerType = ( BePointerType * ) ceTarget . mType ;
auto elemType = pointerType - > mElementType ;
2020-12-23 11:27:46 -08:00
2020-12-13 08:04:42 -08:00
CeOperand refOperand = ceTarget ;
refOperand . mType = elemType ;
EmitSizedOp ( CeOp_Load_8 , refOperand , & result , true ) ;
}
}
break ;
case BeBinaryOpInst : : TypeId :
{
auto castedInst = ( BeBinaryOpInst * ) inst ;
auto ceLHS = GetOperand ( castedInst - > mLHS ) ;
auto ceRHS = GetOperand ( castedInst - > mRHS ) ;
switch ( castedInst - > mOpKind )
{
case BeBinaryOpKind_Add :
EmitBinaryOp ( CeOp_Add_I8 , CeOp_Add_F32 , ceLHS , ceRHS , result ) ;
break ;
2020-12-14 03:50:28 -08:00
case BeBinaryOpKind_Subtract :
EmitBinaryOp ( CeOp_Sub_I8 , CeOp_Sub_F32 , ceLHS , ceRHS , result ) ;
break ;
case BeBinaryOpKind_Multiply :
EmitBinaryOp ( CeOp_Mul_I8 , CeOp_Mul_F32 , ceLHS , ceRHS , result ) ;
break ;
case BeBinaryOpKind_SDivide :
2020-12-17 04:51:05 -08:00
EmitBinaryOp ( CeOp_Div_I8 , CeOp_Div_F32 , ceLHS , ceRHS , result ) ;
2020-12-14 03:50:28 -08:00
break ;
case BeBinaryOpKind_UDivide :
2020-12-17 04:51:05 -08:00
EmitBinaryOp ( CeOp_Div_U8 , CeOp_InvalidOp , ceLHS , ceRHS , result ) ;
2020-12-14 03:50:28 -08:00
break ;
case BeBinaryOpKind_SModulus :
2020-12-17 04:51:05 -08:00
EmitBinaryOp ( CeOp_Mod_I8 , CeOp_Mod_F32 , ceLHS , ceRHS , result ) ;
2020-12-14 03:50:28 -08:00
break ;
case BeBinaryOpKind_UModulus :
2020-12-17 04:51:05 -08:00
EmitBinaryOp ( CeOp_Mod_U8 , CeOp_InvalidOp , ceLHS , ceRHS , result ) ;
break ;
case BeBinaryOpKind_BitwiseAnd :
EmitBinaryOp ( CeOp_And_I8 , CeOp_InvalidOp , ceLHS , ceRHS , result ) ;
break ;
case BeBinaryOpKind_BitwiseOr :
EmitBinaryOp ( CeOp_Or_I8 , CeOp_InvalidOp , ceLHS , ceRHS , result ) ;
break ;
case BeBinaryOpKind_ExclusiveOr :
EmitBinaryOp ( CeOp_Xor_I8 , CeOp_InvalidOp , ceLHS , ceRHS , result ) ;
break ;
case BeBinaryOpKind_LeftShift :
EmitBinaryOp ( CeOp_Shl_I8 , CeOp_InvalidOp , ceLHS , ceRHS , result ) ;
break ;
case BeBinaryOpKind_RightShift :
2021-12-11 09:08:42 -08:00
EmitBinaryOp ( CeOp_Shr_U8 , CeOp_InvalidOp , ceLHS , ceRHS , result ) ;
2020-12-17 04:51:05 -08:00
break ;
case BeBinaryOpKind_ARightShift :
2021-12-11 09:08:42 -08:00
EmitBinaryOp ( CeOp_Shr_I8 , CeOp_InvalidOp , ceLHS , ceRHS , result ) ;
2020-12-14 03:50:28 -08:00
break ;
2020-12-13 08:04:42 -08:00
default :
Fail ( " Invalid binary op " ) ;
}
2020-12-17 04:51:05 -08:00
}
break ;
case BeBitCastInst : : TypeId :
{
auto castedInst = ( BeBitCastInst * ) inst ;
auto mcValue = GetOperand ( castedInst - > mValue , false , true ) ;
if ( castedInst - > mToType - > IsInt ( ) )
{
BF_ASSERT ( castedInst - > mToType - > mSize = = 8 ) ;
}
else
BF_ASSERT ( castedInst - > mToType - > IsPointer ( ) ) ;
auto toType = castedInst - > mToType ;
2020-12-13 08:04:42 -08:00
2020-12-17 04:51:05 -08:00
if ( mcValue . IsImmediate ( ) )
{
if ( mcValue . mImmediate = = 0 )
{
CeOperand newImmediate ;
newImmediate . mKind = CeOperandKind_Immediate ;
newImmediate . mType = toType ;
result = newImmediate ;
}
else
{
// Non-zero constant. Weird case, just do an actual MOV
result = FrameAlloc ( toType ) ;
EmitSizedOp ( CeOp_Const_8 , result , NULL , true ) ;
int64 val = mcValue . mImmediate ;
Emit ( & val , toType - > mSize ) ;
}
}
else
{
if ( toType - > mSize ! = mcValue . mType - > mSize )
Fail ( " Invalid bitcast " ) ;
result = mcValue ;
result . mType = toType ;
}
2020-12-13 08:04:42 -08:00
}
break ;
case BeNumericCastInst : : TypeId :
{
auto castedInst = ( BeNumericCastInst * ) inst ;
auto ceValue = GetOperand ( castedInst - > mValue ) ;
auto fromType = ceValue . mType ;
if ( fromType = = castedInst - > mToType )
{
// If it's just a sign change then leave it alone
result = ceValue ;
}
else
{
2020-12-17 04:51:05 -08:00
auto toType = castedInst - > mToType ;
if ( ( toType - > IsIntable ( ) ) & & ( fromType - > IsIntable ( ) ) & & ( toType - > mSize < = fromType - > mSize ) )
2020-12-13 08:04:42 -08:00
{
// For truncating values, no actual instructions are needed
2020-12-17 04:51:05 -08:00
// Note that a copy is not needed because of SSA rules
2020-12-13 08:04:42 -08:00
result = ceValue ;
2020-12-17 04:51:05 -08:00
result . mType = toType ;
2020-12-13 08:04:42 -08:00
}
else
2020-12-17 04:51:05 -08:00
{
2020-12-13 08:04:42 -08:00
result = FrameAlloc ( toType ) ;
CeOp op = CeOp_InvalidOp ;
2020-12-17 04:51:05 -08:00
BeTypeCode fromTypeCode = fromType - > mTypeCode ;
BeTypeCode toTypeCode = toType - > mTypeCode ;
2020-12-19 14:19:33 -08:00
if ( ( castedInst - > mValSigned ) & & ( castedInst - > mToSigned ) )
2020-12-17 04:51:05 -08:00
{
switch ( fromTypeCode )
2020-12-13 08:04:42 -08:00
{
2020-12-17 04:51:05 -08:00
case BeTypeCode_Int8 :
switch ( toTypeCode )
{
case BeTypeCode_Int16 :
op = CeOp_Conv_I8_I16 ;
break ;
case BeTypeCode_Int32 :
op = CeOp_Conv_I8_I32 ;
break ;
case BeTypeCode_Int64 :
op = CeOp_Conv_I8_I64 ;
break ;
case BeTypeCode_Float :
op = CeOp_Conv_I8_F32 ;
break ;
case BeTypeCode_Double :
op = CeOp_Conv_I8_F64 ;
break ;
}
break ;
case BeTypeCode_Int16 :
switch ( toTypeCode )
{
case BeTypeCode_Int32 :
op = CeOp_Conv_I16_I32 ;
break ;
case BeTypeCode_Int64 :
op = CeOp_Conv_I16_I64 ;
break ;
case BeTypeCode_Float :
op = CeOp_Conv_I16_F32 ;
break ;
case BeTypeCode_Double :
op = CeOp_Conv_I16_F64 ;
break ;
}
break ;
2020-12-13 08:04:42 -08:00
case BeTypeCode_Int32 :
2020-12-17 04:51:05 -08:00
switch ( toTypeCode )
2020-12-13 08:04:42 -08:00
{
case BeTypeCode_Int64 :
op = CeOp_Conv_I32_I64 ;
2020-12-17 04:51:05 -08:00
break ;
case BeTypeCode_Float :
op = CeOp_Conv_I32_F32 ;
break ;
case BeTypeCode_Double :
op = CeOp_Conv_I32_F64 ;
break ;
}
break ;
case BeTypeCode_Int64 :
switch ( toTypeCode )
{
case BeTypeCode_Float :
op = CeOp_Conv_I64_F32 ;
break ;
case BeTypeCode_Double :
op = CeOp_Conv_I64_F64 ;
break ;
}
break ;
case BeTypeCode_Float :
switch ( toTypeCode )
{
case BeTypeCode_Int8 :
op = CeOp_Conv_F32_I8 ;
break ;
case BeTypeCode_Int16 :
op = CeOp_Conv_F32_I16 ;
break ;
case BeTypeCode_Int32 :
op = CeOp_Conv_F32_I32 ;
break ;
case BeTypeCode_Int64 :
op = CeOp_Conv_F32_I64 ;
break ;
case BeTypeCode_Double :
op = CeOp_Conv_F32_F64 ;
break ;
}
break ;
case BeTypeCode_Double :
switch ( toTypeCode )
{
case BeTypeCode_Int8 :
op = CeOp_Conv_F64_I8 ;
break ;
case BeTypeCode_Int16 :
op = CeOp_Conv_F64_I16 ;
break ;
case BeTypeCode_Int32 :
op = CeOp_Conv_F64_I32 ;
break ;
case BeTypeCode_Int64 :
op = CeOp_Conv_F64_I64 ;
break ;
case BeTypeCode_Float :
op = CeOp_Conv_F64_F32 ;
break ;
2020-12-13 08:04:42 -08:00
}
2020-12-17 04:51:05 -08:00
break ;
2020-12-13 08:04:42 -08:00
}
}
else
{
2020-12-17 04:51:05 -08:00
switch ( fromTypeCode )
{
case BeTypeCode_Int8 :
switch ( toTypeCode )
{
case BeTypeCode_Int16 :
op = CeOp_Conv_U8_U16 ;
break ;
case BeTypeCode_Int32 :
op = CeOp_Conv_U8_U32 ;
break ;
case BeTypeCode_Int64 :
op = CeOp_Conv_U8_U64 ;
break ;
case BeTypeCode_Float :
op = CeOp_Conv_I8_F32 ;
break ;
case BeTypeCode_Double :
op = CeOp_Conv_I8_F64 ;
break ;
}
break ;
case BeTypeCode_Int16 :
switch ( toTypeCode )
{
case BeTypeCode_Int32 :
op = CeOp_Conv_U16_U32 ;
break ;
case BeTypeCode_Int64 :
op = CeOp_Conv_U16_U64 ;
break ;
case BeTypeCode_Float :
op = CeOp_Conv_U16_F32 ;
break ;
case BeTypeCode_Double :
op = CeOp_Conv_U16_F64 ;
break ;
}
break ;
case BeTypeCode_Int32 :
switch ( toTypeCode )
{
case BeTypeCode_Int64 :
op = CeOp_Conv_U32_U64 ;
break ;
case BeTypeCode_Float :
op = CeOp_Conv_U32_F32 ;
break ;
case BeTypeCode_Double :
op = CeOp_Conv_U32_F64 ;
break ;
}
break ;
case BeTypeCode_Int64 :
switch ( toTypeCode )
{
case BeTypeCode_Float :
op = CeOp_Conv_I64_F32 ;
break ;
case BeTypeCode_Double :
op = CeOp_Conv_I64_F64 ;
break ;
}
break ;
}
}
if ( op = = CeOp_InvalidOp )
{
Fail ( " Invalid conversion op " ) ;
}
else
{
Emit ( op ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( ceValue ) ;
}
}
}
}
break ;
case BeStoreInst : : TypeId :
{
auto castedInst = ( BeStoreInst * ) inst ;
2020-12-13 08:04:42 -08:00
auto mcVal = GetOperand ( castedInst - > mVal ) ;
auto mcPtr = GetOperand ( castedInst - > mPtr , true ) ;
if ( mcPtr . mKind = = CeOperandKind_AllocaAddr )
2020-12-17 04:51:05 -08:00
{
2020-12-13 08:04:42 -08:00
EmitSizedOp ( CeOp_Move_8 , mcVal , NULL , true ) ;
Emit ( ( int32 ) mcPtr . mFrameOfs ) ;
}
else
{
EmitSizedOp ( CeOp_Store_8 , mcVal , NULL , true ) ;
EmitFrameOffset ( mcPtr ) ;
}
}
break ;
case BeRetInst : : TypeId :
2020-12-30 13:24:13 -08:00
case BeSetRetInst : : TypeId :
{
2020-12-13 08:04:42 -08:00
auto castedInst = ( BeRetInst * ) inst ;
if ( castedInst - > mRetValue ! = NULL )
{
2020-12-30 13:24:13 -08:00
auto mcVal = GetOperand ( castedInst - > mRetValue ) ;
2021-01-18 14:09:16 -08:00
if ( mcVal . mType - > mSize > 0 )
{
BF_ASSERT ( mReturnVal . mKind = = CeOperandKind_AllocaAddr ) ;
EmitSizedOp ( CeOp_Move_8 , mcVal , NULL , true ) ;
Emit ( ( int32 ) mReturnVal . mFrameOfs ) ;
}
2020-12-30 13:24:13 -08:00
}
if ( instType = = BeRetInst : : TypeId )
Emit ( CeOp_Ret ) ;
else
{
auto setRetInst = ( BeSetRetInst * ) inst ;
Emit ( CeOp_SetRetType ) ;
Emit ( ( int32 ) setRetInst - > mReturnTypeId ) ;
2020-12-13 08:04:42 -08:00
}
}
2020-12-30 13:24:13 -08:00
break ;
2020-12-13 08:04:42 -08:00
case BeCmpInst : : TypeId :
{
auto castedInst = ( BeCmpInst * ) inst ;
auto ceLHS = GetOperand ( castedInst - > mLHS ) ;
auto ceRHS = GetOperand ( castedInst - > mRHS ) ;
CeOp iOp = CeOp_InvalidOp ;
CeOp fOp = CeOp_InvalidOp ;
switch ( castedInst - > mCmpKind )
{
2020-12-17 04:51:05 -08:00
case BeCmpKind_EQ :
iOp = CeOp_Cmp_EQ_I8 ;
fOp = CeOp_Cmp_EQ_F32 ;
break ;
case BeCmpKind_NE :
iOp = CeOp_Cmp_NE_I8 ;
fOp = CeOp_Cmp_NE_F32 ;
break ;
2020-12-13 08:04:42 -08:00
case BeCmpKind_SLT :
iOp = CeOp_Cmp_SLT_I8 ;
fOp = CeOp_Cmp_SLT_F32 ;
break ;
2020-12-14 03:50:28 -08:00
case BeCmpKind_ULT :
iOp = CeOp_Cmp_ULT_I8 ;
break ;
case BeCmpKind_SLE :
iOp = CeOp_Cmp_SLE_I8 ;
fOp = CeOp_Cmp_SLE_F32 ;
break ;
case BeCmpKind_ULE :
iOp = CeOp_Cmp_ULE_I8 ;
break ;
2020-12-17 04:51:05 -08:00
case BeCmpKind_SGT :
iOp = CeOp_Cmp_SGT_I8 ;
fOp = CeOp_Cmp_SGT_F32 ;
break ;
case BeCmpKind_UGT :
iOp = CeOp_Cmp_UGT_I8 ;
break ;
case BeCmpKind_SGE :
iOp = CeOp_Cmp_SGE_I8 ;
fOp = CeOp_Cmp_SGE_F32 ;
break ;
case BeCmpKind_UGE :
iOp = CeOp_Cmp_UGE_I8 ;
break ;
2020-12-13 08:04:42 -08:00
}
if ( iOp = = CeOp_InvalidOp )
{
Fail ( " Invalid cmp " ) ;
break ;
}
auto boolType = inst - > GetType ( ) ;
result = FrameAlloc ( boolType ) ;
EmitBinaryOp ( iOp , fOp , ceLHS , ceRHS , result ) ;
// auto mcInst = AllocInst(BeMCInstKind_Cmp, mcLHS, mcRHS);
//
// auto cmpResultIdx = (int)mCmpResults.size();
// BeCmpResult cmpResult;
// cmpResult.mCmpKind = castedInst->mCmpKind;
// mCmpResults.push_back(cmpResult);
//
// result.mKind = BeMCOperandKind_CmpResult;
// result.mCmpResultIdx = cmpResultIdx;
//
// mcInst->mResult = result;
}
break ;
2020-12-14 03:50:28 -08:00
case BeGEPInst : : TypeId :
{
auto castedInst = ( BeGEPInst * ) inst ;
2020-12-14 10:20:44 -08:00
auto ceVal = GetOperand ( castedInst - > mPtr ) ;
auto ceIdx0 = GetOperand ( castedInst - > mIdx0 , false , true ) ;
2020-12-14 03:50:28 -08:00
2020-12-14 10:20:44 -08:00
BePointerType * ptrType = ( BePointerType * ) ceVal . mType ;
2020-12-14 03:50:28 -08:00
BF_ASSERT ( ptrType - > mTypeCode = = BeTypeCode_Pointer ) ;
2020-12-14 10:20:44 -08:00
result = ceVal ;
2020-12-14 03:50:28 -08:00
if ( castedInst - > mIdx1 ! = NULL )
{
// We assume we never do both an idx0 and idx1 at once. Fix if we change that.
BF_ASSERT ( castedInst - > mIdx0 ) ;
2020-12-14 10:20:44 -08:00
auto ceIdx1 = GetOperand ( castedInst - > mIdx1 , false , true ) ;
if ( ! ceIdx1 . IsImmediate ( ) )
2020-12-14 03:50:28 -08:00
{
// This path is used when we have a const array that gets indexed by a non-const index value
2020-12-14 10:20:44 -08:00
if ( ptrType - > mElementType - > mTypeCode = = BeTypeCode_SizedArray )
{
auto arrayType = ( BeSizedArrayType * ) ptrType - > mElementType ;
auto elementPtrType = beModule - > mContext - > GetPointerTo ( arrayType - > mElementType ) ;
if ( ceIdx1 . IsImmediate ( ) )
{
if ( ceIdx1 . mImmediate = = 0 )
{
result = ceVal ;
result . mType = elementPtrType ;
}
else
{
auto ptrValue = FrameAlloc ( elementPtrType ) ;
result = ptrValue ;
result = FrameAlloc ( elementPtrType ) ;
2021-01-26 06:33:23 -08:00
EmitSizedOp ( CeOp_AddConst_I8 , mPtrSize ) ;
2020-12-14 10:20:44 -08:00
EmitFrameOffset ( result ) ;
EmitFrameOffset ( ceVal ) ;
2021-01-18 14:09:16 -08:00
Emit ( ( int32 ) ( ceIdx1 . mImmediate * arrayType - > mElementType - > GetStride ( ) ) ) ;
2021-01-26 06:33:23 -08:00
if ( mPtrSize = = 8 )
Emit ( ( int32 ) 0 ) ;
2020-12-14 10:20:44 -08:00
}
}
else
{
auto ptrValue = FrameAlloc ( elementPtrType ) ;
result = ptrValue ;
2020-12-19 14:19:33 -08:00
if ( ceIdx1 . mType - > mSize < 4 )
{
auto ceNewIdx = FrameAlloc ( mIntPtrType ) ;
if ( mIntPtrType - > mSize = = 8 )
{
if ( ceIdx1 . mType - > mSize = = 1 )
Emit ( CeOp_Conv_I8_I64 ) ;
else
Emit ( CeOp_Conv_I16_I64 ) ;
}
else
{
if ( ceIdx1 . mType - > mSize = = 1 )
Emit ( CeOp_Conv_I8_I32 ) ;
else
Emit ( CeOp_Conv_I16_I32 ) ;
}
EmitFrameOffset ( ceNewIdx ) ;
EmitFrameOffset ( ceIdx1 ) ;
ceIdx1 = ceNewIdx ;
}
2020-12-17 04:51:05 -08:00
result = FrameAlloc ( elementPtrType ) ;
if ( mPtrSize = = 4 )
{
auto mcElementSize = FrameAlloc ( mIntPtrType ) ;
Emit ( CeOp_Const_32 ) ;
EmitFrameOffset ( mcElementSize ) ;
2021-01-18 14:09:16 -08:00
Emit ( ( int32 ) arrayType - > mElementType - > GetStride ( ) ) ;
2020-12-17 04:51:05 -08:00
auto ofsValue = FrameAlloc ( mIntPtrType ) ;
Emit ( CeOp_Mul_I32 ) ;
EmitFrameOffset ( ofsValue ) ;
EmitFrameOffset ( ceIdx1 ) ;
EmitFrameOffset ( mcElementSize ) ;
Emit ( CeOp_Add_I32 ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( ceVal ) ;
EmitFrameOffset ( ofsValue ) ;
}
else
{
auto mcElementSize = FrameAlloc ( mIntPtrType ) ;
Emit ( CeOp_Const_64 ) ;
EmitFrameOffset ( mcElementSize ) ;
2021-01-18 14:09:16 -08:00
Emit ( ( int64 ) arrayType - > mElementType - > GetStride ( ) ) ;
2020-12-17 04:51:05 -08:00
auto ofsValue = FrameAlloc ( mIntPtrType ) ;
Emit ( CeOp_Mul_I64 ) ;
EmitFrameOffset ( ofsValue ) ;
EmitFrameOffset ( ceIdx1 ) ;
EmitFrameOffset ( mcElementSize ) ;
Emit ( CeOp_Add_I64 ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( ceVal ) ;
EmitFrameOffset ( ofsValue ) ;
}
}
2020-12-14 10:20:44 -08:00
}
else
Fail ( " Invalid GEP " ) ;
2020-12-14 03:50:28 -08:00
}
else
{
2020-12-14 10:20:44 -08:00
BF_ASSERT ( ceIdx1 . IsImmediate ( ) ) ;
2020-12-14 03:50:28 -08:00
int byteOffset = 0 ;
BeType * elementType = NULL ;
if ( ptrType - > mElementType - > mTypeCode = = BeTypeCode_Struct )
{
BeStructType * structType = ( BeStructType * ) ptrType - > mElementType ;
2020-12-14 10:20:44 -08:00
auto & structMember = structType - > mMembers [ ceIdx1 . mImmediate ] ;
2020-12-14 03:50:28 -08:00
elementType = structMember . mType ;
byteOffset = structMember . mByteOffset ;
}
else if ( ptrType - > mElementType - > mTypeCode = = BeTypeCode_SizedArray )
{
auto arrayType = ( BeSizedArrayType * ) ptrType - > mElementType ;
elementType = arrayType - > mElementType ;
2021-01-18 14:09:16 -08:00
byteOffset = ceIdx1 . mImmediate * elementType - > GetStride ( ) ;
2020-12-14 03:50:28 -08:00
}
else if ( ptrType - > mElementType - > mTypeCode = = BeTypeCode_Vector )
{
auto arrayType = ( BeVectorType * ) ptrType - > mElementType ;
elementType = arrayType - > mElementType ;
2021-01-18 14:09:16 -08:00
byteOffset = ceIdx1 . mImmediate * elementType - > GetStride ( ) ;
2020-12-14 03:50:28 -08:00
}
else
{
Fail ( " Invalid gep target " ) ;
}
2020-12-17 04:51:05 -08:00
auto elementPtrType = beModule - > mContext - > GetPointerTo ( elementType ) ;
2020-12-14 03:50:28 -08:00
2020-12-14 10:20:44 -08:00
if ( byteOffset ! = 0 )
{
result = FrameAlloc ( elementPtrType ) ;
2021-01-26 06:33:23 -08:00
EmitSizedOp ( CeOp_AddConst_I8 , mPtrSize ) ;
2020-12-14 10:20:44 -08:00
EmitFrameOffset ( result ) ;
EmitFrameOffset ( ceVal ) ;
Emit ( ( int32 ) byteOffset ) ;
2021-01-26 06:33:23 -08:00
if ( mPtrSize = = 8 )
Emit ( ( int32 ) 0 ) ;
2020-12-14 10:20:44 -08:00
}
else
{
result . mType = elementPtrType ;
}
2020-12-14 03:50:28 -08:00
}
}
else
2020-12-17 04:51:05 -08:00
{
CeOperand mcRelOffset ;
int relScale = 1 ;
if ( ceIdx0 . IsImmediate ( ) )
{
2021-01-18 14:09:16 -08:00
int byteOffset = ceIdx0 . mImmediate * ptrType - > mElementType - > GetStride ( ) ;
2020-12-17 04:51:05 -08:00
if ( byteOffset ! = 0 )
{
result = FrameAlloc ( ptrType ) ;
2021-01-26 06:33:23 -08:00
EmitSizedOp ( CeOp_AddConst_I8 , mPtrSize ) ;
2020-12-17 04:51:05 -08:00
EmitFrameOffset ( result ) ;
EmitFrameOffset ( ceVal ) ;
Emit ( ( int32 ) byteOffset ) ;
2021-01-26 06:33:23 -08:00
if ( mPtrSize = = 8 )
Emit ( ( int32 ) 0 ) ;
2020-12-17 04:51:05 -08:00
}
}
else
{
result = FrameAlloc ( ptrType ) ;
if ( mPtrSize = = 4 )
{
auto mcElementSize = FrameAlloc ( mIntPtrType ) ;
Emit ( CeOp_Const_32 ) ;
EmitFrameOffset ( mcElementSize ) ;
2021-01-18 14:09:16 -08:00
Emit ( ( int32 ) ptrType - > mElementType - > GetStride ( ) ) ;
2020-12-17 04:51:05 -08:00
auto ofsValue = FrameAlloc ( mIntPtrType ) ;
Emit ( CeOp_Mul_I32 ) ;
EmitFrameOffset ( ofsValue ) ;
EmitFrameOffset ( ceIdx0 ) ;
EmitFrameOffset ( mcElementSize ) ;
Emit ( CeOp_Add_I32 ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( ceVal ) ;
EmitFrameOffset ( ofsValue ) ;
}
else
{
auto mcElementSize = FrameAlloc ( mIntPtrType ) ;
Emit ( CeOp_Const_64 ) ;
EmitFrameOffset ( mcElementSize ) ;
2021-01-18 14:09:16 -08:00
Emit ( ( int64 ) ptrType - > mElementType - > GetStride ( ) ) ;
2020-12-17 04:51:05 -08:00
auto ofsValue = FrameAlloc ( mIntPtrType ) ;
Emit ( CeOp_Mul_I64 ) ;
EmitFrameOffset ( ofsValue ) ;
EmitFrameOffset ( ceIdx0 ) ;
EmitFrameOffset ( mcElementSize ) ;
Emit ( CeOp_Add_I64 ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( ceVal ) ;
EmitFrameOffset ( ofsValue ) ;
}
}
2020-12-14 03:50:28 -08:00
}
}
break ;
2020-12-19 14:19:33 -08:00
case BeExtractValueInst : : TypeId :
{
auto castedInst = ( BeExtractValueInst * ) inst ;
BeConstant * constant = BeValueDynCast < BeConstant > ( castedInst - > mAggVal ) ;
CeOperand mcAgg ;
2020-12-22 04:50:37 -08:00
2020-12-19 14:19:33 -08:00
if ( constant ! = NULL )
{
result . mImmediate = 0 ;
BeType * wantDefaultType = NULL ;
if ( constant - > mType - > IsStruct ( ) )
{
BeStructType * structType = ( BeStructType * ) constant - > mType ;
auto & member = structType - > mMembers [ castedInst - > mIdx ] ;
wantDefaultType = member . mType ;
}
else if ( constant - > mType - > IsSizedArray ( ) )
{
BeSizedArrayType * arrayType = ( BeSizedArrayType * ) constant - > mType ;
wantDefaultType = arrayType - > mElementType ;
}
if ( wantDefaultType ! = NULL )
{
// switch (wantDefaultType->mTypeCode)
// {
// case BeTypeCode_Boolean:
// case BeTypeCode_Int8:
// result.mKind = BeMCOperandKind_Immediate_i8;
// break;
// case BeTypeCode_Int16:
// result.mKind = BeMCOperandKind_Immediate_i16;
// break;
// case BeTypeCode_Int32:
// result.mKind = BeMCOperandKind_Immediate_i32;
// break;
// case BeTypeCode_Int64:
// result.mKind = BeMCOperandKind_Immediate_i64;
// break;
// case BeTypeCode_Float:
// result.mKind = BeMCOperandKind_Immediate_f32;
// break;
// case BeTypeCode_Double:
// result.mKind = BeMCOperandKind_Immediate_f64;
// break;
// case BeTypeCode_Pointer:
// result.mKind = BeMCOperandKind_Immediate_Null;
// result.mType = wantDefaultType;
// break;
// case BeTypeCode_Struct:
// case BeTypeCode_SizedArray:
// {
// auto subConst = mAlloc.Alloc<BeConstant>();
// subConst->mType = wantDefaultType;
// result.mConstant = subConst;
// result.mKind = BeMCOperandKind_ConstAgg;
// }
// break;
// default:
// NotImpl();
// }
Fail ( " Unhandled extract " ) ;
}
break ;
}
2020-12-23 08:53:38 -08:00
else
{
mcAgg = GetOperand ( castedInst - > mAggVal ) ;
}
2020-12-19 14:19:33 -08:00
auto aggType = mcAgg . mType ;
int byteOffset = 0 ;
BeType * memberType = NULL ;
if ( aggType - > IsSizedArray ( ) )
{
auto sizedArray = ( BeSizedArrayType * ) aggType ;
memberType = sizedArray - > mElementType ;
2021-01-18 14:09:16 -08:00
byteOffset = memberType - > GetStride ( ) * castedInst - > mIdx ;
2020-12-19 14:19:33 -08:00
}
else
{
BF_ASSERT ( aggType - > IsStruct ( ) ) ;
BeStructType * structType = ( BeStructType * ) aggType ;
auto & structMember = structType - > mMembers [ castedInst - > mIdx ] ;
byteOffset = structMember . mByteOffset ;
memberType = structMember . mType ;
}
if ( byteOffset ! = 0 )
{
auto ptrVal = FrameAlloc ( beModule - > mContext - > GetPrimitiveType ( BeTypeCode_Int32 ) ) ;
Emit ( CeOp_FrameAddrOfs_32 ) ;
EmitFrameOffset ( ptrVal ) ;
EmitFrameOffset ( mcAgg ) ;
Emit ( ( int32 ) byteOffset ) ;
result = FrameAlloc ( memberType ) ;
EmitSizedOp ( CeOp_Load_8 , memberType - > mSize ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( ptrVal ) ;
}
else
{
result = mcAgg ;
result . mType = memberType ;
}
}
break ;
2020-12-13 08:04:42 -08:00
case BeBrInst : : TypeId :
{
auto castedInst = ( BeBrInst * ) inst ;
auto targetBlock = GetOperand ( castedInst - > mTargetBlock ) ;
BF_ASSERT ( targetBlock . mKind = = CeOperandKind_Block ) ;
FlushPhi ( ceBlock , targetBlock . mBlockIdx ) ;
if ( targetBlock . mBlockIdx = = blockIdx + 1 )
{
// Do nothing - just continuing to next block
break ;
}
EmitJump ( CeOp_Jmp , targetBlock ) ;
}
break ;
case BeCondBrInst : : TypeId :
{
auto castedInst = ( BeCondBrInst * ) inst ;
auto testVal = GetOperand ( castedInst - > mCond , true ) ;
auto trueBlock = GetOperand ( castedInst - > mTrueBlock ) ;
auto falseBlock = GetOperand ( castedInst - > mFalseBlock ) ;
FlushPhi ( ceBlock , trueBlock . mBlockIdx ) ;
EmitJump ( CeOp_JmpIf , trueBlock ) ;
EmitFrameOffset ( testVal ) ;
FlushPhi ( ceBlock , falseBlock . mBlockIdx ) ;
EmitJump ( CeOp_Jmp , falseBlock ) ;
}
break ;
case BePhiInst : : TypeId :
result = GetOperand ( inst ) ;
BF_ASSERT ( result ) ;
break ;
case BeNegInst : : TypeId :
{
2020-12-17 04:51:05 -08:00
auto castedInst = ( BeNegInst * ) inst ;
2020-12-13 08:04:42 -08:00
auto ceValue = GetOperand ( castedInst - > mValue ) ;
EmitUnaryOp ( CeOp_Neg_I8 , CeOp_Neg_F32 , ceValue , result ) ;
}
break ;
2020-12-17 04:51:05 -08:00
case BeNotInst : : TypeId :
{
auto castedInst = ( BeNotInst * ) inst ;
auto ceValue = GetOperand ( castedInst - > mValue ) ;
if ( ceValue . mType - > mTypeCode = = BeTypeCode_Boolean )
EmitUnaryOp ( CeOp_Not_I1 , CeOp_InvalidOp , ceValue , result ) ;
else
EmitUnaryOp ( CeOp_Not_I8 , CeOp_InvalidOp , ceValue , result ) ;
}
break ;
2020-12-13 08:04:42 -08:00
case BeSwitchInst : : TypeId :
{
auto castedInst = ( BeSwitchInst * ) inst ;
std : : stable_sort ( castedInst - > mCases . begin ( ) , castedInst - > mCases . end ( ) , [ & ] ( const BeSwitchCase & lhs , const BeSwitchCase & rhs )
{
return lhs . mValue - > mInt64 < rhs . mValue - > mInt64 ;
} ) ;
int numVals = castedInst - > mCases . size ( ) ;
if ( numVals > 0 )
{
EmitBinarySwitchSection ( castedInst , 0 , castedInst - > mCases . size ( ) ) ;
}
auto mcDefaultBlock = GetOperand ( castedInst - > mDefaultBlock ) ;
EmitJump ( CeOp_Jmp , mcDefaultBlock ) ;
}
break ;
case BeCallInst : : TypeId :
{
2020-12-19 14:19:33 -08:00
auto castedInst = ( BeCallInst * ) inst ;
2020-12-13 08:04:42 -08:00
BeType * returnType = NULL ;
bool isVarArg = false ;
bool useAltArgs = false ;
2020-12-19 14:19:33 -08:00
CeOperand ceFunc ;
2020-12-17 04:51:05 -08:00
BeFunctionType * beFuncType = NULL ;
CeOperand virtTarget ;
int ifaceTypeId = - 1 ;
int virtualTableIdx = - 1 ;
2020-12-13 08:04:42 -08:00
if ( auto intrin = BeValueDynCast < BeIntrinsic > ( castedInst - > mFunc ) )
{
2020-12-17 04:51:05 -08:00
switch ( intrin - > mKind )
{
2021-01-26 06:33:23 -08:00
case BfIRIntrinsic_Abs :
EmitUnaryOp ( CeOp_Abs_I8 , CeOp_Abs_F32 , GetOperand ( castedInst - > mArgs [ 0 ] . mValue ) , result ) ;
break ;
2020-12-17 04:51:05 -08:00
case BfIRIntrinsic_Cast :
{
result = GetOperand ( castedInst - > mArgs [ 0 ] . mValue ) ;
result . mType = intrin - > mReturnType ;
}
break ;
case BfIRIntrinsic_MemCpy :
{
CeOperand ceDestPtr = GetOperand ( castedInst - > mArgs [ 0 ] . mValue ) ;
CeOperand ceSrcPtr = GetOperand ( castedInst - > mArgs [ 1 ] . mValue ) ;
CeOperand ceSize = GetOperand ( castedInst - > mArgs [ 2 ] . mValue ) ;
Emit ( CeOp_MemCpy ) ;
EmitFrameOffset ( ceDestPtr ) ;
EmitFrameOffset ( ceSrcPtr ) ;
EmitFrameOffset ( ceSize ) ;
}
break ;
2021-12-11 09:08:42 -08:00
case BfIRIntrinsic_MemSet :
{
CeOperand ceDestPtr = GetOperand ( castedInst - > mArgs [ 0 ] . mValue ) ;
CeOperand ceValue = GetOperand ( castedInst - > mArgs [ 1 ] . mValue ) ;
CeOperand ceSize = GetOperand ( castedInst - > mArgs [ 2 ] . mValue ) ;
2021-01-26 06:33:23 -08:00
2021-12-11 09:08:42 -08:00
Emit ( CeOp_MemSet ) ;
EmitFrameOffset ( ceDestPtr ) ;
EmitFrameOffset ( ceValue ) ;
EmitFrameOffset ( ceSize ) ;
}
break ;
2021-01-26 06:33:23 -08:00
2020-12-19 14:19:33 -08:00
case BfIRIntrinsic_AtomicFence :
// Nothing to do
break ;
2021-01-26 06:33:23 -08:00
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 ;
2020-12-17 04:51:05 -08:00
default :
Emit ( CeOp_Error ) ;
Emit ( ( int32 ) CeErrorKind_Intrinsic ) ;
break ;
}
2020-12-13 08:04:42 -08:00
}
else if ( auto beFunction = BeValueDynCast < BeFunction > ( castedInst - > mFunc ) )
{
2020-12-17 04:51:05 -08:00
beFuncType = beFunction - > GetFuncType ( ) ;
2021-01-26 06:33:23 -08:00
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 ;
}
}
2020-12-17 04:51:05 -08:00
if ( beFunction - > mName = = " malloc " )
{
result = FrameAlloc ( beFuncType - > mReturnType ) ;
auto ceSize = GetOperand ( castedInst - > mArgs [ 0 ] . mValue ) ;
Emit ( CeOp_Malloc ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( ceSize ) ;
break ;
}
if ( beFunction - > mName = = " free " )
{
auto cePtr = GetOperand ( castedInst - > mArgs [ 0 ] . mValue ) ;
Emit ( CeOp_Free ) ;
EmitFrameOffset ( cePtr ) ;
break ;
}
2020-12-19 14:19:33 -08:00
ceFunc = GetOperand ( beFunction , false , true ) ;
2020-12-17 04:51:05 -08:00
}
2021-01-09 04:20:45 -08:00
else if ( auto beGetVirtualFunc = BeValueDynCast < BeComptimeGetVirtualFunc > ( castedInst - > mFunc ) )
2020-12-17 04:51:05 -08:00
{
virtTarget = GetOperand ( beGetVirtualFunc - > mValue ) ;
virtualTableIdx = beGetVirtualFunc - > mVirtualTableIdx ;
auto resultType = beGetVirtualFunc - > GetType ( ) ;
BF_ASSERT ( resultType - > IsPointer ( ) ) ;
beFuncType = ( BeFunctionType * ) ( ( BePointerType * ) resultType ) - > mElementType ;
}
2021-01-09 04:20:45 -08:00
else if ( auto beGetInterfaceFunc = BeValueDynCast < BeComptimeGetInterfaceFunc > ( castedInst - > mFunc ) )
2020-12-17 04:51:05 -08:00
{
virtTarget = GetOperand ( beGetInterfaceFunc - > mValue ) ;
ifaceTypeId = beGetInterfaceFunc - > mIFaceTypeId ;
2020-12-19 14:19:33 -08:00
virtualTableIdx = beGetInterfaceFunc - > mMethodIdx ;
2020-12-17 04:51:05 -08:00
auto resultType = beGetInterfaceFunc - > GetType ( ) ;
BF_ASSERT ( resultType - > IsPointer ( ) ) ;
beFuncType = ( BeFunctionType * ) ( ( BePointerType * ) resultType ) - > mElementType ;
}
else
{
2020-12-19 14:19:33 -08:00
ceFunc = GetOperand ( castedInst - > mFunc , false , true ) ;
auto funcType = castedInst - > mFunc - > GetType ( ) ;
if ( funcType - > IsPointer ( ) )
{
auto ptrType = ( BePointerType * ) funcType ;
if ( ptrType - > mElementType - > mTypeCode = = BeTypeCode_Function )
{
beFuncType = ( BeFunctionType * ) ptrType - > mElementType ;
}
}
2020-12-17 04:51:05 -08:00
}
2020-12-13 08:04:42 -08:00
2020-12-19 14:19:33 -08:00
if ( ( ceFunc ) | | ( virtualTableIdx ! = - 1 ) )
2020-12-17 04:51:05 -08:00
{
CeOperand thisOperand ;
2020-12-13 08:04:42 -08:00
2021-01-26 06:33:23 -08:00
int stackAdjust = 0 ;
2020-12-14 03:50:28 -08:00
for ( int argIdx = ( int ) castedInst - > mArgs . size ( ) - 1 ; argIdx > = 0 ; argIdx - - )
{
auto & arg = castedInst - > mArgs [ argIdx ] ;
auto ceArg = GetOperand ( arg . mValue ) ;
2020-12-17 04:51:05 -08:00
if ( argIdx = = 0 )
thisOperand = ceArg ;
2020-12-14 03:50:28 -08:00
EmitSizedOp ( CeOp_Push_8 , ceArg , NULL , true ) ;
2021-01-26 06:33:23 -08:00
stackAdjust + = ceArg . mType - > mSize ;
2020-12-14 03:50:28 -08:00
}
2020-12-13 08:04:42 -08:00
if ( beFuncType - > mReturnType - > mSize > 0 )
{
2020-12-17 04:51:05 -08:00
Emit ( CeOp_AdjustSPConst ) ;
2021-01-26 06:33:23 -08:00
Emit ( ( int32 ) - beFuncType - > mReturnType - > mSize ) ;
2020-12-13 08:04:42 -08:00
}
2020-12-17 04:51:05 -08:00
2020-12-19 14:19:33 -08:00
if ( ! ceFunc )
ceFunc = FrameAlloc ( beModule - > mContext - > GetPrimitiveType ( ( sizeof ( BfMethodInstance * ) = = 8 ) ? BeTypeCode_Int64 : BeTypeCode_Int32 ) ) ;
2020-12-17 04:51:05 -08:00
if ( ifaceTypeId ! = - 1 )
{
2020-12-19 14:19:33 -08:00
Emit ( CeOp_GetMethod_IFace ) ;
EmitFrameOffset ( ceFunc ) ;
2020-12-17 04:51:05 -08:00
EmitFrameOffset ( thisOperand ) ;
Emit ( ( int32 ) ifaceTypeId ) ;
Emit ( ( int32 ) virtualTableIdx ) ;
}
else if ( virtualTableIdx ! = - 1 )
{
2020-12-19 14:19:33 -08:00
Emit ( CeOp_GetMethod_Virt ) ;
EmitFrameOffset ( ceFunc ) ;
2020-12-17 04:51:05 -08:00
EmitFrameOffset ( thisOperand ) ;
Emit ( ( int32 ) virtualTableIdx ) ;
}
2020-12-19 14:19:33 -08:00
if ( ceFunc . mKind = = CeOperandKind_CallTableIdx )
2020-12-17 04:51:05 -08:00
{
2020-12-19 14:19:33 -08:00
CeOperand result = FrameAlloc ( mCeMachine - > GetBeContext ( ) - > GetPrimitiveType ( ( sizeof ( BfMethodInstance * ) = = 8 ) ? BeTypeCode_Int64 : BeTypeCode_Int32 ) ) ;
Emit ( CeOp_GetMethod ) ;
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) ceFunc . mCallTableIdx ) ;
ceFunc = result ;
2020-12-17 04:51:05 -08:00
}
2020-12-13 08:04:42 -08:00
2020-12-19 14:19:33 -08:00
Emit ( CeOp_Call ) ;
EmitFrameOffset ( ceFunc ) ;
2020-12-14 03:50:28 -08:00
if ( beFuncType - > mReturnType - > mSize > 0 )
{
result = FrameAlloc ( beFuncType - > mReturnType ) ;
EmitSizedOp ( CeOp_Pop_8 , result , NULL , true ) ;
}
2020-12-13 08:04:42 -08:00
if ( stackAdjust > 0 )
{
2020-12-17 04:51:05 -08:00
Emit ( CeOp_AdjustSPConst ) ;
2020-12-13 08:04:42 -08:00
Emit ( stackAdjust ) ;
}
}
2020-12-17 04:51:05 -08:00
}
break ;
case BeMemSetInst : : TypeId :
{
auto castedInst = ( BeMemSetInst * ) inst ;
auto ceAddr = GetOperand ( castedInst - > mAddr ) ;
if ( auto constVal = BeValueDynCast < BeConstant > ( castedInst - > mVal ) )
2020-12-13 08:04:42 -08:00
{
2020-12-17 04:51:05 -08:00
if ( auto constSize = BeValueDynCast < BeConstant > ( castedInst - > mSize ) )
{
if ( constVal - > mUInt8 = = 0 )
{
Emit ( CeOp_MemSet_Const ) ;
EmitFrameOffset ( ceAddr ) ;
Emit ( ( uint8 ) 0 ) ;
Emit ( ( int32 ) constSize - > mUInt32 ) ;
break ;
}
}
}
auto ceVal = GetOperand ( castedInst - > mVal ) ;
auto ceSize = GetOperand ( castedInst - > mSize ) ;
Emit ( CeOp_MemSet ) ;
EmitFrameOffset ( ceAddr ) ;
EmitFrameOffset ( ceVal ) ;
EmitFrameOffset ( ceSize ) ;
}
break ;
case BeFenceInst : : TypeId :
break ;
case BeStackSaveInst : : TypeId :
{
result = FrameAlloc ( mIntPtrType ) ;
Emit ( CeOp_GetSP ) ;
EmitFrameOffset ( result ) ;
}
break ;
case BeStackRestoreInst : : TypeId :
{
auto castedInst = ( BeStackRestoreInst * ) inst ;
auto mcStackVal = GetOperand ( castedInst - > mStackVal ) ;
Emit ( CeOp_SetSP ) ;
EmitFrameOffset ( mcStackVal ) ;
}
break ;
2021-01-26 06:33:23 -08:00
case BeComptimeError : : TypeId :
{
auto castedInst = ( BeComptimeError * ) inst ;
Emit ( CeOp_Error ) ;
Emit ( castedInst - > mError ) ;
}
break ;
2021-01-09 04:20:45 -08:00
case BeComptimeGetType : : TypeId :
2020-12-17 04:51:05 -08:00
{
2021-01-09 04:20:45 -08:00
auto castedInst = ( BeComptimeGetType * ) inst ;
2020-12-17 04:51:05 -08:00
result . mKind = CeOperandKind_Immediate ;
result . mImmediate = castedInst - > mTypeId ;
result . mType = beModule - > mContext - > GetPrimitiveType ( BeTypeCode_Int32 ) ;
}
break ;
2021-01-09 04:20:45 -08:00
case BeComptimeGetReflectType : : TypeId :
2020-12-19 14:19:33 -08:00
{
2021-01-09 04:20:45 -08:00
auto castedInst = ( BeComptimeGetReflectType * ) inst ;
2020-12-19 14:19:33 -08:00
auto ptrType = beModule - > mContext - > GetVoidPtrType ( ) ;
result = FrameAlloc ( ptrType ) ;
Emit ( CeOp_GetReflectType ) ;
EmitFrameOffset ( result ) ;
Emit ( ( int32 ) castedInst - > mTypeId ) ;
}
break ;
2021-01-09 04:20:45 -08:00
case BeComptimeDynamicCastCheck : : TypeId :
2020-12-17 04:51:05 -08:00
{
2021-01-09 04:20:45 -08:00
auto castedInst = ( BeComptimeDynamicCastCheck * ) inst ;
2020-12-17 04:51:05 -08:00
auto mcValue = GetOperand ( castedInst - > mValue ) ;
2020-12-19 14:19:33 -08:00
auto ptrType = beModule - > mContext - > GetVoidPtrType ( ) ;
2020-12-17 04:51:05 -08:00
result = FrameAlloc ( ptrType ) ;
Emit ( CeOp_DynamicCastCheck ) ;
EmitFrameOffset ( result ) ;
EmitFrameOffset ( mcValue ) ;
Emit ( ( int32 ) castedInst - > mTypeId ) ;
2020-12-13 08:04:42 -08:00
}
break ;
default :
Fail ( " Unhandled instruction " ) ;
return ;
}
if ( result . mKind ! = CeOperandKind_None )
mValueToOperand [ inst ] = result ;
if ( ( startCodePos ! = GetCodePos ( ) ) & & ( prevEmitDbgPos ! = mCurDbgLoc ) )
{
prevEmitDbgPos = mCurDbgLoc ;
int fileIdx = - 1 ;
BeDbgFile * dbgFile = NULL ;
if ( mCurDbgLoc ! = NULL )
{
auto dbgFile = mCurDbgLoc - > GetDbgFile ( ) ;
int * valuePtr = NULL ;
if ( mDbgFileMap . TryAdd ( dbgFile , NULL , & valuePtr ) )
{
fileIdx = ( int ) mCeFunction - > mFiles . size ( ) ;
2020-12-17 04:51:05 -08:00
String filePath = dbgFile - > mDirectory ;
filePath . Append ( DIR_SEP_CHAR ) ;
filePath + = dbgFile - > mFileName ;
mCeFunction - > mFiles . Add ( filePath ) ;
2020-12-13 08:04:42 -08:00
* valuePtr = fileIdx ;
}
else
fileIdx = * valuePtr ;
}
CeEmitEntry emitEntry ;
emitEntry . mCodePos = startCodePos ;
emitEntry . mFile = fileIdx ;
if ( mCurDbgLoc ! = NULL )
{
emitEntry . mLine = mCurDbgLoc - > mLine ;
emitEntry . mColumn = mCurDbgLoc - > mColumn ;
}
else
{
emitEntry . mLine = - 1 ;
emitEntry . mColumn = - 1 ;
}
mCeFunction - > mEmitTable . Add ( emitEntry ) ;
}
}
}
for ( auto & jumpEntry : mJumpTable )
{
auto & ceBlock = mBlocks [ jumpEntry . mBlockIdx ] ;
* ( ( int32 * ) ( & mCeFunction - > mCode [ 0 ] + jumpEntry . mEmitPos ) ) = ceBlock . mEmitOfs - jumpEntry . mEmitPos - 4 ;
}
2020-12-14 10:20:44 -08:00
if ( mCeFunction - > mCode . size ( ) = = 0 )
{
Fail ( " No method definition available " ) ;
return ;
}
2020-12-13 08:04:42 -08:00
2020-12-14 10:20:44 -08:00
if ( mCeFunction - > mGenError . IsEmpty ( ) )
mCeFunction - > mFailed = false ;
mCeFunction - > mFrameSize = mFrameSize ;
2020-12-13 08:04:42 -08:00
}
//////////////////////////////////////////////////////////////////////////
2021-01-11 09:41:43 -08:00
CeContext : : CeContext ( )
2020-12-13 08:04:42 -08:00
{
2021-11-26 08:59:46 -08:00
mPrevContext = NULL ;
2021-01-08 16:21:03 -08:00
mCurEvalFlags = CeEvalFlags_None ;
2021-01-11 09:41:43 -08:00
mCeMachine = NULL ;
mReflectTypeIdOffset = - 1 ;
mExecuteId = - 1 ;
2021-12-20 15:07:38 -05:00
mStackSize = - 1 ;
2021-01-11 09:41:43 -08:00
mCurTargetSrc = NULL ;
mHeap = new ContiguousHeap ( ) ;
2021-01-08 16:21:03 -08:00
mCurFrame = NULL ;
2020-12-14 03:50:28 -08:00
mCurModule = NULL ;
2020-12-23 08:53:38 -08:00
mCurMethodInstance = NULL ;
2020-12-22 04:50:37 -08:00
mCurExpectingType = NULL ;
2021-01-08 16:21:03 -08:00
mCurEmitContext = NULL ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
CeContext : : ~ CeContext ( )
2020-12-13 08:04:42 -08:00
{
2020-12-17 04:51:05 -08:00
delete mHeap ;
2021-12-20 09:39:39 -05:00
BF_ASSERT ( mInternalDataMap . IsEmpty ( ) ) ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
BfError * CeContext : : Fail ( const StringImpl & error )
2020-12-22 04:50:37 -08:00
{
2021-11-26 08:59:46 -08:00
if ( mCurEmitContext ! = NULL )
mCurEmitContext - > mFailed = true ;
2021-01-08 16:21:03 -08:00
auto bfError = mCurModule - > Fail ( StrFormat ( " Unable to comptime %s " , mCurModule - > MethodToString ( mCurMethodInstance ) . c_str ( ) ) , mCurTargetSrc , ( mCurEvalFlags & CeEvalFlags_PersistantError ) ! = 0 ) ;
2020-12-22 04:50:37 -08:00
if ( bfError = = NULL )
return NULL ;
2021-01-13 05:09:09 -08:00
mCeMachine - > mCompiler - > mPassInstance - > MoreInfo ( error , mCeMachine - > mCompiler - > GetAutoComplete ( ) ! = NULL ) ;
2020-12-22 04:50:37 -08:00
return bfError ;
}
2021-01-11 09:41:43 -08:00
BfError * CeContext : : Fail ( const CeFrame & curFrame , const StringImpl & str )
2020-12-14 03:50:28 -08:00
{
2021-11-26 08:59:46 -08:00
if ( mCurEmitContext ! = NULL )
mCurEmitContext - > mFailed = true ;
2021-01-11 09:41:43 -08:00
auto bfError = mCurModule - > Fail ( StrFormat ( " Unable to comptime %s " , mCurModule - > MethodToString ( mCurMethodInstance ) . c_str ( ) ) , mCurTargetSrc ,
( mCurEvalFlags & CeEvalFlags_PersistantError ) ! = 0 ,
( ( mCurEvalFlags & CeEvalFlags_DeferIfNotOnlyError ) ! = 0 ) & & ! mCurModule - > mHadBuildError ) ;
2020-12-17 04:51:05 -08:00
if ( bfError = = NULL )
return NULL ;
2021-01-11 09:41:43 -08:00
auto passInstance = mCeMachine - > mCompiler - > mPassInstance ;
2020-12-17 04:51:05 -08:00
for ( int stackIdx = mCallStack . size ( ) ; stackIdx > = 0 ; stackIdx - - )
{
bool isHeadEntry = stackIdx = = mCallStack . size ( ) ;
auto * ceFrame = ( isHeadEntry ) ? & curFrame : & mCallStack [ stackIdx ] ;
auto ceFunction = ceFrame - > mFunction ;
int i = 0 ;
CeEmitEntry * emitEntry = NULL ;
if ( ! ceFunction - > mCode . IsEmpty ( ) )
{
int lo = 0 ;
int hi = ceFunction - > mEmitTable . size ( ) - 1 ;
int instIdx = ceFrame - > mInstPtr - & ceFunction - > mCode [ 0 ] - 1 ;
while ( lo < = hi )
{
i = ( lo + hi ) / 2 ;
emitEntry = & ceFunction - > mEmitTable . mVals [ i ] ;
//int c = midVal <=> value;
if ( emitEntry - > mCodePos = = instIdx ) break ;
if ( emitEntry - > mCodePos < instIdx )
lo = i + 1 ;
else
hi = i - 1 ;
}
if ( ( emitEntry ! = NULL ) & & ( emitEntry - > mCodePos > instIdx ) & & ( i > 0 ) )
emitEntry = & ceFunction - > mEmitTable . mVals [ i - 1 ] ;
}
StringT < 256 > err ;
if ( isHeadEntry )
2020-12-19 14:19:33 -08:00
{
2020-12-17 04:51:05 -08:00
err = str ;
2020-12-19 14:19:33 -08:00
err + = " " ;
}
2021-01-05 05:55:41 -08:00
auto contextMethodInstance = mCurModule - > mCurMethodInstance ;
if ( stackIdx > 1 )
{
auto func = mCallStack [ stackIdx - 1 ] . mFunction ;
contextMethodInstance = func - > mCeFunctionInfo - > mMethodInstance ;
}
2021-01-08 16:21:03 -08:00
err + = StrFormat ( " in comptime " ) ;
2021-01-05 05:55:41 -08:00
//
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
SetAndRestoreValue < BfTypeInstance * > prevTypeInstance ( mCeMachine - > mCeModule - > mCurTypeInstance , ( contextMethodInstance ! = NULL ) ? contextMethodInstance - > GetOwner ( ) : NULL ) ;
SetAndRestoreValue < BfMethodInstance * > prevMethodInstance ( mCeMachine - > mCeModule - > mCurMethodInstance , contextMethodInstance ) ;
2021-01-05 05:55:41 -08:00
if ( ceFunction - > mMethodInstance ! = NULL )
2021-01-11 09:41:43 -08:00
err + = mCeMachine - > mCeModule - > MethodToString ( ceFunction - > mMethodInstance , BfMethodNameFlag_OmitParams ) ;
2021-01-05 05:55:41 -08:00
else
{
2021-01-11 09:41:43 -08:00
err + = mCeMachine - > mCeModule - > MethodToString ( ceFunction - > mCeInnerFunctionInfo - > mOwner - > mMethodInstance , BfMethodNameFlag_OmitParams ) ;
2021-01-05 05:55:41 -08:00
}
2020-12-17 04:51:05 -08:00
}
2021-05-18 11:06:40 +02:00
2021-01-26 06:33:23 -08:00
if ( ( emitEntry ! = NULL ) & & ( emitEntry - > mFile ! = - 1 ) )
2021-05-18 11:06:40 +02:00
{
2020-12-17 04:51:05 -08:00
err + = StrFormat ( " at line% d:%d in %s " , emitEntry - > mLine + 1 , emitEntry - > mColumn + 1 , ceFunction - > mFiles [ emitEntry - > mFile ] . c_str ( ) ) ;
2021-05-18 11:06:40 +02:00
auto moreInfo = passInstance - > MoreInfo ( err , mCeMachine - > mCeModule - > mCompiler - > GetAutoComplete ( ) ! = NULL ) ;
if ( ( moreInfo ! = NULL ) )
{
BfErrorLocation * location = new BfErrorLocation ( ) ;
location - > mFile = ceFunction - > mFiles [ emitEntry - > mFile ] ;
location - > mLine = emitEntry - > mLine ;
location - > mColumn = emitEntry - > mColumn ;
moreInfo - > mLocation = location ;
}
}
2021-11-26 08:59:46 -08:00
else
{
auto moreInfo = passInstance - > MoreInfo ( err , mCeMachine - > mCeModule - > mCompiler - > GetAutoComplete ( ) ! = NULL ) ;
}
2020-12-17 04:51:05 -08:00
}
return bfError ;
2020-12-14 03:50:28 -08:00
}
2021-01-11 09:41:43 -08:00
//////////////////////////////////////////////////////////////////////////
2020-12-13 08:04:42 -08:00
2021-12-31 06:28:25 -05:00
void CeContext : : FixProjectRelativePath ( StringImpl & path )
{
BfProject * activeProject = NULL ;
auto activeTypeDef = mCurModule - > GetActiveTypeDef ( ) ;
if ( activeTypeDef ! = NULL )
activeProject = activeTypeDef - > mProject ;
if ( activeProject ! = NULL )
path = GetAbsPath ( path , activeProject - > mDirectory ) ;
}
2020-12-13 08:04:42 -08:00
2021-12-29 10:07:36 -05:00
bool CeContext : : AddRebuild ( const CeRebuildKey & key , const CeRebuildValue & value )
2021-12-20 09:39:39 -05:00
{
if ( mCurModule = = NULL )
2021-12-29 10:07:36 -05:00
return false ;
2021-12-20 09:39:39 -05:00
if ( mCurModule - > mCurTypeInstance = = NULL )
2021-12-29 10:07:36 -05:00
return false ;
if ( ( mCurEvalFlags & CeEvalFlags_NoRebuild ) ! = 0 )
return false ;
2021-12-20 09:39:39 -05:00
if ( mCurModule - > mCurTypeInstance - > mCeTypeInfo = = NULL )
mCurModule - > mCurTypeInstance - > mCeTypeInfo = new BfCeTypeInfo ( ) ;
mCurModule - > mCurTypeInstance - > mCeTypeInfo - > mRebuildMap [ key ] = value ;
2021-12-20 09:52:29 -05:00
mCurModule - > mCompiler - > mHasComptimeRebuilds = true ;
2021-12-29 10:07:36 -05:00
return true ;
}
void CeContext : : AddFileRebuild ( const StringImpl & path )
{
auto timeStamp = BfpFile_GetTime_LastWrite ( path . c_str ( ) ) ;
if ( timeStamp ! = 0 )
{
String fixedPath = FixPathAndCase ( path ) ;
CeRebuildKey rebuildKey ;
rebuildKey . mKind = CeRebuildKey : : Kind_File ;
rebuildKey . mString = fixedPath ;
CeRebuildValue rebuildValue ;
rebuildValue . mInt = timeStamp ;
if ( AddRebuild ( rebuildKey , rebuildValue ) )
mCurModule - > mCompiler - > mRebuildFileSet . Add ( fixedPath ) ;
}
2021-12-20 09:39:39 -05:00
}
2021-01-11 09:41:43 -08:00
uint8 * CeContext : : CeMalloc ( int size )
2020-12-17 04:51:05 -08:00
{
# ifdef CE_ENABLE_HEAP
auto heapRef = mHeap - > Alloc ( size ) ;
2021-12-20 15:07:38 -05:00
auto ceAddr = mStackSize + heapRef ;
2020-12-17 04:51:05 -08:00
int sizeDelta = ( ceAddr + size ) - mMemory . mSize ;
if ( sizeDelta > 0 )
mMemory . GrowUninitialized ( sizeDelta ) ;
return mMemory . mVals + ceAddr ;
# else
return mMemory . GrowUninitialized ( size ) ;
# endif
}
2021-01-11 09:41:43 -08:00
bool CeContext : : CeFree ( addr_ce addr )
2020-12-17 04:51:05 -08:00
{
# ifdef CE_ENABLE_HEAP
2021-12-20 15:07:38 -05:00
ContiguousHeap : : AllocRef heapRef = addr - mStackSize ;
2020-12-17 04:51:05 -08:00
return mHeap - > Free ( heapRef ) ;
# else
return true ;
# endif
}
2021-01-11 09:41:43 -08:00
addr_ce CeContext : : CeAllocArray ( BfArrayType * arrayType , int count , addr_ce & elemsAddr )
2020-12-23 08:53:38 -08:00
{
2021-01-11 09:41:43 -08:00
mCeMachine - > mCeModule - > PopulateType ( arrayType ) ;
2020-12-23 08:53:38 -08:00
BfType * elemType = arrayType - > GetUnderlyingType ( ) ;
auto countOffset = arrayType - > mBaseType - > mFieldInstances [ 0 ] . mDataOffset ;
auto elemOffset = arrayType - > mFieldInstances [ 0 ] . mDataOffset ;
int allocSize = elemOffset + elemType - > GetStride ( ) * count ;
uint8 * mem = CeMalloc ( allocSize ) ;
memset ( mem , 0 , allocSize ) ;
* ( int32 * ) ( mem ) = arrayType - > mTypeId ;
* ( int32 * ) ( mem + countOffset ) = count ;
elemsAddr = ( addr_ce ) ( mem + elemOffset - mMemory . mVals ) ;
return ( addr_ce ) ( mem - mMemory . mVals ) ;
}
2021-01-11 09:41:43 -08:00
addr_ce CeContext : : GetConstantData ( BeConstant * constant )
2020-12-19 14:19:33 -08:00
{
auto writeConstant = constant ;
if ( auto gvConstant = BeValueDynCast < BeGlobalVariable > ( writeConstant ) )
{
if ( gvConstant - > mInitializer ! = NULL )
writeConstant = gvConstant - > mInitializer ;
}
2020-12-22 04:50:37 -08:00
CeConstStructData structData ;
2021-01-11 09:41:43 -08:00
auto result = mCeMachine - > WriteConstant ( structData , writeConstant , this ) ;
2020-12-19 14:19:33 -08:00
BF_ASSERT ( result = = CeErrorKind_None ) ;
2020-12-22 04:50:37 -08:00
uint8 * ptr = CeMalloc ( structData . mData . mSize ) ;
memcpy ( ptr , structData . mData . mVals , structData . mData . mSize ) ;
2020-12-19 14:19:33 -08:00
return ( addr_ce ) ( ptr - mMemory . mVals ) ;
}
2021-01-11 09:41:43 -08:00
addr_ce CeContext : : GetReflectType ( int typeId )
2020-12-19 14:19:33 -08:00
{
addr_ce * addrPtr = NULL ;
if ( ! mReflectMap . TryAdd ( typeId , NULL , & addrPtr ) )
return * addrPtr ;
2021-01-11 09:41:43 -08:00
auto ceModule = mCeMachine - > mCeModule ;
SetAndRestoreValue < bool > ignoreWrites ( ceModule - > mBfIRBuilder - > mIgnoreWrites , false ) ;
2021-01-05 05:55:41 -08:00
2021-01-11 09:41:43 -08:00
if ( ceModule - > mContext - > mBfTypeType = = NULL )
ceModule - > mContext - > ReflectInit ( ) ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
if ( ( uintptr ) typeId > = ( uintptr ) mCeMachine - > mCeModule - > mContext - > mTypes . mSize )
2020-12-19 14:19:33 -08:00
return 0 ;
2021-01-11 09:41:43 -08:00
auto bfType = mCeMachine - > mCeModule - > mContext - > mTypes [ typeId ] ;
2020-12-19 14:19:33 -08:00
if ( bfType = = NULL )
return 0 ;
2021-01-08 16:21:03 -08:00
if ( bfType - > mDefineState ! = BfTypeDefineState_CETypeInit )
2021-01-11 09:41:43 -08:00
ceModule - > PopulateType ( bfType , BfPopulateType_DataAndMethods ) ;
2020-12-19 14:19:33 -08:00
Dictionary < int , int > usedStringMap ;
2021-01-16 12:35:51 -08:00
auto irData = ceModule - > CreateTypeData ( bfType , usedStringMap , true , true , true , false ) ;
2020-12-19 14:19:33 -08:00
BeValue * beValue = NULL ;
2021-01-11 09:41:43 -08:00
if ( auto constant = mCeMachine - > mCeModule - > mBfIRBuilder - > GetConstant ( irData ) )
2021-01-16 12:35:51 -08:00
{
2020-12-19 14:19:33 -08:00
if ( constant - > mConstType = = BfConstType_BitCast )
{
auto bitcast = ( BfConstantBitCast * ) constant ;
2021-01-11 09:41:43 -08:00
constant = mCeMachine - > mCeModule - > mBfIRBuilder - > GetConstantById ( bitcast - > mTarget ) ;
2020-12-19 14:19:33 -08:00
}
if ( constant - > mConstType = = BfConstType_GlobalVar )
{
auto globalVar = ( BfGlobalVar * ) constant ;
2021-01-11 09:41:43 -08:00
beValue = mCeMachine - > mCeModule - > mBfIRBuilder - > mBeIRCodeGen - > GetBeValue ( globalVar - > mStreamId ) ;
2021-01-16 12:35:51 -08:00
}
2020-12-19 14:19:33 -08:00
}
2021-01-16 12:35:51 -08:00
if ( auto constant = BeValueDynCast < BeConstant > ( beValue ) )
2020-12-19 14:19:33 -08:00
* addrPtr = GetConstantData ( constant ) ;
2021-01-16 12:35:51 -08:00
// We need to 'get' again because we might have resized
2020-12-19 14:19:33 -08:00
return * addrPtr ;
}
2021-01-11 09:41:43 -08:00
addr_ce CeContext : : GetReflectType ( const String & typeName )
{
if ( mCeMachine - > mTempParser = = NULL )
{
mCeMachine - > mTempPassInstance = new BfPassInstance ( mCeMachine - > mCompiler - > mSystem ) ;
mCeMachine - > mTempParser = new BfParser ( mCeMachine - > mCompiler - > mSystem ) ;
mCeMachine - > mTempParser - > mIsEmitted = true ;
mCeMachine - > mTempParser - > SetSource ( NULL , 4096 ) ;
mCeMachine - > mTempReducer = new BfReducer ( ) ;
mCeMachine - > mTempReducer - > mPassInstance = mCeMachine - > mTempPassInstance ;
mCeMachine - > mTempReducer - > mSource = mCeMachine - > mTempParser ;
mCeMachine - > mTempReducer - > mAlloc = mCeMachine - > mTempParser - > mAlloc ;
mCeMachine - > mTempReducer - > mSystem = mCeMachine - > mCompiler - > mSystem ;
}
int copyLen = BF_MIN ( typeName . mLength , 4096 ) ;
memcpy ( ( char * ) mCeMachine - > mTempParser - > mSrc , typeName . c_str ( ) , copyLen ) ;
( ( char * ) mCeMachine - > mTempParser - > mSrc ) [ copyLen ] = 0 ;
mCeMachine - > mTempParser - > mSrcLength = typeName . mLength ;
mCeMachine - > mTempParser - > mSrcIdx = 0 ;
mCeMachine - > mTempParser - > Parse ( mCeMachine - > mTempPassInstance ) ;
BfType * type = NULL ;
if ( mCeMachine - > mTempParser - > mRootNode - > mChildArr . mSize > 0 )
{
mCeMachine - > mTempReducer - > mVisitorPos = BfReducer : : BfVisitorPos ( mCeMachine - > mTempParser - > mRootNode ) ;
mCeMachine - > mTempReducer - > mVisitorPos . mReadPos = 0 ;
auto typeRef = mCeMachine - > mTempReducer - > CreateTypeRef ( mCeMachine - > mTempParser - > mRootNode - > mChildArr [ 0 ] ) ;
if ( ( mCeMachine - > mTempPassInstance - > mErrors . mSize = = 0 ) & & ( mCeMachine - > mTempReducer - > mVisitorPos . mReadPos = = mCeMachine - > mTempParser - > mRootNode - > mChildArr . mSize - 1 ) )
{
SetAndRestoreValue < bool > prevIgnoreErrors ( mCeMachine - > mCeModule - > mIgnoreErrors , true ) ;
type = mCeMachine - > mCeModule - > ResolveTypeRefAllowUnboundGenerics ( typeRef , BfPopulateType_Identity ) ;
}
}
mCeMachine - > mTempPassInstance - > ClearErrors ( ) ;
if ( type = = NULL )
return 0 ;
return GetReflectType ( type - > mTypeId ) ;
}
int CeContext : : GetTypeIdFromType ( addr_ce typeAddr )
{
if ( ! CheckMemory ( typeAddr , 8 ) )
return 0 ;
if ( mReflectTypeIdOffset = = - 1 )
{
auto typeTypeInst = mCeMachine - > mCeModule - > ResolveTypeDef ( mCeMachine - > mCompiler - > mTypeTypeDef ) - > ToTypeInstance ( ) ;
auto typeIdField = typeTypeInst - > mTypeDef - > GetFieldByName ( " mTypeId " ) ;
mReflectTypeIdOffset = typeTypeInst - > mFieldInstances [ typeIdField - > mIdx ] . mDataOffset ;
}
return * ( int32 * ) ( mMemory . mVals + typeAddr + mReflectTypeIdOffset ) ;
}
addr_ce CeContext : : GetReflectSpecializedType ( addr_ce unspecializedTypeAddr , addr_ce typeArgsSpanAddr )
{
BfType * unspecializedType = GetBfType ( GetTypeIdFromType ( unspecializedTypeAddr ) ) ;
if ( unspecializedType = = NULL )
return 0 ;
BfTypeInstance * unspecializedTypeInst = unspecializedType - > ToGenericTypeInstance ( ) ;
if ( unspecializedType = = NULL )
return 0 ;
int ptrSize = mCeMachine - > mCompiler - > mSystem - > mPtrSize ;
if ( ! CheckMemory ( typeArgsSpanAddr , ptrSize * 2 ) )
return 0 ;
addr_ce spanPtr = * ( addr_ce * ) ( mMemory . mVals + typeArgsSpanAddr ) ;
int32 spanSize = * ( int32 * ) ( mMemory . mVals + typeArgsSpanAddr + ptrSize ) ;
if ( spanSize < 0 )
return 0 ;
if ( ! CheckMemory ( spanPtr , spanSize * ptrSize ) )
return 0 ;
Array < BfType * > typeGenericArgs ;
for ( int argIdx = 0 ; argIdx < spanSize ; argIdx + + )
{
addr_ce argPtr = * ( addr_ce * ) ( mMemory . mVals + spanPtr + argIdx * ptrSize ) ;
BfType * typeGenericArg = GetBfType ( GetTypeIdFromType ( argPtr ) ) ;
if ( typeGenericArg = = NULL )
return 0 ;
typeGenericArgs . Add ( typeGenericArg ) ;
}
SetAndRestoreValue < bool > prevIgnoreErrors ( mCeMachine - > mCeModule - > mIgnoreErrors , true ) ;
auto specializedType = mCeMachine - > mCeModule - > ResolveTypeDef ( unspecializedTypeInst - > mTypeDef , typeGenericArgs , BfPopulateType_Identity ) ;
if ( specializedType = = NULL )
return 0 ;
return GetReflectType ( specializedType - > mTypeId ) ;
}
addr_ce CeContext : : GetString ( int stringId )
2020-12-19 14:19:33 -08:00
{
addr_ce * ceAddrPtr = NULL ;
if ( ! mStringMap . TryAdd ( stringId , NULL , & ceAddrPtr ) )
return * ceAddrPtr ;
2021-01-11 09:41:43 -08:00
BfTypeInstance * stringTypeInst = ( BfTypeInstance * ) mCeMachine - > mCeModule - > ResolveTypeDef ( mCeMachine - > mCompiler - > mStringTypeDef , BfPopulateType_Data ) ;
2020-12-19 14:19:33 -08:00
String str ;
BfStringPoolEntry * entry = NULL ;
2021-01-11 09:41:43 -08:00
if ( mCeMachine - > mCeModule - > mContext - > mStringObjectIdMap . TryGetValue ( stringId , & entry ) )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
entry - > mLastUsedRevision = mCeMachine - > mCompiler - > mRevision ;
2020-12-19 14:19:33 -08:00
str = entry - > mString ;
}
int allocSize = stringTypeInst - > mInstSize + ( int ) str . length ( ) + 1 ;
2021-01-11 09:41:43 -08:00
int charsOffset = stringTypeInst - > mInstSize ;
2020-12-19 14:19:33 -08:00
uint8 * mem = CeMalloc ( allocSize ) ;
memset ( mem , 0 , allocSize ) ;
auto lenByteCount = stringTypeInst - > mFieldInstances [ 0 ] . mResolvedType - > mSize ;
auto lenOffset = stringTypeInst - > mFieldInstances [ 0 ] . mDataOffset ;
auto allocSizeOffset = stringTypeInst - > mFieldInstances [ 1 ] . mDataOffset ;
auto ptrOffset = stringTypeInst - > mFieldInstances [ 2 ] . mDataOffset ;
// Write TypeId into there
* ( int32 * ) ( mem ) = stringTypeInst - > mTypeId ;
* ( int32 * ) ( mem + lenOffset ) = ( int ) str . length ( ) ;
if ( lenByteCount = = 4 )
* ( int32 * ) ( mem + allocSizeOffset ) = 0x40000000 + ( int ) str . length ( ) + 1 ;
else
* ( int64 * ) ( mem + allocSizeOffset ) = 0x4000000000000000LL + ( int ) str . length ( ) + 1 ;
* ( int32 * ) ( mem + ptrOffset ) = ( mem + charsOffset ) - mMemory . mVals ;
memcpy ( mem + charsOffset , str . c_str ( ) , str . length ( ) ) ;
* ceAddrPtr = mem - mMemory . mVals ;
return * ceAddrPtr ;
}
2021-01-13 05:09:09 -08:00
addr_ce CeContext : : GetString ( const StringImpl & str )
{
int stringId = mCeMachine - > mCeModule - > mContext - > GetStringLiteralId ( str ) ;
return GetString ( stringId ) ;
}
2021-01-11 09:41:43 -08:00
BfType * CeContext : : GetBfType ( int typeId )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
if ( ( uintptr ) typeId < ( uintptr ) mCeMachine - > mCeModule - > mContext - > mTypes . size ( ) )
return mCeMachine - > mCeModule - > mContext - > mTypes [ typeId ] ;
2020-12-19 14:19:33 -08:00
return NULL ;
}
2021-01-11 09:41:43 -08:00
void CeContext : : PrepareConstStructEntry ( CeConstStructData & constEntry )
2020-12-22 04:50:37 -08:00
{
if ( constEntry . mHash . IsZero ( ) )
{
2021-11-03 07:48:01 -07:00
constEntry . mHash = Hash128 ( constEntry . mData . mVals , constEntry . mData . mSize ) ;
2020-12-22 04:50:37 -08:00
if ( ! constEntry . mFixups . IsEmpty ( ) )
constEntry . mHash = Hash128 ( & constEntry . mFixups [ 0 ] , constEntry . mFixups . mSize * sizeof ( CeConstStructFixup ) , constEntry . mHash ) ;
}
if ( ! constEntry . mFixups . IsEmpty ( ) )
{
if ( constEntry . mFixedData . IsEmpty ( ) )
constEntry . mFixedData = constEntry . mData ;
for ( auto & fixup : constEntry . mFixups )
{
if ( fixup . mKind = = CeConstStructFixup : : Kind_StringPtr )
{
2021-01-11 09:41:43 -08:00
BfTypeInstance * stringTypeInst = ( BfTypeInstance * ) mCeMachine - > mCeModule - > ResolveTypeDef ( mCeMachine - > mCompiler - > mStringTypeDef , BfPopulateType_Data ) ;
2020-12-22 04:50:37 -08:00
addr_ce addrPtr = GetString ( fixup . mValue ) ;
* ( addr_ce * ) ( constEntry . mFixedData . mVals + fixup . mOffset ) = addrPtr ;
}
else if ( fixup . mKind = = CeConstStructFixup : : Kind_StringCharPtr )
{
2021-01-11 09:41:43 -08:00
BfTypeInstance * stringTypeInst = ( BfTypeInstance * ) mCeMachine - > mCeModule - > ResolveTypeDef ( mCeMachine - > mCompiler - > mStringTypeDef , BfPopulateType_Data ) ;
2020-12-22 04:50:37 -08:00
addr_ce addrPtr = GetString ( fixup . mValue ) ;
* ( addr_ce * ) ( constEntry . mFixedData . mVals + fixup . mOffset ) = addrPtr + stringTypeInst - > mInstSize ;
}
}
}
constEntry . mBindExecuteId = mExecuteId ;
}
2021-01-11 09:41:43 -08:00
bool CeContext : : CheckMemory ( addr_ce addr , int32 size )
2021-01-08 16:21:03 -08:00
{
if ( ( ( addr ) - 0x10000 ) + ( size ) > ( mMemory . mSize - 0x10000 ) )
return false ;
return true ;
}
2021-01-11 09:41:43 -08:00
bool CeContext : : GetStringFromStringView ( addr_ce addr , StringImpl & str )
2021-01-08 16:21:03 -08:00
{
2021-01-11 09:41:43 -08:00
int ptrSize = mCeMachine - > mCeModule - > mSystem - > mPtrSize ;
2021-01-08 16:21:03 -08:00
if ( ! CheckMemory ( addr , ptrSize * 2 ) )
return false ;
addr_ce charsPtr = * ( addr_ce * ) ( mMemory . mVals + addr ) ;
int32 len = * ( int32 * ) ( mMemory . mVals + addr + ptrSize ) ;
if ( ! CheckMemory ( charsPtr , len ) )
return false ;
str . Append ( ( const char * ) ( mMemory . mVals + charsPtr ) , len ) ;
return true ;
}
2021-01-11 09:41:43 -08:00
bool CeContext : : GetCustomAttribute ( BfCustomAttributes * customAttributes , int attributeTypeId , addr_ce resultAddr )
2020-12-14 10:20:44 -08:00
{
2021-06-24 06:59:49 -07:00
if ( customAttributes = = NULL )
return false ;
2021-01-11 09:41:43 -08:00
BfType * attributeType = GetBfType ( attributeTypeId ) ;
if ( attributeType = = NULL )
return false ;
2020-12-14 10:20:44 -08:00
2021-01-11 09:41:43 -08:00
auto customAttr = customAttributes - > Get ( attributeType ) ;
if ( customAttr = = NULL )
return false ;
2020-12-14 10:20:44 -08:00
2021-01-11 09:41:43 -08:00
if ( resultAddr ! = 0 )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
2020-12-13 08:04:42 -08:00
}
2020-12-17 04:51:05 -08:00
2021-01-11 09:41:43 -08:00
return true ;
2020-12-17 04:51:05 -08:00
}
2020-12-13 08:04:42 -08:00
2020-12-22 04:50:37 -08:00
//#define CE_GETC(T) *((T*)(addr += sizeof(T)) - 1)
# define CE_GETC(T) *(T*)(mMemory.mVals + addr)
2021-01-11 09:41:43 -08:00
bool CeContext : : WriteConstant ( BfModule * module , addr_ce addr , BfConstant * constant , BfType * type , bool isParams )
2020-12-22 04:50:37 -08:00
{
2020-12-13 08:04:42 -08:00
switch ( constant - > mTypeCode )
{
case BfTypeCode_Int8 :
case BfTypeCode_UInt8 :
case BfTypeCode_Boolean :
case BfTypeCode_Char8 :
2020-12-22 04:50:37 -08:00
CE_GETC ( int8 ) = constant - > mInt8 ;
return true ;
2020-12-13 08:04:42 -08:00
case BfTypeCode_Int16 :
case BfTypeCode_UInt16 :
case BfTypeCode_Char16 :
2020-12-22 04:50:37 -08:00
CE_GETC ( int16 ) = constant - > mInt16 ;
return true ;
2020-12-13 08:04:42 -08:00
case BfTypeCode_Int32 :
case BfTypeCode_UInt32 :
case BfTypeCode_Char32 :
2020-12-22 04:50:37 -08:00
CE_GETC ( int32 ) = constant - > mInt32 ;
return true ;
2020-12-13 08:04:42 -08:00
case BfTypeCode_Int64 :
2020-12-22 04:50:37 -08:00
case BfTypeCode_UInt64 :
CE_GETC ( int64 ) = constant - > mInt64 ;
return true ;
2020-12-13 08:04:42 -08:00
case BfTypeCode_NullPtr :
2021-01-11 09:41:43 -08:00
if ( mCeMachine - > mCeModule - > mSystem - > mPtrSize = = 4 )
2020-12-22 04:50:37 -08:00
CE_GETC ( int32 ) = 0 ;
else
CE_GETC ( int64 ) = 0 ;
return true ;
2020-12-13 08:04:42 -08:00
case BfTypeCode_Float :
2020-12-22 04:50:37 -08:00
CE_GETC ( float ) = ( float ) constant - > mDouble ;
return true ;
2020-12-13 08:04:42 -08:00
case BfTypeCode_Double :
2020-12-22 04:50:37 -08:00
CE_GETC ( double ) = constant - > mDouble ;
return true ;
}
if ( constant - > mConstType = = BfConstType_Agg )
{
auto aggConstant = ( BfConstantAgg * ) constant ;
if ( type - > IsSizedArray ( ) )
{
2021-10-28 09:33:27 -07:00
auto sizedArrayType = ( BfSizedArrayType * ) type ;
for ( int i = 0 ; i < sizedArrayType - > mSize ; i + + )
{
auto fieldConstant = module - > mBfIRBuilder - > GetConstant ( aggConstant - > mValues [ i ] ) ;
if ( fieldConstant = = NULL )
return false ;
if ( ! WriteConstant ( module , addr + i * sizedArrayType - > mElementType - > mSize , fieldConstant , sizedArrayType - > mElementType ) )
return false ;
}
return true ;
2020-12-22 04:50:37 -08:00
}
2020-12-23 08:53:38 -08:00
else if ( type - > IsArray ( ) )
{
auto elemType = type - > GetUnderlyingType ( ) ;
addr_ce elemsAddr = 0 ;
addr_ce arrayAddr = CeAllocArray ( ( BfArrayType * ) type , aggConstant - > mValues . size ( ) , elemsAddr ) ;
for ( int i = 0 ; i < ( int ) aggConstant - > mValues . size ( ) ; i + + )
{
auto fieldConstant = module - > mBfIRBuilder - > GetConstant ( aggConstant - > mValues [ i ] ) ;
if ( fieldConstant = = NULL )
return false ;
2021-02-01 11:19:50 -08:00
if ( ! WriteConstant ( module , elemsAddr + i * elemType - > GetStride ( ) , fieldConstant , elemType ) )
return false ;
2020-12-23 08:53:38 -08:00
}
2021-01-11 09:41:43 -08:00
if ( mCeMachine - > mCeModule - > mSystem - > mPtrSize = = 4 )
2020-12-23 08:53:38 -08:00
CE_GETC ( int32 ) = arrayAddr ;
else
CE_GETC ( int64 ) = arrayAddr ;
return true ;
}
else if ( ( type - > IsInstanceOf ( module - > mCompiler - > mSpanTypeDef ) ) & & ( isParams ) )
2020-12-22 04:50:37 -08:00
{
2020-12-23 08:53:38 -08:00
auto elemType = type - > GetUnderlyingType ( ) ;
addr_ce elemsAddr = CeMalloc ( elemType - > GetStride ( ) * aggConstant - > mValues . size ( ) ) - mMemory . mVals ;
for ( int i = 0 ; i < ( int ) aggConstant - > mValues . size ( ) ; i + + )
{
auto fieldConstant = module - > mBfIRBuilder - > GetConstant ( aggConstant - > mValues [ i ] ) ;
if ( fieldConstant = = NULL )
return false ;
2021-02-01 11:19:50 -08:00
if ( ! WriteConstant ( module , elemsAddr + i * elemType - > GetStride ( ) , fieldConstant , elemType ) )
return false ;
2020-12-23 08:53:38 -08:00
}
2021-01-11 09:41:43 -08:00
if ( mCeMachine - > mCeModule - > mSystem - > mPtrSize = = 4 )
2020-12-23 08:53:38 -08:00
{
CE_GETC ( int32 ) = elemsAddr ;
addr + = 4 ;
CE_GETC ( int32 ) = ( int32 ) aggConstant - > mValues . size ( ) ;
}
else
{
CE_GETC ( int32 ) = elemsAddr ;
addr + = 8 ;
CE_GETC ( int64 ) = ( int32 ) aggConstant - > mValues . size ( ) ;
}
}
else
{
2020-12-22 04:50:37 -08:00
BF_ASSERT ( type - > IsStruct ( ) ) ;
module - > PopulateType ( type ) ;
auto typeInst = type - > ToTypeInstance ( ) ;
int idx = 0 ;
if ( typeInst - > mBaseType ! = NULL )
{
auto baseConstant = module - > mBfIRBuilder - > GetConstant ( aggConstant - > mValues [ 0 ] ) ;
2021-02-01 11:19:50 -08:00
if ( ! WriteConstant ( module , addr , baseConstant , typeInst - > mBaseType ) )
return false ;
2020-12-22 04:50:37 -08:00
}
for ( auto & fieldInstance : typeInst - > mFieldInstances )
{
if ( fieldInstance . mDataOffset < 0 )
continue ;
auto fieldConstant = module - > mBfIRBuilder - > GetConstant ( aggConstant - > mValues [ fieldInstance . mDataIdx ] ) ;
if ( fieldConstant = = NULL )
return false ;
2021-02-01 11:19:50 -08:00
if ( ! WriteConstant ( module , addr + fieldInstance . mDataOffset , fieldConstant , fieldInstance . mResolvedType ) )
return false ;
2020-12-22 04:50:37 -08:00
}
}
return true ;
}
if ( constant - > mConstType = = BfConstType_AggZero )
{
BF_ASSERT ( type - > IsComposite ( ) ) ;
memset ( mMemory . mVals + addr , 0 , type - > mSize ) ;
return true ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
if ( constant - > mConstType = = BfConstType_AggCE )
{
auto constAggData = ( BfConstantAggCE * ) constant ;
if ( type - > IsPointer ( ) )
{
if ( mCeMachine - > mCeModule - > mSystem - > mPtrSize = = 4 )
CE_GETC ( int32 ) = constAggData - > mCEAddr ;
else
CE_GETC ( int64 ) = constAggData - > mCEAddr ;
}
else
{
BF_ASSERT ( type - > IsComposite ( ) ) ;
memcpy ( mMemory . mVals + addr , mMemory . mVals + constAggData - > mCEAddr , type - > mSize ) ;
}
return true ;
}
2020-12-22 04:50:37 -08:00
if ( constant - > mConstType = = BfConstType_BitCast )
{
auto constBitCast = ( BfConstantBitCast * ) constant ;
auto constTarget = module - > mBfIRBuilder - > GetConstantById ( constBitCast - > mTarget ) ;
return WriteConstant ( module , addr , constTarget , type ) ;
}
2021-10-28 09:33:27 -07:00
if ( constant - > mConstType = = BfConstType_BitCastNull )
{
BF_ASSERT ( type - > IsPointer ( ) | | type - > IsObjectOrInterface ( ) ) ;
memset ( mMemory . mVals + addr , 0 , type - > mSize ) ;
return true ;
}
2021-01-11 09:41:43 -08:00
2020-12-22 04:50:37 -08:00
if ( constant - > mConstType = = BfConstType_GEP32_2 )
{
auto gepConst = ( BfConstantGEP32_2 * ) constant ;
auto constTarget = module - > mBfIRBuilder - > GetConstantById ( gepConst - > mTarget ) ;
if ( constTarget - > mConstType = = BfConstType_GlobalVar )
{
auto globalVar = ( BfGlobalVar * ) constTarget ;
if ( strncmp ( globalVar - > mName , " __bfStrData " , 10 ) = = 0 )
{
2021-01-11 09:41:43 -08:00
BfTypeInstance * stringTypeInst = ( BfTypeInstance * ) mCeMachine - > mCeModule - > ResolveTypeDef ( mCeMachine - > mCompiler - > mStringTypeDef , BfPopulateType_Data ) ;
2020-12-22 04:50:37 -08:00
int stringId = atoi ( globalVar - > mName + 11 ) ;
2021-01-11 09:41:43 -08:00
addr_ce strAddr = GetString ( stringId ) + stringTypeInst - > mInstSize ;
if ( mCeMachine - > mCeModule - > mSystem - > mPtrSize = = 4 )
2020-12-22 04:50:37 -08:00
CE_GETC ( int32 ) = strAddr ;
else
CE_GETC ( int64 ) = strAddr ;
return true ;
}
}
}
if ( constant - > mConstType = = BfConstType_GlobalVar )
{
auto globalVar = ( BfGlobalVar * ) constant ;
if ( strncmp ( globalVar - > mName , " __bfStrObj " , 10 ) = = 0 )
{
int stringId = atoi ( globalVar - > mName + 10 ) ;
addr_ce strAddr = GetString ( stringId ) ;
2021-01-11 09:41:43 -08:00
if ( mCeMachine - > mCeModule - > mSystem - > mPtrSize = = 4 )
2020-12-22 04:50:37 -08:00
CE_GETC ( int32 ) = strAddr ;
else
CE_GETC ( int64 ) = strAddr ;
return true ;
}
}
2021-01-13 06:00:29 -08:00
if ( constant - > mTypeCode = = BfTypeCode_StringId )
2021-01-11 09:41:43 -08:00
{
addr_ce strAddr = GetString ( constant - > mInt32 ) ;
if ( type - > IsPointer ( ) )
{
BfTypeInstance * stringTypeInst = ( BfTypeInstance * ) mCeMachine - > mCeModule - > ResolveTypeDef ( mCeMachine - > mCompiler - > mStringTypeDef , BfPopulateType_Data ) ;
strAddr + = stringTypeInst - > mInstSize ;
}
if ( mCeMachine - > mCeModule - > mSystem - > mPtrSize = = 4 )
CE_GETC ( int32 ) = strAddr ;
else
CE_GETC ( int64 ) = strAddr ;
return true ;
}
2021-01-08 16:21:03 -08:00
if ( ( constant - > mConstType = = BfConstType_TypeOf ) | | ( constant - > mConstType = = BfConstType_TypeOf_WithData ) )
{
auto constTypeOf = ( BfTypeOf_Const * ) constant ;
2021-02-02 10:46:21 -08:00
addr_ce typeAddr = GetReflectType ( constTypeOf - > mType - > mTypeId ) ;
if ( mCeMachine - > mCeModule - > mSystem - > mPtrSize = = 4 )
CE_GETC ( int32 ) = typeAddr ;
else
CE_GETC ( int64 ) = typeAddr ;
2021-01-08 16:21:03 -08:00
return true ;
}
2020-12-22 04:50:37 -08:00
return false ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
# define CE_CREATECONST_CHECKPTR(PTR, SIZE) \
if ( ( ( ( uint8 * ) ( PTR ) - memStart ) - 0x10000 ) + ( SIZE ) > ( memSize - 0x10000 ) ) \
{ \
Fail ( " Access violation creating constant result " ) ; \
return BfIRValue ( ) ; \
}
BfIRValue CeContext : : CreateConstant ( BfModule * module , uint8 * ptr , BfType * bfType , BfType * * outType )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
auto ceModule = mCeMachine - > mCeModule ;
BfIRBuilder * irBuilder = module - > mBfIRBuilder ;
2021-01-18 14:09:16 -08:00
int32 ptrSize = module - > mSystem - > mPtrSize ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
uint8 * memStart = mMemory . mVals ;
int memSize = mMemory . mSize ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
if ( bfType - > IsPrimitiveType ( ) )
{
auto primType = ( BfPrimitiveType * ) bfType ;
2020-12-23 08:53:38 -08:00
2021-01-11 09:41:43 -08:00
auto typeCode = primType - > mTypeDef - > mTypeCode ;
if ( typeCode = = BfTypeCode_IntPtr )
typeCode = ( ceModule - > mCompiler - > mSystem - > mPtrSize = = 4 ) ? BfTypeCode_Int32 : BfTypeCode_Int64 ;
else if ( typeCode = = BfTypeCode_UIntPtr )
typeCode = ( ceModule - > mCompiler - > mSystem - > mPtrSize = = 4 ) ? BfTypeCode_UInt32 : BfTypeCode_UInt64 ;
2020-12-22 04:50:37 -08:00
switch ( typeCode )
{
case BfTypeCode_Int8 :
CE_CREATECONST_CHECKPTR ( ptr , sizeof ( int8 ) ) ;
return irBuilder - > CreateConst ( primType - > mTypeDef - > mTypeCode , * ( int8 * ) ptr ) ;
case BfTypeCode_UInt8 :
2021-02-26 06:26:26 -08:00
case BfTypeCode_Boolean :
case BfTypeCode_Char8 :
2020-12-22 04:50:37 -08:00
CE_CREATECONST_CHECKPTR ( ptr , sizeof ( uint8 ) ) ;
return irBuilder - > CreateConst ( primType - > mTypeDef - > mTypeCode , * ( uint8 * ) ptr ) ;
case BfTypeCode_Int16 :
CE_CREATECONST_CHECKPTR ( ptr , sizeof ( int16 ) ) ;
return irBuilder - > CreateConst ( primType - > mTypeDef - > mTypeCode , * ( int16 * ) ptr ) ;
case BfTypeCode_UInt16 :
2021-02-26 06:26:26 -08:00
case BfTypeCode_Char16 :
2020-12-22 04:50:37 -08:00
CE_CREATECONST_CHECKPTR ( ptr , sizeof ( uint16 ) ) ;
return irBuilder - > CreateConst ( primType - > mTypeDef - > mTypeCode , * ( uint16 * ) ptr ) ;
case BfTypeCode_Int32 :
CE_CREATECONST_CHECKPTR ( ptr , sizeof ( int32 ) ) ;
return irBuilder - > CreateConst ( primType - > mTypeDef - > mTypeCode , * ( int32 * ) ptr ) ;
case BfTypeCode_UInt32 :
2021-02-26 06:26:26 -08:00
case BfTypeCode_Char32 :
2020-12-22 04:50:37 -08:00
CE_CREATECONST_CHECKPTR ( ptr , sizeof ( uint32 ) ) ;
2021-01-11 09:41:43 -08:00
return irBuilder - > CreateConst ( primType - > mTypeDef - > mTypeCode , ( uint64 ) * ( uint32 * ) ptr ) ;
2020-12-22 04:50:37 -08:00
case BfTypeCode_Int64 :
case BfTypeCode_UInt64 :
CE_CREATECONST_CHECKPTR ( ptr , sizeof ( int64 ) ) ;
return irBuilder - > CreateConst ( primType - > mTypeDef - > mTypeCode , * ( uint64 * ) ptr ) ;
case BfTypeCode_Float :
CE_CREATECONST_CHECKPTR ( ptr , sizeof ( float ) ) ;
return irBuilder - > CreateConst ( primType - > mTypeDef - > mTypeCode , * ( float * ) ptr ) ;
case BfTypeCode_Double :
CE_CREATECONST_CHECKPTR ( ptr , sizeof ( double ) ) ;
return irBuilder - > CreateConst ( primType - > mTypeDef - > mTypeCode , * ( double * ) ptr ) ;
}
return BfIRValue ( ) ;
2020-12-13 08:04:42 -08:00
}
2021-07-22 10:49:17 -07:00
if ( bfType - > IsTypedPrimitive ( ) )
return CreateConstant ( module , ptr , bfType - > GetUnderlyingType ( ) , outType ) ;
2020-12-22 04:50:37 -08:00
if ( bfType - > IsTypeInstance ( ) )
{
auto typeInst = bfType - > ToTypeInstance ( ) ;
2021-02-26 09:29:28 -08:00
2021-01-11 09:41:43 -08:00
uint8 * instData = ptr ;
// if ((typeInst->IsObject()) && (!isBaseType))
// {
// CE_CREATECONST_CHECKPTR(ptr, sizeof(addr_ce));
// instData = mMemory.mVals + *(addr_ce*)ptr;
// CE_CREATECONST_CHECKPTR(instData, typeInst->mInstSize);
// }
2020-12-22 04:50:37 -08:00
2021-11-01 07:22:06 -07:00
if ( typeInst - > IsObjectOrInterface ( ) )
2020-12-22 04:50:37 -08:00
{
2021-11-01 07:22:06 -07:00
addr_ce addr = * ( addr_ce * ) ( ptr ) ;
if ( addr = = 0 )
{
return irBuilder - > CreateConstNull ( irBuilder - > MapType ( typeInst ) ) ;
}
instData = memStart + addr ;
2020-12-22 04:50:37 -08:00
2021-11-01 07:22:06 -07:00
if ( typeInst - > IsInstanceOf ( mCeMachine - > mCompiler - > mStringTypeDef ) )
{
BfTypeInstance * stringTypeInst = ( BfTypeInstance * ) ceModule - > ResolveTypeDef ( mCeMachine - > mCompiler - > mStringTypeDef , BfPopulateType_Data ) ;
module - > PopulateType ( stringTypeInst ) ;
2021-01-11 09:41:43 -08:00
2021-11-01 07:22:06 -07:00
auto lenByteCount = stringTypeInst - > mFieldInstances [ 0 ] . mResolvedType - > mSize ;
auto lenOffset = stringTypeInst - > mFieldInstances [ 0 ] . mDataOffset ;
auto allocSizeOffset = stringTypeInst - > mFieldInstances [ 1 ] . mDataOffset ;
auto ptrOffset = stringTypeInst - > mFieldInstances [ 2 ] . mDataOffset ;
2020-12-22 04:50:37 -08:00
2021-11-01 07:22:06 -07:00
int32 lenVal = * ( int32 * ) ( instData + lenOffset ) ;
2020-12-22 04:50:37 -08:00
2021-11-01 07:22:06 -07:00
char * charPtr = NULL ;
if ( lenByteCount = = 4 )
2020-12-22 04:50:37 -08:00
{
2021-11-01 07:22:06 -07:00
int32 allocSizeVal = * ( int32 * ) ( instData + allocSizeOffset ) ;
if ( ( allocSizeVal & 0x40000000 ) ! = 0 )
{
int32 ptrVal = * ( int32 * ) ( instData + ptrOffset ) ;
charPtr = ( char * ) ( ptrVal + memStart ) ;
}
else
{
charPtr = ( char * ) ( instData + ptrOffset ) ;
}
2020-12-22 04:50:37 -08:00
}
2021-12-20 15:07:38 -05:00
else
{
int64 allocSizeVal = * ( int64 * ) ( instData + allocSizeOffset ) ;
if ( ( allocSizeVal & 0x4000000000000000LL ) ! = 0 )
{
int32 ptrVal = * ( int32 * ) ( instData + ptrOffset ) ;
charPtr = ( char * ) ( ptrVal + memStart ) ;
}
else
{
charPtr = ( char * ) ( instData + ptrOffset ) ;
}
}
2020-12-22 04:50:37 -08:00
2021-11-01 07:22:06 -07:00
CE_CREATECONST_CHECKPTR ( charPtr , lenVal ) ;
String str ( charPtr , lenVal ) ;
return module - > GetStringObjectValue ( str ) ;
}
2021-01-18 14:09:16 -08:00
}
if ( typeInst - > IsInstanceOf ( mCeMachine - > mCompiler - > mStringViewTypeDef ) )
{
char * charPtr = ( char * ) memStart + * ( addr_ce * ) ( ptr ) ;
int32 lenVal = * ( int32 * ) ( ptr + ptrSize ) ;
CE_CREATECONST_CHECKPTR ( charPtr , lenVal ) ;
String str ( charPtr , lenVal ) ;
auto stringViewType = ceModule - > ResolveTypeDef ( mCeMachine - > mCompiler - > mStringViewTypeDef , BfPopulateType_Data ) - > ToTypeInstance ( ) ;
auto spanType = stringViewType - > mBaseType ;
auto valueTypeType = spanType - > mBaseType ;
SizedArray < BfIRValue , 1 > valueTypeValues ;
BfIRValue valueTypeVal = irBuilder - > CreateConstAgg ( irBuilder - > MapType ( valueTypeType , BfIRPopulateType_Full ) , valueTypeValues ) ;
SizedArray < BfIRValue , 3 > spanValues ;
spanValues . Add ( valueTypeVal ) ;
spanValues . Add ( module - > GetStringCharPtr ( str ) ) ;
spanValues . Add ( irBuilder - > CreateConst ( BfTypeCode_IntPtr , lenVal ) ) ;
BfIRValue spanVal = irBuilder - > CreateConstAgg ( irBuilder - > MapType ( spanType , BfIRPopulateType_Full ) , spanValues ) ;
SizedArray < BfIRValue , 1 > stringViewValues ;
stringViewValues . Add ( spanVal ) ;
return irBuilder - > CreateConstAgg ( irBuilder - > MapType ( stringViewType , BfIRPopulateType_Full ) , stringViewValues ) ;
2020-12-22 04:50:37 -08:00
}
SizedArray < BfIRValue , 8 > fieldVals ;
2021-01-11 09:41:43 -08:00
if ( typeInst - > IsInstanceOf ( ceModule - > mCompiler - > mSpanTypeDef ) )
2020-12-22 04:50:37 -08:00
{
2020-12-23 08:53:38 -08:00
if ( ( outType ! = NULL ) & & ( ( mCurExpectingType = = NULL ) | | ( mCurExpectingType - > IsSizedArray ( ) ) ) )
2021-01-11 09:41:43 -08:00
{
2020-12-22 04:50:37 -08:00
module - > PopulateType ( typeInst ) ;
auto ptrOffset = typeInst - > mFieldInstances [ 0 ] . mDataOffset ;
auto lenOffset = typeInst - > mFieldInstances [ 1 ] . mDataOffset ;
2021-01-11 09:41:43 -08:00
2020-12-22 04:50:37 -08:00
BfType * elemType = typeInst - > GetUnderlyingType ( ) ;
2021-01-11 09:41:43 -08:00
CE_CREATECONST_CHECKPTR ( instData , ceModule - > mSystem - > mPtrSize * 2 ) ;
2020-12-22 04:50:37 -08:00
addr_ce addr = * ( addr_ce * ) ( instData + ptrOffset ) ;
2021-01-11 09:41:43 -08:00
int32 lenVal = * ( int32 * ) ( instData + lenOffset ) ;
2020-12-22 04:50:37 -08:00
CE_CREATECONST_CHECKPTR ( memStart + addr , lenVal ) ;
for ( int i = 0 ; i < lenVal ; i + + )
{
auto result = CreateConstant ( module , memStart + addr + i * elemType - > GetStride ( ) , elemType ) ;
if ( ! result )
return BfIRValue ( ) ;
fieldVals . Add ( result ) ;
}
auto irArrayType = irBuilder - > GetSizedArrayType ( irBuilder - > MapType ( elemType , BfIRPopulateType_Full ) , lenVal ) ;
auto instResult = irBuilder - > CreateConstAgg ( irArrayType , fieldVals ) ;
* outType = module - > CreateSizedArrayType ( elemType , lenVal ) ;
return instResult ;
}
2020-12-23 08:53:38 -08:00
Fail ( StrFormat ( " Span return type '%s' must be received by a sized array " , module - > TypeToString ( typeInst ) . c_str ( ) ) ) ;
return BfIRValue ( ) ;
2020-12-22 04:50:37 -08:00
}
2021-01-15 14:28:21 -08:00
if ( typeInst - > IsInstanceOf ( ceModule - > mCompiler - > mTypeTypeDef ) )
{
addr_ce addr = * ( addr_ce * ) ( instData ) ;
int typeId = GetTypeIdFromType ( addr ) ;
if ( typeId < = 0 )
{
Fail ( " Unable to locate return type type " ) ;
return BfIRValue ( ) ;
}
return module - > CreateTypeDataRef ( module - > mContext - > mTypes [ typeId ] ) ;
}
2020-12-22 04:50:37 -08:00
if ( typeInst - > IsObjectOrInterface ( ) )
{
Fail ( StrFormat ( " Reference type '%s' return value not allowed " , module - > TypeToString ( typeInst ) . c_str ( ) ) ) ;
return BfIRValue ( ) ;
}
2021-01-18 14:09:16 -08:00
2020-12-22 04:50:37 -08:00
if ( typeInst - > mBaseType ! = NULL )
{
auto result = CreateConstant ( module , instData , typeInst - > mBaseType ) ;
if ( ! result )
return BfIRValue ( ) ;
fieldVals . Add ( result ) ;
2021-07-22 10:49:17 -07:00
}
2021-02-26 09:29:28 -08:00
if ( typeInst - > mIsUnion )
2021-01-11 09:41:43 -08:00
{
2021-02-26 09:29:28 -08:00
auto unionInnerType = typeInst - > GetUnionInnerType ( ) ;
fieldVals . Add ( CreateConstant ( module , ptr , unionInnerType , outType ) ) ;
}
else
{
for ( int fieldIdx = 0 ; fieldIdx < typeInst - > mFieldInstances . size ( ) ; fieldIdx + + )
2020-12-22 04:50:37 -08:00
{
2021-02-26 09:29:28 -08:00
auto & fieldInstance = typeInst - > mFieldInstances [ fieldIdx ] ;
if ( fieldInstance . mDataOffset < 0 )
continue ;
2020-12-22 04:50:37 -08:00
2021-02-26 09:29:28 -08:00
if ( ( fieldInstance . mDataOffset = = 0 ) & & ( typeInst = = mCeMachine - > mCompiler - > mContext - > mBfObjectType ) )
{
auto vdataPtr = module - > GetClassVDataPtr ( typeInst ) ;
if ( fieldInstance . mResolvedType - > IsInteger ( ) )
fieldVals . Add ( irBuilder - > CreatePtrToInt ( vdataPtr , ( ( BfPrimitiveType * ) fieldInstance . mResolvedType ) - > mTypeDef - > mTypeCode ) ) ;
else
fieldVals . Add ( vdataPtr ) ;
continue ;
}
2020-12-22 04:50:37 -08:00
2021-02-26 09:29:28 -08:00
auto result = CreateConstant ( module , instData + fieldInstance . mDataOffset , fieldInstance . mResolvedType ) ;
if ( ! result )
return BfIRValue ( ) ;
if ( fieldInstance . mDataIdx = = fieldVals . mSize )
{
fieldVals . Add ( result ) ;
}
else
{
while ( fieldInstance . mDataIdx > = fieldVals . mSize )
fieldVals . Add ( BfIRValue ( ) ) ;
fieldVals [ fieldInstance . mDataIdx ] = result ;
}
2020-12-22 04:50:37 -08:00
}
}
2021-01-18 14:09:16 -08:00
for ( auto & fieldVal : fieldVals )
{
if ( ! fieldVal )
fieldVal = irBuilder - > CreateConstArrayZero ( 0 ) ;
}
2021-01-11 09:41:43 -08:00
2020-12-22 04:50:37 -08:00
auto instResult = irBuilder - > CreateConstAgg ( irBuilder - > MapTypeInst ( typeInst , BfIRPopulateType_Full ) , fieldVals ) ;
return instResult ;
2021-01-11 09:41:43 -08:00
}
2020-12-22 04:50:37 -08:00
2021-01-18 14:09:16 -08:00
if ( bfType - > IsPointer ( ) )
{
Fail ( StrFormat ( " Pointer type '%s' return value not allowed " , module - > TypeToString ( bfType ) . c_str ( ) ) ) ;
return BfIRValue ( ) ;
}
if ( ( bfType - > IsSizedArray ( ) ) & & ( ! bfType - > IsUnknownSizedArrayType ( ) ) )
{
SizedArray < BfIRValue , 8 > values ;
auto sizedArrayType = ( BfSizedArrayType * ) bfType ;
for ( int i = 0 ; i < sizedArrayType - > mElementCount ; i + + )
{
auto elemValue = CreateConstant ( module , ptr + i * sizedArrayType - > mElementType - > GetStride ( ) , sizedArrayType - > mElementType ) ;
if ( ! elemValue )
return BfIRValue ( ) ;
values . Add ( elemValue ) ;
}
return irBuilder - > CreateConstAgg ( irBuilder - > MapType ( sizedArrayType , BfIRPopulateType_Full ) , values ) ;
}
2020-12-22 04:50:37 -08:00
return BfIRValue ( ) ;
2020-12-13 08:04:42 -08:00
}
2020-12-22 04:50:37 -08:00
2021-01-11 09:41:43 -08:00
BfIRValue CeContext : : CreateAttribute ( BfAstNode * targetSrc , BfModule * module , BfIRConstHolder * constHolder , BfCustomAttribute * customAttribute )
{
2021-11-02 11:32:06 -07:00
SetAndRestoreValue < bool > prevIgnoreWrites ( module - > mBfIRBuilder - > mIgnoreWrites , true ) ;
2021-02-25 10:14:22 -08:00
module - > mContext - > mUnreifiedModule - > PopulateType ( customAttribute - > mType ) ;
2021-01-11 09:41:43 -08:00
auto ceAttrAddr = CeMalloc ( customAttribute - > mType - > mSize ) - mMemory . mVals ;
BfIRValue ceAttrVal = module - > mBfIRBuilder - > CreateConstAggCE ( module - > mBfIRBuilder - > MapType ( customAttribute - > mType , BfIRPopulateType_Identity ) , ceAttrAddr ) ;
BfTypedValue ceAttrTypedValue ( ceAttrVal , customAttribute - > mType ) ;
auto ctorMethodInstance = module - > GetRawMethodInstance ( customAttribute - > mType , customAttribute - > mCtor ) ;
if ( ctorMethodInstance = = NULL )
{
module - > Fail ( " Attribute ctor failed " , targetSrc ) ;
return ceAttrVal ;
2020-12-14 03:50:28 -08:00
}
2020-12-13 08:04:42 -08:00
2021-01-11 09:41:43 -08:00
SizedArray < BfIRValue , 8 > ctorArgs ;
if ( ! customAttribute - > mType - > IsValuelessType ( ) )
ctorArgs . Add ( ceAttrVal ) ;
int paramIdx = 0 ;
for ( auto & arg : customAttribute - > mCtorArgs )
{
auto constant = constHolder - > GetConstant ( arg ) ;
if ( ! constant )
{
module - > AssertErrorState ( ) ;
return ceAttrVal ;
}
auto paramType = ctorMethodInstance - > GetParamType ( paramIdx ) ;
ctorArgs . Add ( module - > ConstantToCurrent ( constant , constHolder , paramType , true ) ) ;
paramIdx + + ;
2020-12-17 04:51:05 -08:00
}
2021-01-11 09:41:43 -08:00
BfTypedValue retValue = Call ( targetSrc , module , ctorMethodInstance , ctorArgs , CeEvalFlags_None , NULL ) ;
if ( ! retValue )
return ceAttrVal ;
for ( auto & setProperty : customAttribute - > mSetProperties )
{
BfExprEvaluator exprEvaluator ( module ) ;
BfMethodDef * setMethodDef = exprEvaluator . GetPropertyMethodDef ( setProperty . mPropertyRef , BfMethodType_PropertySetter , BfCheckedKind_NotSet , ceAttrTypedValue ) ;
BfMethodInstance * setMethodInstance = NULL ;
if ( setMethodDef ! = NULL )
setMethodInstance = module - > GetRawMethodInstance ( customAttribute - > mType , setMethodDef ) ;
if ( ( setMethodInstance = = NULL ) | | ( ! setProperty . mParam ) )
{
module - > Fail ( " Attribute prop failed " , targetSrc ) ;
return ceAttrVal ;
}
SizedArray < BfIRValue , 1 > setArgs ;
if ( ! customAttribute - > mType - > IsValuelessType ( ) )
setArgs . Add ( ceAttrVal ) ;
if ( ! setProperty . mParam . mType - > IsValuelessType ( ) )
{
auto constant = constHolder - > GetConstant ( setProperty . mParam . mValue ) ;
if ( ! constant )
{
module - > AssertErrorState ( ) ;
return ceAttrVal ;
}
setArgs . Add ( module - > ConstantToCurrent ( constant , constHolder , setProperty . mParam . mType , true ) ) ;
}
BfTypedValue retValue = Call ( targetSrc , module , setMethodInstance , setArgs , CeEvalFlags_None , NULL ) ;
if ( ! retValue )
return ceAttrVal ;
2020-12-22 04:50:37 -08:00
}
2021-01-11 09:41:43 -08:00
for ( auto & setField : customAttribute - > mSetField )
{
BfFieldInstance * fieldInstance = setField . mFieldRef ;
if ( fieldInstance - > mDataOffset < 0 )
continue ;
auto constant = constHolder - > GetConstant ( setField . mParam . mValue ) ;
WriteConstant ( module , ceAttrAddr + fieldInstance - > mDataOffset , constant , fieldInstance - > mResolvedType ) ;
2020-12-14 10:20:44 -08:00
}
2021-01-11 09:41:43 -08:00
return ceAttrVal ;
}
BfTypedValue CeContext : : Call ( BfAstNode * targetSrc , BfModule * module , BfMethodInstance * methodInstance , const BfSizedArray < BfIRValue > & args , CeEvalFlags flags , BfType * expectingType )
{
// DISABLED
//return BfTypedValue();
AutoTimer autoTimer ( mCeMachine - > mRevisionExecuteTime ) ;
2021-11-26 08:59:46 -08:00
SetAndRestoreValue < CeContext * > curPrevContext ( mPrevContext , mCeMachine - > mCurContext ) ;
2021-01-19 05:40:57 -08:00
SetAndRestoreValue < CeContext * > prevContext ( mCeMachine - > mCurContext , this ) ;
2021-01-11 09:41:43 -08:00
SetAndRestoreValue < CeEvalFlags > prevEvalFlags ( mCurEvalFlags , flags ) ;
SetAndRestoreValue < BfAstNode * > prevTargetSrc ( mCurTargetSrc , targetSrc ) ;
SetAndRestoreValue < BfModule * > prevModule ( mCurModule , module ) ;
SetAndRestoreValue < BfMethodInstance * > prevMethodInstance ( mCurMethodInstance , methodInstance ) ;
2021-01-13 05:09:09 -08:00
SetAndRestoreValue < BfType * > prevExpectingType ( mCurExpectingType , expectingType ) ;
2022-01-13 11:40:14 -05:00
SetAndRestoreValue < int > prevCurExecuteId ( mCurModule - > mCompiler - > mCurCEExecuteId , mCeMachine - > mExecuteId ) ;
2021-01-11 09:41:43 -08:00
// Reentrancy may occur as methods need defining
2021-01-13 05:09:09 -08:00
//SetAndRestoreValue<BfMethodState*> prevMethodStateInConstEval(module->mCurMethodState, NULL);
2021-01-11 09:41:43 -08:00
if ( mCeMachine - > mAppendAllocInfo ! = NULL )
2021-01-22 16:46:52 -08:00
{
if ( mCeMachine - > mAppendAllocInfo - > mAppendSizeValue )
2021-01-11 09:41:43 -08:00
{
2021-01-22 16:46:52 -08:00
bool isConst = mCeMachine - > mAppendAllocInfo - > mAppendSizeValue . IsConst ( ) ;
if ( isConst )
{
auto constant = module - > mBfIRBuilder - > GetConstant ( mCeMachine - > mAppendAllocInfo - > mAppendSizeValue ) ;
if ( constant - > mConstType = = BfConstType_Undef )
isConst = false ;
}
if ( ! isConst )
{
Fail ( " Non-constant append alloc " ) ;
return BfTypedValue ( ) ;
}
2021-01-11 09:41:43 -08:00
}
2020-12-14 10:20:44 -08:00
}
2021-01-11 09:41:43 -08:00
int thisArgIdx = - 1 ;
int appendAllocIdx = - 1 ;
bool hasAggData = false ;
if ( methodInstance - > mMethodDef - > mMethodType = = BfMethodType_Ctor )
{
if ( ! methodInstance - > GetOwner ( ) - > IsValuelessType ( ) )
{
thisArgIdx = 0 ;
auto constant = module - > mBfIRBuilder - > GetConstant ( args [ 0 ] ) ;
if ( ( constant ! = NULL ) & & ( constant - > mConstType = = BfConstType_AggCE ) )
hasAggData = true ;
}
if ( ( methodInstance - > GetParamCount ( ) > = 1 ) & & ( methodInstance - > GetParamKind ( 0 ) = = BfParamKind_AppendIdx ) )
appendAllocIdx = 1 ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
int paramCompositeSize = 0 ;
int paramIdx = methodInstance - > GetParamCount ( ) ;
for ( int argIdx = ( int ) args . size ( ) - 1 ; argIdx > = 0 ; argIdx - - )
{
BfType * paramType = NULL ;
while ( true )
{
paramIdx - - ;
paramType = methodInstance - > GetParamType ( paramIdx ) ;
if ( paramType - > IsTypedPrimitive ( ) )
paramType = paramType - > GetUnderlyingType ( ) ;
if ( ! paramType - > IsValuelessType ( ) )
break ;
}
if ( paramType - > IsComposite ( ) )
2021-01-22 16:46:52 -08:00
{
paramCompositeSize + = paramType - > mSize ;
2021-01-11 09:41:43 -08:00
}
auto arg = args [ argIdx ] ;
2021-01-22 16:46:52 -08:00
bool isConst = arg . IsConst ( ) ;
if ( isConst )
{
auto constant = module - > mBfIRBuilder - > GetConstant ( arg ) ;
if ( constant - > mConstType = = BfConstType_Undef )
2021-11-23 17:32:22 -08:00
{
if ( paramType - > IsInstanceOf ( module - > mCompiler - > mTypeTypeDef ) )
{
args [ argIdx ] = module - > CreateTypeDataRef ( module - > GetPrimitiveType ( BfTypeCode_None ) ) ;
}
else
isConst = false ;
}
2021-01-22 16:46:52 -08:00
}
if ( ! isConst )
2021-01-11 09:41:43 -08:00
{
if ( ( argIdx ! = thisArgIdx ) & & ( argIdx ! = appendAllocIdx ) )
{
Fail ( StrFormat ( " Non-constant argument for param '%s' " , methodInstance - > GetParamName ( paramIdx ) . c_str ( ) ) ) ;
return BfTypedValue ( ) ;
}
}
2020-12-14 03:50:28 -08:00
}
2021-01-11 09:41:43 -08:00
BF_ASSERT ( mCallStack . IsEmpty ( ) ) ;
auto methodDef = methodInstance - > mMethodDef ;
if ( mCeMachine - > mCeModule = = NULL )
mCeMachine - > Init ( ) ;
auto ceModule = mCeMachine - > mCeModule ;
bool added = false ;
CeFunction * ceFunction = mCeMachine - > GetFunction ( methodInstance , BfIRValue ( ) , added ) ;
2021-11-26 08:59:46 -08:00
if ( ceFunction - > mInitializeState = = CeFunction : : InitializeState_Initializing_ReEntry )
2021-01-11 09:41:43 -08:00
{
2021-11-26 08:59:46 -08:00
String error = " Comptime method preparation recursion " ;
auto curContext = this ;
while ( curContext ! = NULL )
{
if ( curContext - > mCurMethodInstance ! = NULL )
error + = StrFormat ( " \n %s " , module - > MethodToString ( curContext - > mCurMethodInstance ) . c_str ( ) ) ;
curContext = curContext - > mPrevContext ;
if ( ( curContext ! = NULL ) & & ( curContext - > mCurMethodInstance = = mCurMethodInstance ) )
break ;
}
Fail ( error ) ;
2021-01-11 09:41:43 -08:00
return BfTypedValue ( ) ;
2020-12-14 03:50:28 -08:00
}
2020-12-13 08:04:42 -08:00
2021-11-26 08:59:46 -08:00
if ( ceFunction - > mInitializeState < CeFunction : : InitializeState_Initialized )
2021-01-11 09:41:43 -08:00
mCeMachine - > PrepareFunction ( ceFunction , NULL ) ;
2020-12-17 04:51:05 -08:00
2021-12-20 15:07:38 -05:00
auto stackPtr = & mMemory [ 0 ] + mStackSize ;
2021-01-11 09:41:43 -08:00
auto * memStart = & mMemory [ 0 ] ;
2021-01-08 16:21:03 -08:00
2021-01-11 09:41:43 -08:00
BfTypeInstance * thisType = methodInstance - > GetOwner ( ) ;
addr_ce allocThisInstAddr = 0 ;
addr_ce allocThisAddr = 0 ;
int allocThisSize = - 1 ;
2020-12-23 08:53:38 -08:00
2021-01-11 09:41:43 -08:00
if ( ( thisArgIdx ! = - 1 ) & & ( ! hasAggData ) )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
allocThisSize = thisType - > mInstSize ;
if ( ( mCeMachine - > mAppendAllocInfo ! = NULL ) & & ( mCeMachine - > mAppendAllocInfo - > mAppendSizeValue ) )
{
BF_ASSERT ( mCeMachine - > mAppendAllocInfo - > mModule = = module ) ;
BF_ASSERT ( mCeMachine - > mAppendAllocInfo - > mAppendSizeValue . IsConst ( ) ) ;
auto appendSizeConstant = module - > mBfIRBuilder - > GetConstant ( mCeMachine - > mAppendAllocInfo - > mAppendSizeValue ) ;
BF_ASSERT ( module - > mBfIRBuilder - > IsInt ( appendSizeConstant - > mTypeCode ) ) ;
allocThisSize + = appendSizeConstant - > mInt32 ;
}
2021-12-20 15:07:38 -05:00
if ( allocThisSize > = mStackSize / 4 )
{
// Resize stack a reasonable size
mStackSize = BF_ALIGN ( allocThisSize , 0x100000 ) + BF_CE_DEFAULT_STACK_SIZE ;
int64 memSize = mStackSize + BF_CE_DEFAULT_HEAP_SIZE ;
if ( memSize > BF_CE_MAX_MEMORY )
{
Fail ( " Return value too large (>2GB) " ) ;
return BfTypedValue ( ) ;
}
if ( memSize > mMemory . mSize )
mMemory . Resize ( memSize ) ;
stackPtr = & mMemory [ 0 ] + mStackSize ;
memStart = & mMemory [ 0 ] ;
}
2021-01-11 09:41:43 -08:00
stackPtr - = allocThisSize ;
auto allocThisPtr = stackPtr ;
memset ( allocThisPtr , 0 , allocThisSize ) ;
if ( thisType - > IsObject ( ) )
* ( int32 * ) ( allocThisPtr ) = thisType - > mTypeId ;
allocThisInstAddr = allocThisPtr - memStart ;
allocThisAddr = allocThisInstAddr ;
}
addr_ce allocAppendIdxAddr = 0 ;
if ( appendAllocIdx ! = - 1 )
{
stackPtr - = ceModule - > mSystem - > mPtrSize ;
memset ( stackPtr , 0 , ceModule - > mSystem - > mPtrSize ) ;
2021-12-20 15:07:38 -05:00
* ( addr_ce * ) ( stackPtr ) = ( addr_ce ) ( allocThisInstAddr + thisType - > mInstSize ) ;
2021-01-11 09:41:43 -08:00
allocAppendIdxAddr = stackPtr - memStart ;
}
2020-12-14 03:50:28 -08:00
2020-12-17 04:51:05 -08:00
auto _FixVariables = [ & ] ( )
{
2021-01-11 09:41:43 -08:00
intptr memOffset = & mMemory [ 0 ] - memStart ;
2020-12-17 04:51:05 -08:00
if ( memOffset = = 0 )
return ;
2021-01-11 09:41:43 -08:00
memStart + = memOffset ;
2020-12-17 04:51:05 -08:00
stackPtr + = memOffset ;
2020-12-14 03:50:28 -08:00
} ;
2020-12-14 10:20:44 -08:00
2021-01-11 09:41:43 -08:00
addr_ce compositeStartAddr = stackPtr - memStart ;
stackPtr - = paramCompositeSize ;
addr_ce useCompositeAddr = compositeStartAddr ;
paramIdx = methodInstance - > GetParamCount ( ) ;
for ( int argIdx = ( int ) args . size ( ) - 1 ; argIdx > = 0 ; argIdx - - )
2020-12-14 10:20:44 -08:00
{
2021-01-11 09:41:43 -08:00
BfType * paramType = NULL ;
while ( true )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
paramIdx - - ;
paramType = methodInstance - > GetParamType ( paramIdx ) ;
if ( paramType - > IsTypedPrimitive ( ) )
paramType = paramType - > GetUnderlyingType ( ) ;
if ( ! paramType - > IsValuelessType ( ) )
break ;
2020-12-17 04:51:05 -08:00
}
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
bool isParams = methodInstance - > GetParamKind ( paramIdx ) = = BfParamKind_Params ;
auto arg = args [ argIdx ] ;
if ( ! arg . IsConst ( ) )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
if ( argIdx = = thisArgIdx )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
if ( mCeMachine - > mAppendAllocInfo ! = NULL )
BF_ASSERT ( mCeMachine - > mAppendAllocInfo - > mAllocValue = = arg ) ;
stackPtr - = ceModule - > mSystem - > mPtrSize ;
int64 addr64 = allocThisAddr ;
memcpy ( stackPtr , & addr64 , ceModule - > mSystem - > mPtrSize ) ;
continue ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( argIdx = = appendAllocIdx )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
stackPtr - = ceModule - > mSystem - > mPtrSize ;
int64 addr64 = allocAppendIdxAddr ;
memcpy ( stackPtr , & addr64 , ceModule - > mSystem - > mPtrSize ) ;
continue ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
else
return BfTypedValue ( ) ;
}
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
auto constant = module - > mBfIRBuilder - > GetConstant ( arg ) ;
if ( paramType - > IsComposite ( ) )
2021-10-28 09:33:27 -07:00
{
useCompositeAddr - = paramType - > mSize ;
2021-01-11 09:41:43 -08:00
if ( ! WriteConstant ( module , useCompositeAddr , constant , paramType , isParams ) )
{
Fail ( StrFormat ( " Failed to process argument for param '%s' " , methodInstance - > GetParamName ( paramIdx ) . c_str ( ) ) ) ;
return BfTypedValue ( ) ;
}
_FixVariables ( ) ;
2020-12-14 10:20:44 -08:00
2021-01-11 09:41:43 -08:00
stackPtr - = ceModule - > mSystem - > mPtrSize ;
int64 addr64 = useCompositeAddr ;
memcpy ( stackPtr , & addr64 , ceModule - > mSystem - > mPtrSize ) ;
}
else
{
stackPtr - = paramType - > mSize ;
if ( ! WriteConstant ( module , stackPtr - memStart , constant , paramType , isParams ) )
{
Fail ( StrFormat ( " Failed to process argument for param '%s' " , methodInstance - > GetParamName ( paramIdx ) . c_str ( ) ) ) ;
return BfTypedValue ( ) ;
}
_FixVariables ( ) ;
}
}
2020-12-13 08:04:42 -08:00
2021-01-11 09:41:43 -08:00
addr_ce retAddr = 0 ;
if ( ceFunction - > mMaxReturnSize > 0 )
{
int retSize = ceFunction - > mMaxReturnSize ;
stackPtr - = retSize ;
retAddr = stackPtr - memStart ;
}
2020-12-14 03:50:28 -08:00
2021-01-11 09:41:43 -08:00
mCeMachine - > mAppendAllocInfo = NULL ;
2020-12-17 04:51:05 -08:00
2021-01-11 09:41:43 -08:00
BfType * returnType = NULL ;
bool success = Execute ( ceFunction , stackPtr - ceFunction - > mFrameSize , stackPtr , returnType ) ;
memStart = & mMemory [ 0 ] ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
addr_ce retInstAddr = retAddr ;
2021-01-15 14:28:21 -08:00
if ( returnType - > IsInstanceOf ( mCeMachine - > mCompiler - > mTypeTypeDef ) )
{
// Allow
}
else if ( ( returnType - > IsObject ( ) ) | | ( returnType - > IsPointer ( ) ) )
2021-01-11 09:41:43 -08:00
{
// Or pointer?
retInstAddr = * ( addr_ce * ) ( memStart + retAddr ) ;
}
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
BfTypedValue returnValue ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
if ( success )
{
BfTypedValue retValue ;
2021-11-01 07:22:06 -07:00
if ( returnType - > IsObject ( ) )
{
BfType * usedReturnType = returnType ;
BfIRValue constVal = CreateConstant ( module , ( uint8 * ) & retInstAddr , returnType , & usedReturnType ) ;
if ( constVal )
returnValue = BfTypedValue ( constVal , usedReturnType ) ;
else
{
Fail ( " Failed to encode return argument " ) ;
}
}
else if ( ( retInstAddr ! = 0 ) | | ( allocThisInstAddr ! = 0 ) )
2021-01-11 09:41:43 -08:00
{
auto * retPtr = memStart + retInstAddr ;
if ( allocThisInstAddr ! = 0 )
2020-12-23 08:53:38 -08:00
{
2021-01-11 09:41:43 -08:00
retPtr = memStart + allocThisAddr ;
returnType = thisType ;
2020-12-23 08:53:38 -08:00
}
2021-01-11 09:41:43 -08:00
BfType * usedReturnType = returnType ;
2021-12-20 15:07:38 -05:00
BfIRValue constVal ;
if ( returnType - > IsObject ( ) )
{
addr_ce retAddr = retPtr - memStart ;
constVal = CreateConstant ( module , ( uint8 * ) & retAddr , returnType , & usedReturnType ) ;
}
else
constVal = CreateConstant ( module , retPtr , returnType , & usedReturnType ) ;
2021-01-11 09:41:43 -08:00
if ( constVal )
returnValue = BfTypedValue ( constVal , usedReturnType ) ;
else
2021-01-08 16:21:03 -08:00
{
2021-01-11 09:41:43 -08:00
Fail ( " Failed to encode return argument " ) ;
2021-01-08 16:21:03 -08:00
}
2021-01-11 09:41:43 -08:00
}
2021-01-19 05:40:57 -08:00
else if ( returnType - > IsComposite ( ) )
{
returnValue = BfTypedValue ( module - > mBfIRBuilder - > CreateConstArrayZero ( module - > mBfIRBuilder - > MapType ( returnType ) ) , returnType ) ;
}
2021-01-26 06:33:23 -08:00
else if ( returnType - > IsValuelessType ( ) )
2021-01-11 09:41:43 -08:00
{
2021-01-19 05:40:57 -08:00
returnValue = BfTypedValue ( module - > mBfIRBuilder - > GetFakeVal ( ) , returnType ) ;
2021-01-11 09:41:43 -08:00
}
}
2020-12-23 08:53:38 -08:00
2021-01-11 09:41:43 -08:00
mCallStack . Clear ( ) ;
2020-12-17 04:51:05 -08:00
2021-01-11 09:41:43 -08:00
module - > AddDependency ( methodInstance - > GetOwner ( ) , module - > mCurTypeInstance , BfDependencyMap : : DependencyFlag_ConstEval ) ;
return returnValue ;
}
# define CE_CHECKSTACK() \
if ( stackPtr < memStart ) \
{ \
_Fail ( " Stack overflow " ) ; \
return false ; \
}
# define CE_CHECKALLOC(SIZE) \
2021-12-20 15:07:38 -05:00
if ( ( SIZE < 0 ) | | ( SIZE > = 0x80000000LL ) | | ( ( uintptr ) memSize + ( uintptr ) SIZE > BF_CE_MAX_MEMORY ) ) \
2021-01-11 09:41:43 -08:00
{ \
2021-12-20 15:07:38 -05:00
_Fail ( " Maximum memory size exceeded (2GB) " ) ; \
return false ; \
2021-01-11 09:41:43 -08:00
}
// This check will fail for addresses < 64K (null pointer), or out-of-bounds
# define CE_CHECKSIZE(SIZE) \
if ( ( SIZE ) < 0 ) \
{ \
_Fail ( " Invalid memory size " ) ; \
return false ; \
}
# define CE_CHECKADDR(ADDR, SIZE) \
2021-12-20 15:07:38 -05:00
if ( ( ( ADDR ) < 0x10000 ) | | ( ( ADDR ) + ( SIZE ) > memSize ) ) \
2021-01-11 09:41:43 -08:00
{ \
_Fail ( " Access violation " ) ; \
return false ; \
}
2021-12-20 09:39:39 -05:00
# define CE_CHECKADDR_STR(STRNAME, ADDR) \
{ \
addr_ce checkAddr = ADDR ; \
while ( true ) \
{ \
if ( ( uintptr ) checkAddr > = ( uintptr ) memSize ) \
{ \
break ; \
} \
if ( memStart [ checkAddr ] = = 0 ) \
{ \
CE_CHECKADDR ( ADDR , checkAddr - ADDR + 1 ) ; \
STRNAME = String : : MakeRef ( ( char * ) memStart + ADDR , checkAddr - ADDR + 1 ) ; \
break ; \
} \
checkAddr + + ; \
} \
}
# define CE_GET_INTERNAL(VAR, ID, KIND) \
if ( ! mInternalDataMap . TryGetValue ( ( int ) ID , & VAR ) ) \
{ \
_Fail ( " Invalid internal resource id " ) ; \
return false ; \
} \
if ( VAR - > mKind ! = KIND ) \
{ \
_Fail ( " Invalid internal resource kind " ) ; \
return false ; \
} \
if ( VAR - > mReleased ) \
{ \
_Fail ( " Resource already released " ) ; \
return false ; \
}
# define CE_REMOVE_INTERNAL(VAR, ID, KIND) \
if ( ! mInternalDataMap . Remove ( ( int ) ID , & VAR ) ) \
{ \
_Fail ( " Invalid internal resource id " ) ; \
return false ; \
} \
if ( VAR - > mKind ! = KIND ) \
{ \
_Fail ( " Invalid internal resource kind " ) ; \
return false ; \
} \
if ( VAR - > mReleased ) \
{ \
_Fail ( " Resource already released " ) ; \
return false ; \
}
2021-01-11 09:41:43 -08:00
# define CE_GETINST(T) *((T*)(instPtr += sizeof(T)) - 1)
# define CE_GETFRAME(T) *(T*)(framePtr + *((int32*)(instPtr += sizeof(int32)) - 1))
# define CEOP_BIN(OP, T) \
{ \
auto & result = CE_GETFRAME ( T ) ; \
auto lhs = CE_GETFRAME ( T ) ; \
auto rhs = CE_GETFRAME ( T ) ; \
result = lhs OP rhs ; \
}
# define CEOP_BIN_DIV(OP, T) \
{ \
auto & result = CE_GETFRAME ( T ) ; \
auto lhs = CE_GETFRAME ( T ) ; \
auto rhs = CE_GETFRAME ( T ) ; \
if ( rhs = = 0 ) \
{ \
_Fail ( " Division by zero " ) ; \
return false ; \
} \
result = lhs OP rhs ; \
}
# define CEOP_BIN2(OP, TLHS, TRHS) \
{ \
auto & result = CE_GETFRAME ( TLHS ) ; \
auto lhs = CE_GETFRAME ( TLHS ) ; \
auto rhs = CE_GETFRAME ( TRHS ) ; \
result = lhs OP rhs ; \
}
# define CEOP_BIN_CONST(OP, T) \
{ \
auto & result = CE_GETFRAME ( T ) ; \
auto lhs = CE_GETFRAME ( T ) ; \
auto rhs = CE_GETINST ( T ) ; \
result = lhs OP rhs ; \
}
2021-01-26 06:33:23 -08:00
# 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 ) ; \
}
2021-01-11 09:41:43 -08:00
# define CEOP_UNARY(OP, T) \
{ \
auto & result = CE_GETFRAME ( T ) ; \
auto val = CE_GETFRAME ( T ) ; \
result = OP val ; \
}
# define CEOP_CMP(OP, T) \
{ \
auto & result = CE_GETFRAME ( bool ) ; \
auto lhs = CE_GETFRAME ( T ) ; \
auto rhs = CE_GETFRAME ( T ) ; \
result = lhs OP rhs ; \
}
# define CE_CAST(TFROM, TTO) \
{ \
auto & result = CE_GETFRAME ( TTO ) ; \
auto val = CE_GETFRAME ( TFROM ) ; \
result = ( TTO ) val ; \
}
# define CE_LOAD(T) \
{ \
auto & result = CE_GETFRAME ( T ) ; \
auto ceAddr = CE_GETFRAME ( addr_ce ) ; \
CE_CHECKADDR ( ceAddr , sizeof ( T ) ) ; \
result = * ( T * ) ( memStart + ceAddr ) ; \
}
# define CE_STORE(T) \
{ \
auto val = CE_GETFRAME ( T ) ; \
auto ceAddr = CE_GETFRAME ( addr_ce ) ; \
CE_CHECKADDR ( ceAddr , sizeof ( T ) ) ; \
* ( T * ) ( memStart + ceAddr ) = val ; \
}
# define CEOP_MOVE(T) \
{ \
auto val = CE_GETFRAME ( T ) ; \
auto & ptr = CE_GETFRAME ( T ) ; \
ptr = val ; \
}
# define CEOP_PUSH(T) \
{ \
stackPtr - = sizeof ( T ) ; \
auto val = CE_GETFRAME ( T ) ; \
* ( ( T * ) stackPtr ) = val ; \
CE_CHECKSTACK ( ) ; \
}
# define CEOP_POP(T) \
{ \
auto & result = CE_GETFRAME ( T ) ; \
result = * ( ( T * ) stackPtr ) ; \
stackPtr + = sizeof ( T ) ; \
}
# define CE_CALL(CEFUNC) \
if ( CEFUNC = = NULL ) \
{ \
_Fail ( " Unable to locate function entry " ) ; \
return false ; \
} \
mCallStack . Add ( _GetCurFrame ( ) ) ; \
ceFunction = CEFUNC ; \
framePtr = stackPtr ; \
stackPtr - = ceFunction - > mFrameSize ; \
instPtr = & ceFunction - > mCode [ 0 ] ; \
CE_CHECKSTACK ( ) ;
2021-12-20 09:39:39 -05:00
static void CeSetAddrVal ( void * ptr , int64 val , int32 ptrSize )
2021-01-13 05:09:09 -08:00
{
if ( ptrSize = = 4 )
* ( int32 * ) ( ptr ) = ( int32 ) val ;
else
* ( int64 * ) ( ptr ) = ( int64 ) val ;
}
2021-12-31 10:27:09 -05:00
class CeAsyncOperation
{
public :
CeInternalData * mInternalData ;
int mRefCount ;
void * mData ;
int mDataSize ;
int mReadSize ;
BfpFileResult mResult ;
public :
CeAsyncOperation ( )
{
mInternalData = NULL ;
mRefCount = 1 ;
mData = NULL ;
mDataSize = 0 ;
mReadSize = 0 ;
mResult = BfpFileResult_Ok ;
}
~ CeAsyncOperation ( )
{
mInternalData - > Release ( ) ;
delete mData ;
}
void AddRef ( )
{
BfpSystem_InterlockedExchangeAdd32 ( ( uint32 * ) & mRefCount , 1 ) ;
}
void Release ( )
{
if ( BfpSystem_InterlockedExchangeAdd32 ( ( uint32 * ) & mRefCount , ( uint32 ) - 1 ) = = 1 )
delete this ;
}
void Run ( )
{
mReadSize = BfpFile_Read ( mInternalData - > mFile , mData , mDataSize , - 1 , & mResult ) ;
Release ( ) ;
}
static void RunProc ( void * ptr )
{
( ( CeAsyncOperation * ) ptr ) - > Run ( ) ;
}
} ;
2021-01-11 09:41:43 -08:00
bool CeContext : : Execute ( CeFunction * startFunction , uint8 * startStackPtr , uint8 * startFramePtr , BfType * & returnType )
2021-02-25 10:14:22 -08:00
{
2021-01-11 09:41:43 -08:00
auto ceModule = mCeMachine - > mCeModule ;
CeFunction * ceFunction = startFunction ;
returnType = startFunction - > mMethodInstance - > mReturnType ;
uint8 * memStart = & mMemory [ 0 ] ;
int memSize = mMemory . mSize ;
uint8 * instPtr = ( ceFunction - > mCode . IsEmpty ( ) ) ? NULL : & ceFunction - > mCode [ 0 ] ;
uint8 * stackPtr = startStackPtr ;
uint8 * framePtr = startFramePtr ;
bool needsFunctionIds = ceModule - > mSystem - > mPtrSize ! = 8 ;
int32 ptrSize = ceModule - > mSystem - > mPtrSize ;
volatile bool * fastFinishPtr = & mCeMachine - > mCompiler - > mFastFinish ;
volatile bool * cancelingPtr = & mCeMachine - > mCompiler - > mCanceling ;
auto _GetCurFrame = [ & ] ( )
{
CeFrame ceFrame ;
ceFrame . mFunction = ceFunction ;
ceFrame . mReturnType = returnType ;
ceFrame . mFrameAddr = framePtr - memStart ;
ceFrame . mStackAddr = stackPtr - memStart ;
ceFrame . mInstPtr = instPtr ;
return ceFrame ;
2020-12-17 04:51:05 -08:00
} ;
2021-01-11 09:41:43 -08:00
auto _FixVariables = [ & ] ( )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
memSize = mMemory . mSize ;
intptr memOffset = & mMemory [ 0 ] - memStart ;
if ( memOffset = = 0 )
return ;
memStart + = memOffset ;
stackPtr + = memOffset ;
framePtr + = memOffset ;
} ;
2020-12-17 04:51:05 -08:00
2021-01-11 09:41:43 -08:00
auto _Fail = [ & ] ( const StringImpl & error )
{
Fail ( _GetCurFrame ( ) , error ) ;
} ;
2020-12-17 04:51:05 -08:00
2021-01-11 09:41:43 -08:00
auto _CheckFunction = [ & ] ( CeFunction * checkFunction , bool & handled )
{
if ( checkFunction = = NULL )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
Fail ( _GetCurFrame ( ) , " Const method not available " ) ;
2020-12-17 04:51:05 -08:00
return false ;
}
2021-01-11 09:41:43 -08:00
if ( checkFunction - > mFunctionKind ! = CeFunctionKind_Normal )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
if ( checkFunction - > mFunctionKind = = CeFunctionKind_OOB )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
Fail ( _GetCurFrame ( ) , " Array out of bounds " ) ;
return false ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Malloc )
2020-12-13 08:04:42 -08:00
{
2021-12-20 15:07:38 -05:00
int64 size ;
if ( ptrSize = = 4 )
size = * ( int32 * ) ( ( uint8 * ) stackPtr + 4 ) ;
else
size = * ( int64 * ) ( ( uint8 * ) stackPtr + 8 ) ;
2021-01-11 09:41:43 -08:00
CE_CHECKALLOC ( size ) ;
2021-01-16 12:35:51 -08:00
uint8 * ptr = CeMalloc ( size ) ;
CeSetAddrVal ( stackPtr + 0 , ptr - memStart , ptrSize ) ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Free )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
addr_ce freeAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 4 ) ;
bool success = CeFree ( freeAddr ) ;
if ( ! success )
_Fail ( " Invalid heap address " ) ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_FatalError )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
int32 strInstAddr = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
CE_CHECKADDR ( strInstAddr , 0 ) ;
2020-12-17 04:51:05 -08:00
2021-01-11 09:41:43 -08:00
BfTypeInstance * stringTypeInst = ( BfTypeInstance * ) ceModule - > ResolveTypeDef ( mCeMachine - > mCompiler - > mStringTypeDef , BfPopulateType_Data ) ;
auto lenByteCount = stringTypeInst - > mFieldInstances [ 0 ] . mResolvedType - > mSize ;
auto lenOffset = stringTypeInst - > mFieldInstances [ 0 ] . mDataOffset ;
auto allocSizeOffset = stringTypeInst - > mFieldInstances [ 1 ] . mDataOffset ;
auto ptrOffset = stringTypeInst - > mFieldInstances [ 2 ] . mDataOffset ;
uint8 * strInst = ( uint8 * ) ( strInstAddr + memStart ) ;
int32 lenVal = * ( int32 * ) ( strInst + lenOffset ) ;
char * charPtr = NULL ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
if ( lenByteCount = = 4 )
{
int32 allocSizeVal = * ( int32 * ) ( strInst + allocSizeOffset ) ;
if ( ( allocSizeVal & 0x40000000 ) ! = 0 )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
int32 ptrVal = * ( int32 * ) ( strInst + ptrOffset ) ;
charPtr = ( char * ) ( ptrVal + memStart ) ;
2020-12-19 14:19:33 -08:00
}
else
2021-01-11 09:41:43 -08:00
{
charPtr = ( char * ) ( strInst + ptrOffset ) ;
}
2020-12-17 04:51:05 -08:00
}
2021-12-20 15:07:38 -05:00
else
{
int64 allocSizeVal = * ( int64 * ) ( strInst + allocSizeOffset ) ;
if ( ( allocSizeVal & 0x4000000000000000LL ) ! = 0 )
{
int32 ptrVal = * ( int32 * ) ( strInst + ptrOffset ) ;
charPtr = ( char * ) ( ptrVal + memStart ) ;
}
else
{
charPtr = ( char * ) ( strInst + ptrOffset ) ;
}
}
2021-01-11 09:41:43 -08:00
int32 ptrVal = * ( int32 * ) ( strInst + ptrOffset ) ;
String error = " Fatal Error: " ;
if ( charPtr ! = NULL )
error . Insert ( error . length ( ) , charPtr , lenVal ) ;
_Fail ( error ) ;
return false ;
2020-12-17 04:51:05 -08:00
}
2021-01-26 06:33:23 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_DynCheckFailed )
{
_Fail ( " Dynamic cast check failed " ) ;
return false ;
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_DebugWrite )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
int32 ptrVal = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
auto size = * ( int32 * ) ( stackPtr + ceModule - > mSystem - > mPtrSize ) ;
CE_CHECKADDR ( ptrVal , size ) ;
char * strPtr = ( char * ) ( ptrVal + memStart ) ;
String str ;
str . Insert ( 0 , strPtr , size ) ;
OutputDebugStr ( str ) ;
2020-12-17 04:51:05 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_DebugWrite_Int )
2020-12-17 04:51:05 -08:00
{
2021-12-20 09:39:39 -05:00
if ( ceModule - > mSystem - > mPtrSize = = 4 )
{
int32 intVal = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
2021-12-20 12:03:09 -05:00
OutputDebugStrF ( " Debug Val: %d %X \n " , intVal , intVal ) ;
2021-12-20 09:39:39 -05:00
}
else
{
int64 intVal = * ( int64 * ) ( ( uint8 * ) stackPtr + 0 ) ;
2021-12-20 12:03:09 -05:00
OutputDebugStrF ( " Debug Val: %lld %llX \n " , intVal , intVal ) ;
2021-12-20 09:39:39 -05:00
}
2020-12-17 04:51:05 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_GetReflectType )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
addr_ce objAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ceModule - > mSystem - > mPtrSize ) ;
2021-12-20 15:07:38 -05:00
CE_CHECKADDR ( objAddr , 4 ) ;
2021-01-11 09:41:43 -08:00
int32 typeId = * ( int32 * ) ( objAddr + memStart ) ;
auto reflectType = GetReflectType ( typeId ) ;
_FixVariables ( ) ;
2021-01-16 12:35:51 -08:00
CeSetAddrVal ( stackPtr + 0 , reflectType , ptrSize ) ;
2020-12-17 04:51:05 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_GetReflectTypeById )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
int32 typeId = * ( int32 * ) ( ( uint8 * ) stackPtr + ceModule - > mSystem - > mPtrSize ) ;
auto reflectType = GetReflectType ( typeId ) ;
_FixVariables ( ) ;
2021-01-16 12:35:51 -08:00
CeSetAddrVal ( stackPtr + 0 , reflectType , ptrSize ) ;
2020-12-17 04:51:05 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_GetReflectTypeByName )
2020-12-23 11:27:46 -08:00
{
2021-01-11 09:41:43 -08:00
addr_ce strViewPtr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
String typeName ;
if ( ! GetStringFromStringView ( strViewPtr , typeName ) )
{
_Fail ( " Invalid StringView " ) ;
return false ;
}
auto reflectType = GetReflectType ( typeName ) ;
_FixVariables ( ) ;
2021-01-16 12:35:51 -08:00
CeSetAddrVal ( stackPtr + 0 , reflectType , ptrSize ) ;
2020-12-23 11:27:46 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_GetReflectSpecializedType )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
addr_ce typeAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce typeSpan = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize * 2 ) ;
auto reflectType = GetReflectSpecializedType ( typeAddr , typeSpan ) ;
_FixVariables ( ) ;
2021-01-16 12:35:51 -08:00
CeSetAddrVal ( stackPtr + 0 , reflectType , ptrSize ) ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Type_GetCustomAttribute )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
int32 typeId = * ( int32 * ) ( ( uint8 * ) stackPtr + 1 ) ;
int32 attributeTypeId = * ( int32 * ) ( ( uint8 * ) stackPtr + 1 + 4 ) ;
addr_ce resultPtr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 1 + 4 + 4 ) ;
BfType * type = GetBfType ( typeId ) ;
bool success = false ;
if ( type ! = NULL )
{
auto typeInst = type - > ToTypeInstance ( ) ;
if ( typeInst ! = NULL )
success = GetCustomAttribute ( typeInst - > mCustomAttributes , attributeTypeId , resultPtr ) ;
}
* ( addr_ce * ) ( stackPtr + 0 ) = success ;
2020-12-19 14:19:33 -08:00
}
2021-01-13 05:09:09 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_GetMethodCount )
{
int32 typeId = * ( int32 * ) ( ( uint8 * ) stackPtr + 4 ) ;
CeTypeInfo * typeInfo = mCeMachine - > GetTypeInfo ( GetBfType ( typeId ) ) ;
if ( typeInfo = = NULL )
{
_Fail ( " Invalid type " ) ;
return false ;
}
* ( int32 * ) ( stackPtr + 0 ) = ( int ) typeInfo - > mMethodInstances . size ( ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_GetMethod )
{
int32 typeId = * ( int32 * ) ( ( uint8 * ) stackPtr + 8 ) ;
int32 methodIdx = * ( int32 * ) ( ( uint8 * ) stackPtr + 8 + 4 ) ;
CeTypeInfo * typeInfo = mCeMachine - > GetTypeInfo ( GetBfType ( typeId ) ) ;
if ( typeInfo = = NULL )
{
_Fail ( " Invalid type " ) ;
return false ;
}
if ( ( methodIdx < 0 ) | | ( methodIdx > = typeInfo - > mMethodInstances . mSize ) )
{
_Fail ( " Method out of bounds " ) ;
return false ;
}
* ( int64 * ) ( stackPtr + 0 ) = ( int64 ) ( intptr ) typeInfo - > mMethodInstances [ methodIdx ] ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Method_ToString )
{
int64 methodHandle = * ( int64 * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
auto methodInstance = mCeMachine - > GetMethodInstance ( methodHandle ) ;
if ( methodInstance = = NULL )
{
_Fail ( " Invalid method instance " ) ;
return false ;
}
CeSetAddrVal ( stackPtr + 0 , GetString ( mCeMachine - > mCeModule - > MethodToString ( methodInstance ) ) , ptrSize ) ;
_FixVariables ( ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Method_GetName )
{
int64 methodHandle = * ( int64 * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
auto methodInstance = mCeMachine - > GetMethodInstance ( methodHandle ) ;
if ( methodInstance = = NULL )
{
_Fail ( " Invalid method instance " ) ;
return false ;
}
CeSetAddrVal ( stackPtr + 0 , GetString ( methodInstance - > mMethodDef - > mName ) , ptrSize ) ;
_FixVariables ( ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Method_GetInfo )
{
// int32 mReturnType
// int32 mParamCount
// int16 mFlags
int64 methodHandle = * ( int64 * ) ( ( uint8 * ) stackPtr + 4 + 4 + 2 ) ;
auto methodInstance = mCeMachine - > GetMethodInstance ( methodHandle ) ;
if ( methodInstance = = NULL )
{
_Fail ( " Invalid method instance " ) ;
return false ;
}
* ( int32 * ) ( stackPtr + 0 ) = methodInstance - > mReturnType - > mTypeId ;
* ( int32 * ) ( stackPtr + 4 ) = methodInstance - > GetParamCount ( ) ;
2021-01-26 06:33:23 -08:00
* ( int16 * ) ( stackPtr + 4 + 4 ) = methodInstance - > GetMethodFlags ( ) ;
2021-01-13 05:09:09 -08:00
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Method_GetParamInfo )
{
// int32 mParamType
// int16 mFlags
// str mName
int64 methodHandle = * ( int64 * ) ( ( uint8 * ) stackPtr + 4 + 2 + ptrSize ) ;
int32 paramIdx = * ( int32 * ) ( ( uint8 * ) stackPtr + 4 + 2 + ptrSize + 8 ) ;
auto methodInstance = mCeMachine - > GetMethodInstance ( methodHandle ) ;
if ( methodInstance = = NULL )
{
_Fail ( " Invalid method instance " ) ;
return false ;
}
2021-05-23 11:32:40 +02:00
2021-05-23 11:47:39 +02:00
if ( paramIdx < 0 | | paramIdx > = methodInstance - > mParams . mSize )
2021-05-23 11:32:40 +02:00
{
_Fail ( " paramIdx is out of range " ) ;
return false ;
}
2021-01-16 12:35:51 -08:00
addr_ce stringAddr = GetString ( methodInstance - > GetParamName ( paramIdx ) ) ;
_FixVariables ( ) ;
2021-01-13 05:09:09 -08:00
* ( int32 * ) ( stackPtr + 0 ) = methodInstance - > GetParamType ( paramIdx ) - > mTypeId ;
* ( int16 * ) ( stackPtr + 4 ) = 0 ; // Flags
2021-01-26 06:33:23 -08:00
CeSetAddrVal ( stackPtr + 4 + 2 , stringAddr , ptrSize ) ;
2021-01-13 05:09:09 -08:00
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_EmitTypeBody )
2020-12-22 04:50:37 -08:00
{
2021-01-11 09:41:43 -08:00
int32 typeId = * ( int32 * ) ( ( uint8 * ) stackPtr ) ;
addr_ce strViewPtr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + sizeof ( int32 ) ) ;
if ( ( mCurEmitContext = = NULL ) | | ( mCurEmitContext - > mType - > mTypeId ! = typeId ) )
2020-12-22 04:50:37 -08:00
{
2021-01-11 09:41:43 -08:00
_Fail ( " Code cannot be emitted for this type in this context " ) ;
return false ;
}
if ( ! GetStringFromStringView ( strViewPtr , mCurEmitContext - > mEmitData ) )
{
_Fail ( " Invalid StringView " ) ;
return false ;
2020-12-22 04:50:37 -08:00
}
}
2021-12-16 09:38:19 -05:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_EmitAddInterface )
{
int32 typeId = * ( int32 * ) ( ( uint8 * ) stackPtr ) ;
int32 ifaceTypeId = * ( int32 * ) ( ( uint8 * ) stackPtr + sizeof ( int32 ) ) ;
if ( ( mCurEmitContext = = NULL ) | | ( mCurEmitContext - > mType - > mTypeId ! = typeId ) )
{
_Fail ( " Code cannot be emitted for this type in this context " ) ;
return false ;
}
mCurEmitContext - > mInterfaces . Add ( ifaceTypeId ) ;
}
2021-01-13 05:09:09 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_EmitMethodEntry )
{
int64 methodHandle = * ( int64 * ) ( ( uint8 * ) stackPtr ) ;
addr_ce strViewPtr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + sizeof ( int64 ) ) ;
if ( ( mCurEmitContext = = NULL ) | | ( mCurEmitContext - > mMethodInstance = = NULL ) | |
( methodHandle ! = ( int64 ) mCurEmitContext - > mMethodInstance ) )
{
_Fail ( " Code cannot be emitted for this method in this context " ) ;
return false ;
}
if ( ! GetStringFromStringView ( strViewPtr , mCurEmitContext - > mEmitData ) )
{
_Fail ( " Invalid StringView " ) ;
return false ;
}
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_EmitMethodExit )
{
int64 methodHandle = * ( int64 * ) ( ( uint8 * ) stackPtr ) ;
addr_ce strViewPtr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + sizeof ( int64 ) ) ;
if ( ( mCurEmitContext = = NULL ) | | ( mCurEmitContext - > mMethodInstance = = NULL ) | |
( methodHandle ! = ( int64 ) mCurEmitContext - > mMethodInstance ) )
{
_Fail ( " Code cannot be emitted for this method in this context " ) ;
return false ;
}
if ( ! GetStringFromStringView ( strViewPtr , mCurEmitContext - > mExitEmitData ) )
{
_Fail ( " Invalid StringView " ) ;
return false ;
}
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_EmitMixin )
{
addr_ce strViewPtr = * ( addr_ce * ) ( ( uint8 * ) stackPtr ) ;
String emitStr ;
if ( ! GetStringFromStringView ( strViewPtr , emitStr ) )
{
_Fail ( " Invalid StringView " ) ;
return false ;
}
mCurModule - > CEMixin ( mCurTargetSrc , emitStr ) ;
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Sleep )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
int32 sleepMS = * ( int32 * ) ( ( uint8 * ) stackPtr ) ;
while ( sleepMS > 0 )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
if ( * fastFinishPtr )
break ;
2020-12-22 04:50:37 -08:00
2021-12-31 10:27:09 -05:00
if ( sleepMS > 20 )
2020-12-19 14:19:33 -08:00
{
2021-12-31 10:27:09 -05:00
BfpThread_Sleep ( 20 ) ;
sleepMS - = 20 ;
2021-01-11 09:41:43 -08:00
continue ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
BfpThread_Sleep ( sleepMS ) ;
break ;
2020-12-19 14:19:33 -08:00
}
2021-01-26 06:33:23 -08:00
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpSystem_GetTimeStamp )
{
int64 & result = * ( int64 * ) ( ( uint8 * ) stackPtr + 0 ) ;
result = BfpSystem_GetTimeStamp ( ) ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Char32_ToLower )
2020-12-14 03:50:28 -08:00
{
2021-01-11 09:41:43 -08:00
int32 & result = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
int32 val = * ( int32 * ) ( ( uint8 * ) stackPtr + 4 ) ;
2021-01-26 06:33:23 -08:00
result = utf8proc_tolower ( val ) ;
2020-12-14 03:50:28 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Char32_ToUpper )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
int32 & result = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
int32 val = * ( int32 * ) ( ( uint8 * ) stackPtr + 4 ) ;
2021-01-26 06:33:23 -08:00
result = utf8proc_toupper ( val ) ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Char32_IsLower )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
int32 & result = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
int32 val = * ( int32 * ) ( ( uint8 * ) stackPtr + 1 ) ;
2021-01-26 06:33:23 -08:00
result = utf8proc_category ( val ) = = UTF8PROC_CATEGORY_LL ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Char32_IsUpper )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
int32 & result = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
int32 val = * ( int32 * ) ( ( uint8 * ) stackPtr + 1 ) ;
2021-01-26 06:33:23 -08:00
result = utf8proc_category ( val ) = = UTF8PROC_CATEGORY_LU ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Char32_IsWhiteSpace_EX )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
int32 & result = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
int32 val = * ( int32 * ) ( ( uint8 * ) stackPtr + 1 ) ;
auto cat = utf8proc_category ( val ) ;
2021-01-26 06:33:23 -08:00
result = ( cat = = UTF8PROC_CATEGORY_ZS ) | | ( cat = = UTF8PROC_CATEGORY_ZL ) | | ( cat = = UTF8PROC_CATEGORY_ZP ) ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Char32_IsLetterOrDigit )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
int32 & result = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
int32 val = * ( int32 * ) ( ( uint8 * ) stackPtr + 1 ) ;
auto cat = utf8proc_category ( val ) ;
switch ( cat )
{
case UTF8PROC_CATEGORY_LU :
case UTF8PROC_CATEGORY_LL :
case UTF8PROC_CATEGORY_LT :
case UTF8PROC_CATEGORY_LM :
case UTF8PROC_CATEGORY_LO :
case UTF8PROC_CATEGORY_ND :
case UTF8PROC_CATEGORY_NL :
case UTF8PROC_CATEGORY_NO :
result = true ;
break ;
default :
result = false ;
2021-01-26 06:33:23 -08:00
}
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Char32_IsLetter )
2020-12-22 04:50:37 -08:00
{
2021-01-11 09:41:43 -08:00
int32 & result = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
int32 val = * ( int32 * ) ( ( uint8 * ) stackPtr + 1 ) ;
auto cat = utf8proc_category ( val ) ;
switch ( cat )
{
case UTF8PROC_CATEGORY_LU :
case UTF8PROC_CATEGORY_LL :
case UTF8PROC_CATEGORY_LT :
case UTF8PROC_CATEGORY_LM :
case UTF8PROC_CATEGORY_LO :
result = true ;
break ;
default :
result = false ;
2021-01-26 06:33:23 -08:00
}
2021-01-11 09:41:43 -08:00
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_Char32_IsNumber )
{
int32 & result = * ( int32 * ) ( ( uint8 * ) stackPtr + 0 ) ;
int32 val = * ( int32 * ) ( ( uint8 * ) stackPtr + 1 ) ;
auto cat = utf8proc_category ( val ) ;
switch ( cat )
{
case UTF8PROC_CATEGORY_ND :
case UTF8PROC_CATEGORY_NL :
case UTF8PROC_CATEGORY_NO :
result = true ;
break ;
default :
result = false ;
2021-01-26 06:33:23 -08:00
}
}
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 ) ;
2021-12-20 09:39:39 -05:00
addr_ce checkAddr = strAddr ;
2021-01-26 06:33:23 -08:00
while ( true )
{
if ( ( uintptr ) checkAddr > = ( uintptr ) memSize )
{
checkAddr + + ;
break ;
}
if ( memStart [ checkAddr ] = = 0 )
break ;
2021-12-20 09:39:39 -05:00
checkAddr + + ;
2021-01-26 06:33:23 -08:00
}
CE_CHECKADDR ( strAddr , checkAddr - strAddr + 1 ) ;
2021-12-20 09:39:39 -05:00
char * strPtr = ( char * ) ( memStart + strAddr ) ;
2021-01-26 06:33:23 -08:00
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 ) ;
2021-01-11 09:41:43 -08:00
}
}
2021-01-26 06:33:23 -08:00
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 ;
}
2021-12-28 15:49:50 -05:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpDirectory_Create )
{
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( path ) ;
2021-12-28 15:49:50 -05:00
BfpDirectory_Create ( path . c_str ( ) , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpDirectory_Rename )
{
addr_ce srcAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce destAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
String srcPath ;
CE_CHECKADDR_STR ( srcPath , srcAddr ) ;
String destPath ;
CE_CHECKADDR_STR ( destPath , destAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( srcPath ) ;
FixProjectRelativePath ( destPath ) ;
2021-12-28 15:49:50 -05:00
BfpDirectory_Rename ( srcPath . c_str ( ) , destPath . c_str ( ) , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpDirectory_Delete )
{
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( path ) ;
2021-12-28 15:49:50 -05:00
BfpDirectory_Delete ( path . c_str ( ) , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpDirectory_GetCurrent )
{
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce sizeAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
CE_CHECKADDR ( sizeAddr , 4 ) ;
int & nameSize = * ( int * ) ( memStart + sizeAddr ) ;
CE_CHECKADDR ( nameAddr , nameSize ) ;
char * namePtr = ( char * ) ( memStart + nameAddr ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
BfpDirectory_GetCurrent ( namePtr , & nameSize , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpDirectory_SetCurrent )
{
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( path ) ;
2021-12-28 15:49:50 -05:00
BfpDirectory_SetCurrent ( path . c_str ( ) , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpDirectory_Exists )
{
bool & result = * ( bool * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 1 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( path ) ;
2021-12-28 15:49:50 -05:00
result = BfpDirectory_Exists ( path . c_str ( ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpDirectory_GetSysDirectory )
{
BfpSysDirectoryKind sysDirKind = * ( BfpSysDirectoryKind * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 4 ) ;
addr_ce sizeAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 4 + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 4 + ptrSize + ptrSize ) ;
CE_CHECKADDR ( sizeAddr , 4 ) ;
int & nameSize = * ( int * ) ( memStart + sizeAddr ) ;
CE_CHECKADDR ( nameAddr , nameSize ) ;
char * namePtr = ( char * ) ( memStart + nameAddr ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
BfpDirectory_GetSysDirectory ( sysDirKind , namePtr , & nameSize , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
2021-12-20 09:39:39 -05:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Close )
{
addr_ce fileId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
CE_CHECKADDR ( outResultAddr , 4 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) fileId , CeInternalData : : Kind_File ) ;
BfpFile_Close ( internalData - > mFile , ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Create )
{
void * resultPtr = ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
int createKind = * ( int * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
int createFlags = * ( int * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + 4 ) ;
int createFileAttrs = * ( int * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + 4 + 4 ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + 4 + 4 + 4 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
2021-12-31 06:28:25 -05:00
CE_CHECKADDR ( outResultAddr , 4 ) ;
FixProjectRelativePath ( path ) ;
2021-12-20 09:39:39 -05:00
auto bfpFile = BfpFile_Create ( path . c_str ( ) , ( BfpFileCreateKind ) createKind , ( BfpFileCreateFlags ) createFlags , ( BfpFileAttributes ) createFileAttrs , ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
if ( bfpFile ! = NULL )
{
if ( ( createKind = = BfpFileCreateKind_OpenExisting ) | | ( createKind = = BfpFileCreateKind_OpenAlways ) )
2021-12-29 10:07:36 -05:00
AddFileRebuild ( path ) ;
2021-12-20 09:39:39 -05:00
CeInternalData * internalData = new CeInternalData ( ) ;
internalData - > mKind = CeInternalData : : Kind_File ;
internalData - > mFile = bfpFile ;
mInternalDataMap [ + + mCurHandleId ] = internalData ;
CeSetAddrVal ( resultPtr , mCurHandleId , ptrSize ) ;
}
else
CeSetAddrVal ( resultPtr , 0 , ptrSize ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Flush )
{
addr_ce fileId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) fileId , CeInternalData : : Kind_File ) ;
BfpFile_Flush ( internalData - > mFile ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_GetFileSize )
{
int64 & result = * ( int64 * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce fileId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 8 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) fileId , CeInternalData : : Kind_File ) ;
result = BfpFile_GetFileSize ( internalData - > mFile ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Read )
{
void * resultPtr = ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce fileId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce bufferPtr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
intptr bufferSize = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize ) ;
int timeoutMS = * ( int32 * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize ) ;
CE_CHECKADDR ( bufferPtr , bufferSize ) ;
CE_CHECKADDR ( outResultAddr , 4 ) ;
2021-12-31 10:27:09 -05:00
BfpFileResult fileResult = BfpFileResult_UnknownError ;
2021-12-20 09:39:39 -05:00
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) fileId , CeInternalData : : Kind_File ) ;
2021-12-31 10:27:09 -05:00
int timeoutLeft = timeoutMS ;
int64 result = 0 ;
CeAsyncOperation * asyncOperation = NULL ;
BfpThread * asyncThread = NULL ;
while ( true )
{
if ( * cancelingPtr )
break ;
int useTimeout = timeoutLeft ;
if ( useTimeout < 0 )
{
useTimeout = 20 ;
}
else if ( useTimeout > 20 )
{
useTimeout = 20 ;
timeoutLeft - = useTimeout ;
}
else
timeoutLeft = 0 ;
if ( asyncOperation ! = NULL )
{
if ( BfpThread_WaitFor ( asyncThread , useTimeout ) )
{
if ( asyncOperation - > mReadSize > 0 )
memcpy ( memStart + bufferPtr , asyncOperation - > mData , asyncOperation - > mReadSize ) ;
result = asyncOperation - > mReadSize ;
fileResult = asyncOperation - > mResult ;
break ;
}
continue ;
}
result = BfpFile_Read ( internalData - > mFile , memStart + bufferPtr , bufferSize , useTimeout , & fileResult ) ;
if ( fileResult = = BfpFileResult_Timeout )
{
if ( timeoutLeft > 0 )
continue ;
}
if ( fileResult ! = BfpFileResult_InvalidParameter )
break ;
BF_ASSERT ( asyncOperation = = NULL ) ;
asyncOperation = new CeAsyncOperation ( ) ;
asyncOperation - > mInternalData = internalData ;
asyncOperation - > mInternalData - > AddRef ( ) ;
asyncOperation - > mData = new uint8 [ bufferSize ] ;
asyncOperation - > mDataSize = bufferSize ;
asyncOperation - > AddRef ( ) ;
asyncThread = BfpThread_Create ( CeAsyncOperation : : RunProc , asyncOperation ) ;
}
if ( asyncOperation ! = NULL )
asyncOperation - > Release ( ) ;
if ( asyncThread ! = NULL )
BfpThread_Release ( asyncThread ) ;
if ( outResultAddr ! = 0 )
* ( BfpFileResult * ) ( memStart + outResultAddr ) = fileResult ;
2021-12-20 09:39:39 -05:00
CeSetAddrVal ( resultPtr , result , ptrSize ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Release )
{
addr_ce fileId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
CeInternalData * internalData = NULL ;
CE_REMOVE_INTERNAL ( internalData , ( int ) fileId , CeInternalData : : Kind_File ) ;
2021-12-31 10:27:09 -05:00
internalData - > Release ( ) ;
2021-12-20 09:39:39 -05:00
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Seek )
{
int64 & result = * ( int64 * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce fileId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 8 ) ;
int64 offset = * ( int64 * ) ( ( uint8 * ) stackPtr + 8 + ptrSize ) ;
int seekKind = * ( int * ) ( ( uint8 * ) stackPtr + 8 + ptrSize + 8 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) fileId , CeInternalData : : Kind_File ) ;
result = BfpFile_Seek ( internalData - > mFile , offset , ( BfpFileSeekKind ) seekKind ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Truncate )
{
addr_ce fileId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
CE_CHECKADDR ( outResultAddr , 4 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) fileId , CeInternalData : : Kind_File ) ;
BfpFile_Truncate ( internalData - > mFile , ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Write )
{
void * resultPtr = ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce fileId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce bufferPtr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
intptr bufferSize = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize ) ;
int timeoutMS = * ( int32 * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize ) ;
CE_CHECKADDR ( bufferPtr , bufferSize ) ;
CE_CHECKADDR ( outResultAddr , 4 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) fileId , CeInternalData : : Kind_File ) ;
2021-12-20 15:37:01 -05:00
int64 result = BfpFile_Write ( internalData - > mFile , memStart + bufferPtr , bufferSize , timeoutMS , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
2021-12-20 09:39:39 -05:00
CeSetAddrVal ( resultPtr , result , ptrSize ) ;
}
2021-12-28 15:49:50 -05:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_GetTime_LastWrite )
{
BfpTimeStamp & result = * ( BfpTimeStamp * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 8 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( path ) ;
2021-12-29 10:07:36 -05:00
AddFileRebuild ( path ) ;
2021-12-28 15:49:50 -05:00
result = BfpFile_GetTime_LastWrite ( path . c_str ( ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_GetAttributes )
{
BfpFileAttributes & result = * ( BfpFileAttributes * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 4 ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + 4 ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( path ) ;
2021-12-28 15:49:50 -05:00
result = BfpFile_GetAttributes ( path . c_str ( ) , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_SetAttributes )
{
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
BfpFileAttributes attribs = * ( BfpFileAttributes * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( path ) ;
2021-12-28 15:49:50 -05:00
BfpFile_SetAttributes ( path . c_str ( ) , attribs , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Copy )
{
addr_ce srcAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce destAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
BfpFileCopyKind fileCopyKind = * ( BfpFileCopyKind * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + 4 ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
String srcPath ;
CE_CHECKADDR_STR ( srcPath , srcAddr ) ;
String destPath ;
CE_CHECKADDR_STR ( destPath , destAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( srcPath ) ;
FixProjectRelativePath ( destPath ) ;
2021-12-28 15:49:50 -05:00
BfpFile_Copy ( srcPath . c_str ( ) , destPath . c_str ( ) , fileCopyKind , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Rename )
{
addr_ce srcAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce destAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
String srcPath ;
CE_CHECKADDR_STR ( srcPath , srcAddr ) ;
String destPath ;
CE_CHECKADDR_STR ( destPath , destAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( srcPath ) ;
FixProjectRelativePath ( destPath ) ;
2021-12-28 15:49:50 -05:00
BfpFile_Rename ( srcPath . c_str ( ) , destPath . c_str ( ) , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Delete )
{
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( path ) ;
2021-12-28 15:49:50 -05:00
BfpFile_Delete ( path . c_str ( ) , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_Exists )
{
bool & result = * ( bool * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 1 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( path ) ;
2021-12-29 10:07:36 -05:00
AddFileRebuild ( path ) ;
2021-12-28 15:49:50 -05:00
result = BfpFile_Exists ( path . c_str ( ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_GetTempPath )
{
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce sizeAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
CE_CHECKADDR ( sizeAddr , 4 ) ;
int & nameSize = * ( int * ) ( memStart + sizeAddr ) ;
CE_CHECKADDR ( nameAddr , nameSize ) ;
char * namePtr = ( char * ) ( memStart + nameAddr ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
BfpFile_GetTempPath ( namePtr , & nameSize , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_GetTempFileName )
{
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce sizeAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
CE_CHECKADDR ( sizeAddr , 4 ) ;
int & nameSize = * ( int * ) ( memStart + sizeAddr ) ;
CE_CHECKADDR ( nameAddr , nameSize ) ;
char * namePtr = ( char * ) ( memStart + nameAddr ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
BfpFile_GetTempFileName ( namePtr , & nameSize , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_GetFullPath )
{
addr_ce srcAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce sizeAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize ) ;
String srcPath ;
CE_CHECKADDR_STR ( srcPath , srcAddr ) ;
CE_CHECKADDR ( sizeAddr , 4 ) ;
int & nameSize = * ( int * ) ( memStart + sizeAddr ) ;
CE_CHECKADDR ( nameAddr , nameSize ) ;
char * namePtr = ( char * ) ( memStart + nameAddr ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( srcPath ) ;
2021-12-28 15:49:50 -05:00
BfpFile_GetFullPath ( srcPath . c_str ( ) , namePtr , & nameSize , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFile_GetActualPath )
{
addr_ce srcAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce sizeAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize ) ;
String srcPath ;
CE_CHECKADDR_STR ( srcPath , srcAddr ) ;
CE_CHECKADDR ( sizeAddr , 4 ) ;
int & nameSize = * ( int * ) ( memStart + sizeAddr ) ;
CE_CHECKADDR ( nameAddr , nameSize ) ;
char * namePtr = ( char * ) ( memStart + nameAddr ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( srcPath ) ;
2021-12-28 15:49:50 -05:00
BfpFile_GetActualPath ( srcPath . c_str ( ) , namePtr , & nameSize , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
2021-12-20 09:39:39 -05:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpSpawn_Create )
{
void * resultPtr = ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce targetPathAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce argsAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
addr_ce workingDirAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize ) ;
addr_ce envAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize + ptrSize ) ;
int flags = * ( int * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize ) ;
2021-12-20 15:24:25 -05:00
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize + ptrSize + ptrSize + 4 ) ;
2021-12-20 09:39:39 -05:00
String targetPath ;
CE_CHECKADDR_STR ( targetPath , targetPathAddr ) ;
String args ;
2021-12-20 15:24:25 -05:00
if ( argsAddr ! = 0 )
CE_CHECKADDR_STR ( args , argsAddr ) ;
2021-12-20 09:39:39 -05:00
String workingDir ;
2021-12-20 15:24:25 -05:00
if ( workingDirAddr ! = 0 )
CE_CHECKADDR_STR ( workingDir , workingDirAddr ) ;
2021-12-20 09:39:39 -05:00
String env ;
2021-12-20 15:24:25 -05:00
if ( envAddr ! = 0 )
CE_CHECKADDR_STR ( env , envAddr ) ;
2021-12-28 15:49:50 -05:00
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
2021-12-20 15:24:25 -05:00
if ( ( targetPath . Contains ( ' / ' ) ) | | ( targetPath . Contains ( ' \\ ' ) ) )
{
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( targetPath ) ;
2021-12-20 15:24:25 -05:00
}
2021-12-20 09:39:39 -05:00
2021-12-20 15:24:25 -05:00
auto bfpSpawn = BfpSpawn_Create ( targetPath . c_str ( ) ,
( argsAddr = = 0 ) ? NULL : args . c_str ( ) ,
( workingDirAddr = = 0 ) ? NULL : workingDir . c_str ( ) ,
2021-12-20 15:37:01 -05:00
( envAddr = = 0 ) ? NULL : env . c_str ( ) , ( BfpSpawnFlags ) flags , ( outResultAddr = = 0 ) ? NULL : ( BfpSpawnResult * ) ( memStart + outResultAddr ) ) ;
2021-12-20 09:39:39 -05:00
if ( bfpSpawn ! = NULL )
{
CeInternalData * internalData = new CeInternalData ( ) ;
internalData - > mKind = CeInternalData : : Kind_Spawn ;
internalData - > mSpawn = bfpSpawn ;
mInternalDataMap [ + + mCurHandleId ] = internalData ;
CeSetAddrVal ( resultPtr , mCurHandleId , ptrSize ) ;
}
else
CeSetAddrVal ( resultPtr , 0 , ptrSize ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpSpawn_GetStdHandles )
{
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce outStdInAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce outStdOutAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
addr_ce outStdErrAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize ) ;
2021-12-29 10:07:36 -05:00
if ( outStdInAddr ! = 0 )
CE_CHECKADDR ( outStdInAddr , ptrSize ) ;
if ( outStdOutAddr ! = 0 )
CE_CHECKADDR ( outStdOutAddr , ptrSize ) ;
if ( outStdErrAddr ! = NULL )
CE_CHECKADDR ( outStdErrAddr , ptrSize ) ;
2021-12-20 09:39:39 -05:00
BfpFile * outStdIn = NULL ;
BfpFile * outStdOut = NULL ;
BfpFile * outStdErr = NULL ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_Spawn ) ;
BfpSpawn_GetStdHandles ( internalData - > mSpawn ,
( outStdInAddr ! = 0 ) ? & outStdIn : NULL ,
( outStdOutAddr ! = 0 ) ? & outStdOut : NULL ,
( outStdErrAddr ! = 0 ) ? & outStdErr : NULL ) ;
auto _SetHandle = [ & ] ( addr_ce addr , BfpFile * file )
{
if ( addr = = 0 )
return ;
if ( file ! = NULL )
{
CeInternalData * internalData = new CeInternalData ( ) ;
internalData - > mKind = CeInternalData : : Kind_File ;
internalData - > mFile = file ;
mInternalDataMap [ + + mCurHandleId ] = internalData ;
CeSetAddrVal ( memStart + addr , mCurHandleId , ptrSize ) ;
}
} ;
2021-12-29 10:07:36 -05:00
if ( outStdInAddr ! = NULL )
_SetHandle ( outStdInAddr , outStdIn ) ;
if ( outStdOutAddr ! = NULL )
_SetHandle ( outStdOutAddr , outStdOut ) ;
if ( outStdErrAddr ! = NULL )
_SetHandle ( outStdErrAddr , outStdErr ) ;
2021-12-20 09:39:39 -05:00
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpSpawn_Kill )
{
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
int exitCode = * ( int * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
int killFlags = * ( int * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize ) ;
CE_CHECKADDR ( outResultAddr , 4 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_Spawn ) ;
BfpSpawn_Kill ( internalData - > mSpawn , exitCode , ( BfpKillFlags ) killFlags , ( BfpSpawnResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpSpawn_Release )
{
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_Spawn ) ;
internalData - > mReleased = true ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpSpawn_WaitFor )
{
bool & result = * ( bool * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 1 ) ;
int waitMS = * ( int * ) ( ( uint8 * ) stackPtr + 1 + ptrSize ) ;
addr_ce outExitCodeAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 1 + ptrSize + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 1 + ptrSize + ptrSize + ptrSize ) ;
CE_CHECKADDR ( outExitCodeAddr , ptrSize ) ;
2021-12-20 15:37:01 -05:00
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
2021-12-20 09:39:39 -05:00
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_Spawn ) ;
2021-12-20 15:37:01 -05:00
int outExitCode = 0 ;
2021-12-20 09:39:39 -05:00
int timeLeft = waitMS ;
do
{
if ( * fastFinishPtr )
{
result = false ;
break ;
}
int waitTime = 20 ;
if ( timeLeft > = 0 )
{
waitTime = BF_MIN ( timeLeft , 20 ) ;
timeLeft - = waitTime ;
}
2021-12-20 15:37:01 -05:00
result = BfpSpawn_WaitFor ( internalData - > mSpawn , waitTime , & outExitCode , ( outResultAddr = = 0 ) ? NULL : ( BfpSpawnResult * ) ( memStart + outResultAddr ) ) ;
2021-12-20 09:39:39 -05:00
if ( result )
break ;
if ( waitTime = = 0 )
break ;
} while ( true ) ;
2021-12-20 15:37:01 -05:00
* ( int * ) ( memStart + outExitCodeAddr ) = outExitCode ;
2021-12-20 09:39:39 -05:00
}
2021-12-28 15:49:50 -05:00
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFindFileData_FindFirstFile )
{
void * resultPtr = ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
int flags = * ( int * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + 4 ) ;
String path ;
CE_CHECKADDR_STR ( path , nameAddr ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
2021-12-31 06:28:25 -05:00
FixProjectRelativePath ( path ) ;
2021-12-28 15:49:50 -05:00
auto bfpFindFileData = BfpFindFileData_FindFirstFile ( path . c_str ( ) , ( BfpFindFileFlags ) flags , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
if ( bfpFindFileData ! = NULL )
2021-12-29 10:07:36 -05:00
{
String dir = GetFileDir ( path ) ;
dir = FixPathAndCase ( dir ) ;
dir . Append ( DIR_SEP_CHAR ) ;
CeRebuildKey rebuildKey ;
rebuildKey . mKind = CeRebuildKey : : Kind_Directory ;
rebuildKey . mString = dir ;
CeRebuildValue rebuildValue ;
if ( AddRebuild ( rebuildKey , rebuildValue ) )
mCurModule - > mCompiler - > mRebuildFileSet . Add ( dir ) ;
2021-12-28 15:49:50 -05:00
CeInternalData * internalData = new CeInternalData ( ) ;
internalData - > mKind = CeInternalData : : Kind_FindFileData ;
internalData - > mFindFileData = bfpFindFileData ;
mInternalDataMap [ + + mCurHandleId ] = internalData ;
CeSetAddrVal ( resultPtr , mCurHandleId , ptrSize ) ;
}
else
CeSetAddrVal ( resultPtr , 0 , ptrSize ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFindFileData_FindNextFile )
{
bool & result = * ( bool * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 1 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_FindFileData ) ;
result = BfpFindFileData_FindNextFile ( internalData - > mFindFileData ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFindFileData_GetFileName )
{
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce nameAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize ) ;
addr_ce sizeAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize ) ;
addr_ce outResultAddr = * ( addr_ce * ) ( ( uint8 * ) stackPtr + ptrSize + ptrSize + ptrSize ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_FindFileData ) ;
CE_CHECKADDR ( sizeAddr , 4 ) ;
int & nameSize = * ( int * ) ( memStart + sizeAddr ) ;
CE_CHECKADDR ( nameAddr , nameSize ) ;
char * namePtr = ( char * ) ( memStart + nameAddr ) ;
if ( outResultAddr ! = 0 )
CE_CHECKADDR ( outResultAddr , 4 ) ;
BfpFindFileData_GetFileName ( internalData - > mFindFileData , namePtr , & nameSize , ( outResultAddr = = 0 ) ? NULL : ( BfpFileResult * ) ( memStart + outResultAddr ) ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFindFileData_GetTime_LastWrite )
{
BfpTimeStamp & result = * ( BfpTimeStamp * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 8 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_FindFileData ) ;
result = BfpFindFileData_GetTime_LastWrite ( internalData - > mFindFileData ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFindFileData_GetTime_Created )
{
BfpTimeStamp & result = * ( BfpTimeStamp * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 8 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_FindFileData ) ;
result = BfpFindFileData_GetTime_Created ( internalData - > mFindFileData ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFindFileData_GetTime_Access )
{
BfpTimeStamp & result = * ( BfpTimeStamp * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 8 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_FindFileData ) ;
result = BfpFindFileData_GetTime_Access ( internalData - > mFindFileData ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFindFileData_GetFileAttributes )
{
BfpFileAttributes & result = * ( BfpFileAttributes * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 4 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_FindFileData ) ;
result = BfpFindFileData_GetFileAttributes ( internalData - > mFindFileData ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFindFileData_GetFileSize )
{
int64 & result = * ( int64 * ) ( ( uint8 * ) stackPtr + 0 ) ;
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 8 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_FindFileData ) ;
result = BfpFindFileData_GetFileSize ( internalData - > mFindFileData ) ;
}
else if ( checkFunction - > mFunctionKind = = CeFunctionKind_BfpFindFileData_Release )
{
addr_ce spawnId = * ( addr_ce * ) ( ( uint8 * ) stackPtr + 0 ) ;
CeInternalData * internalData = NULL ;
CE_GET_INTERNAL ( internalData , ( int ) spawnId , CeInternalData : : Kind_FindFileData ) ;
internalData - > mReleased = true ;
}
2021-12-20 09:39:39 -05:00
else
2021-01-26 06:33:23 -08:00
{
Fail ( _GetCurFrame ( ) , StrFormat ( " Unable to invoke extern method '%s' " , ceModule - > MethodToString ( checkFunction - > mMethodInstance ) . c_str ( ) ) ) ;
return false ;
}
handled = true ;
return true ;
2021-01-11 09:41:43 -08:00
}
if ( ! checkFunction - > mFailed )
return true ;
2021-11-26 08:59:46 -08:00
auto error = Fail ( _GetCurFrame ( ) , StrFormat ( " Method call preparation '%s' failed " , ceModule - > MethodToString ( checkFunction - > mMethodInstance ) . c_str ( ) ) ) ;
2021-01-11 09:41:43 -08:00
if ( ( error ! = NULL ) & & ( ! checkFunction - > mGenError . IsEmpty ( ) ) )
mCeMachine - > mCompiler - > mPassInstance - > MoreInfo ( " Comptime method generation error: " + checkFunction - > mGenError ) ;
return false ;
} ;
//
{
bool handled = false ;
if ( ! _CheckFunction ( ceFunction , handled ) )
return false ;
if ( handled )
return true ;
}
int callCount = 0 ;
int instIdx = 0 ;
2021-12-20 15:07:38 -05:00
CE_CHECKSTACK ( ) ;
2021-01-11 09:41:43 -08:00
while ( true )
{
if ( * fastFinishPtr )
{
2022-01-13 11:40:14 -05:00
if ( ( mCurModule ! = NULL ) & & ( mCurModule - > mCurTypeInstance ! = NULL ) )
2021-12-14 11:41:11 -05:00
{
2022-01-13 11:40:14 -05:00
mCurModule - > mCurTypeInstance - > mRebuildFlags = ( BfTypeRebuildFlags ) ( mCurModule - > mCurTypeInstance - > mRebuildFlags | BfTypeRebuildFlag_ConstEvalCancelled ) ;
mCurModule - > DeferRebuildType ( mCurModule - > mCurTypeInstance ) ;
}
if ( * cancelingPtr )
{
if ( ( mCurModule = = NULL ) | | ( mCurModule - > mCurTypeInstance = = NULL ) )
_Fail ( " Comptime evaluation canceled " ) ;
2021-12-14 11:41:11 -05:00
}
2021-01-11 09:41:43 -08:00
return false ;
}
+ + instIdx ;
CeOp op = CE_GETINST ( CeOp ) ;
switch ( op )
{
case CeOp_Ret :
{
if ( mCallStack . mSize = = 0 )
return true ;
auto & ceFrame = mCallStack . back ( ) ;
ceFunction = ceFrame . mFunction ;
instPtr = ceFrame . mInstPtr ;
stackPtr = memStart + ceFrame . mStackAddr ;
framePtr = memStart + ceFrame . mFrameAddr ;
returnType = ceFrame . mReturnType ;
mCallStack . pop_back ( ) ;
}
break ;
case CeOp_SetRetType :
{
int typeId = CE_GETINST ( int32 ) ;
returnType = GetBfType ( typeId ) ;
BF_ASSERT ( returnType ! = NULL ) ;
}
break ;
case CeOp_Jmp :
{
auto relOfs = CE_GETINST ( int32 ) ;
instPtr + = relOfs ;
}
break ;
case CeOp_JmpIf :
{
auto relOfs = CE_GETINST ( int32 ) ;
bool cond = CE_GETFRAME ( bool ) ;
if ( cond )
instPtr + = relOfs - 4 ;
}
break ;
case CeOp_JmpIfNot :
{
auto relOfs = CE_GETINST ( int32 ) ;
bool cond = CE_GETFRAME ( bool ) ;
if ( ! cond )
instPtr + = relOfs - 4 ;
}
break ;
case CeOp_Error :
{
auto errorKind = ( CeErrorKind ) CE_GETINST ( int32 ) ;
switch ( errorKind )
{
case CeErrorKind_GlobalVariable :
_Fail ( " Global variable access not allowed " ) ;
break ;
case CeErrorKind_FunctionPointer :
_Fail ( " Function pointer calls not allowed " ) ;
break ;
case CeErrorKind_Intrinsic :
_Fail ( " Intrinsic not allowed " ) ;
break ;
2021-01-26 06:33:23 -08:00
case CeErrorKind_ObjectDynCheckFailed :
_Fail ( " Dynamic cast check failed " ) ;
break ;
2021-01-11 09:41:43 -08:00
default :
_Fail ( " Operation not allowed " ) ;
break ;
}
}
break ;
case CeOp_DynamicCastCheck :
{
auto & result = CE_GETFRAME ( uint32 ) ;
auto valueAddr = CE_GETFRAME ( addr_ce ) ;
int32 ifaceId = CE_GETINST ( int32 ) ;
if ( valueAddr = = 0 )
{
2021-01-13 05:09:09 -08:00
CeSetAddrVal ( & result , 0 , ptrSize ) ;
2021-01-11 09:41:43 -08:00
}
else
{
CE_CHECKADDR ( valueAddr , sizeof ( int32 ) ) ;
auto ifaceType = GetBfType ( ifaceId ) ;
int32 objTypeId = * ( int32 * ) ( memStart + valueAddr ) ;
auto valueType = GetBfType ( objTypeId ) ;
if ( ( ifaceType = = NULL ) | | ( valueType = = NULL ) )
{
_Fail ( " Invalid type " ) ;
return false ;
}
if ( ceModule - > TypeIsSubTypeOf ( valueType - > ToTypeInstance ( ) , ifaceType - > ToTypeInstance ( ) , false ) )
2021-01-13 05:09:09 -08:00
CeSetAddrVal ( & result , valueAddr , ptrSize ) ;
2021-01-11 09:41:43 -08:00
else
2021-01-13 05:09:09 -08:00
CeSetAddrVal ( & result , 0 , ptrSize ) ;
}
2021-01-11 09:41:43 -08:00
}
break ;
case CeOp_GetReflectType :
{
auto frameOfs = CE_GETINST ( int32 ) ;
int32 typeId = CE_GETINST ( int32 ) ;
auto reflectType = GetReflectType ( typeId ) ;
_FixVariables ( ) ;
2021-02-02 10:46:21 -08:00
CeSetAddrVal ( framePtr + frameOfs , reflectType , ptrSize ) ;
2021-01-11 09:41:43 -08:00
}
break ;
case CeOp_GetString :
{
auto frameOfs = CE_GETINST ( int32 ) ;
auto stringTableIdx = CE_GETINST ( int32 ) ;
auto & ceStringEntry = ceFunction - > mStringTable [ stringTableIdx ] ;
if ( ceStringEntry . mBindExecuteId ! = mExecuteId )
{
ceStringEntry . mStringAddr = GetString ( ceStringEntry . mStringId ) ;
_FixVariables ( ) ;
ceStringEntry . mBindExecuteId = mExecuteId ;
}
2021-02-02 10:46:21 -08:00
CeSetAddrVal ( framePtr + frameOfs , ceStringEntry . mStringAddr , ptrSize ) ;
2021-01-11 09:41:43 -08:00
}
break ;
case CeOp_Malloc :
{
auto frameOfs = CE_GETINST ( int32 ) ;
2021-12-20 15:07:38 -05:00
int64 size ;
if ( ptrSize = = 4 )
size = CE_GETFRAME ( int32 ) ;
else
size = CE_GETFRAME ( int64 ) ;
2021-01-11 09:41:43 -08:00
CE_CHECKALLOC ( size ) ;
uint8 * mem = CeMalloc ( size ) ;
_FixVariables ( ) ;
2021-02-02 10:46:21 -08:00
CeSetAddrVal ( framePtr + frameOfs , mem - memStart , ptrSize ) ;
2021-01-11 09:41:43 -08:00
}
break ;
case CeOp_Free :
{
auto freeAddr = CE_GETFRAME ( addr_ce ) ;
bool success = CeFree ( freeAddr ) ;
if ( ! success )
_Fail ( " Invalid heap address " ) ;
}
break ;
case CeOp_MemSet :
{
auto destAddr = CE_GETFRAME ( addr_ce ) ;
uint8 setValue = CE_GETFRAME ( uint8 ) ;
int32 setSize = CE_GETFRAME ( int32 ) ;
CE_CHECKSIZE ( setSize ) ;
CE_CHECKADDR ( destAddr , setSize ) ;
memset ( memStart + destAddr , setValue , setSize ) ;
}
break ;
case CeOp_MemSet_Const :
{
auto destAddr = CE_GETFRAME ( addr_ce ) ;
uint8 setValue = CE_GETINST ( uint8 ) ;
int32 setSize = CE_GETINST ( int32 ) ;
CE_CHECKSIZE ( setSize ) ;
CE_CHECKADDR ( destAddr , setSize ) ;
memset ( memStart + destAddr , setValue , setSize ) ;
}
break ;
case CeOp_MemCpy :
{
auto destAddr = CE_GETFRAME ( addr_ce ) ;
auto srcAddr = CE_GETFRAME ( addr_ce ) ;
int32 size = CE_GETFRAME ( int32 ) ;
CE_CHECKSIZE ( size ) ;
CE_CHECKADDR ( srcAddr , size ) ;
CE_CHECKADDR ( destAddr , size ) ;
memcpy ( memStart + destAddr , memStart + srcAddr , size ) ;
}
break ;
case CeOp_FrameAddr_32 :
{
auto & result = CE_GETFRAME ( int32 ) ;
auto addr = & CE_GETFRAME ( uint8 ) ;
result = addr - memStart ;
}
break ;
case CeOp_FrameAddr_64 :
{
2021-01-26 06:33:23 -08:00
//if (instPtr - ceFunction->mCode.mVals == 0x9c1)
2021-01-11 09:41:43 -08:00
auto & result = CE_GETFRAME ( int64 ) ;
auto addr = & CE_GETFRAME ( uint8 ) ;
result = addr - memStart ;
}
break ;
case CeOp_FrameAddrOfs_32 :
{
auto & result = CE_GETFRAME ( int32 ) ;
auto addr = & CE_GETFRAME ( uint8 ) ;
int32 ofs = CE_GETINST ( int32 ) ;
result = ( int32 ) ( addr - memStart + ofs ) ;
}
break ;
case CeOp_ConstData :
{
auto frameOfs = CE_GETINST ( int32 ) ;
int32 constIdx = CE_GETINST ( int32 ) ;
auto & constEntry = ceFunction - > mConstStructTable [ constIdx ] ;
if ( constEntry . mBindExecuteId ! = mExecuteId )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
PrepareConstStructEntry ( constEntry ) ;
_FixVariables ( ) ;
}
auto & buff = ( constEntry . mFixedData . mSize > 0 ) ? constEntry . mFixedData : constEntry . mData ;
memcpy ( framePtr + frameOfs , buff . mVals , buff . mSize ) ;
}
break ;
case CeOp_ConstDataRef :
{
auto frameOfs = CE_GETINST ( int32 ) ;
int32 constIdx = CE_GETINST ( int32 ) ;
auto & constEntry = ceFunction - > mConstStructTable [ constIdx ] ;
if ( constEntry . mBindExecuteId ! = mExecuteId )
{
PrepareConstStructEntry ( constEntry ) ;
_FixVariables ( ) ;
auto & buff = ( constEntry . mFixedData . mSize > 0 ) ? constEntry . mFixedData : constEntry . mData ;
addr_ce * constAddrPtr = NULL ;
if ( mConstDataMap . TryAdd ( constEntry . mHash , NULL , & constAddrPtr ) )
{
uint8 * data = CeMalloc ( buff . mSize ) ;
_FixVariables ( ) ;
memcpy ( data , & buff [ 0 ] , buff . mSize ) ;
* constAddrPtr = ( addr_ce ) ( data - memStart ) ;
}
constEntry . mAddr = * constAddrPtr ;
constEntry . mBindExecuteId = mExecuteId ;
2020-12-17 04:51:05 -08:00
}
2021-01-11 09:41:43 -08:00
* ( addr_ce * ) ( framePtr + frameOfs ) = constEntry . mAddr ;
}
break ;
case CeOp_Zero :
{
auto resultPtr = & CE_GETFRAME ( uint8 ) ;
int32 constSize = CE_GETINST ( int32 ) ;
memset ( resultPtr , 0 , constSize ) ;
}
break ;
case CeOp_Const_8 :
{
auto & result = CE_GETFRAME ( int8 ) ;
result = CE_GETINST ( int8 ) ;
}
break ;
case CeOp_Const_16 :
{
auto & result = CE_GETFRAME ( int16 ) ;
result = CE_GETINST ( int16 ) ;
}
break ;
case CeOp_Const_32 :
{
auto & result = CE_GETFRAME ( int32 ) ;
result = CE_GETINST ( int32 ) ;
}
break ;
case CeOp_Const_64 :
{
auto & result = CE_GETFRAME ( int64 ) ;
result = CE_GETINST ( int64 ) ;
}
break ;
case CeOp_Const_X :
{
int32 constSize = CE_GETINST ( int32 ) ;
auto resultPtr = & CE_GETFRAME ( uint8 ) ;
memcpy ( resultPtr , instPtr , constSize ) ;
instPtr + = constSize ;
}
break ;
case CeOp_Load_8 :
CE_LOAD ( uint8 ) ;
break ;
case CeOp_Load_16 :
CE_LOAD ( uint16 ) ;
break ;
case CeOp_Load_32 :
CE_LOAD ( uint32 ) ;
break ;
case CeOp_Load_64 :
2021-01-13 05:09:09 -08:00
CE_LOAD ( uint64 ) ;
2021-01-11 09:41:43 -08:00
break ;
case CeOp_Load_X :
{
int32 size = CE_GETINST ( int32 ) ;
auto resultPtr = & CE_GETFRAME ( uint8 ) ;
auto ceAddr = CE_GETFRAME ( addr_ce ) ;
CE_CHECKADDR ( ceAddr , size ) ;
memcpy ( resultPtr , memStart + ceAddr , size ) ;
}
break ;
case CeOp_Store_8 :
CE_STORE ( uint8 ) ;
break ;
case CeOp_Store_16 :
CE_STORE ( uint16 ) ;
break ;
case CeOp_Store_32 :
CE_STORE ( uint32 ) ;
break ;
case CeOp_Store_64 :
CE_STORE ( uint64 ) ;
2020-12-17 04:51:05 -08:00
break ;
2021-01-11 09:41:43 -08:00
case CeOp_Store_X :
{
auto size = CE_GETINST ( int32 ) ;
auto srcPtr = & CE_GETFRAME ( uint8 ) ;
auto ceAddr = CE_GETFRAME ( addr_ce ) ;
CE_CHECKADDR ( ceAddr , size ) ;
memcpy ( memStart + ceAddr , srcPtr , size ) ;
}
break ;
2020-12-13 08:04:42 -08:00
case CeOp_Move_8 :
2020-12-14 03:50:28 -08:00
CEOP_MOVE ( int8 ) ;
2020-12-13 08:04:42 -08:00
break ;
case CeOp_Move_16 :
2020-12-14 03:50:28 -08:00
CEOP_MOVE ( int16 ) ;
2020-12-13 08:04:42 -08:00
break ;
case CeOp_Move_32 :
2020-12-14 03:50:28 -08:00
CEOP_MOVE ( int32 ) ;
2020-12-13 08:04:42 -08:00
break ;
case CeOp_Move_64 :
2021-01-11 09:41:43 -08:00
CEOP_MOVE ( int64 ) ;
2020-12-14 03:50:28 -08:00
break ;
case CeOp_Move_X :
2021-01-11 09:41:43 -08:00
{
int32 size = CE_GETINST ( int32 ) ;
auto valPtr = & CE_GETFRAME ( uint8 ) ;
auto destPtr = & CE_GETFRAME ( uint8 ) ;
memcpy ( destPtr , valPtr , size ) ;
}
break ;
2020-12-14 03:50:28 -08:00
case CeOp_Push_8 :
CEOP_PUSH ( int8 ) ;
break ;
case CeOp_Push_16 :
CEOP_PUSH ( int16 ) ;
break ;
case CeOp_Push_32 :
CEOP_PUSH ( int32 ) ;
break ;
case CeOp_Push_64 :
CEOP_PUSH ( int64 ) ;
break ;
case CeOp_Pop_8 :
CEOP_POP ( int8 ) ;
break ;
case CeOp_Pop_16 :
CEOP_POP ( int16 ) ;
break ;
case CeOp_Pop_32 :
CEOP_POP ( int32 ) ;
break ;
case CeOp_Pop_64 :
CEOP_POP ( int64 ) ;
break ;
2020-12-22 04:50:37 -08:00
case CeOp_Pop_X :
2021-01-11 09:41:43 -08:00
{
int32 size = CE_GETINST ( int32 ) ;
auto resultPtr = & CE_GETFRAME ( uint8 ) ;
memcpy ( resultPtr , stackPtr , size ) ;
stackPtr + = size ;
}
break ;
case CeOp_AdjustSP :
{
int32 adjust = CE_GETFRAME ( int32 ) ;
stackPtr + = adjust ;
}
break ;
2020-12-17 04:51:05 -08:00
case CeOp_AdjustSPNeg :
2021-01-11 09:41:43 -08:00
{
int32 adjust = CE_GETFRAME ( int32 ) ;
stackPtr - = adjust ;
}
break ;
2020-12-17 04:51:05 -08:00
case CeOp_AdjustSPConst :
2021-01-11 09:41:43 -08:00
{
int32 adjust = CE_GETINST ( int32 ) ;
2021-01-26 06:33:23 -08:00
stackPtr + = adjust ;
2021-01-11 09:41:43 -08:00
}
break ;
2020-12-17 04:51:05 -08:00
case CeOp_GetSP :
2021-01-11 09:41:43 -08:00
{
auto & result = CE_GETFRAME ( int32 ) ;
result = stackPtr - memStart ;
}
break ;
2020-12-17 04:51:05 -08:00
case CeOp_SetSP :
2021-01-11 09:41:43 -08:00
{
auto addr = CE_GETFRAME ( int32 ) ;
stackPtr = memStart + addr ;
}
break ;
2020-12-19 14:19:33 -08:00
case CeOp_GetStaticField :
2021-01-11 09:41:43 -08:00
{
auto frameOfs = CE_GETINST ( int32 ) ;
int32 tableIdx = CE_GETINST ( int32 ) ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
CeFunction * ctorCallFunction = NULL ;
auto & ceStaticFieldEntry = ceFunction - > mStaticFieldTable [ tableIdx ] ;
if ( ceStaticFieldEntry . mBindExecuteId ! = mExecuteId )
{
if ( mStaticCtorExecSet . TryAdd ( ceStaticFieldEntry . mTypeId , NULL ) )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
auto bfType = GetBfType ( ceStaticFieldEntry . mTypeId ) ;
BfTypeInstance * bfTypeInstance = NULL ;
if ( bfType ! = NULL )
bfTypeInstance = bfType - > ToTypeInstance ( ) ;
if ( bfTypeInstance = = NULL )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
_Fail ( " Invalid type " ) ;
return false ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
auto methodDef = bfTypeInstance - > mTypeDef - > GetMethodByName ( " __BfStaticCtor " ) ;
if ( methodDef = = NULL )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
_Fail ( " No static ctor found " ) ;
return false ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
auto moduleMethodInstance = ceModule - > GetMethodInstance ( bfTypeInstance , methodDef , BfTypeVector ( ) ) ;
if ( ! moduleMethodInstance )
{
_Fail ( " No static ctor instance found " ) ;
return false ;
}
2020-12-14 03:50:28 -08:00
2021-01-11 09:41:43 -08:00
bool added = false ;
ctorCallFunction = mCeMachine - > GetFunction ( moduleMethodInstance . mMethodInstance , moduleMethodInstance . mFunc , added ) ;
2021-11-26 08:59:46 -08:00
if ( ctorCallFunction - > mInitializeState < CeFunction : : InitializeState_Initialized )
2021-01-11 09:41:43 -08:00
mCeMachine - > PrepareFunction ( ctorCallFunction , NULL ) ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
CeStaticFieldInfo * staticFieldInfo = NULL ;
mStaticFieldMap . TryAdd ( ceStaticFieldEntry . mName , NULL , & staticFieldInfo ) ;
if ( staticFieldInfo - > mAddr = = 0 )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
if ( ceStaticFieldEntry . mSize < 0 )
_Fail ( StrFormat ( " Reference to unsized global variable '%s' " , ceStaticFieldEntry . mName . c_str ( ) ) ) ;
CE_CHECKALLOC ( ceStaticFieldEntry . mSize ) ;
uint8 * ptr = CeMalloc ( ceStaticFieldEntry . mSize ) ;
_FixVariables ( ) ;
if ( ceStaticFieldEntry . mSize > 0 )
memset ( ptr , 0 , ceStaticFieldEntry . mSize ) ;
staticFieldInfo - > mAddr = ( addr_ce ) ( ptr - memStart ) ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
ceStaticFieldEntry . mAddr = staticFieldInfo - > mAddr ;
ceStaticFieldEntry . mBindExecuteId = mExecuteId ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
* ( addr_ce * ) ( framePtr + frameOfs ) = ceStaticFieldEntry . mAddr ;
if ( ctorCallFunction ! = NULL )
{
bool handled = false ;
if ( ! _CheckFunction ( ctorCallFunction , handled ) )
return false ;
if ( handled )
break ;
CE_CALL ( ctorCallFunction ) ;
}
}
break ;
2020-12-19 14:19:33 -08:00
case CeOp_GetMethod :
2021-01-11 09:41:43 -08:00
{
BF_ASSERT ( memStart = = mMemory . mVals ) ;
auto resultFrameIdx = CE_GETINST ( int32 ) ;
int32 callIdx = CE_GETINST ( int32 ) ;
auto & callEntry = ceFunction - > mCallTable [ callIdx ] ;
2021-02-01 13:55:29 -08:00
if ( callEntry . mBindRevision ! = mCeMachine - > mMethodBindRevision )
2020-12-22 04:50:37 -08:00
{
2021-01-11 09:41:43 -08:00
callEntry . mFunction = NULL ;
//mNamedFunctionMap.TryGetValue(callEntry.mFunctionName, &callEntry.mFunction);
2020-12-22 04:50:37 -08:00
2021-01-11 09:41:43 -08:00
if ( callEntry . mFunctionInfo = = NULL )
2020-12-14 03:50:28 -08:00
{
2021-01-11 09:41:43 -08:00
_Fail ( " Unable to locate function entry " ) ;
return false ;
}
2020-12-17 04:51:05 -08:00
2021-01-11 09:41:43 -08:00
if ( ( callEntry . mFunctionInfo - > mCeFunction = = NULL ) & & ( ! callEntry . mFunctionInfo - > mMethodRef . IsNull ( ) ) )
{
auto methodRef = callEntry . mFunctionInfo - > mMethodRef ;
auto methodDef = methodRef . mTypeInstance - > mTypeDef - > mMethods [ methodRef . mMethodNum ] ;
auto moduleMethodInstance = ceModule - > GetMethodInstance ( methodRef . mTypeInstance , methodDef ,
methodRef . mMethodGenericArguments ) ;
2020-12-17 04:51:05 -08:00
2021-01-11 09:41:43 -08:00
if ( moduleMethodInstance )
2020-12-17 04:51:05 -08:00
{
2021-12-31 14:17:17 -05:00
auto ceFunction = mCeMachine - > QueueMethod ( moduleMethodInstance . mMethodInstance , moduleMethodInstance . mFunc ) ;
2022-01-04 09:38:02 -05:00
ceFunction - > mCeFunctionInfo - > mRefCount + + ;
mCeMachine - > DerefMethodInfo ( callEntry . mFunctionInfo ) ;
2021-12-31 14:17:17 -05:00
callEntry . mFunctionInfo = ceFunction - > mCeFunctionInfo ;
2020-12-17 04:51:05 -08:00
}
2021-01-11 09:41:43 -08:00
}
2020-12-17 04:51:05 -08:00
2021-01-11 09:41:43 -08:00
if ( callEntry . mFunctionInfo - > mCeFunction = = NULL )
{
_Fail ( " Method not generated " ) ;
return false ;
2020-12-14 03:50:28 -08:00
}
2021-01-08 16:21:03 -08:00
2021-01-11 09:41:43 -08:00
callEntry . mFunction = callEntry . mFunctionInfo - > mCeFunction ;
2021-11-26 08:59:46 -08:00
if ( callEntry . mFunction - > mInitializeState < CeFunction : : InitializeState_Initialized )
2021-01-08 16:21:03 -08:00
{
2021-01-11 09:41:43 -08:00
auto curFrame = _GetCurFrame ( ) ;
SetAndRestoreValue < CeFrame * > prevFrame ( mCurFrame , & curFrame ) ;
2021-11-26 08:59:46 -08:00
BF_ASSERT ( callEntry . mFunction - > mInitializeState < CeFunction : : InitializeState_Initialized ) ;
2021-01-11 09:41:43 -08:00
mCeMachine - > PrepareFunction ( callEntry . mFunction , NULL ) ;
2021-01-08 16:21:03 -08:00
}
2021-02-25 10:14:22 -08:00
if ( callEntry . mFunction - > mMethodInstance ! = NULL )
{
if ( callEntry . mFunction - > mMethodInstance - > GetOwner ( ) - > IsDeleting ( ) )
{
_Fail ( " Calling method on deleted type " ) ;
return false ;
}
}
2021-02-01 13:55:29 -08:00
callEntry . mBindRevision = mCeMachine - > mMethodBindRevision ;
2020-12-17 04:51:05 -08:00
}
2021-01-11 09:41:43 -08:00
BF_ASSERT ( memStart = = mMemory . mVals ) ;
auto callFunction = callEntry . mFunction ;
if ( needsFunctionIds )
* ( int32 * ) ( framePtr + resultFrameIdx ) = callFunction - > mId ;
else
* ( CeFunction * * ) ( framePtr + resultFrameIdx ) = callFunction ;
}
break ;
case CeOp_GetMethod_Inner :
{
auto resultFrameIdx = CE_GETINST ( int32 ) ;
int32 innerIdx = CE_GETINST ( int32 ) ;
auto outerFunction = ceFunction ;
if ( outerFunction - > mCeInnerFunctionInfo ! = NULL )
outerFunction = outerFunction - > mCeInnerFunctionInfo - > mOwner ;
auto callFunction = outerFunction - > mInnerFunctions [ innerIdx ] ;
if ( needsFunctionIds )
* ( int32 * ) ( framePtr + resultFrameIdx ) = callFunction - > mId ;
else
* ( CeFunction * * ) ( framePtr + resultFrameIdx ) = callFunction ;
}
break ;
2020-12-19 14:19:33 -08:00
case CeOp_GetMethod_Virt :
2021-01-11 09:41:43 -08:00
{
auto resultFrameIdx = CE_GETINST ( int32 ) ;
auto valueAddr = CE_GETFRAME ( addr_ce ) ;
int32 virtualIdx = CE_GETINST ( int32 ) ;
CE_CHECKADDR ( valueAddr , sizeof ( int32 ) ) ;
int32 objTypeId = * ( int32 * ) ( memStart + valueAddr ) ;
BfType * bfType = GetBfType ( objTypeId ) ;
if ( ( bfType = = NULL ) | | ( ! bfType - > IsObject ( ) ) )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
_Fail ( " Invalid virtual method target " ) ;
return false ;
}
2020-12-17 04:51:05 -08:00
2021-01-11 09:41:43 -08:00
auto valueType = bfType - > ToTypeInstance ( ) ;
if ( valueType - > mVirtualMethodTable . IsEmpty ( ) )
2021-12-20 09:39:39 -05:00
ceModule - > PopulateType ( valueType , BfPopulateType_Full_Force ) ;
if ( valueType - > mVirtualMethodTable . IsEmpty ( ) )
{
_Fail ( " Empty virtual table " ) ;
return false ;
}
2021-01-11 09:41:43 -08:00
auto methodInstance = ( BfMethodInstance * ) valueType - > mVirtualMethodTable [ virtualIdx ] . mImplementingMethod ;
2021-01-08 16:21:03 -08:00
2021-01-11 09:41:43 -08:00
auto callFunction = mCeMachine - > GetPreparedFunction ( methodInstance ) ;
if ( needsFunctionIds )
* ( int32 * ) ( framePtr + resultFrameIdx ) = callFunction - > mId ;
else
* ( CeFunction * * ) ( framePtr + resultFrameIdx ) = callFunction ;
}
break ;
2020-12-19 14:19:33 -08:00
case CeOp_GetMethod_IFace :
2021-01-11 09:41:43 -08:00
{
auto resultFrameIdx = CE_GETINST ( int32 ) ;
auto valueAddr = CE_GETFRAME ( addr_ce ) ;
int32 ifaceId = CE_GETINST ( int32 ) ;
int32 methodIdx = CE_GETINST ( int32 ) ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
auto ifaceType = ceModule - > mContext - > mTypes [ ifaceId ] - > ToTypeInstance ( ) ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
CE_CHECKADDR ( valueAddr , sizeof ( int32 ) ) ;
int32 objTypeId = * ( int32 * ) ( memStart + valueAddr ) ;
2021-01-13 05:09:09 -08:00
auto bfObjectType = GetBfType ( objTypeId ) ;
if ( ( bfObjectType = = NULL ) | | ( ! bfObjectType - > IsTypeInstance ( ) ) )
{
_Fail ( " Invalid object " ) ;
return false ;
}
auto valueType = bfObjectType - > ToTypeInstance ( ) ;
2021-01-11 09:41:43 -08:00
BfMethodInstance * methodInstance = NULL ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
if ( valueType ! = NULL )
{
if ( valueType - > mVirtualMethodTable . IsEmpty ( ) )
ceModule - > PopulateType ( valueType , BfPopulateType_DataAndMethods ) ;
2021-01-08 16:21:03 -08:00
2021-01-11 09:41:43 -08:00
auto checkType = valueType ;
while ( checkType ! = NULL )
{
for ( auto & iface : checkType - > mInterfaces )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
if ( iface . mInterfaceType = = ifaceType )
2020-12-19 14:19:33 -08:00
{
2021-12-21 12:52:51 -05:00
if ( valueType - > mInterfaceMethodTable . IsEmpty ( ) )
ceModule - > PopulateType ( valueType , BfPopulateType_Full_Force ) ;
if ( valueType - > mInterfaceMethodTable . IsEmpty ( ) )
{
_Fail ( " Empty interface table " ) ;
return false ;
}
2021-01-11 09:41:43 -08:00
methodInstance = valueType - > mInterfaceMethodTable [ iface . mStartInterfaceTableIdx + methodIdx ] . mMethodRef ;
break ;
2020-12-19 14:19:33 -08:00
}
}
2021-01-11 09:41:43 -08:00
checkType = checkType - > mBaseType ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
}
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
if ( methodInstance = = NULL )
{
_Fail ( " Failed to invoke interface method " ) ;
return false ;
2020-12-19 14:19:33 -08:00
}
2021-01-11 09:41:43 -08:00
auto callFunction = mCeMachine - > GetPreparedFunction ( methodInstance ) ;
if ( needsFunctionIds )
* ( int32 * ) ( framePtr + resultFrameIdx ) = callFunction - > mId ;
else
* ( CeFunction * * ) ( framePtr + resultFrameIdx ) = callFunction ;
}
break ;
2020-12-19 14:19:33 -08:00
case CeOp_Call :
2021-01-11 09:41:43 -08:00
{
callCount + + ;
CeFunction * callFunction ;
if ( needsFunctionIds )
2020-12-19 14:19:33 -08:00
{
2021-01-11 09:41:43 -08:00
int32 functionId = CE_GETFRAME ( int32 ) ;
callFunction = mCeMachine - > mFunctionIdMap [ functionId ] ;
}
else
callFunction = CE_GETFRAME ( CeFunction * ) ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
bool handled = false ;
if ( ! _CheckFunction ( callFunction , handled ) )
return false ;
if ( callFunction - > mIsVarReturn )
_Fail ( " Illegal call to method with 'var' return. " ) ;
if ( handled )
break ;
2020-12-19 14:19:33 -08:00
2021-01-11 09:41:43 -08:00
CE_CALL ( callFunction ) ;
}
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Conv_I8_I16 :
CE_CAST ( int8 , int16 ) ;
break ;
case CeOp_Conv_I8_I32 :
CE_CAST ( int8 , int32 ) ;
break ;
case CeOp_Conv_I8_I64 :
CE_CAST ( int8 , int64 ) ;
break ;
case CeOp_Conv_I8_F32 :
CE_CAST ( int8 , float ) ;
break ;
case CeOp_Conv_I8_F64 :
CE_CAST ( int8 , double ) ;
break ;
case CeOp_Conv_I16_I32 :
CE_CAST ( int16 , int32 ) ;
break ;
case CeOp_Conv_I16_I64 :
CE_CAST ( int16 , int64 ) ;
break ;
case CeOp_Conv_I16_F32 :
CE_CAST ( int16 , float ) ;
break ;
case CeOp_Conv_I16_F64 :
CE_CAST ( int16 , double ) ;
break ;
2020-12-13 08:04:42 -08:00
case CeOp_Conv_I32_I64 :
CE_CAST ( int32 , int64 ) ;
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Conv_I32_F32 :
CE_CAST ( int32 , float ) ;
break ;
case CeOp_Conv_I32_F64 :
CE_CAST ( int32 , double ) ;
break ;
case CeOp_Conv_I64_F32 :
CE_CAST ( int64 , float ) ;
break ;
case CeOp_Conv_I64_F64 :
CE_CAST ( int64 , double ) ;
break ;
case CeOp_Conv_U8_U16 :
CE_CAST ( uint8 , uint16 ) ;
break ;
case CeOp_Conv_U8_U32 :
CE_CAST ( uint8 , uint32 ) ;
break ;
case CeOp_Conv_U8_U64 :
CE_CAST ( uint8 , uint64 ) ;
break ;
case CeOp_Conv_U8_F32 :
CE_CAST ( uint8 , float ) ;
break ;
case CeOp_Conv_U8_F64 :
CE_CAST ( uint8 , double ) ;
break ;
case CeOp_Conv_U16_U32 :
CE_CAST ( uint16 , uint32 ) ;
break ;
case CeOp_Conv_U16_U64 :
CE_CAST ( uint16 , uint64 ) ;
break ;
case CeOp_Conv_U16_F32 :
CE_CAST ( uint16 , float ) ;
break ;
case CeOp_Conv_U16_F64 :
CE_CAST ( uint16 , double ) ;
break ;
case CeOp_Conv_U32_U64 :
CE_CAST ( uint32 , uint64 ) ;
break ;
case CeOp_Conv_U32_F32 :
CE_CAST ( uint32 , float ) ;
break ;
case CeOp_Conv_U32_F64 :
CE_CAST ( uint32 , double ) ;
break ;
case CeOp_Conv_U64_F32 :
CE_CAST ( uint64 , float ) ;
break ;
case CeOp_Conv_U64_F64 :
CE_CAST ( uint64 , double ) ;
break ;
case CeOp_Conv_F32_I8 :
CE_CAST ( float , int8 ) ;
break ;
case CeOp_Conv_F32_I16 :
CE_CAST ( float , int16 ) ;
break ;
case CeOp_Conv_F32_I32 :
CE_CAST ( float , int32 ) ;
break ;
case CeOp_Conv_F32_I64 :
CE_CAST ( float , int64 ) ;
break ;
case CeOp_Conv_F32_F64 :
CE_CAST ( float , double ) ;
break ;
case CeOp_Conv_F64_I8 :
CE_CAST ( double , int8 ) ;
break ;
case CeOp_Conv_F64_I16 :
CE_CAST ( double , int16 ) ;
break ;
case CeOp_Conv_F64_I32 :
CE_CAST ( double , int32 ) ;
break ;
case CeOp_Conv_F64_I64 :
CE_CAST ( double , int64 ) ;
break ;
case CeOp_Conv_F64_F32 :
CE_CAST ( double , float ) ;
break ;
2021-01-26 06:33:23 -08:00
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 ;
2020-12-17 04:51:05 -08:00
case CeOp_AddConst_I8 :
CEOP_BIN_CONST ( + , int8 ) ;
break ;
case CeOp_AddConst_I16 :
CEOP_BIN_CONST ( + , int16 ) ;
break ;
2020-12-14 10:20:44 -08:00
case CeOp_AddConst_I32 :
CEOP_BIN_CONST ( + , int32 ) ;
break ;
case CeOp_AddConst_I64 :
CEOP_BIN_CONST ( + , int64 ) ;
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Add_I8 :
CEOP_BIN ( + , int8 ) ;
break ;
case CeOp_Add_I16 :
CEOP_BIN ( + , int16 ) ;
break ;
2020-12-13 08:04:42 -08:00
case CeOp_Add_I32 :
CEOP_BIN ( + , int32 ) ;
break ;
case CeOp_Add_I64 :
CEOP_BIN ( + , int64 ) ;
break ;
2021-01-11 09:41:43 -08:00
case CeOp_Add_F32 :
2020-12-17 04:51:05 -08:00
CEOP_BIN ( + , float ) ;
break ;
case CeOp_Add_F64 :
CEOP_BIN ( + , double ) ;
break ;
case CeOp_Sub_I8 :
CEOP_BIN ( - , int8 ) ;
break ;
case CeOp_Sub_I16 :
CEOP_BIN ( - , int16 ) ;
break ;
2020-12-14 03:50:28 -08:00
case CeOp_Sub_I32 :
CEOP_BIN ( - , int32 ) ;
break ;
case CeOp_Sub_I64 :
CEOP_BIN ( - , int64 ) ;
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Sub_F32 :
CEOP_BIN ( - , float ) ;
break ;
case CeOp_Sub_F64 :
CEOP_BIN ( - , double ) ;
break ;
case CeOp_Mul_I8 :
CEOP_BIN ( * , int8 ) ;
break ;
case CeOp_Mul_I16 :
CEOP_BIN ( * , int16 ) ;
break ;
2020-12-14 03:50:28 -08:00
case CeOp_Mul_I32 :
CEOP_BIN ( * , int32 ) ;
break ;
case CeOp_Mul_I64 :
CEOP_BIN ( * , int64 ) ;
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Mul_F32 :
CEOP_BIN ( * , float ) ;
break ;
case CeOp_Mul_F64 :
CEOP_BIN ( * , double ) ;
break ;
case CeOp_Div_I8 :
2021-01-11 09:41:43 -08:00
CEOP_BIN_DIV ( / , int8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Div_I16 :
2021-01-11 09:41:43 -08:00
CEOP_BIN_DIV ( / , int16 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Div_I32 :
2021-01-11 09:41:43 -08:00
CEOP_BIN_DIV ( / , int32 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Div_I64 :
2021-01-11 09:41:43 -08:00
CEOP_BIN_DIV ( / , int64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Div_F32 :
2021-01-11 09:41:43 -08:00
CEOP_BIN_DIV ( / , float ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Div_F64 :
2021-01-11 09:41:43 -08:00
CEOP_BIN_DIV ( / , double ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Div_U8 :
2021-01-11 09:41:43 -08:00
CEOP_BIN_DIV ( / , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Div_U16 :
2021-01-11 09:41:43 -08:00
CEOP_BIN_DIV ( / , uint16 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Div_U32 :
2021-01-11 09:41:43 -08:00
CEOP_BIN_DIV ( / , uint32 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Div_U64 :
2021-01-11 09:41:43 -08:00
CEOP_BIN_DIV ( / , uint64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Mod_I8 :
CEOP_BIN_DIV ( % , int8 ) ;
break ;
case CeOp_Mod_I16 :
CEOP_BIN_DIV ( % , int16 ) ;
break ;
case CeOp_Mod_I32 :
CEOP_BIN_DIV ( % , int32 ) ;
break ;
case CeOp_Mod_I64 :
CEOP_BIN_DIV ( % , int64 ) ;
break ;
case CeOp_Mod_F32 :
2021-01-11 09:41:43 -08:00
{
auto & result = CE_GETFRAME ( float ) ;
auto lhs = CE_GETFRAME ( float ) ;
auto rhs = CE_GETFRAME ( float ) ;
if ( rhs = = 0 )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
_Fail ( " Division by zero " ) ;
return false ;
2020-12-17 04:51:05 -08:00
}
2021-01-11 09:41:43 -08:00
result = fmodf ( lhs , rhs ) ;
}
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Mod_F64 :
2021-01-11 09:41:43 -08:00
{
auto & result = CE_GETFRAME ( double ) ;
auto lhs = CE_GETFRAME ( double ) ;
auto rhs = CE_GETFRAME ( double ) ;
if ( rhs = = 0 )
2020-12-17 04:51:05 -08:00
{
2021-01-11 09:41:43 -08:00
_Fail ( " Division by zero " ) ;
return false ;
2020-12-17 04:51:05 -08:00
}
2021-01-11 09:41:43 -08:00
result = fmod ( lhs , rhs ) ;
}
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Mod_U8 :
CEOP_BIN_DIV ( % , uint8 ) ;
break ;
case CeOp_Mod_U16 :
CEOP_BIN_DIV ( % , uint16 ) ;
break ;
case CeOp_Mod_U32 :
CEOP_BIN_DIV ( % , uint32 ) ;
break ;
case CeOp_Mod_U64 :
CEOP_BIN_DIV ( % , uint64 ) ;
break ;
case CeOp_And_I8 :
CEOP_BIN ( & , uint8 ) ;
break ;
case CeOp_And_I16 :
CEOP_BIN ( & , uint16 ) ;
break ;
case CeOp_And_I32 :
CEOP_BIN ( & , uint32 ) ;
break ;
case CeOp_And_I64 :
CEOP_BIN ( & , uint64 ) ;
break ;
case CeOp_Or_I8 :
2021-01-11 09:41:43 -08:00
CEOP_BIN ( | , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Or_I16 :
2021-01-11 09:41:43 -08:00
CEOP_BIN ( | , uint16 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Or_I32 :
2021-01-11 09:41:43 -08:00
CEOP_BIN ( | , uint32 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Or_I64 :
2021-01-11 09:41:43 -08:00
CEOP_BIN ( | , uint64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Xor_I8 :
CEOP_BIN ( ^ , uint8 ) ;
break ;
case CeOp_Xor_I16 :
CEOP_BIN ( ^ , uint16 ) ;
break ;
case CeOp_Xor_I32 :
CEOP_BIN ( ^ , uint32 ) ;
break ;
case CeOp_Xor_I64 :
CEOP_BIN ( ^ , uint64 ) ;
break ;
case CeOp_Shl_I8 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( < < , int8 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shl_I16 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( < < , int16 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shl_I32 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( < < , int32 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shl_I64 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( < < , int64 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shr_I8 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( > > , int8 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shr_I16 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( > > , int16 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shr_I32 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( > > , int32 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shr_I64 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( > > , int64 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shr_U8 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( > > , uint8 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shr_U16 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( > > , uint16 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shr_U32 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( > > , uint32 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Shr_U64 :
2021-01-11 09:41:43 -08:00
CEOP_BIN2 ( > > , uint64 , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
2021-01-26 06:33:23 -08:00
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 ;
2020-12-17 04:51:05 -08:00
case CeOp_Cmp_NE_I8 :
CEOP_CMP ( ! = , int8 ) ;
break ;
case CeOp_Cmp_NE_I16 :
CEOP_CMP ( ! = , int16 ) ;
break ;
case CeOp_Cmp_NE_I32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( ! = , int32 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_NE_I64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( ! = , int64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_NE_F32 :
CEOP_CMP ( ! = , float ) ;
break ;
case CeOp_Cmp_NE_F64 :
CEOP_CMP ( ! = , double ) ;
break ;
case CeOp_Cmp_EQ_I8 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( = = , int8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_EQ_I16 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( = = , int16 ) ;
2020-12-17 04:51:05 -08:00
break ;
2020-12-13 08:04:42 -08:00
case CeOp_Cmp_EQ_I32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( = = , int32 ) ;
2020-12-13 08:04:42 -08:00
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Cmp_EQ_I64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( = = , int64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_EQ_F32 :
CEOP_CMP ( = = , float ) ;
break ;
case CeOp_Cmp_EQ_F64 :
CEOP_CMP ( = = , double ) ;
break ;
case CeOp_Cmp_SLT_I8 :
CEOP_CMP ( < , int8 ) ;
break ;
case CeOp_Cmp_SLT_I16 :
CEOP_CMP ( < , int16 ) ;
break ;
2020-12-13 08:04:42 -08:00
case CeOp_Cmp_SLT_I32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < , int32 ) ;
2020-12-13 08:04:42 -08:00
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Cmp_SLT_I64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < , int64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SLT_F32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < , float ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SLT_F64 :
CEOP_CMP ( < , double ) ;
break ;
case CeOp_Cmp_ULT_I8 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_ULT_I16 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < , uint16 ) ;
2020-12-17 04:51:05 -08:00
break ;
2020-12-14 03:50:28 -08:00
case CeOp_Cmp_ULT_I32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < , uint32 ) ;
2020-12-14 03:50:28 -08:00
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Cmp_ULT_I64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < , uint64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SLE_I8 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < = , int8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SLE_I16 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < = , int16 ) ;
2020-12-17 04:51:05 -08:00
break ;
2020-12-14 03:50:28 -08:00
case CeOp_Cmp_SLE_I32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < = , int32 ) ;
2020-12-14 03:50:28 -08:00
break ;
case CeOp_Cmp_SLE_I64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < = , int64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SLE_F32 :
CEOP_CMP ( < = , float ) ;
break ;
case CeOp_Cmp_SLE_F64 :
CEOP_CMP ( < = , double ) ;
break ;
case CeOp_Cmp_ULE_I8 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < = , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_ULE_I16 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < = , uint16 ) ;
2020-12-14 03:50:28 -08:00
break ;
case CeOp_Cmp_ULE_I32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < = , uint32 ) ;
2020-12-14 03:50:28 -08:00
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Cmp_ULE_I64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( < = , uint64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGT_I8 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > , int8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGT_I16 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > , int16 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGT_I32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > , int32 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGT_I64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > , int64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGT_F32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > , float ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGT_F64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > , double ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_UGT_I8 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_UGT_I16 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > , uint16 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_UGT_I32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > , uint32 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_UGT_I64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > , uint64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGE_I8 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > = , int8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGE_I16 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > = , int16 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGE_I32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > = , int32 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGE_I64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > = , int64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGE_F32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > = , float ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_SGE_F64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > = , double ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_UGE_I8 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > = , uint8 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_UGE_I16 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > = , uint16 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_UGE_I32 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > = , uint32 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Cmp_UGE_I64 :
2021-01-11 09:41:43 -08:00
CEOP_CMP ( > = , uint64 ) ;
2020-12-17 04:51:05 -08:00
break ;
case CeOp_Neg_I8 :
CEOP_UNARY ( - , int8 ) ;
break ;
case CeOp_Neg_I16 :
CEOP_UNARY ( - , int16 ) ;
break ;
2020-12-13 08:04:42 -08:00
case CeOp_Neg_I32 :
CEOP_UNARY ( - , int32 ) ;
break ;
case CeOp_Neg_I64 :
CEOP_UNARY ( - , int64 ) ;
break ;
2020-12-17 04:51:05 -08:00
case CeOp_Neg_F32 :
CEOP_UNARY ( - , float ) ;
case CeOp_Neg_F64 :
CEOP_UNARY ( - , double ) ;
break ;
case CeOp_Not_I1 :
CEOP_UNARY ( ! , bool ) ;
break ;
case CeOp_Not_I8 :
CEOP_UNARY ( ~ , int8 ) ;
break ;
case CeOp_Not_I16 :
CEOP_UNARY ( ~ , int16 ) ;
break ;
case CeOp_Not_I32 :
CEOP_UNARY ( ~ , int32 ) ;
break ;
case CeOp_Not_I64 :
CEOP_UNARY ( ~ , int64 ) ;
2021-01-11 09:41:43 -08:00
break ;
2020-12-13 08:04:42 -08:00
default :
2020-12-14 03:50:28 -08:00
_Fail ( " Unhandled op " ) ;
2020-12-13 08:04:42 -08:00
return false ;
}
2021-12-20 09:39:39 -05:00
//BF_ASSERT(_CrtCheckMemory() != 0);
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
return true ;
}
//////////////////////////////////////////////////////////////////////////
CeMachine : : CeMachine ( BfCompiler * compiler )
{
mCompiler = compiler ;
mCeModule = NULL ;
mRevision = 0 ;
2021-02-01 13:55:29 -08:00
mMethodBindRevision = 0 ;
2021-01-11 09:41:43 -08:00
mCurContext = NULL ;
mExecuteId = - 1 ;
mCurFunctionId = 0 ;
mRevisionExecuteTime = 0 ;
mCurBuilder = NULL ;
mPreparingFunction = NULL ;
2021-12-20 09:39:39 -05:00
mCurEmitContext = NULL ;
2021-01-11 09:41:43 -08:00
mAppendAllocInfo = NULL ;
mTempParser = NULL ;
mTempReducer = NULL ;
mTempPassInstance = NULL ;
2021-02-01 13:55:29 -08:00
BfLogSys ( mCompiler - > mSystem , " CeMachine::CeMachine %p \n " , this ) ;
2021-01-11 09:41:43 -08:00
}
CeMachine : : ~ CeMachine ( )
{
for ( auto context : mContextList )
delete context ;
delete mTempPassInstance ;
delete mTempParser ;
delete mTempReducer ;
delete mAppendAllocInfo ;
delete mCeModule ;
auto _RemoveFunctionInfo = [ & ] ( CeFunctionInfo * functionInfo )
{
2021-02-25 10:14:22 -08:00
if ( functionInfo - > mMethodInstance ! = NULL )
functionInfo - > mMethodInstance - > mInCEMachine = false ;
2021-01-11 09:41:43 -08:00
if ( functionInfo - > mCeFunction ! = NULL )
{
// We don't need to actually unmap it at this point
functionInfo - > mCeFunction - > mId = - 1 ;
for ( auto innerFunction : functionInfo - > mCeFunction - > mInnerFunctions )
innerFunction - > mId = - 1 ;
}
delete functionInfo ;
} ;
for ( auto kv : mNamedFunctionMap )
{
if ( kv . mValue - > mMethodInstance = = NULL )
_RemoveFunctionInfo ( kv . mValue ) ;
}
for ( auto kv : mFunctions )
{
BF_ASSERT ( kv . mValue ! = NULL ) ;
_RemoveFunctionInfo ( kv . mValue ) ;
}
}
void CeMachine : : Init ( )
{
mCeModule = new BfModule ( mCompiler - > mContext , " __constEval " ) ;
mCeModule - > mIsSpecialModule = true ;
//mCeModule->mIsScratchModule = true;
mCeModule - > mIsComptimeModule = true ;
//mCeModule->mIsReified = true;
if ( mCompiler - > mIsResolveOnly )
mCeModule - > mIsReified = true ;
else
mCeModule - > mIsReified = false ;
mCeModule - > Init ( ) ;
mCeModule - > mBfIRBuilder = new BfIRBuilder ( mCeModule ) ;
mCeModule - > mBfIRBuilder - > mDbgVerifyCodeGen = true ;
mCeModule - > FinishInit ( ) ;
mCeModule - > mBfIRBuilder - > mHasDebugInfo = false ; // Only line info
mCeModule - > mBfIRBuilder - > mIgnoreWrites = false ;
mCeModule - > mWantsIRIgnoreWrites = false ;
}
BeContext * CeMachine : : GetBeContext ( )
{
if ( mCeModule = = NULL )
return NULL ;
return mCeModule - > mBfIRBuilder - > mBeIRCodeGen - > mBeContext ;
}
BeModule * CeMachine : : GetBeModule ( )
{
if ( mCeModule = = NULL )
return NULL ;
return mCeModule - > mBfIRBuilder - > mBeIRCodeGen - > mBeModule ;
}
void CeMachine : : CompileStarted ( )
{
mRevisionExecuteTime = 0 ;
mRevision + + ;
2021-02-01 13:55:29 -08:00
mMethodBindRevision + + ;
2021-01-11 09:41:43 -08:00
if ( mCeModule ! = NULL )
{
delete mCeModule ;
mCeModule = NULL ;
}
}
void CeMachine : : CompileDone ( )
{
2021-02-01 13:55:29 -08:00
// So things like deleted local methods get rechecked
2021-01-11 09:41:43 -08:00
mRevision + + ;
2021-02-01 13:55:29 -08:00
mMethodBindRevision + + ;
2021-01-13 05:09:09 -08:00
mTypeInfoMap . Clear ( ) ;
mMethodInstanceSet . Clear ( ) ;
2021-01-11 09:41:43 -08:00
}
void CeMachine : : DerefMethodInfo ( CeFunctionInfo * ceFunctionInfo )
{
ceFunctionInfo - > mRefCount - - ;
if ( ceFunctionInfo - > mRefCount > 0 )
return ;
BF_ASSERT ( ceFunctionInfo - > mMethodInstance = = NULL ) ;
if ( ! ceFunctionInfo - > mName . IsEmpty ( ) )
{
auto itr = mNamedFunctionMap . Find ( ceFunctionInfo - > mName ) ;
if ( itr - > mValue = = ceFunctionInfo )
mNamedFunctionMap . Remove ( itr ) ;
}
delete ceFunctionInfo ;
}
void CeMachine : : RemoveMethod ( BfMethodInstance * methodInstance )
{
BfLogSys ( methodInstance - > GetOwner ( ) - > mModule - > mSystem , " CeMachine::RemoveMethod %p \n " , methodInstance ) ;
2021-02-01 13:55:29 -08:00
mMethodBindRevision + + ;
2021-01-11 09:41:43 -08:00
auto itr = mFunctions . Find ( methodInstance ) ;
auto ceFunctionInfo = itr - > mValue ;
BF_ASSERT ( itr ! = mFunctions . end ( ) ) ;
if ( itr ! = mFunctions . end ( ) )
{
if ( ceFunctionInfo - > mMethodInstance = = methodInstance )
{
auto ceFunction = ceFunctionInfo - > mCeFunction ;
for ( auto & callEntry : ceFunction - > mCallTable )
{
if ( callEntry . mFunctionInfo ! = NULL )
DerefMethodInfo ( callEntry . mFunctionInfo ) ;
}
if ( ceFunction - > mId ! = - 1 )
{
mFunctionIdMap . Remove ( ceFunction - > mId ) ;
ceFunction - > mId = - 1 ;
for ( auto innerFunction : ceFunction - > mInnerFunctions )
{
mFunctionIdMap . Remove ( innerFunction - > mId ) ;
innerFunction - > mId = - 1 ;
}
}
delete ceFunction ;
ceFunctionInfo - > mCeFunction = NULL ;
ceFunctionInfo - > mMethodInstance = NULL ;
if ( methodInstance - > mMethodDef - > mIsLocalMethod )
{
// We can't rebuild these anyway
}
else if ( ceFunctionInfo - > mRefCount > 1 )
{
// Generate a methodref
ceFunctionInfo - > mMethodRef = methodInstance ;
}
DerefMethodInfo ( ceFunctionInfo ) ;
}
mFunctions . Remove ( itr ) ;
}
}
CeErrorKind CeMachine : : WriteConstant ( CeConstStructData & data , BeConstant * constVal , CeContext * ceContext )
{
auto ceModule = mCeModule ;
auto beType = constVal - > GetType ( ) ;
if ( auto globalVar = BeValueDynCast < BeGlobalVariable > ( constVal ) )
{
if ( globalVar - > mName . StartsWith ( " __bfStrObj " ) )
{
int stringId = atoi ( globalVar - > mName . c_str ( ) + 10 ) ;
2021-02-25 10:14:22 -08:00
addr_ce stringAddr ;
if ( data . mQueueFixups )
{
stringAddr = 0 ;
CeConstStructFixup fixup ;
fixup . mKind = CeConstStructFixup : : Kind_StringPtr ;
fixup . mValue = stringId ;
fixup . mOffset = ( int ) data . mData . mSize ;
data . mFixups . Add ( fixup ) ;
}
else
{
stringAddr = ceContext - > GetString ( stringId ) ;
}
2021-01-11 09:41:43 -08:00
auto ptr = data . mData . GrowUninitialized ( ceModule - > mSystem - > mPtrSize ) ;
int64 addr64 = stringAddr ;
memcpy ( ptr , & addr64 , ceModule - > mSystem - > mPtrSize ) ;
return CeErrorKind_None ;
}
if ( globalVar - > mInitializer = = NULL )
{
auto ptr = data . mData . GrowUninitialized ( ceModule - > mSystem - > mPtrSize ) ;
int64 addr64 = ( addr_ce ) 0 ;
memcpy ( ptr , & addr64 , ceModule - > mSystem - > mPtrSize ) ;
return CeErrorKind_None ;
//TODO: Add this global variable in there and fixup
// CeStaticFieldInfo* staticFieldInfoPtr = NULL;
// if (mCeMachine->mStaticFieldMap.TryGetValue(globalVar->mName, &staticFieldInfoPtr))
// {
// CeStaticFieldInfo* staticFieldInfo = staticFieldInfoPtr;
//
// int* staticFieldTableIdxPtr = NULL;
// if (mStaticFieldMap.TryAdd(globalVar, NULL, &staticFieldTableIdxPtr))
// {
// CeStaticFieldEntry staticFieldEntry;
// staticFieldEntry.mTypeId = staticFieldInfo->mFieldInstance->mOwner->mTypeId;
// staticFieldEntry.mName = globalVar->mName;
// staticFieldEntry.mSize = globalVar->mType->mSize;
// *staticFieldTableIdxPtr = (int)mCeFunction->mStaticFieldTable.size();
// mCeFunction->mStaticFieldTable.Add(staticFieldEntry);
// }
//
// auto result = FrameAlloc(mCeMachine->GetBeContext()->GetPointerTo(globalVar->mType));
//
// Emit(CeOp_GetStaticField);
// EmitFrameOffset(result);
// Emit((int32)*staticFieldTableIdxPtr);
//
// return result;
// }
// return CeErrorKind_GlobalVariable;
}
BF_ASSERT ( ! data . mQueueFixups ) ;
CeConstStructData gvData ;
auto result = WriteConstant ( gvData , globalVar - > mInitializer , ceContext ) ;
if ( result ! = CeErrorKind_None )
return result ;
uint8 * gvPtr = ceContext - > CeMalloc ( gvData . mData . mSize ) ;
memcpy ( gvPtr , gvData . mData . mVals , gvData . mData . mSize ) ;
auto ptr = data . mData . GrowUninitialized ( ceModule - > mSystem - > mPtrSize ) ;
int64 addr64 = ( addr_ce ) ( gvPtr - ceContext - > mMemory . mVals ) ;
memcpy ( ptr , & addr64 , mCeModule - > mSystem - > mPtrSize ) ;
return CeErrorKind_None ;
}
else if ( auto beFunc = BeValueDynCast < BeFunction > ( constVal ) )
{
return CeErrorKind_FunctionPointer ;
}
else if ( auto constStruct = BeValueDynCast < BeStructConstant > ( constVal ) )
{
int startOfs = data . mData . mSize ;
if ( constStruct - > mType - > mTypeCode = = BeTypeCode_Struct )
{
BeStructType * structType = ( BeStructType * ) constStruct - > mType ;
BF_ASSERT ( structType - > mMembers . size ( ) = = constStruct - > mMemberValues . size ( ) ) ;
for ( int memberIdx = 0 ; memberIdx < ( int ) constStruct - > mMemberValues . size ( ) ; memberIdx + + )
{
auto & member = structType - > mMembers [ memberIdx ] ;
// Do any per-member alignment
int wantZeroes = member . mByteOffset - ( data . mData . mSize - startOfs ) ;
if ( wantZeroes > 0 )
data . mData . Insert ( data . mData . size ( ) , ( uint8 ) 0 , wantZeroes ) ;
auto result = WriteConstant ( data , constStruct - > mMemberValues [ memberIdx ] , ceContext ) ;
if ( result ! = CeErrorKind_None )
return result ;
}
// Do end padding
data . mData . Insert ( data . mData . size ( ) , ( uint8 ) 0 , structType - > mSize - ( data . mData . mSize - startOfs ) ) ;
}
else if ( constStruct - > mType - > mTypeCode = = BeTypeCode_SizedArray )
{
for ( auto & memberVal : constStruct - > mMemberValues )
{
auto result = WriteConstant ( data , memberVal , ceContext ) ;
if ( result ! = CeErrorKind_None )
return result ;
}
}
else
BF_FATAL ( " Invalid StructConst type " ) ;
}
else if ( auto constStr = BeValueDynCast < BeStringConstant > ( constVal ) )
{
data . mData . Insert ( data . mData . mSize , ( uint8 * ) constStr - > mString . c_str ( ) , ( int ) constStr - > mString . length ( ) + 1 ) ;
}
else if ( auto constCast = BeValueDynCast < BeCastConstant > ( constVal ) )
{
auto result = WriteConstant ( data , constCast - > mTarget , ceContext ) ;
if ( result ! = CeErrorKind_None )
return result ;
}
else if ( auto constGep = BeValueDynCast < BeGEPConstant > ( constVal ) )
{
if ( auto globalVar = BeValueDynCast < BeGlobalVariable > ( constGep - > mTarget ) )
{
BF_ASSERT ( constGep - > mIdx0 = = 0 ) ;
int64 dataOfs = 0 ;
if ( globalVar - > mType - > mTypeCode = = BeTypeCode_Struct )
{
auto structType = ( BeStructType * ) globalVar - > mType ;
dataOfs = structType - > mMembers [ constGep - > mIdx1 ] . mByteOffset ;
}
else if ( globalVar - > mType - > mTypeCode = = BeTypeCode_SizedArray )
{
auto arrayType = ( BeSizedArrayType * ) globalVar - > mType ;
2021-01-18 14:09:16 -08:00
dataOfs = arrayType - > mElementType - > GetStride ( ) * constGep - > mIdx1 ;
2021-01-11 09:41:43 -08:00
}
else
{
BF_FATAL ( " Invalid GEP " ) ;
}
addr_ce addr = - 1 ;
if ( globalVar - > mName . StartsWith ( " __bfStrData " ) )
{
int stringId = atoi ( globalVar - > mName . c_str ( ) + 11 ) ;
if ( data . mQueueFixups )
{
addr = 0 ;
CeConstStructFixup fixup ;
fixup . mKind = CeConstStructFixup : : Kind_StringCharPtr ;
fixup . mValue = stringId ;
fixup . mOffset = ( int ) data . mData . mSize ;
data . mFixups . Add ( fixup ) ;
}
else
{
addr_ce stringAddr = ceContext - > GetString ( stringId ) ;
BfTypeInstance * stringTypeInst = ( BfTypeInstance * ) ceModule - > ResolveTypeDef ( ceModule - > mCompiler - > mStringTypeDef , BfPopulateType_Data ) ;
addr = stringAddr + stringTypeInst - > mInstSize ;
}
}
if ( addr ! = - 1 )
{
auto ptr = data . mData . GrowUninitialized ( ceModule - > mSystem - > mPtrSize ) ;
int64 addr64 = addr + dataOfs ;
memcpy ( ptr , & addr64 , ceModule - > mSystem - > mPtrSize ) ;
return CeErrorKind_None ;
}
return CeErrorKind_GlobalVariable ;
// auto sym = GetSymbol(globalVar);
//
// BeMCRelocation reloc;
// reloc.mKind = BeMCRelocationKind_ADDR64;
// reloc.mOffset = sect.mData.GetPos();
// reloc.mSymTableIdx = sym->mIdx;
// sect.mRelocs.push_back(reloc);
// sect.mData.Write((int64)dataOfs);
}
else
{
BF_FATAL ( " Invalid GEPConstant " ) ;
}
}
/*else if ((beType->IsPointer()) && (constVal->mTarget != NULL))
{
auto result = WriteConstant ( arr , constVal - > mTarget ) ;
if ( result ! = CeErrorKind_None )
return result ;
}
else if ( beType - > IsComposite ( ) )
{
BF_ASSERT ( constVal - > mInt64 = = 0 ) ;
int64 zero = 0 ;
int sizeLeft = beType - > mSize ;
while ( sizeLeft > 0 )
{
int writeSize = BF_MIN ( sizeLeft , 8 ) ;
auto ptr = arr . GrowUninitialized ( writeSize ) ;
memset ( ptr , 0 , writeSize ) ;
sizeLeft - = writeSize ;
}
} */
else if ( BeValueDynCastExact < BeConstant > ( constVal ) ! = NULL )
{
if ( constVal - > mType - > IsStruct ( ) )
{
if ( constVal - > mType - > mSize > 0 )
{
auto ptr = data . mData . GrowUninitialized ( constVal - > mType - > mSize ) ;
memset ( ptr , 0 , constVal - > mType - > mSize ) ;
}
}
else
{
auto ptr = data . mData . GrowUninitialized ( beType - > mSize ) ;
memcpy ( ptr , & constVal - > mInt64 , beType - > mSize ) ;
}
}
else
return CeErrorKind_Error ;
return CeErrorKind_None ;
2020-12-13 08:04:42 -08:00
}
2021-01-26 06:33:23 -08:00
void CeMachine : : CheckFunctionKind ( CeFunction * ceFunction )
2020-12-22 04:50:37 -08:00
{
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Normal ;
2020-12-22 04:50:37 -08:00
2020-12-19 14:19:33 -08:00
if ( ceFunction - > mMethodInstance ! = NULL )
2020-12-17 04:51:05 -08:00
{
2020-12-19 14:19:33 -08:00
auto methodDef = ceFunction - > mMethodInstance - > mMethodDef ;
if ( methodDef - > mIsExtern )
2020-12-17 04:51:05 -08:00
{
2020-12-19 14:19:33 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Extern ;
auto owner = ceFunction - > mMethodInstance - > GetOwner ( ) ;
if ( owner = = mCeModule - > mContext - > mBfObjectType )
2020-12-17 04:51:05 -08:00
{
2021-01-08 16:21:03 -08:00
if ( methodDef - > mName = = " Comptime_GetType " )
2020-12-19 14:19:33 -08:00
{
ceFunction - > mFunctionKind = CeFunctionKind_GetReflectType ;
}
2020-12-17 04:51:05 -08:00
}
2020-12-23 08:53:38 -08:00
else if ( owner - > IsInstanceOf ( mCeModule - > mCompiler - > mTypeTypeDef ) )
{
2021-01-08 16:21:03 -08:00
if ( methodDef - > mName = = " Comptime_GetTypeById " )
2020-12-23 08:53:38 -08:00
{
ceFunction - > mFunctionKind = CeFunctionKind_GetReflectTypeById ;
}
2021-01-11 09:41:43 -08:00
else if ( methodDef - > mName = = " Comptime_GetTypeByName " )
{
ceFunction - > mFunctionKind = CeFunctionKind_GetReflectTypeByName ;
}
else if ( methodDef - > mName = = " Comptime_GetSpecializedType " )
{
ceFunction - > mFunctionKind = CeFunctionKind_GetReflectSpecializedType ;
}
else if ( methodDef - > mName = = " Comptime_Type_GetCustomAttribute " )
{
ceFunction - > mFunctionKind = CeFunctionKind_Type_GetCustomAttribute ;
}
2021-01-13 05:09:09 -08:00
else if ( methodDef - > mName = = " Comptime_GetMethod " )
{
ceFunction - > mFunctionKind = CeFunctionKind_GetMethod ;
}
else if ( methodDef - > mName = = " Comptime_GetMethodCount " )
{
ceFunction - > mFunctionKind = CeFunctionKind_GetMethodCount ;
}
else if ( methodDef - > mName = = " Comptime_Method_ToString " )
{
ceFunction - > mFunctionKind = CeFunctionKind_Method_ToString ;
}
else if ( methodDef - > mName = = " Comptime_Method_GetName " )
{
ceFunction - > mFunctionKind = CeFunctionKind_Method_GetName ;
}
else if ( methodDef - > mName = = " Comptime_Method_GetInfo " )
{
ceFunction - > mFunctionKind = CeFunctionKind_Method_GetInfo ;
}
else if ( methodDef - > mName = = " Comptime_Method_GetParamInfo " )
{
ceFunction - > mFunctionKind = CeFunctionKind_Method_GetParamInfo ;
}
2020-12-23 08:53:38 -08:00
}
2021-01-08 16:21:03 -08:00
else if ( owner - > IsInstanceOf ( mCeModule - > mCompiler - > mCompilerTypeDef ) )
{
2021-01-13 05:09:09 -08:00
if ( methodDef - > mName = = " Comptime_EmitTypeBody " )
2021-01-08 16:21:03 -08:00
{
2021-01-13 05:09:09 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_EmitTypeBody ;
}
2021-12-16 09:38:19 -05:00
if ( methodDef - > mName = = " Comptime_EmitAddInterface " )
{
ceFunction - > mFunctionKind = CeFunctionKind_EmitAddInterface ;
}
2021-01-13 05:09:09 -08:00
else if ( methodDef - > mName = = " Comptime_EmitMethodEntry " )
{
ceFunction - > mFunctionKind = CeFunctionKind_EmitMethodEntry ;
}
else if ( methodDef - > mName = = " Comptime_EmitMethodExit " )
{
ceFunction - > mFunctionKind = CeFunctionKind_EmitMethodExit ;
}
else if ( methodDef - > mName = = " Comptime_EmitMixin " )
{
ceFunction - > mFunctionKind = CeFunctionKind_EmitMixin ;
2021-01-08 16:21:03 -08:00
}
}
2020-12-19 14:19:33 -08:00
else if ( owner - > IsInstanceOf ( mCeModule - > mCompiler - > mDiagnosticsDebugTypeDef ) )
{
if ( methodDef - > mName = = " Write " )
{
if ( ceFunction - > mMethodInstance - > GetParamCount ( ) = = 1 )
ceFunction - > mFunctionKind = CeFunctionKind_DebugWrite_Int ;
else
ceFunction - > mFunctionKind = CeFunctionKind_DebugWrite ;
}
}
2020-12-23 08:53:38 -08:00
else if ( owner - > IsInstanceOf ( mCeModule - > mCompiler - > mThreadTypeDef ) )
{
if ( methodDef - > mName = = " SleepInternal " )
ceFunction - > mFunctionKind = CeFunctionKind_Sleep ;
}
2020-12-19 14:19:33 -08:00
else if ( owner - > IsInstanceOf ( mCeModule - > mCompiler - > mInternalTypeDef ) )
2020-12-17 04:51:05 -08:00
{
2020-12-19 14:19:33 -08:00
if ( methodDef - > mName = = " ThrowIndexOutOfRange " )
ceFunction - > mFunctionKind = CeFunctionKind_OOB ;
else if ( methodDef - > mName = = " FatalError " )
ceFunction - > mFunctionKind = CeFunctionKind_FatalError ;
else if ( methodDef - > mName = = " Dbg_RawAlloc " )
ceFunction - > mFunctionKind = CeFunctionKind_Malloc ;
else if ( methodDef - > mName = = " Dbg_RawFree " )
ceFunction - > mFunctionKind = CeFunctionKind_Free ;
2021-01-26 06:33:23 -08:00
else if ( methodDef - > mName = = " ObjectDynCheckFailed " )
ceFunction - > mFunctionKind = CeFunctionKind_DynCheckFailed ;
}
else if ( owner - > IsInstanceOf ( mCeModule - > mCompiler - > mPlatformTypeDef ) )
{
2021-12-28 15:49:50 -05:00
if ( methodDef - > mName = = " BfpDirectory_Create " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpDirectory_Create ;
else if ( methodDef - > mName = = " BfpDirectory_Rename " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpDirectory_Rename ;
else if ( methodDef - > mName = = " BfpDirectory_Delete " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpDirectory_Delete ;
else if ( methodDef - > mName = = " BfpDirectory_GetCurrent " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpDirectory_GetCurrent ;
else if ( methodDef - > mName = = " BfpDirectory_SetCurrent " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpDirectory_SetCurrent ;
else if ( methodDef - > mName = = " BfpDirectory_Exists " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpDirectory_Exists ;
else if ( methodDef - > mName = = " BfpDirectory_GetSysDirectory " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpDirectory_GetSysDirectory ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " BfpFile_Close " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Close ;
else if ( methodDef - > mName = = " BfpFile_Create " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Create ;
else if ( methodDef - > mName = = " BfpFile_Flush " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Flush ;
else if ( methodDef - > mName = = " BfpFile_GetFileSize " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_GetFileSize ;
else if ( methodDef - > mName = = " BfpFile_Read " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Read ;
else if ( methodDef - > mName = = " BfpFile_Release " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Release ;
else if ( methodDef - > mName = = " BfpFile_Seek " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Seek ;
else if ( methodDef - > mName = = " BfpFile_Truncate " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Truncate ;
else if ( methodDef - > mName = = " BfpFile_Write " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Write ;
2021-12-28 15:49:50 -05:00
else if ( methodDef - > mName = = " BfpFile_GetTime_LastWrite " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_GetTime_LastWrite ;
else if ( methodDef - > mName = = " BfpFile_GetAttributes " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_GetAttributes ;
else if ( methodDef - > mName = = " BfpFile_SetAttributes " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_SetAttributes ;
else if ( methodDef - > mName = = " BfpFile_Copy " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Copy ;
else if ( methodDef - > mName = = " BfpFile_Rename " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Rename ;
else if ( methodDef - > mName = = " BfpFile_Delete " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Delete ;
else if ( methodDef - > mName = = " BfpFile_Exists " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_Exists ;
else if ( methodDef - > mName = = " BfpFile_GetTempPath " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_GetTempPath ;
else if ( methodDef - > mName = = " BfpFile_GetTempFileName " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_GetTempFileName ;
else if ( methodDef - > mName = = " BfpFile_GetFullPath " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_GetFullPath ;
else if ( methodDef - > mName = = " BfpFile_GetActualPath " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFile_GetActualPath ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " BfpSpawn_Create " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpSpawn_Create ;
else if ( methodDef - > mName = = " BfpSpawn_GetStdHandles " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpSpawn_GetStdHandles ;
else if ( methodDef - > mName = = " BfpSpawn_Kill " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpSpawn_Kill ;
else if ( methodDef - > mName = = " BfpSpawn_Release " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpSpawn_Release ;
else if ( methodDef - > mName = = " BfpSpawn_WaitFor " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpSpawn_WaitFor ;
2021-12-28 15:49:50 -05:00
else if ( methodDef - > mName = = " BfpFindFileData_FindFirstFile " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFindFileData_FindFirstFile ;
else if ( methodDef - > mName = = " BfpFindFileData_FindNextFile " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFindFileData_FindNextFile ;
else if ( methodDef - > mName = = " BfpFindFileData_GetFileName " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFindFileData_GetFileName ;
else if ( methodDef - > mName = = " BfpFindFileData_GetTime_LastWrite " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFindFileData_GetTime_LastWrite ;
else if ( methodDef - > mName = = " BfpFindFileData_GetTime_Created " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFindFileData_GetTime_Created ;
else if ( methodDef - > mName = = " BfpFindFileData_GetTime_Access " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFindFileData_GetTime_Access ;
else if ( methodDef - > mName = = " BfpFindFileData_GetFileAttributes " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFindFileData_GetFileAttributes ;
else if ( methodDef - > mName = = " BfpFindFileData_GetFileSize " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFindFileData_GetFileSize ;
else if ( methodDef - > mName = = " BfpFindFileData_Release " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpFindFileData_Release ;
else if ( methodDef - > mName = = " BfpSystem_GetTimeStamp " )
ceFunction - > mFunctionKind = CeFunctionKind_BfpSystem_GetTimeStamp ;
2020-12-17 04:51:05 -08:00
}
2020-12-19 14:19:33 -08:00
else if ( owner - > IsInstanceOf ( mCeModule - > mCompiler - > mChar32TypeDef ) )
2020-12-17 04:51:05 -08:00
{
2020-12-19 14:19:33 -08:00
if ( methodDef - > mName = = " get__ToLower " )
ceFunction - > mFunctionKind = CeFunctionKind_Char32_ToLower ;
else if ( methodDef - > mName = = " get__ToUpper " )
ceFunction - > mFunctionKind = CeFunctionKind_Char32_ToUpper ;
else if ( methodDef - > mName = = " get__IsLower " )
ceFunction - > mFunctionKind = CeFunctionKind_Char32_IsLower ;
else if ( methodDef - > mName = = " get__IsUpper " )
ceFunction - > mFunctionKind = CeFunctionKind_Char32_IsUpper ;
else if ( methodDef - > mName = = " get__IsWhiteSpace_EX " )
ceFunction - > mFunctionKind = CeFunctionKind_Char32_IsWhiteSpace_EX ;
else if ( methodDef - > mName = = " get__IsLetter " )
ceFunction - > mFunctionKind = CeFunctionKind_Char32_IsLetter ;
else if ( methodDef - > mName = = " get__IsLetterOrDigit " )
ceFunction - > mFunctionKind = CeFunctionKind_Char32_IsLetterOrDigit ;
else if ( methodDef - > mName = = " get__IsNumer " )
ceFunction - > mFunctionKind = CeFunctionKind_Char32_IsNumber ;
2020-12-17 04:51:05 -08:00
}
2021-01-26 06:33:23 -08:00
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 ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Acos " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Acos ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Asin " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Asin ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Atan " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Atan ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Atan2 " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Atan2 ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Ceiling " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Ceiling ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Cos " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Cos ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Cosh " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Cosh ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Exp " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Exp ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Floor " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Floor ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Log " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Log ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Log10 " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Log10 ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Mod " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Mod ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Pow " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Pow ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Round " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Round ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Sin " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Sin ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Sinh " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Sinh ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Sqrt " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Sqrt ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Tan " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Tan ;
2021-12-20 09:39:39 -05:00
else if ( methodDef - > mName = = " Tanh " )
2021-01-26 06:33:23 -08:00
ceFunction - > mFunctionKind = CeFunctionKind_Math_Tanh ;
2021-12-20 09:39:39 -05:00
}
2020-12-17 04:51:05 -08:00
2021-11-26 08:59:46 -08:00
ceFunction - > mInitializeState = CeFunction : : InitializeState_Initialized ;
2020-12-19 14:19:33 -08:00
return ;
}
2020-12-17 04:51:05 -08:00
}
2021-01-26 06:33:23 -08:00
}
void CeMachine : : PrepareFunction ( CeFunction * ceFunction , CeBuilder * parentBuilder )
{
AutoTimer autoTimer ( mRevisionExecuteTime ) ;
SetAndRestoreValue < CeFunction * > prevCEFunction ( mPreparingFunction , ceFunction ) ;
2021-11-26 08:59:46 -08:00
BF_ASSERT ( ceFunction - > mInitializeState < = CeFunction : : InitializeState_Initialized ) ;
2021-11-20 10:39:01 -08:00
2021-01-26 06:33:23 -08:00
if ( ceFunction - > mFunctionKind = = CeFunctionKind_NotSet )
2021-11-20 10:39:01 -08:00
{
CheckFunctionKind ( ceFunction ) ;
2021-11-26 08:59:46 -08:00
if ( ceFunction - > mInitializeState = = CeFunction : : InitializeState_Initialized )
2021-11-20 10:39:01 -08:00
return ;
}
2020-12-13 08:04:42 -08:00
2021-11-26 08:59:46 -08:00
BF_ASSERT ( ceFunction - > mInitializeState < = CeFunction : : InitializeState_Initialized ) ;
if ( ceFunction - > mInitializeState = = CeFunction : : InitializeState_Initializing_ReEntry )
{
//Fail("Function generation re-entry");
return ;
}
2020-12-13 08:04:42 -08:00
2021-11-26 08:59:46 -08:00
if ( ceFunction - > mInitializeState = = CeFunction : : InitializeState_Initializing )
ceFunction - > mInitializeState = CeFunction : : InitializeState_Initializing_ReEntry ;
else
ceFunction - > mInitializeState = CeFunction : : InitializeState_Initializing ;
2020-12-13 08:04:42 -08:00
CeBuilder ceBuilder ;
2021-01-08 16:21:03 -08:00
SetAndRestoreValue < CeBuilder * > prevBuilder ( mCurBuilder , & ceBuilder ) ;
2020-12-19 14:19:33 -08:00
ceBuilder . mParentBuilder = parentBuilder ;
2020-12-13 08:04:42 -08:00
ceBuilder . mPtrSize = mCeModule - > mCompiler - > mSystem - > mPtrSize ;
ceBuilder . mCeMachine = this ;
2020-12-30 13:24:13 -08:00
ceBuilder . mCeFunction = ceFunction ;
2020-12-13 08:04:42 -08:00
ceBuilder . Build ( ) ;
2021-11-26 08:59:46 -08:00
ceFunction - > mInitializeState = CeFunction : : InitializeState_Initialized ;
2020-12-30 13:24:13 -08:00
2020-12-23 12:32:24 -08:00
/*if (!ceFunction->mCode.IsEmpty())
2020-12-13 08:04:42 -08:00
{
CeDumpContext dumpCtx ;
dumpCtx . mCeFunction = ceFunction ;
dumpCtx . mStart = & ceFunction - > mCode [ 0 ] ;
dumpCtx . mPtr = dumpCtx . mStart ;
dumpCtx . mEnd = dumpCtx . mPtr + ceFunction - > mCode . mSize ;
dumpCtx . Dump ( ) ;
OutputDebugStrF ( " Code for %s: \n %s \n " , ceBuilder . mBeFunction - > mName . c_str ( ) , dumpCtx . mStr . c_str ( ) ) ;
2020-12-23 12:32:24 -08:00
} */
2020-12-23 08:53:38 -08:00
}
2020-12-23 11:27:46 -08:00
void CeMachine : : MapFunctionId ( CeFunction * ceFunction )
{
if ( mCeModule - > mSystem - > mPtrSize = = 8 )
return ;
ceFunction - > mId = + + mCurFunctionId ;
mFunctionIdMap [ ceFunction - > mId ] = ceFunction ;
2020-12-13 08:04:42 -08:00
}
2020-12-14 10:20:44 -08:00
CeFunction * CeMachine : : GetFunction ( BfMethodInstance * methodInstance , BfIRValue func , bool & added )
2020-12-17 04:51:05 -08:00
{
if ( func )
{
if ( ( func . IsConst ( ) ) | | ( func . IsFake ( ) ) )
return NULL ;
}
CeFunctionInfo * * functionInfoPtr = NULL ;
CeFunctionInfo * ceFunctionInfo = NULL ;
2020-12-13 08:04:42 -08:00
CeFunction * ceFunction = NULL ;
2020-12-17 04:51:05 -08:00
if ( ! mFunctions . TryAdd ( methodInstance , NULL , & functionInfoPtr ) )
{
2021-11-26 08:59:46 -08:00
ceFunctionInfo = * functionInfoPtr ;
BF_ASSERT ( ceFunctionInfo - > mCeFunction ! = NULL ) ;
2020-12-17 04:51:05 -08:00
return ceFunctionInfo - > mCeFunction ;
}
2020-12-23 08:53:38 -08:00
BF_ASSERT ( ! methodInstance - > mInCEMachine ) ;
methodInstance - > mInCEMachine = true ;
BfLogSys ( mCeModule - > mSystem , " CeMachine::GetFunction %p \n " , methodInstance ) ;
2020-12-17 04:51:05 -08:00
if ( ! func )
{
ceFunctionInfo = new CeFunctionInfo ( ) ;
}
else
{
auto funcVal = mCeModule - > mBfIRBuilder - > mBeIRCodeGen - > GetBeValue ( func . mId ) ;
if ( auto function = BeValueDynCast < BeFunction > ( funcVal ) )
{
CeFunctionInfo * * namedFunctionInfoPtr = NULL ;
if ( mNamedFunctionMap . TryAdd ( function - > mName , NULL , & namedFunctionInfoPtr ) )
{
ceFunctionInfo = new CeFunctionInfo ( ) ;
ceFunctionInfo - > mName = function - > mName ;
* namedFunctionInfoPtr = ceFunctionInfo ;
}
else
{
ceFunctionInfo = * namedFunctionInfoPtr ;
}
}
else
{
ceFunctionInfo = new CeFunctionInfo ( ) ;
}
}
ceFunctionInfo - > mRefCount + + ;
* functionInfoPtr = ceFunctionInfo ;
if ( ceFunctionInfo - > mMethodInstance = = NULL )
2020-12-13 08:04:42 -08:00
{
2020-12-14 03:50:28 -08:00
added = true ;
2020-12-13 08:04:42 -08:00
auto module = methodInstance - > GetOwner ( ) - > mModule ;
2020-12-23 08:53:38 -08:00
BF_ASSERT ( ceFunctionInfo - > mCeFunction = = NULL ) ;
2020-12-13 08:04:42 -08:00
2020-12-23 11:27:46 -08:00
ceFunction = new CeFunction ( ) ;
2021-02-01 13:55:29 -08:00
ceFunction - > mCeMachine = this ;
2020-12-30 13:24:13 -08:00
ceFunction - > mIsVarReturn = methodInstance - > mReturnType - > IsVar ( ) ;
2020-12-17 04:51:05 -08:00
ceFunction - > mCeFunctionInfo = ceFunctionInfo ;
2021-02-25 10:14:22 -08:00
ceFunction - > mMethodInstance = methodInstance ;
2020-12-17 04:51:05 -08:00
ceFunctionInfo - > mMethodInstance = methodInstance ;
2021-02-25 10:14:22 -08:00
ceFunctionInfo - > mCeFunction = ceFunction ;
2020-12-23 11:27:46 -08:00
MapFunctionId ( ceFunction ) ;
2020-12-13 08:04:42 -08:00
}
2020-12-23 08:53:38 -08:00
2020-12-17 04:51:05 -08:00
return ceFunction ;
}
CeFunction * CeMachine : : GetPreparedFunction ( BfMethodInstance * methodInstance )
{
bool added = false ;
auto ceFunction = GetFunction ( methodInstance , BfIRValue ( ) , added ) ;
if ( ceFunction = = NULL )
return NULL ;
2021-11-26 08:59:46 -08:00
if ( ceFunction - > mInitializeState < CeFunction : : InitializeState_Initialized )
2020-12-19 14:19:33 -08:00
PrepareFunction ( ceFunction , NULL ) ;
2020-12-13 08:04:42 -08:00
return ceFunction ;
}
2021-01-13 05:09:09 -08:00
CeTypeInfo * CeMachine : : GetTypeInfo ( BfType * type )
{
if ( type = = NULL )
return NULL ;
auto typeInstance = type - > ToTypeInstance ( ) ;
if ( typeInstance = = NULL )
return NULL ;
CeTypeInfo * ceTypeInfo = NULL ;
if ( ! mTypeInfoMap . TryAdd ( type , NULL , & ceTypeInfo ) )
{
if ( ceTypeInfo - > mRevision = = typeInstance - > mRevision )
return ceTypeInfo ;
ceTypeInfo - > mMethodInstances . Clear ( ) ;
}
mCeModule - > PopulateType ( typeInstance , BfPopulateType_DataAndMethods ) ;
ceTypeInfo - > mRevision = typeInstance - > mRevision ;
for ( auto & methodGroup : typeInstance - > mMethodInstanceGroups )
{
2022-01-06 10:30:25 -05:00
if ( methodGroup . mOnDemandKind = = BfMethodOnDemandKind_NoDecl_AwaitingReference )
{
auto methodDef = typeInstance - > mTypeDef - > mMethods [ methodGroup . mMethodIdx ] ;
auto flags = ( ( methodDef - > mGenericParams . size ( ) ! = 0 ) | | ( typeInstance - > IsUnspecializedType ( ) ) ) ? BfGetMethodInstanceFlag_UnspecializedPass : BfGetMethodInstanceFlag_None ;
flags = ( BfGetMethodInstanceFlags ) ( flags | BfGetMethodInstanceFlag_MethodInstanceOnly ) ;
mCeModule - > GetMethodInstance ( typeInstance , methodDef , BfTypeVector ( ) , flags ) ;
}
2021-01-13 05:09:09 -08:00
if ( methodGroup . mDefault ! = NULL )
{
mMethodInstanceSet . Add ( methodGroup . mDefault ) ;
ceTypeInfo - > mMethodInstances . Add ( methodGroup . mDefault ) ;
}
if ( methodGroup . mMethodSpecializationMap ! = NULL )
{
for ( auto & kv : * methodGroup . mMethodSpecializationMap )
{
mMethodInstanceSet . Add ( kv . mValue ) ;
ceTypeInfo - > mMethodInstances . Add ( kv . mValue ) ;
}
}
}
return ceTypeInfo ;
}
BfMethodInstance * CeMachine : : GetMethodInstance ( int64 methodHandle )
{
BfMethodInstance * methodInstance = ( BfMethodInstance * ) ( intptr ) methodHandle ;
if ( ! mMethodInstanceSet . Contains ( methodInstance ) )
2021-01-13 06:00:29 -08:00
return NULL ;
2021-01-13 05:09:09 -08:00
return methodInstance ;
}
2021-12-31 14:17:17 -05:00
CeFunction * CeMachine : : QueueMethod ( BfMethodInstance * methodInstance , BfIRValue func )
2022-01-04 09:38:02 -05:00
{
2021-01-01 15:33:17 -08:00
if ( mPreparingFunction ! = NULL )
{
auto curOwner = mPreparingFunction - > mMethodInstance - > GetOwner ( ) ;
curOwner - > mModule - > AddDependency ( methodInstance - > GetOwner ( ) , curOwner , BfDependencyMap : : DependencyFlag_ConstEval ) ;
}
2020-12-31 11:31:19 -08:00
2020-12-14 03:50:28 -08:00
bool added = false ;
2021-12-31 14:17:17 -05:00
return GetFunction ( methodInstance , func , added ) ;
2020-12-13 08:04:42 -08:00
}
2020-12-17 04:51:05 -08:00
void CeMachine : : QueueMethod ( BfModuleMethodInstance moduleMethodInstance )
{
QueueMethod ( moduleMethodInstance . mMethodInstance , moduleMethodInstance . mFunc ) ;
}
2020-12-19 14:19:33 -08:00
void CeMachine : : QueueStaticField ( BfFieldInstance * fieldInstance , const StringImpl & mangledFieldName )
2021-01-11 09:41:43 -08:00
{
if ( mCurBuilder ! = NULL )
mCurBuilder - > mStaticFieldInstanceMap [ mangledFieldName ] = fieldInstance ;
2020-12-19 14:19:33 -08:00
}
2020-12-22 04:50:37 -08:00
void CeMachine : : SetAppendAllocInfo ( BfModule * module , BfIRValue allocValue , BfIRValue appendSizeValue )
{
delete mAppendAllocInfo ;
mAppendAllocInfo = new CeAppendAllocInfo ( ) ;
mAppendAllocInfo - > mModule = module ;
mAppendAllocInfo - > mAllocValue = allocValue ;
mAppendAllocInfo - > mAppendSizeValue = appendSizeValue ;
}
void CeMachine : : ClearAppendAllocInfo ( )
{
delete mAppendAllocInfo ;
mAppendAllocInfo = NULL ;
}
2020-12-13 08:04:42 -08:00
2021-01-11 09:41:43 -08:00
CeContext * CeMachine : : AllocContext ( )
2020-12-23 08:53:38 -08:00
{
2021-01-11 09:41:43 -08:00
CeContext * ceContext = NULL ;
if ( ! mContextList . IsEmpty ( ) )
2020-12-13 08:04:42 -08:00
{
2021-01-11 09:41:43 -08:00
ceContext = mContextList . back ( ) ;
mContextList . pop_back ( ) ;
2020-12-13 08:04:42 -08:00
}
2021-01-11 09:41:43 -08:00
else
2020-12-22 04:50:37 -08:00
{
2021-01-11 09:41:43 -08:00
ceContext = new CeContext ( ) ;
ceContext - > mCeMachine = this ;
ceContext - > mMemory . Reserve ( BF_CE_INITIAL_MEMORY ) ;
2020-12-22 04:50:37 -08:00
}
2020-12-13 08:04:42 -08:00
2021-12-20 09:39:39 -05:00
ceContext - > mCurEmitContext = mCurEmitContext ;
mCurEmitContext = NULL ;
2021-01-11 09:41:43 -08:00
mExecuteId + + ;
2021-12-20 15:07:38 -05:00
ceContext - > mStackSize = BF_CE_DEFAULT_STACK_SIZE ;
ceContext - > mMemory . Resize ( ceContext - > mStackSize ) ;
2021-01-11 09:41:43 -08:00
ceContext - > mExecuteId = mExecuteId ;
2021-12-20 09:39:39 -05:00
ceContext - > mCurHandleId = 0 ;
2021-01-11 09:41:43 -08:00
return ceContext ;
}
2020-12-13 08:04:42 -08:00
2021-01-11 09:41:43 -08:00
void CeMachine : : ReleaseContext ( CeContext * ceContext )
{
ceContext - > mStringMap . Clear ( ) ;
ceContext - > mReflectMap . Clear ( ) ;
ceContext - > mConstDataMap . Clear ( ) ;
ceContext - > mMemory . Clear ( ) ;
if ( ceContext - > mMemory . mAllocSize > BF_CE_MAX_CARRYOVER_MEMORY )
ceContext - > mMemory . Dispose ( ) ;
ceContext - > mStaticCtorExecSet . Clear ( ) ;
ceContext - > mStaticFieldMap . Clear ( ) ;
ceContext - > mHeap - > Clear ( BF_CE_MAX_CARRYOVER_HEAP ) ;
ceContext - > mReflectTypeIdOffset = - 1 ;
2021-12-20 09:39:39 -05:00
mCurEmitContext = ceContext - > mCurEmitContext ;
ceContext - > mCurEmitContext = NULL ;
2021-01-11 09:41:43 -08:00
mContextList . Add ( ceContext ) ;
2021-12-31 10:27:09 -05:00
for ( auto kv : ceContext - > mInternalDataMap )
kv . mValue - > Release ( ) ;
2021-12-20 09:39:39 -05:00
ceContext - > mInternalDataMap . Clear ( ) ;
2021-01-11 09:41:43 -08:00
}
2020-12-31 11:31:19 -08:00
2021-01-11 09:41:43 -08:00
BfTypedValue CeMachine : : Call ( BfAstNode * targetSrc , BfModule * module , BfMethodInstance * methodInstance , const BfSizedArray < BfIRValue > & args , CeEvalFlags flags , BfType * expectingType )
{
auto ceContext = AllocContext ( ) ;
auto result = ceContext - > Call ( targetSrc , module , methodInstance , args , flags , expectingType ) ;
ReleaseContext ( ceContext ) ;
return result ;
2020-12-13 08:04:42 -08:00
}
2021-12-20 09:39:39 -05:00