aot_runtime.c 88 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658
  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. #include "../common/wasm_runtime_common.h"
  9. #include "../interpreter/wasm_runtime.h"
  10. #if WASM_ENABLE_SHARED_MEMORY != 0
  11. #include "../common/wasm_shared_memory.h"
  12. #endif
  13. #if WASM_ENABLE_THREAD_MGR != 0
  14. #include "../libraries/thread-mgr/thread_manager.h"
  15. #endif
  16. /*
  17. * Note: These offsets need to match the values hardcoded in
  18. * AoT compilation code: aot_create_func_context, check_suspend_flags.
  19. */
  20. bh_static_assert(offsetof(WASMExecEnv, module_inst) == 2 * sizeof(uintptr_t));
  21. bh_static_assert(offsetof(WASMExecEnv, argv_buf) == 3 * sizeof(uintptr_t));
  22. bh_static_assert(offsetof(WASMExecEnv, native_stack_boundary)
  23. == 4 * sizeof(uintptr_t));
  24. bh_static_assert(offsetof(WASMExecEnv, suspend_flags) == 5 * sizeof(uintptr_t));
  25. bh_static_assert(offsetof(WASMExecEnv, aux_stack_boundary)
  26. == 6 * sizeof(uintptr_t));
  27. bh_static_assert(offsetof(WASMExecEnv, aux_stack_bottom)
  28. == 7 * sizeof(uintptr_t));
  29. bh_static_assert(offsetof(WASMExecEnv, native_symbol) == 8 * sizeof(uintptr_t));
  30. bh_static_assert(offsetof(AOTModuleInstance, memories) == 1 * sizeof(uint64));
  31. bh_static_assert(offsetof(AOTModuleInstance, func_ptrs) == 5 * sizeof(uint64));
  32. bh_static_assert(offsetof(AOTModuleInstance, func_type_indexes)
  33. == 6 * sizeof(uint64));
  34. bh_static_assert(offsetof(AOTModuleInstance, cur_exception)
  35. == 13 * sizeof(uint64));
  36. bh_static_assert(offsetof(AOTModuleInstance, global_table_data)
  37. == 13 * sizeof(uint64) + 128 + 11 * sizeof(uint64));
  38. static void
  39. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  40. {
  41. if (error_buf != NULL) {
  42. snprintf(error_buf, error_buf_size, "AOT module instantiate failed: %s",
  43. string);
  44. }
  45. }
  46. static void
  47. set_error_buf_v(char *error_buf, uint32 error_buf_size, const char *format, ...)
  48. {
  49. va_list args;
  50. char buf[128];
  51. if (error_buf != NULL) {
  52. va_start(args, format);
  53. vsnprintf(buf, sizeof(buf), format, args);
  54. va_end(args);
  55. snprintf(error_buf, error_buf_size, "AOT module instantiate failed: %s",
  56. buf);
  57. }
  58. }
  59. static void *
  60. runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
  61. {
  62. void *mem;
  63. if (size >= UINT32_MAX || !(mem = wasm_runtime_malloc((uint32)size))) {
  64. set_error_buf(error_buf, error_buf_size, "allocate memory failed");
  65. return NULL;
  66. }
  67. memset(mem, 0, (uint32)size);
  68. return mem;
  69. }
  70. static bool
  71. check_global_init_expr(const AOTModule *module, uint32 global_index,
  72. char *error_buf, uint32 error_buf_size)
  73. {
  74. if (global_index >= module->import_global_count + module->global_count) {
  75. set_error_buf_v(error_buf, error_buf_size, "unknown global %d",
  76. global_index);
  77. return false;
  78. }
  79. /**
  80. * Currently, constant expressions occurring as initializers of
  81. * globals are further constrained in that contained global.get
  82. * instructions are only allowed to refer to imported globals.
  83. *
  84. * And initializer expression cannot reference a mutable global.
  85. */
  86. if (global_index >= module->import_global_count
  87. || module->import_globals->is_mutable) {
  88. set_error_buf(error_buf, error_buf_size,
  89. "constant expression required");
  90. return false;
  91. }
  92. return true;
  93. }
  94. static void
  95. init_global_data(uint8 *global_data, uint8 type, WASMValue *initial_value)
  96. {
  97. switch (type) {
  98. case VALUE_TYPE_I32:
  99. case VALUE_TYPE_F32:
  100. #if WASM_ENABLE_REF_TYPES != 0
  101. case VALUE_TYPE_FUNCREF:
  102. case VALUE_TYPE_EXTERNREF:
  103. #endif
  104. *(int32 *)global_data = initial_value->i32;
  105. break;
  106. case VALUE_TYPE_I64:
  107. case VALUE_TYPE_F64:
  108. bh_memcpy_s(global_data, sizeof(int64), &initial_value->i64,
  109. sizeof(int64));
  110. break;
  111. #if WASM_ENABLE_SIMD != 0
  112. case VALUE_TYPE_V128:
  113. bh_memcpy_s(global_data, sizeof(V128), &initial_value->v128,
  114. sizeof(V128));
  115. break;
  116. #endif
  117. default:
  118. bh_assert(0);
  119. }
  120. }
  121. static bool
  122. global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  123. char *error_buf, uint32 error_buf_size)
  124. {
  125. uint32 i;
  126. InitializerExpression *init_expr;
  127. uint8 *p = module_inst->global_data;
  128. AOTImportGlobal *import_global = module->import_globals;
  129. AOTGlobal *global = module->globals;
  130. /* Initialize import global data */
  131. for (i = 0; i < module->import_global_count; i++, import_global++) {
  132. bh_assert(import_global->data_offset
  133. == (uint32)(p - module_inst->global_data));
  134. init_global_data(p, import_global->type,
  135. &import_global->global_data_linked);
  136. p += import_global->size;
  137. }
  138. /* Initialize defined global data */
  139. for (i = 0; i < module->global_count; i++, global++) {
  140. bh_assert(global->data_offset
  141. == (uint32)(p - module_inst->global_data));
  142. init_expr = &global->init_expr;
  143. switch (init_expr->init_expr_type) {
  144. case INIT_EXPR_TYPE_GET_GLOBAL:
  145. {
  146. if (!check_global_init_expr(module, init_expr->u.global_index,
  147. error_buf, error_buf_size)) {
  148. return false;
  149. }
  150. init_global_data(
  151. p, global->type,
  152. &module->import_globals[init_expr->u.global_index]
  153. .global_data_linked);
  154. break;
  155. }
  156. #if WASM_ENABLE_REF_TYPES != 0
  157. case INIT_EXPR_TYPE_REFNULL_CONST:
  158. {
  159. *(uint32 *)p = NULL_REF;
  160. break;
  161. }
  162. #endif
  163. default:
  164. {
  165. init_global_data(p, global->type, &init_expr->u);
  166. break;
  167. }
  168. }
  169. p += global->size;
  170. }
  171. bh_assert(module_inst->global_data_size
  172. == (uint32)(p - module_inst->global_data));
  173. return true;
  174. }
  175. static bool
  176. tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  177. AOTTableInstance *first_tbl_inst, char *error_buf,
  178. uint32 error_buf_size)
  179. {
  180. uint32 i, global_index, global_data_offset, base_offset, length;
  181. uint64 total_size;
  182. AOTTableInitData *table_seg;
  183. AOTTableInstance *tbl_inst = first_tbl_inst;
  184. total_size = (uint64)sizeof(WASMTableInstance *) * module_inst->table_count;
  185. if (total_size > 0
  186. && !(module_inst->tables =
  187. runtime_malloc(total_size, error_buf, error_buf_size))) {
  188. return false;
  189. }
  190. /*
  191. * treat import table like a local one until we enable module linking
  192. * in AOT mode
  193. */
  194. for (i = 0; i != module_inst->table_count; ++i) {
  195. if (i < module->import_table_count) {
  196. AOTImportTable *import_table = module->import_tables + i;
  197. tbl_inst->cur_size = import_table->table_init_size;
  198. tbl_inst->max_size =
  199. aot_get_imp_tbl_data_slots(import_table, false);
  200. }
  201. else {
  202. AOTTable *table = module->tables + (i - module->import_table_count);
  203. tbl_inst->cur_size = table->table_init_size;
  204. tbl_inst->max_size = aot_get_tbl_data_slots(table, false);
  205. }
  206. /* Set all elements to -1 to mark them as uninitialized elements */
  207. memset(tbl_inst->elems, 0xff, sizeof(uint32) * tbl_inst->max_size);
  208. module_inst->tables[i] = tbl_inst;
  209. tbl_inst = (AOTTableInstance *)((uint8 *)tbl_inst
  210. + offsetof(AOTTableInstance, elems)
  211. + sizeof(uint32) * tbl_inst->max_size);
  212. }
  213. /* fill table with element segment content */
  214. for (i = 0; i < module->table_init_data_count; i++) {
  215. table_seg = module->table_init_data_list[i];
  216. #if WASM_ENABLE_REF_TYPES != 0
  217. if (!wasm_elem_is_active(table_seg->mode))
  218. continue;
  219. #endif
  220. bh_assert(table_seg->table_index < module_inst->table_count);
  221. tbl_inst = module_inst->tables[table_seg->table_index];
  222. bh_assert(tbl_inst);
  223. #if WASM_ENABLE_REF_TYPES != 0
  224. bh_assert(
  225. table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
  226. || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL
  227. || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_FUNCREF_CONST
  228. || table_seg->offset.init_expr_type
  229. == INIT_EXPR_TYPE_REFNULL_CONST);
  230. #else
  231. bh_assert(table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
  232. || table_seg->offset.init_expr_type
  233. == INIT_EXPR_TYPE_GET_GLOBAL);
  234. #endif
  235. /* Resolve table data base offset */
  236. if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  237. global_index = table_seg->offset.u.global_index;
  238. if (!check_global_init_expr(module, global_index, error_buf,
  239. error_buf_size)) {
  240. return false;
  241. }
  242. if (global_index < module->import_global_count)
  243. global_data_offset =
  244. module->import_globals[global_index].data_offset;
  245. else
  246. global_data_offset =
  247. module->globals[global_index - module->import_global_count]
  248. .data_offset;
  249. base_offset =
  250. *(uint32 *)(module_inst->global_data + global_data_offset);
  251. }
  252. else
  253. base_offset = (uint32)table_seg->offset.u.i32;
  254. /* Copy table data */
  255. /* base_offset only since length might negative */
  256. if (base_offset > tbl_inst->cur_size) {
  257. #if WASM_ENABLE_REF_TYPES != 0
  258. set_error_buf(error_buf, error_buf_size,
  259. "out of bounds table access");
  260. #else
  261. set_error_buf(error_buf, error_buf_size,
  262. "elements segment does not fit");
  263. #endif
  264. return false;
  265. }
  266. /* base_offset + length(could be zero) */
  267. length = table_seg->func_index_count;
  268. if (base_offset + length > tbl_inst->cur_size) {
  269. #if WASM_ENABLE_REF_TYPES != 0
  270. set_error_buf(error_buf, error_buf_size,
  271. "out of bounds table access");
  272. #else
  273. set_error_buf(error_buf, error_buf_size,
  274. "elements segment does not fit");
  275. #endif
  276. return false;
  277. }
  278. /**
  279. * Check function index in the current module inst for now.
  280. * will check the linked table inst owner in future
  281. */
  282. bh_memcpy_s(tbl_inst->elems + base_offset,
  283. (tbl_inst->max_size - base_offset) * sizeof(uint32),
  284. table_seg->func_indexes, length * sizeof(uint32));
  285. }
  286. return true;
  287. }
  288. static void
  289. memories_deinstantiate(AOTModuleInstance *module_inst)
  290. {
  291. uint32 i;
  292. AOTMemoryInstance *memory_inst;
  293. for (i = 0; i < module_inst->memory_count; i++) {
  294. memory_inst = module_inst->memories[i];
  295. if (memory_inst) {
  296. #if WASM_ENABLE_SHARED_MEMORY != 0
  297. if (memory_inst->is_shared) {
  298. int32 ref_count = shared_memory_dec_reference(
  299. (WASMModuleCommon *)module_inst->module);
  300. bh_assert(ref_count >= 0);
  301. /* if the reference count is not zero,
  302. don't free the memory */
  303. if (ref_count > 0)
  304. continue;
  305. }
  306. #endif
  307. if (memory_inst->heap_handle) {
  308. mem_allocator_destroy(memory_inst->heap_handle);
  309. wasm_runtime_free(memory_inst->heap_handle);
  310. }
  311. if (memory_inst->memory_data) {
  312. #ifndef OS_ENABLE_HW_BOUND_CHECK
  313. wasm_runtime_free(memory_inst->memory_data);
  314. #else
  315. #ifdef BH_PLATFORM_WINDOWS
  316. os_mem_decommit(memory_inst->memory_data,
  317. memory_inst->num_bytes_per_page
  318. * memory_inst->cur_page_count);
  319. #endif
  320. os_munmap(memory_inst->memory_data, 8 * (uint64)BH_GB);
  321. #endif
  322. }
  323. }
  324. }
  325. wasm_runtime_free(module_inst->memories);
  326. }
  327. static AOTMemoryInstance *
  328. memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  329. AOTMemoryInstance *memory_inst, AOTMemory *memory,
  330. uint32 heap_size, char *error_buf, uint32 error_buf_size)
  331. {
  332. void *heap_handle;
  333. uint32 num_bytes_per_page = memory->num_bytes_per_page;
  334. uint32 init_page_count = memory->mem_init_page_count;
  335. uint32 max_page_count = memory->mem_max_page_count;
  336. uint32 inc_page_count, aux_heap_base, global_idx;
  337. uint32 bytes_of_last_page, bytes_to_page_end;
  338. uint32 heap_offset = num_bytes_per_page * init_page_count;
  339. uint64 total_size;
  340. uint8 *p = NULL, *global_addr;
  341. #ifdef OS_ENABLE_HW_BOUND_CHECK
  342. uint8 *mapped_mem;
  343. uint64 map_size = 8 * (uint64)BH_GB;
  344. uint64 page_size = os_getpagesize();
  345. #endif
  346. #if WASM_ENABLE_SHARED_MEMORY != 0
  347. bool is_shared_memory = memory->memory_flags & 0x02 ? true : false;
  348. /* Shared memory */
  349. if (is_shared_memory) {
  350. AOTMemoryInstance *shared_memory_instance;
  351. WASMSharedMemNode *node =
  352. wasm_module_get_shared_memory((WASMModuleCommon *)module);
  353. /* If the memory of this module has been instantiated,
  354. return the memory instance directly */
  355. if (node) {
  356. uint32 ref_count;
  357. ref_count = shared_memory_inc_reference((WASMModuleCommon *)module);
  358. bh_assert(ref_count > 0);
  359. shared_memory_instance =
  360. (AOTMemoryInstance *)shared_memory_get_memory_inst(node);
  361. bh_assert(shared_memory_instance);
  362. (void)ref_count;
  363. return shared_memory_instance;
  364. }
  365. }
  366. #endif
  367. if (heap_size > 0 && module->malloc_func_index != (uint32)-1
  368. && module->free_func_index != (uint32)-1) {
  369. /* Disable app heap, use malloc/free function exported
  370. by wasm app to allocate/free memory instead */
  371. heap_size = 0;
  372. }
  373. if (init_page_count == max_page_count && init_page_count == 1) {
  374. /* If only one page and at most one page, we just append
  375. the app heap to the end of linear memory, enlarge the
  376. num_bytes_per_page, and don't change the page count */
  377. heap_offset = num_bytes_per_page;
  378. num_bytes_per_page += heap_size;
  379. if (num_bytes_per_page < heap_size) {
  380. set_error_buf(error_buf, error_buf_size,
  381. "failed to insert app heap into linear memory, "
  382. "try using `--heap_size=0` option");
  383. return NULL;
  384. }
  385. }
  386. else if (heap_size > 0) {
  387. if (init_page_count == max_page_count && init_page_count == 0) {
  388. /* If the memory data size is always 0, we resize it to
  389. one page for app heap */
  390. num_bytes_per_page = heap_size;
  391. heap_offset = 0;
  392. inc_page_count = 1;
  393. }
  394. else if (module->aux_heap_base_global_index != (uint32)-1
  395. && module->aux_heap_base
  396. < num_bytes_per_page * init_page_count) {
  397. /* Insert app heap before __heap_base */
  398. aux_heap_base = module->aux_heap_base;
  399. bytes_of_last_page = aux_heap_base % num_bytes_per_page;
  400. if (bytes_of_last_page == 0)
  401. bytes_of_last_page = num_bytes_per_page;
  402. bytes_to_page_end = num_bytes_per_page - bytes_of_last_page;
  403. inc_page_count =
  404. (heap_size - bytes_to_page_end + num_bytes_per_page - 1)
  405. / num_bytes_per_page;
  406. heap_offset = aux_heap_base;
  407. aux_heap_base += heap_size;
  408. bytes_of_last_page = aux_heap_base % num_bytes_per_page;
  409. if (bytes_of_last_page == 0)
  410. bytes_of_last_page = num_bytes_per_page;
  411. bytes_to_page_end = num_bytes_per_page - bytes_of_last_page;
  412. if (bytes_to_page_end < 1 * BH_KB) {
  413. aux_heap_base += 1 * BH_KB;
  414. inc_page_count++;
  415. }
  416. /* Adjust __heap_base global value */
  417. global_idx = module->aux_heap_base_global_index
  418. - module->import_global_count;
  419. global_addr = module_inst->global_data
  420. + module->globals[global_idx].data_offset;
  421. *(uint32 *)global_addr = aux_heap_base;
  422. LOG_VERBOSE("Reset __heap_base global to %u", aux_heap_base);
  423. }
  424. else {
  425. /* Insert app heap before new page */
  426. inc_page_count =
  427. (heap_size + num_bytes_per_page - 1) / num_bytes_per_page;
  428. heap_offset = num_bytes_per_page * init_page_count;
  429. heap_size = num_bytes_per_page * inc_page_count;
  430. if (heap_size > 0)
  431. heap_size -= 1 * BH_KB;
  432. }
  433. init_page_count += inc_page_count;
  434. max_page_count += inc_page_count;
  435. if (init_page_count > DEFAULT_MAX_PAGES) {
  436. set_error_buf(error_buf, error_buf_size,
  437. "failed to insert app heap into linear memory, "
  438. "try using `--heap_size=0` option");
  439. return NULL;
  440. }
  441. else if (init_page_count == DEFAULT_MAX_PAGES) {
  442. num_bytes_per_page = UINT32_MAX;
  443. init_page_count = max_page_count = 1;
  444. }
  445. if (max_page_count > DEFAULT_MAX_PAGES)
  446. max_page_count = DEFAULT_MAX_PAGES;
  447. }
  448. LOG_VERBOSE("Memory instantiate:");
  449. LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
  450. num_bytes_per_page, init_page_count, max_page_count);
  451. LOG_VERBOSE(" data offset: %u, stack size: %d", module->aux_data_end,
  452. module->aux_stack_size);
  453. LOG_VERBOSE(" heap offset: %u, heap size: %d\n", heap_offset, heap_size);
  454. total_size = (uint64)num_bytes_per_page * init_page_count;
  455. #if WASM_ENABLE_SHARED_MEMORY != 0
  456. if (is_shared_memory) {
  457. /* Allocate max page for shared memory */
  458. total_size = (uint64)num_bytes_per_page * max_page_count;
  459. }
  460. #endif
  461. bh_assert(total_size <= UINT32_MAX);
  462. #ifndef OS_ENABLE_HW_BOUND_CHECK
  463. /* Allocate memory */
  464. if (total_size > 0
  465. && !(p = runtime_malloc(total_size, error_buf, error_buf_size))) {
  466. return NULL;
  467. }
  468. #else
  469. total_size = (total_size + page_size - 1) & ~(page_size - 1);
  470. /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
  471. * ea = i + memarg.offset
  472. * both i and memarg.offset are u32 in range 0 to 4G
  473. * so the range of ea is 0 to 8G
  474. */
  475. if (!(p = mapped_mem =
  476. os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE))) {
  477. set_error_buf(error_buf, error_buf_size, "mmap memory failed");
  478. return NULL;
  479. }
  480. #ifdef BH_PLATFORM_WINDOWS
  481. if (!os_mem_commit(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) {
  482. set_error_buf(error_buf, error_buf_size, "commit memory failed");
  483. os_munmap(mapped_mem, map_size);
  484. return NULL;
  485. }
  486. #endif
  487. if (os_mprotect(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
  488. set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
  489. #ifdef BH_PLATFORM_WINDOWS
  490. os_mem_decommit(p, total_size);
  491. #endif
  492. os_munmap(mapped_mem, map_size);
  493. return NULL;
  494. }
  495. /* Newly allocated pages are filled with zero by the OS, we don't fill it
  496. * again here */
  497. #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
  498. if (total_size > UINT32_MAX)
  499. total_size = UINT32_MAX;
  500. memory_inst->module_type = Wasm_Module_AoT;
  501. memory_inst->num_bytes_per_page = num_bytes_per_page;
  502. memory_inst->cur_page_count = init_page_count;
  503. memory_inst->max_page_count = max_page_count;
  504. memory_inst->memory_data_size = (uint32)total_size;
  505. /* Init memory info */
  506. memory_inst->memory_data = p;
  507. memory_inst->memory_data_end = p + (uint32)total_size;
  508. /* Initialize heap info */
  509. memory_inst->heap_data = p + heap_offset;
  510. memory_inst->heap_data_end = p + heap_offset + heap_size;
  511. if (heap_size > 0) {
  512. uint32 heap_struct_size = mem_allocator_get_heap_struct_size();
  513. if (!(heap_handle = runtime_malloc((uint64)heap_struct_size, error_buf,
  514. error_buf_size))) {
  515. goto fail1;
  516. }
  517. memory_inst->heap_handle = heap_handle;
  518. if (!mem_allocator_create_with_struct_and_pool(
  519. heap_handle, heap_struct_size, memory_inst->heap_data,
  520. heap_size)) {
  521. set_error_buf(error_buf, error_buf_size, "init app heap failed");
  522. goto fail2;
  523. }
  524. }
  525. if (total_size > 0) {
  526. #if UINTPTR_MAX == UINT64_MAX
  527. memory_inst->mem_bound_check_1byte.u64 = total_size - 1;
  528. memory_inst->mem_bound_check_2bytes.u64 = total_size - 2;
  529. memory_inst->mem_bound_check_4bytes.u64 = total_size - 4;
  530. memory_inst->mem_bound_check_8bytes.u64 = total_size - 8;
  531. memory_inst->mem_bound_check_16bytes.u64 = total_size - 16;
  532. #else
  533. memory_inst->mem_bound_check_1byte.u32[0] = (uint32)total_size - 1;
  534. memory_inst->mem_bound_check_2bytes.u32[0] = (uint32)total_size - 2;
  535. memory_inst->mem_bound_check_4bytes.u32[0] = (uint32)total_size - 4;
  536. memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8;
  537. memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16;
  538. #endif
  539. }
  540. #if WASM_ENABLE_SHARED_MEMORY != 0
  541. if (is_shared_memory) {
  542. memory_inst->is_shared = true;
  543. if (!shared_memory_set_memory_inst(
  544. (WASMModuleCommon *)module,
  545. (WASMMemoryInstanceCommon *)memory_inst)) {
  546. set_error_buf(error_buf, error_buf_size, "allocate memory failed");
  547. goto fail3;
  548. }
  549. }
  550. #endif
  551. return memory_inst;
  552. #if WASM_ENABLE_SHARED_MEMORY != 0
  553. fail3:
  554. if (heap_size > 0)
  555. mem_allocator_destroy(memory_inst->heap_handle);
  556. #endif
  557. fail2:
  558. if (heap_size > 0)
  559. wasm_runtime_free(memory_inst->heap_handle);
  560. fail1:
  561. #ifndef OS_ENABLE_HW_BOUND_CHECK
  562. if (memory_inst->memory_data)
  563. wasm_runtime_free(memory_inst->memory_data);
  564. #else
  565. #ifdef BH_PLATFORM_WINDOWS
  566. if (memory_inst->memory_data)
  567. os_mem_decommit(p, total_size);
  568. #endif
  569. os_munmap(mapped_mem, map_size);
  570. #endif
  571. memory_inst->memory_data = NULL;
  572. return NULL;
  573. }
  574. static AOTMemoryInstance *
  575. aot_get_default_memory(AOTModuleInstance *module_inst)
  576. {
  577. if (module_inst->memories)
  578. return module_inst->memories[0];
  579. else
  580. return NULL;
  581. }
  582. static bool
  583. memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  584. uint32 heap_size, char *error_buf, uint32 error_buf_size)
  585. {
  586. uint32 global_index, global_data_offset, base_offset, length;
  587. uint32 i, memory_count = module->memory_count;
  588. AOTMemoryInstance *memories, *memory_inst;
  589. AOTMemInitData *data_seg;
  590. uint64 total_size;
  591. module_inst->memory_count = memory_count;
  592. total_size = sizeof(AOTMemoryInstance *) * (uint64)memory_count;
  593. if (!(module_inst->memories =
  594. runtime_malloc(total_size, error_buf, error_buf_size))) {
  595. return false;
  596. }
  597. memories = module_inst->global_table_data.memory_instances;
  598. for (i = 0; i < memory_count; i++, memories++) {
  599. memory_inst = memory_instantiate(module_inst, module, memories,
  600. &module->memories[i], heap_size,
  601. error_buf, error_buf_size);
  602. if (!memory_inst) {
  603. return false;
  604. }
  605. module_inst->memories[i] = memory_inst;
  606. }
  607. /* Get default memory instance */
  608. memory_inst = aot_get_default_memory(module_inst);
  609. if (!memory_inst) {
  610. /* Ignore setting memory init data if no memory inst is created */
  611. return true;
  612. }
  613. for (i = 0; i < module->mem_init_data_count; i++) {
  614. data_seg = module->mem_init_data_list[i];
  615. #if WASM_ENABLE_BULK_MEMORY != 0
  616. if (data_seg->is_passive)
  617. continue;
  618. #endif
  619. bh_assert(data_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
  620. || data_seg->offset.init_expr_type
  621. == INIT_EXPR_TYPE_GET_GLOBAL);
  622. /* Resolve memory data base offset */
  623. if (data_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  624. global_index = data_seg->offset.u.global_index;
  625. if (!check_global_init_expr(module, global_index, error_buf,
  626. error_buf_size)) {
  627. return false;
  628. }
  629. if (global_index < module->import_global_count)
  630. global_data_offset =
  631. module->import_globals[global_index].data_offset;
  632. else
  633. global_data_offset =
  634. module->globals[global_index - module->import_global_count]
  635. .data_offset;
  636. base_offset =
  637. *(uint32 *)(module_inst->global_data + global_data_offset);
  638. }
  639. else {
  640. base_offset = (uint32)data_seg->offset.u.i32;
  641. }
  642. /* Copy memory data */
  643. bh_assert(memory_inst->memory_data
  644. || memory_inst->memory_data_size == 0);
  645. /* Check memory data */
  646. /* check offset since length might negative */
  647. if (base_offset > memory_inst->memory_data_size) {
  648. LOG_DEBUG("base_offset(%d) > memory_data_size(%d)", base_offset,
  649. memory_inst->memory_data_size);
  650. #if WASM_ENABLE_REF_TYPES != 0
  651. set_error_buf(error_buf, error_buf_size,
  652. "out of bounds memory access");
  653. #else
  654. set_error_buf(error_buf, error_buf_size,
  655. "data segment does not fit");
  656. #endif
  657. return false;
  658. }
  659. /* check offset + length(could be zero) */
  660. length = data_seg->byte_count;
  661. if (base_offset + length > memory_inst->memory_data_size) {
  662. LOG_DEBUG("base_offset(%d) + length(%d) > memory_data_size(%d)",
  663. base_offset, length, memory_inst->memory_data_size);
  664. #if WASM_ENABLE_REF_TYPES != 0
  665. set_error_buf(error_buf, error_buf_size,
  666. "out of bounds memory access");
  667. #else
  668. set_error_buf(error_buf, error_buf_size,
  669. "data segment does not fit");
  670. #endif
  671. return false;
  672. }
  673. if (memory_inst->memory_data) {
  674. bh_memcpy_s((uint8 *)memory_inst->memory_data + base_offset,
  675. memory_inst->memory_data_size - base_offset,
  676. data_seg->bytes, length);
  677. }
  678. }
  679. return true;
  680. }
  681. static bool
  682. init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
  683. char *error_buf, uint32 error_buf_size)
  684. {
  685. uint32 i;
  686. void **func_ptrs;
  687. uint64 total_size = ((uint64)module->import_func_count + module->func_count)
  688. * sizeof(void *);
  689. if (module->import_func_count + module->func_count == 0)
  690. return true;
  691. /* Allocate memory */
  692. if (!(module_inst->func_ptrs =
  693. runtime_malloc(total_size, error_buf, error_buf_size))) {
  694. return false;
  695. }
  696. /* Set import function pointers */
  697. func_ptrs = (void **)module_inst->func_ptrs;
  698. for (i = 0; i < module->import_func_count; i++, func_ptrs++) {
  699. *func_ptrs = (void *)module->import_funcs[i].func_ptr_linked;
  700. if (!*func_ptrs) {
  701. const char *module_name = module->import_funcs[i].module_name;
  702. const char *field_name = module->import_funcs[i].func_name;
  703. LOG_WARNING("warning: failed to link import function (%s, %s)",
  704. module_name, field_name);
  705. }
  706. }
  707. /* Set defined function pointers */
  708. bh_memcpy_s(func_ptrs, sizeof(void *) * module->func_count,
  709. module->func_ptrs, sizeof(void *) * module->func_count);
  710. return true;
  711. }
  712. static bool
  713. init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
  714. char *error_buf, uint32 error_buf_size)
  715. {
  716. uint32 i;
  717. uint32 *func_type_index;
  718. uint64 total_size = ((uint64)module->import_func_count + module->func_count)
  719. * sizeof(uint32);
  720. if (module->import_func_count + module->func_count == 0)
  721. return true;
  722. /* Allocate memory */
  723. if (!(module_inst->func_type_indexes =
  724. runtime_malloc(total_size, error_buf, error_buf_size))) {
  725. return false;
  726. }
  727. /* Set import function type indexes */
  728. func_type_index = module_inst->func_type_indexes;
  729. for (i = 0; i < module->import_func_count; i++, func_type_index++)
  730. *func_type_index = module->import_funcs[i].func_type_index;
  731. bh_memcpy_s(func_type_index, sizeof(uint32) * module->func_count,
  732. module->func_type_indexes, sizeof(uint32) * module->func_count);
  733. return true;
  734. }
  735. static bool
  736. create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module,
  737. char *error_buf, uint32 error_buf_size)
  738. {
  739. AOTExport *exports = module->exports;
  740. AOTFunctionInstance *export_func;
  741. uint64 size;
  742. uint32 i, func_index, ftype_index;
  743. if (module_inst->export_func_count > 0) {
  744. /* Allocate memory */
  745. size = sizeof(AOTFunctionInstance)
  746. * (uint64)module_inst->export_func_count;
  747. if (!(export_func = runtime_malloc(size, error_buf, error_buf_size))) {
  748. return false;
  749. }
  750. module_inst->export_functions = (void *)export_func;
  751. for (i = 0; i < module->export_count; i++) {
  752. if (exports[i].kind == EXPORT_KIND_FUNC) {
  753. export_func->func_name = exports[i].name;
  754. export_func->func_index = exports[i].index;
  755. if (export_func->func_index < module->import_func_count) {
  756. export_func->is_import_func = true;
  757. export_func->u.func_import =
  758. &module->import_funcs[export_func->func_index];
  759. }
  760. else {
  761. export_func->is_import_func = false;
  762. func_index =
  763. export_func->func_index - module->import_func_count;
  764. ftype_index = module->func_type_indexes[func_index];
  765. export_func->u.func.func_type =
  766. module->func_types[ftype_index];
  767. export_func->u.func.func_ptr =
  768. module->func_ptrs[func_index];
  769. }
  770. export_func++;
  771. }
  772. }
  773. }
  774. return true;
  775. }
  776. static bool
  777. create_exports(AOTModuleInstance *module_inst, AOTModule *module,
  778. char *error_buf, uint32 error_buf_size)
  779. {
  780. AOTExport *exports = module->exports;
  781. uint32 i;
  782. for (i = 0; i < module->export_count; i++) {
  783. switch (exports[i].kind) {
  784. case EXPORT_KIND_FUNC:
  785. module_inst->export_func_count++;
  786. break;
  787. case EXPORT_KIND_GLOBAL:
  788. module_inst->export_global_count++;
  789. break;
  790. case EXPORT_KIND_TABLE:
  791. module_inst->export_table_count++;
  792. break;
  793. case EXPORT_KIND_MEMORY:
  794. module_inst->export_memory_count++;
  795. break;
  796. default:
  797. return false;
  798. }
  799. }
  800. return create_export_funcs(module_inst, module, error_buf, error_buf_size);
  801. }
  802. static bool
  803. clear_wasi_proc_exit_exception(AOTModuleInstance *module_inst)
  804. {
  805. #if WASM_ENABLE_LIBC_WASI != 0
  806. const char *exception = aot_get_exception(module_inst);
  807. if (exception && !strcmp(exception, "Exception: wasi proc exit")) {
  808. /* The "wasi proc exit" exception is thrown by native lib to
  809. let wasm app exit, which is a normal behavior, we clear
  810. the exception here. */
  811. aot_set_exception(module_inst, NULL);
  812. return true;
  813. }
  814. return false;
  815. #else
  816. return false;
  817. #endif
  818. }
  819. static bool
  820. execute_post_inst_function(AOTModuleInstance *module_inst)
  821. {
  822. AOTFunctionInstance *post_inst_func =
  823. aot_lookup_function(module_inst, "__post_instantiate", "()");
  824. if (!post_inst_func)
  825. /* Not found */
  826. return true;
  827. return aot_create_exec_env_and_call_function(module_inst, post_inst_func, 0,
  828. NULL);
  829. }
  830. static bool
  831. execute_start_function(AOTModuleInstance *module_inst)
  832. {
  833. AOTModule *module = (AOTModule *)module_inst->module;
  834. WASMExecEnv *exec_env;
  835. typedef void (*F)(WASMExecEnv *);
  836. union {
  837. F f;
  838. void *v;
  839. } u;
  840. if (!module->start_function)
  841. return true;
  842. if (!(exec_env =
  843. wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
  844. module_inst->default_wasm_stack_size))) {
  845. aot_set_exception(module_inst, "allocate memory failed");
  846. return false;
  847. }
  848. u.v = module->start_function;
  849. u.f(exec_env);
  850. wasm_exec_env_destroy(exec_env);
  851. (void)clear_wasi_proc_exit_exception(module_inst);
  852. return !aot_get_exception(module_inst);
  853. }
  854. #if WASM_ENABLE_BULK_MEMORY != 0
  855. static bool
  856. execute_memory_init_function(AOTModuleInstance *module_inst)
  857. {
  858. AOTFunctionInstance *memory_init_func =
  859. aot_lookup_function(module_inst, "__wasm_call_ctors", "()");
  860. if (!memory_init_func)
  861. /* Not found */
  862. return true;
  863. return aot_create_exec_env_and_call_function(module_inst, memory_init_func,
  864. 0, NULL);
  865. }
  866. #endif
  867. AOTModuleInstance *
  868. aot_instantiate(AOTModule *module, bool is_sub_inst, uint32 stack_size,
  869. uint32 heap_size, char *error_buf, uint32 error_buf_size)
  870. {
  871. AOTModuleInstance *module_inst;
  872. const uint32 module_inst_struct_size =
  873. offsetof(AOTModuleInstance, global_table_data.bytes);
  874. const uint64 module_inst_mem_inst_size =
  875. (uint64)module->memory_count * sizeof(AOTMemoryInstance);
  876. uint64 total_size, table_size = 0;
  877. uint8 *p;
  878. uint32 i, extra_info_offset;
  879. /* Check heap size */
  880. heap_size = align_uint(heap_size, 8);
  881. if (heap_size > APP_HEAP_SIZE_MAX)
  882. heap_size = APP_HEAP_SIZE_MAX;
  883. total_size = (uint64)module_inst_struct_size + module_inst_mem_inst_size
  884. + module->global_data_size;
  885. /*
  886. * calculate size of table data
  887. */
  888. for (i = 0; i != module->import_table_count; ++i) {
  889. table_size += offsetof(AOTTableInstance, elems);
  890. table_size += (uint64)sizeof(uint32)
  891. * (uint64)aot_get_imp_tbl_data_slots(
  892. module->import_tables + i, false);
  893. }
  894. for (i = 0; i != module->table_count; ++i) {
  895. table_size += offsetof(AOTTableInstance, elems);
  896. table_size +=
  897. (uint64)sizeof(uint32)
  898. * (uint64)aot_get_tbl_data_slots(module->tables + i, false);
  899. }
  900. total_size += table_size;
  901. /* The offset of AOTModuleInstanceExtra, make it 8-byte aligned */
  902. total_size = (total_size + 7LL) & ~7LL;
  903. extra_info_offset = (uint32)total_size;
  904. total_size += sizeof(AOTModuleInstanceExtra);
  905. /* Allocate module instance, global data, table data and heap data */
  906. if (!(module_inst =
  907. runtime_malloc(total_size, error_buf, error_buf_size))) {
  908. return NULL;
  909. }
  910. module_inst->module_type = Wasm_Module_AoT;
  911. module_inst->module = (void *)module;
  912. module_inst->e =
  913. (WASMModuleInstanceExtra *)((uint8 *)module_inst + extra_info_offset);
  914. /* Initialize global info */
  915. p = (uint8 *)module_inst + module_inst_struct_size
  916. + module_inst_mem_inst_size;
  917. module_inst->global_data = p;
  918. module_inst->global_data_size = module->global_data_size;
  919. if (!global_instantiate(module_inst, module, error_buf, error_buf_size))
  920. goto fail;
  921. /* Initialize table info */
  922. p += module->global_data_size;
  923. module_inst->table_count = module->table_count + module->import_table_count;
  924. if (!tables_instantiate(module_inst, module, (AOTTableInstance *)p,
  925. error_buf, error_buf_size))
  926. goto fail;
  927. /* Initialize memory space */
  928. if (!memories_instantiate(module_inst, module, heap_size, error_buf,
  929. error_buf_size))
  930. goto fail;
  931. /* Initialize function pointers */
  932. if (!init_func_ptrs(module_inst, module, error_buf, error_buf_size))
  933. goto fail;
  934. /* Initialize function type indexes */
  935. if (!init_func_type_indexes(module_inst, module, error_buf, error_buf_size))
  936. goto fail;
  937. if (!create_exports(module_inst, module, error_buf, error_buf_size))
  938. goto fail;
  939. #if WASM_ENABLE_LIBC_WASI != 0
  940. if (!is_sub_inst) {
  941. if (!wasm_runtime_init_wasi(
  942. (WASMModuleInstanceCommon *)module_inst,
  943. module->wasi_args.dir_list, module->wasi_args.dir_count,
  944. module->wasi_args.map_dir_list, module->wasi_args.map_dir_count,
  945. module->wasi_args.env, module->wasi_args.env_count,
  946. module->wasi_args.addr_pool, module->wasi_args.addr_count,
  947. module->wasi_args.ns_lookup_pool,
  948. module->wasi_args.ns_lookup_count, module->wasi_args.argv,
  949. module->wasi_args.argc, module->wasi_args.stdio[0],
  950. module->wasi_args.stdio[1], module->wasi_args.stdio[2],
  951. error_buf, error_buf_size))
  952. goto fail;
  953. }
  954. #endif
  955. /* Initialize the thread related data */
  956. if (stack_size == 0)
  957. stack_size = DEFAULT_WASM_STACK_SIZE;
  958. #if WASM_ENABLE_SPEC_TEST != 0
  959. if (stack_size < 48 * 1024)
  960. stack_size = 48 * 1024;
  961. #endif
  962. module_inst->default_wasm_stack_size = stack_size;
  963. #if WASM_ENABLE_PERF_PROFILING != 0
  964. total_size = (uint64)sizeof(AOTFuncPerfProfInfo)
  965. * (module->import_func_count + module->func_count);
  966. if (!(module_inst->func_perf_profilings =
  967. runtime_malloc(total_size, error_buf, error_buf_size))) {
  968. goto fail;
  969. }
  970. #endif
  971. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  972. if (!(module_inst->frames =
  973. runtime_malloc(sizeof(Vector), error_buf, error_buf_size))) {
  974. goto fail;
  975. }
  976. #endif
  977. /* Execute __post_instantiate function and start function*/
  978. if (!execute_post_inst_function(module_inst)
  979. || !execute_start_function(module_inst)) {
  980. set_error_buf(error_buf, error_buf_size, module_inst->cur_exception);
  981. goto fail;
  982. }
  983. #if WASM_ENABLE_BULK_MEMORY != 0
  984. #if WASM_ENABLE_LIBC_WASI != 0
  985. if (!module->import_wasi_api) {
  986. #endif
  987. /* Only execute the memory init function for main instance because
  988. the data segments will be dropped once initialized.
  989. */
  990. if (!is_sub_inst) {
  991. if (!execute_memory_init_function(module_inst)) {
  992. set_error_buf(error_buf, error_buf_size,
  993. module_inst->cur_exception);
  994. goto fail;
  995. }
  996. }
  997. #if WASM_ENABLE_LIBC_WASI != 0
  998. }
  999. #endif
  1000. #endif
  1001. #if WASM_ENABLE_MEMORY_TRACING != 0
  1002. wasm_runtime_dump_module_inst_mem_consumption(
  1003. (WASMModuleInstanceCommon *)module_inst);
  1004. #endif
  1005. return module_inst;
  1006. fail:
  1007. aot_deinstantiate(module_inst, is_sub_inst);
  1008. return NULL;
  1009. }
  1010. void
  1011. aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
  1012. {
  1013. #if WASM_ENABLE_LIBC_WASI != 0
  1014. /* Destroy wasi resource before freeing app heap, since some fields of
  1015. wasi contex are allocated from app heap, and if app heap is freed,
  1016. these fields will be set to NULL, we cannot free their internal data
  1017. which may allocated from global heap. */
  1018. /* Only destroy wasi ctx in the main module instance */
  1019. if (!is_sub_inst)
  1020. wasm_runtime_destroy_wasi((WASMModuleInstanceCommon *)module_inst);
  1021. #endif
  1022. #if WASM_ENABLE_PERF_PROFILING != 0
  1023. if (module_inst->func_perf_profilings)
  1024. wasm_runtime_free(module_inst->func_perf_profilings);
  1025. #endif
  1026. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1027. if (module_inst->frames) {
  1028. bh_vector_destroy(module_inst->frames);
  1029. wasm_runtime_free(module_inst->frames);
  1030. module_inst->frames = NULL;
  1031. }
  1032. #endif
  1033. if (module_inst->tables)
  1034. wasm_runtime_free(module_inst->tables);
  1035. if (module_inst->memories)
  1036. memories_deinstantiate(module_inst);
  1037. if (module_inst->export_functions)
  1038. wasm_runtime_free(module_inst->export_functions);
  1039. if (module_inst->func_ptrs)
  1040. wasm_runtime_free(module_inst->func_ptrs);
  1041. if (module_inst->func_type_indexes)
  1042. wasm_runtime_free(module_inst->func_type_indexes);
  1043. if (module_inst->exec_env_singleton)
  1044. wasm_exec_env_destroy((WASMExecEnv *)module_inst->exec_env_singleton);
  1045. if (((AOTModuleInstanceExtra *)module_inst->e)->c_api_func_imports)
  1046. wasm_runtime_free(
  1047. ((AOTModuleInstanceExtra *)module_inst->e)->c_api_func_imports);
  1048. wasm_runtime_free(module_inst);
  1049. }
  1050. AOTFunctionInstance *
  1051. aot_lookup_function(const AOTModuleInstance *module_inst, const char *name,
  1052. const char *signature)
  1053. {
  1054. uint32 i;
  1055. AOTFunctionInstance *export_funcs =
  1056. (AOTFunctionInstance *)module_inst->export_functions;
  1057. for (i = 0; i < module_inst->export_func_count; i++)
  1058. if (!strcmp(export_funcs[i].func_name, name))
  1059. return &export_funcs[i];
  1060. (void)signature;
  1061. return NULL;
  1062. }
  1063. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1064. static bool
  1065. invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
  1066. const WASMType *func_type,
  1067. const char *signature, void *attachment,
  1068. uint32 *argv, uint32 argc, uint32 *argv_ret)
  1069. {
  1070. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  1071. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  1072. WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
  1073. uint32 page_size = os_getpagesize();
  1074. uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
  1075. uint16 param_count = func_type->param_count;
  1076. uint16 result_count = func_type->result_count;
  1077. const uint8 *types = func_type->types;
  1078. #ifdef BH_PLATFORM_WINDOWS
  1079. const char *exce;
  1080. int result;
  1081. #endif
  1082. bool ret;
  1083. /* Check native stack overflow firstly to ensure we have enough
  1084. native stack to run the following codes before actually calling
  1085. the aot function in invokeNative function. */
  1086. if ((uint8 *)&module_inst < exec_env->native_stack_boundary
  1087. + page_size * (guard_page_count + 1)) {
  1088. aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
  1089. return false;
  1090. }
  1091. if (exec_env_tls && (exec_env_tls != exec_env)) {
  1092. aot_set_exception(module_inst, "invalid exec env");
  1093. return false;
  1094. }
  1095. if (!os_thread_signal_inited()) {
  1096. aot_set_exception(module_inst, "thread signal env not inited");
  1097. return false;
  1098. }
  1099. wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
  1100. wasm_runtime_set_exec_env_tls(exec_env);
  1101. if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
  1102. /* Quick call with func_ptr if the function signature is simple */
  1103. if (!signature && param_count == 1 && types[0] == VALUE_TYPE_I32) {
  1104. if (result_count == 0) {
  1105. void (*NativeFunc)(WASMExecEnv *, uint32) =
  1106. (void (*)(WASMExecEnv *, uint32))func_ptr;
  1107. NativeFunc(exec_env, argv[0]);
  1108. ret = aot_get_exception(module_inst) ? false : true;
  1109. }
  1110. else if (result_count == 1
  1111. && types[param_count] == VALUE_TYPE_I32) {
  1112. uint32 (*NativeFunc)(WASMExecEnv *, uint32) =
  1113. (uint32(*)(WASMExecEnv *, uint32))func_ptr;
  1114. argv_ret[0] = NativeFunc(exec_env, argv[0]);
  1115. ret = aot_get_exception(module_inst) ? false : true;
  1116. }
  1117. else {
  1118. ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
  1119. signature, attachment, argv,
  1120. argc, argv_ret);
  1121. }
  1122. }
  1123. else {
  1124. ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
  1125. signature, attachment, argv, argc,
  1126. argv_ret);
  1127. }
  1128. #ifdef BH_PLATFORM_WINDOWS
  1129. if ((exce = aot_get_exception(module_inst))
  1130. && strstr(exce, "native stack overflow")) {
  1131. /* After a stack overflow, the stack was left
  1132. in a damaged state, let the CRT repair it */
  1133. result = _resetstkoflw();
  1134. bh_assert(result != 0);
  1135. }
  1136. #endif
  1137. }
  1138. else {
  1139. /* Exception has been set in signal handler before calling longjmp */
  1140. ret = false;
  1141. }
  1142. jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
  1143. bh_assert(&jmpbuf_node == jmpbuf_node_pop);
  1144. if (!exec_env->jmpbuf_stack_top) {
  1145. wasm_runtime_set_exec_env_tls(NULL);
  1146. }
  1147. if (!ret) {
  1148. os_sigreturn();
  1149. os_signal_unmask();
  1150. }
  1151. (void)jmpbuf_node_pop;
  1152. return ret;
  1153. }
  1154. #define invoke_native_internal invoke_native_with_hw_bound_check
  1155. #else /* else of OS_ENABLE_HW_BOUND_CHECK */
  1156. #define invoke_native_internal wasm_runtime_invoke_native
  1157. #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
  1158. bool
  1159. aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
  1160. unsigned argc, uint32 argv[])
  1161. {
  1162. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  1163. AOTFuncType *func_type = function->u.func.func_type;
  1164. uint32 result_count = func_type->result_count;
  1165. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  1166. bool ret;
  1167. if (argc < func_type->param_cell_num) {
  1168. char buf[108];
  1169. snprintf(buf, sizeof(buf),
  1170. "invalid argument count %u, must be no smaller than %u", argc,
  1171. func_type->param_cell_num);
  1172. aot_set_exception(module_inst, buf);
  1173. return false;
  1174. }
  1175. argc = func_type->param_cell_num;
  1176. /* func pointer was looked up previously */
  1177. bh_assert(function->u.func.func_ptr != NULL);
  1178. /* set thread handle and stack boundary */
  1179. wasm_exec_env_set_thread_info(exec_env);
  1180. if (ext_ret_count > 0) {
  1181. uint32 cell_num = 0, i;
  1182. uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
  1183. uint32 argv1_buf[32], *argv1 = argv1_buf, *ext_rets = NULL;
  1184. uint32 *argv_ret = argv;
  1185. uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
  1186. uint64 size;
  1187. /* Allocate memory all arguments */
  1188. size =
  1189. sizeof(uint32) * (uint64)argc /* original arguments */
  1190. + sizeof(void *)
  1191. * (uint64)ext_ret_count /* extra result values' addr */
  1192. + sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
  1193. if (size > sizeof(argv1_buf)
  1194. && !(argv1 = runtime_malloc(size, module_inst->cur_exception,
  1195. sizeof(module_inst->cur_exception)))) {
  1196. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
  1197. return false;
  1198. }
  1199. /* Copy original arguments */
  1200. bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
  1201. /* Get the extra result value's address */
  1202. ext_rets =
  1203. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  1204. /* Append each extra result value's address to original arguments */
  1205. for (i = 0; i < ext_ret_count; i++) {
  1206. *(uintptr_t *)(argv1 + argc + sizeof(void *) / sizeof(uint32) * i) =
  1207. (uintptr_t)(ext_rets + cell_num);
  1208. cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
  1209. }
  1210. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
  1211. if (!aot_alloc_frame(exec_env, function->func_index)) {
  1212. if (argv1 != argv1_buf)
  1213. wasm_runtime_free(argv1);
  1214. return false;
  1215. }
  1216. #endif
  1217. ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
  1218. func_type, NULL, NULL, argv1, argc, argv);
  1219. if (!ret || aot_get_exception(module_inst)) {
  1220. if (clear_wasi_proc_exit_exception(module_inst))
  1221. ret = true;
  1222. else
  1223. ret = false;
  1224. }
  1225. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1226. if (!ret) {
  1227. if (aot_create_call_stack(exec_env)) {
  1228. aot_dump_call_stack(exec_env, true, NULL, 0);
  1229. }
  1230. }
  1231. #endif
  1232. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
  1233. aot_free_frame(exec_env);
  1234. #endif
  1235. if (!ret) {
  1236. if (argv1 != argv1_buf)
  1237. wasm_runtime_free(argv1);
  1238. return ret;
  1239. }
  1240. /* Get extra result values */
  1241. switch (func_type->types[func_type->param_count]) {
  1242. case VALUE_TYPE_I32:
  1243. case VALUE_TYPE_F32:
  1244. #if WASM_ENABLE_REF_TYPES != 0
  1245. case VALUE_TYPE_FUNCREF:
  1246. case VALUE_TYPE_EXTERNREF:
  1247. #endif
  1248. argv_ret++;
  1249. break;
  1250. case VALUE_TYPE_I64:
  1251. case VALUE_TYPE_F64:
  1252. argv_ret += 2;
  1253. break;
  1254. #if WASM_ENABLE_SIMD != 0
  1255. case VALUE_TYPE_V128:
  1256. argv_ret += 4;
  1257. break;
  1258. #endif
  1259. default:
  1260. bh_assert(0);
  1261. break;
  1262. }
  1263. ext_rets =
  1264. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  1265. bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num, ext_rets,
  1266. sizeof(uint32) * cell_num);
  1267. if (argv1 != argv1_buf)
  1268. wasm_runtime_free(argv1);
  1269. return true;
  1270. }
  1271. else {
  1272. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
  1273. if (!aot_alloc_frame(exec_env, function->func_index)) {
  1274. return false;
  1275. }
  1276. #endif
  1277. ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
  1278. func_type, NULL, NULL, argv, argc, argv);
  1279. if (clear_wasi_proc_exit_exception(module_inst))
  1280. ret = true;
  1281. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1282. if (aot_get_exception(module_inst)) {
  1283. if (aot_create_call_stack(exec_env)) {
  1284. aot_dump_call_stack(exec_env, true, NULL, 0);
  1285. }
  1286. }
  1287. #endif
  1288. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
  1289. aot_free_frame(exec_env);
  1290. #endif
  1291. return ret && !aot_get_exception(module_inst) ? true : false;
  1292. }
  1293. }
  1294. bool
  1295. aot_create_exec_env_and_call_function(AOTModuleInstance *module_inst,
  1296. AOTFunctionInstance *func, unsigned argc,
  1297. uint32 argv[])
  1298. {
  1299. WASMExecEnv *exec_env = NULL, *existing_exec_env = NULL;
  1300. bool ret;
  1301. #if defined(OS_ENABLE_HW_BOUND_CHECK)
  1302. existing_exec_env = exec_env = wasm_runtime_get_exec_env_tls();
  1303. #elif WASM_ENABLE_THREAD_MGR != 0
  1304. existing_exec_env = exec_env =
  1305. wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst);
  1306. #endif
  1307. if (!existing_exec_env) {
  1308. if (!(exec_env =
  1309. wasm_exec_env_create((WASMModuleInstanceCommon *)module_inst,
  1310. module_inst->default_wasm_stack_size))) {
  1311. aot_set_exception(module_inst, "allocate memory failed");
  1312. return false;
  1313. }
  1314. }
  1315. ret = aot_call_function(exec_env, func, argc, argv);
  1316. /* don't destroy the exec_env if it isn't created in this function */
  1317. if (!existing_exec_env)
  1318. wasm_exec_env_destroy(exec_env);
  1319. return ret;
  1320. }
  1321. void
  1322. aot_set_exception(AOTModuleInstance *module_inst, const char *exception)
  1323. {
  1324. wasm_set_exception(module_inst, exception);
  1325. }
  1326. void
  1327. aot_set_exception_with_id(AOTModuleInstance *module_inst, uint32 id)
  1328. {
  1329. if (id != EXCE_ALREADY_THROWN)
  1330. wasm_set_exception_with_id(module_inst, id);
  1331. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1332. wasm_runtime_access_exce_check_guard_page();
  1333. #endif
  1334. }
  1335. const char *
  1336. aot_get_exception(AOTModuleInstance *module_inst)
  1337. {
  1338. return wasm_get_exception(module_inst);
  1339. }
  1340. static bool
  1341. execute_malloc_function(AOTModuleInstance *module_inst,
  1342. AOTFunctionInstance *malloc_func,
  1343. AOTFunctionInstance *retain_func, uint32 size,
  1344. uint32 *p_result)
  1345. {
  1346. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1347. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  1348. #endif
  1349. uint32 argv[2], argc;
  1350. bool ret;
  1351. argv[0] = size;
  1352. argc = 1;
  1353. if (retain_func) {
  1354. argv[1] = 0;
  1355. argc = 2;
  1356. }
  1357. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1358. if (exec_env_tls != NULL) {
  1359. bh_assert(exec_env_tls->module_inst
  1360. == (WASMModuleInstanceCommon *)module_inst);
  1361. ret = aot_call_function(exec_env_tls, malloc_func, argc, argv);
  1362. if (retain_func && ret) {
  1363. ret = aot_call_function(exec_env_tls, retain_func, 1, argv);
  1364. }
  1365. }
  1366. else
  1367. #endif
  1368. {
  1369. ret = aot_create_exec_env_and_call_function(module_inst, malloc_func,
  1370. argc, argv);
  1371. if (retain_func && ret) {
  1372. ret = aot_create_exec_env_and_call_function(module_inst,
  1373. retain_func, 1, argv);
  1374. }
  1375. }
  1376. if (ret)
  1377. *p_result = argv[0];
  1378. return ret;
  1379. }
  1380. static bool
  1381. execute_free_function(AOTModuleInstance *module_inst,
  1382. AOTFunctionInstance *free_func, uint32 offset)
  1383. {
  1384. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1385. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  1386. #endif
  1387. uint32 argv[2];
  1388. argv[0] = offset;
  1389. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1390. if (exec_env_tls != NULL) {
  1391. bh_assert(exec_env_tls->module_inst
  1392. == (WASMModuleInstanceCommon *)module_inst);
  1393. return aot_call_function(exec_env_tls, free_func, 1, argv);
  1394. }
  1395. else
  1396. #endif
  1397. {
  1398. return aot_create_exec_env_and_call_function(module_inst, free_func, 1,
  1399. argv);
  1400. }
  1401. }
  1402. uint32
  1403. aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
  1404. void **p_native_addr)
  1405. {
  1406. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1407. AOTModule *module = (AOTModule *)module_inst->module;
  1408. uint8 *addr = NULL;
  1409. uint32 offset = 0;
  1410. if (!memory_inst) {
  1411. aot_set_exception(module_inst, "uninitialized memory");
  1412. return 0;
  1413. }
  1414. if (memory_inst->heap_handle) {
  1415. addr = mem_allocator_malloc(memory_inst->heap_handle, size);
  1416. }
  1417. else if (module->malloc_func_index != (uint32)-1
  1418. && module->free_func_index != (uint32)-1) {
  1419. AOTFunctionInstance *malloc_func, *retain_func = NULL;
  1420. char *malloc_func_name;
  1421. char *malloc_func_sig;
  1422. if (module->retain_func_index != (uint32)-1) {
  1423. malloc_func_name = "__new";
  1424. malloc_func_sig = "(ii)i";
  1425. retain_func = aot_lookup_function(module_inst, "__retain", "(i)i");
  1426. if (!retain_func)
  1427. retain_func = aot_lookup_function(module_inst, "__pin", "(i)i");
  1428. bh_assert(retain_func);
  1429. }
  1430. else {
  1431. malloc_func_name = "malloc";
  1432. malloc_func_sig = "(i)i";
  1433. }
  1434. malloc_func =
  1435. aot_lookup_function(module_inst, malloc_func_name, malloc_func_sig);
  1436. if (!malloc_func
  1437. || !execute_malloc_function(module_inst, malloc_func, retain_func,
  1438. size, &offset)) {
  1439. return 0;
  1440. }
  1441. addr = offset ? (uint8 *)memory_inst->memory_data + offset : NULL;
  1442. }
  1443. if (!addr) {
  1444. if (memory_inst->heap_handle
  1445. && mem_allocator_is_heap_corrupted(memory_inst->heap_handle)) {
  1446. wasm_runtime_show_app_heap_corrupted_prompt();
  1447. aot_set_exception(module_inst, "app heap corrupted");
  1448. }
  1449. else {
  1450. LOG_WARNING("warning: allocate %u bytes memory failed", size);
  1451. }
  1452. return 0;
  1453. }
  1454. if (p_native_addr)
  1455. *p_native_addr = addr;
  1456. return (uint32)(addr - memory_inst->memory_data);
  1457. }
  1458. uint32
  1459. aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size,
  1460. void **p_native_addr)
  1461. {
  1462. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1463. uint8 *addr = NULL;
  1464. if (!memory_inst) {
  1465. aot_set_exception(module_inst, "uninitialized memory");
  1466. return 0;
  1467. }
  1468. if (memory_inst->heap_handle) {
  1469. addr = mem_allocator_realloc(
  1470. memory_inst->heap_handle,
  1471. ptr ? memory_inst->memory_data + ptr : NULL, size);
  1472. }
  1473. /* Only support realloc in WAMR's app heap */
  1474. if (!addr) {
  1475. if (memory_inst->heap_handle
  1476. && mem_allocator_is_heap_corrupted(memory_inst->heap_handle)) {
  1477. aot_set_exception(module_inst, "app heap corrupted");
  1478. }
  1479. else {
  1480. aot_set_exception(module_inst, "out of memory");
  1481. }
  1482. return 0;
  1483. }
  1484. if (p_native_addr)
  1485. *p_native_addr = addr;
  1486. return (uint32)(addr - memory_inst->memory_data);
  1487. }
  1488. void
  1489. aot_module_free(AOTModuleInstance *module_inst, uint32 ptr)
  1490. {
  1491. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1492. AOTModule *module = (AOTModule *)module_inst->module;
  1493. if (!memory_inst) {
  1494. return;
  1495. }
  1496. if (ptr) {
  1497. uint8 *addr = memory_inst->memory_data + ptr;
  1498. if (memory_inst->heap_handle && memory_inst->heap_data < addr
  1499. && addr < memory_inst->heap_data_end) {
  1500. mem_allocator_free(memory_inst->heap_handle, addr);
  1501. }
  1502. else if (module->malloc_func_index != (uint32)-1
  1503. && module->free_func_index != (uint32)-1
  1504. && memory_inst->memory_data <= addr
  1505. && addr < memory_inst->memory_data_end) {
  1506. AOTFunctionInstance *free_func;
  1507. char *free_func_name;
  1508. if (module->retain_func_index != (uint32)-1) {
  1509. free_func_name = "__release";
  1510. }
  1511. else {
  1512. free_func_name = "free";
  1513. }
  1514. free_func =
  1515. aot_lookup_function(module_inst, free_func_name, "(i)i");
  1516. if (!free_func && module->retain_func_index != (uint32)-1)
  1517. free_func = aot_lookup_function(module_inst, "__unpin", "(i)i");
  1518. if (free_func)
  1519. execute_free_function(module_inst, free_func, ptr);
  1520. }
  1521. }
  1522. }
  1523. uint32
  1524. aot_module_dup_data(AOTModuleInstance *module_inst, const char *src,
  1525. uint32 size)
  1526. {
  1527. char *buffer;
  1528. uint32 buffer_offset =
  1529. aot_module_malloc(module_inst, size, (void **)&buffer);
  1530. if (buffer_offset != 0) {
  1531. buffer = wasm_runtime_addr_app_to_native(
  1532. (WASMModuleInstanceCommon *)module_inst, buffer_offset);
  1533. bh_memcpy_s(buffer, size, src, size);
  1534. }
  1535. return buffer_offset;
  1536. }
  1537. bool
  1538. aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
  1539. {
  1540. return wasm_enlarge_memory(module_inst, inc_page_count);
  1541. }
  1542. bool
  1543. aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
  1544. uint32 *argv)
  1545. {
  1546. AOTModuleInstance *module_inst =
  1547. (AOTModuleInstance *)wasm_runtime_get_module_inst(exec_env);
  1548. AOTModule *aot_module = (AOTModule *)module_inst->module;
  1549. AOTModuleInstanceExtra *module_inst_extra =
  1550. (AOTModuleInstanceExtra *)module_inst->e;
  1551. CApiFuncImport *c_api_func_import =
  1552. module_inst_extra->c_api_func_imports + func_idx;
  1553. uint32 *func_type_indexes = module_inst->func_type_indexes;
  1554. uint32 func_type_idx = func_type_indexes[func_idx];
  1555. AOTFuncType *func_type = aot_module->func_types[func_type_idx];
  1556. void **func_ptrs = module_inst->func_ptrs;
  1557. void *func_ptr = func_ptrs[func_idx];
  1558. AOTImportFunc *import_func;
  1559. const char *signature;
  1560. void *attachment;
  1561. char buf[96];
  1562. bool ret = false;
  1563. bh_assert(func_idx < aot_module->import_func_count);
  1564. import_func = aot_module->import_funcs + func_idx;
  1565. if (import_func->call_conv_wasm_c_api)
  1566. func_ptr = c_api_func_import->func_ptr_linked;
  1567. if (!func_ptr) {
  1568. snprintf(buf, sizeof(buf),
  1569. "failed to call unlinked import function (%s, %s)",
  1570. import_func->module_name, import_func->func_name);
  1571. aot_set_exception(module_inst, buf);
  1572. goto fail;
  1573. }
  1574. attachment = import_func->attachment;
  1575. if (import_func->call_conv_wasm_c_api) {
  1576. ret = wasm_runtime_invoke_c_api_native(
  1577. (WASMModuleInstanceCommon *)module_inst, func_ptr, func_type, argc,
  1578. argv, c_api_func_import->with_env_arg, c_api_func_import->env_arg);
  1579. }
  1580. else if (!import_func->call_conv_raw) {
  1581. signature = import_func->signature;
  1582. ret =
  1583. wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature,
  1584. attachment, argv, argc, argv);
  1585. }
  1586. else {
  1587. signature = import_func->signature;
  1588. ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type,
  1589. signature, attachment, argv, argc,
  1590. argv);
  1591. }
  1592. fail:
  1593. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1594. if (!ret)
  1595. wasm_runtime_access_exce_check_guard_page();
  1596. #endif
  1597. return ret;
  1598. }
  1599. bool
  1600. aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
  1601. uint32 argc, uint32 *argv)
  1602. {
  1603. AOTModuleInstance *module_inst =
  1604. (AOTModuleInstance *)wasm_runtime_get_module_inst(exec_env);
  1605. AOTModule *aot_module = (AOTModule *)module_inst->module;
  1606. uint32 *func_type_indexes = module_inst->func_type_indexes;
  1607. AOTTableInstance *tbl_inst;
  1608. AOTFuncType *func_type;
  1609. void **func_ptrs = module_inst->func_ptrs, *func_ptr;
  1610. uint32 func_type_idx, func_idx, ext_ret_count;
  1611. AOTImportFunc *import_func;
  1612. const char *signature = NULL;
  1613. void *attachment = NULL;
  1614. char buf[96];
  1615. bool ret;
  1616. /* this function is called from native code, so exec_env->handle and
  1617. exec_env->native_stack_boundary must have been set, we don't set
  1618. it again */
  1619. if ((uint8 *)&module_inst < exec_env->native_stack_boundary) {
  1620. aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
  1621. goto fail;
  1622. }
  1623. tbl_inst = module_inst->tables[tbl_idx];
  1624. bh_assert(tbl_inst);
  1625. if (table_elem_idx >= tbl_inst->cur_size) {
  1626. aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
  1627. goto fail;
  1628. }
  1629. func_idx = tbl_inst->elems[table_elem_idx];
  1630. if (func_idx == NULL_REF) {
  1631. aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
  1632. goto fail;
  1633. }
  1634. func_type_idx = func_type_indexes[func_idx];
  1635. func_type = aot_module->func_types[func_type_idx];
  1636. if (func_idx >= aot_module->import_func_count) {
  1637. /* func pointer was looked up previously */
  1638. bh_assert(func_ptrs[func_idx] != NULL);
  1639. }
  1640. if (!(func_ptr = func_ptrs[func_idx])) {
  1641. bh_assert(func_idx < aot_module->import_func_count);
  1642. import_func = aot_module->import_funcs + func_idx;
  1643. snprintf(buf, sizeof(buf),
  1644. "failed to call unlinked import function (%s, %s)",
  1645. import_func->module_name, import_func->func_name);
  1646. aot_set_exception(module_inst, buf);
  1647. goto fail;
  1648. }
  1649. if (func_idx < aot_module->import_func_count) {
  1650. /* Call native function */
  1651. import_func = aot_module->import_funcs + func_idx;
  1652. signature = import_func->signature;
  1653. if (import_func->call_conv_raw) {
  1654. attachment = import_func->attachment;
  1655. ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type,
  1656. signature, attachment, argv,
  1657. argc, argv);
  1658. if (!ret)
  1659. goto fail;
  1660. return true;
  1661. }
  1662. }
  1663. ext_ret_count =
  1664. func_type->result_count > 1 ? func_type->result_count - 1 : 0;
  1665. if (ext_ret_count > 0) {
  1666. uint32 argv1_buf[32], *argv1 = argv1_buf;
  1667. uint32 *ext_rets = NULL, *argv_ret = argv;
  1668. uint32 cell_num = 0, i;
  1669. uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
  1670. uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
  1671. uint64 size;
  1672. /* Allocate memory all arguments */
  1673. size =
  1674. sizeof(uint32) * (uint64)argc /* original arguments */
  1675. + sizeof(void *)
  1676. * (uint64)ext_ret_count /* extra result values' addr */
  1677. + sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
  1678. if (size > sizeof(argv1_buf)
  1679. && !(argv1 = runtime_malloc(size, module_inst->cur_exception,
  1680. sizeof(module_inst->cur_exception)))) {
  1681. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
  1682. goto fail;
  1683. }
  1684. /* Copy original arguments */
  1685. bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
  1686. /* Get the extra result value's address */
  1687. ext_rets =
  1688. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  1689. /* Append each extra result value's address to original arguments */
  1690. for (i = 0; i < ext_ret_count; i++) {
  1691. *(uintptr_t *)(argv1 + argc + sizeof(void *) / sizeof(uint32) * i) =
  1692. (uintptr_t)(ext_rets + cell_num);
  1693. cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
  1694. }
  1695. ret = invoke_native_internal(exec_env, func_ptr, func_type, signature,
  1696. attachment, argv1, argc, argv);
  1697. if (!ret) {
  1698. if (argv1 != argv1_buf)
  1699. wasm_runtime_free(argv1);
  1700. goto fail;
  1701. }
  1702. /* Get extra result values */
  1703. switch (func_type->types[func_type->param_count]) {
  1704. case VALUE_TYPE_I32:
  1705. case VALUE_TYPE_F32:
  1706. #if WASM_ENABLE_REF_TYPES != 0
  1707. case VALUE_TYPE_FUNCREF:
  1708. case VALUE_TYPE_EXTERNREF:
  1709. #endif
  1710. argv_ret++;
  1711. break;
  1712. case VALUE_TYPE_I64:
  1713. case VALUE_TYPE_F64:
  1714. argv_ret += 2;
  1715. break;
  1716. #if WASM_ENABLE_SIMD != 0
  1717. case VALUE_TYPE_V128:
  1718. argv_ret += 4;
  1719. break;
  1720. #endif
  1721. default:
  1722. bh_assert(0);
  1723. break;
  1724. }
  1725. ext_rets =
  1726. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  1727. bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num, ext_rets,
  1728. sizeof(uint32) * cell_num);
  1729. if (argv1 != argv1_buf)
  1730. wasm_runtime_free(argv1);
  1731. return true;
  1732. }
  1733. else {
  1734. ret = invoke_native_internal(exec_env, func_ptr, func_type, signature,
  1735. attachment, argv, argc, argv);
  1736. if (!ret)
  1737. goto fail;
  1738. return true;
  1739. }
  1740. fail:
  1741. if (clear_wasi_proc_exit_exception(module_inst))
  1742. return true;
  1743. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1744. wasm_runtime_access_exce_check_guard_page();
  1745. #endif
  1746. return false;
  1747. }
  1748. bool
  1749. aot_check_app_addr_and_convert(AOTModuleInstance *module_inst, bool is_str,
  1750. uint32 app_buf_addr, uint32 app_buf_size,
  1751. void **p_native_addr)
  1752. {
  1753. bool ret;
  1754. ret = wasm_check_app_addr_and_convert(module_inst, is_str, app_buf_addr,
  1755. app_buf_size, p_native_addr);
  1756. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1757. if (!ret)
  1758. wasm_runtime_access_exce_check_guard_page();
  1759. #endif
  1760. return ret;
  1761. }
  1762. void *
  1763. aot_memmove(void *dest, const void *src, size_t n)
  1764. {
  1765. return memmove(dest, src, n);
  1766. }
  1767. void *
  1768. aot_memset(void *s, int c, size_t n)
  1769. {
  1770. return memset(s, c, n);
  1771. }
  1772. double
  1773. aot_sqrt(double x)
  1774. {
  1775. return sqrt(x);
  1776. }
  1777. float
  1778. aot_sqrtf(float x)
  1779. {
  1780. return sqrtf(x);
  1781. }
  1782. #if WASM_ENABLE_BULK_MEMORY != 0
  1783. bool
  1784. aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
  1785. uint32 len, uint32 dst)
  1786. {
  1787. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1788. AOTModule *aot_module;
  1789. uint8 *data = NULL;
  1790. uint8 *maddr;
  1791. uint64 seg_len = 0;
  1792. aot_module = (AOTModule *)module_inst->module;
  1793. seg_len = aot_module->mem_init_data_list[seg_index]->byte_count;
  1794. data = aot_module->mem_init_data_list[seg_index]->bytes;
  1795. if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
  1796. dst, len))
  1797. return false;
  1798. if ((uint64)offset + (uint64)len > seg_len) {
  1799. aot_set_exception(module_inst, "out of bounds memory access");
  1800. return false;
  1801. }
  1802. maddr = wasm_runtime_addr_app_to_native(
  1803. (WASMModuleInstanceCommon *)module_inst, dst);
  1804. bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len);
  1805. return true;
  1806. }
  1807. bool
  1808. aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index)
  1809. {
  1810. AOTModule *aot_module = (AOTModule *)module_inst->module;
  1811. aot_module->mem_init_data_list[seg_index]->byte_count = 0;
  1812. /* Currently we can't free the dropped data segment
  1813. as the mem_init_data_count is a continuous array */
  1814. return true;
  1815. }
  1816. #endif /* WASM_ENABLE_BULK_MEMORY */
  1817. #if WASM_ENABLE_THREAD_MGR != 0
  1818. bool
  1819. aot_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
  1820. {
  1821. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  1822. AOTModule *module = (AOTModule *)module_inst->module;
  1823. uint32 stack_top_idx = module->aux_stack_top_global_index;
  1824. uint32 data_end = module->aux_data_end;
  1825. uint32 stack_bottom = module->aux_stack_bottom;
  1826. bool is_stack_before_data = stack_bottom < data_end ? true : false;
  1827. /* Check the aux stack space, currently we don't allocate space in heap */
  1828. if ((is_stack_before_data && (size > start_offset))
  1829. || ((!is_stack_before_data) && (start_offset - data_end < size)))
  1830. return false;
  1831. if (stack_top_idx != (uint32)-1) {
  1832. /* The aux stack top is a wasm global,
  1833. set the initial value for the global */
  1834. uint32 global_offset = module->globals[stack_top_idx].data_offset;
  1835. uint8 *global_addr = module_inst->global_data + global_offset;
  1836. *(int32 *)global_addr = start_offset;
  1837. /* The aux stack boundary is a constant value,
  1838. set the value to exec_env */
  1839. exec_env->aux_stack_boundary.boundary = start_offset - size;
  1840. exec_env->aux_stack_bottom.bottom = start_offset;
  1841. return true;
  1842. }
  1843. return false;
  1844. }
  1845. bool
  1846. aot_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset, uint32 *size)
  1847. {
  1848. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  1849. AOTModule *module = (AOTModule *)module_inst->module;
  1850. /* The aux stack information is resolved in loader
  1851. and store in module */
  1852. uint32 stack_bottom = module->aux_stack_bottom;
  1853. uint32 total_aux_stack_size = module->aux_stack_size;
  1854. if (stack_bottom != 0 && total_aux_stack_size != 0) {
  1855. if (start_offset)
  1856. *start_offset = stack_bottom;
  1857. if (size)
  1858. *size = total_aux_stack_size;
  1859. return true;
  1860. }
  1861. return false;
  1862. }
  1863. #endif
  1864. #if (WASM_ENABLE_MEMORY_PROFILING != 0) || (WASM_ENABLE_MEMORY_TRACING != 0)
  1865. static void
  1866. const_string_node_size_cb(void *key, void *value, void *p_const_string_size)
  1867. {
  1868. uint32 const_string_size = 0;
  1869. const_string_size += bh_hash_map_get_elem_struct_size();
  1870. const_string_size += strlen((const char *)value) + 1;
  1871. *(uint32 *)p_const_string_size += const_string_size;
  1872. }
  1873. void
  1874. aot_get_module_mem_consumption(const AOTModule *module,
  1875. WASMModuleMemConsumption *mem_conspn)
  1876. {
  1877. uint32 i, size;
  1878. memset(mem_conspn, 0, sizeof(*mem_conspn));
  1879. mem_conspn->module_struct_size = sizeof(AOTModule);
  1880. mem_conspn->types_size = sizeof(AOTFuncType *) * module->func_type_count;
  1881. for (i = 0; i < module->func_type_count; i++) {
  1882. AOTFuncType *type = module->func_types[i];
  1883. size = offsetof(AOTFuncType, types)
  1884. + sizeof(uint8) * (type->param_count + type->result_count);
  1885. mem_conspn->types_size += size;
  1886. }
  1887. mem_conspn->imports_size =
  1888. sizeof(AOTImportMemory) * module->import_memory_count
  1889. + sizeof(AOTImportTable) * module->import_table_count
  1890. + sizeof(AOTImportGlobal) * module->import_global_count
  1891. + sizeof(AOTImportFunc) * module->import_func_count;
  1892. /* func_ptrs and func_type_indexes */
  1893. mem_conspn->functions_size =
  1894. (sizeof(void *) + sizeof(uint32)) * module->func_count;
  1895. mem_conspn->tables_size = sizeof(AOTTable) * module->table_count;
  1896. mem_conspn->memories_size = sizeof(AOTMemory) * module->memory_count;
  1897. mem_conspn->globals_size = sizeof(AOTGlobal) * module->global_count;
  1898. mem_conspn->exports_size = sizeof(AOTExport) * module->export_count;
  1899. mem_conspn->table_segs_size =
  1900. sizeof(AOTTableInitData *) * module->table_init_data_count;
  1901. for (i = 0; i < module->table_init_data_count; i++) {
  1902. AOTTableInitData *init_data = module->table_init_data_list[i];
  1903. size = offsetof(AOTTableInitData, func_indexes)
  1904. + sizeof(uint32) * init_data->func_index_count;
  1905. mem_conspn->table_segs_size += size;
  1906. }
  1907. mem_conspn->data_segs_size =
  1908. sizeof(AOTMemInitData *) * module->mem_init_data_count;
  1909. for (i = 0; i < module->mem_init_data_count; i++) {
  1910. mem_conspn->data_segs_size += sizeof(AOTMemInitData);
  1911. }
  1912. if (module->const_str_set) {
  1913. uint32 const_string_size = 0;
  1914. mem_conspn->const_strs_size =
  1915. bh_hash_map_get_struct_size(module->const_str_set);
  1916. bh_hash_map_traverse(module->const_str_set, const_string_node_size_cb,
  1917. (void *)&const_string_size);
  1918. mem_conspn->const_strs_size += const_string_size;
  1919. }
  1920. /* code size + literal size + object data section size */
  1921. mem_conspn->aot_code_size =
  1922. module->code_size + module->literal_size
  1923. + sizeof(AOTObjectDataSection) * module->data_section_count;
  1924. for (i = 0; i < module->data_section_count; i++) {
  1925. AOTObjectDataSection *obj_data = module->data_sections + i;
  1926. mem_conspn->aot_code_size += sizeof(uint8) * obj_data->size;
  1927. }
  1928. mem_conspn->total_size += mem_conspn->module_struct_size;
  1929. mem_conspn->total_size += mem_conspn->types_size;
  1930. mem_conspn->total_size += mem_conspn->imports_size;
  1931. mem_conspn->total_size += mem_conspn->functions_size;
  1932. mem_conspn->total_size += mem_conspn->tables_size;
  1933. mem_conspn->total_size += mem_conspn->memories_size;
  1934. mem_conspn->total_size += mem_conspn->globals_size;
  1935. mem_conspn->total_size += mem_conspn->exports_size;
  1936. mem_conspn->total_size += mem_conspn->table_segs_size;
  1937. mem_conspn->total_size += mem_conspn->data_segs_size;
  1938. mem_conspn->total_size += mem_conspn->const_strs_size;
  1939. mem_conspn->total_size += mem_conspn->aot_code_size;
  1940. }
  1941. void
  1942. aot_get_module_inst_mem_consumption(const AOTModuleInstance *module_inst,
  1943. WASMModuleInstMemConsumption *mem_conspn)
  1944. {
  1945. AOTTableInstance *tbl_inst;
  1946. uint32 i;
  1947. memset(mem_conspn, 0, sizeof(*mem_conspn));
  1948. mem_conspn->module_inst_struct_size = sizeof(AOTModuleInstance);
  1949. mem_conspn->memories_size =
  1950. sizeof(void *) * module_inst->memory_count
  1951. + sizeof(AOTMemoryInstance) * module_inst->memory_count;
  1952. for (i = 0; i < module_inst->memory_count; i++) {
  1953. AOTMemoryInstance *mem_inst = module_inst->memories[i];
  1954. mem_conspn->memories_size +=
  1955. mem_inst->num_bytes_per_page * mem_inst->cur_page_count;
  1956. mem_conspn->app_heap_size =
  1957. mem_inst->heap_data_end - mem_inst->heap_data;
  1958. /* size of app heap structure */
  1959. mem_conspn->memories_size += mem_allocator_get_heap_struct_size();
  1960. }
  1961. mem_conspn->tables_size +=
  1962. sizeof(AOTTableInstance *) * module_inst->table_count;
  1963. for (i = 0; i < module_inst->table_count; i++) {
  1964. tbl_inst = module_inst->tables[i];
  1965. mem_conspn->tables_size += offsetof(AOTTableInstance, elems);
  1966. mem_conspn->tables_size += sizeof(uint32) * tbl_inst->max_size;
  1967. }
  1968. /* func_ptrs and func_type_indexes */
  1969. mem_conspn->functions_size =
  1970. (sizeof(void *) + sizeof(uint32))
  1971. * (((AOTModule *)module_inst->module)->import_func_count
  1972. + ((AOTModule *)module_inst->module)->func_count);
  1973. mem_conspn->globals_size = module_inst->global_data_size;
  1974. mem_conspn->exports_size =
  1975. sizeof(AOTFunctionInstance) * (uint64)module_inst->export_func_count;
  1976. mem_conspn->total_size += mem_conspn->module_inst_struct_size;
  1977. mem_conspn->total_size += mem_conspn->memories_size;
  1978. mem_conspn->total_size += mem_conspn->functions_size;
  1979. mem_conspn->total_size += mem_conspn->tables_size;
  1980. mem_conspn->total_size += mem_conspn->globals_size;
  1981. mem_conspn->total_size += mem_conspn->exports_size;
  1982. }
  1983. #endif /* end of (WASM_ENABLE_MEMORY_PROFILING != 0) \
  1984. || (WASM_ENABLE_MEMORY_TRACING != 0) */
  1985. #if WASM_ENABLE_REF_TYPES != 0
  1986. void
  1987. aot_drop_table_seg(AOTModuleInstance *module_inst, uint32 tbl_seg_idx)
  1988. {
  1989. AOTModule *module = (AOTModule *)module_inst->module;
  1990. AOTTableInitData *tbl_seg = module->table_init_data_list[tbl_seg_idx];
  1991. tbl_seg->is_dropped = true;
  1992. }
  1993. void
  1994. aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
  1995. uint32 tbl_seg_idx, uint32 length, uint32 src_offset,
  1996. uint32 dst_offset)
  1997. {
  1998. AOTTableInstance *tbl_inst;
  1999. AOTTableInitData *tbl_seg;
  2000. const AOTModule *module = (AOTModule *)module_inst->module;
  2001. tbl_inst = module_inst->tables[tbl_idx];
  2002. bh_assert(tbl_inst);
  2003. tbl_seg = module->table_init_data_list[tbl_seg_idx];
  2004. bh_assert(tbl_seg);
  2005. if (!length) {
  2006. return;
  2007. }
  2008. if (length + src_offset > tbl_seg->func_index_count
  2009. || dst_offset + length > tbl_inst->cur_size) {
  2010. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2011. return;
  2012. }
  2013. if (tbl_seg->is_dropped) {
  2014. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2015. return;
  2016. }
  2017. if (!wasm_elem_is_passive(tbl_seg->mode)) {
  2018. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2019. return;
  2020. }
  2021. bh_memcpy_s((uint8 *)tbl_inst + offsetof(AOTTableInstance, elems)
  2022. + dst_offset * sizeof(uint32),
  2023. (tbl_inst->cur_size - dst_offset) * sizeof(uint32),
  2024. tbl_seg->func_indexes + src_offset, length * sizeof(uint32));
  2025. }
  2026. void
  2027. aot_table_copy(AOTModuleInstance *module_inst, uint32 src_tbl_idx,
  2028. uint32 dst_tbl_idx, uint32 length, uint32 src_offset,
  2029. uint32 dst_offset)
  2030. {
  2031. AOTTableInstance *src_tbl_inst, *dst_tbl_inst;
  2032. src_tbl_inst = module_inst->tables[src_tbl_idx];
  2033. bh_assert(src_tbl_inst);
  2034. dst_tbl_inst = module_inst->tables[dst_tbl_idx];
  2035. bh_assert(dst_tbl_inst);
  2036. if ((uint64)dst_offset + length > dst_tbl_inst->cur_size
  2037. || (uint64)src_offset + length > src_tbl_inst->cur_size) {
  2038. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2039. return;
  2040. }
  2041. /* if src_offset >= dst_offset, copy from front to back */
  2042. /* if src_offset < dst_offset, copy from back to front */
  2043. /* merge all together */
  2044. bh_memmove_s((uint8 *)dst_tbl_inst + offsetof(AOTTableInstance, elems)
  2045. + dst_offset * sizeof(uint32),
  2046. (dst_tbl_inst->cur_size - dst_offset) * sizeof(uint32),
  2047. (uint8 *)src_tbl_inst + offsetof(AOTTableInstance, elems)
  2048. + src_offset * sizeof(uint32),
  2049. length * sizeof(uint32));
  2050. }
  2051. void
  2052. aot_table_fill(AOTModuleInstance *module_inst, uint32 tbl_idx, uint32 length,
  2053. uint32 val, uint32 data_offset)
  2054. {
  2055. AOTTableInstance *tbl_inst;
  2056. tbl_inst = module_inst->tables[tbl_idx];
  2057. bh_assert(tbl_inst);
  2058. if (data_offset + length > tbl_inst->cur_size) {
  2059. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2060. return;
  2061. }
  2062. for (; length != 0; data_offset++, length--) {
  2063. tbl_inst->elems[data_offset] = val;
  2064. }
  2065. }
  2066. uint32
  2067. aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx,
  2068. uint32 inc_entries, uint32 init_val)
  2069. {
  2070. uint32 entry_count, i, orig_tbl_sz;
  2071. AOTTableInstance *tbl_inst;
  2072. tbl_inst = module_inst->tables[tbl_idx];
  2073. if (!tbl_inst) {
  2074. return (uint32)-1;
  2075. }
  2076. orig_tbl_sz = tbl_inst->cur_size;
  2077. if (!inc_entries) {
  2078. return orig_tbl_sz;
  2079. }
  2080. if (tbl_inst->cur_size > UINT32_MAX - inc_entries) {
  2081. return (uint32)-1;
  2082. }
  2083. entry_count = tbl_inst->cur_size + inc_entries;
  2084. if (entry_count > tbl_inst->max_size) {
  2085. return (uint32)-1;
  2086. }
  2087. /* fill in */
  2088. for (i = 0; i < inc_entries; ++i) {
  2089. tbl_inst->elems[tbl_inst->cur_size + i] = init_val;
  2090. }
  2091. tbl_inst->cur_size = entry_count;
  2092. return orig_tbl_sz;
  2093. }
  2094. #endif /* WASM_ENABLE_REF_TYPES != 0 */
  2095. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
  2096. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  2097. static const char *
  2098. lookup_func_name(const char **func_names, uint32 *func_indexes,
  2099. uint32 func_index_count, uint32 func_index)
  2100. {
  2101. int64 low = 0, mid;
  2102. int64 high = func_index_count - 1;
  2103. if (!func_names || !func_indexes || func_index_count == 0)
  2104. return NULL;
  2105. while (low <= high) {
  2106. mid = (low + high) / 2;
  2107. if (func_index == func_indexes[mid]) {
  2108. return func_names[mid];
  2109. }
  2110. else if (func_index < func_indexes[mid])
  2111. high = mid - 1;
  2112. else
  2113. low = mid + 1;
  2114. }
  2115. return NULL;
  2116. }
  2117. #endif /* WASM_ENABLE_CUSTOM_NAME_SECTION != 0 */
  2118. static const char *
  2119. get_func_name_from_index(const AOTModuleInstance *module_inst,
  2120. uint32 func_index)
  2121. {
  2122. const char *func_name = NULL;
  2123. AOTModule *module = (AOTModule *)module_inst->module;
  2124. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  2125. if ((func_name =
  2126. lookup_func_name(module->aux_func_names, module->aux_func_indexes,
  2127. module->aux_func_name_count, func_index))) {
  2128. return func_name;
  2129. }
  2130. #endif
  2131. if (func_index < module->import_func_count) {
  2132. func_name = module->import_funcs[func_index].func_name;
  2133. }
  2134. else {
  2135. uint32 i;
  2136. for (i = 0; i < module->export_count; i++) {
  2137. AOTExport export = module->exports[i];
  2138. if (export.index == func_index && export.kind == EXPORT_KIND_FUNC) {
  2139. func_name = export.name;
  2140. break;
  2141. }
  2142. }
  2143. }
  2144. return func_name;
  2145. }
  2146. bool
  2147. aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
  2148. {
  2149. AOTFrame *frame =
  2150. wasm_exec_env_alloc_wasm_frame(exec_env, sizeof(AOTFrame));
  2151. #if WASM_ENABLE_PERF_PROFILING != 0
  2152. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  2153. AOTFuncPerfProfInfo *func_perf_prof =
  2154. module_inst->func_perf_profilings + func_index;
  2155. #endif
  2156. if (!frame) {
  2157. aot_set_exception((AOTModuleInstance *)exec_env->module_inst,
  2158. "auxiliary call stack overflow");
  2159. return false;
  2160. }
  2161. #if WASM_ENABLE_PERF_PROFILING != 0
  2162. frame->time_started = os_time_get_boot_microsecond();
  2163. frame->func_perf_prof_info = func_perf_prof;
  2164. #endif
  2165. frame->prev_frame = (AOTFrame *)exec_env->cur_frame;
  2166. exec_env->cur_frame = (struct WASMInterpFrame *)frame;
  2167. frame->func_index = func_index;
  2168. return true;
  2169. }
  2170. void
  2171. aot_free_frame(WASMExecEnv *exec_env)
  2172. {
  2173. AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame;
  2174. AOTFrame *prev_frame = cur_frame->prev_frame;
  2175. #if WASM_ENABLE_PERF_PROFILING != 0
  2176. cur_frame->func_perf_prof_info->total_exec_time +=
  2177. os_time_get_boot_microsecond() - cur_frame->time_started;
  2178. cur_frame->func_perf_prof_info->total_exec_cnt++;
  2179. #endif
  2180. wasm_exec_env_free_wasm_frame(exec_env, cur_frame);
  2181. exec_env->cur_frame = (struct WASMInterpFrame *)prev_frame;
  2182. }
  2183. #endif /* end of (WASM_ENABLE_DUMP_CALL_STACK != 0) \
  2184. || (WASM_ENABLE_PERF_PROFILING != 0) */
  2185. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  2186. bool
  2187. aot_create_call_stack(struct WASMExecEnv *exec_env)
  2188. {
  2189. AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame,
  2190. *first_frame = cur_frame;
  2191. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  2192. uint32 n = 0;
  2193. while (cur_frame) {
  2194. cur_frame = cur_frame->prev_frame;
  2195. n++;
  2196. }
  2197. /* release previous stack frames and create new ones */
  2198. if (!bh_vector_destroy(module_inst->frames)
  2199. || !bh_vector_init(module_inst->frames, n, sizeof(WASMCApiFrame),
  2200. false)) {
  2201. return false;
  2202. }
  2203. cur_frame = first_frame;
  2204. while (cur_frame) {
  2205. WASMCApiFrame frame = { 0 };
  2206. frame.instance = module_inst;
  2207. frame.module_offset = 0;
  2208. frame.func_index = cur_frame->func_index;
  2209. frame.func_offset = 0;
  2210. frame.func_name_wp =
  2211. get_func_name_from_index(module_inst, cur_frame->func_index);
  2212. if (!bh_vector_append(module_inst->frames, &frame)) {
  2213. bh_vector_destroy(module_inst->frames);
  2214. return false;
  2215. }
  2216. cur_frame = cur_frame->prev_frame;
  2217. }
  2218. return true;
  2219. }
  2220. #define PRINT_OR_DUMP() \
  2221. do { \
  2222. total_len += \
  2223. wasm_runtime_dump_line_buf_impl(line_buf, print, &buf, &len); \
  2224. if ((!print) && buf && (len == 0)) { \
  2225. return total_len; \
  2226. } \
  2227. } while (0)
  2228. uint32
  2229. aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len)
  2230. {
  2231. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  2232. uint32 n = 0, total_len = 0, total_frames;
  2233. /* reserve 256 bytes for line buffer, any line longer than 256 bytes
  2234. * will be truncated */
  2235. char line_buf[256];
  2236. if (!module_inst->frames) {
  2237. return 0;
  2238. }
  2239. total_frames = (uint32)bh_vector_size(module_inst->frames);
  2240. if (total_frames == 0) {
  2241. return 0;
  2242. }
  2243. snprintf(line_buf, sizeof(line_buf), "\n");
  2244. PRINT_OR_DUMP();
  2245. while (n < total_frames) {
  2246. WASMCApiFrame frame = { 0 };
  2247. uint32 line_length, i;
  2248. if (!bh_vector_get(module_inst->frames, n, &frame)) {
  2249. return 0;
  2250. }
  2251. /* function name not exported, print number instead */
  2252. if (frame.func_name_wp == NULL) {
  2253. line_length = snprintf(line_buf, sizeof(line_buf), "#%02d $f%d\n",
  2254. n, frame.func_index);
  2255. }
  2256. else {
  2257. line_length = snprintf(line_buf, sizeof(line_buf), "#%02d %s\n", n,
  2258. frame.func_name_wp);
  2259. }
  2260. if (line_length >= sizeof(line_buf)) {
  2261. uint32 line_buffer_len = sizeof(line_buf);
  2262. /* If line too long, ensure the last character is '\n' */
  2263. for (i = line_buffer_len - 5; i < line_buffer_len - 2; i++) {
  2264. line_buf[i] = '.';
  2265. }
  2266. line_buf[line_buffer_len - 2] = '\n';
  2267. }
  2268. PRINT_OR_DUMP();
  2269. n++;
  2270. }
  2271. snprintf(line_buf, sizeof(line_buf), "\n");
  2272. PRINT_OR_DUMP();
  2273. return total_len + 1;
  2274. }
  2275. #endif /* end of WASM_ENABLE_DUMP_CALL_STACK */
  2276. #if WASM_ENABLE_PERF_PROFILING != 0
  2277. void
  2278. aot_dump_perf_profiling(const AOTModuleInstance *module_inst)
  2279. {
  2280. AOTFuncPerfProfInfo *perf_prof =
  2281. (AOTFuncPerfProfInfo *)module_inst->func_perf_profilings;
  2282. AOTModule *module = (AOTModule *)module_inst->module;
  2283. uint32 total_func_count = module->import_func_count + module->func_count, i;
  2284. const char *func_name;
  2285. os_printf("Performance profiler data:\n");
  2286. for (i = 0; i < total_func_count; i++, perf_prof++) {
  2287. func_name = get_func_name_from_index(module_inst, i);
  2288. if (func_name)
  2289. os_printf(" func %s, execution time: %.3f ms, execution count: %d "
  2290. "times\n",
  2291. func_name, perf_prof->total_exec_time / 1000.0f,
  2292. perf_prof->total_exec_cnt);
  2293. else
  2294. os_printf(" func %d, execution time: %.3f ms, execution count: %d "
  2295. "times\n",
  2296. i, perf_prof->total_exec_time / 1000.0f,
  2297. perf_prof->total_exec_cnt);
  2298. }
  2299. }
  2300. #endif /* end of WASM_ENABLE_PERF_PROFILING */