aot_runtime.c 130 KB

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