aot_runtime.c 114 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373
  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(WASMExecEnv, native_stack_top_min)
  31. == 9 * sizeof(uintptr_t));
  32. bh_static_assert(offsetof(AOTModuleInstance, memories) == 1 * sizeof(uint64));
  33. bh_static_assert(offsetof(AOTModuleInstance, func_ptrs) == 5 * sizeof(uint64));
  34. bh_static_assert(offsetof(AOTModuleInstance, func_type_indexes)
  35. == 6 * sizeof(uint64));
  36. bh_static_assert(offsetof(AOTModuleInstance, cur_exception)
  37. == 13 * sizeof(uint64));
  38. bh_static_assert(offsetof(AOTModuleInstance, global_table_data)
  39. == 13 * sizeof(uint64) + 128 + 11 * sizeof(uint64));
  40. static void
  41. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  42. {
  43. if (error_buf != NULL) {
  44. snprintf(error_buf, error_buf_size, "AOT module instantiate failed: %s",
  45. string);
  46. }
  47. }
  48. static void
  49. set_error_buf_v(char *error_buf, uint32 error_buf_size, const char *format, ...)
  50. {
  51. va_list args;
  52. char buf[128];
  53. if (error_buf != NULL) {
  54. va_start(args, format);
  55. vsnprintf(buf, sizeof(buf), format, args);
  56. va_end(args);
  57. snprintf(error_buf, error_buf_size, "AOT module instantiate failed: %s",
  58. buf);
  59. }
  60. }
  61. static void *
  62. runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
  63. {
  64. void *mem;
  65. if (size >= UINT32_MAX || !(mem = wasm_runtime_malloc((uint32)size))) {
  66. set_error_buf(error_buf, error_buf_size, "allocate memory failed");
  67. return NULL;
  68. }
  69. memset(mem, 0, (uint32)size);
  70. return mem;
  71. }
  72. static bool
  73. check_global_init_expr(const AOTModule *module, uint32 global_index,
  74. char *error_buf, uint32 error_buf_size)
  75. {
  76. if (global_index >= module->import_global_count + module->global_count) {
  77. set_error_buf_v(error_buf, error_buf_size, "unknown global %d",
  78. global_index);
  79. return false;
  80. }
  81. /**
  82. * Currently, constant expressions occurring as initializers of
  83. * globals are further constrained in that contained global.get
  84. * instructions are only allowed to refer to imported globals.
  85. *
  86. * And initializer expression cannot reference a mutable global.
  87. */
  88. if (global_index >= module->import_global_count
  89. || module->import_globals->is_mutable) {
  90. set_error_buf(error_buf, error_buf_size,
  91. "constant expression required");
  92. return false;
  93. }
  94. return true;
  95. }
  96. static void
  97. init_global_data(uint8 *global_data, uint8 type, WASMValue *initial_value)
  98. {
  99. switch (type) {
  100. case VALUE_TYPE_I32:
  101. case VALUE_TYPE_F32:
  102. #if WASM_ENABLE_REF_TYPES != 0
  103. case VALUE_TYPE_FUNCREF:
  104. case VALUE_TYPE_EXTERNREF:
  105. #endif
  106. *(int32 *)global_data = initial_value->i32;
  107. break;
  108. case VALUE_TYPE_I64:
  109. case VALUE_TYPE_F64:
  110. bh_memcpy_s(global_data, sizeof(int64), &initial_value->i64,
  111. sizeof(int64));
  112. break;
  113. #if WASM_ENABLE_SIMD != 0
  114. case VALUE_TYPE_V128:
  115. bh_memcpy_s(global_data, sizeof(V128), &initial_value->v128,
  116. sizeof(V128));
  117. break;
  118. #endif
  119. default:
  120. bh_assert(0);
  121. }
  122. }
  123. static bool
  124. global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  125. char *error_buf, uint32 error_buf_size)
  126. {
  127. uint32 i;
  128. InitializerExpression *init_expr;
  129. uint8 *p = module_inst->global_data;
  130. AOTImportGlobal *import_global = module->import_globals;
  131. AOTGlobal *global = module->globals;
  132. /* Initialize import global data */
  133. for (i = 0; i < module->import_global_count; i++, import_global++) {
  134. bh_assert(import_global->data_offset
  135. == (uint32)(p - module_inst->global_data));
  136. init_global_data(p, import_global->type,
  137. &import_global->global_data_linked);
  138. p += import_global->size;
  139. }
  140. /* Initialize defined global data */
  141. for (i = 0; i < module->global_count; i++, global++) {
  142. bh_assert(global->data_offset
  143. == (uint32)(p - module_inst->global_data));
  144. init_expr = &global->init_expr;
  145. switch (init_expr->init_expr_type) {
  146. case INIT_EXPR_TYPE_GET_GLOBAL:
  147. {
  148. if (!check_global_init_expr(module, init_expr->u.global_index,
  149. error_buf, error_buf_size)) {
  150. return false;
  151. }
  152. init_global_data(
  153. p, global->type,
  154. &module->import_globals[init_expr->u.global_index]
  155. .global_data_linked);
  156. break;
  157. }
  158. #if WASM_ENABLE_REF_TYPES != 0
  159. case INIT_EXPR_TYPE_REFNULL_CONST:
  160. {
  161. *(uint32 *)p = NULL_REF;
  162. break;
  163. }
  164. #endif
  165. default:
  166. {
  167. init_global_data(p, global->type, &init_expr->u);
  168. break;
  169. }
  170. }
  171. p += global->size;
  172. }
  173. bh_assert(module_inst->global_data_size
  174. == (uint32)(p - module_inst->global_data));
  175. return true;
  176. }
  177. static bool
  178. tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  179. AOTTableInstance *first_tbl_inst, char *error_buf,
  180. uint32 error_buf_size)
  181. {
  182. uint32 i, global_index, global_data_offset, base_offset, length;
  183. uint64 total_size;
  184. AOTTableInitData *table_seg;
  185. AOTTableInstance *tbl_inst = first_tbl_inst;
  186. total_size = (uint64)sizeof(WASMTableInstance *) * module_inst->table_count;
  187. if (total_size > 0
  188. && !(module_inst->tables =
  189. runtime_malloc(total_size, error_buf, error_buf_size))) {
  190. return false;
  191. }
  192. /*
  193. * treat import table like a local one until we enable module linking
  194. * in AOT mode
  195. */
  196. for (i = 0; i != module_inst->table_count; ++i) {
  197. if (i < module->import_table_count) {
  198. AOTImportTable *import_table = module->import_tables + i;
  199. tbl_inst->cur_size = import_table->table_init_size;
  200. tbl_inst->max_size =
  201. aot_get_imp_tbl_data_slots(import_table, false);
  202. }
  203. else {
  204. AOTTable *table = module->tables + (i - module->import_table_count);
  205. tbl_inst->cur_size = table->table_init_size;
  206. tbl_inst->max_size = aot_get_tbl_data_slots(table, false);
  207. }
  208. /* Set all elements to -1 to mark them as uninitialized elements */
  209. memset(tbl_inst->elems, 0xff, sizeof(uint32) * tbl_inst->max_size);
  210. module_inst->tables[i] = tbl_inst;
  211. tbl_inst = (AOTTableInstance *)((uint8 *)tbl_inst
  212. + offsetof(AOTTableInstance, elems)
  213. + sizeof(uint32) * tbl_inst->max_size);
  214. }
  215. /* fill table with element segment content */
  216. for (i = 0; i < module->table_init_data_count; i++) {
  217. table_seg = module->table_init_data_list[i];
  218. #if WASM_ENABLE_REF_TYPES != 0
  219. if (!wasm_elem_is_active(table_seg->mode))
  220. continue;
  221. #endif
  222. bh_assert(table_seg->table_index < module_inst->table_count);
  223. tbl_inst = module_inst->tables[table_seg->table_index];
  224. bh_assert(tbl_inst);
  225. #if WASM_ENABLE_REF_TYPES != 0
  226. bh_assert(
  227. table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
  228. || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL
  229. || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_FUNCREF_CONST
  230. || table_seg->offset.init_expr_type
  231. == INIT_EXPR_TYPE_REFNULL_CONST);
  232. #else
  233. bh_assert(table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
  234. || table_seg->offset.init_expr_type
  235. == INIT_EXPR_TYPE_GET_GLOBAL);
  236. #endif
  237. /* Resolve table data base offset */
  238. if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  239. global_index = table_seg->offset.u.global_index;
  240. if (!check_global_init_expr(module, global_index, error_buf,
  241. error_buf_size)) {
  242. return false;
  243. }
  244. if (global_index < module->import_global_count)
  245. global_data_offset =
  246. module->import_globals[global_index].data_offset;
  247. else
  248. global_data_offset =
  249. module->globals[global_index - module->import_global_count]
  250. .data_offset;
  251. base_offset =
  252. *(uint32 *)(module_inst->global_data + global_data_offset);
  253. }
  254. else
  255. base_offset = (uint32)table_seg->offset.u.i32;
  256. /* Copy table data */
  257. /* base_offset only since length might negative */
  258. if (base_offset > tbl_inst->cur_size) {
  259. #if WASM_ENABLE_REF_TYPES != 0
  260. set_error_buf(error_buf, error_buf_size,
  261. "out of bounds table access");
  262. #else
  263. set_error_buf(error_buf, error_buf_size,
  264. "elements segment does not fit");
  265. #endif
  266. return false;
  267. }
  268. /* base_offset + length(could be zero) */
  269. length = table_seg->func_index_count;
  270. if (base_offset + length > tbl_inst->cur_size) {
  271. #if WASM_ENABLE_REF_TYPES != 0
  272. set_error_buf(error_buf, error_buf_size,
  273. "out of bounds table access");
  274. #else
  275. set_error_buf(error_buf, error_buf_size,
  276. "elements segment does not fit");
  277. #endif
  278. return false;
  279. }
  280. /**
  281. * Check function index in the current module inst for now.
  282. * will check the linked table inst owner in future
  283. */
  284. bh_memcpy_s(tbl_inst->elems + base_offset,
  285. (tbl_inst->max_size - base_offset) * sizeof(uint32),
  286. table_seg->func_indexes, length * sizeof(uint32));
  287. }
  288. return true;
  289. }
  290. static void
  291. memories_deinstantiate(AOTModuleInstance *module_inst)
  292. {
  293. uint32 i;
  294. AOTMemoryInstance *memory_inst;
  295. for (i = 0; i < module_inst->memory_count; i++) {
  296. memory_inst = module_inst->memories[i];
  297. if (memory_inst) {
  298. #if WASM_ENABLE_SHARED_MEMORY != 0
  299. if (memory_inst->is_shared) {
  300. int32 ref_count = shared_memory_dec_reference(
  301. (WASMModuleCommon *)module_inst->module);
  302. bh_assert(ref_count >= 0);
  303. /* if the reference count is not zero,
  304. don't free the memory */
  305. if (ref_count > 0)
  306. continue;
  307. }
  308. #endif
  309. if (memory_inst->heap_handle) {
  310. mem_allocator_destroy(memory_inst->heap_handle);
  311. wasm_runtime_free(memory_inst->heap_handle);
  312. }
  313. if (memory_inst->memory_data) {
  314. #ifndef OS_ENABLE_HW_BOUND_CHECK
  315. wasm_runtime_free(memory_inst->memory_data);
  316. #else
  317. #ifdef BH_PLATFORM_WINDOWS
  318. os_mem_decommit(memory_inst->memory_data,
  319. memory_inst->num_bytes_per_page
  320. * memory_inst->cur_page_count);
  321. #endif
  322. os_munmap(memory_inst->memory_data, 8 * (uint64)BH_GB);
  323. #endif
  324. }
  325. }
  326. }
  327. wasm_runtime_free(module_inst->memories);
  328. }
  329. static AOTMemoryInstance *
  330. memory_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  331. AOTMemoryInstance *memory_inst, AOTMemory *memory,
  332. uint32 heap_size, char *error_buf, uint32 error_buf_size)
  333. {
  334. void *heap_handle;
  335. uint32 num_bytes_per_page = memory->num_bytes_per_page;
  336. uint32 init_page_count = memory->mem_init_page_count;
  337. uint32 max_page_count = memory->mem_max_page_count;
  338. uint32 inc_page_count, aux_heap_base, global_idx;
  339. uint32 bytes_of_last_page, bytes_to_page_end;
  340. uint32 heap_offset = num_bytes_per_page * init_page_count;
  341. uint64 total_size;
  342. uint8 *p = NULL, *global_addr;
  343. #ifdef OS_ENABLE_HW_BOUND_CHECK
  344. uint8 *mapped_mem;
  345. uint64 map_size = 8 * (uint64)BH_GB;
  346. uint64 page_size = os_getpagesize();
  347. #endif
  348. #if WASM_ENABLE_SHARED_MEMORY != 0
  349. bool is_shared_memory = memory->memory_flags & 0x02 ? true : false;
  350. /* Shared memory */
  351. if (is_shared_memory) {
  352. AOTMemoryInstance *shared_memory_instance;
  353. WASMSharedMemNode *node =
  354. wasm_module_get_shared_memory((WASMModuleCommon *)module);
  355. /* If the memory of this module has been instantiated,
  356. return the memory instance directly */
  357. if (node) {
  358. uint32 ref_count;
  359. ref_count = shared_memory_inc_reference((WASMModuleCommon *)module);
  360. bh_assert(ref_count > 0);
  361. shared_memory_instance =
  362. (AOTMemoryInstance *)shared_memory_get_memory_inst(node);
  363. bh_assert(shared_memory_instance);
  364. (void)ref_count;
  365. return shared_memory_instance;
  366. }
  367. }
  368. #endif
  369. if (heap_size > 0 && module->malloc_func_index != (uint32)-1
  370. && module->free_func_index != (uint32)-1) {
  371. /* Disable app heap, use malloc/free function exported
  372. by wasm app to allocate/free memory instead */
  373. heap_size = 0;
  374. }
  375. if (init_page_count == max_page_count && init_page_count == 1) {
  376. /* If only one page and at most one page, we just append
  377. the app heap to the end of linear memory, enlarge the
  378. num_bytes_per_page, and don't change the page count */
  379. heap_offset = num_bytes_per_page;
  380. num_bytes_per_page += heap_size;
  381. if (num_bytes_per_page < heap_size) {
  382. set_error_buf(error_buf, error_buf_size,
  383. "failed to insert app heap into linear memory, "
  384. "try using `--heap_size=0` option");
  385. return NULL;
  386. }
  387. }
  388. else if (heap_size > 0) {
  389. if (init_page_count == max_page_count && init_page_count == 0) {
  390. /* If the memory data size is always 0, we resize it to
  391. one page for app heap */
  392. num_bytes_per_page = heap_size;
  393. heap_offset = 0;
  394. inc_page_count = 1;
  395. }
  396. else if (module->aux_heap_base_global_index != (uint32)-1
  397. && module->aux_heap_base
  398. < num_bytes_per_page * init_page_count) {
  399. /* Insert app heap before __heap_base */
  400. aux_heap_base = module->aux_heap_base;
  401. bytes_of_last_page = aux_heap_base % num_bytes_per_page;
  402. if (bytes_of_last_page == 0)
  403. bytes_of_last_page = num_bytes_per_page;
  404. bytes_to_page_end = num_bytes_per_page - bytes_of_last_page;
  405. inc_page_count =
  406. (heap_size - bytes_to_page_end + num_bytes_per_page - 1)
  407. / num_bytes_per_page;
  408. heap_offset = aux_heap_base;
  409. aux_heap_base += heap_size;
  410. bytes_of_last_page = aux_heap_base % num_bytes_per_page;
  411. if (bytes_of_last_page == 0)
  412. bytes_of_last_page = num_bytes_per_page;
  413. bytes_to_page_end = num_bytes_per_page - bytes_of_last_page;
  414. if (bytes_to_page_end < 1 * BH_KB) {
  415. aux_heap_base += 1 * BH_KB;
  416. inc_page_count++;
  417. }
  418. /* Adjust __heap_base global value */
  419. global_idx = module->aux_heap_base_global_index
  420. - module->import_global_count;
  421. global_addr = module_inst->global_data
  422. + module->globals[global_idx].data_offset;
  423. *(uint32 *)global_addr = aux_heap_base;
  424. LOG_VERBOSE("Reset __heap_base global to %u", aux_heap_base);
  425. }
  426. else {
  427. /* Insert app heap before new page */
  428. inc_page_count =
  429. (heap_size + num_bytes_per_page - 1) / num_bytes_per_page;
  430. heap_offset = num_bytes_per_page * init_page_count;
  431. heap_size = num_bytes_per_page * inc_page_count;
  432. if (heap_size > 0)
  433. heap_size -= 1 * BH_KB;
  434. }
  435. init_page_count += inc_page_count;
  436. max_page_count += inc_page_count;
  437. if (init_page_count > DEFAULT_MAX_PAGES) {
  438. set_error_buf(error_buf, error_buf_size,
  439. "failed to insert app heap into linear memory, "
  440. "try using `--heap_size=0` option");
  441. return NULL;
  442. }
  443. else if (init_page_count == DEFAULT_MAX_PAGES) {
  444. num_bytes_per_page = UINT32_MAX;
  445. init_page_count = max_page_count = 1;
  446. }
  447. if (max_page_count > DEFAULT_MAX_PAGES)
  448. max_page_count = DEFAULT_MAX_PAGES;
  449. }
  450. LOG_VERBOSE("Memory instantiate:");
  451. LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
  452. num_bytes_per_page, init_page_count, max_page_count);
  453. LOG_VERBOSE(" data offset: %u, stack size: %d", module->aux_data_end,
  454. module->aux_stack_size);
  455. LOG_VERBOSE(" heap offset: %u, heap size: %d\n", heap_offset, heap_size);
  456. total_size = (uint64)num_bytes_per_page * init_page_count;
  457. #if WASM_ENABLE_SHARED_MEMORY != 0
  458. if (is_shared_memory) {
  459. /* Allocate max page for shared memory */
  460. total_size = (uint64)num_bytes_per_page * max_page_count;
  461. }
  462. #endif
  463. bh_assert(total_size <= UINT32_MAX);
  464. #ifndef OS_ENABLE_HW_BOUND_CHECK
  465. /* Allocate memory */
  466. if (total_size > 0
  467. && !(p = runtime_malloc(total_size, error_buf, error_buf_size))) {
  468. return NULL;
  469. }
  470. #else
  471. total_size = (total_size + page_size - 1) & ~(page_size - 1);
  472. /* Totally 8G is mapped, the opcode load/store address range is 0 to 8G:
  473. * ea = i + memarg.offset
  474. * both i and memarg.offset are u32 in range 0 to 4G
  475. * so the range of ea is 0 to 8G
  476. */
  477. if (!(p = mapped_mem =
  478. os_mmap(NULL, map_size, MMAP_PROT_NONE, MMAP_MAP_NONE))) {
  479. set_error_buf(error_buf, error_buf_size, "mmap memory failed");
  480. return NULL;
  481. }
  482. #ifdef BH_PLATFORM_WINDOWS
  483. if (!os_mem_commit(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE)) {
  484. set_error_buf(error_buf, error_buf_size, "commit memory failed");
  485. os_munmap(mapped_mem, map_size);
  486. return NULL;
  487. }
  488. #endif
  489. if (os_mprotect(p, total_size, MMAP_PROT_READ | MMAP_PROT_WRITE) != 0) {
  490. set_error_buf(error_buf, error_buf_size, "mprotect memory failed");
  491. #ifdef BH_PLATFORM_WINDOWS
  492. os_mem_decommit(p, total_size);
  493. #endif
  494. os_munmap(mapped_mem, map_size);
  495. return NULL;
  496. }
  497. /* Newly allocated pages are filled with zero by the OS, we don't fill it
  498. * again here */
  499. #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
  500. if (total_size > UINT32_MAX)
  501. total_size = UINT32_MAX;
  502. memory_inst->module_type = Wasm_Module_AoT;
  503. memory_inst->num_bytes_per_page = num_bytes_per_page;
  504. memory_inst->cur_page_count = init_page_count;
  505. memory_inst->max_page_count = max_page_count;
  506. memory_inst->memory_data_size = (uint32)total_size;
  507. /* Init memory info */
  508. memory_inst->memory_data = p;
  509. memory_inst->memory_data_end = p + (uint32)total_size;
  510. /* Initialize heap info */
  511. memory_inst->heap_data = p + heap_offset;
  512. memory_inst->heap_data_end = p + heap_offset + heap_size;
  513. if (heap_size > 0) {
  514. uint32 heap_struct_size = mem_allocator_get_heap_struct_size();
  515. if (!(heap_handle = runtime_malloc((uint64)heap_struct_size, error_buf,
  516. error_buf_size))) {
  517. goto fail1;
  518. }
  519. memory_inst->heap_handle = heap_handle;
  520. if (!mem_allocator_create_with_struct_and_pool(
  521. heap_handle, heap_struct_size, memory_inst->heap_data,
  522. heap_size)) {
  523. set_error_buf(error_buf, error_buf_size, "init app heap failed");
  524. goto fail2;
  525. }
  526. }
  527. if (total_size > 0) {
  528. #if UINTPTR_MAX == UINT64_MAX
  529. memory_inst->mem_bound_check_1byte.u64 = total_size - 1;
  530. memory_inst->mem_bound_check_2bytes.u64 = total_size - 2;
  531. memory_inst->mem_bound_check_4bytes.u64 = total_size - 4;
  532. memory_inst->mem_bound_check_8bytes.u64 = total_size - 8;
  533. memory_inst->mem_bound_check_16bytes.u64 = total_size - 16;
  534. #else
  535. memory_inst->mem_bound_check_1byte.u32[0] = (uint32)total_size - 1;
  536. memory_inst->mem_bound_check_2bytes.u32[0] = (uint32)total_size - 2;
  537. memory_inst->mem_bound_check_4bytes.u32[0] = (uint32)total_size - 4;
  538. memory_inst->mem_bound_check_8bytes.u32[0] = (uint32)total_size - 8;
  539. memory_inst->mem_bound_check_16bytes.u32[0] = (uint32)total_size - 16;
  540. #endif
  541. }
  542. #if WASM_ENABLE_SHARED_MEMORY != 0
  543. if (is_shared_memory) {
  544. memory_inst->is_shared = true;
  545. if (!shared_memory_set_memory_inst(
  546. (WASMModuleCommon *)module,
  547. (WASMMemoryInstanceCommon *)memory_inst)) {
  548. set_error_buf(error_buf, error_buf_size, "allocate memory failed");
  549. goto fail3;
  550. }
  551. }
  552. #endif
  553. return memory_inst;
  554. #if WASM_ENABLE_SHARED_MEMORY != 0
  555. fail3:
  556. if (heap_size > 0)
  557. mem_allocator_destroy(memory_inst->heap_handle);
  558. #endif
  559. fail2:
  560. if (heap_size > 0)
  561. wasm_runtime_free(memory_inst->heap_handle);
  562. fail1:
  563. #ifndef OS_ENABLE_HW_BOUND_CHECK
  564. if (memory_inst->memory_data)
  565. wasm_runtime_free(memory_inst->memory_data);
  566. #else
  567. #ifdef BH_PLATFORM_WINDOWS
  568. if (memory_inst->memory_data)
  569. os_mem_decommit(p, total_size);
  570. #endif
  571. os_munmap(mapped_mem, map_size);
  572. #endif
  573. memory_inst->memory_data = NULL;
  574. return NULL;
  575. }
  576. static AOTMemoryInstance *
  577. aot_get_default_memory(AOTModuleInstance *module_inst)
  578. {
  579. if (module_inst->memories)
  580. return module_inst->memories[0];
  581. else
  582. return NULL;
  583. }
  584. static bool
  585. memories_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  586. uint32 heap_size, char *error_buf, uint32 error_buf_size)
  587. {
  588. uint32 global_index, global_data_offset, base_offset, length;
  589. uint32 i, memory_count = module->memory_count;
  590. AOTMemoryInstance *memories, *memory_inst;
  591. AOTMemInitData *data_seg;
  592. uint64 total_size;
  593. module_inst->memory_count = memory_count;
  594. total_size = sizeof(AOTMemoryInstance *) * (uint64)memory_count;
  595. if (!(module_inst->memories =
  596. runtime_malloc(total_size, error_buf, error_buf_size))) {
  597. return false;
  598. }
  599. memories = module_inst->global_table_data.memory_instances;
  600. for (i = 0; i < memory_count; i++, memories++) {
  601. memory_inst = memory_instantiate(module_inst, module, memories,
  602. &module->memories[i], heap_size,
  603. error_buf, error_buf_size);
  604. if (!memory_inst) {
  605. return false;
  606. }
  607. module_inst->memories[i] = memory_inst;
  608. }
  609. /* Get default memory instance */
  610. memory_inst = aot_get_default_memory(module_inst);
  611. if (!memory_inst) {
  612. /* Ignore setting memory init data if no memory inst is created */
  613. return true;
  614. }
  615. for (i = 0; i < module->mem_init_data_count; i++) {
  616. data_seg = module->mem_init_data_list[i];
  617. #if WASM_ENABLE_BULK_MEMORY != 0
  618. if (data_seg->is_passive)
  619. continue;
  620. #endif
  621. bh_assert(data_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
  622. || data_seg->offset.init_expr_type
  623. == INIT_EXPR_TYPE_GET_GLOBAL);
  624. /* Resolve memory data base offset */
  625. if (data_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  626. global_index = data_seg->offset.u.global_index;
  627. if (!check_global_init_expr(module, global_index, error_buf,
  628. error_buf_size)) {
  629. return false;
  630. }
  631. if (global_index < module->import_global_count)
  632. global_data_offset =
  633. module->import_globals[global_index].data_offset;
  634. else
  635. global_data_offset =
  636. module->globals[global_index - module->import_global_count]
  637. .data_offset;
  638. base_offset =
  639. *(uint32 *)(module_inst->global_data + global_data_offset);
  640. }
  641. else {
  642. base_offset = (uint32)data_seg->offset.u.i32;
  643. }
  644. /* Copy memory data */
  645. bh_assert(memory_inst->memory_data
  646. || memory_inst->memory_data_size == 0);
  647. /* Check memory data */
  648. /* check offset since length might negative */
  649. if (base_offset > memory_inst->memory_data_size) {
  650. LOG_DEBUG("base_offset(%d) > memory_data_size(%d)", base_offset,
  651. memory_inst->memory_data_size);
  652. #if WASM_ENABLE_REF_TYPES != 0
  653. set_error_buf(error_buf, error_buf_size,
  654. "out of bounds memory access");
  655. #else
  656. set_error_buf(error_buf, error_buf_size,
  657. "data segment does not fit");
  658. #endif
  659. return false;
  660. }
  661. /* check offset + length(could be zero) */
  662. length = data_seg->byte_count;
  663. if (base_offset + length > memory_inst->memory_data_size) {
  664. LOG_DEBUG("base_offset(%d) + length(%d) > memory_data_size(%d)",
  665. base_offset, length, memory_inst->memory_data_size);
  666. #if WASM_ENABLE_REF_TYPES != 0
  667. set_error_buf(error_buf, error_buf_size,
  668. "out of bounds memory access");
  669. #else
  670. set_error_buf(error_buf, error_buf_size,
  671. "data segment does not fit");
  672. #endif
  673. return false;
  674. }
  675. if (memory_inst->memory_data) {
  676. bh_memcpy_s((uint8 *)memory_inst->memory_data + base_offset,
  677. memory_inst->memory_data_size - base_offset,
  678. data_seg->bytes, length);
  679. }
  680. }
  681. return true;
  682. }
  683. static bool
  684. init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
  685. char *error_buf, uint32 error_buf_size)
  686. {
  687. uint32 i;
  688. void **func_ptrs;
  689. uint64 total_size = ((uint64)module->import_func_count + module->func_count)
  690. * sizeof(void *);
  691. if (module->import_func_count + module->func_count == 0)
  692. return true;
  693. /* Allocate memory */
  694. if (!(module_inst->func_ptrs =
  695. runtime_malloc(total_size, error_buf, error_buf_size))) {
  696. return false;
  697. }
  698. /* Set import function pointers */
  699. func_ptrs = (void **)module_inst->func_ptrs;
  700. for (i = 0; i < module->import_func_count; i++, func_ptrs++) {
  701. *func_ptrs = (void *)module->import_funcs[i].func_ptr_linked;
  702. if (!*func_ptrs) {
  703. const char *module_name = module->import_funcs[i].module_name;
  704. const char *field_name = module->import_funcs[i].func_name;
  705. LOG_WARNING("warning: failed to link import function (%s, %s)",
  706. module_name, field_name);
  707. }
  708. }
  709. /* Set defined function pointers */
  710. bh_memcpy_s(func_ptrs, sizeof(void *) * module->func_count,
  711. module->func_ptrs, sizeof(void *) * module->func_count);
  712. return true;
  713. }
  714. static bool
  715. init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
  716. char *error_buf, uint32 error_buf_size)
  717. {
  718. uint32 i;
  719. uint32 *func_type_index;
  720. uint64 total_size = ((uint64)module->import_func_count + module->func_count)
  721. * sizeof(uint32);
  722. if (module->import_func_count + module->func_count == 0)
  723. return true;
  724. /* Allocate memory */
  725. if (!(module_inst->func_type_indexes =
  726. runtime_malloc(total_size, error_buf, error_buf_size))) {
  727. return false;
  728. }
  729. /* Set import function type indexes */
  730. func_type_index = module_inst->func_type_indexes;
  731. for (i = 0; i < module->import_func_count; i++, func_type_index++)
  732. *func_type_index = module->import_funcs[i].func_type_index;
  733. bh_memcpy_s(func_type_index, sizeof(uint32) * module->func_count,
  734. module->func_type_indexes, sizeof(uint32) * module->func_count);
  735. return true;
  736. }
  737. static bool
  738. create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module,
  739. char *error_buf, uint32 error_buf_size)
  740. {
  741. AOTExport *exports = module->exports;
  742. AOTFunctionInstance *export_func;
  743. uint64 size;
  744. uint32 i, func_index, ftype_index;
  745. if (module_inst->export_func_count > 0) {
  746. /* Allocate memory */
  747. size = sizeof(AOTFunctionInstance)
  748. * (uint64)module_inst->export_func_count;
  749. if (!(export_func = runtime_malloc(size, error_buf, error_buf_size))) {
  750. return false;
  751. }
  752. module_inst->export_functions = (void *)export_func;
  753. for (i = 0; i < module->export_count; i++) {
  754. if (exports[i].kind == EXPORT_KIND_FUNC) {
  755. export_func->func_name = exports[i].name;
  756. export_func->func_index = exports[i].index;
  757. if (export_func->func_index < module->import_func_count) {
  758. export_func->is_import_func = true;
  759. export_func->u.func_import =
  760. &module->import_funcs[export_func->func_index];
  761. }
  762. else {
  763. export_func->is_import_func = false;
  764. func_index =
  765. export_func->func_index - module->import_func_count;
  766. ftype_index = module->func_type_indexes[func_index];
  767. export_func->u.func.func_type =
  768. module->func_types[ftype_index];
  769. export_func->u.func.func_ptr =
  770. module->func_ptrs[func_index];
  771. }
  772. export_func++;
  773. }
  774. }
  775. }
  776. return true;
  777. }
  778. static bool
  779. create_exports(AOTModuleInstance *module_inst, AOTModule *module,
  780. char *error_buf, uint32 error_buf_size)
  781. {
  782. AOTExport *exports = module->exports;
  783. uint32 i;
  784. for (i = 0; i < module->export_count; i++) {
  785. switch (exports[i].kind) {
  786. case EXPORT_KIND_FUNC:
  787. module_inst->export_func_count++;
  788. break;
  789. case EXPORT_KIND_GLOBAL:
  790. module_inst->export_global_count++;
  791. break;
  792. case EXPORT_KIND_TABLE:
  793. module_inst->export_table_count++;
  794. break;
  795. case EXPORT_KIND_MEMORY:
  796. module_inst->export_memory_count++;
  797. break;
  798. default:
  799. return false;
  800. }
  801. }
  802. return create_export_funcs(module_inst, module, error_buf, error_buf_size);
  803. }
  804. static AOTFunctionInstance *
  805. lookup_post_instantiate_func(AOTModuleInstance *module_inst,
  806. const char *func_name)
  807. {
  808. AOTFunctionInstance *func;
  809. AOTFuncType *func_type;
  810. if (!(func = aot_lookup_function(module_inst, func_name, NULL)))
  811. /* Not found */
  812. return NULL;
  813. func_type = func->u.func.func_type;
  814. if (!(func_type->param_count == 0 && func_type->result_count == 0))
  815. /* Not a valid function type, ignore it */
  816. return NULL;
  817. return func;
  818. }
  819. static bool
  820. execute_post_instantiate_functions(AOTModuleInstance *module_inst,
  821. bool is_sub_inst, WASMExecEnv *exec_env_main)
  822. {
  823. AOTModule *module = (AOTModule *)module_inst->module;
  824. AOTFunctionInstance *initialize_func = NULL;
  825. AOTFunctionInstance *post_inst_func = NULL;
  826. AOTFunctionInstance *call_ctors_func = NULL;
  827. WASMModuleInstanceCommon *module_inst_main = NULL;
  828. #ifdef OS_ENABLE_HW_BOUND_CHECK
  829. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  830. #endif
  831. WASMExecEnv *exec_env = NULL, *exec_env_created = NULL;
  832. bool ret = false;
  833. #if WASM_ENABLE_LIBC_WASI != 0
  834. /*
  835. * WASI reactor instances may assume that _initialize will be called by
  836. * the environment at most once, and that none of their other exports
  837. * are accessed before that call.
  838. */
  839. if (!is_sub_inst && module->import_wasi_api) {
  840. initialize_func =
  841. lookup_post_instantiate_func(module_inst, "_initialize");
  842. }
  843. #endif
  844. /* Execute possible "__post_instantiate" function if wasm app is
  845. compiled by emsdk's early version */
  846. if (!is_sub_inst) {
  847. post_inst_func =
  848. lookup_post_instantiate_func(module_inst, "__post_instantiate");
  849. }
  850. #if WASM_ENABLE_BULK_MEMORY != 0
  851. /* Only execute the memory init function for main instance since
  852. the data segments will be dropped once initialized */
  853. if (!is_sub_inst
  854. #if WASM_ENABLE_LIBC_WASI != 0
  855. && !module->import_wasi_api
  856. #endif
  857. ) {
  858. call_ctors_func =
  859. lookup_post_instantiate_func(module_inst, "__wasm_call_ctors");
  860. }
  861. #endif
  862. if (!module->start_function && !initialize_func && !post_inst_func
  863. && !call_ctors_func) {
  864. /* No post instantiation functions to call */
  865. return true;
  866. }
  867. if (is_sub_inst) {
  868. bh_assert(exec_env_main);
  869. #ifdef OS_ENABLE_HW_BOUND_CHECK
  870. bh_assert(exec_env_tls == exec_env_main);
  871. (void)exec_env_tls;
  872. #endif
  873. exec_env = exec_env_main;
  874. /* Temporarily replace parent exec_env's module inst to current
  875. module inst to avoid checking failure when calling the
  876. wasm functions, and ensure that the exec_env's module inst
  877. is the correct one. */
  878. module_inst_main = exec_env_main->module_inst;
  879. exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
  880. }
  881. else {
  882. /* Try using the existing exec_env */
  883. #ifdef OS_ENABLE_HW_BOUND_CHECK
  884. exec_env = exec_env_tls;
  885. #endif
  886. #if WASM_ENABLE_THREAD_MGR != 0
  887. if (!exec_env)
  888. exec_env = wasm_clusters_search_exec_env(
  889. (WASMModuleInstanceCommon *)module_inst);
  890. #endif
  891. if (!exec_env) {
  892. if (!(exec_env = exec_env_created = wasm_exec_env_create(
  893. (WASMModuleInstanceCommon *)module_inst,
  894. module_inst->default_wasm_stack_size))) {
  895. aot_set_exception(module_inst, "allocate memory failed");
  896. return false;
  897. }
  898. }
  899. else {
  900. /* Temporarily replace exec_env's module inst with current
  901. module inst to ensure that the exec_env's module inst
  902. is the correct one. */
  903. module_inst_main = exec_env->module_inst;
  904. exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
  905. }
  906. }
  907. #if defined(os_writegsbase)
  908. {
  909. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  910. if (memory_inst)
  911. /* write base addr of linear memory to GS segment register */
  912. os_writegsbase(memory_inst->memory_data);
  913. }
  914. #endif
  915. /* Execute start function for both main insance and sub instance */
  916. if (module->start_function) {
  917. AOTFunctionInstance start_func = { 0 };
  918. uint32 func_type_idx;
  919. start_func.func_name = "";
  920. start_func.func_index = module->start_func_index;
  921. start_func.is_import_func = false;
  922. func_type_idx = module->func_type_indexes[module->start_func_index
  923. - module->import_func_count];
  924. start_func.u.func.func_type = module->func_types[func_type_idx];
  925. start_func.u.func.func_ptr = module->start_function;
  926. if (!aot_call_function(exec_env, &start_func, 0, NULL)) {
  927. goto fail;
  928. }
  929. }
  930. if (initialize_func
  931. && !aot_call_function(exec_env, initialize_func, 0, NULL)) {
  932. goto fail;
  933. }
  934. if (post_inst_func
  935. && !aot_call_function(exec_env, post_inst_func, 0, NULL)) {
  936. goto fail;
  937. }
  938. if (call_ctors_func
  939. && !aot_call_function(exec_env, call_ctors_func, 0, NULL)) {
  940. goto fail;
  941. }
  942. ret = true;
  943. fail:
  944. if (is_sub_inst) {
  945. /* Restore the parent exec_env's module inst */
  946. exec_env_main->module_inst = module_inst_main;
  947. }
  948. else {
  949. if (module_inst_main)
  950. /* Restore the existing exec_env's module inst */
  951. exec_env->module_inst = module_inst_main;
  952. if (exec_env_created)
  953. wasm_exec_env_destroy(exec_env_created);
  954. }
  955. return ret;
  956. }
  957. static bool
  958. check_linked_symbol(AOTModule *module, char *error_buf, uint32 error_buf_size)
  959. {
  960. uint32 i;
  961. /* init_func_ptrs() will go through import functions */
  962. for (i = 0; i < module->import_global_count; i++) {
  963. AOTImportGlobal *global = module->import_globals + i;
  964. if (!global->is_linked) {
  965. set_error_buf_v(error_buf, error_buf_size,
  966. "failed to link import global (%s, %s)",
  967. global->module_name, global->global_name);
  968. return false;
  969. }
  970. }
  971. return true;
  972. }
  973. AOTModuleInstance *
  974. aot_instantiate(AOTModule *module, bool is_sub_inst, WASMExecEnv *exec_env_main,
  975. uint32 stack_size, uint32 heap_size, char *error_buf,
  976. uint32 error_buf_size)
  977. {
  978. AOTModuleInstance *module_inst;
  979. const uint32 module_inst_struct_size =
  980. offsetof(AOTModuleInstance, global_table_data.bytes);
  981. const uint64 module_inst_mem_inst_size =
  982. (uint64)module->memory_count * sizeof(AOTMemoryInstance);
  983. uint64 total_size, table_size = 0;
  984. uint8 *p;
  985. uint32 i, extra_info_offset;
  986. /* Check heap size */
  987. heap_size = align_uint(heap_size, 8);
  988. if (heap_size > APP_HEAP_SIZE_MAX)
  989. heap_size = APP_HEAP_SIZE_MAX;
  990. total_size = (uint64)module_inst_struct_size + module_inst_mem_inst_size
  991. + module->global_data_size;
  992. /*
  993. * calculate size of table data
  994. */
  995. for (i = 0; i != module->import_table_count; ++i) {
  996. table_size += offsetof(AOTTableInstance, elems);
  997. table_size += (uint64)sizeof(uint32)
  998. * (uint64)aot_get_imp_tbl_data_slots(
  999. module->import_tables + i, false);
  1000. }
  1001. for (i = 0; i != module->table_count; ++i) {
  1002. table_size += offsetof(AOTTableInstance, elems);
  1003. table_size +=
  1004. (uint64)sizeof(uint32)
  1005. * (uint64)aot_get_tbl_data_slots(module->tables + i, false);
  1006. }
  1007. total_size += table_size;
  1008. /* The offset of AOTModuleInstanceExtra, make it 8-byte aligned */
  1009. total_size = (total_size + 7LL) & ~7LL;
  1010. extra_info_offset = (uint32)total_size;
  1011. total_size += sizeof(AOTModuleInstanceExtra);
  1012. /* Allocate module instance, global data, table data and heap data */
  1013. if (!(module_inst =
  1014. runtime_malloc(total_size, error_buf, error_buf_size))) {
  1015. return NULL;
  1016. }
  1017. module_inst->module_type = Wasm_Module_AoT;
  1018. module_inst->module = (void *)module;
  1019. module_inst->e =
  1020. (WASMModuleInstanceExtra *)((uint8 *)module_inst + extra_info_offset);
  1021. /* Initialize global info */
  1022. p = (uint8 *)module_inst + module_inst_struct_size
  1023. + module_inst_mem_inst_size;
  1024. module_inst->global_data = p;
  1025. module_inst->global_data_size = module->global_data_size;
  1026. if (!global_instantiate(module_inst, module, error_buf, error_buf_size))
  1027. goto fail;
  1028. /* Initialize table info */
  1029. p += module->global_data_size;
  1030. module_inst->table_count = module->table_count + module->import_table_count;
  1031. if (!tables_instantiate(module_inst, module, (AOTTableInstance *)p,
  1032. error_buf, error_buf_size))
  1033. goto fail;
  1034. /* Initialize memory space */
  1035. if (!memories_instantiate(module_inst, module, heap_size, error_buf,
  1036. error_buf_size))
  1037. goto fail;
  1038. /* Initialize function pointers */
  1039. if (!init_func_ptrs(module_inst, module, error_buf, error_buf_size))
  1040. goto fail;
  1041. /* Initialize function type indexes */
  1042. if (!init_func_type_indexes(module_inst, module, error_buf, error_buf_size))
  1043. goto fail;
  1044. if (!check_linked_symbol(module, error_buf, error_buf_size))
  1045. goto fail;
  1046. if (!create_exports(module_inst, module, error_buf, error_buf_size))
  1047. goto fail;
  1048. #if WASM_ENABLE_LIBC_WASI != 0
  1049. if (!is_sub_inst) {
  1050. if (!wasm_runtime_init_wasi(
  1051. (WASMModuleInstanceCommon *)module_inst,
  1052. module->wasi_args.dir_list, module->wasi_args.dir_count,
  1053. module->wasi_args.map_dir_list, module->wasi_args.map_dir_count,
  1054. module->wasi_args.env, module->wasi_args.env_count,
  1055. module->wasi_args.addr_pool, module->wasi_args.addr_count,
  1056. module->wasi_args.ns_lookup_pool,
  1057. module->wasi_args.ns_lookup_count, module->wasi_args.argv,
  1058. module->wasi_args.argc, module->wasi_args.stdio[0],
  1059. module->wasi_args.stdio[1], module->wasi_args.stdio[2],
  1060. error_buf, error_buf_size))
  1061. goto fail;
  1062. }
  1063. #endif
  1064. #if WASM_ENABLE_WASI_NN != 0
  1065. if (!is_sub_inst) {
  1066. if (!(((AOTModuleInstanceExtra *)module_inst->e)->wasi_nn_ctx =
  1067. wasi_nn_initialize())) {
  1068. set_error_buf(error_buf, error_buf_size,
  1069. "wasi nn initialization failed");
  1070. goto fail;
  1071. }
  1072. }
  1073. #endif
  1074. /* Initialize the thread related data */
  1075. if (stack_size == 0)
  1076. stack_size = DEFAULT_WASM_STACK_SIZE;
  1077. #if WASM_ENABLE_SPEC_TEST != 0
  1078. if (stack_size < 48 * 1024)
  1079. stack_size = 48 * 1024;
  1080. #endif
  1081. module_inst->default_wasm_stack_size = stack_size;
  1082. #if WASM_ENABLE_PERF_PROFILING != 0
  1083. total_size = (uint64)sizeof(AOTFuncPerfProfInfo)
  1084. * (module->import_func_count + module->func_count);
  1085. if (!(module_inst->func_perf_profilings =
  1086. runtime_malloc(total_size, error_buf, error_buf_size))) {
  1087. goto fail;
  1088. }
  1089. #endif
  1090. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1091. if (!(module_inst->frames =
  1092. runtime_malloc(sizeof(Vector), error_buf, error_buf_size))) {
  1093. goto fail;
  1094. }
  1095. #endif
  1096. if (!execute_post_instantiate_functions(module_inst, is_sub_inst,
  1097. exec_env_main)) {
  1098. set_error_buf(error_buf, error_buf_size, module_inst->cur_exception);
  1099. goto fail;
  1100. }
  1101. #if WASM_ENABLE_MEMORY_TRACING != 0
  1102. wasm_runtime_dump_module_inst_mem_consumption(
  1103. (WASMModuleInstanceCommon *)module_inst);
  1104. #endif
  1105. return module_inst;
  1106. fail:
  1107. aot_deinstantiate(module_inst, is_sub_inst);
  1108. return NULL;
  1109. }
  1110. void
  1111. aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
  1112. {
  1113. if (module_inst->exec_env_singleton) {
  1114. /* wasm_exec_env_destroy will call
  1115. wasm_cluster_wait_for_all_except_self to wait for other
  1116. threads, so as to destroy their exec_envs and module
  1117. instances first, and avoid accessing the shared resources
  1118. of current module instance after it is deinstantiated. */
  1119. wasm_exec_env_destroy((WASMExecEnv *)module_inst->exec_env_singleton);
  1120. }
  1121. #if WASM_ENABLE_LIBC_WASI != 0
  1122. /* Destroy wasi resource before freeing app heap, since some fields of
  1123. wasi contex are allocated from app heap, and if app heap is freed,
  1124. these fields will be set to NULL, we cannot free their internal data
  1125. which may allocated from global heap. */
  1126. /* Only destroy wasi ctx in the main module instance */
  1127. if (!is_sub_inst)
  1128. wasm_runtime_destroy_wasi((WASMModuleInstanceCommon *)module_inst);
  1129. #endif
  1130. #if WASM_ENABLE_PERF_PROFILING != 0
  1131. if (module_inst->func_perf_profilings)
  1132. wasm_runtime_free(module_inst->func_perf_profilings);
  1133. #endif
  1134. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1135. if (module_inst->frames) {
  1136. bh_vector_destroy(module_inst->frames);
  1137. wasm_runtime_free(module_inst->frames);
  1138. module_inst->frames = NULL;
  1139. }
  1140. #endif
  1141. if (module_inst->tables)
  1142. wasm_runtime_free(module_inst->tables);
  1143. if (module_inst->memories)
  1144. memories_deinstantiate(module_inst);
  1145. if (module_inst->export_functions)
  1146. wasm_runtime_free(module_inst->export_functions);
  1147. if (module_inst->func_ptrs)
  1148. wasm_runtime_free(module_inst->func_ptrs);
  1149. if (module_inst->func_type_indexes)
  1150. wasm_runtime_free(module_inst->func_type_indexes);
  1151. if (((AOTModuleInstanceExtra *)module_inst->e)->c_api_func_imports)
  1152. wasm_runtime_free(
  1153. ((AOTModuleInstanceExtra *)module_inst->e)->c_api_func_imports);
  1154. #if WASM_ENABLE_WASI_NN != 0
  1155. if (!is_sub_inst) {
  1156. WASINNContext *wasi_nn_ctx =
  1157. ((AOTModuleInstanceExtra *)module_inst->e)->wasi_nn_ctx;
  1158. if (wasi_nn_ctx)
  1159. wasi_nn_destroy(wasi_nn_ctx);
  1160. }
  1161. #endif
  1162. wasm_runtime_free(module_inst);
  1163. }
  1164. AOTFunctionInstance *
  1165. aot_lookup_function(const AOTModuleInstance *module_inst, const char *name,
  1166. const char *signature)
  1167. {
  1168. uint32 i;
  1169. AOTFunctionInstance *export_funcs =
  1170. (AOTFunctionInstance *)module_inst->export_functions;
  1171. for (i = 0; i < module_inst->export_func_count; i++)
  1172. if (!strcmp(export_funcs[i].func_name, name))
  1173. return &export_funcs[i];
  1174. (void)signature;
  1175. return NULL;
  1176. }
  1177. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1178. static bool
  1179. invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
  1180. const WASMType *func_type,
  1181. const char *signature, void *attachment,
  1182. uint32 *argv, uint32 argc, uint32 *argv_ret)
  1183. {
  1184. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  1185. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  1186. WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
  1187. uint32 page_size = os_getpagesize();
  1188. uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
  1189. uint16 param_count = func_type->param_count;
  1190. uint16 result_count = func_type->result_count;
  1191. const uint8 *types = func_type->types;
  1192. #ifdef BH_PLATFORM_WINDOWS
  1193. int result;
  1194. bool has_exception;
  1195. char exception[EXCEPTION_BUF_LEN];
  1196. #endif
  1197. bool ret;
  1198. /* Check native stack overflow firstly to ensure we have enough
  1199. native stack to run the following codes before actually calling
  1200. the aot function in invokeNative function. */
  1201. RECORD_STACK_USAGE(exec_env, (uint8 *)&module_inst);
  1202. if ((uint8 *)&module_inst < exec_env->native_stack_boundary
  1203. + page_size * (guard_page_count + 1)) {
  1204. aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
  1205. return false;
  1206. }
  1207. if (exec_env_tls && (exec_env_tls != exec_env)) {
  1208. aot_set_exception(module_inst, "invalid exec env");
  1209. return false;
  1210. }
  1211. if (!os_thread_signal_inited()) {
  1212. aot_set_exception(module_inst, "thread signal env not inited");
  1213. return false;
  1214. }
  1215. wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
  1216. wasm_runtime_set_exec_env_tls(exec_env);
  1217. if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
  1218. /* Quick call with func_ptr if the function signature is simple */
  1219. if (!signature && param_count == 1 && types[0] == VALUE_TYPE_I32) {
  1220. if (result_count == 0) {
  1221. void (*NativeFunc)(WASMExecEnv *, uint32) =
  1222. (void (*)(WASMExecEnv *, uint32))func_ptr;
  1223. NativeFunc(exec_env, argv[0]);
  1224. ret = aot_copy_exception(module_inst, NULL) ? false : true;
  1225. }
  1226. else if (result_count == 1
  1227. && types[param_count] == VALUE_TYPE_I32) {
  1228. uint32 (*NativeFunc)(WASMExecEnv *, uint32) =
  1229. (uint32(*)(WASMExecEnv *, uint32))func_ptr;
  1230. argv_ret[0] = NativeFunc(exec_env, argv[0]);
  1231. ret = aot_copy_exception(module_inst, NULL) ? false : true;
  1232. }
  1233. else {
  1234. ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
  1235. signature, attachment, argv,
  1236. argc, argv_ret);
  1237. }
  1238. }
  1239. else {
  1240. ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
  1241. signature, attachment, argv, argc,
  1242. argv_ret);
  1243. }
  1244. #ifdef BH_PLATFORM_WINDOWS
  1245. has_exception = aot_copy_exception(module_inst, exception);
  1246. if (has_exception && strstr(exception, "native stack overflow")) {
  1247. /* After a stack overflow, the stack was left
  1248. in a damaged state, let the CRT repair it */
  1249. result = _resetstkoflw();
  1250. bh_assert(result != 0);
  1251. }
  1252. #endif
  1253. }
  1254. else {
  1255. /* Exception has been set in signal handler before calling longjmp */
  1256. ret = false;
  1257. }
  1258. jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
  1259. bh_assert(&jmpbuf_node == jmpbuf_node_pop);
  1260. if (!exec_env->jmpbuf_stack_top) {
  1261. wasm_runtime_set_exec_env_tls(NULL);
  1262. }
  1263. if (!ret) {
  1264. os_sigreturn();
  1265. os_signal_unmask();
  1266. }
  1267. (void)jmpbuf_node_pop;
  1268. return ret;
  1269. }
  1270. #define invoke_native_internal invoke_native_with_hw_bound_check
  1271. #else /* else of OS_ENABLE_HW_BOUND_CHECK */
  1272. #define invoke_native_internal wasm_runtime_invoke_native
  1273. #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
  1274. bool
  1275. aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
  1276. unsigned argc, uint32 argv[])
  1277. {
  1278. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  1279. AOTFuncType *func_type = function->u.func.func_type;
  1280. uint32 result_count = func_type->result_count;
  1281. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  1282. bool ret;
  1283. if (argc < func_type->param_cell_num) {
  1284. char buf[108];
  1285. snprintf(buf, sizeof(buf),
  1286. "invalid argument count %u, must be no smaller than %u", argc,
  1287. func_type->param_cell_num);
  1288. aot_set_exception(module_inst, buf);
  1289. return false;
  1290. }
  1291. argc = func_type->param_cell_num;
  1292. #if defined(os_writegsbase)
  1293. {
  1294. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1295. if (memory_inst)
  1296. /* write base addr of linear memory to GS segment register */
  1297. os_writegsbase(memory_inst->memory_data);
  1298. }
  1299. #endif
  1300. /* func pointer was looked up previously */
  1301. bh_assert(function->u.func.func_ptr != NULL);
  1302. /* set thread handle and stack boundary */
  1303. wasm_exec_env_set_thread_info(exec_env);
  1304. if (ext_ret_count > 0) {
  1305. uint32 cell_num = 0, i;
  1306. uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
  1307. uint32 argv1_buf[32], *argv1 = argv1_buf, *ext_rets = NULL;
  1308. uint32 *argv_ret = argv;
  1309. uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
  1310. uint64 size;
  1311. /* Allocate memory all arguments */
  1312. size =
  1313. sizeof(uint32) * (uint64)argc /* original arguments */
  1314. + sizeof(void *)
  1315. * (uint64)ext_ret_count /* extra result values' addr */
  1316. + sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
  1317. if (size > sizeof(argv1_buf)
  1318. && !(argv1 = runtime_malloc(size, module_inst->cur_exception,
  1319. sizeof(module_inst->cur_exception)))) {
  1320. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
  1321. return false;
  1322. }
  1323. /* Copy original arguments */
  1324. bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
  1325. /* Get the extra result value's address */
  1326. ext_rets =
  1327. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  1328. /* Append each extra result value's address to original arguments */
  1329. for (i = 0; i < ext_ret_count; i++) {
  1330. *(uintptr_t *)(argv1 + argc + sizeof(void *) / sizeof(uint32) * i) =
  1331. (uintptr_t)(ext_rets + cell_num);
  1332. cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
  1333. }
  1334. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
  1335. if (!aot_alloc_frame(exec_env, function->func_index)) {
  1336. if (argv1 != argv1_buf)
  1337. wasm_runtime_free(argv1);
  1338. return false;
  1339. }
  1340. #endif
  1341. ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
  1342. func_type, NULL, NULL, argv1, argc, argv);
  1343. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1344. if (!ret) {
  1345. if (aot_create_call_stack(exec_env)) {
  1346. aot_dump_call_stack(exec_env, true, NULL, 0);
  1347. }
  1348. }
  1349. #endif
  1350. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
  1351. aot_free_frame(exec_env);
  1352. #endif
  1353. if (!ret) {
  1354. if (argv1 != argv1_buf)
  1355. wasm_runtime_free(argv1);
  1356. return ret;
  1357. }
  1358. /* Get extra result values */
  1359. switch (func_type->types[func_type->param_count]) {
  1360. case VALUE_TYPE_I32:
  1361. case VALUE_TYPE_F32:
  1362. #if WASM_ENABLE_REF_TYPES != 0
  1363. case VALUE_TYPE_FUNCREF:
  1364. case VALUE_TYPE_EXTERNREF:
  1365. #endif
  1366. argv_ret++;
  1367. break;
  1368. case VALUE_TYPE_I64:
  1369. case VALUE_TYPE_F64:
  1370. argv_ret += 2;
  1371. break;
  1372. #if WASM_ENABLE_SIMD != 0
  1373. case VALUE_TYPE_V128:
  1374. argv_ret += 4;
  1375. break;
  1376. #endif
  1377. default:
  1378. bh_assert(0);
  1379. break;
  1380. }
  1381. ext_rets =
  1382. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  1383. bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num, ext_rets,
  1384. sizeof(uint32) * cell_num);
  1385. if (argv1 != argv1_buf)
  1386. wasm_runtime_free(argv1);
  1387. return true;
  1388. }
  1389. else {
  1390. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
  1391. if (!aot_alloc_frame(exec_env, function->func_index)) {
  1392. return false;
  1393. }
  1394. #endif
  1395. ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
  1396. func_type, NULL, NULL, argv, argc, argv);
  1397. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1398. if (aot_copy_exception(module_inst, NULL)) {
  1399. if (aot_create_call_stack(exec_env)) {
  1400. aot_dump_call_stack(exec_env, true, NULL, 0);
  1401. }
  1402. }
  1403. #endif
  1404. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
  1405. aot_free_frame(exec_env);
  1406. #endif
  1407. return ret && !aot_copy_exception(module_inst, NULL) ? true : false;
  1408. }
  1409. }
  1410. void
  1411. aot_set_exception(AOTModuleInstance *module_inst, const char *exception)
  1412. {
  1413. wasm_set_exception(module_inst, exception);
  1414. }
  1415. void
  1416. aot_set_exception_with_id(AOTModuleInstance *module_inst, uint32 id)
  1417. {
  1418. if (id != EXCE_ALREADY_THROWN)
  1419. wasm_set_exception_with_id(module_inst, id);
  1420. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1421. wasm_runtime_access_exce_check_guard_page();
  1422. #endif
  1423. }
  1424. const char *
  1425. aot_get_exception(AOTModuleInstance *module_inst)
  1426. {
  1427. return wasm_get_exception(module_inst);
  1428. }
  1429. bool
  1430. aot_copy_exception(AOTModuleInstance *module_inst, char *exception_buf)
  1431. {
  1432. /* The field offsets of cur_exception in AOTModuleInstance and
  1433. WASMModuleInstance are the same */
  1434. return wasm_copy_exception(module_inst, exception_buf);
  1435. }
  1436. static bool
  1437. execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
  1438. AOTFunctionInstance *malloc_func,
  1439. AOTFunctionInstance *retain_func, uint32 size,
  1440. uint32 *p_result)
  1441. {
  1442. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1443. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  1444. #endif
  1445. WASMExecEnv *exec_env_created = NULL;
  1446. WASMModuleInstanceCommon *module_inst_old = NULL;
  1447. uint32 argv[2], argc;
  1448. bool ret;
  1449. argv[0] = size;
  1450. argc = 1;
  1451. if (retain_func) {
  1452. argv[1] = 0;
  1453. argc = 2;
  1454. }
  1455. if (exec_env) {
  1456. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1457. if (exec_env_tls) {
  1458. bh_assert(exec_env_tls == exec_env);
  1459. }
  1460. #endif
  1461. bh_assert(exec_env->module_inst
  1462. == (WASMModuleInstanceCommon *)module_inst);
  1463. }
  1464. else {
  1465. /* Try using the existing exec_env */
  1466. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1467. exec_env = exec_env_tls;
  1468. #endif
  1469. #if WASM_ENABLE_THREAD_MGR != 0
  1470. if (!exec_env)
  1471. exec_env = wasm_clusters_search_exec_env(
  1472. (WASMModuleInstanceCommon *)module_inst);
  1473. #endif
  1474. if (!exec_env) {
  1475. if (!(exec_env = exec_env_created = wasm_exec_env_create(
  1476. (WASMModuleInstanceCommon *)module_inst,
  1477. module_inst->default_wasm_stack_size))) {
  1478. wasm_set_exception(module_inst, "allocate memory failed");
  1479. return false;
  1480. }
  1481. }
  1482. else {
  1483. /* Temporarily replace exec_env's module inst with current
  1484. module inst to ensure that the exec_env's module inst
  1485. is the correct one. */
  1486. module_inst_old = exec_env->module_inst;
  1487. exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
  1488. }
  1489. }
  1490. ret = aot_call_function(exec_env, malloc_func, argc, argv);
  1491. if (retain_func && ret)
  1492. ret = aot_call_function(exec_env, retain_func, 1, argv);
  1493. if (module_inst_old)
  1494. /* Restore the existing exec_env's module inst */
  1495. exec_env->module_inst = module_inst_old;
  1496. if (exec_env_created)
  1497. wasm_exec_env_destroy(exec_env_created);
  1498. if (ret)
  1499. *p_result = argv[0];
  1500. return ret;
  1501. }
  1502. static bool
  1503. execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
  1504. AOTFunctionInstance *free_func, uint32 offset)
  1505. {
  1506. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1507. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  1508. #endif
  1509. WASMExecEnv *exec_env_created = NULL;
  1510. WASMModuleInstanceCommon *module_inst_old = NULL;
  1511. uint32 argv[2];
  1512. bool ret;
  1513. argv[0] = offset;
  1514. if (exec_env) {
  1515. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1516. if (exec_env_tls) {
  1517. bh_assert(exec_env_tls == exec_env);
  1518. }
  1519. #endif
  1520. bh_assert(exec_env->module_inst
  1521. == (WASMModuleInstanceCommon *)module_inst);
  1522. }
  1523. else {
  1524. /* Try using the existing exec_env */
  1525. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1526. exec_env = exec_env_tls;
  1527. #endif
  1528. #if WASM_ENABLE_THREAD_MGR != 0
  1529. if (!exec_env)
  1530. exec_env = wasm_clusters_search_exec_env(
  1531. (WASMModuleInstanceCommon *)module_inst);
  1532. #endif
  1533. if (!exec_env) {
  1534. if (!(exec_env = exec_env_created = wasm_exec_env_create(
  1535. (WASMModuleInstanceCommon *)module_inst,
  1536. module_inst->default_wasm_stack_size))) {
  1537. wasm_set_exception(module_inst, "allocate memory failed");
  1538. return false;
  1539. }
  1540. }
  1541. else {
  1542. /* Temporarily replace exec_env's module inst with current
  1543. module inst to ensure that the exec_env's module inst
  1544. is the correct one. */
  1545. module_inst_old = exec_env->module_inst;
  1546. exec_env->module_inst = (WASMModuleInstanceCommon *)module_inst;
  1547. }
  1548. }
  1549. ret = aot_call_function(exec_env, free_func, 1, argv);
  1550. if (module_inst_old)
  1551. /* Restore the existing exec_env's module inst */
  1552. exec_env->module_inst = module_inst_old;
  1553. if (exec_env_created)
  1554. wasm_exec_env_destroy(exec_env_created);
  1555. return ret;
  1556. }
  1557. uint32
  1558. aot_module_malloc_internal(AOTModuleInstance *module_inst,
  1559. WASMExecEnv *exec_env, uint32 size,
  1560. void **p_native_addr)
  1561. {
  1562. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1563. AOTModule *module = (AOTModule *)module_inst->module;
  1564. uint8 *addr = NULL;
  1565. uint32 offset = 0;
  1566. if (!memory_inst) {
  1567. aot_set_exception(module_inst, "uninitialized memory");
  1568. return 0;
  1569. }
  1570. if (memory_inst->heap_handle) {
  1571. addr = mem_allocator_malloc(memory_inst->heap_handle, size);
  1572. }
  1573. else if (module->malloc_func_index != (uint32)-1
  1574. && module->free_func_index != (uint32)-1) {
  1575. AOTFunctionInstance *malloc_func, *retain_func = NULL;
  1576. char *malloc_func_name;
  1577. char *malloc_func_sig;
  1578. if (module->retain_func_index != (uint32)-1) {
  1579. malloc_func_name = "__new";
  1580. malloc_func_sig = "(ii)i";
  1581. retain_func = aot_lookup_function(module_inst, "__retain", "(i)i");
  1582. if (!retain_func)
  1583. retain_func = aot_lookup_function(module_inst, "__pin", "(i)i");
  1584. bh_assert(retain_func);
  1585. }
  1586. else {
  1587. malloc_func_name = "malloc";
  1588. malloc_func_sig = "(i)i";
  1589. }
  1590. malloc_func =
  1591. aot_lookup_function(module_inst, malloc_func_name, malloc_func_sig);
  1592. if (!malloc_func
  1593. || !execute_malloc_function(module_inst, exec_env, malloc_func,
  1594. retain_func, size, &offset)) {
  1595. return 0;
  1596. }
  1597. addr = offset ? (uint8 *)memory_inst->memory_data + offset : NULL;
  1598. }
  1599. if (!addr) {
  1600. if (memory_inst->heap_handle
  1601. && mem_allocator_is_heap_corrupted(memory_inst->heap_handle)) {
  1602. wasm_runtime_show_app_heap_corrupted_prompt();
  1603. aot_set_exception(module_inst, "app heap corrupted");
  1604. }
  1605. else {
  1606. LOG_WARNING("warning: allocate %u bytes memory failed", size);
  1607. }
  1608. return 0;
  1609. }
  1610. if (p_native_addr)
  1611. *p_native_addr = addr;
  1612. return (uint32)(addr - memory_inst->memory_data);
  1613. }
  1614. uint32
  1615. aot_module_realloc_internal(AOTModuleInstance *module_inst,
  1616. WASMExecEnv *exec_env, uint32 ptr, uint32 size,
  1617. void **p_native_addr)
  1618. {
  1619. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1620. uint8 *addr = NULL;
  1621. if (!memory_inst) {
  1622. aot_set_exception(module_inst, "uninitialized memory");
  1623. return 0;
  1624. }
  1625. if (memory_inst->heap_handle) {
  1626. addr = mem_allocator_realloc(
  1627. memory_inst->heap_handle,
  1628. ptr ? memory_inst->memory_data + ptr : NULL, size);
  1629. }
  1630. /* Only support realloc in WAMR's app heap */
  1631. (void)exec_env;
  1632. if (!addr) {
  1633. if (memory_inst->heap_handle
  1634. && mem_allocator_is_heap_corrupted(memory_inst->heap_handle)) {
  1635. aot_set_exception(module_inst, "app heap corrupted");
  1636. }
  1637. else {
  1638. aot_set_exception(module_inst, "out of memory");
  1639. }
  1640. return 0;
  1641. }
  1642. if (p_native_addr)
  1643. *p_native_addr = addr;
  1644. return (uint32)(addr - memory_inst->memory_data);
  1645. }
  1646. void
  1647. aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
  1648. uint32 ptr)
  1649. {
  1650. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1651. AOTModule *module = (AOTModule *)module_inst->module;
  1652. if (!memory_inst) {
  1653. return;
  1654. }
  1655. if (ptr) {
  1656. uint8 *addr = memory_inst->memory_data + ptr;
  1657. if (memory_inst->heap_handle && memory_inst->heap_data < addr
  1658. && addr < memory_inst->heap_data_end) {
  1659. mem_allocator_free(memory_inst->heap_handle, addr);
  1660. }
  1661. else if (module->malloc_func_index != (uint32)-1
  1662. && module->free_func_index != (uint32)-1
  1663. && memory_inst->memory_data <= addr
  1664. && addr < memory_inst->memory_data_end) {
  1665. AOTFunctionInstance *free_func;
  1666. char *free_func_name;
  1667. if (module->retain_func_index != (uint32)-1) {
  1668. free_func_name = "__release";
  1669. }
  1670. else {
  1671. free_func_name = "free";
  1672. }
  1673. free_func =
  1674. aot_lookup_function(module_inst, free_func_name, "(i)i");
  1675. if (!free_func && module->retain_func_index != (uint32)-1)
  1676. free_func = aot_lookup_function(module_inst, "__unpin", "(i)i");
  1677. if (free_func)
  1678. execute_free_function(module_inst, exec_env, free_func, ptr);
  1679. }
  1680. }
  1681. }
  1682. uint32
  1683. aot_module_malloc(AOTModuleInstance *module_inst, uint32 size,
  1684. void **p_native_addr)
  1685. {
  1686. return aot_module_malloc_internal(module_inst, NULL, size, p_native_addr);
  1687. }
  1688. uint32
  1689. aot_module_realloc(AOTModuleInstance *module_inst, uint32 ptr, uint32 size,
  1690. void **p_native_addr)
  1691. {
  1692. return aot_module_realloc_internal(module_inst, NULL, ptr, size,
  1693. p_native_addr);
  1694. }
  1695. void
  1696. aot_module_free(AOTModuleInstance *module_inst, uint32 ptr)
  1697. {
  1698. aot_module_free_internal(module_inst, NULL, ptr);
  1699. }
  1700. uint32
  1701. aot_module_dup_data(AOTModuleInstance *module_inst, const char *src,
  1702. uint32 size)
  1703. {
  1704. char *buffer;
  1705. uint32 buffer_offset =
  1706. aot_module_malloc(module_inst, size, (void **)&buffer);
  1707. if (buffer_offset != 0) {
  1708. buffer = wasm_runtime_addr_app_to_native(
  1709. (WASMModuleInstanceCommon *)module_inst, buffer_offset);
  1710. bh_memcpy_s(buffer, size, src, size);
  1711. }
  1712. return buffer_offset;
  1713. }
  1714. bool
  1715. aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
  1716. {
  1717. return wasm_enlarge_memory(module_inst, inc_page_count);
  1718. }
  1719. bool
  1720. aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
  1721. uint32 *argv)
  1722. {
  1723. AOTModuleInstance *module_inst =
  1724. (AOTModuleInstance *)wasm_runtime_get_module_inst(exec_env);
  1725. AOTModule *aot_module = (AOTModule *)module_inst->module;
  1726. AOTModuleInstanceExtra *module_inst_extra =
  1727. (AOTModuleInstanceExtra *)module_inst->e;
  1728. CApiFuncImport *c_api_func_import =
  1729. module_inst_extra->c_api_func_imports
  1730. ? module_inst_extra->c_api_func_imports + func_idx
  1731. : NULL;
  1732. uint32 *func_type_indexes = module_inst->func_type_indexes;
  1733. uint32 func_type_idx = func_type_indexes[func_idx];
  1734. AOTFuncType *func_type = aot_module->func_types[func_type_idx];
  1735. void **func_ptrs = module_inst->func_ptrs;
  1736. void *func_ptr = func_ptrs[func_idx];
  1737. AOTImportFunc *import_func;
  1738. const char *signature;
  1739. void *attachment;
  1740. char buf[96];
  1741. bool ret = false;
  1742. bh_assert(func_idx < aot_module->import_func_count);
  1743. import_func = aot_module->import_funcs + func_idx;
  1744. if (import_func->call_conv_wasm_c_api)
  1745. func_ptr =
  1746. c_api_func_import ? c_api_func_import->func_ptr_linked : NULL;
  1747. if (!func_ptr) {
  1748. snprintf(buf, sizeof(buf),
  1749. "failed to call unlinked import function (%s, %s)",
  1750. import_func->module_name, import_func->func_name);
  1751. aot_set_exception(module_inst, buf);
  1752. goto fail;
  1753. }
  1754. attachment = import_func->attachment;
  1755. if (import_func->call_conv_wasm_c_api) {
  1756. ret = wasm_runtime_invoke_c_api_native(
  1757. (WASMModuleInstanceCommon *)module_inst, func_ptr, func_type, argc,
  1758. argv, c_api_func_import->with_env_arg, c_api_func_import->env_arg);
  1759. }
  1760. else if (!import_func->call_conv_raw) {
  1761. signature = import_func->signature;
  1762. ret =
  1763. wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature,
  1764. attachment, argv, argc, argv);
  1765. }
  1766. else {
  1767. signature = import_func->signature;
  1768. ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type,
  1769. signature, attachment, argv, argc,
  1770. argv);
  1771. }
  1772. fail:
  1773. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1774. if (!ret)
  1775. wasm_runtime_access_exce_check_guard_page();
  1776. #endif
  1777. return ret;
  1778. }
  1779. bool
  1780. aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
  1781. uint32 argc, uint32 *argv)
  1782. {
  1783. AOTModuleInstance *module_inst =
  1784. (AOTModuleInstance *)wasm_runtime_get_module_inst(exec_env);
  1785. AOTModule *aot_module = (AOTModule *)module_inst->module;
  1786. uint32 *func_type_indexes = module_inst->func_type_indexes;
  1787. AOTTableInstance *tbl_inst;
  1788. AOTFuncType *func_type;
  1789. void **func_ptrs = module_inst->func_ptrs, *func_ptr;
  1790. uint32 func_type_idx, func_idx, ext_ret_count;
  1791. AOTImportFunc *import_func;
  1792. const char *signature = NULL;
  1793. void *attachment = NULL;
  1794. char buf[96];
  1795. bool ret;
  1796. /* this function is called from native code, so exec_env->handle and
  1797. exec_env->native_stack_boundary must have been set, we don't set
  1798. it again */
  1799. RECORD_STACK_USAGE(exec_env, (uint8 *)&module_inst);
  1800. if ((uint8 *)&module_inst < exec_env->native_stack_boundary) {
  1801. aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
  1802. goto fail;
  1803. }
  1804. tbl_inst = module_inst->tables[tbl_idx];
  1805. bh_assert(tbl_inst);
  1806. if (table_elem_idx >= tbl_inst->cur_size) {
  1807. aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
  1808. goto fail;
  1809. }
  1810. func_idx = tbl_inst->elems[table_elem_idx];
  1811. if (func_idx == NULL_REF) {
  1812. aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
  1813. goto fail;
  1814. }
  1815. func_type_idx = func_type_indexes[func_idx];
  1816. func_type = aot_module->func_types[func_type_idx];
  1817. if (func_idx >= aot_module->import_func_count) {
  1818. /* func pointer was looked up previously */
  1819. bh_assert(func_ptrs[func_idx] != NULL);
  1820. }
  1821. if (!(func_ptr = func_ptrs[func_idx])) {
  1822. bh_assert(func_idx < aot_module->import_func_count);
  1823. import_func = aot_module->import_funcs + func_idx;
  1824. snprintf(buf, sizeof(buf),
  1825. "failed to call unlinked import function (%s, %s)",
  1826. import_func->module_name, import_func->func_name);
  1827. aot_set_exception(module_inst, buf);
  1828. goto fail;
  1829. }
  1830. if (func_idx < aot_module->import_func_count) {
  1831. /* Call native function */
  1832. import_func = aot_module->import_funcs + func_idx;
  1833. signature = import_func->signature;
  1834. if (import_func->call_conv_raw) {
  1835. attachment = import_func->attachment;
  1836. ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type,
  1837. signature, attachment, argv,
  1838. argc, argv);
  1839. if (!ret)
  1840. goto fail;
  1841. return true;
  1842. }
  1843. }
  1844. ext_ret_count =
  1845. func_type->result_count > 1 ? func_type->result_count - 1 : 0;
  1846. if (ext_ret_count > 0) {
  1847. uint32 argv1_buf[32], *argv1 = argv1_buf;
  1848. uint32 *ext_rets = NULL, *argv_ret = argv;
  1849. uint32 cell_num = 0, i;
  1850. uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
  1851. uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
  1852. uint64 size;
  1853. /* Allocate memory all arguments */
  1854. size =
  1855. sizeof(uint32) * (uint64)argc /* original arguments */
  1856. + sizeof(void *)
  1857. * (uint64)ext_ret_count /* extra result values' addr */
  1858. + sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
  1859. if (size > sizeof(argv1_buf)
  1860. && !(argv1 = runtime_malloc(size, module_inst->cur_exception,
  1861. sizeof(module_inst->cur_exception)))) {
  1862. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
  1863. goto fail;
  1864. }
  1865. /* Copy original arguments */
  1866. bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
  1867. /* Get the extra result value's address */
  1868. ext_rets =
  1869. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  1870. /* Append each extra result value's address to original arguments */
  1871. for (i = 0; i < ext_ret_count; i++) {
  1872. *(uintptr_t *)(argv1 + argc + sizeof(void *) / sizeof(uint32) * i) =
  1873. (uintptr_t)(ext_rets + cell_num);
  1874. cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
  1875. }
  1876. ret = invoke_native_internal(exec_env, func_ptr, func_type, signature,
  1877. attachment, argv1, argc, argv);
  1878. if (!ret) {
  1879. if (argv1 != argv1_buf)
  1880. wasm_runtime_free(argv1);
  1881. goto fail;
  1882. }
  1883. /* Get extra result values */
  1884. switch (func_type->types[func_type->param_count]) {
  1885. case VALUE_TYPE_I32:
  1886. case VALUE_TYPE_F32:
  1887. #if WASM_ENABLE_REF_TYPES != 0
  1888. case VALUE_TYPE_FUNCREF:
  1889. case VALUE_TYPE_EXTERNREF:
  1890. #endif
  1891. argv_ret++;
  1892. break;
  1893. case VALUE_TYPE_I64:
  1894. case VALUE_TYPE_F64:
  1895. argv_ret += 2;
  1896. break;
  1897. #if WASM_ENABLE_SIMD != 0
  1898. case VALUE_TYPE_V128:
  1899. argv_ret += 4;
  1900. break;
  1901. #endif
  1902. default:
  1903. bh_assert(0);
  1904. break;
  1905. }
  1906. ext_rets =
  1907. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  1908. bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num, ext_rets,
  1909. sizeof(uint32) * cell_num);
  1910. if (argv1 != argv1_buf)
  1911. wasm_runtime_free(argv1);
  1912. return true;
  1913. }
  1914. else {
  1915. ret = invoke_native_internal(exec_env, func_ptr, func_type, signature,
  1916. attachment, argv, argc, argv);
  1917. if (!ret)
  1918. goto fail;
  1919. return true;
  1920. }
  1921. fail:
  1922. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1923. wasm_runtime_access_exce_check_guard_page();
  1924. #endif
  1925. return false;
  1926. }
  1927. bool
  1928. aot_check_app_addr_and_convert(AOTModuleInstance *module_inst, bool is_str,
  1929. uint32 app_buf_addr, uint32 app_buf_size,
  1930. void **p_native_addr)
  1931. {
  1932. bool ret;
  1933. ret = wasm_check_app_addr_and_convert(module_inst, is_str, app_buf_addr,
  1934. app_buf_size, p_native_addr);
  1935. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1936. if (!ret)
  1937. wasm_runtime_access_exce_check_guard_page();
  1938. #endif
  1939. return ret;
  1940. }
  1941. void *
  1942. aot_memmove(void *dest, const void *src, size_t n)
  1943. {
  1944. return memmove(dest, src, n);
  1945. }
  1946. void *
  1947. aot_memset(void *s, int c, size_t n)
  1948. {
  1949. return memset(s, c, n);
  1950. }
  1951. double
  1952. aot_sqrt(double x)
  1953. {
  1954. return sqrt(x);
  1955. }
  1956. float
  1957. aot_sqrtf(float x)
  1958. {
  1959. return sqrtf(x);
  1960. }
  1961. #if WASM_ENABLE_BULK_MEMORY != 0
  1962. bool
  1963. aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
  1964. uint32 len, uint32 dst)
  1965. {
  1966. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1967. AOTModule *aot_module;
  1968. uint8 *data = NULL;
  1969. uint8 *maddr;
  1970. uint64 seg_len = 0;
  1971. aot_module = (AOTModule *)module_inst->module;
  1972. seg_len = aot_module->mem_init_data_list[seg_index]->byte_count;
  1973. data = aot_module->mem_init_data_list[seg_index]->bytes;
  1974. if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
  1975. dst, len))
  1976. return false;
  1977. if ((uint64)offset + (uint64)len > seg_len) {
  1978. aot_set_exception(module_inst, "out of bounds memory access");
  1979. return false;
  1980. }
  1981. maddr = wasm_runtime_addr_app_to_native(
  1982. (WASMModuleInstanceCommon *)module_inst, dst);
  1983. bh_memcpy_s(maddr, memory_inst->memory_data_size - dst, data + offset, len);
  1984. return true;
  1985. }
  1986. bool
  1987. aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index)
  1988. {
  1989. AOTModule *aot_module = (AOTModule *)module_inst->module;
  1990. aot_module->mem_init_data_list[seg_index]->byte_count = 0;
  1991. /* Currently we can't free the dropped data segment
  1992. as the mem_init_data_count is a continuous array */
  1993. return true;
  1994. }
  1995. #endif /* WASM_ENABLE_BULK_MEMORY */
  1996. #if WASM_ENABLE_THREAD_MGR != 0
  1997. bool
  1998. aot_set_aux_stack(WASMExecEnv *exec_env, uint32 start_offset, uint32 size)
  1999. {
  2000. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  2001. AOTModule *module = (AOTModule *)module_inst->module;
  2002. uint32 stack_top_idx = module->aux_stack_top_global_index;
  2003. uint32 data_end = module->aux_data_end;
  2004. uint32 stack_bottom = module->aux_stack_bottom;
  2005. bool is_stack_before_data = stack_bottom < data_end ? true : false;
  2006. /* Check the aux stack space, currently we don't allocate space in heap */
  2007. if ((is_stack_before_data && (size > start_offset))
  2008. || ((!is_stack_before_data) && (start_offset - data_end < size)))
  2009. return false;
  2010. if (stack_top_idx != (uint32)-1) {
  2011. /* The aux stack top is a wasm global,
  2012. set the initial value for the global */
  2013. uint32 global_offset = module->globals[stack_top_idx].data_offset;
  2014. uint8 *global_addr = module_inst->global_data + global_offset;
  2015. *(int32 *)global_addr = start_offset;
  2016. /* The aux stack boundary is a constant value,
  2017. set the value to exec_env */
  2018. exec_env->aux_stack_boundary.boundary = start_offset - size;
  2019. exec_env->aux_stack_bottom.bottom = start_offset;
  2020. return true;
  2021. }
  2022. return false;
  2023. }
  2024. bool
  2025. aot_get_aux_stack(WASMExecEnv *exec_env, uint32 *start_offset, uint32 *size)
  2026. {
  2027. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  2028. AOTModule *module = (AOTModule *)module_inst->module;
  2029. /* The aux stack information is resolved in loader
  2030. and store in module */
  2031. uint32 stack_bottom = module->aux_stack_bottom;
  2032. uint32 total_aux_stack_size = module->aux_stack_size;
  2033. if (stack_bottom != 0 && total_aux_stack_size != 0) {
  2034. if (start_offset)
  2035. *start_offset = stack_bottom;
  2036. if (size)
  2037. *size = total_aux_stack_size;
  2038. return true;
  2039. }
  2040. return false;
  2041. }
  2042. #endif
  2043. #if (WASM_ENABLE_MEMORY_PROFILING != 0) || (WASM_ENABLE_MEMORY_TRACING != 0)
  2044. static void
  2045. const_string_node_size_cb(void *key, void *value, void *p_const_string_size)
  2046. {
  2047. uint32 const_string_size = 0;
  2048. const_string_size += bh_hash_map_get_elem_struct_size();
  2049. const_string_size += strlen((const char *)value) + 1;
  2050. *(uint32 *)p_const_string_size += const_string_size;
  2051. }
  2052. void
  2053. aot_get_module_mem_consumption(const AOTModule *module,
  2054. WASMModuleMemConsumption *mem_conspn)
  2055. {
  2056. uint32 i, size;
  2057. memset(mem_conspn, 0, sizeof(*mem_conspn));
  2058. mem_conspn->module_struct_size = sizeof(AOTModule);
  2059. mem_conspn->types_size = sizeof(AOTFuncType *) * module->func_type_count;
  2060. for (i = 0; i < module->func_type_count; i++) {
  2061. AOTFuncType *type = module->func_types[i];
  2062. size = offsetof(AOTFuncType, types)
  2063. + sizeof(uint8) * (type->param_count + type->result_count);
  2064. mem_conspn->types_size += size;
  2065. }
  2066. mem_conspn->imports_size =
  2067. sizeof(AOTImportMemory) * module->import_memory_count
  2068. + sizeof(AOTImportTable) * module->import_table_count
  2069. + sizeof(AOTImportGlobal) * module->import_global_count
  2070. + sizeof(AOTImportFunc) * module->import_func_count;
  2071. /* func_ptrs and func_type_indexes */
  2072. mem_conspn->functions_size =
  2073. (sizeof(void *) + sizeof(uint32)) * module->func_count;
  2074. mem_conspn->tables_size = sizeof(AOTTable) * module->table_count;
  2075. mem_conspn->memories_size = sizeof(AOTMemory) * module->memory_count;
  2076. mem_conspn->globals_size = sizeof(AOTGlobal) * module->global_count;
  2077. mem_conspn->exports_size = sizeof(AOTExport) * module->export_count;
  2078. mem_conspn->table_segs_size =
  2079. sizeof(AOTTableInitData *) * module->table_init_data_count;
  2080. for (i = 0; i < module->table_init_data_count; i++) {
  2081. AOTTableInitData *init_data = module->table_init_data_list[i];
  2082. size = offsetof(AOTTableInitData, func_indexes)
  2083. + sizeof(uint32) * init_data->func_index_count;
  2084. mem_conspn->table_segs_size += size;
  2085. }
  2086. mem_conspn->data_segs_size =
  2087. sizeof(AOTMemInitData *) * module->mem_init_data_count;
  2088. for (i = 0; i < module->mem_init_data_count; i++) {
  2089. mem_conspn->data_segs_size += sizeof(AOTMemInitData);
  2090. }
  2091. if (module->const_str_set) {
  2092. uint32 const_string_size = 0;
  2093. mem_conspn->const_strs_size =
  2094. bh_hash_map_get_struct_size(module->const_str_set);
  2095. bh_hash_map_traverse(module->const_str_set, const_string_node_size_cb,
  2096. (void *)&const_string_size);
  2097. mem_conspn->const_strs_size += const_string_size;
  2098. }
  2099. /* code size + literal size + object data section size */
  2100. mem_conspn->aot_code_size =
  2101. module->code_size + module->literal_size
  2102. + sizeof(AOTObjectDataSection) * module->data_section_count;
  2103. for (i = 0; i < module->data_section_count; i++) {
  2104. AOTObjectDataSection *obj_data = module->data_sections + i;
  2105. mem_conspn->aot_code_size += sizeof(uint8) * obj_data->size;
  2106. }
  2107. mem_conspn->total_size += mem_conspn->module_struct_size;
  2108. mem_conspn->total_size += mem_conspn->types_size;
  2109. mem_conspn->total_size += mem_conspn->imports_size;
  2110. mem_conspn->total_size += mem_conspn->functions_size;
  2111. mem_conspn->total_size += mem_conspn->tables_size;
  2112. mem_conspn->total_size += mem_conspn->memories_size;
  2113. mem_conspn->total_size += mem_conspn->globals_size;
  2114. mem_conspn->total_size += mem_conspn->exports_size;
  2115. mem_conspn->total_size += mem_conspn->table_segs_size;
  2116. mem_conspn->total_size += mem_conspn->data_segs_size;
  2117. mem_conspn->total_size += mem_conspn->const_strs_size;
  2118. mem_conspn->total_size += mem_conspn->aot_code_size;
  2119. }
  2120. void
  2121. aot_get_module_inst_mem_consumption(const AOTModuleInstance *module_inst,
  2122. WASMModuleInstMemConsumption *mem_conspn)
  2123. {
  2124. AOTTableInstance *tbl_inst;
  2125. uint32 i;
  2126. memset(mem_conspn, 0, sizeof(*mem_conspn));
  2127. mem_conspn->module_inst_struct_size = sizeof(AOTModuleInstance);
  2128. mem_conspn->memories_size =
  2129. sizeof(void *) * module_inst->memory_count
  2130. + sizeof(AOTMemoryInstance) * module_inst->memory_count;
  2131. for (i = 0; i < module_inst->memory_count; i++) {
  2132. AOTMemoryInstance *mem_inst = module_inst->memories[i];
  2133. mem_conspn->memories_size +=
  2134. mem_inst->num_bytes_per_page * mem_inst->cur_page_count;
  2135. mem_conspn->app_heap_size =
  2136. mem_inst->heap_data_end - mem_inst->heap_data;
  2137. /* size of app heap structure */
  2138. mem_conspn->memories_size += mem_allocator_get_heap_struct_size();
  2139. }
  2140. mem_conspn->tables_size +=
  2141. sizeof(AOTTableInstance *) * module_inst->table_count;
  2142. for (i = 0; i < module_inst->table_count; i++) {
  2143. tbl_inst = module_inst->tables[i];
  2144. mem_conspn->tables_size += offsetof(AOTTableInstance, elems);
  2145. mem_conspn->tables_size += sizeof(uint32) * tbl_inst->max_size;
  2146. }
  2147. /* func_ptrs and func_type_indexes */
  2148. mem_conspn->functions_size =
  2149. (sizeof(void *) + sizeof(uint32))
  2150. * (((AOTModule *)module_inst->module)->import_func_count
  2151. + ((AOTModule *)module_inst->module)->func_count);
  2152. mem_conspn->globals_size = module_inst->global_data_size;
  2153. mem_conspn->exports_size =
  2154. sizeof(AOTFunctionInstance) * (uint64)module_inst->export_func_count;
  2155. mem_conspn->total_size += mem_conspn->module_inst_struct_size;
  2156. mem_conspn->total_size += mem_conspn->memories_size;
  2157. mem_conspn->total_size += mem_conspn->functions_size;
  2158. mem_conspn->total_size += mem_conspn->tables_size;
  2159. mem_conspn->total_size += mem_conspn->globals_size;
  2160. mem_conspn->total_size += mem_conspn->exports_size;
  2161. }
  2162. #endif /* end of (WASM_ENABLE_MEMORY_PROFILING != 0) \
  2163. || (WASM_ENABLE_MEMORY_TRACING != 0) */
  2164. #if WASM_ENABLE_REF_TYPES != 0
  2165. void
  2166. aot_drop_table_seg(AOTModuleInstance *module_inst, uint32 tbl_seg_idx)
  2167. {
  2168. AOTModule *module = (AOTModule *)module_inst->module;
  2169. AOTTableInitData *tbl_seg = module->table_init_data_list[tbl_seg_idx];
  2170. tbl_seg->is_dropped = true;
  2171. }
  2172. void
  2173. aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
  2174. uint32 tbl_seg_idx, uint32 length, uint32 src_offset,
  2175. uint32 dst_offset)
  2176. {
  2177. AOTTableInstance *tbl_inst;
  2178. AOTTableInitData *tbl_seg;
  2179. const AOTModule *module = (AOTModule *)module_inst->module;
  2180. tbl_inst = module_inst->tables[tbl_idx];
  2181. bh_assert(tbl_inst);
  2182. tbl_seg = module->table_init_data_list[tbl_seg_idx];
  2183. bh_assert(tbl_seg);
  2184. if (!length) {
  2185. return;
  2186. }
  2187. if (length + src_offset > tbl_seg->func_index_count
  2188. || dst_offset + length > tbl_inst->cur_size) {
  2189. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2190. return;
  2191. }
  2192. if (tbl_seg->is_dropped) {
  2193. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2194. return;
  2195. }
  2196. if (!wasm_elem_is_passive(tbl_seg->mode)) {
  2197. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2198. return;
  2199. }
  2200. bh_memcpy_s((uint8 *)tbl_inst + offsetof(AOTTableInstance, elems)
  2201. + dst_offset * sizeof(uint32),
  2202. (tbl_inst->cur_size - dst_offset) * sizeof(uint32),
  2203. tbl_seg->func_indexes + src_offset, length * sizeof(uint32));
  2204. }
  2205. void
  2206. aot_table_copy(AOTModuleInstance *module_inst, uint32 src_tbl_idx,
  2207. uint32 dst_tbl_idx, uint32 length, uint32 src_offset,
  2208. uint32 dst_offset)
  2209. {
  2210. AOTTableInstance *src_tbl_inst, *dst_tbl_inst;
  2211. src_tbl_inst = module_inst->tables[src_tbl_idx];
  2212. bh_assert(src_tbl_inst);
  2213. dst_tbl_inst = module_inst->tables[dst_tbl_idx];
  2214. bh_assert(dst_tbl_inst);
  2215. if ((uint64)dst_offset + length > dst_tbl_inst->cur_size
  2216. || (uint64)src_offset + length > src_tbl_inst->cur_size) {
  2217. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2218. return;
  2219. }
  2220. /* if src_offset >= dst_offset, copy from front to back */
  2221. /* if src_offset < dst_offset, copy from back to front */
  2222. /* merge all together */
  2223. bh_memmove_s((uint8 *)dst_tbl_inst + offsetof(AOTTableInstance, elems)
  2224. + dst_offset * sizeof(uint32),
  2225. (dst_tbl_inst->cur_size - dst_offset) * sizeof(uint32),
  2226. (uint8 *)src_tbl_inst + offsetof(AOTTableInstance, elems)
  2227. + src_offset * sizeof(uint32),
  2228. length * sizeof(uint32));
  2229. }
  2230. void
  2231. aot_table_fill(AOTModuleInstance *module_inst, uint32 tbl_idx, uint32 length,
  2232. uint32 val, uint32 data_offset)
  2233. {
  2234. AOTTableInstance *tbl_inst;
  2235. tbl_inst = module_inst->tables[tbl_idx];
  2236. bh_assert(tbl_inst);
  2237. if (data_offset + length > tbl_inst->cur_size) {
  2238. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2239. return;
  2240. }
  2241. for (; length != 0; data_offset++, length--) {
  2242. tbl_inst->elems[data_offset] = val;
  2243. }
  2244. }
  2245. uint32
  2246. aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx,
  2247. uint32 inc_entries, uint32 init_val)
  2248. {
  2249. uint32 entry_count, i, orig_tbl_sz;
  2250. AOTTableInstance *tbl_inst;
  2251. tbl_inst = module_inst->tables[tbl_idx];
  2252. if (!tbl_inst) {
  2253. return (uint32)-1;
  2254. }
  2255. orig_tbl_sz = tbl_inst->cur_size;
  2256. if (!inc_entries) {
  2257. return orig_tbl_sz;
  2258. }
  2259. if (tbl_inst->cur_size > UINT32_MAX - inc_entries) {
  2260. return (uint32)-1;
  2261. }
  2262. entry_count = tbl_inst->cur_size + inc_entries;
  2263. if (entry_count > tbl_inst->max_size) {
  2264. return (uint32)-1;
  2265. }
  2266. /* fill in */
  2267. for (i = 0; i < inc_entries; ++i) {
  2268. tbl_inst->elems[tbl_inst->cur_size + i] = init_val;
  2269. }
  2270. tbl_inst->cur_size = entry_count;
  2271. return orig_tbl_sz;
  2272. }
  2273. #endif /* WASM_ENABLE_REF_TYPES != 0 */
  2274. #if (WASM_ENABLE_DUMP_CALL_STACK != 0) || (WASM_ENABLE_PERF_PROFILING != 0)
  2275. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  2276. static const char *
  2277. lookup_func_name(const char **func_names, uint32 *func_indexes,
  2278. uint32 func_index_count, uint32 func_index)
  2279. {
  2280. int64 low = 0, mid;
  2281. int64 high = func_index_count - 1;
  2282. if (!func_names || !func_indexes || func_index_count == 0)
  2283. return NULL;
  2284. while (low <= high) {
  2285. mid = (low + high) / 2;
  2286. if (func_index == func_indexes[mid]) {
  2287. return func_names[mid];
  2288. }
  2289. else if (func_index < func_indexes[mid])
  2290. high = mid - 1;
  2291. else
  2292. low = mid + 1;
  2293. }
  2294. return NULL;
  2295. }
  2296. #endif /* WASM_ENABLE_CUSTOM_NAME_SECTION != 0 */
  2297. static const char *
  2298. get_func_name_from_index(const AOTModuleInstance *module_inst,
  2299. uint32 func_index)
  2300. {
  2301. const char *func_name = NULL;
  2302. AOTModule *module = (AOTModule *)module_inst->module;
  2303. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  2304. if ((func_name =
  2305. lookup_func_name(module->aux_func_names, module->aux_func_indexes,
  2306. module->aux_func_name_count, func_index))) {
  2307. return func_name;
  2308. }
  2309. #endif
  2310. if (func_index < module->import_func_count) {
  2311. func_name = module->import_funcs[func_index].func_name;
  2312. }
  2313. else {
  2314. uint32 i;
  2315. for (i = 0; i < module->export_count; i++) {
  2316. AOTExport export = module->exports[i];
  2317. if (export.index == func_index && export.kind == EXPORT_KIND_FUNC) {
  2318. func_name = export.name;
  2319. break;
  2320. }
  2321. }
  2322. }
  2323. return func_name;
  2324. }
  2325. bool
  2326. aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
  2327. {
  2328. AOTFrame *frame =
  2329. wasm_exec_env_alloc_wasm_frame(exec_env, sizeof(AOTFrame));
  2330. #if WASM_ENABLE_PERF_PROFILING != 0
  2331. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  2332. AOTFuncPerfProfInfo *func_perf_prof =
  2333. module_inst->func_perf_profilings + func_index;
  2334. #endif
  2335. if (!frame) {
  2336. aot_set_exception((AOTModuleInstance *)exec_env->module_inst,
  2337. "auxiliary call stack overflow");
  2338. return false;
  2339. }
  2340. #if WASM_ENABLE_PERF_PROFILING != 0
  2341. frame->time_started = os_time_get_boot_microsecond();
  2342. frame->func_perf_prof_info = func_perf_prof;
  2343. #endif
  2344. frame->prev_frame = (AOTFrame *)exec_env->cur_frame;
  2345. exec_env->cur_frame = (struct WASMInterpFrame *)frame;
  2346. frame->func_index = func_index;
  2347. return true;
  2348. }
  2349. void
  2350. aot_free_frame(WASMExecEnv *exec_env)
  2351. {
  2352. AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame;
  2353. AOTFrame *prev_frame = cur_frame->prev_frame;
  2354. #if WASM_ENABLE_PERF_PROFILING != 0
  2355. cur_frame->func_perf_prof_info->total_exec_time +=
  2356. os_time_get_boot_microsecond() - cur_frame->time_started;
  2357. cur_frame->func_perf_prof_info->total_exec_cnt++;
  2358. #endif
  2359. wasm_exec_env_free_wasm_frame(exec_env, cur_frame);
  2360. exec_env->cur_frame = (struct WASMInterpFrame *)prev_frame;
  2361. }
  2362. #endif /* end of (WASM_ENABLE_DUMP_CALL_STACK != 0) \
  2363. || (WASM_ENABLE_PERF_PROFILING != 0) */
  2364. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  2365. bool
  2366. aot_create_call_stack(struct WASMExecEnv *exec_env)
  2367. {
  2368. AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame,
  2369. *first_frame = cur_frame;
  2370. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  2371. uint32 n = 0;
  2372. while (cur_frame) {
  2373. cur_frame = cur_frame->prev_frame;
  2374. n++;
  2375. }
  2376. /* release previous stack frames and create new ones */
  2377. if (!bh_vector_destroy(module_inst->frames)
  2378. || !bh_vector_init(module_inst->frames, n, sizeof(WASMCApiFrame),
  2379. false)) {
  2380. return false;
  2381. }
  2382. cur_frame = first_frame;
  2383. while (cur_frame) {
  2384. WASMCApiFrame frame = { 0 };
  2385. frame.instance = module_inst;
  2386. frame.module_offset = 0;
  2387. frame.func_index = cur_frame->func_index;
  2388. frame.func_offset = 0;
  2389. frame.func_name_wp =
  2390. get_func_name_from_index(module_inst, cur_frame->func_index);
  2391. if (!bh_vector_append(module_inst->frames, &frame)) {
  2392. bh_vector_destroy(module_inst->frames);
  2393. return false;
  2394. }
  2395. cur_frame = cur_frame->prev_frame;
  2396. }
  2397. return true;
  2398. }
  2399. #define PRINT_OR_DUMP() \
  2400. do { \
  2401. total_len += \
  2402. wasm_runtime_dump_line_buf_impl(line_buf, print, &buf, &len); \
  2403. if ((!print) && buf && (len == 0)) { \
  2404. return total_len; \
  2405. } \
  2406. } while (0)
  2407. uint32
  2408. aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len)
  2409. {
  2410. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  2411. uint32 n = 0, total_len = 0, total_frames;
  2412. /* reserve 256 bytes for line buffer, any line longer than 256 bytes
  2413. * will be truncated */
  2414. char line_buf[256];
  2415. if (!module_inst->frames) {
  2416. return 0;
  2417. }
  2418. total_frames = (uint32)bh_vector_size(module_inst->frames);
  2419. if (total_frames == 0) {
  2420. return 0;
  2421. }
  2422. snprintf(line_buf, sizeof(line_buf), "\n");
  2423. PRINT_OR_DUMP();
  2424. while (n < total_frames) {
  2425. WASMCApiFrame frame = { 0 };
  2426. uint32 line_length, i;
  2427. if (!bh_vector_get(module_inst->frames, n, &frame)) {
  2428. return 0;
  2429. }
  2430. /* function name not exported, print number instead */
  2431. if (frame.func_name_wp == NULL) {
  2432. line_length =
  2433. snprintf(line_buf, sizeof(line_buf),
  2434. "#%02" PRIu32 " $f%" PRIu32 "\n", n, frame.func_index);
  2435. }
  2436. else {
  2437. line_length =
  2438. snprintf(line_buf, sizeof(line_buf), "#%02" PRIu32 " %s\n", n,
  2439. frame.func_name_wp);
  2440. }
  2441. if (line_length >= sizeof(line_buf)) {
  2442. uint32 line_buffer_len = sizeof(line_buf);
  2443. /* If line too long, ensure the last character is '\n' */
  2444. for (i = line_buffer_len - 5; i < line_buffer_len - 2; i++) {
  2445. line_buf[i] = '.';
  2446. }
  2447. line_buf[line_buffer_len - 2] = '\n';
  2448. }
  2449. PRINT_OR_DUMP();
  2450. n++;
  2451. }
  2452. snprintf(line_buf, sizeof(line_buf), "\n");
  2453. PRINT_OR_DUMP();
  2454. return total_len + 1;
  2455. }
  2456. #endif /* end of WASM_ENABLE_DUMP_CALL_STACK */
  2457. #if WASM_ENABLE_PERF_PROFILING != 0
  2458. void
  2459. aot_dump_perf_profiling(const AOTModuleInstance *module_inst)
  2460. {
  2461. AOTFuncPerfProfInfo *perf_prof =
  2462. (AOTFuncPerfProfInfo *)module_inst->func_perf_profilings;
  2463. AOTModule *module = (AOTModule *)module_inst->module;
  2464. uint32 total_func_count = module->import_func_count + module->func_count, i;
  2465. const char *func_name;
  2466. os_printf("Performance profiler data:\n");
  2467. for (i = 0; i < total_func_count; i++, perf_prof++) {
  2468. func_name = get_func_name_from_index(module_inst, i);
  2469. if (func_name)
  2470. os_printf(" func %s, execution time: %.3f ms, execution count: %d "
  2471. "times\n",
  2472. func_name, perf_prof->total_exec_time / 1000.0f,
  2473. perf_prof->total_exec_cnt);
  2474. else
  2475. os_printf(" func %d, execution time: %.3f ms, execution count: %d "
  2476. "times\n",
  2477. i, perf_prof->total_exec_time / 1000.0f,
  2478. perf_prof->total_exec_cnt);
  2479. }
  2480. }
  2481. #endif /* end of WASM_ENABLE_PERF_PROFILING */
  2482. #if WASM_ENABLE_STATIC_PGO != 0
  2483. /* indirect call target */
  2484. #define IPVK_IndirectCallTarget 0
  2485. /* memory intrinsic functions size */
  2486. #define IPVK_MemOPSize 1
  2487. #define IPVK_First IPVK_IndirectCallTarget
  2488. #define IPVK_Last IPVK_MemOPSize
  2489. #define INSTR_PROF_DEFAULT_NUM_VAL_PER_SITE 24
  2490. #define INSTR_PROF_MAX_NUM_VAL_PER_SITE 255
  2491. static int hasNonDefaultValsPerSite = 0;
  2492. static uint32 VPMaxNumValsPerSite = INSTR_PROF_DEFAULT_NUM_VAL_PER_SITE;
  2493. static bool
  2494. cmpxchg_ptr(void **ptr, void *old_val, void *new_val)
  2495. {
  2496. #if defined(os_atomic_cmpxchg)
  2497. return os_atomic_cmpxchg(ptr, &old_val, new_val);
  2498. #else
  2499. /* TODO: add lock when thread-manager is enabled */
  2500. void *read = *ptr;
  2501. if (read == old_val) {
  2502. *ptr = new_val;
  2503. return true;
  2504. }
  2505. return false;
  2506. #endif
  2507. }
  2508. static int
  2509. allocateValueProfileCounters(LLVMProfileData *Data)
  2510. {
  2511. ValueProfNode **Mem;
  2512. uint64 NumVSites = 0, total_size;
  2513. uint32 VKI;
  2514. /* When dynamic allocation is enabled, allow tracking the max number of
  2515. values allowed. */
  2516. if (!hasNonDefaultValsPerSite)
  2517. VPMaxNumValsPerSite = INSTR_PROF_MAX_NUM_VAL_PER_SITE;
  2518. for (VKI = IPVK_First; VKI <= IPVK_Last; ++VKI)
  2519. NumVSites += Data->num_value_sites[VKI];
  2520. /* If NumVSites = 0, calloc is allowed to return a non-null pointer. */
  2521. bh_assert(NumVSites > 0 && "NumVSites can't be zero");
  2522. total_size = (uint64)sizeof(ValueProfNode *) * NumVSites;
  2523. if (total_size > UINT32_MAX
  2524. || !(Mem = (ValueProfNode **)wasm_runtime_malloc((uint32)total_size))) {
  2525. return 0;
  2526. }
  2527. memset(Mem, 0, (uint32)total_size);
  2528. if (!cmpxchg_ptr((void **)&Data->values, NULL, Mem)) {
  2529. wasm_runtime_free(Mem);
  2530. return 0;
  2531. }
  2532. return 1;
  2533. }
  2534. static ValueProfNode *
  2535. allocateOneNode(void)
  2536. {
  2537. ValueProfNode *Node;
  2538. Node = wasm_runtime_malloc((uint32)sizeof(ValueProfNode));
  2539. if (Node)
  2540. memset(Node, 0, sizeof(ValueProfNode));
  2541. return Node;
  2542. }
  2543. static void
  2544. instrumentTargetValueImpl(uint64 TargetValue, void *Data, uint32 CounterIndex,
  2545. uint64 CountValue)
  2546. {
  2547. ValueProfNode **ValueCounters;
  2548. ValueProfNode *PrevVNode = NULL, *MinCountVNode = NULL, *CurVNode;
  2549. LLVMProfileData *PData = (LLVMProfileData *)Data;
  2550. uint64 MinCount = UINT64_MAX;
  2551. uint8 VDataCount = 0;
  2552. bool success = false;
  2553. if (!PData)
  2554. return;
  2555. if (!CountValue)
  2556. return;
  2557. if (!PData->values) {
  2558. if (!allocateValueProfileCounters(PData))
  2559. return;
  2560. }
  2561. ValueCounters = (ValueProfNode **)PData->values;
  2562. CurVNode = ValueCounters[CounterIndex];
  2563. while (CurVNode) {
  2564. if (TargetValue == CurVNode->value) {
  2565. CurVNode->count += CountValue;
  2566. return;
  2567. }
  2568. if (CurVNode->count < MinCount) {
  2569. MinCount = CurVNode->count;
  2570. MinCountVNode = CurVNode;
  2571. }
  2572. PrevVNode = CurVNode;
  2573. CurVNode = CurVNode->next;
  2574. ++VDataCount;
  2575. }
  2576. if (VDataCount >= VPMaxNumValsPerSite) {
  2577. if (MinCountVNode->count <= CountValue) {
  2578. CurVNode = MinCountVNode;
  2579. CurVNode->value = TargetValue;
  2580. CurVNode->count = CountValue;
  2581. }
  2582. else
  2583. MinCountVNode->count -= CountValue;
  2584. return;
  2585. }
  2586. CurVNode = allocateOneNode();
  2587. if (!CurVNode)
  2588. return;
  2589. CurVNode->value = TargetValue;
  2590. CurVNode->count += CountValue;
  2591. if (!ValueCounters[CounterIndex]) {
  2592. success =
  2593. cmpxchg_ptr((void **)&ValueCounters[CounterIndex], NULL, CurVNode);
  2594. }
  2595. else if (PrevVNode && !PrevVNode->next) {
  2596. success = cmpxchg_ptr((void **)&PrevVNode->next, 0, CurVNode);
  2597. }
  2598. if (!success) {
  2599. wasm_runtime_free(CurVNode);
  2600. }
  2601. }
  2602. void
  2603. llvm_profile_instrument_target(uint64 target_value, void *data,
  2604. uint32 counter_idx)
  2605. {
  2606. instrumentTargetValueImpl(target_value, data, counter_idx, 1);
  2607. }
  2608. static inline uint32
  2609. popcount64(uint64 u)
  2610. {
  2611. uint32 ret = 0;
  2612. while (u) {
  2613. u = (u & (u - 1));
  2614. ret++;
  2615. }
  2616. return ret;
  2617. }
  2618. static inline uint32
  2619. clz64(uint64 type)
  2620. {
  2621. uint32 num = 0;
  2622. if (type == 0)
  2623. return 64;
  2624. while (!(type & 0x8000000000000000LL)) {
  2625. num++;
  2626. type <<= 1;
  2627. }
  2628. return num;
  2629. }
  2630. /* Map an (observed) memop size value to the representative value of its range.
  2631. For example, 5 -> 5, 22 -> 17, 99 -> 65, 256 -> 256, 1001 -> 513. */
  2632. static uint64
  2633. InstrProfGetRangeRepValue(uint64 Value)
  2634. {
  2635. if (Value <= 8)
  2636. /* The first ranges are individually tracked. Use the value as is. */
  2637. return Value;
  2638. else if (Value >= 513)
  2639. /* The last range is mapped to its lowest value. */
  2640. return 513;
  2641. else if (popcount64(Value) == 1)
  2642. /* If it's a power of two, use it as is. */
  2643. return Value;
  2644. else
  2645. /* Otherwise, take to the previous power of two + 1. */
  2646. return (((uint64)1) << (64 - clz64(Value) - 1)) + 1;
  2647. }
  2648. void
  2649. llvm_profile_instrument_memop(uint64 target_value, void *data,
  2650. uint32 counter_idx)
  2651. {
  2652. uint64 rep_value = InstrProfGetRangeRepValue(target_value);
  2653. instrumentTargetValueImpl(rep_value, data, counter_idx, 1);
  2654. }
  2655. static uint32
  2656. get_pgo_prof_data_size(AOTModuleInstance *module_inst, uint32 *p_num_prof_data,
  2657. uint32 *p_num_prof_counters, uint32 *p_padding_size,
  2658. uint32 *p_prof_counters_size, uint32 *p_prof_names_size,
  2659. uint32 *p_value_counters_size, uint8 **p_prof_names)
  2660. {
  2661. AOTModule *module = (AOTModule *)module_inst->module;
  2662. LLVMProfileData *prof_data;
  2663. uint8 *prof_names = NULL;
  2664. uint32 num_prof_data = 0, num_prof_counters = 0, padding_size, i;
  2665. uint32 prof_counters_size = 0, prof_names_size = 0;
  2666. uint32 total_size, total_size_wo_value_counters;
  2667. for (i = 0; i < module->data_section_count; i++) {
  2668. if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
  2669. bh_assert(module->data_sections[i].size == sizeof(LLVMProfileData));
  2670. num_prof_data++;
  2671. prof_data = (LLVMProfileData *)module->data_sections[i].data;
  2672. num_prof_counters += prof_data->num_counters;
  2673. }
  2674. else if (!strncmp(module->data_sections[i].name, "__llvm_prf_cnts",
  2675. 15)) {
  2676. prof_counters_size += module->data_sections[i].size;
  2677. }
  2678. else if (!strncmp(module->data_sections[i].name, "__llvm_prf_names",
  2679. 16)) {
  2680. prof_names_size = module->data_sections[i].size;
  2681. prof_names = module->data_sections[i].data;
  2682. }
  2683. }
  2684. if (prof_counters_size != num_prof_counters * sizeof(uint64))
  2685. return 0;
  2686. total_size = sizeof(LLVMProfileRawHeader)
  2687. + num_prof_data * sizeof(LLVMProfileData_64)
  2688. + prof_counters_size + prof_names_size;
  2689. padding_size = sizeof(uint64) - (prof_names_size % sizeof(uint64));
  2690. if (padding_size != sizeof(uint64))
  2691. total_size += padding_size;
  2692. /* Total size excluding value counters */
  2693. total_size_wo_value_counters = total_size;
  2694. for (i = 0; i < module->data_section_count; i++) {
  2695. if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
  2696. uint32 j, k, num_value_sites, num_value_nodes;
  2697. ValueProfNode **values, *value_node;
  2698. prof_data = (LLVMProfileData *)module->data_sections[i].data;
  2699. values = prof_data->values;
  2700. if (prof_data->num_value_sites[0] > 0
  2701. || prof_data->num_value_sites[1] > 0) {
  2702. /* TotalSize (uint32) and NumValueKinds (uint32) */
  2703. total_size += 8;
  2704. for (j = 0; j < 2; j++) {
  2705. if ((num_value_sites = prof_data->num_value_sites[j]) > 0) {
  2706. /* ValueKind (uint32) and NumValueSites (uint32) */
  2707. total_size += 8;
  2708. /* (Value + Counter) group counts of each value site,
  2709. each count is one byte */
  2710. total_size += align_uint(num_value_sites, 8);
  2711. if (values) {
  2712. for (k = 0; k < num_value_sites; k++) {
  2713. num_value_nodes = 0;
  2714. value_node = *values;
  2715. while (value_node) {
  2716. num_value_nodes++;
  2717. value_node = value_node->next;
  2718. }
  2719. if (num_value_nodes) {
  2720. /* (Value + Counter) groups */
  2721. total_size += num_value_nodes * 8 * 2;
  2722. }
  2723. values++;
  2724. }
  2725. }
  2726. }
  2727. }
  2728. }
  2729. }
  2730. }
  2731. if (p_num_prof_data)
  2732. *p_num_prof_data = num_prof_data;
  2733. if (p_num_prof_counters)
  2734. *p_num_prof_counters = num_prof_counters;
  2735. if (p_padding_size)
  2736. *p_padding_size = padding_size;
  2737. if (p_prof_counters_size)
  2738. *p_prof_counters_size = prof_counters_size;
  2739. if (p_prof_names_size)
  2740. *p_prof_names_size = prof_names_size;
  2741. if (p_value_counters_size)
  2742. *p_value_counters_size = total_size - total_size_wo_value_counters;
  2743. if (p_prof_names)
  2744. *p_prof_names = prof_names;
  2745. return total_size;
  2746. }
  2747. uint32
  2748. aot_get_pgo_prof_data_size(AOTModuleInstance *module_inst)
  2749. {
  2750. return get_pgo_prof_data_size(module_inst, NULL, NULL, NULL, NULL, NULL,
  2751. NULL, NULL);
  2752. }
  2753. static union {
  2754. int a;
  2755. char b;
  2756. } __ue = { .a = 1 };
  2757. #define is_little_endian() (__ue.b == 1)
  2758. uint32
  2759. aot_dump_pgo_prof_data_to_buf(AOTModuleInstance *module_inst, char *buf,
  2760. uint32 len)
  2761. {
  2762. AOTModule *module = (AOTModule *)module_inst->module;
  2763. LLVMProfileRawHeader prof_header = { 0 };
  2764. LLVMProfileData *prof_data;
  2765. uint8 *prof_names = NULL;
  2766. uint32 num_prof_data = 0, num_prof_counters = 0, padding_size, i;
  2767. uint32 prof_counters_size = 0, prof_names_size = 0;
  2768. uint32 value_counters_size = 0, value_counters_size_backup = 0;
  2769. uint32 total_size, size;
  2770. int64 counters_delta, offset_counters;
  2771. total_size = get_pgo_prof_data_size(module_inst, &num_prof_data,
  2772. &num_prof_counters, &padding_size,
  2773. &prof_counters_size, &prof_names_size,
  2774. &value_counters_size, &prof_names);
  2775. if (len < total_size)
  2776. return 0;
  2777. value_counters_size_backup = value_counters_size;
  2778. value_counters_size = 0;
  2779. prof_header.counters_delta = counters_delta =
  2780. sizeof(LLVMProfileData_64) * num_prof_data;
  2781. offset_counters = 0;
  2782. for (i = 0; i < module->data_section_count; i++) {
  2783. if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
  2784. prof_data = (LLVMProfileData *)module->data_sections[i].data;
  2785. prof_data->offset_counters = counters_delta + offset_counters;
  2786. offset_counters += prof_data->num_counters * sizeof(uint64);
  2787. counters_delta -= sizeof(LLVMProfileData_64);
  2788. }
  2789. }
  2790. prof_header.magic = 0xFF6C70726F667281LL;
  2791. /* Version 8 */
  2792. prof_header.version = 0x0000000000000008LL;
  2793. /* with VARIANT_MASK_IR_PROF (IR Instrumentation) */
  2794. prof_header.version |= 0x1ULL << 56;
  2795. /* with VARIANT_MASK_MEMPROF (Memory Profile) */
  2796. prof_header.version |= 0x1ULL << 62;
  2797. prof_header.num_prof_data = num_prof_data;
  2798. prof_header.num_prof_counters = num_prof_counters;
  2799. prof_header.names_size = prof_names_size;
  2800. prof_header.value_kind_last = 1;
  2801. if (!is_little_endian()) {
  2802. aot_exchange_uint64((uint8 *)&prof_header.magic);
  2803. aot_exchange_uint64((uint8 *)&prof_header.version);
  2804. aot_exchange_uint64((uint8 *)&prof_header.num_prof_data);
  2805. aot_exchange_uint64((uint8 *)&prof_header.num_prof_counters);
  2806. aot_exchange_uint64((uint8 *)&prof_header.names_size);
  2807. aot_exchange_uint64((uint8 *)&prof_header.counters_delta);
  2808. aot_exchange_uint64((uint8 *)&prof_header.value_kind_last);
  2809. }
  2810. size = sizeof(LLVMProfileRawHeader);
  2811. bh_memcpy_s(buf, size, &prof_header, size);
  2812. buf += size;
  2813. for (i = 0; i < module->data_section_count; i++) {
  2814. if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
  2815. LLVMProfileData_64 *prof_data_64 = (LLVMProfileData_64 *)buf;
  2816. /* Convert LLVMProfileData to LLVMProfileData_64, the pointer width
  2817. in the output file is alawys 8 bytes */
  2818. prof_data = (LLVMProfileData *)module->data_sections[i].data;
  2819. prof_data_64->func_md5 = prof_data->func_md5;
  2820. prof_data_64->func_hash = prof_data->func_hash;
  2821. prof_data_64->offset_counters = prof_data->offset_counters;
  2822. prof_data_64->func_ptr = prof_data->func_ptr;
  2823. prof_data_64->values = (uint64)(uintptr_t)prof_data->values;
  2824. prof_data_64->num_counters = prof_data->num_counters;
  2825. prof_data_64->num_value_sites[0] = prof_data->num_value_sites[0];
  2826. prof_data_64->num_value_sites[1] = prof_data->num_value_sites[1];
  2827. if (!is_little_endian()) {
  2828. aot_exchange_uint64((uint8 *)&prof_data_64->func_hash);
  2829. aot_exchange_uint64((uint8 *)&prof_data_64->offset_counters);
  2830. aot_exchange_uint64((uint8 *)&prof_data_64->offset_counters);
  2831. aot_exchange_uint64((uint8 *)&prof_data_64->func_ptr);
  2832. aot_exchange_uint64((uint8 *)&prof_data_64->values);
  2833. aot_exchange_uint32((uint8 *)&prof_data_64->num_counters);
  2834. aot_exchange_uint16((uint8 *)&prof_data_64->num_value_sites[0]);
  2835. aot_exchange_uint16((uint8 *)&prof_data_64->num_value_sites[1]);
  2836. }
  2837. buf += sizeof(LLVMProfileData_64);
  2838. }
  2839. }
  2840. for (i = 0; i < module->data_section_count; i++) {
  2841. if (!strncmp(module->data_sections[i].name, "__llvm_prf_cnts", 15)) {
  2842. size = module->data_sections[i].size;
  2843. bh_memcpy_s(buf, size, module->data_sections[i].data, size);
  2844. buf += size;
  2845. }
  2846. }
  2847. if (prof_names && prof_names_size > 0) {
  2848. size = prof_names_size;
  2849. bh_memcpy_s(buf, size, prof_names, size);
  2850. buf += size;
  2851. padding_size = sizeof(uint64) - (prof_names_size % sizeof(uint64));
  2852. if (padding_size != sizeof(uint64)) {
  2853. char padding_buf[8] = { 0 };
  2854. bh_memcpy_s(buf, padding_size, padding_buf, padding_size);
  2855. buf += padding_size;
  2856. }
  2857. }
  2858. for (i = 0; i < module->data_section_count; i++) {
  2859. if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
  2860. uint32 j, k, num_value_sites, num_value_nodes;
  2861. ValueProfNode **values, **values_tmp, *value_node;
  2862. prof_data = (LLVMProfileData *)module->data_sections[i].data;
  2863. values = values_tmp = prof_data->values;
  2864. if (prof_data->num_value_sites[0] > 0
  2865. || prof_data->num_value_sites[1] > 0) {
  2866. uint32 *buf_total_size = (uint32 *)buf;
  2867. buf += 4; /* emit TotalSize later */
  2868. *(uint32 *)buf = (prof_data->num_value_sites[0] > 0
  2869. && prof_data->num_value_sites[1] > 0)
  2870. ? 2
  2871. : 1;
  2872. if (!is_little_endian())
  2873. aot_exchange_uint32((uint8 *)buf);
  2874. buf += 4;
  2875. for (j = 0; j < 2; j++) {
  2876. if ((num_value_sites = prof_data->num_value_sites[j]) > 0) {
  2877. /* ValueKind */
  2878. *(uint32 *)buf = j;
  2879. if (!is_little_endian())
  2880. aot_exchange_uint32((uint8 *)buf);
  2881. buf += 4;
  2882. /* NumValueSites */
  2883. *(uint32 *)buf = num_value_sites;
  2884. if (!is_little_endian())
  2885. aot_exchange_uint32((uint8 *)buf);
  2886. buf += 4;
  2887. for (k = 0; k < num_value_sites; k++) {
  2888. num_value_nodes = 0;
  2889. if (values_tmp) {
  2890. value_node = *values_tmp;
  2891. while (value_node) {
  2892. num_value_nodes++;
  2893. value_node = value_node->next;
  2894. }
  2895. values_tmp++;
  2896. }
  2897. bh_assert(num_value_nodes < 255);
  2898. *(uint8 *)buf++ = (uint8)num_value_nodes;
  2899. }
  2900. if (num_value_sites % 8) {
  2901. buf += 8 - (num_value_sites % 8);
  2902. }
  2903. for (k = 0; k < num_value_sites; k++) {
  2904. if (values) {
  2905. value_node = *values;
  2906. while (value_node) {
  2907. *(uint64 *)buf = value_node->value;
  2908. if (!is_little_endian())
  2909. aot_exchange_uint64((uint8 *)buf);
  2910. buf += 8;
  2911. *(uint64 *)buf = value_node->count;
  2912. if (!is_little_endian())
  2913. aot_exchange_uint64((uint8 *)buf);
  2914. buf += 8;
  2915. value_node = value_node->next;
  2916. }
  2917. values++;
  2918. }
  2919. }
  2920. }
  2921. }
  2922. /* TotalSize */
  2923. *(uint32 *)buf_total_size =
  2924. (uint8 *)buf - (uint8 *)buf_total_size;
  2925. if (!is_little_endian())
  2926. aot_exchange_uint64((uint8 *)buf_total_size);
  2927. value_counters_size += (uint8 *)buf - (uint8 *)buf_total_size;
  2928. }
  2929. }
  2930. }
  2931. bh_assert(value_counters_size == value_counters_size_backup);
  2932. (void)value_counters_size_backup;
  2933. return total_size;
  2934. }
  2935. #endif /* end of WASM_ENABLE_STATIC_PGO != 0 */