CeMachine.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. #pragma once
  2. #include "BfSystem.h"
  3. #include "BfModule.h"
  4. #include "BeefySysLib/util/Heap.h"
  5. #include "BeefySysLib/util/AllocDebug.h"
  6. NS_BF_BEGIN
  7. class BfMethodInstance;
  8. class BeModule;
  9. class BeContext;
  10. class BeDbgLoc;
  11. class BeType;
  12. class BeValue;
  13. class BeInst;
  14. class BeDbgFile;
  15. class BePhiInst;
  16. class BeFunction;
  17. class BeSwitchInst;
  18. class CeMachine;
  19. class CeFunction;
  20. typedef int addr_ce;
  21. #define CEOP_SIZED(OPNAME) \
  22. CeOp_##OPNAME##_8, \
  23. CeOp_##OPNAME##_16, \
  24. CeOp_##OPNAME##_32, \
  25. CeOp_##OPNAME##_64, \
  26. CeOp_##OPNAME##_X
  27. #define CEOP_SIZED_NUMERIC(OPNAME) \
  28. CeOp_##OPNAME##_I8, \
  29. CeOp_##OPNAME##_I16, \
  30. CeOp_##OPNAME##_I32, \
  31. CeOp_##OPNAME##_I64
  32. #define CEOP_SIZED_UNUMERIC(OPNAME) \
  33. CeOp_##OPNAME##_U8, \
  34. CeOp_##OPNAME##_U16, \
  35. CeOp_##OPNAME##_U32, \
  36. CeOp_##OPNAME##_U64
  37. #define CEOP_SIZED_NUMERIC_PLUSF(OPNAME) \
  38. CeOp_##OPNAME##_I8, \
  39. CeOp_##OPNAME##_I16, \
  40. CeOp_##OPNAME##_I32, \
  41. CeOp_##OPNAME##_I64, \
  42. CeOp_##OPNAME##_F32, \
  43. CeOp_##OPNAME##_F64
  44. enum CeErrorKind
  45. {
  46. CeErrorKind_None,
  47. CeErrorKind_GlobalVariable,
  48. CeErrorKind_FunctionPointer,
  49. CeErrorKind_Intrinsic
  50. };
  51. enum CeOp : int16
  52. {
  53. CeOp_InvalidOp,
  54. CeOp_Ret,
  55. CeOp_Jmp,
  56. CeOp_JmpIf,
  57. CeOp_JmpIfNot,
  58. CeOp_Error,
  59. CeOp_DynamicCastCheck,
  60. CeOp_GetString,
  61. CeOp_Malloc,
  62. CeOp_Free,
  63. CeOp_MemSet,
  64. CeOp_MemSet_Const,
  65. CeOp_MemCpy,
  66. CeOp_FrameAddr_32,
  67. CeOp_FrameAddr_64,
  68. CeOp_Zero,
  69. CEOP_SIZED(Const),
  70. CEOP_SIZED(Load),
  71. CEOP_SIZED(Store),
  72. CEOP_SIZED(Move),
  73. CEOP_SIZED(Push),
  74. CEOP_SIZED(Pop),
  75. CeOp_AdjustSP,
  76. CeOp_AdjustSPNeg,
  77. CeOp_AdjustSPConst,
  78. CeOp_GetSP,
  79. CeOp_SetSP,
  80. CeOp_Call,
  81. CeOp_Call_Virt,
  82. CeOp_Call_IFace,
  83. CeOp_Conv_I8_I16,
  84. CeOp_Conv_I8_I32,
  85. CeOp_Conv_I8_I64,
  86. CeOp_Conv_I8_F32,
  87. CeOp_Conv_I8_F64,
  88. CeOp_Conv_I16_I32,
  89. CeOp_Conv_I16_I64,
  90. CeOp_Conv_I16_F32,
  91. CeOp_Conv_I16_F64,
  92. CeOp_Conv_I32_I64,
  93. CeOp_Conv_I32_F32,
  94. CeOp_Conv_I32_F64,
  95. CeOp_Conv_I64_F32,
  96. CeOp_Conv_I64_F64,
  97. CeOp_Conv_U8_U16,
  98. CeOp_Conv_U8_U32,
  99. CeOp_Conv_U8_U64,
  100. CeOp_Conv_U8_F32,
  101. CeOp_Conv_U8_F64,
  102. CeOp_Conv_U16_U32,
  103. CeOp_Conv_U16_U64,
  104. CeOp_Conv_U16_F32,
  105. CeOp_Conv_U16_F64,
  106. CeOp_Conv_U32_U64,
  107. CeOp_Conv_U32_F32,
  108. CeOp_Conv_U32_F64,
  109. CeOp_Conv_U64_F32,
  110. CeOp_Conv_U64_F64,
  111. CeOp_Conv_F32_I8,
  112. CeOp_Conv_F32_I16,
  113. CeOp_Conv_F32_I32,
  114. CeOp_Conv_F32_I64,
  115. CeOp_Conv_F32_F64,
  116. CeOp_Conv_F64_I8,
  117. CeOp_Conv_F64_I16,
  118. CeOp_Conv_F64_I32,
  119. CeOp_Conv_F64_I64,
  120. CeOp_Conv_F64_F32,
  121. CEOP_SIZED_NUMERIC_PLUSF(AddConst),
  122. CEOP_SIZED_NUMERIC_PLUSF(Add),
  123. CEOP_SIZED_NUMERIC_PLUSF(Sub),
  124. CEOP_SIZED_NUMERIC_PLUSF(Mul),
  125. CEOP_SIZED_NUMERIC_PLUSF(Div),
  126. CEOP_SIZED_UNUMERIC(Div),
  127. CEOP_SIZED_NUMERIC_PLUSF(Mod),
  128. CEOP_SIZED_UNUMERIC(Mod),
  129. CEOP_SIZED_NUMERIC(And),
  130. CEOP_SIZED_NUMERIC(Or),
  131. CEOP_SIZED_NUMERIC(Xor),
  132. CEOP_SIZED_NUMERIC(Shl),
  133. CEOP_SIZED_NUMERIC(Shr),
  134. CEOP_SIZED_UNUMERIC(Shr),
  135. CEOP_SIZED_NUMERIC_PLUSF(Cmp_EQ),
  136. CEOP_SIZED_NUMERIC_PLUSF(Cmp_NE),
  137. CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLT),
  138. CEOP_SIZED_NUMERIC(Cmp_ULT),
  139. CEOP_SIZED_NUMERIC_PLUSF(Cmp_SLE),
  140. CEOP_SIZED_NUMERIC(Cmp_ULE),
  141. CEOP_SIZED_NUMERIC_PLUSF(Cmp_SGT),
  142. CEOP_SIZED_NUMERIC(Cmp_UGT),
  143. CEOP_SIZED_NUMERIC_PLUSF(Cmp_SGE),
  144. CEOP_SIZED_NUMERIC(Cmp_UGE),
  145. CEOP_SIZED_NUMERIC_PLUSF(Neg),
  146. CeOp_Not_I1,
  147. CEOP_SIZED_NUMERIC(Not),
  148. CeOp_COUNT
  149. };
  150. struct CeEmitEntry
  151. {
  152. int mCodePos;
  153. int mFile;
  154. int mLine;
  155. int mColumn;
  156. };
  157. class CeFunctionInfo
  158. {
  159. public:
  160. String mName;
  161. BfMethodInstance* mMethodInstance;
  162. BfMethodRef mMethodRef;
  163. CeFunction* mCeFunction;
  164. int mRefCount;
  165. public:
  166. CeFunctionInfo()
  167. {
  168. mMethodInstance = NULL;
  169. mCeFunction = NULL;
  170. mRefCount = 0;
  171. }
  172. };
  173. class CeCallEntry
  174. {
  175. public:
  176. CeFunctionInfo* mFunctionInfo;
  177. int mBindRevision;
  178. CeFunction* mFunction;
  179. public:
  180. CeCallEntry()
  181. {
  182. mFunctionInfo = NULL;
  183. mBindRevision = -1;
  184. mFunction = NULL;
  185. }
  186. };
  187. class CeStringEntry
  188. {
  189. public:
  190. int mStringId;
  191. int mBindExecuteId;
  192. addr_ce mStringAddr;
  193. public:
  194. CeStringEntry()
  195. {
  196. mStringId = -1;
  197. mBindExecuteId = -1;
  198. mStringAddr = 0;
  199. }
  200. };
  201. enum CeFunctionKind
  202. {
  203. CeFunctionKind_Normal,
  204. CeFunctionKind_Extern,
  205. CeFunctionKind_OOB,
  206. CeFunctionKind_FatalError,
  207. CeFunctionKind_DebugWrite,
  208. CeFunctionKind_DebugWrite_Int,
  209. };
  210. class CeFunction
  211. {
  212. public:
  213. CeFunctionInfo* mCeFunctionInfo;
  214. BfMethodInstance* mMethodInstance;
  215. CeFunctionKind mFunctionKind;
  216. bool mInitialized;
  217. bool mFailed;
  218. Array<uint8> mCode;
  219. Array<String> mFiles;
  220. Array<CeEmitEntry> mEmitTable;
  221. Array<CeCallEntry> mCallTable;
  222. Array<CeStringEntry> mStringTable;
  223. Array<BfType*> mTypeTable;
  224. String mGenError;
  225. int mFrameSize;
  226. public:
  227. CeFunction()
  228. {
  229. mCeFunctionInfo = NULL;
  230. mFunctionKind = CeFunctionKind_Normal;
  231. mInitialized = false;
  232. mMethodInstance = NULL;
  233. mFailed = false;
  234. mFrameSize = 0;
  235. }
  236. ~CeFunction();
  237. };
  238. enum CeEvalFlags
  239. {
  240. CeEvalFlags_None = 0
  241. };
  242. enum CeOperandKind
  243. {
  244. CeOperandKind_None,
  245. CeOperandKind_FrameOfs,
  246. CeOperandKind_AllocaAddr,
  247. CeOperandKind_Block,
  248. CeOperandKind_Immediate
  249. };
  250. class CeOperand
  251. {
  252. public:
  253. CeOperandKind mKind;
  254. union
  255. {
  256. int mFrameOfs;
  257. int mBlockIdx;
  258. int mImmediate;
  259. };
  260. BeType* mType;
  261. public:
  262. CeOperand()
  263. {
  264. mKind = CeOperandKind_None;
  265. mFrameOfs = 0;
  266. mType = NULL;
  267. }
  268. operator bool() const
  269. {
  270. return mKind != CeOperandKind_None;
  271. }
  272. bool IsImmediate()
  273. {
  274. return mKind == CeOperandKind_Immediate;
  275. }
  276. };
  277. #define BF_CE_STACK_SIZE 1024*1024
  278. #define BF_CE_MAX_MEMORY 128*1024*1024
  279. enum CeOperandInfoKind
  280. {
  281. CEOI_None,
  282. CEOI_FrameRef,
  283. CEOI_IMM8,
  284. CEOI_IMM16,
  285. CEOI_IMM32,
  286. CEOI_IMM64,
  287. CEOI_IMMF32,
  288. CEOI_IMMF64,
  289. CEOI_IMM_VAR,
  290. CEOI_JMPREL
  291. };
  292. enum CeSizeClass
  293. {
  294. CeSizeClass_8,
  295. CeSizeClass_16,
  296. CeSizeClass_32,
  297. CeSizeClass_64,
  298. CeSizeClass_X,
  299. };
  300. class CeDumpContext
  301. {
  302. public:
  303. CeFunction* mCeFunction;
  304. String mStr;
  305. uint8* mStart;
  306. uint8* mPtr;
  307. uint8* mEnd;
  308. public:
  309. void DumpOperandInfo(CeOperandInfoKind operandInfoKind);
  310. void Dump();
  311. };
  312. struct CePhiOutgoing
  313. {
  314. BeValue* mPhiValue;
  315. BePhiInst* mPhiInst;
  316. int mPhiBlockIdx;
  317. };
  318. class CeBlock
  319. {
  320. public:
  321. int mEmitOfs;
  322. Array<CePhiOutgoing> mPhiOutgoing;
  323. public:
  324. CeBlock()
  325. {
  326. mEmitOfs = -1;
  327. }
  328. };
  329. class CeJumpEntry
  330. {
  331. public:
  332. int mEmitPos;
  333. int mBlockIdx;
  334. };
  335. class CeBuilder
  336. {
  337. public:
  338. CeMachine* mCeMachine;
  339. CeFunction* mCeFunction;
  340. BeFunction* mBeFunction;
  341. CeOperand mReturnVal;
  342. BeType* mIntPtrType;
  343. int mPtrSize;
  344. String mError;
  345. BeDbgLoc* mCurDbgLoc;
  346. Array<CeBlock> mBlocks;
  347. Array<CeJumpEntry> mJumpTable;
  348. Dictionary<BeValue*, CeOperand> mValueToOperand;
  349. int mFrameSize;
  350. Dictionary<BeDbgFile*, int> mDbgFileMap;
  351. Dictionary<BeFunction*, int> mFunctionMap;
  352. Dictionary<int, int> mStringMap;
  353. public:
  354. CeBuilder()
  355. {
  356. mPtrSize = 0;
  357. mCeFunction = NULL;
  358. mBeFunction = NULL;
  359. mCeMachine = NULL;
  360. mCurDbgLoc = NULL;
  361. mFrameSize = 0;
  362. }
  363. void Fail(const StringImpl& error);
  364. CeOperand FrameAlloc(BeType* type);
  365. CeOperand EmitConst(int64 val, int size);
  366. CeOperand GetOperand(BeValue* value, bool allowAlloca = false, bool allowImmediate = false);
  367. CeSizeClass GetSizeClass(int size);
  368. int GetCodePos();
  369. void HandleParams();
  370. void Emit(uint8 val);
  371. void Emit(CeOp val);
  372. void EmitSizedOp(CeOp val, int size);
  373. void Emit(int32 val);
  374. void Emit(int64 val);
  375. void Emit(bool val);
  376. void Emit(void* ptr, int size);
  377. void EmitJump(CeOp op, const CeOperand& block);
  378. void EmitBinarySwitchSection(BeSwitchInst* switchInst, int startIdx, int endIdx);
  379. void EmitFrameOffset(const CeOperand& val);
  380. void FlushPhi(CeBlock* ceBlock, int targetBlockIdx);
  381. void EmitBinaryOp(CeOp iOp, CeOp fOp, const CeOperand& lhs, const CeOperand& rhs, CeOperand& result);
  382. void EmitUnaryOp(CeOp iOp, CeOp fOp, const CeOperand& val, CeOperand& result);
  383. void EmitSizedOp(CeOp op, const CeOperand& operand, CeOperand* result, bool allowNonStdSize);
  384. void Build();
  385. };
  386. class CeFrame
  387. {
  388. public:
  389. CeFunction* mFunction;
  390. addr_ce mStackAddr;
  391. addr_ce mFrameAddr;
  392. uint8* mInstPtr;
  393. public:
  394. CeFrame()
  395. {
  396. mFunction = NULL;
  397. mStackAddr = NULL;
  398. mFrameAddr = NULL;
  399. mInstPtr = NULL;
  400. }
  401. };
  402. class CeFunctionRef
  403. {
  404. //CeFunction* ;
  405. };
  406. class CeMachine
  407. {
  408. public:
  409. Dictionary<BfMethodInstance*, CeFunctionInfo*> mFunctions;
  410. Dictionary<String, CeFunctionInfo*> mNamedFunctionMap;
  411. BfCompiler* mCompiler;
  412. BfModule* mCeModule;
  413. int mRevision;
  414. int mExecuteId;
  415. ContiguousHeap* mHeap;
  416. Array<CeFrame> mCallStack;
  417. Array<uint8> mMemory;
  418. Dictionary<int, addr_ce> mStringMap;
  419. BfAstNode* mCurTargetSrc;
  420. BfModule* mCurModule;
  421. public:
  422. CeMachine(BfCompiler* compiler);
  423. ~CeMachine();
  424. BfError* Fail(const CeFrame& curFrame, const StringImpl& error);
  425. void Init();
  426. uint8* CeMalloc(int size);
  427. bool CeFree(addr_ce addr);
  428. BeContext* GetBeContext();
  429. BeModule* GetBeModule();
  430. void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo);
  431. void RemoveMethod(BfMethodInstance* methodInstance);
  432. int GetConstantSize(BfConstant* constant);
  433. void WriteConstant(uint8* ptr, BfConstant* constant);
  434. void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
  435. bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr);
  436. void PrepareFunction(CeFunction* methodInstance);
  437. CeFunction* GetFunction(BfMethodInstance* methodInstance, BfIRValue func, bool& added);
  438. CeFunction* GetPreparedFunction(BfMethodInstance* methodInstance);
  439. public:
  440. void CompileStarted();
  441. void QueueMethod(BfMethodInstance* methodInstance, BfIRValue func);
  442. void QueueMethod(BfModuleMethodInstance moduleMethodInstance);
  443. BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags);
  444. };
  445. NS_BF_END