aot_runtime.c 164 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_runtime.h"
  6. #include "bh_log.h"
  7. #include "mem_alloc.h"
  8. #include "../common/wasm_runtime_common.h"
  9. #include "../common/wasm_memory.h"
  10. #include "../interpreter/wasm_runtime.h"
  11. #if WASM_ENABLE_SHARED_MEMORY != 0
  12. #include "../common/wasm_shared_memory.h"
  13. #endif
  14. #if WASM_ENABLE_THREAD_MGR != 0
  15. #include "../libraries/thread-mgr/thread_manager.h"
  16. #endif
  17. /*
  18. * Note: These offsets need to match the values hardcoded in
  19. * AoT compilation code: aot_create_func_context, check_suspend_flags.
  20. */
  21. bh_static_assert(offsetof(WASMExecEnv, cur_frame) == 1 * sizeof(uintptr_t));
  22. bh_static_assert(offsetof(WASMExecEnv, module_inst) == 2 * sizeof(uintptr_t));
  23. bh_static_assert(offsetof(WASMExecEnv, argv_buf) == 3 * sizeof(uintptr_t));
  24. bh_static_assert(offsetof(WASMExecEnv, native_stack_boundary)
  25. == 4 * sizeof(uintptr_t));
  26. bh_static_assert(offsetof(WASMExecEnv, suspend_flags) == 5 * sizeof(uintptr_t));
  27. bh_static_assert(offsetof(WASMExecEnv, aux_stack_boundary)
  28. == 6 * sizeof(uintptr_t));
  29. bh_static_assert(offsetof(WASMExecEnv, aux_stack_bottom)
  30. == 7 * sizeof(uintptr_t));
  31. bh_static_assert(offsetof(WASMExecEnv, native_symbol) == 8 * sizeof(uintptr_t));
  32. bh_static_assert(offsetof(WASMExecEnv, native_stack_top_min)
  33. == 9 * sizeof(uintptr_t));
  34. bh_static_assert(offsetof(WASMExecEnv, wasm_stack.top_boundary)
  35. == 10 * sizeof(uintptr_t));
  36. bh_static_assert(offsetof(WASMExecEnv, wasm_stack.top)
  37. == 11 * sizeof(uintptr_t));
  38. bh_static_assert(offsetof(WASMExecEnv, wasm_stack.bottom)
  39. == 12 * sizeof(uintptr_t));
  40. bh_static_assert(offsetof(AOTModuleInstance, memories) == 1 * sizeof(uint64));
  41. bh_static_assert(offsetof(AOTModuleInstance, func_ptrs) == 5 * sizeof(uint64));
  42. bh_static_assert(offsetof(AOTModuleInstance, func_type_indexes)
  43. == 6 * sizeof(uint64));
  44. bh_static_assert(offsetof(AOTModuleInstance, cur_exception)
  45. == 13 * sizeof(uint64));
  46. bh_static_assert(offsetof(AOTModuleInstance, c_api_func_imports)
  47. == 13 * sizeof(uint64) + 128 + 7 * sizeof(uint64));
  48. bh_static_assert(offsetof(AOTModuleInstance, global_table_data)
  49. == 13 * sizeof(uint64) + 128 + 14 * sizeof(uint64));
  50. bh_static_assert(sizeof(AOTMemoryInstance) == 120);
  51. bh_static_assert(offsetof(AOTTableInstance, elems) == 24);
  52. bh_static_assert(offsetof(AOTModuleInstanceExtra, stack_sizes) == 0);
  53. bh_static_assert(sizeof(CApiFuncImport) == sizeof(uintptr_t) * 3);
  54. bh_static_assert(sizeof(wasm_val_t) == 16);
  55. bh_static_assert(offsetof(wasm_val_t, of) == 8);
  56. bh_static_assert(offsetof(AOTFrame, prev_frame) == sizeof(uintptr_t) * 0);
  57. bh_static_assert(offsetof(AOTFrame, func_index) == sizeof(uintptr_t) * 1);
  58. bh_static_assert(offsetof(AOTFrame, time_started) == sizeof(uintptr_t) * 2);
  59. bh_static_assert(offsetof(AOTFrame, func_perf_prof_info)
  60. == sizeof(uintptr_t) * 3);
  61. bh_static_assert(offsetof(AOTFrame, ip_offset) == sizeof(uintptr_t) * 4);
  62. bh_static_assert(offsetof(AOTFrame, sp) == sizeof(uintptr_t) * 5);
  63. bh_static_assert(offsetof(AOTFrame, frame_ref) == sizeof(uintptr_t) * 6);
  64. bh_static_assert(offsetof(AOTFrame, lp) == sizeof(uintptr_t) * 7);
  65. static void
  66. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  67. {
  68. if (error_buf != NULL) {
  69. snprintf(error_buf, error_buf_size, "AOT module instantiate failed: %s",
  70. string);
  71. }
  72. }
  73. static void
  74. set_error_buf_v(char *error_buf, uint32 error_buf_size, const char *format, ...)
  75. {
  76. va_list args;
  77. char buf[128];
  78. if (error_buf != NULL) {
  79. va_start(args, format);
  80. vsnprintf(buf, sizeof(buf), format, args);
  81. va_end(args);
  82. snprintf(error_buf, error_buf_size, "AOT module instantiate failed: %s",
  83. buf);
  84. }
  85. }
  86. static void *
  87. runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
  88. {
  89. void *mem;
  90. if (size >= UINT32_MAX || !(mem = wasm_runtime_malloc((uint32)size))) {
  91. set_error_buf(error_buf, error_buf_size, "allocate memory failed");
  92. return NULL;
  93. }
  94. memset(mem, 0, (uint32)size);
  95. return mem;
  96. }
  97. static bool
  98. check_global_init_expr(const AOTModule *module, uint32 global_index,
  99. char *error_buf, uint32 error_buf_size)
  100. {
  101. if (global_index >= module->import_global_count + module->global_count) {
  102. set_error_buf_v(error_buf, error_buf_size, "unknown global %d",
  103. global_index);
  104. return false;
  105. }
  106. #if WASM_ENABLE_GC == 0
  107. /**
  108. * Currently, constant expressions occurring as initializers of
  109. * globals are further constrained in that contained global.get
  110. * instructions are only allowed to refer to imported globals.
  111. *
  112. * And initializer expression cannot reference a mutable global.
  113. */
  114. if (global_index >= module->import_global_count
  115. || module->import_globals->type.is_mutable) {
  116. set_error_buf(error_buf, error_buf_size,
  117. "constant expression required");
  118. return false;
  119. }
  120. #else
  121. if (global_index >= module->import_global_count + module->global_count) {
  122. set_error_buf_v(error_buf, error_buf_size, "unknown global %u",
  123. global_index);
  124. return false;
  125. }
  126. if (global_index < module->import_global_count
  127. && module->import_globals[global_index].type.is_mutable) {
  128. set_error_buf(error_buf, error_buf_size,
  129. "constant expression required");
  130. return false;
  131. }
  132. #endif
  133. return true;
  134. }
  135. static void
  136. init_global_data(uint8 *global_data, uint8 type, WASMValue *initial_value)
  137. {
  138. switch (type) {
  139. case VALUE_TYPE_I32:
  140. case VALUE_TYPE_F32:
  141. #if WASM_ENABLE_REF_TYPES != 0
  142. case VALUE_TYPE_FUNCREF:
  143. case VALUE_TYPE_EXTERNREF:
  144. #endif
  145. *(int32 *)global_data = initial_value->i32;
  146. break;
  147. case VALUE_TYPE_I64:
  148. case VALUE_TYPE_F64:
  149. bh_memcpy_s(global_data, sizeof(int64), &initial_value->i64,
  150. sizeof(int64));
  151. break;
  152. #if WASM_ENABLE_SIMD != 0
  153. case VALUE_TYPE_V128:
  154. bh_memcpy_s(global_data, sizeof(V128), &initial_value->v128,
  155. sizeof(V128));
  156. break;
  157. #endif
  158. default:
  159. #if WASM_ENABLE_GC != 0
  160. if ((type >= (uint8)REF_TYPE_ARRAYREF
  161. && type <= (uint8)REF_TYPE_NULLFUNCREF)
  162. || (type >= (uint8)REF_TYPE_HT_NULLABLE
  163. && type <= (uint8)REF_TYPE_HT_NON_NULLABLE)
  164. #if WASM_ENABLE_STRINGREF != 0
  165. || (type >= (uint8)REF_TYPE_STRINGVIEWWTF8
  166. && type <= (uint8)REF_TYPE_STRINGREF)
  167. || (type >= (uint8)REF_TYPE_STRINGVIEWITER
  168. && type <= (uint8)REF_TYPE_STRINGVIEWWTF16)
  169. #endif
  170. ) {
  171. bh_memcpy_s(global_data, sizeof(wasm_obj_t),
  172. &initial_value->gc_obj, sizeof(wasm_obj_t));
  173. break;
  174. }
  175. #endif /* end of WASM_ENABLE_GC */
  176. bh_assert(0);
  177. }
  178. }
  179. #if WASM_ENABLE_GC != 0
  180. static bool
  181. assign_table_init_value(AOTModuleInstance *module_inst, AOTModule *module,
  182. InitializerExpression *init_expr, void *addr,
  183. char *error_buf, uint32 error_buf_size)
  184. {
  185. uint8 flag = init_expr->init_expr_type;
  186. bh_assert(flag >= INIT_EXPR_TYPE_GET_GLOBAL
  187. && flag <= INIT_EXPR_TYPE_EXTERN_CONVERT_ANY);
  188. switch (flag) {
  189. case INIT_EXPR_TYPE_GET_GLOBAL:
  190. {
  191. if (!check_global_init_expr(module, init_expr->u.global_index,
  192. error_buf, error_buf_size)) {
  193. return false;
  194. }
  195. if (init_expr->u.global_index < module->import_global_count) {
  196. PUT_REF_TO_ADDR(
  197. addr, module->import_globals[init_expr->u.global_index]
  198. .global_data_linked.gc_obj);
  199. }
  200. else {
  201. uint32 global_idx =
  202. init_expr->u.global_index - module->import_global_count;
  203. return assign_table_init_value(
  204. module_inst, module, &module->globals[global_idx].init_expr,
  205. addr, error_buf, error_buf_size);
  206. }
  207. break;
  208. }
  209. case INIT_EXPR_TYPE_REFNULL_CONST:
  210. {
  211. WASMObjectRef gc_obj = NULL_REF;
  212. PUT_REF_TO_ADDR(addr, gc_obj);
  213. break;
  214. }
  215. case INIT_EXPR_TYPE_FUNCREF_CONST:
  216. {
  217. WASMFuncObjectRef func_obj = NULL;
  218. uint32 func_idx = init_expr->u.u32;
  219. if (func_idx != UINT32_MAX) {
  220. if (!(func_obj =
  221. aot_create_func_obj(module_inst, func_idx, false,
  222. error_buf, error_buf_size))) {
  223. return false;
  224. }
  225. }
  226. PUT_REF_TO_ADDR(addr, func_obj);
  227. break;
  228. }
  229. case INIT_EXPR_TYPE_I31_NEW:
  230. {
  231. WASMI31ObjectRef i31_obj = wasm_i31_obj_new(init_expr->u.i32);
  232. PUT_REF_TO_ADDR(addr, i31_obj);
  233. break;
  234. }
  235. case INIT_EXPR_TYPE_STRUCT_NEW:
  236. case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
  237. {
  238. WASMRttType *rtt_type;
  239. WASMStructObjectRef struct_obj;
  240. WASMStructType *struct_type;
  241. WASMStructNewInitValues *init_values = NULL;
  242. uint32 type_idx;
  243. if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
  244. init_values = (WASMStructNewInitValues *)init_expr->u.data;
  245. type_idx = init_values->type_idx;
  246. }
  247. else {
  248. type_idx = init_expr->u.type_index;
  249. }
  250. struct_type = (WASMStructType *)module->types[type_idx];
  251. if (!(rtt_type = wasm_rtt_type_new(
  252. (WASMType *)struct_type, type_idx, module->rtt_types,
  253. module->type_count, &module->rtt_type_lock))) {
  254. set_error_buf(error_buf, error_buf_size,
  255. "create rtt object failed");
  256. return false;
  257. }
  258. if (!(struct_obj = wasm_struct_obj_new_internal(
  259. ((AOTModuleInstanceExtra *)module_inst->e)
  260. ->common.gc_heap_handle,
  261. rtt_type))) {
  262. set_error_buf(error_buf, error_buf_size,
  263. "create struct object failed");
  264. return false;
  265. }
  266. if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
  267. uint32 field_idx;
  268. bh_assert(init_values->count == struct_type->field_count);
  269. for (field_idx = 0; field_idx < init_values->count;
  270. field_idx++) {
  271. wasm_struct_obj_set_field(struct_obj, field_idx,
  272. &init_values->fields[field_idx]);
  273. }
  274. }
  275. PUT_REF_TO_ADDR(addr, struct_obj);
  276. break;
  277. }
  278. case INIT_EXPR_TYPE_ARRAY_NEW:
  279. case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
  280. case INIT_EXPR_TYPE_ARRAY_NEW_FIXED:
  281. {
  282. WASMRttType *rtt_type;
  283. WASMArrayObjectRef array_obj;
  284. WASMArrayType *array_type;
  285. WASMArrayNewInitValues *init_values = NULL;
  286. WASMValue *arr_init_val = NULL, empty_val = { 0 };
  287. uint32 type_idx, len;
  288. if (flag == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
  289. type_idx = init_expr->u.array_new_default.type_index;
  290. len = init_expr->u.array_new_default.length;
  291. arr_init_val = &empty_val;
  292. }
  293. else {
  294. init_values = (WASMArrayNewInitValues *)init_expr->u.data;
  295. type_idx = init_values->type_idx;
  296. len = init_values->length;
  297. if (flag == INIT_EXPR_TYPE_ARRAY_NEW) {
  298. arr_init_val = init_values->elem_data;
  299. }
  300. }
  301. array_type = (WASMArrayType *)module->types[type_idx];
  302. if (!(rtt_type = wasm_rtt_type_new(
  303. (WASMType *)array_type, type_idx, module->rtt_types,
  304. module->type_count, &module->rtt_type_lock))) {
  305. set_error_buf(error_buf, error_buf_size,
  306. "create rtt object failed");
  307. return false;
  308. }
  309. if (!(array_obj = wasm_array_obj_new_internal(
  310. ((AOTModuleInstanceExtra *)module_inst->e)
  311. ->common.gc_heap_handle,
  312. rtt_type, len, arr_init_val))) {
  313. set_error_buf(error_buf, error_buf_size,
  314. "create array object failed");
  315. return false;
  316. }
  317. if (flag == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
  318. uint32 elem_idx;
  319. bh_assert(init_values);
  320. for (elem_idx = 0; elem_idx < len; elem_idx++) {
  321. wasm_array_obj_set_elem(array_obj, elem_idx,
  322. &init_values->elem_data[elem_idx]);
  323. }
  324. }
  325. PUT_REF_TO_ADDR(addr, array_obj);
  326. break;
  327. }
  328. default:
  329. set_error_buf(error_buf, error_buf_size, "invalid init expr type.");
  330. return false;
  331. }
  332. return true;
  333. }
  334. #endif /* end of WASM_ENABLE_GC != 0 */
  335. static bool
  336. global_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  337. char *error_buf, uint32 error_buf_size)
  338. {
  339. uint32 i;
  340. InitializerExpression *init_expr;
  341. uint8 *p = module_inst->global_data;
  342. AOTImportGlobal *import_global = module->import_globals;
  343. AOTGlobal *global = module->globals;
  344. /* Initialize import global data */
  345. for (i = 0; i < module->import_global_count; i++, import_global++) {
  346. bh_assert(import_global->data_offset
  347. == (uint32)(p - module_inst->global_data));
  348. init_global_data(p, import_global->type.val_type,
  349. &import_global->global_data_linked);
  350. p += import_global->size;
  351. }
  352. /* Initialize defined global data */
  353. for (i = 0; i < module->global_count; i++, global++) {
  354. uint8 flag;
  355. bh_assert(global->data_offset
  356. == (uint32)(p - module_inst->global_data));
  357. init_expr = &global->init_expr;
  358. flag = init_expr->init_expr_type;
  359. switch (flag) {
  360. case INIT_EXPR_TYPE_GET_GLOBAL:
  361. {
  362. if (!check_global_init_expr(module, init_expr->u.global_index,
  363. error_buf, error_buf_size)) {
  364. return false;
  365. }
  366. #if WASM_ENABLE_GC == 0
  367. init_global_data(
  368. p, global->type.val_type,
  369. &module->import_globals[init_expr->u.global_index]
  370. .global_data_linked);
  371. #else
  372. if (init_expr->u.global_index < module->import_global_count) {
  373. init_global_data(
  374. p, global->type.val_type,
  375. &module->import_globals[init_expr->u.global_index]
  376. .global_data_linked);
  377. }
  378. else {
  379. uint32 global_idx =
  380. init_expr->u.global_index - module->import_global_count;
  381. init_global_data(p, global->type.val_type,
  382. &module->globals[global_idx].init_expr.u);
  383. }
  384. #endif
  385. break;
  386. }
  387. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  388. case INIT_EXPR_TYPE_REFNULL_CONST:
  389. {
  390. *(uint32 *)p = NULL_REF;
  391. break;
  392. }
  393. #elif WASM_ENABLE_GC != 0
  394. case INIT_EXPR_TYPE_REFNULL_CONST:
  395. {
  396. WASMObjectRef gc_obj = NULL_REF;
  397. PUT_REF_TO_ADDR(p, gc_obj);
  398. break;
  399. }
  400. #endif
  401. #if WASM_ENABLE_GC != 0
  402. case INIT_EXPR_TYPE_FUNCREF_CONST:
  403. {
  404. WASMFuncObjectRef func_obj = NULL;
  405. uint32 func_idx = init_expr->u.u32;
  406. if (func_idx != UINT32_MAX) {
  407. if (!(func_obj =
  408. aot_create_func_obj(module_inst, func_idx, false,
  409. error_buf, error_buf_size))) {
  410. return false;
  411. }
  412. }
  413. PUT_REF_TO_ADDR(p, func_obj);
  414. break;
  415. }
  416. case INIT_EXPR_TYPE_I31_NEW:
  417. {
  418. WASMI31ObjectRef i31_obj = wasm_i31_obj_new(init_expr->u.i32);
  419. PUT_REF_TO_ADDR(p, i31_obj);
  420. break;
  421. }
  422. case INIT_EXPR_TYPE_STRUCT_NEW:
  423. case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
  424. {
  425. WASMRttType *rtt_type;
  426. WASMStructObjectRef struct_obj;
  427. WASMStructType *struct_type;
  428. WASMStructNewInitValues *init_values = NULL;
  429. uint32 type_idx;
  430. if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
  431. init_values = (WASMStructNewInitValues *)init_expr->u.data;
  432. type_idx = init_values->type_idx;
  433. }
  434. else {
  435. type_idx = init_expr->u.type_index;
  436. }
  437. struct_type = (WASMStructType *)module->types[type_idx];
  438. if (!(rtt_type = wasm_rtt_type_new(
  439. (WASMType *)struct_type, type_idx, module->rtt_types,
  440. module->type_count, &module->rtt_type_lock))) {
  441. set_error_buf(error_buf, error_buf_size,
  442. "create rtt object failed");
  443. return false;
  444. }
  445. if (!(struct_obj = wasm_struct_obj_new_internal(
  446. ((AOTModuleInstanceExtra *)module_inst->e)
  447. ->common.gc_heap_handle,
  448. rtt_type))) {
  449. set_error_buf(error_buf, error_buf_size,
  450. "create struct object failed");
  451. return false;
  452. }
  453. if (flag == INIT_EXPR_TYPE_STRUCT_NEW) {
  454. uint32 field_idx;
  455. bh_assert(init_values->count == struct_type->field_count);
  456. for (field_idx = 0; field_idx < init_values->count;
  457. field_idx++) {
  458. wasm_struct_obj_set_field(
  459. struct_obj, field_idx,
  460. &init_values->fields[field_idx]);
  461. }
  462. }
  463. PUT_REF_TO_ADDR(p, struct_obj);
  464. break;
  465. }
  466. case INIT_EXPR_TYPE_ARRAY_NEW:
  467. case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
  468. case INIT_EXPR_TYPE_ARRAY_NEW_FIXED:
  469. {
  470. WASMRttType *rtt_type;
  471. WASMArrayObjectRef array_obj;
  472. WASMArrayType *array_type;
  473. WASMArrayNewInitValues *init_values = NULL;
  474. WASMValue *arr_init_val = NULL, empty_val = { 0 };
  475. uint32 type_idx, len;
  476. if (flag == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
  477. type_idx = init_expr->u.array_new_default.type_index;
  478. len = init_expr->u.array_new_default.length;
  479. arr_init_val = &empty_val;
  480. }
  481. else {
  482. init_values = (WASMArrayNewInitValues *)init_expr->u.data;
  483. type_idx = init_values->type_idx;
  484. len = init_values->length;
  485. if (flag == INIT_EXPR_TYPE_ARRAY_NEW) {
  486. arr_init_val = init_values->elem_data;
  487. }
  488. }
  489. array_type = (WASMArrayType *)module->types[type_idx];
  490. if (!(rtt_type = wasm_rtt_type_new(
  491. (WASMType *)array_type, type_idx, module->rtt_types,
  492. module->type_count, &module->rtt_type_lock))) {
  493. set_error_buf(error_buf, error_buf_size,
  494. "create rtt object failed");
  495. return false;
  496. }
  497. if (!(array_obj = wasm_array_obj_new_internal(
  498. ((AOTModuleInstanceExtra *)module_inst->e)
  499. ->common.gc_heap_handle,
  500. rtt_type, len, arr_init_val))) {
  501. set_error_buf(error_buf, error_buf_size,
  502. "create array object failed");
  503. return false;
  504. }
  505. if (flag == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
  506. uint32 elem_idx;
  507. bh_assert(init_values);
  508. for (elem_idx = 0; elem_idx < len; elem_idx++) {
  509. wasm_array_obj_set_elem(
  510. array_obj, elem_idx,
  511. &init_values->elem_data[elem_idx]);
  512. }
  513. }
  514. PUT_REF_TO_ADDR(p, array_obj);
  515. break;
  516. }
  517. #endif /* end of WASM_ENABLE_GC != 0 */
  518. default:
  519. {
  520. init_global_data(p, global->type.val_type, &init_expr->u);
  521. break;
  522. }
  523. }
  524. p += global->size;
  525. }
  526. bh_assert(module_inst->global_data_size
  527. == (uint32)(p - module_inst->global_data));
  528. return true;
  529. }
  530. static bool
  531. tables_instantiate(AOTModuleInstance *module_inst, AOTModule *module,
  532. AOTTableInstance *first_tbl_inst, char *error_buf,
  533. uint32 error_buf_size)
  534. {
  535. uint32 i, global_index, global_data_offset, base_offset, length;
  536. uint64 total_size;
  537. AOTTableInitData *table_seg;
  538. AOTTableInstance *tbl_inst = first_tbl_inst;
  539. total_size = (uint64)sizeof(AOTTableInstance *) * module_inst->table_count;
  540. if (total_size > 0
  541. && !(module_inst->tables =
  542. runtime_malloc(total_size, error_buf, error_buf_size))) {
  543. return false;
  544. }
  545. /*
  546. * treat import table like a local one until we enable module linking
  547. * in AOT mode
  548. */
  549. for (i = 0; i != module_inst->table_count; ++i) {
  550. if (i < module->import_table_count) {
  551. AOTImportTable *import_table = module->import_tables + i;
  552. tbl_inst->cur_size = import_table->table_init_size;
  553. tbl_inst->max_size =
  554. aot_get_imp_tbl_data_slots(import_table, false);
  555. #if WASM_ENABLE_GC != 0
  556. tbl_inst->elem_type = module->tables[i].elem_type;
  557. tbl_inst->elem_ref_type.elem_ref_type =
  558. module->tables[i].elem_ref_type;
  559. #endif
  560. }
  561. else {
  562. AOTTable *table = module->tables + (i - module->import_table_count);
  563. tbl_inst->cur_size = table->table_init_size;
  564. tbl_inst->max_size = aot_get_tbl_data_slots(table, false);
  565. #if WASM_ENABLE_GC != 0
  566. tbl_inst->elem_type = module->tables[i].elem_type;
  567. tbl_inst->elem_ref_type.elem_ref_type =
  568. module->tables[i].elem_ref_type;
  569. #endif
  570. }
  571. /* Set all elements to -1 or NULL_REF to mark them as uninitialized
  572. * elements */
  573. #if WASM_ENABLE_GC == 0
  574. memset(tbl_inst->elems, 0xff,
  575. sizeof(table_elem_type_t) * tbl_inst->max_size);
  576. #else
  577. memset(tbl_inst->elems, 0x00,
  578. sizeof(table_elem_type_t) * tbl_inst->max_size);
  579. #endif
  580. module_inst->tables[i] = tbl_inst;
  581. tbl_inst = (AOTTableInstance *)((uint8 *)tbl_inst
  582. + offsetof(AOTTableInstance, elems)
  583. + sizeof(table_elem_type_t)
  584. * tbl_inst->max_size);
  585. }
  586. /* fill table with element segment content */
  587. for (i = 0; i < module->table_init_data_count; i++) {
  588. #if WASM_ENABLE_GC == 0
  589. uint32 j;
  590. #endif
  591. table_seg = module->table_init_data_list[i];
  592. #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
  593. if (!wasm_elem_is_active(table_seg->mode))
  594. continue;
  595. #endif
  596. bh_assert(table_seg->table_index < module_inst->table_count);
  597. tbl_inst = module_inst->tables[table_seg->table_index];
  598. bh_assert(tbl_inst);
  599. #if WASM_ENABLE_REF_TYPES != 0
  600. bh_assert(
  601. table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
  602. || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL
  603. || table_seg->offset.init_expr_type == INIT_EXPR_TYPE_FUNCREF_CONST
  604. || table_seg->offset.init_expr_type
  605. == INIT_EXPR_TYPE_REFNULL_CONST);
  606. #else
  607. bh_assert(table_seg->offset.init_expr_type == INIT_EXPR_TYPE_I32_CONST
  608. || table_seg->offset.init_expr_type
  609. == INIT_EXPR_TYPE_GET_GLOBAL);
  610. #endif
  611. /* Resolve table data base offset */
  612. if (table_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  613. global_index = table_seg->offset.u.global_index;
  614. if (!check_global_init_expr(module, global_index, error_buf,
  615. error_buf_size)) {
  616. return false;
  617. }
  618. if (global_index < module->import_global_count)
  619. global_data_offset =
  620. module->import_globals[global_index].data_offset;
  621. else
  622. global_data_offset =
  623. module->globals[global_index - module->import_global_count]
  624. .data_offset;
  625. base_offset =
  626. *(uint32 *)(module_inst->global_data + global_data_offset);
  627. }
  628. else
  629. base_offset = (uint32)table_seg->offset.u.i32;
  630. /* Copy table data */
  631. /* base_offset only since length might negative */
  632. if (base_offset > tbl_inst->cur_size) {
  633. #if WASM_ENABLE_REF_TYPES != 0
  634. set_error_buf(error_buf, error_buf_size,
  635. "out of bounds table access");
  636. #else
  637. set_error_buf(error_buf, error_buf_size,
  638. "type mismatch: elements segment does not fit");
  639. #endif
  640. return false;
  641. }
  642. /* base_offset + length(could be zero) */
  643. length = table_seg->value_count;
  644. if (base_offset + length > tbl_inst->cur_size) {
  645. #if WASM_ENABLE_REF_TYPES != 0
  646. set_error_buf(error_buf, error_buf_size,
  647. "out of bounds table access");
  648. #else
  649. set_error_buf(error_buf, error_buf_size,
  650. "type mismatch: elements segment does not fit");
  651. #endif
  652. return false;
  653. }
  654. /**
  655. * Check function index in the current module inst for now.
  656. * will check the linked table inst owner in future
  657. */
  658. #if WASM_ENABLE_GC == 0
  659. for (j = 0; j < length; j++) {
  660. tbl_inst->elems[base_offset + j] =
  661. table_seg->init_values[j].u.ref_index;
  662. }
  663. #endif
  664. }
  665. return true;
  666. }
  667. static void
  668. memories_deinstantiate(AOTModuleInstance *module_inst)
  669. {
  670. uint32 i;
  671. AOTMemoryInstance *memory_inst;
  672. for (i = 0; i < module_inst->memory_count; i++) {
  673. memory_inst = module_inst->memories[i];
  674. if (memory_inst) {
  675. #if WASM_ENABLE_SHARED_MEMORY != 0
  676. if (shared_memory_is_shared(memory_inst)) {
  677. uint32 ref_count = shared_memory_dec_reference(memory_inst);
  678. /* if the reference count is not zero,
  679. don't free the memory */
  680. if (ref_count > 0)
  681. continue;
  682. }
  683. #endif
  684. if (memory_inst->heap_handle) {
  685. mem_allocator_destroy(memory_inst->heap_handle);
  686. wasm_runtime_free(memory_inst->heap_handle);
  687. }
  688. if (memory_inst->memory_data) {
  689. wasm_deallocate_linear_memory(memory_inst);
  690. }
  691. }
  692. }
  693. wasm_runtime_free(module_inst->memories);
  694. }
  695. static AOTMemoryInstance *
  696. memory_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
  697. AOTModule *module, AOTMemoryInstance *memory_inst,
  698. AOTMemory *memory, uint32 memory_idx, uint32 heap_size,
  699. uint32 max_memory_pages, char *error_buf,
  700. uint32 error_buf_size)
  701. {
  702. void *heap_handle;
  703. uint32 num_bytes_per_page = memory->num_bytes_per_page;
  704. uint32 init_page_count = memory->mem_init_page_count;
  705. uint32 max_page_count =
  706. wasm_runtime_get_max_mem(max_memory_pages, memory->mem_init_page_count,
  707. memory->mem_max_page_count);
  708. uint32 default_max_pages;
  709. uint32 inc_page_count, global_idx;
  710. uint32 bytes_of_last_page, bytes_to_page_end;
  711. uint64 aux_heap_base,
  712. heap_offset = (uint64)num_bytes_per_page * init_page_count;
  713. uint64 memory_data_size, max_memory_data_size;
  714. uint8 *p = NULL, *global_addr;
  715. bool is_memory64 = memory->memory_flags & MEMORY64_FLAG;
  716. bool is_shared_memory = false;
  717. #if WASM_ENABLE_SHARED_MEMORY != 0
  718. is_shared_memory = memory->memory_flags & SHARED_MEMORY_FLAG ? true : false;
  719. /* Shared memory */
  720. if (is_shared_memory && parent != NULL) {
  721. AOTMemoryInstance *shared_memory_instance;
  722. bh_assert(memory_idx == 0);
  723. bh_assert(parent->memory_count > memory_idx);
  724. shared_memory_instance = parent->memories[memory_idx];
  725. shared_memory_inc_reference(shared_memory_instance);
  726. return shared_memory_instance;
  727. }
  728. #endif
  729. #if WASM_ENABLE_MEMORY64 != 0
  730. if (is_memory64) {
  731. default_max_pages = DEFAULT_MEM64_MAX_PAGES;
  732. }
  733. else
  734. #endif
  735. {
  736. default_max_pages = DEFAULT_MAX_PAGES;
  737. }
  738. if (heap_size > 0 && module->malloc_func_index != (uint32)-1
  739. && module->free_func_index != (uint32)-1) {
  740. /* Disable app heap, use malloc/free function exported
  741. by wasm app to allocate/free memory instead */
  742. heap_size = 0;
  743. }
  744. /* If initial memory is the largest size allowed, disallowing insert host
  745. * managed heap */
  746. if (heap_size > 0 && heap_offset == MAX_LINEAR_MEMORY_SIZE) {
  747. set_error_buf(error_buf, error_buf_size,
  748. "failed to insert app heap into linear memory, "
  749. "try using `--heap-size=0` option");
  750. return NULL;
  751. }
  752. if (init_page_count == max_page_count && init_page_count == 1) {
  753. /* If only one page and at most one page, we just append
  754. the app heap to the end of linear memory, enlarge the
  755. num_bytes_per_page, and don't change the page count */
  756. heap_offset = num_bytes_per_page;
  757. num_bytes_per_page += heap_size;
  758. if (num_bytes_per_page < heap_size) {
  759. set_error_buf(error_buf, error_buf_size,
  760. "failed to insert app heap into linear memory, "
  761. "try using `--heap-size=0` option");
  762. return NULL;
  763. }
  764. }
  765. else if (heap_size > 0) {
  766. if (init_page_count == max_page_count && init_page_count == 0) {
  767. /* If the memory data size is always 0, we resize it to
  768. one page for app heap */
  769. num_bytes_per_page = heap_size;
  770. heap_offset = 0;
  771. inc_page_count = 1;
  772. }
  773. else if (module->aux_heap_base_global_index != (uint32)-1
  774. && module->aux_heap_base
  775. < (uint64)num_bytes_per_page * init_page_count) {
  776. /* Insert app heap before __heap_base */
  777. aux_heap_base = module->aux_heap_base;
  778. bytes_of_last_page = aux_heap_base % num_bytes_per_page;
  779. if (bytes_of_last_page == 0)
  780. bytes_of_last_page = num_bytes_per_page;
  781. bytes_to_page_end = num_bytes_per_page - bytes_of_last_page;
  782. inc_page_count =
  783. (heap_size - bytes_to_page_end + num_bytes_per_page - 1)
  784. / num_bytes_per_page;
  785. heap_offset = aux_heap_base;
  786. aux_heap_base += heap_size;
  787. bytes_of_last_page = aux_heap_base % num_bytes_per_page;
  788. if (bytes_of_last_page == 0)
  789. bytes_of_last_page = num_bytes_per_page;
  790. bytes_to_page_end = num_bytes_per_page - bytes_of_last_page;
  791. if (bytes_to_page_end < 1 * BH_KB) {
  792. aux_heap_base += 1 * BH_KB;
  793. inc_page_count++;
  794. }
  795. /* Adjust __heap_base global value */
  796. global_idx = module->aux_heap_base_global_index
  797. - module->import_global_count;
  798. global_addr = module_inst->global_data
  799. + module->globals[global_idx].data_offset;
  800. *(uint32 *)global_addr = (uint32)aux_heap_base;
  801. LOG_VERBOSE("Reset __heap_base global to %" PRIu64, aux_heap_base);
  802. }
  803. else {
  804. /* Insert app heap before new page */
  805. inc_page_count =
  806. (heap_size + num_bytes_per_page - 1) / num_bytes_per_page;
  807. heap_offset = (uint64)num_bytes_per_page * init_page_count;
  808. heap_size = (uint64)num_bytes_per_page * inc_page_count;
  809. if (heap_size > 0)
  810. heap_size -= 1 * BH_KB;
  811. }
  812. init_page_count += inc_page_count;
  813. max_page_count += inc_page_count;
  814. if (init_page_count > default_max_pages) {
  815. set_error_buf(error_buf, error_buf_size,
  816. "failed to insert app heap into linear memory, "
  817. "try using `--heap-size=0` option");
  818. return NULL;
  819. }
  820. if (max_page_count > default_max_pages)
  821. max_page_count = default_max_pages;
  822. }
  823. LOG_VERBOSE("Memory instantiate:");
  824. LOG_VERBOSE(" page bytes: %u, init pages: %u, max pages: %u",
  825. num_bytes_per_page, init_page_count, max_page_count);
  826. LOG_VERBOSE(" data offset: %" PRIu64 ", stack size: %d",
  827. module->aux_data_end, module->aux_stack_size);
  828. LOG_VERBOSE(" heap offset: %" PRIu64 ", heap size: %d\n", heap_offset,
  829. heap_size);
  830. max_memory_data_size = (uint64)num_bytes_per_page * max_page_count;
  831. bh_assert(max_memory_data_size <= GET_MAX_LINEAR_MEMORY_SIZE(is_memory64));
  832. (void)max_memory_data_size;
  833. /* TODO: memory64 uses is_memory64 flag */
  834. if (wasm_allocate_linear_memory(&p, is_shared_memory, is_memory64,
  835. num_bytes_per_page, init_page_count,
  836. max_page_count, &memory_data_size)
  837. != BHT_OK) {
  838. set_error_buf(error_buf, error_buf_size,
  839. "allocate linear memory failed");
  840. return NULL;
  841. }
  842. memory_inst->module_type = Wasm_Module_AoT;
  843. memory_inst->num_bytes_per_page = num_bytes_per_page;
  844. memory_inst->cur_page_count = init_page_count;
  845. memory_inst->max_page_count = max_page_count;
  846. memory_inst->memory_data_size = memory_data_size;
  847. #if WASM_ENABLE_MEMORY64 != 0
  848. if (is_memory64) {
  849. memory_inst->is_memory64 = 1;
  850. }
  851. #endif
  852. /* Init memory info */
  853. memory_inst->memory_data = p;
  854. memory_inst->memory_data_end = p + memory_data_size;
  855. /* Initialize heap info */
  856. memory_inst->heap_data = p + heap_offset;
  857. memory_inst->heap_data_end = p + heap_offset + heap_size;
  858. if (heap_size > 0) {
  859. uint32 heap_struct_size = mem_allocator_get_heap_struct_size();
  860. if (!(heap_handle = runtime_malloc((uint64)heap_struct_size, error_buf,
  861. error_buf_size))) {
  862. goto fail1;
  863. }
  864. memory_inst->heap_handle = heap_handle;
  865. if (!mem_allocator_create_with_struct_and_pool(
  866. heap_handle, heap_struct_size, memory_inst->heap_data,
  867. heap_size)) {
  868. set_error_buf(error_buf, error_buf_size, "init app heap failed");
  869. goto fail2;
  870. }
  871. }
  872. if (memory_data_size > 0) {
  873. wasm_runtime_set_mem_bound_check_bytes(memory_inst, memory_data_size);
  874. }
  875. #if WASM_ENABLE_SHARED_MEMORY != 0
  876. if (is_shared_memory) {
  877. memory_inst->is_shared_memory = 1;
  878. memory_inst->ref_count = 1;
  879. }
  880. #endif
  881. return memory_inst;
  882. fail2:
  883. if (heap_size > 0)
  884. wasm_runtime_free(memory_inst->heap_handle);
  885. fail1:
  886. wasm_deallocate_linear_memory(memory_inst);
  887. return NULL;
  888. }
  889. static AOTMemoryInstance *
  890. aot_get_default_memory(AOTModuleInstance *module_inst)
  891. {
  892. if (module_inst->memories)
  893. return module_inst->memories[0];
  894. else
  895. return NULL;
  896. }
  897. static bool
  898. memories_instantiate(AOTModuleInstance *module_inst, AOTModuleInstance *parent,
  899. AOTModule *module, uint32 heap_size,
  900. uint32 max_memory_pages, char *error_buf,
  901. uint32 error_buf_size)
  902. {
  903. uint32 global_index, global_data_offset, length;
  904. uint32 i, memory_count = module->memory_count;
  905. AOTMemoryInstance *memories, *memory_inst;
  906. AOTMemInitData *data_seg;
  907. uint64 total_size;
  908. mem_offset_t base_offset;
  909. module_inst->memory_count = memory_count;
  910. total_size = sizeof(AOTMemoryInstance *) * (uint64)memory_count;
  911. if (!(module_inst->memories =
  912. runtime_malloc(total_size, error_buf, error_buf_size))) {
  913. return false;
  914. }
  915. memories = module_inst->global_table_data.memory_instances;
  916. for (i = 0; i < memory_count; i++, memories++) {
  917. memory_inst = memory_instantiate(
  918. module_inst, parent, module, memories, &module->memories[i], i,
  919. heap_size, max_memory_pages, error_buf, error_buf_size);
  920. if (!memory_inst) {
  921. return false;
  922. }
  923. module_inst->memories[i] = memory_inst;
  924. }
  925. /* Get default memory instance */
  926. memory_inst = aot_get_default_memory(module_inst);
  927. if (!memory_inst) {
  928. /* Ignore setting memory init data if no memory inst is created */
  929. return true;
  930. }
  931. for (i = 0; i < module->mem_init_data_count; i++) {
  932. data_seg = module->mem_init_data_list[i];
  933. #if WASM_ENABLE_BULK_MEMORY != 0
  934. if (data_seg->is_passive)
  935. continue;
  936. #endif
  937. if (parent != NULL)
  938. /* Ignore setting memory init data if the memory has been
  939. initialized */
  940. continue;
  941. bh_assert(data_seg->offset.init_expr_type
  942. == (memory_inst->is_memory64 ? INIT_EXPR_TYPE_I64_CONST
  943. : INIT_EXPR_TYPE_I32_CONST)
  944. || data_seg->offset.init_expr_type
  945. == INIT_EXPR_TYPE_GET_GLOBAL);
  946. /* Resolve memory data base offset */
  947. if (data_seg->offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  948. global_index = data_seg->offset.u.global_index;
  949. if (!check_global_init_expr(module, global_index, error_buf,
  950. error_buf_size)) {
  951. return false;
  952. }
  953. if (global_index < module->import_global_count)
  954. global_data_offset =
  955. module->import_globals[global_index].data_offset;
  956. else
  957. global_data_offset =
  958. module->globals[global_index - module->import_global_count]
  959. .data_offset;
  960. #if WASM_ENABLE_MEMORY64 != 0
  961. if (memory_inst->is_memory64) {
  962. base_offset =
  963. *(uint64 *)(module_inst->global_data + global_data_offset);
  964. }
  965. else
  966. #endif
  967. {
  968. base_offset =
  969. *(uint32 *)(module_inst->global_data + global_data_offset);
  970. }
  971. }
  972. else {
  973. #if WASM_ENABLE_MEMORY64 != 0
  974. if (memory_inst->is_memory64) {
  975. base_offset = data_seg->offset.u.i64;
  976. }
  977. else
  978. #endif
  979. {
  980. base_offset = data_seg->offset.u.u32;
  981. }
  982. }
  983. /* Copy memory data */
  984. bh_assert(memory_inst->memory_data
  985. || memory_inst->memory_data_size == 0);
  986. /* Check memory data */
  987. /* check offset since length might negative */
  988. if (base_offset > memory_inst->memory_data_size) {
  989. LOG_DEBUG("base_offset(%" PR_MEM_OFFSET
  990. ") > memory_data_size(%" PRIu64 ")",
  991. base_offset, memory_inst->memory_data_size);
  992. #if WASM_ENABLE_REF_TYPES != 0
  993. set_error_buf(error_buf, error_buf_size,
  994. "out of bounds memory access");
  995. #else
  996. set_error_buf(error_buf, error_buf_size,
  997. "data segment does not fit");
  998. #endif
  999. return false;
  1000. }
  1001. /* check offset + length(could be zero) */
  1002. length = data_seg->byte_count;
  1003. if (base_offset + length > memory_inst->memory_data_size) {
  1004. LOG_DEBUG("base_offset(%" PR_MEM_OFFSET
  1005. ") + length(%d) > memory_data_size(%" PRIu64 ")",
  1006. base_offset, length, memory_inst->memory_data_size);
  1007. #if WASM_ENABLE_REF_TYPES != 0
  1008. set_error_buf(error_buf, error_buf_size,
  1009. "out of bounds memory access");
  1010. #else
  1011. set_error_buf(error_buf, error_buf_size,
  1012. "data segment does not fit");
  1013. #endif
  1014. return false;
  1015. }
  1016. if (memory_inst->memory_data) {
  1017. bh_memcpy_s((uint8 *)memory_inst->memory_data + base_offset,
  1018. (uint32)memory_inst->memory_data_size - base_offset,
  1019. data_seg->bytes, length);
  1020. }
  1021. }
  1022. return true;
  1023. }
  1024. static bool
  1025. init_func_ptrs(AOTModuleInstance *module_inst, AOTModule *module,
  1026. char *error_buf, uint32 error_buf_size)
  1027. {
  1028. uint32 i;
  1029. void **func_ptrs;
  1030. uint64 total_size = ((uint64)module->import_func_count + module->func_count)
  1031. * sizeof(void *);
  1032. if (module->import_func_count + module->func_count == 0)
  1033. return true;
  1034. /* Allocate memory */
  1035. if (!(module_inst->func_ptrs =
  1036. runtime_malloc(total_size, error_buf, error_buf_size))) {
  1037. return false;
  1038. }
  1039. /* Set import function pointers */
  1040. func_ptrs = (void **)module_inst->func_ptrs;
  1041. for (i = 0; i < module->import_func_count; i++, func_ptrs++) {
  1042. *func_ptrs = (void *)module->import_funcs[i].func_ptr_linked;
  1043. if (!*func_ptrs) {
  1044. const char *module_name = module->import_funcs[i].module_name;
  1045. const char *field_name = module->import_funcs[i].func_name;
  1046. LOG_WARNING("warning: failed to link import function (%s, %s)",
  1047. module_name, field_name);
  1048. }
  1049. }
  1050. /* Set defined function pointers */
  1051. bh_memcpy_s(func_ptrs, sizeof(void *) * module->func_count,
  1052. module->func_ptrs, sizeof(void *) * module->func_count);
  1053. return true;
  1054. }
  1055. static bool
  1056. init_func_type_indexes(AOTModuleInstance *module_inst, AOTModule *module,
  1057. char *error_buf, uint32 error_buf_size)
  1058. {
  1059. uint32 i;
  1060. uint32 *func_type_index;
  1061. uint64 total_size = ((uint64)module->import_func_count + module->func_count)
  1062. * sizeof(uint32);
  1063. if (module->import_func_count + module->func_count == 0)
  1064. return true;
  1065. /* Allocate memory */
  1066. if (!(module_inst->func_type_indexes =
  1067. runtime_malloc(total_size, error_buf, error_buf_size))) {
  1068. return false;
  1069. }
  1070. /* Set import function type indexes */
  1071. func_type_index = module_inst->func_type_indexes;
  1072. for (i = 0; i < module->import_func_count; i++, func_type_index++)
  1073. *func_type_index = module->import_funcs[i].func_type_index;
  1074. bh_memcpy_s(func_type_index, sizeof(uint32) * module->func_count,
  1075. module->func_type_indexes, sizeof(uint32) * module->func_count);
  1076. return true;
  1077. }
  1078. static bool
  1079. create_export_funcs(AOTModuleInstance *module_inst, AOTModule *module,
  1080. char *error_buf, uint32 error_buf_size)
  1081. {
  1082. AOTExport *exports = module->exports;
  1083. AOTFunctionInstance *export_func;
  1084. uint64 size;
  1085. uint32 i, func_index, ftype_index;
  1086. if (module_inst->export_func_count > 0) {
  1087. /* Allocate memory */
  1088. size = sizeof(AOTFunctionInstance)
  1089. * (uint64)module_inst->export_func_count;
  1090. if (!(export_func = runtime_malloc(size, error_buf, error_buf_size))) {
  1091. return false;
  1092. }
  1093. module_inst->export_functions = (void *)export_func;
  1094. for (i = 0; i < module->export_count; i++) {
  1095. if (exports[i].kind == EXPORT_KIND_FUNC) {
  1096. export_func->func_name = exports[i].name;
  1097. export_func->func_index = exports[i].index;
  1098. if (export_func->func_index < module->import_func_count) {
  1099. export_func->is_import_func = true;
  1100. export_func->u.func_import =
  1101. &module->import_funcs[export_func->func_index];
  1102. }
  1103. else {
  1104. export_func->is_import_func = false;
  1105. func_index =
  1106. export_func->func_index - module->import_func_count;
  1107. ftype_index = module->func_type_indexes[func_index];
  1108. export_func->u.func.func_type =
  1109. (AOTFuncType *)module->types[ftype_index];
  1110. export_func->u.func.func_ptr =
  1111. module->func_ptrs[func_index];
  1112. }
  1113. export_func++;
  1114. }
  1115. }
  1116. }
  1117. return true;
  1118. }
  1119. static bool
  1120. create_exports(AOTModuleInstance *module_inst, AOTModule *module,
  1121. char *error_buf, uint32 error_buf_size)
  1122. {
  1123. AOTExport *exports = module->exports;
  1124. uint32 i;
  1125. for (i = 0; i < module->export_count; i++) {
  1126. switch (exports[i].kind) {
  1127. case EXPORT_KIND_FUNC:
  1128. module_inst->export_func_count++;
  1129. break;
  1130. case EXPORT_KIND_GLOBAL:
  1131. module_inst->export_global_count++;
  1132. break;
  1133. case EXPORT_KIND_TABLE:
  1134. module_inst->export_table_count++;
  1135. break;
  1136. case EXPORT_KIND_MEMORY:
  1137. module_inst->export_memory_count++;
  1138. break;
  1139. default:
  1140. return false;
  1141. }
  1142. }
  1143. return create_export_funcs(module_inst, module, error_buf, error_buf_size);
  1144. }
  1145. static AOTFunctionInstance *
  1146. lookup_post_instantiate_func(AOTModuleInstance *module_inst,
  1147. const char *func_name)
  1148. {
  1149. AOTFunctionInstance *func;
  1150. AOTFuncType *func_type;
  1151. if (!(func = aot_lookup_function(module_inst, func_name)))
  1152. /* Not found */
  1153. return NULL;
  1154. func_type = func->u.func.func_type;
  1155. if (!(func_type->param_count == 0 && func_type->result_count == 0))
  1156. /* Not a valid function type, ignore it */
  1157. return NULL;
  1158. return func;
  1159. }
  1160. static bool
  1161. execute_post_instantiate_functions(AOTModuleInstance *module_inst,
  1162. bool is_sub_inst, WASMExecEnv *exec_env_main)
  1163. {
  1164. AOTModule *module = (AOTModule *)module_inst->module;
  1165. AOTFunctionInstance *initialize_func = NULL;
  1166. AOTFunctionInstance *post_inst_func = NULL;
  1167. AOTFunctionInstance *call_ctors_func = NULL;
  1168. WASMModuleInstanceCommon *module_inst_main = NULL;
  1169. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1170. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  1171. #endif
  1172. WASMExecEnv *exec_env = NULL, *exec_env_created = NULL;
  1173. bool ret = false;
  1174. #if WASM_ENABLE_LIBC_WASI != 0
  1175. /*
  1176. * WASI reactor instances may assume that _initialize will be called by
  1177. * the environment at most once, and that none of their other exports
  1178. * are accessed before that call.
  1179. */
  1180. if (!is_sub_inst && module->import_wasi_api) {
  1181. initialize_func =
  1182. lookup_post_instantiate_func(module_inst, "_initialize");
  1183. }
  1184. #endif
  1185. /* Execute possible "__post_instantiate" function if wasm app is
  1186. compiled by emsdk's early version */
  1187. if (!is_sub_inst) {
  1188. post_inst_func =
  1189. lookup_post_instantiate_func(module_inst, "__post_instantiate");
  1190. }
  1191. #if WASM_ENABLE_BULK_MEMORY != 0
  1192. /* Only execute the memory init function for main instance since
  1193. the data segments will be dropped once initialized */
  1194. if (!is_sub_inst
  1195. #if WASM_ENABLE_LIBC_WASI != 0
  1196. && !module->import_wasi_api
  1197. #endif
  1198. ) {
  1199. call_ctors_func =
  1200. lookup_post_instantiate_func(module_inst, "__wasm_call_ctors");
  1201. }
  1202. #endif
  1203. if (!module->start_function && !initialize_func && !post_inst_func
  1204. && !call_ctors_func) {
  1205. /* No post instantiation functions to call */
  1206. return true;
  1207. }
  1208. if (is_sub_inst) {
  1209. bh_assert(exec_env_main);
  1210. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1211. bh_assert(exec_env_tls == exec_env_main);
  1212. (void)exec_env_tls;
  1213. #endif
  1214. exec_env = exec_env_main;
  1215. /* Temporarily replace parent exec_env's module inst to current
  1216. module inst to avoid checking failure when calling the
  1217. wasm functions, and ensure that the exec_env's module inst
  1218. is the correct one. */
  1219. module_inst_main = exec_env_main->module_inst;
  1220. wasm_exec_env_set_module_inst(exec_env,
  1221. (WASMModuleInstanceCommon *)module_inst);
  1222. }
  1223. else {
  1224. /* Try using the existing exec_env */
  1225. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1226. exec_env = exec_env_tls;
  1227. #endif
  1228. #if WASM_ENABLE_THREAD_MGR != 0
  1229. if (!exec_env)
  1230. exec_env = wasm_clusters_search_exec_env(
  1231. (WASMModuleInstanceCommon *)module_inst);
  1232. #endif
  1233. if (!exec_env) {
  1234. if (!(exec_env = exec_env_created = wasm_exec_env_create(
  1235. (WASMModuleInstanceCommon *)module_inst,
  1236. module_inst->default_wasm_stack_size))) {
  1237. aot_set_exception(module_inst, "allocate memory failed");
  1238. return false;
  1239. }
  1240. }
  1241. else {
  1242. /* Temporarily replace exec_env's module inst with current
  1243. module inst to ensure that the exec_env's module inst
  1244. is the correct one. */
  1245. module_inst_main = exec_env->module_inst;
  1246. wasm_exec_env_set_module_inst(
  1247. exec_env, (WASMModuleInstanceCommon *)module_inst);
  1248. }
  1249. }
  1250. #if defined(os_writegsbase)
  1251. {
  1252. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1253. if (memory_inst)
  1254. /* write base addr of linear memory to GS segment register */
  1255. os_writegsbase(memory_inst->memory_data);
  1256. }
  1257. #endif
  1258. /* Execute start function for both main instance and sub instance */
  1259. if (module->start_function) {
  1260. AOTFunctionInstance start_func = { 0 };
  1261. uint32 func_type_idx;
  1262. start_func.func_name = "";
  1263. start_func.func_index = module->start_func_index;
  1264. start_func.is_import_func = false;
  1265. func_type_idx = module->func_type_indexes[module->start_func_index
  1266. - module->import_func_count];
  1267. start_func.u.func.func_type =
  1268. (AOTFuncType *)module->types[func_type_idx];
  1269. start_func.u.func.func_ptr = module->start_function;
  1270. if (!aot_call_function(exec_env, &start_func, 0, NULL)) {
  1271. goto fail;
  1272. }
  1273. }
  1274. if (initialize_func
  1275. && !aot_call_function(exec_env, initialize_func, 0, NULL)) {
  1276. goto fail;
  1277. }
  1278. if (post_inst_func
  1279. && !aot_call_function(exec_env, post_inst_func, 0, NULL)) {
  1280. goto fail;
  1281. }
  1282. if (call_ctors_func
  1283. && !aot_call_function(exec_env, call_ctors_func, 0, NULL)) {
  1284. goto fail;
  1285. }
  1286. ret = true;
  1287. fail:
  1288. if (is_sub_inst) {
  1289. /* Restore the parent exec_env's module inst */
  1290. wasm_exec_env_restore_module_inst(exec_env_main, module_inst_main);
  1291. }
  1292. else {
  1293. if (module_inst_main)
  1294. /* Restore the existing exec_env's module inst */
  1295. wasm_exec_env_restore_module_inst(exec_env, module_inst_main);
  1296. if (exec_env_created)
  1297. wasm_exec_env_destroy(exec_env_created);
  1298. }
  1299. return ret;
  1300. }
  1301. static bool
  1302. check_linked_symbol(AOTModule *module, char *error_buf, uint32 error_buf_size)
  1303. {
  1304. uint32 i;
  1305. /* init_func_ptrs() will go through import functions */
  1306. for (i = 0; i < module->import_global_count; i++) {
  1307. AOTImportGlobal *global = module->import_globals + i;
  1308. if (!global->is_linked) {
  1309. set_error_buf_v(error_buf, error_buf_size,
  1310. "failed to link import global (%s, %s)",
  1311. global->module_name, global->global_name);
  1312. return false;
  1313. }
  1314. }
  1315. return true;
  1316. }
  1317. AOTModuleInstance *
  1318. aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
  1319. WASMExecEnv *exec_env_main, uint32 stack_size, uint32 heap_size,
  1320. uint32 max_memory_pages, char *error_buf, uint32 error_buf_size)
  1321. {
  1322. AOTModuleInstance *module_inst;
  1323. #if WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_REF_TYPES != 0
  1324. WASMModuleInstanceExtraCommon *common;
  1325. #endif
  1326. const uint32 module_inst_struct_size =
  1327. offsetof(AOTModuleInstance, global_table_data.bytes);
  1328. const uint64 module_inst_mem_inst_size =
  1329. (uint64)module->memory_count * sizeof(AOTMemoryInstance);
  1330. uint64 total_size, table_size = 0;
  1331. uint8 *p;
  1332. uint32 i, extra_info_offset;
  1333. const bool is_sub_inst = parent != NULL;
  1334. #if WASM_ENABLE_MULTI_MODULE != 0
  1335. bool ret = false;
  1336. #endif
  1337. /* Check heap size */
  1338. heap_size = align_uint(heap_size, 8);
  1339. if (heap_size > APP_HEAP_SIZE_MAX)
  1340. heap_size = APP_HEAP_SIZE_MAX;
  1341. total_size = (uint64)module_inst_struct_size + module_inst_mem_inst_size
  1342. + module->global_data_size;
  1343. /*
  1344. * calculate size of table data
  1345. */
  1346. for (i = 0; i != module->import_table_count; ++i) {
  1347. table_size += offsetof(AOTTableInstance, elems);
  1348. table_size += (uint64)sizeof(table_elem_type_t)
  1349. * (uint64)aot_get_imp_tbl_data_slots(
  1350. module->import_tables + i, false);
  1351. }
  1352. for (i = 0; i != module->table_count; ++i) {
  1353. table_size += offsetof(AOTTableInstance, elems);
  1354. table_size +=
  1355. (uint64)sizeof(table_elem_type_t)
  1356. * (uint64)aot_get_tbl_data_slots(module->tables + i, false);
  1357. }
  1358. total_size += table_size;
  1359. /* The offset of AOTModuleInstanceExtra, make it 8-byte aligned */
  1360. total_size = (total_size + 7LL) & ~7LL;
  1361. extra_info_offset = (uint32)total_size;
  1362. total_size += sizeof(AOTModuleInstanceExtra);
  1363. /* Allocate module instance, global data, table data and heap data */
  1364. if (!(module_inst =
  1365. runtime_malloc(total_size, error_buf, error_buf_size))) {
  1366. return NULL;
  1367. }
  1368. module_inst->module_type = Wasm_Module_AoT;
  1369. module_inst->module = (void *)module;
  1370. module_inst->e =
  1371. (WASMModuleInstanceExtra *)((uint8 *)module_inst + extra_info_offset);
  1372. #if WASM_ENABLE_GC != 0
  1373. /* Initialize gc heap first since it may be used when initializing
  1374. globals and others */
  1375. if (!is_sub_inst) {
  1376. uint32 gc_heap_size = wasm_runtime_get_gc_heap_size_default();
  1377. AOTModuleInstanceExtra *extra =
  1378. (AOTModuleInstanceExtra *)module_inst->e;
  1379. if (gc_heap_size < GC_HEAP_SIZE_MIN)
  1380. gc_heap_size = GC_HEAP_SIZE_MIN;
  1381. if (gc_heap_size > GC_HEAP_SIZE_MAX)
  1382. gc_heap_size = GC_HEAP_SIZE_MAX;
  1383. extra->common.gc_heap_pool =
  1384. runtime_malloc(gc_heap_size, error_buf, error_buf_size);
  1385. if (!extra->common.gc_heap_pool)
  1386. goto fail;
  1387. extra->common.gc_heap_handle =
  1388. mem_allocator_create(extra->common.gc_heap_pool, gc_heap_size);
  1389. if (!extra->common.gc_heap_handle)
  1390. goto fail;
  1391. }
  1392. #endif
  1393. #if WASM_ENABLE_MULTI_MODULE != 0
  1394. ((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list =
  1395. &((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list_head;
  1396. ret = wasm_runtime_sub_module_instantiate(
  1397. (WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst,
  1398. stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
  1399. if (!ret) {
  1400. LOG_DEBUG("build a sub module list failed");
  1401. goto fail;
  1402. }
  1403. #endif
  1404. /* Initialize function type indexes before initializing global info,
  1405. module_inst->func_type_indexes may be used in the latter */
  1406. if (!init_func_type_indexes(module_inst, module, error_buf, error_buf_size))
  1407. goto fail;
  1408. #if WASM_ENABLE_BULK_MEMORY != 0 || WASM_ENABLE_REF_TYPES != 0
  1409. common = &((AOTModuleInstanceExtra *)module_inst->e)->common;
  1410. #endif
  1411. #if WASM_ENABLE_BULK_MEMORY != 0
  1412. if (module->mem_init_data_count > 0) {
  1413. common->data_dropped = bh_bitmap_new(0, module->mem_init_data_count);
  1414. if (common->data_dropped == NULL) {
  1415. LOG_DEBUG("failed to allocate bitmaps");
  1416. set_error_buf(error_buf, error_buf_size,
  1417. "failed to allocate bitmaps");
  1418. goto fail;
  1419. }
  1420. for (i = 0; i < module->mem_init_data_count; i++) {
  1421. if (!module->mem_init_data_list[i]->is_passive)
  1422. bh_bitmap_set_bit(common->data_dropped, i);
  1423. }
  1424. }
  1425. #endif
  1426. #if WASM_ENABLE_REF_TYPES != 0
  1427. if (module->table_init_data_count > 0) {
  1428. common->elem_dropped = bh_bitmap_new(0, module->table_init_data_count);
  1429. if (common->elem_dropped == NULL) {
  1430. LOG_DEBUG("failed to allocate bitmaps");
  1431. set_error_buf(error_buf, error_buf_size,
  1432. "failed to allocate bitmaps");
  1433. goto fail;
  1434. }
  1435. for (i = 0; i < module->table_init_data_count; i++) {
  1436. if (wasm_elem_is_active(module->table_init_data_list[i]->mode))
  1437. bh_bitmap_set_bit(common->elem_dropped, i);
  1438. }
  1439. }
  1440. #endif
  1441. /* Initialize global info */
  1442. p = (uint8 *)module_inst + module_inst_struct_size
  1443. + module_inst_mem_inst_size;
  1444. module_inst->global_data = p;
  1445. module_inst->global_data_size = module->global_data_size;
  1446. if (!global_instantiate(module_inst, module, error_buf, error_buf_size))
  1447. goto fail;
  1448. /* Initialize table info */
  1449. p += module->global_data_size;
  1450. module_inst->table_count = module->table_count + module->import_table_count;
  1451. if (!tables_instantiate(module_inst, module, (AOTTableInstance *)p,
  1452. error_buf, error_buf_size))
  1453. goto fail;
  1454. /* Initialize memory space */
  1455. if (!memories_instantiate(module_inst, parent, module, heap_size,
  1456. max_memory_pages, error_buf, error_buf_size))
  1457. goto fail;
  1458. /* Initialize function pointers */
  1459. if (!init_func_ptrs(module_inst, module, error_buf, error_buf_size))
  1460. goto fail;
  1461. if (!check_linked_symbol(module, error_buf, error_buf_size))
  1462. goto fail;
  1463. if (!create_exports(module_inst, module, error_buf, error_buf_size))
  1464. goto fail;
  1465. #if WASM_ENABLE_LIBC_WASI != 0
  1466. if (!is_sub_inst) {
  1467. if (!wasm_runtime_init_wasi(
  1468. (WASMModuleInstanceCommon *)module_inst,
  1469. module->wasi_args.dir_list, module->wasi_args.dir_count,
  1470. module->wasi_args.map_dir_list, module->wasi_args.map_dir_count,
  1471. module->wasi_args.env, module->wasi_args.env_count,
  1472. module->wasi_args.addr_pool, module->wasi_args.addr_count,
  1473. module->wasi_args.ns_lookup_pool,
  1474. module->wasi_args.ns_lookup_count, module->wasi_args.argv,
  1475. module->wasi_args.argc, module->wasi_args.stdio[0],
  1476. module->wasi_args.stdio[1], module->wasi_args.stdio[2],
  1477. error_buf, error_buf_size))
  1478. goto fail;
  1479. }
  1480. #endif
  1481. /* Initialize the thread related data */
  1482. if (stack_size == 0)
  1483. stack_size = DEFAULT_WASM_STACK_SIZE;
  1484. #if WASM_ENABLE_SPEC_TEST != 0
  1485. #if WASM_ENABLE_TAIL_CALL == 0
  1486. if (stack_size < 128 * 1024)
  1487. stack_size = 128 * 1024;
  1488. #else
  1489. /* Some tail-call cases require large operand stack */
  1490. if (stack_size < 10 * 1024 * 1024)
  1491. stack_size = 10 * 1024 * 1024;
  1492. #endif
  1493. #endif
  1494. module_inst->default_wasm_stack_size = stack_size;
  1495. ((AOTModuleInstanceExtra *)module_inst->e)->stack_sizes =
  1496. aot_get_data_section_addr(module, AOT_STACK_SIZES_SECTION_NAME, NULL);
  1497. #if WASM_ENABLE_PERF_PROFILING != 0
  1498. total_size = (uint64)sizeof(AOTFuncPerfProfInfo)
  1499. * (module->import_func_count + module->func_count);
  1500. if (!(module_inst->func_perf_profilings =
  1501. runtime_malloc(total_size, error_buf, error_buf_size))) {
  1502. goto fail;
  1503. }
  1504. #endif
  1505. #if WASM_ENABLE_GC != 0
  1506. for (i = 0; i < module_inst->table_count; i++) {
  1507. uint32 j;
  1508. AOTTable *table;
  1509. AOTTableInstance *table_inst;
  1510. table_elem_type_t *table_data;
  1511. table = &module->tables[i];
  1512. bh_assert(table);
  1513. if (table->init_expr.init_expr_type == INIT_EXPR_NONE) {
  1514. continue;
  1515. }
  1516. table_inst = module_inst->tables[i];
  1517. bh_assert(table_inst);
  1518. table_data = table_inst->elems;
  1519. bh_assert(table_data);
  1520. for (j = 0; j < table_inst->cur_size; j++) {
  1521. if (!assign_table_init_value(module_inst, module, &table->init_expr,
  1522. table_data + j, error_buf,
  1523. error_buf_size)) {
  1524. goto fail;
  1525. }
  1526. }
  1527. }
  1528. /* Initialize the table data with table init data */
  1529. for (i = 0;
  1530. module_inst->table_count > 0 && i < module->table_init_data_count;
  1531. i++) {
  1532. AOTTableInitData *table_init_data = module->table_init_data_list[i];
  1533. AOTTableInstance *table;
  1534. table_elem_type_t *table_data;
  1535. uint8 tbl_elem_type;
  1536. uint32 tbl_init_size, tbl_max_size, j;
  1537. WASMRefType *tbl_elem_ref_type;
  1538. bh_assert(table_init_data);
  1539. bh_assert(table_init_data->table_index < module_inst->table_count);
  1540. table = module_inst->tables[table_init_data->table_index];
  1541. bh_assert(table);
  1542. table_data = table->elems;
  1543. bh_assert(table_data);
  1544. wasm_runtime_get_table_inst_elem_type(
  1545. (WASMModuleInstanceCommon *)module_inst,
  1546. table_init_data->table_index, &tbl_elem_type, &tbl_elem_ref_type,
  1547. &tbl_init_size, &tbl_max_size);
  1548. if (!wasm_elem_is_declarative(table_init_data->mode)
  1549. && !wasm_reftype_is_subtype_of(
  1550. table_init_data->elem_type, table_init_data->elem_ref_type,
  1551. table->elem_type, table->elem_ref_type.elem_ref_type,
  1552. module->types, module->type_count)) {
  1553. set_error_buf(error_buf, error_buf_size,
  1554. "type mismatch: elements segment does not fit");
  1555. goto fail;
  1556. }
  1557. (void)tbl_init_size;
  1558. (void)tbl_max_size;
  1559. if (!wasm_elem_is_active(table_init_data->mode)) {
  1560. continue;
  1561. }
  1562. bh_assert(table_init_data->offset.init_expr_type
  1563. == INIT_EXPR_TYPE_I32_CONST
  1564. || table_init_data->offset.init_expr_type
  1565. == INIT_EXPR_TYPE_GET_GLOBAL
  1566. || table_init_data->offset.init_expr_type
  1567. == INIT_EXPR_TYPE_FUNCREF_CONST
  1568. || table_init_data->offset.init_expr_type
  1569. == INIT_EXPR_TYPE_REFNULL_CONST);
  1570. /* init vec(funcidx) or vec(expr) */
  1571. if (table_init_data->offset.init_expr_type
  1572. == INIT_EXPR_TYPE_GET_GLOBAL) {
  1573. uint32 data_offset;
  1574. if (!check_global_init_expr(module,
  1575. table_init_data->offset.u.global_index,
  1576. error_buf, error_buf_size)) {
  1577. goto fail;
  1578. }
  1579. if (table_init_data->offset.u.global_index
  1580. < module->import_global_count) {
  1581. data_offset =
  1582. module
  1583. ->import_globals[table_init_data->offset.u.global_index]
  1584. .data_offset;
  1585. }
  1586. else {
  1587. data_offset =
  1588. module
  1589. ->globals[table_init_data->offset.u.global_index
  1590. - module->import_global_count]
  1591. .data_offset;
  1592. }
  1593. table_init_data->offset.u.i32 =
  1594. *(uint32 *)(module_inst->global_data + data_offset);
  1595. }
  1596. /* check offset since length might negative */
  1597. if ((uint32)table_init_data->offset.u.i32 > table->cur_size) {
  1598. LOG_DEBUG("base_offset(%d) > table->cur_size(%d)",
  1599. table_init_data->offset.u.i32, table->cur_size);
  1600. set_error_buf(error_buf, error_buf_size,
  1601. "out of bounds table access");
  1602. goto fail;
  1603. }
  1604. if ((uint32)table_init_data->offset.u.i32 + table_init_data->value_count
  1605. > table->cur_size) {
  1606. LOG_DEBUG("base_offset(%d) + length(%d) > table->cur_size(%d)",
  1607. table_init_data->offset.u.i32,
  1608. table_init_data->value_count, table->cur_size);
  1609. set_error_buf(error_buf, error_buf_size,
  1610. "out of bounds table access");
  1611. goto fail;
  1612. }
  1613. for (j = 0; j < module->table_init_data_list[i]->value_count; j++) {
  1614. if (!assign_table_init_value(
  1615. module_inst, module, &table_init_data->init_values[j],
  1616. table_data + table_init_data->offset.u.i32 + j, error_buf,
  1617. error_buf_size)) {
  1618. goto fail;
  1619. }
  1620. }
  1621. }
  1622. #endif
  1623. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1624. if (!(module_inst->frames =
  1625. runtime_malloc(sizeof(Vector), error_buf, error_buf_size))) {
  1626. goto fail;
  1627. }
  1628. #endif
  1629. if (!execute_post_instantiate_functions(module_inst, is_sub_inst,
  1630. exec_env_main)) {
  1631. set_error_buf(error_buf, error_buf_size, module_inst->cur_exception);
  1632. goto fail;
  1633. }
  1634. #if WASM_ENABLE_MEMORY_TRACING != 0
  1635. wasm_runtime_dump_module_inst_mem_consumption(
  1636. (WASMModuleInstanceCommon *)module_inst);
  1637. #endif
  1638. return module_inst;
  1639. fail:
  1640. aot_deinstantiate(module_inst, is_sub_inst);
  1641. return NULL;
  1642. }
  1643. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1644. static void
  1645. destroy_c_api_frames(Vector *frames)
  1646. {
  1647. WASMCApiFrame frame = { 0 };
  1648. uint32 i, total_frames, ret;
  1649. total_frames = (uint32)bh_vector_size(frames);
  1650. for (i = 0; i < total_frames; i++) {
  1651. ret = bh_vector_get(frames, i, &frame);
  1652. bh_assert(ret);
  1653. if (frame.lp)
  1654. wasm_runtime_free(frame.lp);
  1655. }
  1656. ret = bh_vector_destroy(frames);
  1657. bh_assert(ret);
  1658. (void)ret;
  1659. }
  1660. #endif
  1661. void
  1662. aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
  1663. {
  1664. WASMModuleInstanceExtraCommon *common =
  1665. &((AOTModuleInstanceExtra *)module_inst->e)->common;
  1666. if (module_inst->exec_env_singleton) {
  1667. /* wasm_exec_env_destroy will call
  1668. wasm_cluster_wait_for_all_except_self to wait for other
  1669. threads, so as to destroy their exec_envs and module
  1670. instances first, and avoid accessing the shared resources
  1671. of current module instance after it is deinstantiated. */
  1672. wasm_exec_env_destroy((WASMExecEnv *)module_inst->exec_env_singleton);
  1673. }
  1674. #if WASM_ENABLE_PERF_PROFILING != 0
  1675. if (module_inst->func_perf_profilings)
  1676. wasm_runtime_free(module_inst->func_perf_profilings);
  1677. #endif
  1678. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1679. if (module_inst->frames) {
  1680. destroy_c_api_frames(module_inst->frames);
  1681. wasm_runtime_free(module_inst->frames);
  1682. module_inst->frames = NULL;
  1683. }
  1684. #endif
  1685. #if WASM_ENABLE_MULTI_MODULE != 0
  1686. wasm_runtime_sub_module_deinstantiate(
  1687. (WASMModuleInstanceCommon *)module_inst);
  1688. #endif
  1689. if (module_inst->tables)
  1690. wasm_runtime_free(module_inst->tables);
  1691. if (module_inst->memories)
  1692. memories_deinstantiate(module_inst);
  1693. if (module_inst->export_functions)
  1694. wasm_runtime_free(module_inst->export_functions);
  1695. if (module_inst->func_ptrs)
  1696. wasm_runtime_free(module_inst->func_ptrs);
  1697. if (module_inst->func_type_indexes)
  1698. wasm_runtime_free(module_inst->func_type_indexes);
  1699. if (module_inst->c_api_func_imports)
  1700. wasm_runtime_free(module_inst->c_api_func_imports);
  1701. #if WASM_ENABLE_GC != 0
  1702. if (!is_sub_inst) {
  1703. AOTModuleInstanceExtra *extra =
  1704. (AOTModuleInstanceExtra *)module_inst->e;
  1705. if (extra->common.gc_heap_handle)
  1706. mem_allocator_destroy(extra->common.gc_heap_handle);
  1707. if (extra->common.gc_heap_pool)
  1708. wasm_runtime_free(extra->common.gc_heap_pool);
  1709. }
  1710. #endif
  1711. if (!is_sub_inst) {
  1712. #if WASM_ENABLE_WASI_NN != 0
  1713. wasi_nn_destroy(module_inst);
  1714. #endif
  1715. wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
  1716. }
  1717. #if WASM_ENABLE_BULK_MEMORY != 0
  1718. bh_bitmap_delete(common->data_dropped);
  1719. #endif
  1720. #if WASM_ENABLE_REF_TYPES != 0
  1721. bh_bitmap_delete(common->elem_dropped);
  1722. #endif
  1723. wasm_runtime_free(module_inst);
  1724. }
  1725. AOTFunctionInstance *
  1726. aot_lookup_function(const AOTModuleInstance *module_inst, const char *name)
  1727. {
  1728. uint32 i;
  1729. AOTFunctionInstance *export_funcs =
  1730. (AOTFunctionInstance *)module_inst->export_functions;
  1731. for (i = 0; i < module_inst->export_func_count; i++)
  1732. if (!strcmp(export_funcs[i].func_name, name))
  1733. return &export_funcs[i];
  1734. return NULL;
  1735. }
  1736. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1737. static bool
  1738. invoke_native_with_hw_bound_check(WASMExecEnv *exec_env, void *func_ptr,
  1739. const WASMFuncType *func_type,
  1740. const char *signature, void *attachment,
  1741. uint32 *argv, uint32 argc, uint32 *argv_ret)
  1742. {
  1743. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  1744. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  1745. WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
  1746. #ifdef BH_PLATFORM_WINDOWS
  1747. int result;
  1748. bool has_exception;
  1749. char exception[EXCEPTION_BUF_LEN];
  1750. #endif
  1751. bool ret;
  1752. /* Check native stack overflow firstly to ensure we have enough
  1753. native stack to run the following codes before actually calling
  1754. the aot function in invokeNative function. */
  1755. if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
  1756. return false;
  1757. }
  1758. if (!exec_env_tls) {
  1759. if (!os_thread_signal_inited()) {
  1760. aot_set_exception(module_inst, "thread signal env not inited");
  1761. return false;
  1762. }
  1763. /* Set thread handle and stack boundary if they haven't been set */
  1764. wasm_exec_env_set_thread_info(exec_env);
  1765. wasm_runtime_set_exec_env_tls(exec_env);
  1766. }
  1767. else {
  1768. if (exec_env_tls != exec_env) {
  1769. aot_set_exception(module_inst, "invalid exec env");
  1770. return false;
  1771. }
  1772. }
  1773. wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node);
  1774. if (os_setjmp(jmpbuf_node.jmpbuf) == 0) {
  1775. #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
  1776. /* Quick call if the quick aot entry is registered */
  1777. if (!signature && func_type->quick_aot_entry) {
  1778. void (*invoke_native)(void *func_ptr, void *exec_env, uint32 *argv,
  1779. uint32 *argv_ret) =
  1780. func_type->quick_aot_entry;
  1781. invoke_native(func_ptr, exec_env, argv, argv_ret);
  1782. ret = !aot_copy_exception(module_inst, NULL);
  1783. }
  1784. else
  1785. #endif
  1786. {
  1787. ret = wasm_runtime_invoke_native(exec_env, func_ptr, func_type,
  1788. signature, attachment, argv, argc,
  1789. argv_ret);
  1790. }
  1791. #ifdef BH_PLATFORM_WINDOWS
  1792. has_exception = aot_copy_exception(module_inst, exception);
  1793. if (has_exception && strstr(exception, "native stack overflow")) {
  1794. /* After a stack overflow, the stack was left
  1795. in a damaged state, let the CRT repair it */
  1796. result = _resetstkoflw();
  1797. bh_assert(result != 0);
  1798. }
  1799. #endif
  1800. }
  1801. else {
  1802. /* Exception has been set in signal handler before calling longjmp */
  1803. ret = false;
  1804. }
  1805. jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);
  1806. bh_assert(&jmpbuf_node == jmpbuf_node_pop);
  1807. if (!exec_env->jmpbuf_stack_top) {
  1808. wasm_runtime_set_exec_env_tls(NULL);
  1809. }
  1810. if (!ret) {
  1811. os_sigreturn();
  1812. os_signal_unmask();
  1813. }
  1814. (void)jmpbuf_node_pop;
  1815. return ret;
  1816. }
  1817. #define invoke_native_internal invoke_native_with_hw_bound_check /* NOLINT */
  1818. #else /* else of OS_ENABLE_HW_BOUND_CHECK */
  1819. static inline bool
  1820. invoke_native_internal(WASMExecEnv *exec_env, void *func_ptr,
  1821. const WASMFuncType *func_type, const char *signature,
  1822. void *attachment, uint32 *argv, uint32 argc,
  1823. uint32 *argv_ret)
  1824. {
  1825. #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
  1826. /* Quick call if the quick aot entry is registered */
  1827. if (!signature && func_type->quick_aot_entry) {
  1828. AOTModuleInstance *module_inst =
  1829. (AOTModuleInstance *)exec_env->module_inst;
  1830. void (*invoke_native)(void *func_ptr, void *exec_env, uint32 *argv,
  1831. uint32 *argv_ret) = func_type->quick_aot_entry;
  1832. invoke_native(func_ptr, exec_env, argv, argv_ret);
  1833. return !aot_copy_exception(module_inst, NULL);
  1834. }
  1835. #endif
  1836. return wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature,
  1837. attachment, argv, argc, argv_ret);
  1838. }
  1839. #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
  1840. #ifdef AOT_STACK_FRAME_DEBUG
  1841. typedef void (*stack_frame_callback_t)(struct WASMExecEnv *exec_env);
  1842. static stack_frame_callback_t aot_stack_frame_callback;
  1843. /* set the callback, only for debug purpose */
  1844. void
  1845. aot_set_stack_frame_callback(stack_frame_callback_t callback)
  1846. {
  1847. aot_stack_frame_callback = callback;
  1848. }
  1849. #endif
  1850. bool
  1851. aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
  1852. unsigned argc, uint32 argv[])
  1853. {
  1854. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  1855. AOTFuncType *func_type = function->is_import_func
  1856. ? function->u.func_import->func_type
  1857. : function->u.func.func_type;
  1858. uint32 result_count = func_type->result_count;
  1859. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  1860. bool ret;
  1861. void *func_ptr = function->is_import_func
  1862. ? function->u.func_import->func_ptr_linked
  1863. : function->u.func.func_ptr;
  1864. #if WASM_ENABLE_MULTI_MODULE != 0
  1865. bh_list *sub_module_list_node = NULL;
  1866. const char *sub_inst_name = NULL;
  1867. const char *func_name = function->u.func_import->module_name;
  1868. if (function->is_import_func) {
  1869. sub_module_list_node =
  1870. ((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list;
  1871. sub_module_list_node = bh_list_first_elem(sub_module_list_node);
  1872. while (sub_module_list_node) {
  1873. sub_inst_name =
  1874. ((AOTSubModInstNode *)sub_module_list_node)->module_name;
  1875. if (strcmp(sub_inst_name, func_name) == 0) {
  1876. exec_env = wasm_runtime_get_exec_env_singleton(
  1877. (WASMModuleInstanceCommon *)((AOTSubModInstNode *)
  1878. sub_module_list_node)
  1879. ->module_inst);
  1880. module_inst = (AOTModuleInstance *)exec_env->module_inst;
  1881. break;
  1882. }
  1883. sub_module_list_node = bh_list_elem_next(sub_module_list_node);
  1884. }
  1885. if (exec_env == NULL) {
  1886. wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst,
  1887. "create singleton exec_env failed");
  1888. return false;
  1889. }
  1890. }
  1891. #endif
  1892. if (argc < func_type->param_cell_num) {
  1893. char buf[108];
  1894. snprintf(buf, sizeof(buf),
  1895. "invalid argument count %u, must be no smaller than %u", argc,
  1896. func_type->param_cell_num);
  1897. aot_set_exception(module_inst, buf);
  1898. return false;
  1899. }
  1900. argc = func_type->param_cell_num;
  1901. #if defined(os_writegsbase)
  1902. {
  1903. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  1904. if (memory_inst)
  1905. /* write base addr of linear memory to GS segment register */
  1906. os_writegsbase(memory_inst->memory_data);
  1907. }
  1908. #endif
  1909. /* func pointer was looked up previously */
  1910. bh_assert(func_ptr != NULL);
  1911. #ifndef OS_ENABLE_HW_BOUND_CHECK
  1912. /* Set thread handle and stack boundary */
  1913. wasm_exec_env_set_thread_info(exec_env);
  1914. #else
  1915. /* Set thread info in invoke_native_with_hw_bound_check when
  1916. hw bound check is enabled */
  1917. #endif
  1918. /* Set exec env, so it can be later retrieved from instance */
  1919. module_inst->cur_exec_env = exec_env;
  1920. if (ext_ret_count > 0) {
  1921. uint32 cell_num = 0, i;
  1922. uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
  1923. uint32 argv1_buf[32], *argv1 = argv1_buf, *ext_rets = NULL;
  1924. uint32 *argv_ret = argv;
  1925. uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
  1926. uint64 size;
  1927. #if WASM_ENABLE_AOT_STACK_FRAME != 0
  1928. struct WASMInterpFrame *prev_frame = exec_env->cur_frame;
  1929. #endif
  1930. /* Allocate memory all arguments */
  1931. size =
  1932. sizeof(uint32) * (uint64)argc /* original arguments */
  1933. + sizeof(void *)
  1934. * (uint64)ext_ret_count /* extra result values' addr */
  1935. + sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
  1936. if (size > sizeof(argv1_buf)
  1937. && !(argv1 = runtime_malloc(size, module_inst->cur_exception,
  1938. sizeof(module_inst->cur_exception)))) {
  1939. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
  1940. return false;
  1941. }
  1942. /* Copy original arguments */
  1943. bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
  1944. /* Get the extra result value's address */
  1945. ext_rets =
  1946. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  1947. /* Append each extra result value's address to original arguments */
  1948. for (i = 0; i < ext_ret_count; i++) {
  1949. *(uintptr_t *)(argv1 + argc + sizeof(void *) / sizeof(uint32) * i) =
  1950. (uintptr_t)(ext_rets + cell_num);
  1951. cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
  1952. }
  1953. #if WASM_ENABLE_AOT_STACK_FRAME != 0
  1954. if (!aot_alloc_frame(exec_env, function->func_index)) {
  1955. if (argv1 != argv1_buf)
  1956. wasm_runtime_free(argv1);
  1957. return false;
  1958. }
  1959. #endif
  1960. ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
  1961. func_type, NULL, NULL, argv1, argc, argv);
  1962. if (!ret) {
  1963. #ifdef AOT_STACK_FRAME_DEBUG
  1964. if (aot_stack_frame_callback) {
  1965. aot_stack_frame_callback(exec_env);
  1966. }
  1967. #endif
  1968. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  1969. if (aot_create_call_stack(exec_env)) {
  1970. aot_dump_call_stack(exec_env, true, NULL, 0);
  1971. }
  1972. #endif
  1973. }
  1974. #if WASM_ENABLE_AOT_STACK_FRAME != 0
  1975. /* Free all frames allocated, note that some frames
  1976. may be allocated in AOT code and haven't been
  1977. freed if exception occurred */
  1978. while (exec_env->cur_frame != prev_frame)
  1979. aot_free_frame(exec_env);
  1980. #endif
  1981. if (!ret) {
  1982. if (argv1 != argv1_buf)
  1983. wasm_runtime_free(argv1);
  1984. return ret;
  1985. }
  1986. /* Get extra result values */
  1987. switch (func_type->types[func_type->param_count]) {
  1988. case VALUE_TYPE_I32:
  1989. case VALUE_TYPE_F32:
  1990. #if WASM_ENABLE_REF_TYPES != 0
  1991. case VALUE_TYPE_FUNCREF:
  1992. case VALUE_TYPE_EXTERNREF:
  1993. #endif
  1994. argv_ret++;
  1995. break;
  1996. case VALUE_TYPE_I64:
  1997. case VALUE_TYPE_F64:
  1998. argv_ret += 2;
  1999. break;
  2000. #if WASM_ENABLE_SIMD != 0
  2001. case VALUE_TYPE_V128:
  2002. argv_ret += 4;
  2003. break;
  2004. #endif
  2005. default:
  2006. bh_assert(0);
  2007. break;
  2008. }
  2009. ext_rets =
  2010. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  2011. bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num, ext_rets,
  2012. sizeof(uint32) * cell_num);
  2013. if (argv1 != argv1_buf)
  2014. wasm_runtime_free(argv1);
  2015. return true;
  2016. }
  2017. else {
  2018. #if WASM_ENABLE_AOT_STACK_FRAME != 0
  2019. struct WASMInterpFrame *prev_frame = exec_env->cur_frame;
  2020. if (!aot_alloc_frame(exec_env, function->func_index)) {
  2021. return false;
  2022. }
  2023. #endif
  2024. ret = invoke_native_internal(exec_env, func_ptr, func_type, NULL, NULL,
  2025. argv, argc, argv);
  2026. if (aot_copy_exception(module_inst, NULL)) {
  2027. #ifdef AOT_STACK_FRAME_DEBUG
  2028. if (aot_stack_frame_callback) {
  2029. aot_stack_frame_callback(exec_env);
  2030. }
  2031. #endif
  2032. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  2033. if (aot_create_call_stack(exec_env)) {
  2034. aot_dump_call_stack(exec_env, true, NULL, 0);
  2035. }
  2036. #endif
  2037. }
  2038. #if WASM_ENABLE_AOT_STACK_FRAME != 0
  2039. /* Free all frames allocated, note that some frames
  2040. may be allocated in AOT code and haven't been
  2041. freed if exception occurred */
  2042. while (exec_env->cur_frame != prev_frame)
  2043. aot_free_frame(exec_env);
  2044. #endif
  2045. return ret && !aot_copy_exception(module_inst, NULL) ? true : false;
  2046. }
  2047. }
  2048. void
  2049. aot_set_exception(AOTModuleInstance *module_inst, const char *exception)
  2050. {
  2051. wasm_set_exception(module_inst, exception);
  2052. }
  2053. void
  2054. aot_set_exception_with_id(AOTModuleInstance *module_inst, uint32 id)
  2055. {
  2056. if (id != EXCE_ALREADY_THROWN)
  2057. wasm_set_exception_with_id(module_inst, id);
  2058. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2059. wasm_runtime_access_exce_check_guard_page();
  2060. #endif
  2061. }
  2062. const char *
  2063. aot_get_exception(AOTModuleInstance *module_inst)
  2064. {
  2065. return wasm_get_exception(module_inst);
  2066. }
  2067. bool
  2068. aot_copy_exception(AOTModuleInstance *module_inst, char *exception_buf)
  2069. {
  2070. /* The field offsets of cur_exception in AOTModuleInstance and
  2071. WASMModuleInstance are the same */
  2072. return wasm_copy_exception(module_inst, exception_buf);
  2073. }
  2074. static bool
  2075. execute_malloc_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
  2076. AOTFunctionInstance *malloc_func,
  2077. AOTFunctionInstance *retain_func, uint64 size,
  2078. uint64 *p_result)
  2079. {
  2080. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2081. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  2082. #endif
  2083. WASMExecEnv *exec_env_created = NULL;
  2084. WASMModuleInstanceCommon *module_inst_old = NULL;
  2085. union {
  2086. uint32 u32[3];
  2087. uint64 u64;
  2088. } argv;
  2089. uint32 argc;
  2090. bool ret;
  2091. #if WASM_ENABLE_MEMORY64 != 0
  2092. bool is_memory64 = module_inst->memories[0]->is_memory64;
  2093. if (is_memory64) {
  2094. argc = 2;
  2095. PUT_I64_TO_ADDR(&argv.u64, size);
  2096. }
  2097. else
  2098. #endif
  2099. {
  2100. argc = 1;
  2101. argv.u32[0] = (uint32)size;
  2102. }
  2103. /* if __retain is exported, then this module is compiled by
  2104. assemblyscript, the memory should be managed by as's runtime,
  2105. in this case we need to call the retain function after malloc
  2106. the memory */
  2107. if (retain_func) {
  2108. /* the malloc function from assemblyscript is:
  2109. function __new(size: usize, id: u32)
  2110. id = 0 means this is an ArrayBuffer object */
  2111. argv.u32[argc] = 0;
  2112. argc++;
  2113. }
  2114. if (exec_env) {
  2115. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2116. if (exec_env_tls) {
  2117. bh_assert(exec_env_tls == exec_env);
  2118. }
  2119. #endif
  2120. bh_assert(exec_env->module_inst
  2121. == (WASMModuleInstanceCommon *)module_inst);
  2122. }
  2123. else {
  2124. /* Try using the existing exec_env */
  2125. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2126. exec_env = exec_env_tls;
  2127. #endif
  2128. #if WASM_ENABLE_THREAD_MGR != 0
  2129. if (!exec_env)
  2130. exec_env = wasm_clusters_search_exec_env(
  2131. (WASMModuleInstanceCommon *)module_inst);
  2132. #endif
  2133. if (!exec_env) {
  2134. if (!(exec_env = exec_env_created = wasm_exec_env_create(
  2135. (WASMModuleInstanceCommon *)module_inst,
  2136. module_inst->default_wasm_stack_size))) {
  2137. wasm_set_exception(module_inst, "allocate memory failed");
  2138. return false;
  2139. }
  2140. }
  2141. else {
  2142. /* Temporarily replace exec_env's module inst with current
  2143. module inst to ensure that the exec_env's module inst
  2144. is the correct one. */
  2145. module_inst_old = exec_env->module_inst;
  2146. wasm_exec_env_set_module_inst(
  2147. exec_env, (WASMModuleInstanceCommon *)module_inst);
  2148. }
  2149. }
  2150. ret = aot_call_function(exec_env, malloc_func, argc, argv.u32);
  2151. if (retain_func && ret)
  2152. ret = aot_call_function(exec_env, retain_func, 1, argv.u32);
  2153. if (module_inst_old)
  2154. /* Restore the existing exec_env's module inst */
  2155. wasm_exec_env_restore_module_inst(exec_env, module_inst_old);
  2156. if (exec_env_created)
  2157. wasm_exec_env_destroy(exec_env_created);
  2158. if (ret) {
  2159. #if WASM_ENABLE_MEMORY64 != 0
  2160. if (is_memory64)
  2161. *p_result = GET_I64_FROM_ADDR(&argv.u64);
  2162. else
  2163. #endif
  2164. {
  2165. *p_result = argv.u32[0];
  2166. }
  2167. }
  2168. return ret;
  2169. }
  2170. static bool
  2171. execute_free_function(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
  2172. AOTFunctionInstance *free_func, uint64 offset)
  2173. {
  2174. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2175. WASMExecEnv *exec_env_tls = wasm_runtime_get_exec_env_tls();
  2176. #endif
  2177. WASMExecEnv *exec_env_created = NULL;
  2178. WASMModuleInstanceCommon *module_inst_old = NULL;
  2179. union {
  2180. uint32 u32[2];
  2181. uint64 u64;
  2182. } argv;
  2183. uint32 argc;
  2184. bool ret;
  2185. #if WASM_ENABLE_MEMORY64 != 0
  2186. if (module_inst->memories[0]->is_memory64) {
  2187. PUT_I64_TO_ADDR(&argv.u64, offset);
  2188. argc = 2;
  2189. }
  2190. else
  2191. #endif
  2192. {
  2193. argv.u32[0] = (uint32)offset;
  2194. argc = 1;
  2195. }
  2196. if (exec_env) {
  2197. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2198. if (exec_env_tls) {
  2199. bh_assert(exec_env_tls == exec_env);
  2200. }
  2201. #endif
  2202. bh_assert(exec_env->module_inst
  2203. == (WASMModuleInstanceCommon *)module_inst);
  2204. }
  2205. else {
  2206. /* Try using the existing exec_env */
  2207. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2208. exec_env = exec_env_tls;
  2209. #endif
  2210. #if WASM_ENABLE_THREAD_MGR != 0
  2211. if (!exec_env)
  2212. exec_env = wasm_clusters_search_exec_env(
  2213. (WASMModuleInstanceCommon *)module_inst);
  2214. #endif
  2215. if (!exec_env) {
  2216. if (!(exec_env = exec_env_created = wasm_exec_env_create(
  2217. (WASMModuleInstanceCommon *)module_inst,
  2218. module_inst->default_wasm_stack_size))) {
  2219. wasm_set_exception(module_inst, "allocate memory failed");
  2220. return false;
  2221. }
  2222. }
  2223. else {
  2224. /* Temporarily replace exec_env's module inst with current
  2225. module inst to ensure that the exec_env's module inst
  2226. is the correct one. */
  2227. module_inst_old = exec_env->module_inst;
  2228. wasm_exec_env_set_module_inst(
  2229. exec_env, (WASMModuleInstanceCommon *)module_inst);
  2230. }
  2231. }
  2232. ret = aot_call_function(exec_env, free_func, argc, argv.u32);
  2233. if (module_inst_old)
  2234. /* Restore the existing exec_env's module inst */
  2235. wasm_exec_env_restore_module_inst(exec_env, module_inst_old);
  2236. if (exec_env_created)
  2237. wasm_exec_env_destroy(exec_env_created);
  2238. return ret;
  2239. }
  2240. uint64
  2241. aot_module_malloc_internal(AOTModuleInstance *module_inst,
  2242. WASMExecEnv *exec_env, uint64 size,
  2243. void **p_native_addr)
  2244. {
  2245. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  2246. AOTModule *module = (AOTModule *)module_inst->module;
  2247. uint8 *addr = NULL;
  2248. uint64 offset = 0;
  2249. /* TODO: Memory64 size check based on memory idx type */
  2250. bh_assert(size <= UINT32_MAX);
  2251. if (!memory_inst) {
  2252. aot_set_exception(module_inst, "uninitialized memory");
  2253. return 0;
  2254. }
  2255. if (memory_inst->heap_handle) {
  2256. addr = mem_allocator_malloc(memory_inst->heap_handle, (uint32)size);
  2257. }
  2258. else if (module->malloc_func_index != (uint32)-1
  2259. && module->free_func_index != (uint32)-1) {
  2260. AOTFunctionInstance *malloc_func, *retain_func = NULL;
  2261. char *malloc_func_name;
  2262. if (module->retain_func_index != (uint32)-1) {
  2263. malloc_func_name = "__new";
  2264. retain_func = aot_lookup_function(module_inst, "__retain");
  2265. if (!retain_func)
  2266. retain_func = aot_lookup_function(module_inst, "__pin");
  2267. bh_assert(retain_func);
  2268. }
  2269. else {
  2270. malloc_func_name = "malloc";
  2271. }
  2272. malloc_func = aot_lookup_function(module_inst, malloc_func_name);
  2273. if (!malloc_func
  2274. || !execute_malloc_function(module_inst, exec_env, malloc_func,
  2275. retain_func, size, &offset)) {
  2276. return 0;
  2277. }
  2278. addr = offset ? (uint8 *)memory_inst->memory_data + offset : NULL;
  2279. }
  2280. if (!addr) {
  2281. if (memory_inst->heap_handle
  2282. && mem_allocator_is_heap_corrupted(memory_inst->heap_handle)) {
  2283. wasm_runtime_show_app_heap_corrupted_prompt();
  2284. aot_set_exception(module_inst, "app heap corrupted");
  2285. }
  2286. else {
  2287. LOG_WARNING("warning: allocate %" PRIu64 " bytes memory failed",
  2288. size);
  2289. }
  2290. return 0;
  2291. }
  2292. if (p_native_addr)
  2293. *p_native_addr = addr;
  2294. return (uint64)(addr - memory_inst->memory_data);
  2295. }
  2296. uint64
  2297. aot_module_realloc_internal(AOTModuleInstance *module_inst,
  2298. WASMExecEnv *exec_env, uint64 ptr, uint64 size,
  2299. void **p_native_addr)
  2300. {
  2301. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  2302. uint8 *addr = NULL;
  2303. /* TODO: Memory64 ptr and size check based on memory idx type */
  2304. bh_assert(ptr <= UINT32_MAX);
  2305. bh_assert(size <= UINT32_MAX);
  2306. if (!memory_inst) {
  2307. aot_set_exception(module_inst, "uninitialized memory");
  2308. return 0;
  2309. }
  2310. if (memory_inst->heap_handle) {
  2311. addr = mem_allocator_realloc(
  2312. memory_inst->heap_handle,
  2313. (uint32)ptr ? memory_inst->memory_data + (uint32)ptr : NULL,
  2314. (uint32)size);
  2315. }
  2316. /* Only support realloc in WAMR's app heap */
  2317. (void)exec_env;
  2318. if (!addr) {
  2319. if (memory_inst->heap_handle
  2320. && mem_allocator_is_heap_corrupted(memory_inst->heap_handle)) {
  2321. aot_set_exception(module_inst, "app heap corrupted");
  2322. }
  2323. else {
  2324. aot_set_exception(module_inst, "out of memory");
  2325. }
  2326. return 0;
  2327. }
  2328. if (p_native_addr)
  2329. *p_native_addr = addr;
  2330. return (uint64)(addr - memory_inst->memory_data);
  2331. }
  2332. void
  2333. aot_module_free_internal(AOTModuleInstance *module_inst, WASMExecEnv *exec_env,
  2334. uint64 ptr)
  2335. {
  2336. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  2337. AOTModule *module = (AOTModule *)module_inst->module;
  2338. if (!memory_inst) {
  2339. return;
  2340. }
  2341. /* TODO: Memory64 ptr and size check based on memory idx type */
  2342. bh_assert(ptr <= UINT32_MAX);
  2343. if (ptr) {
  2344. uint8 *addr = memory_inst->memory_data + (uint32)ptr;
  2345. uint8 *memory_data_end;
  2346. /* memory->memory_data_end may be changed in memory grow */
  2347. SHARED_MEMORY_LOCK(memory_inst);
  2348. memory_data_end = memory_inst->memory_data_end;
  2349. SHARED_MEMORY_UNLOCK(memory_inst);
  2350. if (memory_inst->heap_handle && memory_inst->heap_data < addr
  2351. && addr < memory_inst->heap_data_end) {
  2352. mem_allocator_free(memory_inst->heap_handle, addr);
  2353. }
  2354. else if (module->malloc_func_index != (uint32)-1
  2355. && module->free_func_index != (uint32)-1
  2356. && memory_inst->memory_data <= addr
  2357. && addr < memory_data_end) {
  2358. AOTFunctionInstance *free_func;
  2359. char *free_func_name;
  2360. if (module->retain_func_index != (uint32)-1) {
  2361. free_func_name = "__release";
  2362. }
  2363. else {
  2364. free_func_name = "free";
  2365. }
  2366. free_func = aot_lookup_function(module_inst, free_func_name);
  2367. if (!free_func && module->retain_func_index != (uint32)-1)
  2368. free_func = aot_lookup_function(module_inst, "__unpin");
  2369. if (free_func)
  2370. execute_free_function(module_inst, exec_env, free_func, ptr);
  2371. }
  2372. }
  2373. }
  2374. uint64
  2375. aot_module_malloc(AOTModuleInstance *module_inst, uint64 size,
  2376. void **p_native_addr)
  2377. {
  2378. return aot_module_malloc_internal(module_inst, NULL, size, p_native_addr);
  2379. }
  2380. uint64
  2381. aot_module_realloc(AOTModuleInstance *module_inst, uint64 ptr, uint64 size,
  2382. void **p_native_addr)
  2383. {
  2384. return aot_module_realloc_internal(module_inst, NULL, ptr, size,
  2385. p_native_addr);
  2386. }
  2387. void
  2388. aot_module_free(AOTModuleInstance *module_inst, uint64 ptr)
  2389. {
  2390. aot_module_free_internal(module_inst, NULL, ptr);
  2391. }
  2392. uint64
  2393. aot_module_dup_data(AOTModuleInstance *module_inst, const char *src,
  2394. uint64 size)
  2395. {
  2396. char *buffer;
  2397. uint64 buffer_offset;
  2398. /* TODO: Memory64 size check based on memory idx type */
  2399. bh_assert(size <= UINT32_MAX);
  2400. buffer_offset = aot_module_malloc(module_inst, size, (void **)&buffer);
  2401. if (buffer_offset != 0) {
  2402. buffer = wasm_runtime_addr_app_to_native(
  2403. (WASMModuleInstanceCommon *)module_inst, buffer_offset);
  2404. bh_memcpy_s(buffer, (uint32)size, src, (uint32)size);
  2405. }
  2406. return buffer_offset;
  2407. }
  2408. bool
  2409. aot_enlarge_memory(AOTModuleInstance *module_inst, uint32 inc_page_count)
  2410. {
  2411. return wasm_enlarge_memory(module_inst, inc_page_count);
  2412. }
  2413. bool
  2414. aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
  2415. uint32 *argv)
  2416. {
  2417. AOTModuleInstance *module_inst =
  2418. (AOTModuleInstance *)wasm_runtime_get_module_inst(exec_env);
  2419. AOTModule *aot_module = (AOTModule *)module_inst->module;
  2420. CApiFuncImport *c_api_func_import =
  2421. module_inst->c_api_func_imports
  2422. ? module_inst->c_api_func_imports + func_idx
  2423. : NULL;
  2424. uint32 *func_type_indexes = module_inst->func_type_indexes;
  2425. uint32 func_type_idx = func_type_indexes[func_idx];
  2426. AOTFuncType *func_type = (AOTFuncType *)aot_module->types[func_type_idx];
  2427. void **func_ptrs = module_inst->func_ptrs;
  2428. void *func_ptr = func_ptrs[func_idx];
  2429. AOTImportFunc *import_func;
  2430. const char *signature;
  2431. void *attachment;
  2432. char buf[96];
  2433. bool ret = false;
  2434. #if WASM_ENABLE_MULTI_MODULE != 0
  2435. bh_list *sub_module_list_node = NULL;
  2436. const char *sub_inst_name = NULL;
  2437. #endif
  2438. bh_assert(func_idx < aot_module->import_func_count);
  2439. import_func = aot_module->import_funcs + func_idx;
  2440. if (import_func->call_conv_wasm_c_api)
  2441. func_ptr =
  2442. c_api_func_import ? c_api_func_import->func_ptr_linked : NULL;
  2443. if (!func_ptr) {
  2444. snprintf(buf, sizeof(buf),
  2445. "failed to call unlinked import function (%s, %s)",
  2446. import_func->module_name, import_func->func_name);
  2447. aot_set_exception(module_inst, buf);
  2448. goto fail;
  2449. }
  2450. attachment = import_func->attachment;
  2451. if (import_func->call_conv_wasm_c_api) {
  2452. ret = wasm_runtime_invoke_c_api_native(
  2453. (WASMModuleInstanceCommon *)module_inst, func_ptr, func_type, argc,
  2454. argv, c_api_func_import->with_env_arg, c_api_func_import->env_arg);
  2455. }
  2456. else if (!import_func->call_conv_raw) {
  2457. signature = import_func->signature;
  2458. #if WASM_ENABLE_MULTI_MODULE != 0
  2459. sub_module_list_node =
  2460. ((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list;
  2461. sub_module_list_node = bh_list_first_elem(sub_module_list_node);
  2462. while (sub_module_list_node) {
  2463. sub_inst_name =
  2464. ((AOTSubModInstNode *)sub_module_list_node)->module_name;
  2465. if (strcmp(sub_inst_name, import_func->module_name) == 0) {
  2466. exec_env = wasm_runtime_get_exec_env_singleton(
  2467. (WASMModuleInstanceCommon *)((AOTSubModInstNode *)
  2468. sub_module_list_node)
  2469. ->module_inst);
  2470. break;
  2471. }
  2472. sub_module_list_node = bh_list_elem_next(sub_module_list_node);
  2473. }
  2474. if (exec_env == NULL) {
  2475. wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst,
  2476. "create singleton exec_env failed");
  2477. goto fail;
  2478. }
  2479. #endif
  2480. ret =
  2481. wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature,
  2482. attachment, argv, argc, argv);
  2483. }
  2484. else {
  2485. signature = import_func->signature;
  2486. ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type,
  2487. signature, attachment, argv, argc,
  2488. argv);
  2489. }
  2490. fail:
  2491. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2492. if (!ret)
  2493. wasm_runtime_access_exce_check_guard_page();
  2494. #endif
  2495. return ret;
  2496. }
  2497. bool
  2498. aot_call_indirect(WASMExecEnv *exec_env, uint32 tbl_idx, uint32 table_elem_idx,
  2499. uint32 argc, uint32 *argv)
  2500. {
  2501. AOTModuleInstance *module_inst =
  2502. (AOTModuleInstance *)wasm_runtime_get_module_inst(exec_env);
  2503. AOTModule *aot_module = (AOTModule *)module_inst->module;
  2504. uint32 *func_type_indexes = module_inst->func_type_indexes;
  2505. AOTTableInstance *tbl_inst;
  2506. AOTFuncType *func_type;
  2507. void **func_ptrs = module_inst->func_ptrs, *func_ptr;
  2508. uint32 func_type_idx, func_idx, ext_ret_count;
  2509. table_elem_type_t tbl_elem_val = NULL_REF;
  2510. AOTImportFunc *import_func;
  2511. const char *signature = NULL;
  2512. void *attachment = NULL;
  2513. char buf[96];
  2514. bool ret;
  2515. /* this function is called from native code, so exec_env->handle and
  2516. exec_env->native_stack_boundary must have been set, we don't set
  2517. it again */
  2518. if (!wasm_runtime_detect_native_stack_overflow(exec_env)) {
  2519. goto fail;
  2520. }
  2521. tbl_inst = module_inst->tables[tbl_idx];
  2522. bh_assert(tbl_inst);
  2523. if (table_elem_idx >= tbl_inst->cur_size) {
  2524. aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
  2525. goto fail;
  2526. }
  2527. tbl_elem_val = ((table_elem_type_t *)tbl_inst->elems)[table_elem_idx];
  2528. if (tbl_elem_val == NULL_REF) {
  2529. aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
  2530. goto fail;
  2531. }
  2532. #if WASM_ENABLE_GC == 0
  2533. func_idx = (uint32)tbl_elem_val;
  2534. #else
  2535. func_idx =
  2536. wasm_func_obj_get_func_idx_bound((WASMFuncObjectRef)tbl_elem_val);
  2537. #endif
  2538. func_type_idx = func_type_indexes[func_idx];
  2539. func_type = (AOTFuncType *)aot_module->types[func_type_idx];
  2540. if (func_idx >= aot_module->import_func_count) {
  2541. /* func pointer was looked up previously */
  2542. bh_assert(func_ptrs[func_idx] != NULL);
  2543. }
  2544. if (!(func_ptr = func_ptrs[func_idx])) {
  2545. bh_assert(func_idx < aot_module->import_func_count);
  2546. import_func = aot_module->import_funcs + func_idx;
  2547. snprintf(buf, sizeof(buf),
  2548. "failed to call unlinked import function (%s, %s)",
  2549. import_func->module_name, import_func->func_name);
  2550. aot_set_exception(module_inst, buf);
  2551. goto fail;
  2552. }
  2553. if (func_idx < aot_module->import_func_count) {
  2554. /* Call native function */
  2555. import_func = aot_module->import_funcs + func_idx;
  2556. signature = import_func->signature;
  2557. if (import_func->call_conv_raw) {
  2558. attachment = import_func->attachment;
  2559. ret = wasm_runtime_invoke_native_raw(exec_env, func_ptr, func_type,
  2560. signature, attachment, argv,
  2561. argc, argv);
  2562. if (!ret)
  2563. goto fail;
  2564. return true;
  2565. }
  2566. }
  2567. ext_ret_count =
  2568. func_type->result_count > 1 ? func_type->result_count - 1 : 0;
  2569. if (ext_ret_count > 0) {
  2570. uint32 argv1_buf[32], *argv1 = argv1_buf;
  2571. uint32 *ext_rets = NULL, *argv_ret = argv;
  2572. uint32 cell_num = 0, i;
  2573. uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
  2574. uint32 ext_ret_cell = wasm_get_cell_num(ext_ret_types, ext_ret_count);
  2575. uint64 size;
  2576. /* Allocate memory all arguments */
  2577. size =
  2578. sizeof(uint32) * (uint64)argc /* original arguments */
  2579. + sizeof(void *)
  2580. * (uint64)ext_ret_count /* extra result values' addr */
  2581. + sizeof(uint32) * (uint64)ext_ret_cell; /* extra result values */
  2582. if (size > sizeof(argv1_buf)
  2583. && !(argv1 = runtime_malloc(size, module_inst->cur_exception,
  2584. sizeof(module_inst->cur_exception)))) {
  2585. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_MEMORY);
  2586. goto fail;
  2587. }
  2588. /* Copy original arguments */
  2589. bh_memcpy_s(argv1, (uint32)size, argv, sizeof(uint32) * argc);
  2590. /* Get the extra result value's address */
  2591. ext_rets =
  2592. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  2593. /* Append each extra result value's address to original arguments */
  2594. for (i = 0; i < ext_ret_count; i++) {
  2595. *(uintptr_t *)(argv1 + argc + sizeof(void *) / sizeof(uint32) * i) =
  2596. (uintptr_t)(ext_rets + cell_num);
  2597. cell_num += wasm_value_type_cell_num(ext_ret_types[i]);
  2598. }
  2599. ret = invoke_native_internal(exec_env, func_ptr, func_type, signature,
  2600. attachment, argv1, argc, argv);
  2601. if (!ret) {
  2602. if (argv1 != argv1_buf)
  2603. wasm_runtime_free(argv1);
  2604. goto fail;
  2605. }
  2606. /* Get extra result values */
  2607. switch (func_type->types[func_type->param_count]) {
  2608. case VALUE_TYPE_I32:
  2609. case VALUE_TYPE_F32:
  2610. #if WASM_ENABLE_REF_TYPES != 0
  2611. case VALUE_TYPE_FUNCREF:
  2612. case VALUE_TYPE_EXTERNREF:
  2613. #endif
  2614. argv_ret++;
  2615. break;
  2616. case VALUE_TYPE_I64:
  2617. case VALUE_TYPE_F64:
  2618. argv_ret += 2;
  2619. break;
  2620. #if WASM_ENABLE_SIMD != 0
  2621. case VALUE_TYPE_V128:
  2622. argv_ret += 4;
  2623. break;
  2624. #endif
  2625. default:
  2626. bh_assert(0);
  2627. break;
  2628. }
  2629. ext_rets =
  2630. argv1 + argc + sizeof(void *) / sizeof(uint32) * ext_ret_count;
  2631. bh_memcpy_s(argv_ret, sizeof(uint32) * cell_num, ext_rets,
  2632. sizeof(uint32) * cell_num);
  2633. if (argv1 != argv1_buf)
  2634. wasm_runtime_free(argv1);
  2635. return true;
  2636. }
  2637. else {
  2638. ret = invoke_native_internal(exec_env, func_ptr, func_type, signature,
  2639. attachment, argv, argc, argv);
  2640. if (!ret)
  2641. goto fail;
  2642. return true;
  2643. }
  2644. fail:
  2645. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2646. wasm_runtime_access_exce_check_guard_page();
  2647. #endif
  2648. return false;
  2649. }
  2650. bool
  2651. aot_check_app_addr_and_convert(AOTModuleInstance *module_inst, bool is_str,
  2652. uint64 app_buf_addr, uint64 app_buf_size,
  2653. void **p_native_addr)
  2654. {
  2655. bool ret;
  2656. ret = wasm_check_app_addr_and_convert(module_inst, is_str, app_buf_addr,
  2657. app_buf_size, p_native_addr);
  2658. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2659. if (!ret)
  2660. wasm_runtime_access_exce_check_guard_page();
  2661. #endif
  2662. return ret;
  2663. }
  2664. void *
  2665. aot_memmove(void *dest, const void *src, size_t n)
  2666. {
  2667. return memmove(dest, src, n);
  2668. }
  2669. void *
  2670. aot_memset(void *s, int c, size_t n)
  2671. {
  2672. return memset(s, c, n);
  2673. }
  2674. double
  2675. aot_sqrt(double x)
  2676. {
  2677. return sqrt(x);
  2678. }
  2679. float
  2680. aot_sqrtf(float x)
  2681. {
  2682. return sqrtf(x);
  2683. }
  2684. #if WASM_ENABLE_BULK_MEMORY != 0
  2685. bool
  2686. aot_memory_init(AOTModuleInstance *module_inst, uint32 seg_index, uint32 offset,
  2687. uint32 len, size_t dst)
  2688. {
  2689. AOTMemoryInstance *memory_inst = aot_get_default_memory(module_inst);
  2690. AOTModule *aot_module;
  2691. uint8 *data;
  2692. uint8 *maddr;
  2693. uint64 seg_len;
  2694. if (bh_bitmap_get_bit(
  2695. ((AOTModuleInstanceExtra *)module_inst->e)->common.data_dropped,
  2696. seg_index)) {
  2697. seg_len = 0;
  2698. data = NULL;
  2699. }
  2700. else {
  2701. aot_module = (AOTModule *)module_inst->module;
  2702. seg_len = aot_module->mem_init_data_list[seg_index]->byte_count;
  2703. data = aot_module->mem_init_data_list[seg_index]->bytes;
  2704. }
  2705. if (!wasm_runtime_validate_app_addr((WASMModuleInstanceCommon *)module_inst,
  2706. (uint64)dst, (uint64)len))
  2707. return false;
  2708. if ((uint64)offset + (uint64)len > seg_len) {
  2709. aot_set_exception(module_inst, "out of bounds memory access");
  2710. return false;
  2711. }
  2712. maddr = wasm_runtime_addr_app_to_native(
  2713. (WASMModuleInstanceCommon *)module_inst, (uint64)dst);
  2714. SHARED_MEMORY_LOCK(memory_inst);
  2715. bh_memcpy_s(maddr, CLAMP_U64_TO_U32(memory_inst->memory_data_size - dst),
  2716. data + offset, len);
  2717. SHARED_MEMORY_UNLOCK(memory_inst);
  2718. return true;
  2719. }
  2720. bool
  2721. aot_data_drop(AOTModuleInstance *module_inst, uint32 seg_index)
  2722. {
  2723. bh_bitmap_set_bit(
  2724. ((AOTModuleInstanceExtra *)module_inst->e)->common.data_dropped,
  2725. seg_index);
  2726. /* Currently we can't free the dropped data segment
  2727. as the mem_init_data_count is a continuous array */
  2728. return true;
  2729. }
  2730. #endif /* WASM_ENABLE_BULK_MEMORY */
  2731. #if WASM_ENABLE_THREAD_MGR != 0
  2732. bool
  2733. aot_set_aux_stack(WASMExecEnv *exec_env, uint64 start_offset, uint32 size)
  2734. {
  2735. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  2736. AOTModule *module = (AOTModule *)module_inst->module;
  2737. uint32 stack_top_idx = module->aux_stack_top_global_index;
  2738. uint64 data_end = module->aux_data_end;
  2739. uint64 stack_bottom = module->aux_stack_bottom;
  2740. bool is_stack_before_data = stack_bottom < data_end ? true : false;
  2741. /* Check the aux stack space, currently we don't allocate space in heap */
  2742. if ((is_stack_before_data && (size > start_offset))
  2743. || ((!is_stack_before_data) && (start_offset - data_end < size)))
  2744. return false;
  2745. if (stack_top_idx != (uint32)-1) {
  2746. /* The aux stack top is a wasm global,
  2747. set the initial value for the global */
  2748. uint32 global_offset = module->globals[stack_top_idx].data_offset;
  2749. uint8 *global_addr = module_inst->global_data + global_offset;
  2750. /* TODO: Memory64 the type i32/i64 depends on memory idx type*/
  2751. *(int32 *)global_addr = (uint32)start_offset;
  2752. /* The aux stack boundary is a constant value,
  2753. set the value to exec_env */
  2754. exec_env->aux_stack_boundary = (uintptr_t)start_offset - size;
  2755. exec_env->aux_stack_bottom = (uintptr_t)start_offset;
  2756. return true;
  2757. }
  2758. return false;
  2759. }
  2760. bool
  2761. aot_get_aux_stack(WASMExecEnv *exec_env, uint64 *start_offset, uint32 *size)
  2762. {
  2763. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  2764. AOTModule *module = (AOTModule *)module_inst->module;
  2765. /* The aux stack information is resolved in loader
  2766. and store in module */
  2767. uint64 stack_bottom = module->aux_stack_bottom;
  2768. uint32 total_aux_stack_size = module->aux_stack_size;
  2769. if (stack_bottom != 0 && total_aux_stack_size != 0) {
  2770. if (start_offset)
  2771. *start_offset = stack_bottom;
  2772. if (size)
  2773. *size = total_aux_stack_size;
  2774. return true;
  2775. }
  2776. return false;
  2777. }
  2778. #endif
  2779. #if (WASM_ENABLE_MEMORY_PROFILING != 0) || (WASM_ENABLE_MEMORY_TRACING != 0)
  2780. static void
  2781. const_string_node_size_cb(void *key, void *value, void *p_const_string_size)
  2782. {
  2783. uint32 const_string_size = 0;
  2784. const_string_size += bh_hash_map_get_elem_struct_size();
  2785. const_string_size += strlen((const char *)value) + 1;
  2786. *(uint32 *)p_const_string_size += const_string_size;
  2787. }
  2788. void
  2789. aot_get_module_mem_consumption(const AOTModule *module,
  2790. WASMModuleMemConsumption *mem_conspn)
  2791. {
  2792. uint32 i, size;
  2793. memset(mem_conspn, 0, sizeof(*mem_conspn));
  2794. mem_conspn->module_struct_size = sizeof(AOTModule);
  2795. mem_conspn->types_size = sizeof(AOTFuncType *) * module->type_count;
  2796. for (i = 0; i < module->type_count; i++) {
  2797. AOTFuncType *type = (AOTFuncType *)module->types[i];
  2798. size = offsetof(AOTFuncType, types)
  2799. + sizeof(uint8) * (type->param_count + type->result_count);
  2800. mem_conspn->types_size += size;
  2801. }
  2802. mem_conspn->imports_size =
  2803. sizeof(AOTImportMemory) * module->import_memory_count
  2804. + sizeof(AOTImportTable) * module->import_table_count
  2805. + sizeof(AOTImportGlobal) * module->import_global_count
  2806. + sizeof(AOTImportFunc) * module->import_func_count;
  2807. /* func_ptrs and func_type_indexes */
  2808. mem_conspn->functions_size =
  2809. (sizeof(void *) + sizeof(uint32)) * module->func_count;
  2810. mem_conspn->tables_size = sizeof(AOTTable) * module->table_count;
  2811. mem_conspn->memories_size = sizeof(AOTMemory) * module->memory_count;
  2812. mem_conspn->globals_size = sizeof(AOTGlobal) * module->global_count;
  2813. mem_conspn->exports_size = sizeof(AOTExport) * module->export_count;
  2814. mem_conspn->table_segs_size =
  2815. sizeof(AOTTableInitData *) * module->table_init_data_count;
  2816. for (i = 0; i < module->table_init_data_count; i++) {
  2817. AOTTableInitData *init_data = module->table_init_data_list[i];
  2818. size = offsetof(AOTTableInitData, init_values)
  2819. + sizeof(InitializerExpression) * init_data->value_count;
  2820. mem_conspn->table_segs_size += size;
  2821. }
  2822. mem_conspn->data_segs_size =
  2823. sizeof(AOTMemInitData *) * module->mem_init_data_count;
  2824. for (i = 0; i < module->mem_init_data_count; i++) {
  2825. mem_conspn->data_segs_size += sizeof(AOTMemInitData);
  2826. }
  2827. if (module->const_str_set) {
  2828. uint32 const_string_size = 0;
  2829. mem_conspn->const_strs_size =
  2830. bh_hash_map_get_struct_size(module->const_str_set);
  2831. bh_hash_map_traverse(module->const_str_set, const_string_node_size_cb,
  2832. (void *)&const_string_size);
  2833. mem_conspn->const_strs_size += const_string_size;
  2834. }
  2835. /* code size + literal size + object data section size */
  2836. mem_conspn->aot_code_size =
  2837. module->code_size + module->literal_size
  2838. + sizeof(AOTObjectDataSection) * module->data_section_count;
  2839. for (i = 0; i < module->data_section_count; i++) {
  2840. AOTObjectDataSection *obj_data = module->data_sections + i;
  2841. mem_conspn->aot_code_size += sizeof(uint8) * obj_data->size;
  2842. }
  2843. mem_conspn->total_size += mem_conspn->module_struct_size;
  2844. mem_conspn->total_size += mem_conspn->types_size;
  2845. mem_conspn->total_size += mem_conspn->imports_size;
  2846. mem_conspn->total_size += mem_conspn->functions_size;
  2847. mem_conspn->total_size += mem_conspn->tables_size;
  2848. mem_conspn->total_size += mem_conspn->memories_size;
  2849. mem_conspn->total_size += mem_conspn->globals_size;
  2850. mem_conspn->total_size += mem_conspn->exports_size;
  2851. mem_conspn->total_size += mem_conspn->table_segs_size;
  2852. mem_conspn->total_size += mem_conspn->data_segs_size;
  2853. mem_conspn->total_size += mem_conspn->const_strs_size;
  2854. mem_conspn->total_size += mem_conspn->aot_code_size;
  2855. }
  2856. void
  2857. aot_get_module_inst_mem_consumption(const AOTModuleInstance *module_inst,
  2858. WASMModuleInstMemConsumption *mem_conspn)
  2859. {
  2860. AOTTableInstance *tbl_inst;
  2861. uint32 i;
  2862. memset(mem_conspn, 0, sizeof(*mem_conspn));
  2863. mem_conspn->module_inst_struct_size = sizeof(AOTModuleInstance);
  2864. mem_conspn->memories_size =
  2865. sizeof(void *) * module_inst->memory_count
  2866. + sizeof(AOTMemoryInstance) * module_inst->memory_count;
  2867. for (i = 0; i < module_inst->memory_count; i++) {
  2868. AOTMemoryInstance *mem_inst = module_inst->memories[i];
  2869. mem_conspn->memories_size +=
  2870. mem_inst->num_bytes_per_page * mem_inst->cur_page_count;
  2871. mem_conspn->app_heap_size =
  2872. mem_inst->heap_data_end - mem_inst->heap_data;
  2873. /* size of app heap structure */
  2874. mem_conspn->memories_size += mem_allocator_get_heap_struct_size();
  2875. }
  2876. mem_conspn->tables_size +=
  2877. sizeof(AOTTableInstance *) * module_inst->table_count;
  2878. for (i = 0; i < module_inst->table_count; i++) {
  2879. tbl_inst = module_inst->tables[i];
  2880. mem_conspn->tables_size += offsetof(AOTTableInstance, elems);
  2881. mem_conspn->tables_size += sizeof(uint32) * tbl_inst->max_size;
  2882. }
  2883. /* func_ptrs and func_type_indexes */
  2884. mem_conspn->functions_size =
  2885. (sizeof(void *) + sizeof(uint32))
  2886. * (((AOTModule *)module_inst->module)->import_func_count
  2887. + ((AOTModule *)module_inst->module)->func_count);
  2888. mem_conspn->globals_size = module_inst->global_data_size;
  2889. mem_conspn->exports_size =
  2890. sizeof(AOTFunctionInstance) * (uint64)module_inst->export_func_count;
  2891. mem_conspn->total_size += mem_conspn->module_inst_struct_size;
  2892. mem_conspn->total_size += mem_conspn->memories_size;
  2893. mem_conspn->total_size += mem_conspn->functions_size;
  2894. mem_conspn->total_size += mem_conspn->tables_size;
  2895. mem_conspn->total_size += mem_conspn->globals_size;
  2896. mem_conspn->total_size += mem_conspn->exports_size;
  2897. }
  2898. #endif /* end of (WASM_ENABLE_MEMORY_PROFILING != 0) \
  2899. || (WASM_ENABLE_MEMORY_TRACING != 0) */
  2900. #if WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0
  2901. void
  2902. aot_drop_table_seg(AOTModuleInstance *module_inst, uint32 tbl_seg_idx)
  2903. {
  2904. bh_bitmap_set_bit(
  2905. ((AOTModuleInstanceExtra *)module_inst->e)->common.elem_dropped,
  2906. tbl_seg_idx);
  2907. }
  2908. void
  2909. aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
  2910. uint32 tbl_seg_idx, uint32 length, uint32 src_offset,
  2911. uint32 dst_offset)
  2912. {
  2913. AOTTableInstance *tbl_inst;
  2914. AOTTableInitData *tbl_seg;
  2915. const AOTModule *module = (AOTModule *)module_inst->module;
  2916. table_elem_type_t *table_elems;
  2917. InitializerExpression *tbl_seg_init_values = NULL, *init_values;
  2918. uint32 i, tbl_seg_len = 0;
  2919. #if WASM_ENABLE_GC != 0
  2920. void *func_obj;
  2921. #endif
  2922. tbl_inst = module_inst->tables[tbl_idx];
  2923. bh_assert(tbl_inst);
  2924. tbl_seg = module->table_init_data_list[tbl_seg_idx];
  2925. bh_assert(tbl_seg);
  2926. if (!bh_bitmap_get_bit(
  2927. ((AOTModuleInstanceExtra *)module_inst->e)->common.elem_dropped,
  2928. tbl_seg_idx)) {
  2929. /* table segment isn't dropped */
  2930. tbl_seg_init_values = tbl_seg->init_values;
  2931. tbl_seg_len = tbl_seg->value_count;
  2932. }
  2933. if (offset_len_out_of_bounds(src_offset, length, tbl_seg_len)
  2934. || offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
  2935. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2936. return;
  2937. }
  2938. if (!length) {
  2939. return;
  2940. }
  2941. table_elems = tbl_inst->elems + dst_offset;
  2942. init_values = tbl_seg_init_values + src_offset;
  2943. for (i = 0; i < length; i++) {
  2944. #if WASM_ENABLE_GC != 0
  2945. /* UINT32_MAX indicates that it is a null ref */
  2946. if (init_values[i].u.ref_index != UINT32_MAX) {
  2947. if (!(func_obj = aot_create_func_obj(module_inst,
  2948. init_values[i].u.ref_index,
  2949. true, NULL, 0))) {
  2950. aot_set_exception_with_id(module_inst, EXCE_NULL_FUNC_OBJ);
  2951. return;
  2952. }
  2953. table_elems[i] = func_obj;
  2954. }
  2955. else {
  2956. table_elems[i] = NULL_REF;
  2957. }
  2958. #else
  2959. table_elems[i] = init_values[i].u.ref_index;
  2960. #endif
  2961. }
  2962. }
  2963. void
  2964. aot_table_copy(AOTModuleInstance *module_inst, uint32 src_tbl_idx,
  2965. uint32 dst_tbl_idx, uint32 length, uint32 src_offset,
  2966. uint32 dst_offset)
  2967. {
  2968. AOTTableInstance *src_tbl_inst, *dst_tbl_inst;
  2969. src_tbl_inst = module_inst->tables[src_tbl_idx];
  2970. bh_assert(src_tbl_inst);
  2971. dst_tbl_inst = module_inst->tables[dst_tbl_idx];
  2972. bh_assert(dst_tbl_inst);
  2973. if (offset_len_out_of_bounds(dst_offset, length, dst_tbl_inst->cur_size)
  2974. || offset_len_out_of_bounds(src_offset, length,
  2975. src_tbl_inst->cur_size)) {
  2976. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2977. return;
  2978. }
  2979. /* if src_offset >= dst_offset, copy from front to back */
  2980. /* if src_offset < dst_offset, copy from back to front */
  2981. /* merge all together */
  2982. bh_memmove_s((uint8 *)dst_tbl_inst + offsetof(AOTTableInstance, elems)
  2983. + dst_offset * sizeof(table_elem_type_t),
  2984. (dst_tbl_inst->cur_size - dst_offset)
  2985. * sizeof(table_elem_type_t),
  2986. (uint8 *)src_tbl_inst + offsetof(AOTTableInstance, elems)
  2987. + src_offset * sizeof(table_elem_type_t),
  2988. length * sizeof(table_elem_type_t));
  2989. }
  2990. void
  2991. aot_table_fill(AOTModuleInstance *module_inst, uint32 tbl_idx, uint32 length,
  2992. table_elem_type_t val, uint32 data_offset)
  2993. {
  2994. AOTTableInstance *tbl_inst;
  2995. tbl_inst = module_inst->tables[tbl_idx];
  2996. bh_assert(tbl_inst);
  2997. if (offset_len_out_of_bounds(data_offset, length, tbl_inst->cur_size)) {
  2998. aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
  2999. return;
  3000. }
  3001. for (; length != 0; data_offset++, length--) {
  3002. tbl_inst->elems[data_offset] = val;
  3003. }
  3004. }
  3005. uint32
  3006. aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx, uint32 inc_size,
  3007. table_elem_type_t init_val)
  3008. {
  3009. AOTTableInstance *tbl_inst;
  3010. uint32 i, orig_size, total_size;
  3011. tbl_inst = module_inst->tables[tbl_idx];
  3012. if (!tbl_inst) {
  3013. return (uint32)-1;
  3014. }
  3015. orig_size = tbl_inst->cur_size;
  3016. if (!inc_size) {
  3017. return orig_size;
  3018. }
  3019. if (tbl_inst->cur_size > UINT32_MAX - inc_size) {
  3020. #if WASM_ENABLE_SPEC_TEST == 0
  3021. LOG_WARNING("table grow (%" PRIu32 "-> %" PRIu32
  3022. ") failed because of integer overflow",
  3023. tbl_inst->cur_size, inc_size);
  3024. #endif
  3025. return (uint32)-1;
  3026. }
  3027. total_size = tbl_inst->cur_size + inc_size;
  3028. if (total_size > tbl_inst->max_size) {
  3029. #if WASM_ENABLE_SPEC_TEST == 0
  3030. LOG_WARNING("table grow (%" PRIu32 "-> %" PRIu32
  3031. ") failed because of over max size",
  3032. tbl_inst->cur_size, inc_size);
  3033. #endif
  3034. return (uint32)-1;
  3035. }
  3036. /* fill in */
  3037. for (i = 0; i < inc_size; ++i) {
  3038. tbl_inst->elems[tbl_inst->cur_size + i] = init_val;
  3039. }
  3040. tbl_inst->cur_size = total_size;
  3041. return orig_size;
  3042. }
  3043. #endif /* WASM_ENABLE_REF_TYPES != 0 || WASM_ENABLE_GC != 0 */
  3044. #if WASM_ENABLE_AOT_STACK_FRAME != 0
  3045. #if WASM_ENABLE_DUMP_CALL_STACK != 0 || WASM_ENABLE_PERF_PROFILING != 0
  3046. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  3047. static const char *
  3048. lookup_func_name(const char **func_names, uint32 *func_indexes,
  3049. uint32 func_index_count, uint32 func_index)
  3050. {
  3051. int64 low = 0, mid;
  3052. int64 high = func_index_count - 1;
  3053. if (!func_names || !func_indexes || func_index_count == 0)
  3054. return NULL;
  3055. while (low <= high) {
  3056. mid = (low + high) / 2;
  3057. if (func_index == func_indexes[mid]) {
  3058. return func_names[mid];
  3059. }
  3060. else if (func_index < func_indexes[mid])
  3061. high = mid - 1;
  3062. else
  3063. low = mid + 1;
  3064. }
  3065. return NULL;
  3066. }
  3067. #endif /* WASM_ENABLE_CUSTOM_NAME_SECTION != 0 */
  3068. static const char *
  3069. get_func_name_from_index(const AOTModuleInstance *module_inst,
  3070. uint32 func_index)
  3071. {
  3072. const char *func_name = NULL;
  3073. AOTModule *module = (AOTModule *)module_inst->module;
  3074. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  3075. if ((func_name =
  3076. lookup_func_name(module->aux_func_names, module->aux_func_indexes,
  3077. module->aux_func_name_count, func_index))) {
  3078. return func_name;
  3079. }
  3080. #endif
  3081. if (func_index < module->import_func_count) {
  3082. func_name = module->import_funcs[func_index].func_name;
  3083. }
  3084. else {
  3085. uint32 i;
  3086. for (i = 0; i < module->export_count; i++) {
  3087. AOTExport export = module->exports[i];
  3088. if (export.index == func_index && export.kind == EXPORT_KIND_FUNC) {
  3089. func_name = export.name;
  3090. break;
  3091. }
  3092. }
  3093. }
  3094. return func_name;
  3095. }
  3096. #endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 || \
  3097. WASM_ENABLE_PERF_PROFILING != 0 */
  3098. #if WASM_ENABLE_GC == 0
  3099. bool
  3100. aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
  3101. {
  3102. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  3103. #if WASM_ENABLE_PERF_PROFILING != 0
  3104. AOTFuncPerfProfInfo *func_perf_prof =
  3105. module_inst->func_perf_profilings + func_index;
  3106. #endif
  3107. AOTFrame *cur_frame, *frame;
  3108. uint32 size = (uint32)offsetof(AOTFrame, lp);
  3109. cur_frame = (AOTFrame *)exec_env->cur_frame;
  3110. if (!cur_frame)
  3111. frame = (AOTFrame *)exec_env->wasm_stack.bottom;
  3112. else
  3113. frame = (AOTFrame *)((uint8 *)cur_frame + size);
  3114. if ((uint8 *)frame + size > exec_env->wasm_stack.top_boundary) {
  3115. aot_set_exception(module_inst, "wasm operand stack overflow");
  3116. return false;
  3117. }
  3118. frame->func_index = func_index;
  3119. /* No need to initialize ip, it will be committed in jitted code
  3120. when needed */
  3121. /* frame->ip = NULL; */
  3122. frame->prev_frame = (AOTFrame *)exec_env->cur_frame;
  3123. #if WASM_ENABLE_PERF_PROFILING != 0
  3124. frame->time_started = (uintptr_t)os_time_thread_cputime_us();
  3125. frame->func_perf_prof_info = func_perf_prof;
  3126. #endif
  3127. #if WASM_ENABLE_MEMORY_PROFILING != 0
  3128. {
  3129. uint32 wasm_stack_used =
  3130. (uint8 *)frame + size - exec_env->wasm_stack.bottom;
  3131. if (wasm_stack_used > exec_env->max_wasm_stack_used)
  3132. exec_env->max_wasm_stack_used = wasm_stack_used;
  3133. }
  3134. #endif
  3135. exec_env->cur_frame = (struct WASMInterpFrame *)frame;
  3136. return true;
  3137. }
  3138. static inline void
  3139. aot_free_frame_internal(WASMExecEnv *exec_env)
  3140. {
  3141. AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame;
  3142. AOTFrame *prev_frame = cur_frame->prev_frame;
  3143. #if WASM_ENABLE_PERF_PROFILING != 0
  3144. uint64 time_elapsed =
  3145. (uintptr_t)os_time_thread_cputime_us() - cur_frame->time_started;
  3146. cur_frame->func_perf_prof_info->total_exec_time += time_elapsed;
  3147. cur_frame->func_perf_prof_info->total_exec_cnt++;
  3148. /* parent function */
  3149. if (prev_frame)
  3150. prev_frame->func_perf_prof_info->children_exec_time += time_elapsed;
  3151. #endif
  3152. exec_env->cur_frame = (struct WASMInterpFrame *)prev_frame;
  3153. }
  3154. void
  3155. aot_free_frame(WASMExecEnv *exec_env)
  3156. {
  3157. aot_free_frame_internal(exec_env);
  3158. }
  3159. #else /* else of WASM_ENABLE_GC == 0 */
  3160. bool
  3161. aot_alloc_frame(WASMExecEnv *exec_env, uint32 func_index)
  3162. {
  3163. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  3164. AOTModule *module = (AOTModule *)module_inst->module;
  3165. #if WASM_ENABLE_PERF_PROFILING != 0
  3166. AOTFuncPerfProfInfo *func_perf_prof =
  3167. module_inst->func_perf_profilings + func_index;
  3168. #endif
  3169. AOTFrame *frame;
  3170. uint32 max_local_cell_num, max_stack_cell_num, all_cell_num;
  3171. uint32 aot_func_idx, frame_size;
  3172. if (func_index >= module->import_func_count) {
  3173. aot_func_idx = func_index - module->import_func_count;
  3174. max_local_cell_num = module->max_local_cell_nums[aot_func_idx];
  3175. max_stack_cell_num = module->max_stack_cell_nums[aot_func_idx];
  3176. }
  3177. else {
  3178. AOTFuncType *func_type = module->import_funcs[func_index].func_type;
  3179. max_local_cell_num =
  3180. func_type->param_cell_num > 2 ? func_type->param_cell_num : 2;
  3181. max_stack_cell_num = 0;
  3182. }
  3183. all_cell_num = max_local_cell_num + max_stack_cell_num;
  3184. #if WASM_ENABLE_GC == 0
  3185. frame_size = (uint32)offsetof(AOTFrame, lp) + all_cell_num * 4;
  3186. #else
  3187. frame_size =
  3188. (uint32)offsetof(AOTFrame, lp) + align_uint(all_cell_num * 5, 4);
  3189. #endif
  3190. frame = wasm_exec_env_alloc_wasm_frame(exec_env, frame_size);
  3191. if (!frame) {
  3192. aot_set_exception(module_inst, "wasm operand stack overflow");
  3193. return false;
  3194. }
  3195. #if WASM_ENABLE_PERF_PROFILING != 0
  3196. frame->time_started = (uintptr_t)os_time_thread_cputime_us();
  3197. frame->func_perf_prof_info = func_perf_prof;
  3198. #endif
  3199. #if WASM_ENABLE_GC != 0
  3200. frame->sp = frame->lp + max_local_cell_num;
  3201. frame->frame_ref = (uint8 *)(frame->sp + max_stack_cell_num);
  3202. #endif
  3203. frame->prev_frame = (AOTFrame *)exec_env->cur_frame;
  3204. exec_env->cur_frame = (struct WASMInterpFrame *)frame;
  3205. frame->func_index = func_index;
  3206. return true;
  3207. }
  3208. static inline void
  3209. aot_free_frame_internal(WASMExecEnv *exec_env)
  3210. {
  3211. AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame;
  3212. AOTFrame *prev_frame = cur_frame->prev_frame;
  3213. #if WASM_ENABLE_PERF_PROFILING != 0
  3214. uint64 time_elapsed =
  3215. (uintptr_t)os_time_thread_cputime_us() - cur_frame->time_started;
  3216. cur_frame->func_perf_prof_info->total_exec_time += time_elapsed;
  3217. cur_frame->func_perf_prof_info->total_exec_cnt++;
  3218. /* parent function */
  3219. if (prev_frame)
  3220. prev_frame->func_perf_prof_info->children_exec_time += time_elapsed;
  3221. #endif
  3222. wasm_exec_env_free_wasm_frame(exec_env, cur_frame);
  3223. exec_env->cur_frame = (struct WASMInterpFrame *)prev_frame;
  3224. }
  3225. void
  3226. aot_free_frame(WASMExecEnv *exec_env)
  3227. {
  3228. aot_free_frame_internal(exec_env);
  3229. }
  3230. #endif /* end of WASM_ENABLE_GC == 0 */
  3231. void
  3232. aot_frame_update_profile_info(WASMExecEnv *exec_env, bool alloc_frame)
  3233. {
  3234. #if WASM_ENABLE_PERF_PROFILING != 0
  3235. AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame;
  3236. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  3237. AOTFuncPerfProfInfo *func_perf_prof =
  3238. module_inst->func_perf_profilings + cur_frame->func_index;
  3239. if (alloc_frame) {
  3240. cur_frame->time_started = (uintptr_t)os_time_thread_cputime_us();
  3241. cur_frame->func_perf_prof_info = func_perf_prof;
  3242. }
  3243. else {
  3244. AOTFrame *prev_frame = cur_frame->prev_frame;
  3245. uint64 time_elapsed =
  3246. (uintptr_t)os_time_thread_cputime_us() - cur_frame->time_started;
  3247. cur_frame->func_perf_prof_info->total_exec_time += time_elapsed;
  3248. cur_frame->func_perf_prof_info->total_exec_cnt++;
  3249. /* parent function */
  3250. if (prev_frame)
  3251. prev_frame->func_perf_prof_info->children_exec_time += time_elapsed;
  3252. }
  3253. #endif
  3254. #if WASM_ENABLE_MEMORY_PROFILING != 0
  3255. if (alloc_frame) {
  3256. #if WASM_ENABLE_GC == 0
  3257. uint32 wasm_stack_used = (uint8 *)exec_env->cur_frame
  3258. + (uint32)offsetof(AOTFrame, lp)
  3259. - exec_env->wasm_stack.bottom;
  3260. #else
  3261. uint32 wasm_stack_used =
  3262. exec_env->wasm_stack.top - exec_env->wasm_stack.bottom;
  3263. #endif
  3264. if (wasm_stack_used > exec_env->max_wasm_stack_used)
  3265. exec_env->max_wasm_stack_used = wasm_stack_used;
  3266. }
  3267. #endif
  3268. }
  3269. #endif /* end of WASM_ENABLE_AOT_STACK_FRAME != 0 */
  3270. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  3271. bool
  3272. aot_create_call_stack(struct WASMExecEnv *exec_env)
  3273. {
  3274. AOTFrame *cur_frame = (AOTFrame *)exec_env->cur_frame,
  3275. *first_frame = cur_frame;
  3276. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  3277. AOTModule *module = (AOTModule *)module_inst->module;
  3278. uint32 n = 0;
  3279. while (cur_frame) {
  3280. cur_frame = cur_frame->prev_frame;
  3281. n++;
  3282. }
  3283. /* release previous stack frames and create new ones */
  3284. destroy_c_api_frames(module_inst->frames);
  3285. if (!bh_vector_init(module_inst->frames, n, sizeof(WASMCApiFrame), false)) {
  3286. return false;
  3287. }
  3288. cur_frame = first_frame;
  3289. while (cur_frame) {
  3290. WASMCApiFrame frame = { 0 };
  3291. uint32 max_local_cell_num, max_stack_cell_num;
  3292. uint32 all_cell_num, lp_size;
  3293. frame.instance = module_inst;
  3294. frame.module_offset = 0;
  3295. frame.func_index = (uint32)cur_frame->func_index;
  3296. frame.func_offset = (uint32)cur_frame->ip_offset;
  3297. frame.func_name_wp = get_func_name_from_index(
  3298. module_inst, (uint32)cur_frame->func_index);
  3299. if (cur_frame->func_index >= module->import_func_count) {
  3300. uint32 aot_func_idx =
  3301. (uint32)(cur_frame->func_index - module->import_func_count);
  3302. max_local_cell_num = module->max_local_cell_nums[aot_func_idx];
  3303. max_stack_cell_num = module->max_stack_cell_nums[aot_func_idx];
  3304. }
  3305. else {
  3306. AOTFuncType *func_type =
  3307. module->import_funcs[cur_frame->func_index].func_type;
  3308. max_local_cell_num =
  3309. func_type->param_cell_num > 2 ? func_type->param_cell_num : 2;
  3310. max_stack_cell_num = 0;
  3311. }
  3312. all_cell_num = max_local_cell_num + max_stack_cell_num;
  3313. #if WASM_ENABLE_GC == 0
  3314. lp_size = all_cell_num * 4;
  3315. #else
  3316. lp_size = align_uint(all_cell_num * 5, 4);
  3317. #endif
  3318. if (lp_size > 0) {
  3319. if (!(frame.lp = wasm_runtime_malloc(lp_size))) {
  3320. destroy_c_api_frames(module_inst->frames);
  3321. return false;
  3322. }
  3323. bh_memcpy_s(frame.lp, lp_size, cur_frame->lp, lp_size);
  3324. #if WASM_ENABLE_GC != 0
  3325. uint32 local_ref_flags_cell_num =
  3326. module->func_local_ref_flags[frame.func_index]
  3327. .local_ref_flag_cell_num;
  3328. uint8 *local_ref_flags =
  3329. module->func_local_ref_flags[frame.func_index].local_ref_flags;
  3330. frame.sp = frame.lp + (cur_frame->sp - cur_frame->lp);
  3331. frame.frame_ref = (uint8 *)frame.lp
  3332. + (cur_frame->frame_ref - (uint8 *)cur_frame->lp);
  3333. /* copy local ref flags from AOT module */
  3334. bh_memcpy_s(frame.frame_ref, local_ref_flags_cell_num,
  3335. local_ref_flags, lp_size);
  3336. #endif
  3337. }
  3338. if (!bh_vector_append(module_inst->frames, &frame)) {
  3339. if (frame.lp)
  3340. wasm_runtime_free(frame.lp);
  3341. destroy_c_api_frames(module_inst->frames);
  3342. return false;
  3343. }
  3344. cur_frame = cur_frame->prev_frame;
  3345. }
  3346. return true;
  3347. }
  3348. #define PRINT_OR_DUMP() \
  3349. do { \
  3350. total_len += \
  3351. wasm_runtime_dump_line_buf_impl(line_buf, print, &buf, &len); \
  3352. if ((!print) && buf && (len == 0)) { \
  3353. exception_unlock(module_inst); \
  3354. return total_len; \
  3355. } \
  3356. } while (0)
  3357. uint32
  3358. aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len)
  3359. {
  3360. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  3361. uint32 n = 0, total_len = 0, total_frames;
  3362. /* reserve 256 bytes for line buffer, any line longer than 256 bytes
  3363. * will be truncated */
  3364. char line_buf[256];
  3365. if (!module_inst->frames) {
  3366. return 0;
  3367. }
  3368. total_frames = (uint32)bh_vector_size(module_inst->frames);
  3369. if (total_frames == 0) {
  3370. return 0;
  3371. }
  3372. exception_lock(module_inst);
  3373. snprintf(line_buf, sizeof(line_buf), "\n");
  3374. PRINT_OR_DUMP();
  3375. while (n < total_frames) {
  3376. WASMCApiFrame frame = { 0 };
  3377. uint32 line_length, i;
  3378. if (!bh_vector_get(module_inst->frames, n, &frame)) {
  3379. exception_unlock(module_inst);
  3380. return 0;
  3381. }
  3382. /* function name not exported, print number instead */
  3383. if (frame.func_name_wp == NULL) {
  3384. line_length = snprintf(line_buf, sizeof(line_buf),
  3385. "#%02" PRIu32 ": 0x%04x - $f%" PRIu32 "\n",
  3386. n, frame.func_offset, frame.func_index);
  3387. }
  3388. else {
  3389. line_length = snprintf(line_buf, sizeof(line_buf),
  3390. "#%02" PRIu32 ": 0x%04x - %s\n", n,
  3391. frame.func_offset, frame.func_name_wp);
  3392. }
  3393. if (line_length >= sizeof(line_buf)) {
  3394. uint32 line_buffer_len = sizeof(line_buf);
  3395. /* If line too long, ensure the last character is '\n' */
  3396. for (i = line_buffer_len - 5; i < line_buffer_len - 2; i++) {
  3397. line_buf[i] = '.';
  3398. }
  3399. line_buf[line_buffer_len - 2] = '\n';
  3400. }
  3401. PRINT_OR_DUMP();
  3402. n++;
  3403. }
  3404. snprintf(line_buf, sizeof(line_buf), "\n");
  3405. PRINT_OR_DUMP();
  3406. exception_unlock(module_inst);
  3407. return total_len + 1;
  3408. }
  3409. #endif /* end of WASM_ENABLE_DUMP_CALL_STACK != 0 */
  3410. #if WASM_ENABLE_PERF_PROFILING != 0
  3411. void
  3412. aot_dump_perf_profiling(const AOTModuleInstance *module_inst)
  3413. {
  3414. AOTFuncPerfProfInfo *perf_prof =
  3415. (AOTFuncPerfProfInfo *)module_inst->func_perf_profilings;
  3416. AOTModule *module = (AOTModule *)module_inst->module;
  3417. uint32 total_func_count = module->import_func_count + module->func_count, i;
  3418. const char *func_name;
  3419. os_printf("Performance profiler data:\n");
  3420. for (i = 0; i < total_func_count; i++, perf_prof++) {
  3421. if (perf_prof->total_exec_cnt == 0)
  3422. continue;
  3423. func_name = get_func_name_from_index(module_inst, i);
  3424. if (func_name)
  3425. os_printf(
  3426. " func %s, execution time: %.3f ms, execution count: %" PRIu32
  3427. " times, children execution time: %.3f ms\n",
  3428. func_name, perf_prof->total_exec_time / 1000.0f,
  3429. perf_prof->total_exec_cnt,
  3430. perf_prof->children_exec_time / 1000.0f);
  3431. else
  3432. os_printf(" func %" PRIu32
  3433. ", execution time: %.3f ms, execution count: %" PRIu32
  3434. " times, children execution time: %.3f ms\n",
  3435. i, perf_prof->total_exec_time / 1000.0f,
  3436. perf_prof->total_exec_cnt,
  3437. perf_prof->children_exec_time / 1000.0f);
  3438. }
  3439. }
  3440. double
  3441. aot_summarize_wasm_execute_time(const AOTModuleInstance *inst)
  3442. {
  3443. double ret = 0;
  3444. AOTModule *module = (AOTModule *)inst->module;
  3445. uint32 total_func_count = module->import_func_count + module->func_count, i;
  3446. for (i = 0; i < total_func_count; i++) {
  3447. AOTFuncPerfProfInfo *perf_prof =
  3448. (AOTFuncPerfProfInfo *)inst->func_perf_profilings + i;
  3449. ret += (perf_prof->total_exec_time - perf_prof->children_exec_time)
  3450. / 1000.0f;
  3451. }
  3452. return ret;
  3453. }
  3454. double
  3455. aot_get_wasm_func_exec_time(const AOTModuleInstance *inst,
  3456. const char *func_name)
  3457. {
  3458. AOTModule *module = (AOTModule *)inst->module;
  3459. uint32 total_func_count = module->import_func_count + module->func_count, i;
  3460. for (i = 0; i < total_func_count; i++) {
  3461. const char *name_in_wasm = get_func_name_from_index(inst, i);
  3462. if (name_in_wasm && strcmp(func_name, name_in_wasm) == 0) {
  3463. AOTFuncPerfProfInfo *perf_prof =
  3464. (AOTFuncPerfProfInfo *)inst->func_perf_profilings + i;
  3465. return (perf_prof->total_exec_time - perf_prof->children_exec_time)
  3466. / 1000.0f;
  3467. }
  3468. }
  3469. return -1.0;
  3470. }
  3471. #endif /* end of WASM_ENABLE_PERF_PROFILING != 0 */
  3472. #if WASM_ENABLE_STATIC_PGO != 0
  3473. /* indirect call target */
  3474. #define IPVK_IndirectCallTarget 0
  3475. /* memory intrinsic functions size */
  3476. #define IPVK_MemOPSize 1
  3477. #define IPVK_First IPVK_IndirectCallTarget
  3478. #define IPVK_Last IPVK_MemOPSize
  3479. #define INSTR_PROF_DEFAULT_NUM_VAL_PER_SITE 24
  3480. #define INSTR_PROF_MAX_NUM_VAL_PER_SITE 255
  3481. static int hasNonDefaultValsPerSite = 0;
  3482. static uint32 VPMaxNumValsPerSite = INSTR_PROF_DEFAULT_NUM_VAL_PER_SITE;
  3483. static bool
  3484. cmpxchg_ptr(void **ptr, void *old_val, void *new_val)
  3485. {
  3486. #if defined(os_atomic_cmpxchg)
  3487. return os_atomic_cmpxchg(ptr, &old_val, new_val);
  3488. #else
  3489. /* TODO: add lock when thread-manager is enabled */
  3490. void *read = *ptr;
  3491. if (read == old_val) {
  3492. *ptr = new_val;
  3493. return true;
  3494. }
  3495. return false;
  3496. #endif
  3497. }
  3498. static int
  3499. allocateValueProfileCounters(LLVMProfileData *Data)
  3500. {
  3501. ValueProfNode **Mem;
  3502. uint64 NumVSites = 0, total_size;
  3503. uint32 VKI;
  3504. /* When dynamic allocation is enabled, allow tracking the max number of
  3505. values allowed. */
  3506. if (!hasNonDefaultValsPerSite)
  3507. VPMaxNumValsPerSite = INSTR_PROF_MAX_NUM_VAL_PER_SITE;
  3508. for (VKI = IPVK_First; VKI <= IPVK_Last; ++VKI)
  3509. NumVSites += Data->num_value_sites[VKI];
  3510. /* If NumVSites = 0, calloc is allowed to return a non-null pointer. */
  3511. bh_assert(NumVSites > 0 && "NumVSites can't be zero");
  3512. total_size = (uint64)sizeof(ValueProfNode *) * NumVSites;
  3513. if (total_size > UINT32_MAX
  3514. || !(Mem = (ValueProfNode **)wasm_runtime_malloc((uint32)total_size))) {
  3515. return 0;
  3516. }
  3517. memset(Mem, 0, (uint32)total_size);
  3518. if (!cmpxchg_ptr((void **)&Data->values, NULL, Mem)) {
  3519. wasm_runtime_free(Mem);
  3520. return 0;
  3521. }
  3522. return 1;
  3523. }
  3524. static ValueProfNode *
  3525. allocateOneNode(void)
  3526. {
  3527. ValueProfNode *Node;
  3528. Node = wasm_runtime_malloc((uint32)sizeof(ValueProfNode));
  3529. if (Node)
  3530. memset(Node, 0, sizeof(ValueProfNode));
  3531. return Node;
  3532. }
  3533. static void
  3534. instrumentTargetValueImpl(uint64 TargetValue, void *Data, uint32 CounterIndex,
  3535. uint64 CountValue)
  3536. {
  3537. ValueProfNode **ValueCounters;
  3538. ValueProfNode *PrevVNode = NULL, *MinCountVNode = NULL, *CurVNode;
  3539. LLVMProfileData *PData = (LLVMProfileData *)Data;
  3540. uint64 MinCount = UINT64_MAX;
  3541. uint8 VDataCount = 0;
  3542. bool success = false;
  3543. if (!PData)
  3544. return;
  3545. if (!CountValue)
  3546. return;
  3547. if (!PData->values) {
  3548. if (!allocateValueProfileCounters(PData))
  3549. return;
  3550. }
  3551. ValueCounters = (ValueProfNode **)PData->values;
  3552. CurVNode = ValueCounters[CounterIndex];
  3553. while (CurVNode) {
  3554. if (TargetValue == CurVNode->value) {
  3555. CurVNode->count += CountValue;
  3556. return;
  3557. }
  3558. if (CurVNode->count < MinCount) {
  3559. MinCount = CurVNode->count;
  3560. MinCountVNode = CurVNode;
  3561. }
  3562. PrevVNode = CurVNode;
  3563. CurVNode = CurVNode->next;
  3564. ++VDataCount;
  3565. }
  3566. if (VDataCount >= VPMaxNumValsPerSite) {
  3567. if (MinCountVNode->count <= CountValue) {
  3568. CurVNode = MinCountVNode;
  3569. CurVNode->value = TargetValue;
  3570. CurVNode->count = CountValue;
  3571. }
  3572. else
  3573. MinCountVNode->count -= CountValue;
  3574. return;
  3575. }
  3576. CurVNode = allocateOneNode();
  3577. if (!CurVNode)
  3578. return;
  3579. CurVNode->value = TargetValue;
  3580. CurVNode->count += CountValue;
  3581. if (!ValueCounters[CounterIndex]) {
  3582. success =
  3583. cmpxchg_ptr((void **)&ValueCounters[CounterIndex], NULL, CurVNode);
  3584. }
  3585. else if (PrevVNode && !PrevVNode->next) {
  3586. success = cmpxchg_ptr((void **)&PrevVNode->next, 0, CurVNode);
  3587. }
  3588. if (!success) {
  3589. wasm_runtime_free(CurVNode);
  3590. }
  3591. }
  3592. void
  3593. llvm_profile_instrument_target(uint64 target_value, void *data,
  3594. uint32 counter_idx)
  3595. {
  3596. instrumentTargetValueImpl(target_value, data, counter_idx, 1);
  3597. }
  3598. static inline uint32
  3599. popcount64(uint64 u)
  3600. {
  3601. uint32 ret = 0;
  3602. while (u) {
  3603. u = (u & (u - 1));
  3604. ret++;
  3605. }
  3606. return ret;
  3607. }
  3608. static inline uint32
  3609. clz64(uint64 type)
  3610. {
  3611. uint32 num = 0;
  3612. if (type == 0)
  3613. return 64;
  3614. while (!(type & 0x8000000000000000LL)) {
  3615. num++;
  3616. type <<= 1;
  3617. }
  3618. return num;
  3619. }
  3620. /* Map an (observed) memop size value to the representative value of its range.
  3621. For example, 5 -> 5, 22 -> 17, 99 -> 65, 256 -> 256, 1001 -> 513. */
  3622. static uint64
  3623. InstrProfGetRangeRepValue(uint64 Value)
  3624. {
  3625. if (Value <= 8)
  3626. /* The first ranges are individually tracked. Use the value as is. */
  3627. return Value;
  3628. else if (Value >= 513)
  3629. /* The last range is mapped to its lowest value. */
  3630. return 513;
  3631. else if (popcount64(Value) == 1)
  3632. /* If it's a power of two, use it as is. */
  3633. return Value;
  3634. else
  3635. /* Otherwise, take to the previous power of two + 1. */
  3636. return (((uint64)1) << (64 - clz64(Value) - 1)) + 1;
  3637. }
  3638. void
  3639. llvm_profile_instrument_memop(uint64 target_value, void *data,
  3640. uint32 counter_idx)
  3641. {
  3642. uint64 rep_value = InstrProfGetRangeRepValue(target_value);
  3643. instrumentTargetValueImpl(rep_value, data, counter_idx, 1);
  3644. }
  3645. static uint32
  3646. get_pgo_prof_data_size(AOTModuleInstance *module_inst, uint32 *p_num_prof_data,
  3647. uint32 *p_num_prof_counters, uint32 *p_padding_size,
  3648. uint32 *p_prof_counters_size, uint32 *p_prof_names_size,
  3649. uint32 *p_value_counters_size, uint8 **p_prof_names)
  3650. {
  3651. AOTModule *module = (AOTModule *)module_inst->module;
  3652. LLVMProfileData *prof_data;
  3653. uint8 *prof_names = NULL;
  3654. uint32 num_prof_data = 0, num_prof_counters = 0, padding_size, i;
  3655. uint32 prof_counters_size = 0, prof_names_size = 0;
  3656. uint32 total_size, total_size_wo_value_counters;
  3657. for (i = 0; i < module->data_section_count; i++) {
  3658. if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
  3659. bh_assert(module->data_sections[i].size == sizeof(LLVMProfileData));
  3660. num_prof_data++;
  3661. prof_data = (LLVMProfileData *)module->data_sections[i].data;
  3662. num_prof_counters += prof_data->num_counters;
  3663. }
  3664. else if (!strncmp(module->data_sections[i].name, "__llvm_prf_cnts",
  3665. 15)) {
  3666. prof_counters_size += module->data_sections[i].size;
  3667. }
  3668. else if (!strncmp(module->data_sections[i].name, "__llvm_prf_names",
  3669. 16)) {
  3670. prof_names_size = module->data_sections[i].size;
  3671. prof_names = module->data_sections[i].data;
  3672. }
  3673. }
  3674. if (prof_counters_size != num_prof_counters * sizeof(uint64))
  3675. return 0;
  3676. total_size = sizeof(LLVMProfileRawHeader)
  3677. + num_prof_data * sizeof(LLVMProfileData_64)
  3678. + prof_counters_size + prof_names_size;
  3679. padding_size = sizeof(uint64) - (prof_names_size % sizeof(uint64));
  3680. if (padding_size != sizeof(uint64))
  3681. total_size += padding_size;
  3682. /* Total size excluding value counters */
  3683. total_size_wo_value_counters = total_size;
  3684. for (i = 0; i < module->data_section_count; i++) {
  3685. if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
  3686. uint32 j, k, num_value_sites, num_value_nodes;
  3687. ValueProfNode **values, *value_node;
  3688. prof_data = (LLVMProfileData *)module->data_sections[i].data;
  3689. values = prof_data->values;
  3690. if (prof_data->num_value_sites[0] > 0
  3691. || prof_data->num_value_sites[1] > 0) {
  3692. /* TotalSize (uint32) and NumValueKinds (uint32) */
  3693. total_size += 8;
  3694. for (j = 0; j < 2; j++) {
  3695. if ((num_value_sites = prof_data->num_value_sites[j]) > 0) {
  3696. /* ValueKind (uint32) and NumValueSites (uint32) */
  3697. total_size += 8;
  3698. /* (Value + Counter) group counts of each value site,
  3699. each count is one byte */
  3700. total_size += align_uint(num_value_sites, 8);
  3701. if (values) {
  3702. for (k = 0; k < num_value_sites; k++) {
  3703. num_value_nodes = 0;
  3704. value_node = *values;
  3705. while (value_node) {
  3706. num_value_nodes++;
  3707. value_node = value_node->next;
  3708. }
  3709. if (num_value_nodes) {
  3710. /* (Value + Counter) groups */
  3711. total_size += num_value_nodes * 8 * 2;
  3712. }
  3713. values++;
  3714. }
  3715. }
  3716. }
  3717. }
  3718. }
  3719. }
  3720. }
  3721. if (p_num_prof_data)
  3722. *p_num_prof_data = num_prof_data;
  3723. if (p_num_prof_counters)
  3724. *p_num_prof_counters = num_prof_counters;
  3725. if (p_padding_size)
  3726. *p_padding_size = padding_size;
  3727. if (p_prof_counters_size)
  3728. *p_prof_counters_size = prof_counters_size;
  3729. if (p_prof_names_size)
  3730. *p_prof_names_size = prof_names_size;
  3731. if (p_value_counters_size)
  3732. *p_value_counters_size = total_size - total_size_wo_value_counters;
  3733. if (p_prof_names)
  3734. *p_prof_names = prof_names;
  3735. return total_size;
  3736. }
  3737. uint32
  3738. aot_get_pgo_prof_data_size(AOTModuleInstance *module_inst)
  3739. {
  3740. return get_pgo_prof_data_size(module_inst, NULL, NULL, NULL, NULL, NULL,
  3741. NULL, NULL);
  3742. }
  3743. static union {
  3744. int a;
  3745. char b;
  3746. } __ue = { .a = 1 };
  3747. #define is_little_endian() (__ue.b == 1)
  3748. uint32
  3749. aot_dump_pgo_prof_data_to_buf(AOTModuleInstance *module_inst, char *buf,
  3750. uint32 len)
  3751. {
  3752. AOTModule *module = (AOTModule *)module_inst->module;
  3753. LLVMProfileRawHeader prof_header = { 0 };
  3754. LLVMProfileData *prof_data;
  3755. uint8 *prof_names = NULL;
  3756. uint32 num_prof_data = 0, num_prof_counters = 0, padding_size, i;
  3757. uint32 prof_counters_size = 0, prof_names_size = 0;
  3758. uint32 value_counters_size = 0, value_counters_size_backup = 0;
  3759. uint32 total_size, size;
  3760. int64 counters_delta, offset_counters;
  3761. total_size = get_pgo_prof_data_size(module_inst, &num_prof_data,
  3762. &num_prof_counters, &padding_size,
  3763. &prof_counters_size, &prof_names_size,
  3764. &value_counters_size, &prof_names);
  3765. if (len < total_size)
  3766. return 0;
  3767. value_counters_size_backup = value_counters_size;
  3768. value_counters_size = 0;
  3769. prof_header.counters_delta = counters_delta =
  3770. sizeof(LLVMProfileData_64) * num_prof_data;
  3771. offset_counters = 0;
  3772. for (i = 0; i < module->data_section_count; i++) {
  3773. if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
  3774. prof_data = (LLVMProfileData *)module->data_sections[i].data;
  3775. prof_data->offset_counters = counters_delta + offset_counters;
  3776. offset_counters += prof_data->num_counters * sizeof(uint64);
  3777. counters_delta -= sizeof(LLVMProfileData_64);
  3778. }
  3779. }
  3780. prof_header.magic = 0xFF6C70726F667281LL;
  3781. /* Version 8 */
  3782. prof_header.version = 0x0000000000000008LL;
  3783. /* with VARIANT_MASK_IR_PROF (IR Instrumentation) */
  3784. prof_header.version |= 0x1ULL << 56;
  3785. /* with VARIANT_MASK_MEMPROF (Memory Profile) */
  3786. prof_header.version |= 0x1ULL << 62;
  3787. prof_header.num_prof_data = num_prof_data;
  3788. prof_header.num_prof_counters = num_prof_counters;
  3789. prof_header.names_size = prof_names_size;
  3790. prof_header.value_kind_last = 1;
  3791. if (!is_little_endian()) {
  3792. aot_exchange_uint64((uint8 *)&prof_header.magic);
  3793. aot_exchange_uint64((uint8 *)&prof_header.version);
  3794. aot_exchange_uint64((uint8 *)&prof_header.num_prof_data);
  3795. aot_exchange_uint64((uint8 *)&prof_header.num_prof_counters);
  3796. aot_exchange_uint64((uint8 *)&prof_header.names_size);
  3797. aot_exchange_uint64((uint8 *)&prof_header.counters_delta);
  3798. aot_exchange_uint64((uint8 *)&prof_header.value_kind_last);
  3799. }
  3800. size = sizeof(LLVMProfileRawHeader);
  3801. bh_memcpy_s(buf, size, &prof_header, size);
  3802. buf += size;
  3803. for (i = 0; i < module->data_section_count; i++) {
  3804. if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
  3805. LLVMProfileData_64 *prof_data_64 = (LLVMProfileData_64 *)buf;
  3806. /* Convert LLVMProfileData to LLVMProfileData_64, the pointer width
  3807. in the output file is always 8 bytes */
  3808. prof_data = (LLVMProfileData *)module->data_sections[i].data;
  3809. prof_data_64->func_md5 = prof_data->func_md5;
  3810. prof_data_64->func_hash = prof_data->func_hash;
  3811. prof_data_64->offset_counters = prof_data->offset_counters;
  3812. prof_data_64->func_ptr = prof_data->func_ptr;
  3813. prof_data_64->values = (uint64)(uintptr_t)prof_data->values;
  3814. prof_data_64->num_counters = prof_data->num_counters;
  3815. prof_data_64->num_value_sites[0] = prof_data->num_value_sites[0];
  3816. prof_data_64->num_value_sites[1] = prof_data->num_value_sites[1];
  3817. if (!is_little_endian()) {
  3818. aot_exchange_uint64((uint8 *)&prof_data_64->func_hash);
  3819. aot_exchange_uint64((uint8 *)&prof_data_64->offset_counters);
  3820. aot_exchange_uint64((uint8 *)&prof_data_64->offset_counters);
  3821. aot_exchange_uint64((uint8 *)&prof_data_64->func_ptr);
  3822. aot_exchange_uint64((uint8 *)&prof_data_64->values);
  3823. aot_exchange_uint32((uint8 *)&prof_data_64->num_counters);
  3824. aot_exchange_uint16((uint8 *)&prof_data_64->num_value_sites[0]);
  3825. aot_exchange_uint16((uint8 *)&prof_data_64->num_value_sites[1]);
  3826. }
  3827. buf += sizeof(LLVMProfileData_64);
  3828. }
  3829. }
  3830. for (i = 0; i < module->data_section_count; i++) {
  3831. if (!strncmp(module->data_sections[i].name, "__llvm_prf_cnts", 15)) {
  3832. size = module->data_sections[i].size;
  3833. bh_memcpy_s(buf, size, module->data_sections[i].data, size);
  3834. buf += size;
  3835. }
  3836. }
  3837. if (prof_names && prof_names_size > 0) {
  3838. size = prof_names_size;
  3839. bh_memcpy_s(buf, size, prof_names, size);
  3840. buf += size;
  3841. padding_size = sizeof(uint64) - (prof_names_size % sizeof(uint64));
  3842. if (padding_size != sizeof(uint64)) {
  3843. char padding_buf[8] = { 0 };
  3844. bh_memcpy_s(buf, padding_size, padding_buf, padding_size);
  3845. buf += padding_size;
  3846. }
  3847. }
  3848. for (i = 0; i < module->data_section_count; i++) {
  3849. if (!strncmp(module->data_sections[i].name, "__llvm_prf_data", 15)) {
  3850. uint32 j, k, num_value_sites, num_value_nodes;
  3851. ValueProfNode **values, **values_tmp, *value_node;
  3852. prof_data = (LLVMProfileData *)module->data_sections[i].data;
  3853. values = values_tmp = prof_data->values;
  3854. if (prof_data->num_value_sites[0] > 0
  3855. || prof_data->num_value_sites[1] > 0) {
  3856. uint32 *buf_total_size = (uint32 *)buf;
  3857. buf += 4; /* emit TotalSize later */
  3858. *(uint32 *)buf = (prof_data->num_value_sites[0] > 0
  3859. && prof_data->num_value_sites[1] > 0)
  3860. ? 2
  3861. : 1;
  3862. if (!is_little_endian())
  3863. aot_exchange_uint32((uint8 *)buf);
  3864. buf += 4;
  3865. for (j = 0; j < 2; j++) {
  3866. if ((num_value_sites = prof_data->num_value_sites[j]) > 0) {
  3867. /* ValueKind */
  3868. *(uint32 *)buf = j;
  3869. if (!is_little_endian())
  3870. aot_exchange_uint32((uint8 *)buf);
  3871. buf += 4;
  3872. /* NumValueSites */
  3873. *(uint32 *)buf = num_value_sites;
  3874. if (!is_little_endian())
  3875. aot_exchange_uint32((uint8 *)buf);
  3876. buf += 4;
  3877. for (k = 0; k < num_value_sites; k++) {
  3878. num_value_nodes = 0;
  3879. if (values_tmp) {
  3880. value_node = *values_tmp;
  3881. while (value_node) {
  3882. num_value_nodes++;
  3883. value_node = value_node->next;
  3884. }
  3885. values_tmp++;
  3886. }
  3887. bh_assert(num_value_nodes < 255);
  3888. *(uint8 *)buf++ = (uint8)num_value_nodes;
  3889. }
  3890. if (num_value_sites % 8) {
  3891. buf += 8 - (num_value_sites % 8);
  3892. }
  3893. for (k = 0; k < num_value_sites; k++) {
  3894. if (values) {
  3895. value_node = *values;
  3896. while (value_node) {
  3897. *(uint64 *)buf = value_node->value;
  3898. if (!is_little_endian())
  3899. aot_exchange_uint64((uint8 *)buf);
  3900. buf += 8;
  3901. *(uint64 *)buf = value_node->count;
  3902. if (!is_little_endian())
  3903. aot_exchange_uint64((uint8 *)buf);
  3904. buf += 8;
  3905. value_node = value_node->next;
  3906. }
  3907. values++;
  3908. }
  3909. }
  3910. }
  3911. }
  3912. /* TotalSize */
  3913. *(uint32 *)buf_total_size =
  3914. (uint8 *)buf - (uint8 *)buf_total_size;
  3915. if (!is_little_endian())
  3916. aot_exchange_uint64((uint8 *)buf_total_size);
  3917. value_counters_size += (uint8 *)buf - (uint8 *)buf_total_size;
  3918. }
  3919. }
  3920. }
  3921. bh_assert(value_counters_size == value_counters_size_backup);
  3922. (void)value_counters_size_backup;
  3923. return total_size;
  3924. }
  3925. #endif /* end of WASM_ENABLE_STATIC_PGO != 0 */
  3926. #if WASM_ENABLE_GC != 0
  3927. void *
  3928. aot_create_func_obj(AOTModuleInstance *module_inst, uint32 func_idx,
  3929. bool throw_exce, char *error_buf, uint32 error_buf_size)
  3930. {
  3931. AOTModule *module = (AOTModule *)module_inst->module;
  3932. WASMRttTypeRef rtt_type;
  3933. WASMFuncObjectRef func_obj;
  3934. AOTFuncType *func_type;
  3935. uint32 type_idx;
  3936. if (throw_exce) {
  3937. error_buf = module_inst->cur_exception;
  3938. error_buf_size = sizeof(module_inst->cur_exception);
  3939. }
  3940. if (func_idx >= module->import_func_count + module->func_count) {
  3941. set_error_buf_v(error_buf, error_buf_size, "unknown function %d",
  3942. func_idx);
  3943. return NULL;
  3944. }
  3945. type_idx = module_inst->func_type_indexes[func_idx];
  3946. func_type = (AOTFuncType *)module->types[type_idx];
  3947. if (!(rtt_type = wasm_rtt_type_new((AOTType *)func_type, type_idx,
  3948. module->rtt_types, module->type_count,
  3949. &module->rtt_type_lock))) {
  3950. set_error_buf(error_buf, error_buf_size, "create rtt object failed");
  3951. return NULL;
  3952. }
  3953. if (!(func_obj = wasm_func_obj_new_internal(
  3954. ((AOTModuleInstanceExtra *)module_inst->e)->common.gc_heap_handle,
  3955. rtt_type, func_idx))) {
  3956. set_error_buf(error_buf, error_buf_size, "create func object failed");
  3957. return NULL;
  3958. }
  3959. return func_obj;
  3960. }
  3961. bool
  3962. aot_obj_is_instance_of(AOTModuleInstance *module_inst, WASMObjectRef gc_obj,
  3963. uint32 type_index)
  3964. {
  3965. AOTModule *aot_module = (AOTModule *)module_inst->module;
  3966. AOTType **types = aot_module->types;
  3967. uint32 type_count = aot_module->type_count;
  3968. return wasm_obj_is_instance_of(gc_obj, type_index, types, type_count);
  3969. }
  3970. bool
  3971. aot_func_type_is_super_of(AOTModuleInstance *module_inst, uint32 type_idx1,
  3972. uint32 type_idx2)
  3973. {
  3974. AOTModule *aot_module = (AOTModule *)module_inst->module;
  3975. AOTType **types = aot_module->types;
  3976. if (type_idx1 == type_idx2)
  3977. return true;
  3978. bh_assert(types[type_idx1]->type_flag == WASM_TYPE_FUNC);
  3979. bh_assert(types[type_idx2]->type_flag == WASM_TYPE_FUNC);
  3980. return wasm_func_type_is_super_of((WASMFuncType *)types[type_idx1],
  3981. (WASMFuncType *)types[type_idx2]);
  3982. }
  3983. WASMRttTypeRef
  3984. aot_rtt_type_new(AOTModuleInstance *module_inst, uint32 type_index)
  3985. {
  3986. AOTModule *aot_module = (AOTModule *)module_inst->module;
  3987. AOTType *defined_type = aot_module->types[type_index];
  3988. WASMRttType **rtt_types = aot_module->rtt_types;
  3989. uint32 rtt_type_count = aot_module->type_count;
  3990. korp_mutex *rtt_type_lock = &aot_module->rtt_type_lock;
  3991. return wasm_rtt_type_new(defined_type, type_index, rtt_types,
  3992. rtt_type_count, rtt_type_lock);
  3993. }
  3994. bool
  3995. aot_array_init_with_data(AOTModuleInstance *module_inst, uint32 seg_index,
  3996. uint32 data_seg_offset, WASMArrayObjectRef array_obj,
  3997. uint32 elem_size, uint32 array_len)
  3998. {
  3999. AOTModule *aot_module;
  4000. uint8 *data = NULL;
  4001. uint8 *array_elem_base;
  4002. uint64 seg_len = 0;
  4003. uint64 total_size = (int64)elem_size * array_len;
  4004. aot_module = (AOTModule *)module_inst->module;
  4005. seg_len = aot_module->mem_init_data_list[seg_index]->byte_count;
  4006. data = aot_module->mem_init_data_list[seg_index]->bytes;
  4007. if (data_seg_offset >= seg_len || total_size > seg_len - data_seg_offset) {
  4008. aot_set_exception(module_inst, "out of bounds memory access");
  4009. return false;
  4010. }
  4011. array_elem_base = (uint8 *)wasm_array_obj_first_elem_addr(array_obj);
  4012. bh_memcpy_s(array_elem_base, (uint32)total_size, data + data_seg_offset,
  4013. (uint32)total_size);
  4014. return true;
  4015. }
  4016. static bool
  4017. aot_global_traverse_gc_rootset(AOTModuleInstance *module_inst, void *heap)
  4018. {
  4019. AOTModule *module = (AOTModule *)module_inst->module;
  4020. uint8 *global_data = module_inst->global_data;
  4021. AOTImportGlobal *import_global = module->import_globals;
  4022. AOTGlobal *global = module->globals;
  4023. WASMObjectRef gc_obj;
  4024. uint32 i;
  4025. for (i = 0; i < module->import_global_count; i++, import_global++) {
  4026. if (wasm_is_type_reftype(import_global->type.val_type)) {
  4027. gc_obj = GET_REF_FROM_ADDR((uint32 *)global_data);
  4028. if (wasm_obj_is_created_from_heap(gc_obj)) {
  4029. if (0 != mem_allocator_add_root((mem_allocator_t)heap, gc_obj))
  4030. return false;
  4031. }
  4032. }
  4033. global_data += import_global->size;
  4034. }
  4035. for (i = 0; i < module->global_count; i++, global++) {
  4036. if (wasm_is_type_reftype(global->type.val_type)) {
  4037. gc_obj = GET_REF_FROM_ADDR((uint32 *)global_data);
  4038. if (wasm_obj_is_created_from_heap(gc_obj)) {
  4039. if (0 != mem_allocator_add_root((mem_allocator_t)heap, gc_obj))
  4040. return false;
  4041. }
  4042. }
  4043. global_data += global->size;
  4044. }
  4045. return true;
  4046. }
  4047. static bool
  4048. aot_table_traverse_gc_rootset(WASMModuleInstance *module_inst, void *heap)
  4049. {
  4050. AOTTableInstance **tables = (AOTTableInstance **)module_inst->tables;
  4051. AOTTableInstance *table;
  4052. uint32 table_count = module_inst->table_count, i, j;
  4053. WASMObjectRef gc_obj, *table_elems;
  4054. for (i = 0; i < table_count; i++) {
  4055. table = tables[i];
  4056. table_elems = (WASMObjectRef *)table->elems;
  4057. for (j = 0; j < table->cur_size; j++) {
  4058. gc_obj = table_elems[j];
  4059. if (wasm_obj_is_created_from_heap(gc_obj)) {
  4060. if (0 != mem_allocator_add_root((mem_allocator_t)heap, gc_obj))
  4061. return false;
  4062. }
  4063. }
  4064. }
  4065. return true;
  4066. }
  4067. static bool
  4068. local_object_refs_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap)
  4069. {
  4070. WASMLocalObjectRef *r;
  4071. WASMObjectRef gc_obj;
  4072. for (r = exec_env->cur_local_object_ref; r; r = r->prev) {
  4073. gc_obj = r->val;
  4074. if (wasm_obj_is_created_from_heap(gc_obj)) {
  4075. if (0 != mem_allocator_add_root((mem_allocator_t)heap, gc_obj))
  4076. return false;
  4077. }
  4078. }
  4079. return true;
  4080. }
  4081. static bool
  4082. aot_frame_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap)
  4083. {
  4084. AOTFrame *frame;
  4085. AOTModule *module;
  4086. LocalRefFlag frame_local_flags;
  4087. WASMObjectRef gc_obj;
  4088. uint32 i, local_ref_flag_cell_num;
  4089. module = (AOTModule *)wasm_exec_env_get_module(exec_env);
  4090. frame = (AOTFrame *)wasm_exec_env_get_cur_frame(exec_env);
  4091. for (; frame; frame = frame->prev_frame) {
  4092. /* local ref flags */
  4093. frame_local_flags = module->func_local_ref_flags[frame->func_index];
  4094. local_ref_flag_cell_num = frame_local_flags.local_ref_flag_cell_num;
  4095. for (i = 0; i < local_ref_flag_cell_num; i++) {
  4096. if (frame_local_flags.local_ref_flags[i]) {
  4097. gc_obj = GET_REF_FROM_ADDR(frame->lp + i);
  4098. if (wasm_obj_is_created_from_heap(gc_obj)) {
  4099. if (mem_allocator_add_root((mem_allocator_t)heap, gc_obj)) {
  4100. return false;
  4101. }
  4102. }
  4103. #if UINTPTR_MAX == UINT64_MAX
  4104. bh_assert(frame_local_flags.local_ref_flags[i + 1]);
  4105. i++;
  4106. #endif
  4107. }
  4108. }
  4109. /* stack ref flags */
  4110. uint8 *frame_ref = frame->frame_ref;
  4111. for (i = local_ref_flag_cell_num; i < (uint32)(frame->sp - frame->lp);
  4112. i++) {
  4113. if (frame_ref[i]) {
  4114. gc_obj = GET_REF_FROM_ADDR(frame->lp + i);
  4115. if (wasm_obj_is_created_from_heap(gc_obj)) {
  4116. if (mem_allocator_add_root((mem_allocator_t)heap, gc_obj)) {
  4117. return false;
  4118. }
  4119. }
  4120. #if UINTPTR_MAX == UINT64_MAX
  4121. bh_assert(frame_ref[i + 1]);
  4122. i++;
  4123. #endif
  4124. }
  4125. }
  4126. }
  4127. return true;
  4128. }
  4129. bool
  4130. aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap)
  4131. {
  4132. AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
  4133. bool ret;
  4134. ret = aot_global_traverse_gc_rootset(module_inst, heap);
  4135. if (!ret)
  4136. return ret;
  4137. ret = aot_table_traverse_gc_rootset(module_inst, heap);
  4138. if (!ret)
  4139. return ret;
  4140. ret = local_object_refs_traverse_gc_rootset(exec_env, heap);
  4141. if (!ret)
  4142. return ret;
  4143. ret = aot_frame_traverse_gc_rootset(exec_env, heap);
  4144. if (!ret)
  4145. return ret;
  4146. return true;
  4147. }
  4148. #endif /* end of WASM_ENABLE_GC != 0 */
  4149. char *
  4150. aot_const_str_set_insert(const uint8 *str, int32 len, AOTModule *module,
  4151. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  4152. bool is_vram_word_align,
  4153. #endif
  4154. char *error_buf, uint32 error_buf_size)
  4155. {
  4156. HashMap *set = module->const_str_set;
  4157. char *c_str, *value;
  4158. /* Create const string set if it isn't created */
  4159. if (!set
  4160. && !(set = module->const_str_set = bh_hash_map_create(
  4161. 32, false, (HashFunc)wasm_string_hash,
  4162. (KeyEqualFunc)wasm_string_equal, NULL, wasm_runtime_free))) {
  4163. set_error_buf(error_buf, error_buf_size,
  4164. "create const string set failed");
  4165. return NULL;
  4166. }
  4167. /* Lookup const string set, use the string if found */
  4168. if (!(c_str = runtime_malloc((uint32)len, error_buf, error_buf_size))) {
  4169. return NULL;
  4170. }
  4171. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  4172. if (is_vram_word_align) {
  4173. bh_memcpy_wa(c_str, (uint32)len, str, (uint32)len);
  4174. }
  4175. else
  4176. #endif
  4177. {
  4178. bh_memcpy_s(c_str, len, str, (uint32)len);
  4179. }
  4180. if ((value = bh_hash_map_find(set, c_str))) {
  4181. wasm_runtime_free(c_str);
  4182. return value;
  4183. }
  4184. if (!bh_hash_map_insert(set, c_str, c_str)) {
  4185. set_error_buf(error_buf, error_buf_size,
  4186. "insert string to hash map failed");
  4187. wasm_runtime_free(c_str);
  4188. return NULL;
  4189. }
  4190. return c_str;
  4191. }
  4192. bool
  4193. aot_set_module_name(AOTModule *module, const char *name, char *error_buf,
  4194. uint32_t error_buf_size)
  4195. {
  4196. if (!name)
  4197. return false;
  4198. module->name = aot_const_str_set_insert((const uint8 *)name,
  4199. (uint32)(strlen(name) + 1), module,
  4200. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  4201. false,
  4202. #endif
  4203. error_buf, error_buf_size);
  4204. return module->name != NULL;
  4205. }
  4206. const char *
  4207. aot_get_module_name(AOTModule *module)
  4208. {
  4209. return module->name;
  4210. }