aot_runtime.c 106 KB

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