aot_runtime.c 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782
  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_log.h"
  7. #include "mem_alloc.h"
  8. #if WASM_ENABLE_SHARED_MEMORY != 0
  9. #include "../common/wasm_shared_memory.h"
  10. #endif
  11. static void
  12. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  13. {
  14. if (error_buf != NULL)
  15. snprintf(error_buf, error_buf_size, "%s", string);
  16. }
  17. static void *
  18. runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
  19. {
  20. void *mem;
  21. if (size >= UINT32_MAX
  22. || !(mem = wasm_runtime_malloc((uint32)size))) {
  23. set_error_buf(error_buf, error_buf_size,
  24. "AOT module instantiate failed: "
  25. "allocate memory failed.");
  26. return NULL;
  27. }
  28. memset(mem, 0, (uint32)size);
  29. return mem;
  30. }
  31. static bool
  32. global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  33. char *error_buf, uint32 error_buf_size)
  34. {
  35. uint32 i;
  36. InitializerExpression *init_expr;
  37. uint8 *p = (uint8*)module_inst->global_data.ptr;
  38. AOTImportGlobal *import_global = module->import_globals;
  39. AOTGlobal *global = module->globals;
  40. /* Initialize import global data */
  41. for (i = 0; i < module->import_global_count; i++, import_global++) {
  42. bh_assert(import_global->data_offset ==
  43. (uint32)(p - (uint8*)module_inst->global_data.ptr));
  44. memcpy(p, &import_global->global_data_linked, import_global->size);
  45. p += import_global->size;
  46. }
  47. /* Initialize defined global data */
  48. for (i = 0; i < module->global_count; i++, global++) {
  49. bh_assert(global->data_offset ==
  50. (uint32)(p - (uint8*)module_inst->global_data.ptr));
  51. init_expr = &global->init_expr;
  52. switch (init_expr->init_expr_type) {
  53. case INIT_EXPR_TYPE_GET_GLOBAL:
  54. if (init_expr->u.global_index >= module->import_global_count + i) {
  55. set_error_buf(error_buf, error_buf_size,
  56. "Instantiate global failed: unknown global.");
  57. return false;
  58. }
  59. memcpy(p,
  60. &module->import_globals[init_expr->u.global_index].global_data_linked,
  61. global->size);
  62. break;
  63. default:
  64. /* TODO: check whether global type and init_expr type are matching */
  65. memcpy(p, &init_expr->u, global->size);
  66. break;
  67. }
  68. p += global->size;
  69. }
  70. bh_assert(module_inst->global_data_size ==
  71. (uint32)(p - (uint8*)module_inst->global_data.ptr));
  72. return true;
  73. }
  74. static bool
  75. table_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  76. char *error_buf, uint32 error_buf_size)
  77. {
  78. uint32 i, global_index, global_data_offset, base_offset, length;
  79. AOTTableInitData *table_seg;
  80. for (i = 0; i < module->table_init_data_count; i++) {
  81. table_seg = module->table_init_data_list[i];
  82. bh_assert(table_seg->offset.init_expr_type ==
  83. INIT_EXPR_TYPE_I32_CONST
  84. || table_seg->offset.init_expr_type ==
  85. INIT_EXPR_TYPE_GET_GLOBAL);
  86. /* Resolve table data base offset */
  87. if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  88. global_index = table_seg->offset.u.global_index;
  89. bh_assert(global_index <
  90. module->import_global_count + module->global_count);
  91. /* TODO: && globals[table_seg->offset.u.global_index].type ==
  92. VALUE_TYPE_I32*/
  93. if (global_index < module->import_global_count)
  94. global_data_offset =
  95. module->import_globals[global_index].data_offset;
  96. else
  97. global_data_offset =
  98. module->globals[global_index - module->import_global_count]
  99. .data_offset;
  100. base_offset = *(uint32*)
  101. ((uint8*)module_inst->global_data.ptr + global_data_offset);
  102. }
  103. else
  104. base_offset = (uint32)table_seg->offset.u.i32;
  105. /* Copy table data */
  106. bh_assert(module_inst->table_data.ptr);
  107. /* base_offset only since length might negative */
  108. if (base_offset > module_inst->table_size) {
  109. LOG_DEBUG("base_offset(%d) > table_size(%d)", base_offset,
  110. module_inst->table_size);
  111. set_error_buf(error_buf, error_buf_size,
  112. "elements segment does not fit");
  113. return false;
  114. }
  115. /* base_offset + length(could be zero) */
  116. length = table_seg->func_index_count;
  117. if (base_offset + length > module_inst->table_size) {
  118. LOG_DEBUG("base_offset(%d) + length(%d) > table_size(%d)",
  119. base_offset, length, module_inst->table_size);
  120. set_error_buf(error_buf, error_buf_size,
  121. "elements segment does not fit");
  122. return false;
  123. }
  124. /**
  125. * Check function index in the current module inst for now.
  126. * will check the linked table inst owner in future
  127. */
  128. memcpy((uint32 *)module_inst->table_data.ptr + base_offset,
  129. table_seg->func_indexes,
  130. length * sizeof(uint32));
  131. }
  132. return true;
  133. }
  134. static void
  135. memories_deinstantiate(AOTModuleInstance *module_inst)
  136. {
  137. uint32 i;
  138. AOTMemoryInstance *memory_inst;
  139. for (i = 0; i < module_inst->memory_count; i++) {
  140. memory_inst = ((AOTMemoryInstance **)module_inst->memories.ptr)[i];
  141. if (memory_inst) {
  142. #if WASM_ENABLE_SHARED_MEMORY != 0
  143. if (memory_inst->is_shared) {
  144. int32 ref_count =
  145. shared_memory_dec_reference(
  146. (WASMModuleCommon *)module_inst->aot_module.ptr);
  147. bh_assert(ref_count >= 0);
  148. /* if the reference count is not zero,
  149. don't free the memory */
  150. if (ref_count > 0)
  151. continue;
  152. }
  153. #endif
  154. if (memory_inst->heap_handle.ptr)
  155. mem_allocator_destroy(memory_inst->heap_handle.ptr);
  156. if (memory_inst->heap_data.ptr) {
  157. #ifndef OS_ENABLE_HW_BOUND_CHECK
  158. wasm_runtime_free(memory_inst->heap_data.ptr);
  159. #else
  160. os_munmap((uint8*)memory_inst->memory_data.ptr - 2 * (uint64)BH_GB,
  161. 8 * (uint64)BH_GB);
  162. #endif
  163. }
  164. }
  165. }
  166. wasm_runtime_free(module_inst->memories.ptr);
  167. }
  168. static AOTMemoryInstance*
  169. memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  170. AOTMemoryInstance *memory_inst, AOTMemory *memory,
  171. uint32 heap_size, char *error_buf, uint32 error_buf_size)
  172. {
  173. void *heap_handle;
  174. uint64 memory_data_size = (uint64)memory->num_bytes_per_page
  175. * memory->mem_init_page_count;
  176. uint64 total_size = heap_size + memory_data_size;
  177. uint8 *p;
  178. #if WASM_ENABLE_SHARED_MEMORY != 0
  179. AOTMemoryInstance *shared_memory_instance;
  180. bool is_shared_memory = memory->memory_flags & 0x02 ? true : false;
  181. uint64 max_memory_data_size = (uint64)memory->num_bytes_per_page
  182. * memory->mem_max_page_count;
  183. /* Shared memory */
  184. if (is_shared_memory) {
  185. WASMSharedMemNode *node =
  186. wasm_module_get_shared_memory((WASMModuleCommon *)module);
  187. /* If the memory of this module has been instantiated,
  188. return the memory instance directly */
  189. if (node) {
  190. uint32 ref_count;
  191. ref_count = shared_memory_inc_reference(
  192. (WASMModuleCommon *)module);
  193. bh_assert(ref_count > 0);
  194. shared_memory_instance =
  195. (AOTMemoryInstance *)shared_memory_get_memory_inst(node);
  196. bh_assert(shared_memory_instance);
  197. /* Set the shared memory flag, so the runtime will get the
  198. actual memory inst through module_inst->memories array */
  199. memory_inst->is_shared = true;
  200. (void)ref_count;
  201. return shared_memory_instance;
  202. }
  203. #ifndef OS_ENABLE_HW_BOUND_CHECK
  204. /* Allocate max page for shared memory */
  205. total_size = heap_size + max_memory_data_size;
  206. #endif
  207. }
  208. #endif
  209. #ifndef OS_ENABLE_HW_BOUND_CHECK
  210. /* Allocate memory */
  211. if (!(p = runtime_malloc(total_size, error_buf, error_buf_size))) {
  212. return NULL;
  213. }
  214. #else
  215. uint8 *mapped_mem;
  216. uint64 map_size = 8 * (uint64)BH_GB;
  217. /* Totally 8G is mapped, the opcode load/store address range is -2G to 6G:
  218. * ea = i + memarg.offset
  219. * i is i32, the range is -2G to 2G
  220. * memarg.offset is u32, the range is 0 to 4G
  221. * so the range of ea is -2G to 6G
  222. */
  223. if (total_size >= UINT32_MAX
  224. || !(mapped_mem = os_mmap(NULL, map_size,
  225. MMAP_PROT_NONE, MMAP_MAP_NONE))) {
  226. set_error_buf(error_buf, error_buf_size,
  227. "AOT module instantiate failed: mmap memory failed.");
  228. return NULL;
  229. }
  230. p = mapped_mem + 2 * (uint64)BH_GB - heap_size;
  231. if (os_mprotect(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
  232. set_error_buf(error_buf, error_buf_size,
  233. "AOT module instantiate failed: mprotec memory failed.");
  234. os_munmap(mapped_mem, map_size);
  235. return NULL;
  236. }
  237. memset(p, 0, (uint32)total_size);
  238. #endif
  239. memory_inst->module_type = Wasm_Module_AoT;
  240. /* Initialize heap info */
  241. memory_inst->heap_data.ptr = p;
  242. p += heap_size;
  243. memory_inst->heap_data_end.ptr = p;
  244. memory_inst->heap_data_size = heap_size;
  245. memory_inst->heap_base_offset = -(int32)heap_size;
  246. if (heap_size > 0) {
  247. if (!(heap_handle = mem_allocator_create(memory_inst->heap_data.ptr,
  248. heap_size))) {
  249. set_error_buf(error_buf, error_buf_size,
  250. "AOT module instantiate failed:"
  251. "init app heap failed.");
  252. goto fail1;
  253. }
  254. memory_inst->heap_handle.ptr = heap_handle;
  255. }
  256. /* Init memory info */
  257. memory_inst->memory_data.ptr = p;
  258. #if WASM_ENABLE_SHARED_MEMORY != 0
  259. if (is_shared_memory) {
  260. p += (uint32)max_memory_data_size;
  261. }
  262. else
  263. #endif
  264. {
  265. p += (uint32)memory_data_size;
  266. }
  267. memory_inst->memory_data_end.ptr = p;
  268. memory_inst->memory_data_size = (uint32)memory_data_size;
  269. memory_inst->mem_cur_page_count = memory->mem_init_page_count;
  270. memory_inst->mem_max_page_count = memory->mem_max_page_count;
  271. memory_inst->mem_bound_check_heap_base = memory_inst->heap_base_offset;
  272. memory_inst->mem_bound_check_1byte =
  273. (int64)memory_inst->memory_data_size - 1;
  274. memory_inst->mem_bound_check_2bytes =
  275. (int64)memory_inst->memory_data_size - 2;
  276. memory_inst->mem_bound_check_4bytes =
  277. (int64)memory_inst->memory_data_size - 4;
  278. memory_inst->mem_bound_check_8bytes =
  279. (int64)memory_inst->memory_data_size - 8;
  280. #if WASM_ENABLE_SHARED_MEMORY != 0
  281. if (is_shared_memory) {
  282. memory_inst->is_shared = true;
  283. if (!shared_memory_set_memory_inst((WASMModuleCommon *)module,
  284. (WASMMemoryInstanceCommon *)memory_inst)) {
  285. set_error_buf(error_buf, error_buf_size,
  286. "Instantiate memory failed:"
  287. "allocate memory failed.");
  288. goto fail2;
  289. }
  290. }
  291. #endif
  292. return memory_inst;
  293. #if WASM_ENABLE_SHARED_MEMORY != 0
  294. fail2:
  295. if (heap_size > 0) {
  296. mem_allocator_destroy(memory_inst->heap_handle.ptr);
  297. memory_inst->heap_handle.ptr = NULL;
  298. }
  299. #endif
  300. fail1:
  301. #ifndef OS_ENABLE_HW_BOUND_CHECK
  302. wasm_runtime_free(memory_inst->heap_data.ptr);
  303. #else
  304. os_munmap(mapped_mem, map_size);
  305. #endif
  306. memory_inst->heap_data.ptr = NULL;
  307. return NULL;
  308. }
  309. static AOTMemoryInstance*
  310. aot_get_default_memory(AOTModuleInstance *module_inst)
  311. {
  312. if (module_inst->memories.ptr)
  313. return ((AOTMemoryInstance **)module_inst->memories.ptr)[0];
  314. else
  315. return NULL;
  316. }
  317. static bool
  318. memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  319. uint32 heap_size, char *error_buf, uint32 error_buf_size)
  320. {
  321. uint32 global_index, global_data_offset, base_offset, length;
  322. uint32 i, memory_count = module->memory_count;
  323. AOTMemoryInstance *memories, *memory_inst;
  324. AOTMemInitData *data_seg;
  325. uint64 total_size;
  326. module_inst->memory_count = memory_count;
  327. total_size = sizeof(AOTPointer) * (uint64)memory_count;
  328. if (!(module_inst->memories.ptr =
  329. runtime_malloc(total_size, error_buf, error_buf_size))) {
  330. return false;
  331. }
  332. memories = module_inst->global_table_data.memory_instances;
  333. for (i = 0; i < memory_count; i++, memories++) {
  334. memory_inst =
  335. memory_instantiate(module_inst, module,
  336. memories, &module->memories[i],
  337. heap_size, error_buf, error_buf_size);
  338. if (!memory_inst) {
  339. return false;
  340. }
  341. ((AOTMemoryInstance **)module_inst->memories.ptr)[i] = memory_inst;
  342. }
  343. /* Get default memory instance */
  344. memory_inst = aot_get_default_memory(module_inst);
  345. for (i = 0; i < module->mem_init_data_count; i++) {
  346. data_seg = module->mem_init_data_list[i];
  347. #if WASM_ENABLE_BULK_MEMORY != 0
  348. if (data_seg->is_passive)
  349. continue;
  350. #endif
  351. bh_assert(data_seg->offset.init_expr_type ==
  352. INIT_EXPR_TYPE_I32_CONST
  353. || data_seg->offset.init_expr_type ==
  354. INIT_EXPR_TYPE_GET_GLOBAL);
  355. /* Resolve memory data base offset */
  356. if (data_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  357. global_index = data_seg->offset.u.global_index;
  358. bh_assert(global_index <
  359. module->import_global_count + module->global_count);
  360. /* TODO: && globals[data_seg->offset.u.global_index].type ==
  361. VALUE_TYPE_I32*/
  362. if (global_index < module->import_global_count)
  363. global_data_offset =
  364. module->import_globals[global_index].data_offset;
  365. else
  366. global_data_offset =
  367. module->globals[global_index - module->import_global_count]
  368. .data_offset;
  369. base_offset = *(uint32*)
  370. ((uint8*)module_inst->global_data.ptr + global_data_offset);
  371. } else {
  372. base_offset = (uint32)data_seg->offset.u.i32;
  373. }
  374. /* Copy memory data */
  375. bh_assert(memory_inst->memory_data.ptr);
  376. /* Check memory data */
  377. /* check offset since length might negative */
  378. if (base_offset > memory_inst->memory_data_size) {
  379. LOG_DEBUG("base_offset(%d) > memory_data_size(%d)", base_offset,
  380. memory_inst->memory_data_size);
  381. set_error_buf(error_buf, error_buf_size,
  382. "data segment does not fit");
  383. return false;
  384. }
  385. /* check offset + length(could be zero) */
  386. length = data_seg->byte_count;
  387. if (base_offset + length > memory_inst->memory_data_size) {
  388. LOG_DEBUG("base_offset(%d) + length(%d) > memory_data_size(%d)",
  389. base_offset, length, memory_inst->memory_data_size);
  390. set_error_buf(error_buf, error_buf_size,
  391. "data segment does not fit");
  392. return false;
  393. }
  394. bh_memcpy_s((uint8*)memory_inst->memory_data.ptr + base_offset,
  395. memory_inst->memory_data_size - base_offset,
  396. data_seg->bytes, length);
  397. }
  398. return true;
  399. }
  400. static bool
  401. init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
  402. char *error_buf, uint32 error_buf_size)
  403. {
  404. uint32 i;
  405. void **func_ptrs;
  406. uint64 total_size =
  407. ((uint64)module->import_func_count + module->func_count) * sizeof(void*);
  408. /* Allocate memory */
  409. if (!(module_inst->func_ptrs.ptr = runtime_malloc
  410. (total_size, error_buf, error_buf_size))) {
  411. return false;
  412. }
  413. /* Set import function pointers */
  414. func_ptrs = (void**)module_inst->func_ptrs.ptr;
  415. for (i = 0; i < module->import_func_count; i++, func_ptrs++)
  416. *func_ptrs = (void*)module->import_funcs[i].func_ptr_linked;
  417. /* Set defined function pointers */
  418. memcpy(func_ptrs, module->func_ptrs, module->func_count * sizeof(void*));
  419. return true;
  420. }
  421. static bool
  422. init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
  423. char *error_buf, uint32 error_buf_size)
  424. {
  425. uint32 i;
  426. uint32 *func_type_index;
  427. uint64 total_size =
  428. ((uint64)module->import_func_count + module->func_count) * sizeof(uint32);
  429. /* Allocate memory */
  430. if (!(module_inst->func_type_indexes.ptr =
  431. runtime_malloc(total_size, error_buf, error_buf_size))) {
  432. return false;
  433. }
  434. /* Set import function type indexes */
  435. func_type_index = (uint32*)module_inst->func_type_indexes.ptr;
  436. for (i = 0; i < module->import_func_count; i++, func_type_index++)
  437. *func_type_index = module->import_funcs[i].func_type_index;
  438. memcpy(func_type_index, module->func_type_indexes,
  439. module->func_count * sizeof(uint32));
  440. return true;
  441. }
  442. static bool
  443. create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module,
  444. char *error_buf, uint32 error_buf_size)
  445. {
  446. AOTExport *exports = module->exports;
  447. AOTFunctionInstance *export_func;
  448. uint64 size;
  449. uint32 i, func_index, ftype_index;
  450. for (i = 0; i < module->export_count; i++) {
  451. if (exports[i].kind == EXPORT_KIND_FUNC)
  452. module_inst->export_func_count++;
  453. }
  454. if (module_inst->export_func_count > 0) {
  455. /* Allocate memory */
  456. size = sizeof(AOTFunctionInstance)
  457. * (uint64)module_inst->export_func_count;
  458. if (!(module_inst->export_funcs.ptr = export_func =
  459. runtime_malloc(size, error_buf, error_buf_size))) {
  460. return false;
  461. }
  462. for (i = 0; i < module->export_count; i++) {
  463. if (exports[i].kind == EXPORT_KIND_FUNC) {
  464. export_func->func_name = exports[i].name;
  465. export_func->func_index = exports[i].index;
  466. if (export_func->func_index < module->import_func_count) {
  467. export_func->is_import_func = true;
  468. export_func->u.func_import =
  469. &module->import_funcs[export_func->func_index];
  470. }
  471. else {
  472. export_func->is_import_func = false;
  473. func_index = export_func->func_index
  474. - module->import_func_count;
  475. ftype_index = module->func_type_indexes[func_index];
  476. export_func->u.func.func_type =
  477. module->func_types[ftype_index];
  478. export_func->u.func.func_ptr =
  479. module->func_ptrs[func_index];
  480. }
  481. export_func++;
  482. }
  483. }
  484. }
  485. return true;
  486. }
  487. static bool
  488. create_exports(AOTModuleInstance *module_inst, AOTModule *module,
  489. char *error_buf, uint32 error_buf_size)
  490. {
  491. return create_export_funcs(module_inst, module,
  492. error_buf, error_buf_size);
  493. }
  494. static bool
  495. execute_post_inst_function(AOTModuleInstance *module_inst)
  496. {
  497. AOTFunctionInstance *post_inst_func =
  498. aot_lookup_function(module_inst, "__post_instantiate", "()");
  499. if (!post_inst_func)
  500. /* Not found */
  501. return true;
  502. return aot_create_exec_env_and_call_function(module_inst, post_inst_func, 0, NULL);
  503. }
  504. static bool
  505. execute_start_function(AOTModuleInstance *module_inst)
  506. {
  507. AOTModule *module = (AOTModule*)module_inst->aot_module.ptr;
  508. WASMExecEnv *exec_env;
  509. typedef void (*F)(WASMExecEnv*);
  510. union { F f; void *v; } u;
  511. if (!module->start_function)
  512. return true;
  513. if (!(exec_env = wasm_exec_env_create((WASMModuleInstanceCommon*)module_inst,
  514. module_inst->default_wasm_stack_size))) {
  515. aot_set_exception(module_inst, "allocate memory failed.");
  516. return false;
  517. }
  518. u.v = module->start_function;
  519. u.f(exec_env);
  520. wasm_exec_env_destroy(exec_env);
  521. return !aot_get_exception(module_inst);
  522. }
  523. #if WASM_ENABLE_BULK_MEMORY != 0
  524. static bool
  525. execute_memory_init_function(AOTModuleInstance *module_inst)
  526. {
  527. AOTFunctionInstance *memory_init_func =
  528. aot_lookup_function(module_inst, "__wasm_call_ctors", "()");
  529. if (!memory_init_func)
  530. /* Not found */
  531. return true;
  532. return aot_create_exec_env_and_call_function(module_inst, memory_init_func,
  533. 0, NULL);
  534. }
  535. #endif
  536. AOTModuleInstance*
  537. aot_instantiate(AOTModule *module, bool is_sub_inst,
  538. uint32 stack_size, uint32 heap_size,
  539. char *error_buf, uint32 error_buf_size)
  540. {
  541. AOTModuleInstance *module_inst;
  542. uint32 module_inst_struct_size =
  543. offsetof(AOTModuleInstance, global_table_data.bytes);
  544. uint64 module_inst_mem_inst_size =
  545. (uint64)module->memory_count * sizeof(AOTMemoryInstance);
  546. uint32 table_size = module->table_count > 0 ?
  547. module->tables[0].table_init_size : 0;
  548. uint64 table_data_size = (uint64)table_size * sizeof(uint32);
  549. uint64 total_size = (uint64)module_inst_struct_size
  550. + module_inst_mem_inst_size
  551. + module->global_data_size
  552. + table_data_size;
  553. uint8 *p;
  554. /* Check heap size */
  555. heap_size = align_uint(heap_size, 8);
  556. if (heap_size > APP_HEAP_SIZE_MAX)
  557. heap_size = APP_HEAP_SIZE_MAX;
  558. #ifdef OS_ENABLE_HW_BOUND_CHECK
  559. heap_size = align_uint(heap_size, os_getpagesize());
  560. #endif
  561. /* Allocate module instance, global data, table data and heap data */
  562. if (!(module_inst = runtime_malloc(total_size,
  563. error_buf, error_buf_size))) {
  564. return NULL;
  565. }
  566. module_inst->module_type = Wasm_Module_AoT;
  567. module_inst->aot_module.ptr = module;
  568. /* Initialize global info */
  569. p = (uint8*)module_inst + module_inst_struct_size +
  570. module_inst_mem_inst_size;
  571. module_inst->global_data.ptr = p;
  572. module_inst->global_data_size = module->global_data_size;
  573. if (!global_instantiate(module_inst, module, error_buf, error_buf_size))
  574. goto fail;
  575. /* Initialize table info */
  576. p += module->global_data_size;
  577. module_inst->table_data.ptr = p;
  578. module_inst->table_size = table_size;
  579. /* Set all elements to -1 to mark them as uninitialized elements */
  580. memset(module_inst->table_data.ptr, -1, (uint32)table_data_size);
  581. if (!table_instantiate(module_inst, module, error_buf, error_buf_size))
  582. goto fail;
  583. /* Initialize memory space */
  584. if (!memories_instantiate(module_inst, module, heap_size,
  585. error_buf, error_buf_size))
  586. goto fail;
  587. /* Initialize function pointers */
  588. if (!init_func_ptrs(module_inst, module, error_buf, error_buf_size))
  589. goto fail;
  590. /* Initialize function type indexes */
  591. if (!init_func_type_indexes(module_inst, module, error_buf, error_buf_size))
  592. goto fail;
  593. if (!create_exports(module_inst, module, error_buf, error_buf_size))
  594. goto fail;
  595. #if WASM_ENABLE_LIBC_WASI != 0
  596. if (!is_sub_inst) {
  597. if (heap_size > 0
  598. && !wasm_runtime_init_wasi((WASMModuleInstanceCommon*)module_inst,
  599. module->wasi_args.dir_list,
  600. module->wasi_args.dir_count,
  601. module->wasi_args.map_dir_list,
  602. module->wasi_args.map_dir_count,
  603. module->wasi_args.env,
  604. module->wasi_args.env_count,
  605. module->wasi_args.argv,
  606. module->wasi_args.argc,
  607. error_buf, error_buf_size))
  608. goto fail;
  609. }
  610. #endif
  611. /* Initialize the thread related data */
  612. if (stack_size == 0)
  613. stack_size = DEFAULT_WASM_STACK_SIZE;
  614. #if WASM_ENABLE_SPEC_TEST != 0
  615. if (stack_size < 48 *1024)
  616. stack_size = 48 * 1024;
  617. #endif
  618. module_inst->default_wasm_stack_size = stack_size;
  619. /* Execute __post_instantiate function and start function*/
  620. if (!execute_post_inst_function(module_inst)
  621. || !execute_start_function(module_inst)) {
  622. set_error_buf(error_buf, error_buf_size,
  623. module_inst->cur_exception);
  624. goto fail;
  625. }
  626. #if WASM_ENABLE_BULK_MEMORY != 0
  627. #if WASM_ENABLE_LIBC_WASI != 0
  628. if (!module->is_wasi_module) {
  629. #endif
  630. /* Only execute the memory init function for main instance because
  631. the data segments will be dropped once initialized.
  632. */
  633. if (!is_sub_inst) {
  634. if (!execute_memory_init_function(module_inst)) {
  635. set_error_buf(error_buf, error_buf_size,
  636. module_inst->cur_exception);
  637. goto fail;
  638. }
  639. }
  640. #if WASM_ENABLE_LIBC_WASI != 0
  641. }
  642. #endif
  643. #endif
  644. return module_inst;
  645. fail:
  646. aot_deinstantiate(module_inst, is_sub_inst);
  647. return NULL;
  648. }
  649. void
  650. aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
  651. {
  652. #if WASM_ENABLE_LIBC_WASI != 0
  653. /* Destroy wasi resource before freeing app heap, since some fields of
  654. wasi contex are allocated from app heap, and if app heap is freed,
  655. these fields will be set to NULL, we cannot free their internal data
  656. which may allocated from global heap. */
  657. /* Only destroy wasi ctx in the main module instance */
  658. if (!is_sub_inst)
  659. wasm_runtime_destroy_wasi((WASMModuleInstanceCommon*)module_inst);
  660. #endif
  661. if (module_inst->memories.ptr)
  662. memories_deinstantiate(module_inst);
  663. if (module_inst->export_funcs.ptr)
  664. wasm_runtime_free(module_inst->export_funcs.ptr);
  665. if (module_inst->func_ptrs.ptr)
  666. wasm_runtime_free(module_inst->func_ptrs.ptr);
  667. if (module_inst->func_type_indexes.ptr)
  668. wasm_runtime_free(module_inst->func_type_indexes.ptr);
  669. wasm_runtime_free(module_inst);
  670. }
  671. AOTFunctionInstance*
  672. aot_lookup_function(const AOTModuleInstance *module_inst,
  673. const char *name, const char *signature)
  674. {
  675. uint32 i;
  676. AOTFunctionInstance *export_funcs = (AOTFunctionInstance *)
  677. module_inst->export_funcs.ptr;
  678. for (i = 0; i < module_inst->export_func_count; i++)
  679. if (!strcmp(export_funcs[i].func_name, name))
  680. return &export_funcs[i];
  681. (void)signature;
  682. return NULL;
  683. }
  684. #define PUT_I64_TO_ADDR(addr, value) do { \
  685. union { int64 val; uint32 parts[2]; } u; \
  686. u.val = (value); \
  687. (addr)[0] = u.parts[0]; \
  688. (addr)[1] = u.parts[1]; \
  689. } while (0)
  690. #define PUT_F64_TO_ADDR(addr, value) do { \
  691. union { float64 val; uint32 parts[2]; } u; \
  692. u.val = (value); \
  693. (addr)[0] = u.parts[0]; \
  694. (addr)[1] = u.parts[1]; \
  695. } while (0)
  696. #ifdef OS_ENABLE_HW_BOUND_CHECK
  697. #define STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT 3
  698. static os_thread_local_attribute WASMExecEnv *aot_exec_env = NULL;
  699. static inline uint8 *
  700. get_stack_min_addr(WASMExecEnv *exec_env, uint32 page_size)
  701. {
  702. uintptr_t stack_bound = (uintptr_t)exec_env->native_stack_boundary;
  703. return (uint8*)(stack_bound & ~(uintptr_t)(page_size -1 ));
  704. }
  705. static void
  706. aot_signal_handler(void *sig_addr)
  707. {
  708. AOTModuleInstance *module_inst;
  709. AOTMemoryInstance *memory_inst;
  710. WASMJmpBuf *jmpbuf_node;
  711. uint8 *mapped_mem_start_addr, *mapped_mem_end_addr;
  712. uint8 *stack_min_addr;
  713. uint32 page_size;
  714. uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
  715. /* Check whether current thread is running aot function */
  716. if (aot_exec_env
  717. && aot_exec_env->handle == os_self_thread()
  718. && (jmpbuf_node = aot_exec_env->jmpbuf_stack_top)) {
  719. /* Get mapped mem info of current instance */
  720. module_inst = (AOTModuleInstance *)aot_exec_env->module_inst;
  721. /* Get the default memory instance */
  722. memory_inst = aot_get_default_memory(module_inst);
  723. if (memory_inst) {
  724. mapped_mem_start_addr = (uint8*)memory_inst->memory_data.ptr
  725. - 2 * (uint64)BH_GB;
  726. mapped_mem_end_addr = (uint8*)memory_inst->memory_data.ptr
  727. + 6 * (uint64)BH_GB;
  728. }
  729. /* Get stack info of current thread */
  730. page_size = os_getpagesize();
  731. stack_min_addr = get_stack_min_addr(aot_exec_env, page_size);
  732. if (memory_inst
  733. && (mapped_mem_start_addr <= (uint8*)sig_addr
  734. && (uint8*)sig_addr < mapped_mem_end_addr)) {
  735. /* The address which causes segmentation fault is inside
  736. aot instance's guard regions */
  737. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS);
  738. os_longjmp(jmpbuf_node->jmpbuf, 1);
  739. }
  740. else if (stack_min_addr - page_size <= (uint8*)sig_addr
  741. && (uint8*)sig_addr < stack_min_addr
  742. + page_size * guard_page_count) {
  743. /* The address which causes segmentation fault is inside
  744. native thread's guard page */
  745. aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
  746. os_longjmp(jmpbuf_node->jmpbuf, 1);
  747. }
  748. }
  749. }
  750. bool
  751. aot_signal_init()
  752. {
  753. return os_signal_init(aot_signal_handler) == 0 ? true : false;
  754. }
  755. void
  756. aot_signal_destroy()
  757. {
  758. os_signal_destroy();
  759. }
  760. #if defined(__GNUC__)
  761. __attribute__((no_sanitize_address)) static uint32
  762. #else
  763. static uint32
  764. #endif
  765. touch_pages(uint8 *stack_min_addr, uint32 page_size)
  766. {
  767. uint8 sum = 0;
  768. while (1) {
  769. volatile uint8 *touch_addr =
  770. (volatile uint8*)os_alloca(page_size / 2);
  771. if (touch_addr < stack_min_addr + page_size) {
  772. sum += *(stack_min_addr + page_size - 1);
  773. break;
  774. }
  775. sum += *touch_addr;
  776. }
  777. return sum;
  778. }
  779. static bool
  780. invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
  781. const WASMType *func_type, const char *signature,
  782. void *attachment,
  783. uint32 *argv, uint32 argc, uint32 *argv_ret)
  784. {
  785. AOTModuleInstance *module_inst = (AOTModuleInstance*)exec_env->module_inst;
  786. WASMExecEnv **p_aot_exec_env = &aot_exec_env;
  787. WASMJmpBuf *jmpbuf_node, *jmpbuf_node_pop;
  788. uint32 page_size = os_getpagesize();
  789. uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
  790. uint8 *stack_min_addr = get_stack_min_addr(exec_env, page_size);
  791. bool ret;
  792. /* Check native stack overflow firstly to ensure we have enough
  793. native stack to run the following codes before actually calling
  794. the aot function in invokeNative function. */
  795. if ((uint8*)&module_inst < exec_env->native_stack_boundary
  796. + page_size * (guard_page_count + 1)) {
  797. aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
  798. return false;
  799. }
  800. if (aot_exec_env
  801. && (aot_exec_env != exec_env)) {
  802. aot_set_exception(module_inst, "Invalid exec env.");
  803. return false;
  804. }
  805. if (!exec_env->jmpbuf_stack_top) {
  806. /* Touch each stack page to ensure that it has been mapped: the OS may
  807. lazily grow the stack mapping as a guard page is hit. */
  808. touch_pages(stack_min_addr, page_size);
  809. /* First time to call aot function, protect one page */
  810. if (os_mprotect(stack_min_addr, page_size * guard_page_count,
  811. MMAP_PROT_NONE) != 0) {
  812. aot_set_exception(module_inst, "Set protected page failed.");
  813. return false;
  814. }
  815. }
  816. if (!(jmpbuf_node = wasm_runtime_malloc(sizeof(WASMJmpBuf)))) {
  817. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
  818. return false;
  819. }
  820. wasm_exec_env_push_jmpbuf(exec_env, jmpbuf_node);
  821. aot_exec_env = exec_env;
  822. if (os_setjmp(jmpbuf_node->jmpbuf) == 0) {
  823. ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
  824. signature, attachment,
  825. argv, argc, argv_ret);
  826. }
  827. else {
  828. /* Exception has been set in signal handler before calling longjmp */
  829. ret = false;
  830. }
  831. jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
  832. bh_assert(jmpbuf_node == jmpbuf_node_pop);
  833. wasm_runtime_free(jmpbuf_node);
  834. if (!exec_env->jmpbuf_stack_top) {
  835. /* Unprotect the guard page when the nested call depth is zero */
  836. os_mprotect(stack_min_addr, page_size * guard_page_count,
  837. MMAP_PROT_READ | MMAP_PROT_WRITE);
  838. *p_aot_exec_env = NULL;
  839. }
  840. os_sigreturn();
  841. os_signal_unmask();
  842. (void)jmpbuf_node_pop;
  843. return ret;
  844. }
  845. #define invoke_native_internal invoke_native_with_hw_bound_check
  846. #else /* else of OS_ENABLE_HW_BOUND_CHECK */
  847. #define invoke_native_internal wasm_runtime_invoke_native
  848. #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
  849. bool
  850. aot_call_function(WASMExecEnv *exec_env,
  851. AOTFunctionInstance *function,
  852. unsigned argc, uint32 argv[])
  853. {
  854. AOTModuleInstance *module_inst = (AOTModuleInstance*)exec_env->module_inst;
  855. AOTFuncType *func_type = function->u.func.func_type;
  856. uint32 result_count = func_type->result_count;
  857. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  858. bool ret;
  859. if (ext_ret_count > 0) {
  860. uint32 cell_num = 0, i;
  861. uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
  862. uint32 argv1_buf[32], *argv1 = argv1_buf, *ext_rets = NULL;
  863. uint32 *argv_ret = argv;
  864. uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
  865. uint64 size;
  866. /* Allocate memory all arguments */
  867. size = sizeof(uint32) * (uint64)argc /* original arguments */
  868. + sizeof(void*) * (uint64)ext_ret_count /* extra result values' addr */
  869. + sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
  870. if (size > sizeof(argv1_buf)
  871. && !(argv1 = runtime_malloc(size, module_inst->cur_exception,
  872. sizeof(module_inst->cur_exception)))) {
  873. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
  874. return false;
  875. }
  876. /* Copy original arguments */
  877. bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
  878. /* Get the extra result value's address */
  879. ext_rets = argv1 + argc + sizeof(void*)/sizeof(uint32) * ext_ret_count;
  880. /* Append each extra result value's address to original arguments */
  881. for (i = 0; i < ext_ret_count; i++) {
  882. *(uintptr_t*)(argv1 + argc + sizeof(void*) / sizeof(uint32) * i) =
  883. (uintptr_t)(ext_rets + cell_num);
  884. cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
  885. }
  886. ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
  887. func_type, NULL, NULL, argv1, argc, argv);
  888. if (!ret || aot_get_exception(module_inst)) {
  889. if (argv1 != argv1_buf)
  890. wasm_runtime_free(argv1);
  891. return false;
  892. }
  893. /* Get extra result values */
  894. switch (func_type->types[func_type->param_count]) {
  895. case VALUE_TYPE_I32:
  896. case VALUE_TYPE_F32:
  897. argv_ret++;
  898. break;
  899. case VALUE_TYPE_I64:
  900. case VALUE_TYPE_F64:
  901. argv_ret += 2;
  902. break;
  903. default:
  904. bh_assert(0);
  905. break;
  906. }
  907. ext_rets = argv1 + argc + sizeof(void*)/sizeof(uint32) * ext_ret_count;
  908. bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num,
  909. ext_rets, sizeof(uint32) * cell_num);
  910. if (argv1 != argv1_buf)
  911. wasm_runtime_free(argv1);
  912. return true;
  913. }
  914. else {
  915. ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
  916. func_type, NULL, NULL, argv, argc, argv);
  917. return ret && !aot_get_exception(module_inst) ? true : false;
  918. }
  919. }
  920. bool
  921. aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
  922. AOTFunctionInstance *func,
  923. unsigned argc, uint32 argv[])
  924. {
  925. WASMExecEnv *exec_env;
  926. bool ret;
  927. if (!(exec_env = wasm_exec_env_create((WASMModuleInstanceCommon*)module_inst,
  928. module_inst->default_wasm_stack_size))) {
  929. aot_set_exception(module_inst, "allocate memory failed.");
  930. return false;
  931. }
  932. /* set thread handle and stack boundary */
  933. wasm_exec_env_set_thread_info(exec_env);
  934. ret = aot_call_function(exec_env, func, argc, argv);
  935. wasm_exec_env_destroy(exec_env);
  936. return ret;
  937. }
  938. void
  939. aot_set_exception(AOTModuleInstance *module_inst,
  940. const char *exception)
  941. {
  942. if (exception)
  943. snprintf(module_inst->cur_exception,
  944. sizeof(module_inst->cur_exception),
  945. "Exception: %s", exception);
  946. else
  947. module_inst->cur_exception[0] = '\0';
  948. }
  949. void
  950. aot_set_exception_with_id(AOTModuleInstance *module_inst,
  951. uint32 id)
  952. {
  953. switch (id) {
  954. case EXCE_UNREACHABLE:
  955. aot_set_exception(module_inst, "unreachable");
  956. break;
  957. case EXCE_OUT_OF_MEMORY:
  958. aot_set_exception(module_inst, "allocate memory failed");
  959. break;
  960. case EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS:
  961. aot_set_exception(module_inst, "out of bounds memory access");
  962. break;
  963. case EXCE_INTEGER_OVERFLOW:
  964. aot_set_exception(module_inst, "integer overflow");
  965. break;
  966. case EXCE_INTEGER_DIVIDE_BY_ZERO:
  967. aot_set_exception(module_inst, "integer divide by zero");
  968. break;
  969. case EXCE_INVALID_CONVERSION_TO_INTEGER:
  970. aot_set_exception(module_inst, "invalid conversion to integer");
  971. break;
  972. case EXCE_INVALID_FUNCTION_TYPE_INDEX:
  973. aot_set_exception(module_inst, "indirect call type mismatch");
  974. break;
  975. case EXCE_INVALID_FUNCTION_INDEX:
  976. aot_set_exception(module_inst, "invalid function index");
  977. break;
  978. case EXCE_UNDEFINED_ELEMENT:
  979. aot_set_exception(module_inst, "undefined element");
  980. break;
  981. case EXCE_UNINITIALIZED_ELEMENT:
  982. aot_set_exception(module_inst, "uninitialized element");
  983. break;
  984. case EXCE_CALL_UNLINKED_IMPORT_FUNC:
  985. aot_set_exception(module_inst, "fail to call unlinked import function");
  986. break;
  987. case EXCE_NATIVE_STACK_OVERFLOW:
  988. aot_set_exception(module_inst, "native stack overflow");
  989. break;
  990. default:
  991. break;
  992. }
  993. }
  994. const char*
  995. aot_get_exception(AOTModuleInstance *module_inst)
  996. {
  997. if (module_inst->cur_exception[0] == '\0')
  998. return NULL;
  999. else
  1000. return module_inst->cur_exception;
  1001. }
  1002. void
  1003. aot_clear_exception(AOTModuleInstance *module_inst)
  1004. {
  1005. module_inst->cur_exception[0] = '\0';
  1006. }
  1007. int32
  1008. aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
  1009. void **p_native_addr)
  1010. {
  1011. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1012. uint8 *addr = mem_allocator_malloc(memory_inst->heap_handle.ptr, size);
  1013. if (!addr) {
  1014. aot_set_exception(module_inst, "out of memory");
  1015. return 0;
  1016. }
  1017. if (p_native_addr)
  1018. *p_native_addr = addr;
  1019. return (int32)(addr - (uint8*)memory_inst->memory_data.ptr);
  1020. }
  1021. void
  1022. aot_module_free(AOTModuleInstance *module_inst, int32 ptr)
  1023. {
  1024. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1025. if (ptr) {
  1026. uint8 *addr = (uint8*)memory_inst->memory_data.ptr + ptr;
  1027. if ((uint8*)memory_inst->heap_data.ptr < addr
  1028. && addr < (uint8*)memory_inst->memory_data.ptr)
  1029. mem_allocator_free(memory_inst->heap_handle.ptr, addr);
  1030. }
  1031. }
  1032. int32
  1033. aot_module_dup_data(AOTModuleInstance *module_inst,
  1034. const char *src, uint32 size)
  1035. {
  1036. char *buffer;
  1037. int32 buffer_offset = aot_module_malloc(module_inst, size,
  1038. (void**)&buffer);
  1039. if (buffer_offset != 0) {
  1040. buffer = aot_addr_app_to_native(module_inst, buffer_offset);
  1041. memcpy(buffer, src, size);
  1042. }
  1043. return buffer_offset;
  1044. }
  1045. bool
  1046. aot_validate_app_addr(AOTModuleInstance *module_inst,
  1047. int32 app_offset, uint32 size)
  1048. {
  1049. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1050. /* integer overflow check */
  1051. if(app_offset + (int32)size < app_offset) {
  1052. goto fail;
  1053. }
  1054. if (memory_inst->heap_base_offset <= app_offset
  1055. && app_offset + (int32)size <= (int32)memory_inst->memory_data_size) {
  1056. return true;
  1057. }
  1058. fail:
  1059. aot_set_exception(module_inst, "out of bounds memory access");
  1060. return false;
  1061. }
  1062. bool
  1063. aot_validate_native_addr(AOTModuleInstance *module_inst,
  1064. void *native_ptr, uint32 size)
  1065. {
  1066. uint8 *addr = (uint8*)native_ptr;
  1067. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1068. int32 memory_data_size = (int32)memory_inst->memory_data_size;
  1069. /* integer overflow check */
  1070. if (addr + size < addr) {
  1071. goto fail;
  1072. }
  1073. if ((uint8*)memory_inst->heap_data.ptr <= addr
  1074. && addr + size <= (uint8*)memory_inst->memory_data.ptr
  1075. + memory_data_size) {
  1076. return true;
  1077. }
  1078. fail:
  1079. aot_set_exception(module_inst, "out of bounds memory access");
  1080. return false;
  1081. }
  1082. void *
  1083. aot_addr_app_to_native(AOTModuleInstance *module_inst, int32 app_offset)
  1084. {
  1085. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1086. int32 memory_data_size = (int32)memory_inst->memory_data_size;
  1087. uint8 *addr = (uint8 *)memory_inst->memory_data.ptr + app_offset;
  1088. if ((uint8*)memory_inst->heap_data.ptr <= addr
  1089. && addr < (uint8*)memory_inst->memory_data.ptr
  1090. + memory_data_size)
  1091. return addr;
  1092. return NULL;
  1093. }
  1094. int32
  1095. aot_addr_native_to_app(AOTModuleInstance *module_inst, void *native_ptr)
  1096. {
  1097. uint8 *addr = (uint8*)native_ptr;
  1098. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1099. int32 memory_data_size = (int32)memory_inst->memory_data_size;
  1100. if ((uint8*)memory_inst->heap_data.ptr <= addr
  1101. && addr < (uint8*)memory_inst->memory_data.ptr
  1102. + memory_data_size)
  1103. return (int32)(addr - (uint8*)memory_inst->memory_data.ptr);
  1104. return 0;
  1105. }
  1106. bool
  1107. aot_get_app_addr_range(AOTModuleInstance *module_inst,
  1108. int32 app_offset,
  1109. int32 *p_app_start_offset,
  1110. int32 *p_app_end_offset)
  1111. {
  1112. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1113. int32 memory_data_size = (int32)memory_inst->memory_data_size;
  1114. if (memory_inst->heap_base_offset <= app_offset
  1115. && app_offset < memory_data_size) {
  1116. if (p_app_start_offset)
  1117. *p_app_start_offset = memory_inst->heap_base_offset;
  1118. if (p_app_end_offset)
  1119. *p_app_end_offset = memory_data_size;
  1120. return true;
  1121. }
  1122. return false;
  1123. }
  1124. bool
  1125. aot_get_native_addr_range(AOTModuleInstance *module_inst,
  1126. uint8 *native_ptr,
  1127. uint8 **p_native_start_addr,
  1128. uint8 **p_native_end_addr)
  1129. {
  1130. uint8 *addr = (uint8*)native_ptr;
  1131. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1132. int32 memory_data_size = (int32)memory_inst->memory_data_size;
  1133. if ((uint8*)memory_inst->heap_data.ptr <= addr
  1134. && addr < (uint8*)memory_inst->memory_data.ptr
  1135. + memory_data_size) {
  1136. if (p_native_start_addr)
  1137. *p_native_start_addr = (uint8*)memory_inst->heap_data.ptr;
  1138. if (p_native_end_addr)
  1139. *p_native_end_addr = (uint8*)memory_inst->memory_data.ptr
  1140. + memory_data_size;
  1141. return true;
  1142. }
  1143. return false;
  1144. }
  1145. #ifndef OS_ENABLE_HW_BOUND_CHECK
  1146. bool
  1147. aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
  1148. {
  1149. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1150. uint8 *heap_data_old = memory_inst->heap_data.ptr, *heap_data;
  1151. uint32 num_bytes_per_page =
  1152. ((AOTModule*)module_inst->aot_module.ptr)->memories[0].num_bytes_per_page;
  1153. uint32 cur_page_count = memory_inst->mem_cur_page_count;
  1154. uint32 max_page_count = memory_inst->mem_max_page_count;
  1155. uint32 total_page_count = cur_page_count + inc_page_count;
  1156. uint64 memory_data_size = (uint64)num_bytes_per_page * total_page_count;
  1157. uint32 heap_size = (uint32)((uint8*)memory_inst->memory_data.ptr
  1158. - (uint8*)memory_inst->heap_data.ptr);
  1159. uint32 total_size_old = heap_size + memory_inst->memory_data_size;
  1160. uint64 total_size = heap_size + memory_data_size;
  1161. void *heap_handle_old = memory_inst->heap_handle.ptr;
  1162. if (inc_page_count <= 0)
  1163. /* No need to enlarge memory */
  1164. return true;
  1165. if (total_page_count < cur_page_count /* integer overflow */
  1166. || total_page_count > max_page_count) {
  1167. aot_set_exception(module_inst, "fail to enlarge memory.");
  1168. return false;
  1169. }
  1170. if (total_size >= UINT32_MAX) {
  1171. aot_set_exception(module_inst, "fail to enlarge memory.");
  1172. return false;
  1173. }
  1174. #if WASM_ENABLE_SHARED_MEMORY != 0
  1175. if (memory_inst->is_shared) {
  1176. /* For shared memory, we have reserved the maximum spaces during
  1177. instantiate, only change the cur_page_count here */
  1178. memory_inst->mem_cur_page_count = total_page_count;
  1179. return true;
  1180. }
  1181. #endif
  1182. if (heap_size > 0) {
  1183. /* Destroy heap's lock firstly, if its memory is re-allocated,
  1184. we cannot access its lock again. */
  1185. mem_allocator_destroy_lock(memory_inst->heap_handle.ptr);
  1186. }
  1187. if (!(heap_data = wasm_runtime_realloc(heap_data_old, (uint32)total_size))) {
  1188. if (!(heap_data = wasm_runtime_malloc((uint32)total_size))) {
  1189. if (heap_size > 0) {
  1190. /* Restore heap's lock if memory re-alloc failed */
  1191. mem_allocator_reinit_lock(memory_inst->heap_handle.ptr);
  1192. }
  1193. aot_set_exception(module_inst, "fail to enlarge memory.");
  1194. return false;
  1195. }
  1196. bh_memcpy_s(heap_data, (uint32)total_size,
  1197. heap_data_old, total_size_old);
  1198. wasm_runtime_free(heap_data_old);
  1199. }
  1200. memset(heap_data + total_size_old,
  1201. 0, (uint32)total_size - total_size_old);
  1202. memory_inst->heap_data.ptr = heap_data;
  1203. memory_inst->heap_data_end.ptr = heap_data + heap_size;
  1204. if (heap_size > 0) {
  1205. memory_inst->heap_handle.ptr = (uint8*)heap_handle_old
  1206. + (heap_data - heap_data_old);
  1207. if (mem_allocator_migrate(memory_inst->heap_handle.ptr,
  1208. heap_handle_old) != 0) {
  1209. aot_set_exception(module_inst, "fail to enlarge memory.");
  1210. return false;
  1211. }
  1212. }
  1213. memory_inst->mem_cur_page_count = total_page_count;
  1214. memory_inst->memory_data_size = (uint32)memory_data_size;
  1215. memory_inst->memory_data.ptr = (uint8*)heap_data + heap_size;
  1216. memory_inst->memory_data_end.ptr = (uint8*)memory_inst->memory_data.ptr
  1217. + (uint32)memory_data_size;
  1218. memory_inst->mem_bound_check_1byte = memory_inst->memory_data_size - 1;
  1219. memory_inst->mem_bound_check_2bytes = memory_inst->memory_data_size - 2;
  1220. memory_inst->mem_bound_check_4bytes = memory_inst->memory_data_size - 4;
  1221. memory_inst->mem_bound_check_8bytes = memory_inst->memory_data_size - 8;
  1222. return true;
  1223. }
  1224. #else
  1225. bool
  1226. aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
  1227. {
  1228. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1229. uint32 num_bytes_per_page =
  1230. ((AOTModule*)module_inst->aot_module.ptr)->memories[0].num_bytes_per_page;
  1231. uint32 cur_page_count = memory_inst->mem_cur_page_count;
  1232. uint32 max_page_count = memory_inst->mem_max_page_count;
  1233. uint32 total_page_count = cur_page_count + inc_page_count;
  1234. uint64 memory_data_size = (uint64)num_bytes_per_page * total_page_count;
  1235. if (inc_page_count <= 0)
  1236. /* No need to enlarge memory */
  1237. return true;
  1238. if (total_page_count < cur_page_count /* integer overflow */
  1239. || total_page_count > max_page_count) {
  1240. aot_set_exception(module_inst, "fail to enlarge memory.");
  1241. return false;
  1242. }
  1243. if (os_mprotect(memory_inst->memory_data.ptr, memory_data_size,
  1244. MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
  1245. aot_set_exception(module_inst, "fail to enlarge memory.");
  1246. return false;
  1247. }
  1248. memset(memory_inst->memory_data_end.ptr, 0,
  1249. num_bytes_per_page * inc_page_count);
  1250. memory_inst->mem_cur_page_count = total_page_count;
  1251. memory_inst->memory_data_size = (uint32)memory_data_size;
  1252. memory_inst->memory_data_end.ptr = (uint8*)memory_inst->memory_data.ptr
  1253. + (uint32)memory_data_size;
  1254. memory_inst->mem_bound_check_1byte = memory_inst->memory_data_size - 1;
  1255. memory_inst->mem_bound_check_2bytes = memory_inst->memory_data_size - 2;
  1256. memory_inst->mem_bound_check_4bytes = memory_inst->memory_data_size - 4;
  1257. memory_inst->mem_bound_check_8bytes = memory_inst->memory_data_size - 8;
  1258. return true;
  1259. }
  1260. #endif
  1261. bool
  1262. aot_is_wasm_type_equal(AOTModuleInstance *module_inst,
  1263. uint32 type1_idx, uint32 type2_idx)
  1264. {
  1265. WASMType *type1, *type2;
  1266. AOTModule *module = (AOTModule*)module_inst->aot_module.ptr;
  1267. if (type1_idx >= module->func_type_count
  1268. || type2_idx >= module->func_type_count) {
  1269. aot_set_exception(module_inst, "type index out of bounds");
  1270. return false;
  1271. }
  1272. if (type1_idx == type2_idx)
  1273. return true;
  1274. type1 = module->func_types[type1_idx];
  1275. type2 = module->func_types[type2_idx];
  1276. return wasm_type_equal(type1, type2);
  1277. }
  1278. bool
  1279. aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
  1280. uint32 argc, uint32 *argv)
  1281. {
  1282. AOTModuleInstance *module_inst = (AOTModuleInstance*)
  1283. wasm_runtime_get_module_inst(exec_env);
  1284. AOTModule *aot_module = (AOTModule*)module_inst->aot_module.ptr;
  1285. uint32 *func_type_indexes = (uint32*)module_inst->func_type_indexes.ptr;
  1286. uint32 func_type_idx = func_type_indexes[func_idx];
  1287. AOTFuncType *func_type = aot_module->func_types[func_type_idx];
  1288. void **func_ptrs = (void**)module_inst->func_ptrs.ptr;
  1289. void *func_ptr = func_ptrs[func_idx];
  1290. AOTImportFunc *import_func;
  1291. const char *signature;
  1292. void *attachment;
  1293. char buf[128];
  1294. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1295. uint32 page_size = os_getpagesize();
  1296. uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
  1297. /* Check native stack overflow firstly to ensure we have enough
  1298. native stack to run the following codes before actually calling
  1299. the aot function in invokeNative function. */
  1300. if ((uint8*)&module_inst < exec_env->native_stack_boundary
  1301. + page_size * (guard_page_count + 1)) {
  1302. aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
  1303. return false;
  1304. }
  1305. #endif
  1306. bh_assert(func_idx < aot_module->import_func_count);
  1307. import_func = aot_module->import_funcs + func_idx;
  1308. if (!func_ptr) {
  1309. snprintf(buf, sizeof(buf),
  1310. "fail to call unlinked import function (%s, %s)",
  1311. import_func->module_name, import_func->func_name);
  1312. aot_set_exception(module_inst, buf);
  1313. return false;
  1314. }
  1315. signature = import_func->signature;
  1316. attachment = import_func->attachment;
  1317. if (!import_func->call_conv_raw) {
  1318. return wasm_runtime_invoke_native(exec_env, func_ptr,
  1319. func_type, signature, attachment,
  1320. argv, argc, argv);
  1321. }
  1322. else {
  1323. return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
  1324. func_type, signature, attachment,
  1325. argv, argc, argv);
  1326. }
  1327. }
  1328. bool
  1329. aot_call_indirect(WASMExecEnv *exec_env,
  1330. bool check_func_type, uint32 func_type_idx,
  1331. uint32 table_elem_idx,
  1332. uint32 argc, uint32 *argv)
  1333. {
  1334. AOTModuleInstance *module_inst = (AOTModuleInstance*)
  1335. wasm_runtime_get_module_inst(exec_env);
  1336. AOTModule *aot_module = (AOTModule*)module_inst->aot_module.ptr;
  1337. uint32 *func_type_indexes = (uint32*)module_inst->func_type_indexes.ptr;
  1338. uint32 *table_data = (uint32*)module_inst->table_data.ptr;
  1339. AOTFuncType *func_type;
  1340. void **func_ptrs = (void**)module_inst->func_ptrs.ptr, *func_ptr;
  1341. uint32 table_size = module_inst->table_size;
  1342. uint32 func_idx, func_type_idx1;
  1343. uint32 ext_ret_count;
  1344. AOTImportFunc *import_func;
  1345. const char *signature = NULL;
  1346. void *attachment = NULL;
  1347. char buf[128];
  1348. bool ret;
  1349. /* this function is called from native code, so exec_env->handle and
  1350. exec_env->native_stack_boundary must have been set, we don't set
  1351. it again */
  1352. if ((uint8*)&module_inst < exec_env->native_stack_boundary) {
  1353. aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
  1354. return false;
  1355. }
  1356. if (table_elem_idx >= table_size) {
  1357. aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
  1358. return false;
  1359. }
  1360. func_idx = table_data[table_elem_idx];
  1361. if (func_idx == (uint32)-1) {
  1362. aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
  1363. return false;
  1364. }
  1365. func_type_idx1 = func_type_indexes[func_idx];
  1366. if (check_func_type
  1367. && !aot_is_wasm_type_equal(module_inst, func_type_idx,
  1368. func_type_idx1)) {
  1369. aot_set_exception_with_id(module_inst,
  1370. EXCE_INVALID_FUNCTION_TYPE_INDEX);
  1371. return false;
  1372. }
  1373. func_type = aot_module->func_types[func_type_idx1];
  1374. if (!(func_ptr = func_ptrs[func_idx])) {
  1375. bh_assert(func_idx < aot_module->import_func_count);
  1376. import_func = aot_module->import_funcs + func_idx;
  1377. snprintf(buf, sizeof(buf),
  1378. "fail to call unlinked import function (%s, %s)",
  1379. import_func->module_name, import_func->func_name);
  1380. aot_set_exception(module_inst, buf);
  1381. return false;
  1382. }
  1383. if (func_idx < aot_module->import_func_count) {
  1384. /* Call native function */
  1385. import_func = aot_module->import_funcs + func_idx;
  1386. signature = import_func->signature;
  1387. if (import_func->call_conv_raw) {
  1388. attachment = import_func->attachment;
  1389. return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
  1390. func_type, signature,
  1391. attachment,
  1392. argv, argc, argv);
  1393. }
  1394. }
  1395. ext_ret_count = func_type->result_count > 1
  1396. ? func_type->result_count - 1 : 0;
  1397. if (ext_ret_count > 0) {
  1398. uint32 argv1_buf[32], *argv1 = argv1_buf;
  1399. uint32 *ext_rets = NULL, *argv_ret = argv;
  1400. uint32 cell_num = 0, i;
  1401. uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
  1402. uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
  1403. uint64 size;
  1404. /* Allocate memory all arguments */
  1405. size = sizeof(uint32) * (uint64)argc /* original arguments */
  1406. + sizeof(void*) * (uint64)ext_ret_count /* extra result values' addr */
  1407. + sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
  1408. if (size > sizeof(argv1_buf)
  1409. && !(argv1 = runtime_malloc(size, module_inst->cur_exception,
  1410. sizeof(module_inst->cur_exception)))) {
  1411. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
  1412. return false;
  1413. }
  1414. /* Copy original arguments */
  1415. bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
  1416. /* Get the extra result value's address */
  1417. ext_rets = argv1 + argc + sizeof(void*)/sizeof(uint32) * ext_ret_count;
  1418. /* Append each extra result value's address to original arguments */
  1419. for (i = 0; i < ext_ret_count; i++) {
  1420. *(uintptr_t*)(argv1 + argc + sizeof(void*) / sizeof(uint32) * i) =
  1421. (uintptr_t)(ext_rets + cell_num);
  1422. cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
  1423. }
  1424. ret = invoke_native_internal(exec_env, func_ptr,
  1425. func_type, signature, attachment,
  1426. argv1, argc, argv);
  1427. if (!ret || aot_get_exception(module_inst)) {
  1428. if (argv1 != argv1_buf)
  1429. wasm_runtime_free(argv1);
  1430. return false;
  1431. }
  1432. /* Get extra result values */
  1433. switch (func_type->types[func_type->param_count]) {
  1434. case VALUE_TYPE_I32:
  1435. case VALUE_TYPE_F32:
  1436. argv_ret++;
  1437. break;
  1438. case VALUE_TYPE_I64:
  1439. case VALUE_TYPE_F64:
  1440. argv_ret += 2;
  1441. break;
  1442. default:
  1443. bh_assert(0);
  1444. break;
  1445. }
  1446. ext_rets = argv1 + argc + sizeof(void*)/sizeof(uint32) * ext_ret_count;
  1447. bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num,
  1448. ext_rets, sizeof(uint32) * cell_num);
  1449. if (argv1 != argv1_buf)
  1450. wasm_runtime_free(argv1);
  1451. return true;
  1452. }
  1453. else {
  1454. return invoke_native_internal(exec_env, func_ptr,
  1455. func_type, signature, attachment,
  1456. argv, argc, argv);
  1457. }
  1458. }
  1459. #if WASM_ENABLE_BULK_MEMORY != 0
  1460. bool
  1461. aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index,
  1462. uint32 offset, uint32 len, uint32 dst)
  1463. {
  1464. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1465. AOTModule *aot_module;
  1466. uint8 *data = NULL;
  1467. uint8 *maddr;
  1468. uint64 seg_len = 0;
  1469. aot_module = (AOTModule *)module_inst->aot_module.ptr;
  1470. if (aot_module->is_jit_mode) {
  1471. #if WASM_ENABLE_JIT != 0
  1472. seg_len = aot_module->wasm_module->data_segments[seg_index]->data_length;
  1473. data = aot_module->wasm_module->data_segments[seg_index]->data;
  1474. #endif
  1475. }
  1476. else {
  1477. seg_len = aot_module->mem_init_data_list[seg_index]->byte_count;
  1478. data = aot_module->mem_init_data_list[seg_index]->bytes;
  1479. }
  1480. if (!aot_validate_app_addr(module_inst, dst, len))
  1481. return false;
  1482. if ((uint64)offset + (uint64)len > seg_len) {
  1483. aot_set_exception(module_inst, "out of bounds memory access");
  1484. return false;
  1485. }
  1486. maddr = aot_addr_app_to_native(module_inst, dst);
  1487. bh_memcpy_s(maddr, memory_inst->memory_data_size - dst,
  1488. data + offset, len);
  1489. return true;
  1490. }
  1491. bool
  1492. aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index)
  1493. {
  1494. AOTModule *aot_module = (AOTModule *)(module_inst->aot_module.ptr);
  1495. if (aot_module->is_jit_mode) {
  1496. #if WASM_ENABLE_JIT != 0
  1497. aot_module->wasm_module->data_segments[seg_index]->data_length = 0;
  1498. /* Currently we can't free the dropped data segment
  1499. as they are stored in wasm bytecode */
  1500. #endif
  1501. }
  1502. else {
  1503. aot_module->mem_init_data_list[seg_index]->byte_count = 0;
  1504. /* Currently we can't free the dropped data segment
  1505. as the mem_init_data_count is a continuous array */
  1506. }
  1507. return true;
  1508. }
  1509. #endif /* WASM_ENABLE_BULK_MEMORY */
  1510. #if WASM_ENABLE_THREAD_MGR != 0
  1511. bool
  1512. aot_set_aux_stack(WASMExecEnv *exec_env,
  1513. uint32 start_offset, uint32 size)
  1514. {
  1515. AOTModuleInstance *module_inst =
  1516. (AOTModuleInstance*)exec_env->module_inst;
  1517. AOTModule *module = (AOTModule *)module_inst->aot_module.ptr;
  1518. uint32 stack_top_idx =
  1519. module->llvm_aux_stack_global_index;
  1520. uint32 data_end =
  1521. module->llvm_aux_data_end;
  1522. uint32 stack_bottom =
  1523. module->llvm_aux_stack_bottom;
  1524. bool is_stack_before_data =
  1525. stack_bottom < data_end ? true : false;
  1526. /* Check the aux stack space, currently we don't allocate space in heap */
  1527. if ((is_stack_before_data && (size > start_offset))
  1528. || ((!is_stack_before_data) && (start_offset - data_end < size)))
  1529. return false;
  1530. if ((stack_bottom != (uint32)-1) && (stack_top_idx != (uint32)-1)) {
  1531. /* The aux stack top is a wasm global,
  1532. set the initial value for the global */
  1533. uint32 global_offset =
  1534. module->globals[stack_top_idx].data_offset;
  1535. uint8 *global_addr = module_inst->global_data.ptr + global_offset;
  1536. *(int32*)global_addr = start_offset;
  1537. /* The aux stack boundary is a constant value,
  1538. set the value to exec_env */
  1539. exec_env->aux_stack_boundary = start_offset - size;
  1540. return true;
  1541. }
  1542. return false;
  1543. }
  1544. bool
  1545. aot_get_aux_stack(WASMExecEnv *exec_env,
  1546. uint32 *start_offset, uint32 *size)
  1547. {
  1548. AOTModuleInstance *module_inst =
  1549. (AOTModuleInstance*)exec_env->module_inst;
  1550. AOTModule *module = (AOTModule *)module_inst->aot_module.ptr;
  1551. /* The aux stack information is resolved in loader
  1552. and store in module */
  1553. uint32 stack_bottom = module->llvm_aux_stack_bottom;
  1554. uint32 total_aux_stack_size = module->llvm_aux_stack_size;
  1555. if (stack_bottom != 0 && total_aux_stack_size != 0) {
  1556. if (start_offset)
  1557. *start_offset = stack_bottom;
  1558. if (size)
  1559. *size = total_aux_stack_size;
  1560. return true;
  1561. }
  1562. return false;
  1563. }
  1564. #endif