wasm.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #ifndef _WASM_H_
  6. #define _WASM_H_
  7. #include "bh_platform.h"
  8. #include "bh_hashmap.h"
  9. #include "bh_assert.h"
  10. #ifdef __cplusplus
  11. extern "C" {
  12. #endif
  13. /** Value Type */
  14. #define VALUE_TYPE_I32 0x7F
  15. #define VALUE_TYPE_I64 0X7E
  16. #define VALUE_TYPE_F32 0x7D
  17. #define VALUE_TYPE_F64 0x7C
  18. #define VALUE_TYPE_VOID 0x40
  19. /* Used by AOT */
  20. #define VALUE_TYPE_I1 0x41
  21. /* Used by loader to represent any type of i32/i64/f32/f64 */
  22. #define VALUE_TYPE_ANY 0x42
  23. /* Table Element Type */
  24. #define TABLE_ELEM_TYPE_ANY_FUNC 0x70
  25. #define DEFAULT_NUM_BYTES_PER_PAGE 65536
  26. #define INIT_EXPR_TYPE_I32_CONST 0x41
  27. #define INIT_EXPR_TYPE_I64_CONST 0x42
  28. #define INIT_EXPR_TYPE_F32_CONST 0x43
  29. #define INIT_EXPR_TYPE_F64_CONST 0x44
  30. #define INIT_EXPR_TYPE_GET_GLOBAL 0x23
  31. #define INIT_EXPR_TYPE_ERROR 0xff
  32. #define WASM_MAGIC_NUMBER 0x6d736100
  33. #define WASM_CURRENT_VERSION 1
  34. #define SECTION_TYPE_USER 0
  35. #define SECTION_TYPE_TYPE 1
  36. #define SECTION_TYPE_IMPORT 2
  37. #define SECTION_TYPE_FUNC 3
  38. #define SECTION_TYPE_TABLE 4
  39. #define SECTION_TYPE_MEMORY 5
  40. #define SECTION_TYPE_GLOBAL 6
  41. #define SECTION_TYPE_EXPORT 7
  42. #define SECTION_TYPE_START 8
  43. #define SECTION_TYPE_ELEM 9
  44. #define SECTION_TYPE_CODE 10
  45. #define SECTION_TYPE_DATA 11
  46. #if WASM_ENABLE_BULK_MEMORY != 0
  47. #define SECTION_TYPE_DATACOUNT 12
  48. #endif
  49. #define IMPORT_KIND_FUNC 0
  50. #define IMPORT_KIND_TABLE 1
  51. #define IMPORT_KIND_MEMORY 2
  52. #define IMPORT_KIND_GLOBAL 3
  53. #define EXPORT_KIND_FUNC 0
  54. #define EXPORT_KIND_TABLE 1
  55. #define EXPORT_KIND_MEMORY 2
  56. #define EXPORT_KIND_GLOBAL 3
  57. #define LABEL_TYPE_BLOCK 0
  58. #define LABEL_TYPE_LOOP 1
  59. #define LABEL_TYPE_IF 2
  60. #define LABEL_TYPE_FUNCTION 3
  61. typedef struct WASMModule WASMModule;
  62. typedef struct WASMFunction WASMFunction;
  63. typedef struct WASMGlobal WASMGlobal;
  64. typedef union WASMValue {
  65. int32 i32;
  66. uint32 u32;
  67. int64 i64;
  68. uint64 u64;
  69. float32 f32;
  70. float64 f64;
  71. uintptr_t addr;
  72. } WASMValue;
  73. typedef struct InitializerExpression {
  74. /* type of INIT_EXPR_TYPE_XXX */
  75. uint8 init_expr_type;
  76. union {
  77. int32 i32;
  78. int64 i64;
  79. float32 f32;
  80. float64 f64;
  81. uint32 global_index;
  82. } u;
  83. } InitializerExpression;
  84. typedef struct WASMType {
  85. uint16 param_count;
  86. uint16 result_count;
  87. uint16 param_cell_num;
  88. uint16 ret_cell_num;
  89. /* types of params and results */
  90. uint8 types[1];
  91. } WASMType;
  92. typedef struct WASMTable {
  93. uint8 elem_type;
  94. uint32 flags;
  95. uint32 init_size;
  96. /* specified if (flags & 1), else it is 0x10000 */
  97. uint32 max_size;
  98. } WASMTable;
  99. typedef struct WASMMemory {
  100. uint32 flags;
  101. uint32 num_bytes_per_page;
  102. uint32 init_page_count;
  103. uint32 max_page_count;
  104. } WASMMemory;
  105. typedef struct WASMTableImport {
  106. char *module_name;
  107. char *field_name;
  108. uint8 elem_type;
  109. uint32 flags;
  110. uint32 init_size;
  111. /* specified if (flags & 1), else it is 0x10000 */
  112. uint32 max_size;
  113. #if WASM_ENABLE_MULTI_MODULE != 0
  114. WASMModule *import_module;
  115. WASMTable *import_table_linked;
  116. #endif
  117. } WASMTableImport;
  118. typedef struct WASMMemoryImport {
  119. char *module_name;
  120. char *field_name;
  121. uint32 flags;
  122. uint32 num_bytes_per_page;
  123. uint32 init_page_count;
  124. uint32 max_page_count;
  125. #if WASM_ENABLE_MULTI_MODULE != 0
  126. WASMModule *import_module;
  127. WASMMemory *import_memory_linked;
  128. #endif
  129. } WASMMemoryImport;
  130. typedef struct WASMFunctionImport {
  131. char *module_name;
  132. char *field_name;
  133. /* function type */
  134. WASMType *func_type;
  135. /* native function pointer after linked */
  136. void *func_ptr_linked;
  137. /* signature from registered native symbols */
  138. const char *signature;
  139. /* attachment */
  140. void *attachment;
  141. bool call_conv_raw;
  142. #if WASM_ENABLE_MULTI_MODULE != 0
  143. WASMModule *import_module;
  144. WASMFunction *import_func_linked;
  145. #endif
  146. } WASMFunctionImport;
  147. typedef struct WASMGlobalImport {
  148. char *module_name;
  149. char *field_name;
  150. uint8 type;
  151. bool is_mutable;
  152. /* global data after linked */
  153. WASMValue global_data_linked;
  154. #if WASM_ENABLE_MULTI_MODULE != 0
  155. /* imported function pointer after linked */
  156. // TODO: remove if not necessary
  157. WASMModule *import_module;
  158. WASMGlobal *import_global_linked;
  159. #endif
  160. } WASMGlobalImport;
  161. typedef struct WASMImport {
  162. uint8 kind;
  163. union {
  164. WASMFunctionImport function;
  165. WASMTableImport table;
  166. WASMMemoryImport memory;
  167. WASMGlobalImport global;
  168. struct {
  169. char *module_name;
  170. char *field_name;
  171. } names;
  172. } u;
  173. } WASMImport;
  174. typedef struct WASMFunction {
  175. /* the type of function */
  176. WASMType *func_type;
  177. uint32 local_count;
  178. uint8 *local_types;
  179. /* cell num of parameters */
  180. uint16 param_cell_num;
  181. /* cell num of return type */
  182. uint16 ret_cell_num;
  183. /* cell num of local variables */
  184. uint16 local_cell_num;
  185. /* offset of each local, including function parameters
  186. and local variables */
  187. uint16 *local_offsets;
  188. uint32 max_stack_cell_num;
  189. uint32 max_block_num;
  190. /* Whether function has opcode memory.grow */
  191. bool has_op_memory_grow;
  192. /* Whether function has opcode call or
  193. call_indirect */
  194. bool has_op_func_call;
  195. uint32 code_size;
  196. uint8 *code;
  197. #if WASM_ENABLE_FAST_INTERP != 0
  198. uint32 code_compiled_size;
  199. uint8 *code_compiled;
  200. uint8 *consts;
  201. uint32 const_cell_num;
  202. #endif
  203. } WASMFunction;
  204. typedef struct WASMGlobal {
  205. uint8 type;
  206. bool is_mutable;
  207. InitializerExpression init_expr;
  208. } WASMGlobal;
  209. typedef struct WASMExport {
  210. char *name;
  211. uint8 kind;
  212. uint32 index;
  213. } WASMExport;
  214. typedef struct WASMTableSeg {
  215. uint32 table_index;
  216. InitializerExpression base_offset;
  217. uint32 function_count;
  218. uint32 *func_indexes;
  219. } WASMTableSeg;
  220. typedef struct WASMDataSeg {
  221. uint32 memory_index;
  222. InitializerExpression base_offset;
  223. uint32 data_length;
  224. #if WASM_ENABLE_BULK_MEMORY != 0
  225. bool is_passive;
  226. #endif
  227. uint8 *data;
  228. } WASMDataSeg;
  229. typedef struct BlockAddr {
  230. const uint8 *start_addr;
  231. uint8 *else_addr;
  232. uint8 *end_addr;
  233. } BlockAddr;
  234. #if WASM_ENABLE_LIBC_WASI != 0
  235. typedef struct WASIArguments {
  236. const char **dir_list;
  237. uint32 dir_count;
  238. const char **map_dir_list;
  239. uint32 map_dir_count;
  240. const char **env;
  241. uint32 env_count;
  242. char **argv;
  243. uint32 argc;
  244. } WASIArguments;
  245. #endif
  246. typedef struct StringNode {
  247. struct StringNode *next;
  248. char *str;
  249. } StringNode, *StringList;
  250. typedef struct WASMModule {
  251. /* Module type, for module loaded from WASM bytecode binary,
  252. this field is Wasm_Module_Bytecode;
  253. for module loaded from AOT file, this field is
  254. Wasm_Module_AoT, and this structure should be treated as
  255. AOTModule structure. */
  256. uint32 module_type;
  257. uint32 type_count;
  258. uint32 import_count;
  259. uint32 function_count;
  260. uint32 table_count;
  261. uint32 memory_count;
  262. uint32 global_count;
  263. uint32 export_count;
  264. uint32 table_seg_count;
  265. /* data seg count read from data segment section */
  266. uint32 data_seg_count;
  267. #if WASM_ENABLE_BULK_MEMORY != 0
  268. /* data count read from datacount section */
  269. uint32 data_seg_count1;
  270. #endif
  271. uint32 import_function_count;
  272. uint32 import_table_count;
  273. uint32 import_memory_count;
  274. uint32 import_global_count;
  275. WASMImport *import_functions;
  276. WASMImport *import_tables;
  277. WASMImport *import_memories;
  278. WASMImport *import_globals;
  279. WASMType **types;
  280. WASMImport *imports;
  281. WASMFunction **functions;
  282. WASMTable *tables;
  283. WASMMemory *memories;
  284. WASMGlobal *globals;
  285. WASMExport *exports;
  286. WASMTableSeg *table_segments;
  287. WASMDataSeg **data_segments;
  288. uint32 start_function;
  289. /* __data_end global exported by llvm */
  290. uint32 llvm_aux_data_end;
  291. /* auxiliary stack bottom, or __heap_base global exported by llvm */
  292. uint32 llvm_aux_stack_bottom;
  293. /* auxiliary stack size */
  294. uint32 llvm_aux_stack_size;
  295. /* the index of a global exported by llvm, which is
  296. auxiliary stack top pointer */
  297. uint32 llvm_aux_stack_global_index;
  298. /* Whether there is possible memory grow, e.g. memory.grow opcode */
  299. bool possible_memory_grow;
  300. StringList const_str_list;
  301. #if WASM_ENABLE_LIBC_WASI != 0
  302. WASIArguments wasi_args;
  303. bool is_wasi_module;
  304. #endif
  305. #if WASM_ENABLE_MULTI_MODULE != 0
  306. // TODO: mutex ? mutli-threads ?
  307. bh_list import_module_list_head;
  308. bh_list *import_module_list;
  309. #endif
  310. } WASMModule;
  311. typedef struct BlockType {
  312. /* Block type may be expressed in one of two forms:
  313. * either by the type of the single return value or
  314. * by a type index of module.
  315. */
  316. union {
  317. uint8 value_type;
  318. WASMType *type;
  319. } u;
  320. bool is_value_type;
  321. } BlockType;
  322. typedef struct WASMBranchBlock {
  323. uint8 label_type;
  324. uint32 cell_num;
  325. uint8 *target_addr;
  326. uint32 *frame_sp;
  327. } WASMBranchBlock;
  328. /* Execution environment, e.g. stack info */
  329. /**
  330. * Align an unsigned value on a alignment boundary.
  331. *
  332. * @param v the value to be aligned
  333. * @param b the alignment boundary (2, 4, 8, ...)
  334. *
  335. * @return the aligned value
  336. */
  337. inline static unsigned
  338. align_uint (unsigned v, unsigned b)
  339. {
  340. unsigned m = b - 1;
  341. return (v + m) & ~m;
  342. }
  343. /**
  344. * Return the hash value of c string.
  345. */
  346. inline static uint32
  347. wasm_string_hash(const char *str)
  348. {
  349. unsigned h = (unsigned)strlen(str);
  350. const uint8 *p = (uint8*)str;
  351. const uint8 *end = p + h;
  352. while (p != end)
  353. h = ((h << 5) - h) + *p++;
  354. return h;
  355. }
  356. /**
  357. * Whether two c strings are equal.
  358. */
  359. inline static bool
  360. wasm_string_equal(const char *s1, const char *s2)
  361. {
  362. return strcmp(s1, s2) == 0 ? true : false;
  363. }
  364. /**
  365. * Return the byte size of value type.
  366. *
  367. */
  368. inline static uint32
  369. wasm_value_type_size(uint8 value_type)
  370. {
  371. switch (value_type) {
  372. case VALUE_TYPE_I32:
  373. case VALUE_TYPE_F32:
  374. return sizeof(int32);
  375. case VALUE_TYPE_I64:
  376. case VALUE_TYPE_F64:
  377. return sizeof(int64);
  378. default:
  379. bh_assert(0);
  380. }
  381. return 0;
  382. }
  383. inline static uint16
  384. wasm_value_type_cell_num(uint8 value_type)
  385. {
  386. if (value_type == VALUE_TYPE_VOID)
  387. return 0;
  388. else if (value_type == VALUE_TYPE_I32
  389. || value_type == VALUE_TYPE_F32)
  390. return 1;
  391. else if (value_type == VALUE_TYPE_I64
  392. || value_type == VALUE_TYPE_F64)
  393. return 2;
  394. else {
  395. bh_assert(0);
  396. }
  397. return 0;
  398. }
  399. inline static uint32
  400. wasm_get_cell_num(const uint8 *types, uint32 type_count)
  401. {
  402. uint32 cell_num = 0;
  403. uint32 i;
  404. for (i = 0; i < type_count; i++)
  405. cell_num += wasm_value_type_cell_num(types[i]);
  406. return cell_num;
  407. }
  408. inline static bool
  409. wasm_type_equal(const WASMType *type1, const WASMType *type2)
  410. {
  411. return (type1->param_count == type2->param_count
  412. && type1->result_count == type2->result_count
  413. && memcmp(type1->types, type2->types,
  414. type1->param_count + type1->result_count) == 0)
  415. ? true : false;
  416. }
  417. static inline uint32
  418. block_type_get_param_types(BlockType *block_type,
  419. uint8 **p_param_types)
  420. {
  421. uint32 param_count = 0;
  422. if (!block_type->is_value_type) {
  423. WASMType *wasm_type = block_type->u.type;
  424. *p_param_types = wasm_type->types;
  425. param_count = wasm_type->param_count;
  426. }
  427. else {
  428. *p_param_types = NULL;
  429. param_count = 0;
  430. }
  431. return param_count;
  432. }
  433. static inline uint32
  434. block_type_get_result_types(BlockType *block_type,
  435. uint8 **p_result_types)
  436. {
  437. uint32 result_count = 0;
  438. if (block_type->is_value_type) {
  439. if (block_type->u.value_type != VALUE_TYPE_VOID) {
  440. *p_result_types = &block_type->u.value_type;
  441. result_count = 1;
  442. }
  443. }
  444. else {
  445. WASMType *wasm_type = block_type->u.type;
  446. *p_result_types = wasm_type->types + wasm_type->param_count;
  447. result_count = wasm_type->result_count;
  448. }
  449. return result_count;
  450. }
  451. #ifdef __cplusplus
  452. } /* end of extern "C" */
  453. #endif
  454. #endif /* end of _WASM_H_ */