aot_runtime.c 194 KB

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