aot_runtime.c 204 KB

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