PikaVM.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. /*
  2. * This file is part of the PikaScript project.
  3. * http://github.com/pikastech/pikapython
  4. *
  5. * MIT License
  6. *
  7. * Copyright (c) 2021 lyon liang6516@outlook.com
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a
  10. * copy of this software and associated documentation files (the "Software"),
  11. * to deal in the Software without restriction, including without limitation
  12. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13. * and/or sell copies of the Software, and to permit persons to whom the
  14. * Software is furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  22. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  24. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  25. * DEALINGS IN THE SOFTWARE.
  26. */
  27. #ifdef __cplusplus
  28. extern "C" {
  29. #endif
  30. #ifndef __PIKA_VM__H
  31. #define __PIKA_VM__H
  32. #include "PikaObj.h"
  33. #include "dataQueue.h"
  34. #include "dataQueueObj.h"
  35. #include "dataStack.h"
  36. #if PIKA_SETJMP_ENABLE
  37. #include <setjmp.h>
  38. #endif
  39. typedef struct {
  40. int8_t n_positional;
  41. int8_t n_positional_got;
  42. int8_t n_default;
  43. int8_t n_arg;
  44. int8_t i_arg;
  45. int8_t n_input;
  46. pika_bool is_vars;
  47. pika_bool is_keys;
  48. pika_bool is_default;
  49. ArgType method_type;
  50. PikaTuple* tuple;
  51. PikaDict* kw;
  52. PikaDict* kw_keys;
  53. char* var_tuple_name;
  54. char* kw_dict_name;
  55. char* type_list;
  56. } FunctionArgsInfo;
  57. typedef struct OperatorInfo OperatorInfo;
  58. struct OperatorInfo {
  59. char* opt;
  60. ArgType t1;
  61. ArgType t2;
  62. Arg* a1;
  63. Arg* a2;
  64. pika_float f1;
  65. pika_float f2;
  66. int64_t i1;
  67. int64_t i2;
  68. Arg* res;
  69. uint32_t num;
  70. PikaVMFrame* vm;
  71. };
  72. typedef enum VM_SIGNAL_CTRL {
  73. VM_SIGNAL_CTRL_NONE = 0,
  74. VM_SIGNAL_CTRL_EXIT,
  75. } VM_SIGNAL_CTRL;
  76. typedef union _EventDataType {
  77. int signal;
  78. Arg* arg;
  79. } EventDataType;
  80. typedef struct PikaArgEventQueue {
  81. uint32_t id[PIKA_EVENT_LIST_SIZE];
  82. EventDataType data[PIKA_EVENT_LIST_SIZE];
  83. PikaEventListener* listener[PIKA_EVENT_LIST_SIZE];
  84. Arg* res[PIKA_EVENT_LIST_SIZE];
  85. int head;
  86. int tail;
  87. } PikaEventQueue;
  88. #if PIKA_SETJMP_ENABLE
  89. typedef struct JmpBufCQ {
  90. jmp_buf* buf[PIKA_JMP_BUF_LIST_SIZE];
  91. int head;
  92. int tail;
  93. } JmpBufCQ;
  94. #endif
  95. typedef struct VMState VMState;
  96. struct VMState {
  97. VM_SIGNAL_CTRL signal_ctrl;
  98. int vm_cnt;
  99. #if PIKA_EVENT_ENABLE
  100. PikaEventQueue cq;
  101. PikaEventQueue sq;
  102. int event_pickup_cnt;
  103. pika_platform_thread_t* event_thread;
  104. pika_bool event_thread_exit;
  105. pika_bool event_thread_exit_done;
  106. #endif
  107. #if PIKA_DEBUG_BREAK_POINT_MAX > 0
  108. Hash break_module_hash[PIKA_DEBUG_BREAK_POINT_MAX];
  109. uint32_t break_point_pc[PIKA_DEBUG_BREAK_POINT_MAX];
  110. int break_point_cnt;
  111. #endif
  112. };
  113. typedef Arg* (*VM_instruct_handler)(PikaObj* self,
  114. PikaVMFrame* vm,
  115. char* data,
  116. Arg* arg_ret_reg);
  117. typedef struct VMInstruction VMInstruction;
  118. struct VMInstruction {
  119. VM_instruct_handler handler;
  120. const char* op_str;
  121. uint16_t op_idx;
  122. uint16_t op_str_len : 4;
  123. uint16_t : 12;
  124. };
  125. typedef struct VMInstructionSet VMInstructionSet;
  126. struct VMInstructionSet {
  127. const VMInstruction* instructions;
  128. uint16_t count;
  129. uint16_t signature;
  130. uint16_t op_idx_start;
  131. uint16_t op_idx_end;
  132. };
  133. VMParameters* pikaVM_run(PikaObj* self, char* pyLine);
  134. VMParameters* pikaVM_runAsm(PikaObj* self, char* pikaAsm);
  135. VMParameters* _pikaVM_runByteCodeFrame(PikaObj* self,
  136. ByteCodeFrame* byteCode_frame,
  137. pika_bool in_repl);
  138. VMParameters* _pikaVM_runByteCodeFrameGlobals(PikaObj* self,
  139. PikaObj* globals,
  140. ByteCodeFrame* byteCode_frame,
  141. pika_bool in_repl);
  142. VMParameters* pikaVM_runByteCodeFrame(PikaObj* self,
  143. ByteCodeFrame* byteCode_frame);
  144. static inline int instructUnit_getBlockDeepth(InstructUnit* self) {
  145. return self->deepth & 0x0F;
  146. }
  147. static inline int instructUnit_getInvokeDeepth(InstructUnit* self) {
  148. return self->deepth >> 4;
  149. }
  150. static inline enum InstructIndex instructUnit_getInstructIndex(
  151. InstructUnit* self) {
  152. return (enum InstructIndex)(self->isNewLine_instruct & 0x7F);
  153. }
  154. static inline int instructUnit_getConstPoolIndex(InstructUnit* self) {
  155. return self->const_pool_index;
  156. }
  157. static inline int instructUnit_getIsNewLine(InstructUnit* self) {
  158. return self->isNewLine_instruct >> 7;
  159. }
  160. static inline void instructUnit_setBlockDeepth(InstructUnit* self, int val) {
  161. self->deepth |= (0x0F & val);
  162. }
  163. static inline void instructUnit_setConstPoolIndex(InstructUnit* self, int val) {
  164. self->const_pool_index = val;
  165. }
  166. static inline void instructUnit_setInvokeDeepth(InstructUnit* self, int val) {
  167. self->deepth |= ((0x0F & val) << 4);
  168. }
  169. static inline void instructUnit_setInstruct(InstructUnit* self, int val) {
  170. self->isNewLine_instruct |= (0x7F & val);
  171. }
  172. static inline void instructUnit_setIsNewLine(InstructUnit* self, int val) {
  173. self->isNewLine_instruct |= ((0x01 & val) << 7);
  174. }
  175. InstructUnit* New_instructUnit(uint8_t data_size);
  176. void instructUnit_deinit(InstructUnit* self);
  177. enum InstructIndex pikaVM_getInstructFromAsm(char* line);
  178. void constPool_init(ConstPool* self);
  179. void constPool_deinit(ConstPool* self);
  180. void constPool_append(ConstPool* self, char* content);
  181. static inline void* constPool_getStart(ConstPool* self) {
  182. return self->content_start;
  183. }
  184. static inline int constPool_getLastOffset(ConstPool* self) {
  185. return self->size;
  186. }
  187. static inline char* constPool_getByOffset(ConstPool* self, int offset) {
  188. return (char*)((uintptr_t)constPool_getStart(self) + (uintptr_t)offset);
  189. }
  190. static inline char* PikaVMFrame_getConstWithInstructUnit(
  191. PikaVMFrame* vm,
  192. InstructUnit* ins_unit) {
  193. return constPool_getByOffset(&(vm->bytecode_frame->const_pool),
  194. instructUnit_getConstPoolIndex(ins_unit));
  195. }
  196. pika_bool PikaVMFrame_checkBreakPoint(PikaVMFrame* vm);
  197. typedef struct {
  198. PikaObj* globals;
  199. pika_bool in_repl;
  200. char* module_name;
  201. } pikaVM_run_ex_cfg;
  202. char* constPool_getNow(ConstPool* self);
  203. char* constPool_getNext(ConstPool* self);
  204. char* constPool_getByIndex(ConstPool* self, uint16_t index);
  205. void constPool_print(ConstPool* self);
  206. void byteCodeFrame_init(ByteCodeFrame* bf);
  207. void byteCodeFrame_deinit(ByteCodeFrame* bf);
  208. void byteCodeFrame_setName(ByteCodeFrame* self, char* name);
  209. size_t byteCodeFrame_getSize(ByteCodeFrame* bf);
  210. InstructUnit* byteCodeFrame_findInstructUnit(ByteCodeFrame* bcframe,
  211. int32_t iPcStart,
  212. enum InstructIndex index,
  213. int32_t* iOffset_p,
  214. pika_bool bIsForward);
  215. InstructUnit* byteCodeFrame_findInsUnitBackward(ByteCodeFrame* bcframe,
  216. int32_t pc_start,
  217. enum InstructIndex index,
  218. int32_t* p_offset);
  219. InstructUnit* byteCodeFrame_findInsForward(ByteCodeFrame* bcframe,
  220. int32_t pc_start,
  221. enum InstructIndex index,
  222. int32_t* p_offset);
  223. Hash byteCodeFrame_getNameHash(ByteCodeFrame* bcframe);
  224. void instructArray_init(InstructArray* ins_array);
  225. void instructArray_deinit(InstructArray* ins_array);
  226. void instructArray_append(InstructArray* ins_array, InstructUnit* ins_unit);
  227. void instructUnit_init(InstructUnit* ins_unit);
  228. void instructUnit_print(InstructUnit* self);
  229. void instructArray_print(InstructArray* self);
  230. static inline InstructUnit* instructArray_getStart(InstructArray* self) {
  231. return (InstructUnit*)self->content_start;
  232. }
  233. static inline size_t instructArray_getSize(InstructArray* self) {
  234. return (size_t)self->size;
  235. }
  236. static inline int PikaVMFrame_getInstructArraySize(PikaVMFrame* vm) {
  237. return instructArray_getSize(&(vm->bytecode_frame->instruct_array));
  238. }
  239. static inline InstructUnit* instructArray_getByOffset(InstructArray* self,
  240. int offset) {
  241. return (InstructUnit*)((uintptr_t)instructArray_getStart(self) +
  242. (uintptr_t)offset);
  243. }
  244. static inline InstructUnit* PikaVMFrame_getInstructUnitWithOffset(
  245. PikaVMFrame* vm,
  246. int offset) {
  247. return instructArray_getByOffset(&(vm->bytecode_frame->instruct_array),
  248. vm->pc + offset);
  249. }
  250. static inline InstructUnit* PikaVMFrame_getInstructNow(PikaVMFrame* vm) {
  251. return instructArray_getByOffset(&(vm->bytecode_frame->instruct_array),
  252. vm->pc);
  253. }
  254. void byteCodeFrame_print(ByteCodeFrame* self);
  255. static inline size_t instructUnit_getSize(void) {
  256. return (size_t)sizeof(InstructUnit);
  257. }
  258. uint16_t constPool_getOffsetByData(ConstPool* self, char* data);
  259. void instructArray_printWithConst(InstructArray* self, ConstPool* const_pool);
  260. void constPool_update(ConstPool* self);
  261. void instructArray_update(InstructArray* self);
  262. void constPool_printAsArray(ConstPool* self);
  263. void instructArray_printAsArray(InstructArray* self);
  264. void byteCodeFrame_loadByteCode(ByteCodeFrame* self, uint8_t* bytes);
  265. void byteCodeFrame_printAsArray(ByteCodeFrame* self);
  266. void byteCodeFrame_init(ByteCodeFrame* self);
  267. pika_bool pikaVM_registerInstructionSet(VMInstructionSet* ins_set);
  268. VMParameters* pikaVM_runByteCode(PikaObj* self, const uint8_t* bytecode);
  269. VMParameters* pikaVM_runByteCodeInconstant(PikaObj* self, uint8_t* bytecode);
  270. Arg* pikaVM_runByteCodeReturn(PikaObj* self,
  271. const uint8_t* bytecode,
  272. char* returnName);
  273. Arg* pikaVM_runByteCode_exReturn(PikaObj* self,
  274. VMParameters* locals,
  275. VMParameters* globals,
  276. uint8_t* bytecode,
  277. PikaVMThread* vm_thread,
  278. pika_bool is_const_bytecode,
  279. char* return_name);
  280. int pikaVMThread_init(PikaVMThread* state, uint64_t thread_id);
  281. PikaVMThread* pikaVMThread_require(void);
  282. void pikaVMThread_delete(void);
  283. int pikaVMThread_pushError(PikaVMThread* state, PikaVMError* error);
  284. PikaVMError* pikaVMThread_popError(PikaVMThread* state);
  285. int pikaVMFrame_checkErrorCode(PikaVMFrame* state);
  286. int pikaVMFrame_checkErrorStack(PikaVMFrame* vm);
  287. int pikaVMThread_clearErrorStack(PikaVMThread* state);
  288. int pikaVMThread_clearExceptionStack(PikaVMThread* vmThread);
  289. int pikaVMFrame_checkExceptionStack(PikaVMFrame* vm);
  290. int pikaVMThread_convertExceptionStack(PikaVMThread* vmThread);
  291. PikaVMError* pikaVMThread_getErrorCurrent(PikaVMThread* state);
  292. InstructUnit* instructArray_getNow(InstructArray* self);
  293. InstructUnit* instructArray_getNext(InstructArray* self);
  294. VMParameters* pikaVM_runSingleFile(PikaObj* self, char* filename);
  295. VMParameters* pikaVM_runByteCodeFile(PikaObj* self, char* filename);
  296. Arg* obj_runMethodArg(PikaObj* self, PikaObj* method_args_obj, Arg* method_arg);
  297. PikaObj* pikaVM_runFile(PikaObj* self, char* file_name);
  298. Arg* _vm_slice(PikaVMFrame* vm,
  299. PikaObj* self,
  300. Arg* end,
  301. Arg* obj,
  302. Arg* start,
  303. int step);
  304. typedef struct {
  305. VMParameters* locals;
  306. VMParameters* globals;
  307. char* name;
  308. PikaVMThread* vm_thread;
  309. pika_bool is_const_bytecode;
  310. } pikaVM_runBytecode_ex_cfg;
  311. VMParameters* pikaVM_runByteCode_ex(PikaObj* self,
  312. uint8_t* bytecode,
  313. pikaVM_runBytecode_ex_cfg* cfg);
  314. void _do_byteCodeFrame_loadByteCode(ByteCodeFrame* self,
  315. uint8_t* bytes,
  316. char* name,
  317. pika_bool is_const);
  318. Arg* _vm_get(PikaVMFrame* vm, PikaObj* self, Arg* key, Arg* obj);
  319. VM_SIGNAL_CTRL VMSignal_getCtrl(void);
  320. void pika_vm_exit(void);
  321. void pika_vm_exit_await(void);
  322. void pika_vmSignal_setCtrlClear(void);
  323. PIKA_RES __eventListener_popEvent(PikaEventListener** lisener_p,
  324. uintptr_t* id,
  325. Arg** eventData,
  326. int* signal,
  327. int* head);
  328. PIKA_RES __eventListener_pushEvent(PikaEventListener* lisener,
  329. uintptr_t eventId,
  330. Arg* eventData);
  331. PIKA_RES __eventListener_pushSignal(PikaEventListener* lisener,
  332. uintptr_t eventId,
  333. int signal);
  334. int _VMEvent_getVMCnt(void);
  335. void __VMEvent_pickupEvent(char* info);
  336. void _pikaVM_yield(void);
  337. int _VM_lock_init(void);
  338. int _VM_is_first_lock(void);
  339. PIKA_RES pika_debug_set_break(char* module_name, int pc_break);
  340. void pika_debug_set_trace(PikaObj* self);
  341. PIKA_RES pika_debug_reset_break(char* module_name, int pc_break);
  342. pika_bool pika_debug_check_break_hash(Hash module_hash, int pc_break);
  343. pika_bool pika_debug_check_break(char* module_name, int pc_break);
  344. #define _VMEvent_pickupEvent() __VMEvent_pickupEvent(__FILE__)
  345. #define PIKA_INS(__INS_NAME) _##PIKA_VM_INS_##__INS_NAME
  346. typedef struct {
  347. PikaObj* lreg[PIKA_REGIST_SIZE];
  348. } VMLocals;
  349. VMParameters* pikaVM_run_ex(PikaObj* self,
  350. char* py_lines,
  351. pikaVM_run_ex_cfg* cfg);
  352. #endif
  353. #ifdef __cplusplus
  354. }
  355. #endif