wasm.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  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. /* Table Element Type */
  22. #define TABLE_ELEM_TYPE_ANY_FUNC 0x70
  23. #define DEFAULT_NUM_BYTES_PER_PAGE 65536
  24. #define INIT_EXPR_TYPE_I32_CONST 0x41
  25. #define INIT_EXPR_TYPE_I64_CONST 0x42
  26. #define INIT_EXPR_TYPE_F32_CONST 0x43
  27. #define INIT_EXPR_TYPE_F64_CONST 0x44
  28. #define INIT_EXPR_TYPE_GET_GLOBAL 0x23
  29. #define INIT_EXPR_TYPE_ERROR 0xff
  30. #define WASM_MAGIC_NUMBER 0x6d736100
  31. #define WASM_CURRENT_VERSION 1
  32. #define SECTION_TYPE_USER 0
  33. #define SECTION_TYPE_TYPE 1
  34. #define SECTION_TYPE_IMPORT 2
  35. #define SECTION_TYPE_FUNC 3
  36. #define SECTION_TYPE_TABLE 4
  37. #define SECTION_TYPE_MEMORY 5
  38. #define SECTION_TYPE_GLOBAL 6
  39. #define SECTION_TYPE_EXPORT 7
  40. #define SECTION_TYPE_START 8
  41. #define SECTION_TYPE_ELEM 9
  42. #define SECTION_TYPE_CODE 10
  43. #define SECTION_TYPE_DATA 11
  44. #define IMPORT_KIND_FUNC 0
  45. #define IMPORT_KIND_TABLE 1
  46. #define IMPORT_KIND_MEMORY 2
  47. #define IMPORT_KIND_GLOBAL 3
  48. #define EXPORT_KIND_FUNC 0
  49. #define EXPORT_KIND_TABLE 1
  50. #define EXPORT_KIND_MEMORY 2
  51. #define EXPORT_KIND_GLOBAL 3
  52. #define BLOCK_TYPE_BLOCK 0
  53. #define BLOCK_TYPE_LOOP 1
  54. #define BLOCK_TYPE_IF 2
  55. #define BLOCK_TYPE_FUNCTION 3
  56. typedef union WASMValue {
  57. int32 i32;
  58. uint32 u32;
  59. int64 i64;
  60. uint64 u64;
  61. float32 f32;
  62. float64 f64;
  63. uintptr_t addr;
  64. } WASMValue;
  65. typedef struct InitializerExpression {
  66. /* type of INIT_EXPR_TYPE_XXX */
  67. uint8 init_expr_type;
  68. union {
  69. int32 i32;
  70. int64 i64;
  71. float32 f32;
  72. float64 f64;
  73. uint32 global_index;
  74. } u;
  75. } InitializerExpression;
  76. typedef struct WASMType {
  77. uint32 param_count;
  78. /* only one result is supported currently */
  79. uint32 result_count;
  80. /* types of params and results */
  81. uint8 types[1];
  82. } WASMType;
  83. typedef struct WASMTable {
  84. uint8 elem_type;
  85. uint32 flags;
  86. uint32 init_size;
  87. /* specified if (flags & 1), else it is 0x10000 */
  88. uint32 max_size;
  89. } WASMTable;
  90. typedef struct WASMMemory {
  91. uint32 flags;
  92. uint32 num_bytes_per_page;
  93. uint32 init_page_count;
  94. uint32 max_page_count;
  95. } WASMMemory;
  96. typedef struct WASMTableImport {
  97. char *module_name;
  98. char *field_name;
  99. uint8 elem_type;
  100. uint32 flags;
  101. uint32 init_size;
  102. /* specified if (flags & 1), else it is 0x10000 */
  103. uint32 max_size;
  104. } WASMTableImport;
  105. typedef struct WASMMemoryImport {
  106. char *module_name;
  107. char *field_name;
  108. uint32 flags;
  109. uint32 num_bytes_per_page;
  110. uint32 init_page_count;
  111. uint32 max_page_count;
  112. } WASMMemoryImport;
  113. typedef struct WASMFunctionImport {
  114. char *module_name;
  115. char *field_name;
  116. /* function type */
  117. WASMType *func_type;
  118. /* function pointer after linked */
  119. void *func_ptr_linked;
  120. } WASMFunctionImport;
  121. typedef struct WASMGlobalImport {
  122. char *module_name;
  123. char *field_name;
  124. uint8 type;
  125. bool is_mutable;
  126. /* global data after linked */
  127. WASMValue global_data_linked;
  128. } WASMGlobalImport;
  129. typedef struct WASMImport {
  130. uint8 kind;
  131. union {
  132. WASMFunctionImport function;
  133. WASMTableImport table;
  134. WASMMemoryImport memory;
  135. WASMGlobalImport global;
  136. struct {
  137. char *module_name;
  138. char *field_name;
  139. } names;
  140. } u;
  141. } WASMImport;
  142. typedef struct WASMFunction {
  143. /* the type of function */
  144. WASMType *func_type;
  145. uint32 local_count;
  146. uint8 *local_types;
  147. uint32 max_stack_cell_num;
  148. uint32 max_block_num;
  149. /* Whether function has opcode memory.grow */
  150. bool has_op_memory_grow;
  151. /* Whether function has opcode call or
  152. call_indirect */
  153. bool has_op_func_call;
  154. uint32 code_size;
  155. uint8 *code;
  156. } WASMFunction;
  157. typedef struct WASMGlobal {
  158. uint8 type;
  159. bool is_mutable;
  160. InitializerExpression init_expr;
  161. } WASMGlobal;
  162. typedef struct WASMExport {
  163. char *name;
  164. uint8 kind;
  165. uint32 index;
  166. } WASMExport;
  167. typedef struct WASMTableSeg {
  168. uint32 table_index;
  169. InitializerExpression base_offset;
  170. uint32 function_count;
  171. uint32 *func_indexes;
  172. } WASMTableSeg;
  173. typedef struct WASMDataSeg {
  174. uint32 memory_index;
  175. InitializerExpression base_offset;
  176. uint32 data_length;
  177. uint8 *data;
  178. } WASMDataSeg;
  179. typedef struct BlockAddr {
  180. const uint8 *start_addr;
  181. uint8 *else_addr;
  182. uint8 *end_addr;
  183. } BlockAddr;
  184. #define BLOCK_ADDR_CACHE_SIZE 64
  185. #define BLOCK_ADDR_CONFLICT_SIZE 4
  186. #if WASM_ENABLE_LIBC_WASI != 0
  187. typedef struct WASIArguments {
  188. const char **dir_list;
  189. uint32 dir_count;
  190. const char **map_dir_list;
  191. uint32 map_dir_count;
  192. const char **env;
  193. uint32 env_count;
  194. const char **argv;
  195. uint32 argc;
  196. } WASIArguments;
  197. #endif
  198. typedef struct WASMModule {
  199. /* Module type, for module loaded from WASM bytecode binary,
  200. this field is Wasm_Module_Bytecode;
  201. for module loaded from AOT file, this field is
  202. Wasm_Module_AoT, and this structure should be treated as
  203. AOTModule structure. */
  204. uint32 module_type;
  205. uint32 type_count;
  206. uint32 import_count;
  207. uint32 function_count;
  208. uint32 table_count;
  209. uint32 memory_count;
  210. uint32 global_count;
  211. uint32 export_count;
  212. uint32 table_seg_count;
  213. uint32 data_seg_count;
  214. uint32 import_function_count;
  215. uint32 import_table_count;
  216. uint32 import_memory_count;
  217. uint32 import_global_count;
  218. WASMImport *import_functions;
  219. WASMImport *import_tables;
  220. WASMImport *import_memories;
  221. WASMImport *import_globals;
  222. WASMType **types;
  223. WASMImport *imports;
  224. WASMFunction **functions;
  225. WASMTable *tables;
  226. WASMMemory *memories;
  227. WASMGlobal *globals;
  228. WASMExport *exports;
  229. WASMTableSeg *table_segments;
  230. WASMDataSeg **data_segments;
  231. uint32 start_function;
  232. /* __data_end global exported by llvm */
  233. uint32 llvm_aux_data_end;
  234. /* auxiliary stack bottom, or __heap_base global exported by llvm */
  235. uint32 llvm_aux_stack_bottom;
  236. /* auxiliary stack size */
  237. uint32 llvm_aux_stack_size;
  238. /* the index of a global exported by llvm, which is
  239. auxiliary stack top pointer */
  240. uint32 llvm_aux_stack_global_index;
  241. /* Whether there is possible memory grow, e.g.
  242. memory.grow opcode or call enlargeMemory */
  243. bool possible_memory_grow;
  244. HashMap *const_str_set;
  245. BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
  246. #if WASM_ENABLE_LIBC_WASI != 0
  247. WASIArguments wasi_args;
  248. bool is_wasi_module;
  249. #endif
  250. } WASMModule;
  251. typedef struct WASMBranchBlock {
  252. uint8 block_type;
  253. uint8 return_type;
  254. uint8 *start_addr;
  255. uint8 *end_addr;
  256. uint32 *frame_sp;
  257. } WASMBranchBlock;
  258. /* Execution environment, e.g. stack info */
  259. /**
  260. * Align an unsigned value on a alignment boundary.
  261. *
  262. * @param v the value to be aligned
  263. * @param b the alignment boundary (2, 4, 8, ...)
  264. *
  265. * @return the aligned value
  266. */
  267. inline static unsigned
  268. align_uint (unsigned v, unsigned b)
  269. {
  270. unsigned m = b - 1;
  271. return (v + m) & ~m;
  272. }
  273. /**
  274. * Return the hash value of c string.
  275. */
  276. inline static uint32
  277. wasm_string_hash(const char *str)
  278. {
  279. unsigned h = (unsigned)strlen(str);
  280. const uint8 *p = (uint8*)str;
  281. const uint8 *end = p + h;
  282. while (p != end)
  283. h = ((h << 5) - h) + *p++;
  284. return h;
  285. }
  286. /**
  287. * Whether two c strings are equal.
  288. */
  289. inline static bool
  290. wasm_string_equal(const char *s1, const char *s2)
  291. {
  292. return strcmp(s1, s2) == 0 ? true : false;
  293. }
  294. /**
  295. * Return the byte size of value type.
  296. *
  297. */
  298. inline static uint32
  299. wasm_value_type_size(uint8 value_type)
  300. {
  301. switch (value_type) {
  302. case VALUE_TYPE_I32:
  303. case VALUE_TYPE_F32:
  304. return sizeof(int32);
  305. case VALUE_TYPE_I64:
  306. case VALUE_TYPE_F64:
  307. return sizeof(int64);
  308. default:
  309. bh_assert(0);
  310. }
  311. return 0;
  312. }
  313. inline static uint16
  314. wasm_value_type_cell_num(uint8 value_type)
  315. {
  316. switch (value_type) {
  317. case VALUE_TYPE_I32:
  318. case VALUE_TYPE_F32:
  319. return 1;
  320. case VALUE_TYPE_I64:
  321. case VALUE_TYPE_F64:
  322. return 2;
  323. default:
  324. bh_assert(0);
  325. }
  326. return 0;
  327. }
  328. inline static uint16
  329. wasm_get_cell_num(const uint8 *types, uint32 type_count)
  330. {
  331. uint32 cell_num = 0;
  332. uint32 i;
  333. for (i = 0; i < type_count; i++)
  334. cell_num += wasm_value_type_cell_num(types[i]);
  335. return (uint16)cell_num;
  336. }
  337. inline static uint16
  338. wasm_type_param_cell_num(const WASMType *type)
  339. {
  340. return wasm_get_cell_num(type->types, type->param_count);
  341. }
  342. inline static uint16
  343. wasm_type_return_cell_num(const WASMType *type)
  344. {
  345. return wasm_get_cell_num(type->types + type->param_count,
  346. type->result_count);
  347. }
  348. inline static bool
  349. wasm_type_equal(const WASMType *type1, const WASMType *type2)
  350. {
  351. return (type1->param_count == type2->param_count
  352. && type1->result_count == type2->result_count
  353. && memcmp(type1->types, type2->types,
  354. type1->param_count + type1->result_count) == 0)
  355. ? true : false;
  356. }
  357. #ifdef __cplusplus
  358. } /* end of extern "C" */
  359. #endif
  360. #endif /* end of _WASM_H_ */