aot_runtime.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_runtime.h"
  6. #include "bh_memory.h"
  7. #include "bh_log.h"
  8. #include "mem_alloc.h"
  9. static void
  10. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  11. {
  12. if (error_buf != NULL)
  13. snprintf(error_buf, error_buf_size, "%s", string);
  14. }
  15. static bool
  16. global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  17. char *error_buf, uint32 error_buf_size)
  18. {
  19. uint32 i;
  20. InitializerExpression *init_expr;
  21. uint8 *p = (uint8*)module_inst->global_data.ptr;
  22. AOTImportGlobal *import_global = module->import_globals;;
  23. AOTGlobal *global = module->globals;
  24. /* Initialize import global data */
  25. for (i = 0; i < module->import_global_count; i++, import_global++) {
  26. bh_assert(import_global->data_offset ==
  27. p - (uint8*)module_inst->global_data.ptr);
  28. memcpy(p, &import_global->global_data_linked, import_global->size);
  29. p += import_global->size;
  30. }
  31. /* Initialize defined global data */
  32. for (i = 0; i < module->global_count; i++, global++) {
  33. bh_assert(global->data_offset ==
  34. p - (uint8*)module_inst->global_data.ptr);
  35. init_expr = &global->init_expr;
  36. switch (init_expr->init_expr_type) {
  37. case INIT_EXPR_TYPE_GET_GLOBAL:
  38. bh_assert(init_expr->u.global_index < module->import_global_count);
  39. memcpy(p,
  40. &module->import_globals[init_expr->u.global_index].global_data_linked,
  41. global->size);
  42. break;
  43. default:
  44. /* TODO: check whether global type and init_expr type are matching */
  45. memcpy(p, &init_expr->u, global->size);
  46. break;
  47. }
  48. p += global->size;
  49. }
  50. bh_assert(module_inst->global_data_size == p - (uint8*)module_inst->global_data.ptr);
  51. return true;
  52. }
  53. static bool
  54. table_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  55. char *error_buf, uint32 error_buf_size)
  56. {
  57. uint32 i, global_index, global_data_offset, base_offset, length;
  58. AOTTableInitData *table_seg;
  59. if (module->table_init_data_count > 0) {
  60. for (i = 0; i < module->table_init_data_count; i++) {
  61. table_seg = module->table_init_data_list[i];
  62. bh_assert(table_seg->offset.init_expr_type ==
  63. INIT_EXPR_TYPE_I32_CONST
  64. || table_seg->offset.init_expr_type ==
  65. INIT_EXPR_TYPE_GET_GLOBAL);
  66. /* Resolve table data base offset */
  67. if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  68. global_index = table_seg->offset.u.global_index;
  69. bh_assert(global_index <
  70. module->import_global_count + module->global_count);
  71. /* TODO: && globals[table_seg->offset.u.global_index].type ==
  72. VALUE_TYPE_I32*/
  73. if (global_index < module->import_global_count)
  74. global_data_offset =
  75. module->import_globals[global_index].data_offset;
  76. else
  77. global_data_offset =
  78. module->globals[global_index - module->import_global_count]
  79. .data_offset;
  80. base_offset = *(uint32*)
  81. ((uint8*)module_inst->global_data.ptr + global_data_offset);
  82. }
  83. else
  84. base_offset = (uint32)table_seg->offset.u.i32;
  85. /* Copy table data */
  86. length = table_seg->func_index_count;
  87. if (base_offset < module_inst->table_size) {
  88. memcpy((uint32*)module_inst->table_data.ptr + base_offset,
  89. table_seg->func_indexes, length * sizeof(uint32));
  90. }
  91. }
  92. }
  93. return true;
  94. }
  95. static bool
  96. memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  97. char *error_buf, uint32 error_buf_size)
  98. {
  99. uint32 i, global_index, global_data_offset, base_offset, length;
  100. AOTMemInitData *data_seg;
  101. uint64 total_size = (uint64)module->num_bytes_per_page * module->mem_init_page_count;
  102. /* Allocate memory */
  103. if (total_size >= UINT32_MAX
  104. || !(module_inst->memory_data.ptr = wasm_malloc((uint32)total_size))) {
  105. set_error_buf(error_buf, error_buf_size,
  106. "AOT module instantiate failed: allocate memory failed.");
  107. return false;
  108. }
  109. memset(module_inst->memory_data.ptr, 0, (uint32)total_size);
  110. /* Init memory info */
  111. module_inst->memory_data_end.ptr = (uint8*)module_inst->memory_data.ptr
  112. + total_size;
  113. module_inst->memory_data_size = (uint32)total_size;
  114. module_inst->mem_cur_page_count = module->mem_init_page_count;
  115. module_inst->mem_max_page_count = module->mem_max_page_count;
  116. if (module->mem_init_page_count > 0) {
  117. for (i = 0; i < module->mem_init_data_count; i++) {
  118. data_seg = module->mem_init_data_list[i];
  119. bh_assert(data_seg->offset.init_expr_type ==
  120. INIT_EXPR_TYPE_I32_CONST
  121. || data_seg->offset.init_expr_type ==
  122. INIT_EXPR_TYPE_GET_GLOBAL);
  123. /* Resolve memory data base offset */
  124. if (data_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  125. global_index = data_seg->offset.u.global_index;
  126. bh_assert(global_index <
  127. module->import_global_count + module->global_count);
  128. /* TODO: && globals[data_seg->offset.u.global_index].type ==
  129. VALUE_TYPE_I32*/
  130. if (global_index < module->import_global_count)
  131. global_data_offset =
  132. module->import_globals[global_index].data_offset;
  133. else
  134. global_data_offset =
  135. module->globals[global_index - module->import_global_count]
  136. .data_offset;
  137. base_offset = *(uint32*)
  138. ((uint8*)module_inst->global_data.ptr + global_data_offset);
  139. }
  140. else
  141. base_offset = (uint32)data_seg->offset.u.i32;
  142. length = data_seg->byte_count;
  143. /* Check memory data */
  144. if (length > 0
  145. && (base_offset >= module_inst->memory_data_size
  146. || base_offset + length > module_inst->memory_data_size)) {
  147. wasm_free(module_inst->memory_data.ptr);
  148. module_inst->memory_data.ptr = NULL;
  149. set_error_buf(error_buf, error_buf_size,
  150. "AOT module instantiate failed: data segment out of range.");
  151. return false;
  152. }
  153. /* Copy memory data */
  154. memcpy((uint8*)module_inst->memory_data.ptr + base_offset,
  155. data_seg->bytes, length);
  156. }
  157. }
  158. return true;
  159. }
  160. static bool
  161. init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
  162. char *error_buf, uint32 error_buf_size)
  163. {
  164. uint32 i;
  165. void **func_ptrs;
  166. uint64 total_size =
  167. ((uint64)module->import_func_count + module->func_count) * sizeof(void*);
  168. /* Allocate memory */
  169. if (total_size >= UINT32_MAX
  170. || !(module_inst->func_ptrs.ptr = wasm_malloc((uint32)total_size))) {
  171. set_error_buf(error_buf, error_buf_size,
  172. "AOT module instantiate failed: allocate memory failed.");
  173. return false;
  174. }
  175. memset(module_inst->func_ptrs.ptr, 0, (uint32)total_size);
  176. /* Set import function pointers */
  177. func_ptrs = (void**)module_inst->func_ptrs.ptr;
  178. for (i = 0; i < module->import_func_count; i++, func_ptrs++)
  179. *func_ptrs = (void*)module->import_funcs[i].func_ptr_linked;
  180. /* Set defined function pointers */
  181. memcpy(func_ptrs, module->func_ptrs, module->func_count * sizeof(void*));
  182. return true;
  183. }
  184. static bool
  185. init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
  186. char *error_buf, uint32 error_buf_size)
  187. {
  188. uint32 i;
  189. uint32 *func_type_index;
  190. uint64 total_size =
  191. ((uint64)module->import_func_count + module->func_count) * sizeof(uint32);
  192. /* Allocate memory */
  193. if (total_size >= UINT32_MAX
  194. || !(module_inst->func_type_indexes.ptr = wasm_malloc((uint32)total_size))) {
  195. set_error_buf(error_buf, error_buf_size,
  196. "AOT module instantiate failed: allocate memory failed.");
  197. return false;
  198. }
  199. memset(module_inst->func_type_indexes.ptr, 0, (uint32)total_size);
  200. /* Set import function type indexes */
  201. func_type_index = (uint32*)module_inst->func_type_indexes.ptr;
  202. for (i = 0; i < module->import_func_count; i++, func_type_index++)
  203. *func_type_index = module->import_funcs[i].func_type_index;
  204. memcpy(func_type_index, module->func_type_indexes,
  205. module->func_count * sizeof(uint32));
  206. return true;
  207. }
  208. static bool
  209. execute_post_inst_function(AOTModuleInstance *module_inst)
  210. {
  211. AOTFunctionInstance *post_inst_func =
  212. aot_lookup_function(module_inst, "__post_instantiate", "()");
  213. if (!post_inst_func)
  214. /* Not found */
  215. return true;
  216. return aot_create_exec_env_and_call_function(module_inst, post_inst_func, 0, NULL);
  217. }
  218. static bool
  219. execute_start_function(AOTModuleInstance *module_inst)
  220. {
  221. AOTModule *module = (AOTModule*)module_inst->aot_module.ptr;
  222. WASMExecEnv *exec_env;
  223. typedef void (*F)(WASMExecEnv*);
  224. union { F f; void *v; } u;
  225. if (!module->start_function)
  226. return true;
  227. if (!(exec_env = wasm_exec_env_create((WASMModuleInstanceCommon*)module_inst,
  228. module_inst->default_wasm_stack_size))) {
  229. aot_set_exception(module_inst, "allocate memory failed.");
  230. return false;
  231. }
  232. u.v = module->start_function;
  233. u.f(exec_env);
  234. wasm_exec_env_destroy(exec_env);
  235. return !aot_get_exception(module_inst);
  236. }
  237. AOTModuleInstance*
  238. aot_instantiate(AOTModule *module,
  239. uint32 stack_size, uint32 heap_size,
  240. char *error_buf, uint32 error_buf_size)
  241. {
  242. AOTModuleInstance *module_inst;
  243. uint32 module_inst_struct_size =
  244. offsetof(AOTModuleInstance, global_table_heap_data.bytes);
  245. uint64 table_data_size = (uint64)module->table_size * sizeof(uint32);
  246. uint64 total_size = (uint64)module_inst_struct_size
  247. + module->global_data_size
  248. + table_data_size + heap_size;
  249. void *heap_handle;
  250. uint8 *p;
  251. /* Check heap size */
  252. heap_size = align_uint(heap_size, 8);
  253. if (heap_size == 0)
  254. heap_size = APP_HEAP_SIZE_DEFAULT;
  255. if (heap_size < APP_HEAP_SIZE_MIN)
  256. heap_size = APP_HEAP_SIZE_MIN;
  257. if (heap_size > APP_HEAP_SIZE_MAX)
  258. heap_size = APP_HEAP_SIZE_MAX;
  259. /* Allocate module instance, global data, table data and heap data */
  260. if (total_size >= UINT32_MAX
  261. || !(module_inst = wasm_malloc((uint32)total_size))) {
  262. set_error_buf(error_buf, error_buf_size,
  263. "AOT module instantiate failed: allocate memory failed.");
  264. return NULL;
  265. }
  266. memset(module_inst, 0, total_size);
  267. module_inst->module_type = Wasm_Module_AoT;
  268. module_inst->aot_module.ptr = module;
  269. /* Initialize global info */
  270. p = (uint8*)module_inst + module_inst_struct_size;
  271. module_inst->global_data.ptr = p;
  272. module_inst->global_data_size = module->global_data_size;
  273. if (!global_instantiate(module_inst, module, error_buf, error_buf_size))
  274. goto fail;
  275. /* Initialize table info */
  276. p += module->global_data_size;
  277. module_inst->table_data.ptr = p;
  278. module_inst->table_size = module->table_size;
  279. /* Set all elements to -1 to mark them as uninitialized elements */
  280. memset(module_inst->table_data.ptr, -1, (uint32)table_data_size);
  281. if (!table_instantiate(module_inst, module, error_buf, error_buf_size))
  282. goto fail;
  283. /* Initialize heap info */
  284. p += (uint32)table_data_size;
  285. module_inst->heap_data.ptr = p;
  286. p += heap_size;
  287. module_inst->heap_data_end.ptr = p;
  288. module_inst->heap_data_size = heap_size;
  289. #if WASM_ENABLE_MEMORY_GROW != 0
  290. module_inst->heap_base_offset = DEFAULT_APP_HEAP_BASE_OFFSET;
  291. #else
  292. module_inst->heap_base_offset = module_inst->memory_data_size;
  293. #endif
  294. if (!(heap_handle = mem_allocator_create(module_inst->heap_data.ptr,
  295. heap_size))) {
  296. set_error_buf(error_buf, error_buf_size,
  297. "AOT module instantiate failed: init app heap failed.");
  298. goto fail;
  299. }
  300. module_inst->heap_handle.ptr = heap_handle;
  301. /* Initialize memory space */
  302. if (!memory_instantiate(module_inst, module, error_buf, error_buf_size))
  303. goto fail;
  304. /* Initialize function pointers */
  305. if (!init_func_ptrs(module_inst, module, error_buf, error_buf_size))
  306. goto fail;
  307. /* Initialize function type indexes */
  308. if (!init_func_type_indexes(module_inst, module, error_buf, error_buf_size))
  309. goto fail;
  310. #if WASM_ENABLE_LIBC_WASI != 0
  311. if (!wasm_runtime_init_wasi((WASMModuleInstanceCommon*)module_inst,
  312. module->wasi_args.dir_list,
  313. module->wasi_args.dir_count,
  314. module->wasi_args.map_dir_list,
  315. module->wasi_args.map_dir_count,
  316. module->wasi_args.env,
  317. module->wasi_args.env_count,
  318. module->wasi_args.argv,
  319. module->wasi_args.argc,
  320. error_buf, error_buf_size))
  321. goto fail;
  322. #endif
  323. /* Initialize the thread related data */
  324. if (stack_size == 0)
  325. stack_size = DEFAULT_WASM_STACK_SIZE;
  326. module_inst->default_wasm_stack_size = stack_size;
  327. /* Execute __post_instantiate function and start function*/
  328. if (!execute_post_inst_function(module_inst)
  329. || !execute_start_function(module_inst)) {
  330. set_error_buf(error_buf, error_buf_size,
  331. module_inst->cur_exception);
  332. goto fail;
  333. }
  334. return module_inst;
  335. fail:
  336. aot_deinstantiate(module_inst);
  337. return NULL;
  338. }
  339. void
  340. aot_deinstantiate(AOTModuleInstance *module_inst)
  341. {
  342. #if WASM_ENABLE_LIBC_WASI != 0
  343. /* Destroy wasi resource before freeing app heap, since some fields of
  344. wasi contex are allocated from app heap, and if app heap is freed,
  345. these fields will be set to NULL, we cannot free their internal data
  346. which may allocated from global heap. */
  347. wasm_runtime_destroy_wasi((WASMModuleInstanceCommon*)module_inst);
  348. #endif
  349. if (module_inst->memory_data.ptr)
  350. wasm_free(module_inst->memory_data.ptr);
  351. if (module_inst->heap_handle.ptr)
  352. mem_allocator_destroy(module_inst->heap_handle.ptr);
  353. if (module_inst->func_ptrs.ptr)
  354. wasm_free(module_inst->func_ptrs.ptr);
  355. if (module_inst->func_type_indexes.ptr)
  356. wasm_free(module_inst->func_type_indexes.ptr);
  357. wasm_free(module_inst);
  358. }
  359. static bool
  360. check_type(uint8 type, const char *p)
  361. {
  362. const char *str = "i32";
  363. if (strlen(p) < 3)
  364. return false;
  365. switch (type) {
  366. case VALUE_TYPE_I32:
  367. str = "i32";
  368. break;
  369. case VALUE_TYPE_I64:
  370. str = "i64";
  371. break;
  372. case VALUE_TYPE_F32:
  373. str = "f32";
  374. break;
  375. case VALUE_TYPE_F64:
  376. str = "f64";
  377. break;
  378. }
  379. if (strncmp(p, str, 3))
  380. return false;
  381. return true;
  382. }
  383. static bool
  384. check_function_type(const WASMType *type,
  385. const char *signature)
  386. {
  387. uint32 i;
  388. const char *p = signature;
  389. if (!p || *p++ != '(')
  390. return false;
  391. for (i = 0; i < type->param_count; i++) {
  392. if (!check_type(type->types[i], p))
  393. return false;
  394. p += 3;
  395. }
  396. if (*p++ != ')')
  397. return false;
  398. if (type->result_count) {
  399. if (!check_type(type->types[type->param_count], p))
  400. return false;
  401. p += 3;
  402. }
  403. if (*p != '\0')
  404. return false;
  405. return true;
  406. }
  407. AOTFunctionInstance*
  408. aot_lookup_function(const AOTModuleInstance *module_inst,
  409. const char *name, const char *signature)
  410. {
  411. uint32 i;
  412. AOTModule *module = (AOTModule*)module_inst->aot_module.ptr;
  413. for (i = 0; i < module->export_func_count; i++) {
  414. if (!strcmp(module->export_funcs[i].func_name, name)
  415. && check_function_type(module->export_funcs[i].func_type,
  416. signature))
  417. return &module->export_funcs[i];
  418. }
  419. return NULL;
  420. }
  421. #define PUT_I64_TO_ADDR(addr, value) do { \
  422. union { int64 val; uint32 parts[2]; } u; \
  423. u.val = (value); \
  424. (addr)[0] = u.parts[0]; \
  425. (addr)[1] = u.parts[1]; \
  426. } while (0)
  427. #define PUT_F64_TO_ADDR(addr, value) do { \
  428. union { float64 val; uint32 parts[2]; } u; \
  429. u.val = (value); \
  430. (addr)[0] = u.parts[0]; \
  431. (addr)[1] = u.parts[1]; \
  432. } while (0)
  433. bool
  434. aot_call_function(WASMExecEnv *exec_env,
  435. AOTFunctionInstance *function,
  436. unsigned argc, uint32 argv[])
  437. {
  438. AOTModuleInstance *module_inst = (AOTModuleInstance*)exec_env->module_inst;
  439. AOTFuncType *func_type = function->func_type;
  440. bool ret = wasm_runtime_invoke_native(function->func_ptr, func_type,
  441. exec_env, argv, argc, argv);
  442. return ret && !aot_get_exception(module_inst) ? true : false;
  443. }
  444. bool
  445. aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
  446. AOTFunctionInstance *func,
  447. unsigned argc, uint32 argv[])
  448. {
  449. WASMExecEnv *exec_env;
  450. bool ret;
  451. if (!(exec_env = wasm_exec_env_create((WASMModuleInstanceCommon*)module_inst,
  452. module_inst->default_wasm_stack_size))) {
  453. aot_set_exception(module_inst, "allocate memory failed.");
  454. return false;
  455. }
  456. ret = aot_call_function(exec_env, func, argc, argv);
  457. wasm_exec_env_destroy(exec_env);
  458. return ret;
  459. }
  460. void
  461. aot_set_exception(AOTModuleInstance *module_inst,
  462. const char *exception)
  463. {
  464. if (exception)
  465. snprintf(module_inst->cur_exception,
  466. sizeof(module_inst->cur_exception),
  467. "Exception: %s", exception);
  468. else
  469. module_inst->cur_exception[0] = '\0';
  470. }
  471. void
  472. aot_set_exception_with_id(AOTModuleInstance *module_inst,
  473. uint32 id)
  474. {
  475. switch (id) {
  476. case EXCE_UNREACHABLE:
  477. aot_set_exception(module_inst, "unreachable");
  478. break;
  479. case EXCE_OUT_OF_MEMORY:
  480. aot_set_exception(module_inst, "allocate memory failed");
  481. break;
  482. case EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS:
  483. aot_set_exception(module_inst, "out of bounds memory access");
  484. break;
  485. case EXCE_INTEGER_OVERFLOW:
  486. aot_set_exception(module_inst, "integer overflow");
  487. break;
  488. case EXCE_INTEGER_DIVIDE_BY_ZERO:
  489. aot_set_exception(module_inst, "integer divide by zero");
  490. break;
  491. case EXCE_INVALID_CONVERSION_TO_INTEGER:
  492. aot_set_exception(module_inst, "invalid conversion to integer");
  493. break;
  494. case EXCE_INVALID_FUNCTION_TYPE_INDEX:
  495. aot_set_exception(module_inst, "indirect call type mismatch");
  496. break;
  497. case EXCE_INVALID_FUNCTION_INDEX:
  498. aot_set_exception(module_inst, "invalid function index");
  499. break;
  500. case EXCE_UNDEFINED_ELEMENT:
  501. aot_set_exception(module_inst, "undefined element");
  502. break;
  503. case EXCE_UNINITIALIZED_ELEMENT:
  504. aot_set_exception(module_inst, "uninitialized element");
  505. break;
  506. case EXCE_CALL_UNLINKED_IMPORT_FUNC:
  507. aot_set_exception(module_inst, "fail to call unlinked import function");
  508. break;
  509. default:
  510. break;
  511. }
  512. }
  513. const char*
  514. aot_get_exception(AOTModuleInstance *module_inst)
  515. {
  516. if (module_inst->cur_exception[0] == '\0')
  517. return NULL;
  518. else
  519. return module_inst->cur_exception;
  520. }
  521. void
  522. aot_clear_exception(AOTModuleInstance *module_inst)
  523. {
  524. module_inst->cur_exception[0] = '\0';
  525. }
  526. int32
  527. aot_module_malloc(AOTModuleInstance *module_inst, uint32 size)
  528. {
  529. uint8 *addr =
  530. mem_allocator_malloc(module_inst->heap_handle.ptr, size);
  531. if (!addr) {
  532. aot_set_exception(module_inst, "out of memory");
  533. return 0;
  534. }
  535. return (int32)(module_inst->heap_base_offset
  536. + (addr - (uint8*)module_inst->heap_data.ptr));
  537. }
  538. void
  539. aot_module_free(AOTModuleInstance *module_inst, int32 ptr)
  540. {
  541. if (ptr) {
  542. uint8 *addr = (uint8*)module_inst->heap_data.ptr
  543. + (ptr - module_inst->heap_base_offset);
  544. if ((uint8*)module_inst->heap_data.ptr < addr
  545. && addr < (uint8*)module_inst->heap_data_end.ptr)
  546. mem_allocator_free(module_inst->heap_handle.ptr, addr);
  547. }
  548. }
  549. int32
  550. aot_module_dup_data(AOTModuleInstance *module_inst,
  551. const char *src, uint32 size)
  552. {
  553. int32 buffer_offset = aot_module_malloc(module_inst, size);
  554. if (buffer_offset != 0) {
  555. char *buffer;
  556. buffer = aot_addr_app_to_native(module_inst, buffer_offset);
  557. memcpy(buffer, src, size);
  558. }
  559. return buffer_offset;
  560. }
  561. bool
  562. aot_validate_app_addr(AOTModuleInstance *module_inst,
  563. int32 app_offset, uint32 size)
  564. {
  565. uint8 *addr;
  566. /* integer overflow check */
  567. if(app_offset + (int32)size < app_offset) {
  568. goto fail;
  569. }
  570. if (0 <= app_offset
  571. && app_offset < (int32)module_inst->memory_data_size) {
  572. addr = (uint8*)module_inst->memory_data.ptr + app_offset;
  573. if (!((uint8*)module_inst->memory_data.ptr <= addr
  574. && addr + size <= (uint8*)module_inst->memory_data_end.ptr))
  575. goto fail;
  576. return true;
  577. }
  578. /* Currently heap_size is no more than 1G, and heap_base_offset is 1G,
  579. heap_base_offset + heap_data_size will not be larger than INT32_MAX */
  580. else if (module_inst->heap_base_offset < app_offset
  581. && app_offset < module_inst->heap_base_offset
  582. + (int32)module_inst->heap_data_size) {
  583. addr = (uint8*)module_inst->heap_data.ptr
  584. + (app_offset - module_inst->heap_base_offset);
  585. if (!((uint8*)module_inst->heap_data.ptr <= addr
  586. && addr + size <= (uint8*)module_inst->heap_data_end.ptr))
  587. goto fail;
  588. return true;
  589. }
  590. fail:
  591. aot_set_exception(module_inst, "out of bounds memory access");
  592. return false;
  593. }
  594. bool
  595. aot_validate_native_addr(AOTModuleInstance *module_inst,
  596. void *native_ptr, uint32 size)
  597. {
  598. uint8 *addr = native_ptr;
  599. /* integer overflow check */
  600. if (addr + size < addr) {
  601. goto fail;
  602. }
  603. if (((uint8*)module_inst->memory_data.ptr <= addr
  604. && addr + size <= (uint8*)module_inst->memory_data_end.ptr)
  605. || ((uint8*)module_inst->heap_data.ptr <= addr
  606. && addr + size <= (uint8*)module_inst->heap_data_end.ptr)
  607. )
  608. return true;
  609. fail:
  610. aot_set_exception(module_inst, "out of bounds memory access");
  611. return false;
  612. }
  613. void *
  614. aot_addr_app_to_native(AOTModuleInstance *module_inst, int32 app_offset)
  615. {
  616. if (0 <= app_offset && app_offset < module_inst->heap_base_offset)
  617. return (uint8*)module_inst->memory_data.ptr + app_offset;
  618. if (module_inst->heap_base_offset < app_offset
  619. && app_offset < module_inst->heap_base_offset
  620. + (int32)module_inst->heap_data_size)
  621. return (uint8*)module_inst->heap_data.ptr
  622. + (app_offset - module_inst->heap_base_offset);
  623. return NULL;
  624. }
  625. int32
  626. aot_addr_native_to_app(AOTModuleInstance *module_inst, void *native_ptr)
  627. {
  628. if ((uint8*)module_inst->memory_data.ptr <= (uint8*)native_ptr
  629. && (uint8*)native_ptr < (uint8*)module_inst->memory_data_end.ptr)
  630. return (int32)((uint8*)native_ptr - (uint8*)module_inst->memory_data.ptr);
  631. if ((uint8*)module_inst->heap_data.ptr <= (uint8*)native_ptr
  632. && (uint8*)native_ptr < (uint8*)module_inst->heap_data_end.ptr)
  633. return (int32)(module_inst->heap_base_offset
  634. + ((uint8*)native_ptr - (uint8*)module_inst->heap_data.ptr));
  635. return 0;
  636. }
  637. bool
  638. aot_get_app_addr_range(AOTModuleInstance *module_inst,
  639. int32 app_offset,
  640. int32 *p_app_start_offset,
  641. int32 *p_app_end_offset)
  642. {
  643. int32 app_start_offset, app_end_offset;
  644. if (0 <= app_offset && app_offset < (int32)module_inst->memory_data_size) {
  645. app_start_offset = 0;
  646. app_end_offset = (int32)module_inst->memory_data_size;
  647. }
  648. else if (module_inst->heap_base_offset < app_offset
  649. && app_offset < module_inst->heap_base_offset
  650. + (int32)module_inst->heap_data_size) {
  651. app_start_offset = module_inst->heap_base_offset;
  652. app_end_offset = module_inst->heap_base_offset
  653. + (int32)module_inst->heap_data_size;
  654. }
  655. else
  656. return false;
  657. if (p_app_start_offset)
  658. *p_app_start_offset = app_start_offset;
  659. if (p_app_end_offset)
  660. *p_app_end_offset = app_end_offset;
  661. return true;
  662. }
  663. bool
  664. aot_get_native_addr_range(AOTModuleInstance *module_inst,
  665. uint8 *native_ptr,
  666. uint8 **p_native_start_addr,
  667. uint8 **p_native_end_addr)
  668. {
  669. uint8 *native_start_addr, *native_end_addr;
  670. if ((uint8*)module_inst->memory_data.ptr <= (uint8*)native_ptr
  671. && (uint8*)native_ptr < (uint8*)module_inst->memory_data_end.ptr) {
  672. native_start_addr = (uint8*)module_inst->memory_data.ptr;
  673. native_end_addr = (uint8*)module_inst->memory_data_end.ptr;
  674. }
  675. else if ((uint8*)module_inst->heap_data.ptr <= (uint8*)native_ptr
  676. && (uint8*)native_ptr < (uint8*)module_inst->heap_data_end.ptr) {
  677. native_start_addr = (uint8*)module_inst->heap_data.ptr;
  678. native_end_addr = (uint8*)module_inst->heap_data_end.ptr;
  679. }
  680. else
  681. return false;
  682. if (p_native_start_addr)
  683. *p_native_start_addr = native_start_addr;
  684. if (p_native_end_addr)
  685. *p_native_end_addr = native_end_addr;
  686. return true;
  687. }
  688. bool
  689. aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
  690. {
  691. uint8 *mem_data_old = module_inst->memory_data.ptr, *mem_data_new;
  692. uint32 num_bytes_per_page =
  693. ((AOTModule*)module_inst->aot_module.ptr)->num_bytes_per_page;
  694. uint32 cur_page_count = module_inst->mem_cur_page_count;
  695. uint32 max_page_count = module_inst->mem_max_page_count;
  696. uint32 total_page_count = cur_page_count + inc_page_count;
  697. uint32 old_size = num_bytes_per_page * cur_page_count;
  698. uint64 total_size = (uint64)num_bytes_per_page * total_page_count;
  699. if (inc_page_count <= 0)
  700. /* No need to enlarge memory */
  701. return true;
  702. if (total_page_count < cur_page_count /* integer overflow */
  703. || total_page_count > max_page_count) {
  704. aot_set_exception(module_inst, "fail to enlarge memory.");
  705. return false;
  706. }
  707. if (total_size >= UINT32_MAX
  708. || !(mem_data_new = wasm_malloc((uint32)total_size))) {
  709. aot_set_exception(module_inst, "fail to enlarge memory.");
  710. return false;
  711. }
  712. memcpy(mem_data_new, mem_data_old, old_size);
  713. memset(mem_data_new + old_size, 0, (uint32)total_size - old_size);
  714. module_inst->mem_cur_page_count = total_page_count;
  715. module_inst->memory_data_size = (uint32)total_size;
  716. module_inst->memory_data.ptr = mem_data_new;
  717. module_inst->memory_data_end.ptr = mem_data_new + (uint32)total_size;
  718. wasm_free(mem_data_old);
  719. return true;
  720. }
  721. bool
  722. aot_is_wasm_type_equal(AOTModuleInstance *module_inst,
  723. uint32 type1_idx, uint32 type2_idx)
  724. {
  725. WASMType *type1, *type2;
  726. AOTModule *module = (AOTModule*)module_inst->aot_module.ptr;
  727. if (type1_idx >= module->func_type_count
  728. || type2_idx >= module->func_type_count) {
  729. aot_set_exception(module_inst, "type index out of bounds");
  730. return false;
  731. }
  732. if (type1_idx == type2_idx)
  733. return true;
  734. type1 = module->func_types[type1_idx];
  735. type2 = module->func_types[type2_idx];
  736. return wasm_type_equal(type1, type2);
  737. }