wasm_runtime_common.c 228 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "bh_platform.h"
  6. #include "bh_common.h"
  7. #include "bh_assert.h"
  8. #include "bh_log.h"
  9. #include "wasm_native.h"
  10. #include "wasm_runtime_common.h"
  11. #include "wasm_memory.h"
  12. #if WASM_ENABLE_INTERP != 0
  13. #include "../interpreter/wasm_runtime.h"
  14. #endif
  15. #if WASM_ENABLE_AOT != 0
  16. #include "../aot/aot_runtime.h"
  17. #if WASM_ENABLE_DEBUG_AOT != 0
  18. #include "../aot/debug/jit_debug.h"
  19. #endif
  20. #endif
  21. #if WASM_ENABLE_GC != 0
  22. #include "gc/gc_object.h"
  23. #endif
  24. #if WASM_ENABLE_THREAD_MGR != 0
  25. #include "../libraries/thread-mgr/thread_manager.h"
  26. #if WASM_ENABLE_DEBUG_INTERP != 0
  27. #include "../libraries/debug-engine/debug_engine.h"
  28. #endif
  29. #endif
  30. #if WASM_ENABLE_SHARED_MEMORY != 0
  31. #include "wasm_shared_memory.h"
  32. #endif
  33. #if WASM_ENABLE_FAST_JIT != 0
  34. #include "../fast-jit/jit_compiler.h"
  35. #endif
  36. #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
  37. #include "../compilation/aot_llvm.h"
  38. #endif
  39. #include "../common/wasm_c_api_internal.h"
  40. #include "../../version.h"
  41. /**
  42. * For runtime build, BH_MALLOC/BH_FREE should be defined as
  43. * wasm_runtime_malloc/wasm_runtime_free.
  44. */
  45. #define CHECK(a) CHECK1(a)
  46. #define CHECK1(a) SHOULD_BE_##a
  47. #define SHOULD_BE_wasm_runtime_malloc 1
  48. #if !CHECK(BH_MALLOC)
  49. #error unexpected BH_MALLOC
  50. #endif
  51. #undef SHOULD_BE_wasm_runtime_malloc
  52. #define SHOULD_BE_wasm_runtime_free 1
  53. #if !CHECK(BH_FREE)
  54. #error unexpected BH_FREE
  55. #endif
  56. #undef SHOULD_BE_wasm_runtime_free
  57. #undef CHECK
  58. #undef CHECK1
  59. #if WASM_ENABLE_MULTI_MODULE != 0
  60. /**
  61. * A safety insurance to prevent
  62. * circular dependencies which leads stack overflow
  63. * try to break early
  64. */
  65. typedef struct LoadingModule {
  66. bh_list_link l;
  67. /* point to a string pool */
  68. const char *module_name;
  69. } LoadingModule;
  70. static bh_list loading_module_list_head;
  71. static bh_list *const loading_module_list = &loading_module_list_head;
  72. static korp_mutex loading_module_list_lock;
  73. /**
  74. * A list to store all exported functions/globals/memories/tables
  75. * of every fully loaded module
  76. */
  77. static bh_list registered_module_list_head;
  78. static bh_list *const registered_module_list = &registered_module_list_head;
  79. static korp_mutex registered_module_list_lock;
  80. static void
  81. wasm_runtime_destroy_registered_module_list();
  82. #endif /* WASM_ENABLE_MULTI_MODULE */
  83. #define E_TYPE_XIP 4
  84. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  85. /* Initialize externref hashmap */
  86. static bool
  87. wasm_externref_map_init();
  88. /* Destroy externref hashmap */
  89. static void
  90. wasm_externref_map_destroy();
  91. #endif /* end of WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0 */
  92. static void
  93. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  94. {
  95. if (error_buf != NULL)
  96. snprintf(error_buf, error_buf_size, "%s", string);
  97. }
  98. static void *
  99. runtime_malloc(uint64 size, WASMModuleInstanceCommon *module_inst,
  100. char *error_buf, uint32 error_buf_size)
  101. {
  102. void *mem;
  103. if (size >= UINT32_MAX || !(mem = wasm_runtime_malloc((uint32)size))) {
  104. if (module_inst != NULL) {
  105. wasm_runtime_set_exception(module_inst, "allocate memory failed");
  106. }
  107. else if (error_buf != NULL) {
  108. set_error_buf(error_buf, error_buf_size, "allocate memory failed");
  109. }
  110. return NULL;
  111. }
  112. memset(mem, 0, (uint32)size);
  113. return mem;
  114. }
  115. #if WASM_ENABLE_MULTI_MODULE != 0
  116. /* TODO: Let loader_malloc be a general API both for AOT and WASM. */
  117. #define loader_malloc(size, error_buf, error_buf_size) \
  118. runtime_malloc(size, NULL, error_buf, error_buf_size)
  119. static void
  120. set_error_buf_v(const WASMModuleCommon *module, char *error_buf,
  121. uint32 error_buf_size, const char *format, ...)
  122. {
  123. va_list args;
  124. char buf[128];
  125. if (error_buf != NULL) {
  126. va_start(args, format);
  127. vsnprintf(buf, sizeof(buf), format, args);
  128. va_end(args);
  129. if (module->module_type == Wasm_Module_AoT) {
  130. snprintf(error_buf, error_buf_size, "AOT module load failed: %s",
  131. buf);
  132. }
  133. else if (module->module_type == Wasm_Module_Bytecode) {
  134. snprintf(error_buf, error_buf_size, "WASM module load failed: %s",
  135. buf);
  136. }
  137. }
  138. }
  139. #endif
  140. #if WASM_ENABLE_FAST_JIT != 0
  141. static JitCompOptions jit_options = { 0 };
  142. #endif
  143. #if WASM_ENABLE_JIT != 0
  144. /* opt_level: 3, size_level: 3, segue-flags: 0,
  145. quick_invoke_c_api_import: false */
  146. static LLVMJITOptions llvm_jit_options = { 3, 3, 0, false };
  147. #endif
  148. #if WASM_ENABLE_GC != 0
  149. static uint32 gc_heap_size_default = GC_HEAP_SIZE_DEFAULT;
  150. #endif
  151. static RunningMode runtime_running_mode = Mode_Default;
  152. #ifdef OS_ENABLE_HW_BOUND_CHECK
  153. /* The exec_env of thread local storage, set before calling function
  154. and used in signal handler, as we cannot get it from the argument
  155. of signal handler */
  156. static os_thread_local_attribute WASMExecEnv *exec_env_tls = NULL;
  157. #ifndef BH_PLATFORM_WINDOWS
  158. static void
  159. runtime_signal_handler(void *sig_addr)
  160. {
  161. WASMModuleInstance *module_inst;
  162. WASMMemoryInstance *memory_inst;
  163. WASMJmpBuf *jmpbuf_node;
  164. uint8 *mapped_mem_start_addr = NULL;
  165. uint8 *mapped_mem_end_addr = NULL;
  166. uint32 page_size = os_getpagesize();
  167. #if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
  168. uint8 *stack_min_addr;
  169. uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
  170. #endif
  171. /* Check whether current thread is running wasm function */
  172. if (exec_env_tls && exec_env_tls->handle == os_self_thread()
  173. && (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
  174. /* Get mapped mem info of current instance */
  175. module_inst = (WASMModuleInstance *)exec_env_tls->module_inst;
  176. /* Get the default memory instance */
  177. memory_inst = wasm_get_default_memory(module_inst);
  178. if (memory_inst) {
  179. mapped_mem_start_addr = memory_inst->memory_data;
  180. mapped_mem_end_addr = memory_inst->memory_data + 8 * (uint64)BH_GB;
  181. }
  182. #if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
  183. /* Get stack info of current thread */
  184. stack_min_addr = os_thread_get_stack_boundary();
  185. #endif
  186. if (memory_inst
  187. && (mapped_mem_start_addr <= (uint8 *)sig_addr
  188. && (uint8 *)sig_addr < mapped_mem_end_addr)) {
  189. /* The address which causes segmentation fault is inside
  190. the memory instance's guard regions */
  191. wasm_set_exception(module_inst, "out of bounds memory access");
  192. os_longjmp(jmpbuf_node->jmpbuf, 1);
  193. }
  194. #if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
  195. else if (stack_min_addr <= (uint8 *)sig_addr
  196. && (uint8 *)sig_addr
  197. < stack_min_addr + page_size * guard_page_count) {
  198. /* The address which causes segmentation fault is inside
  199. native thread's guard page */
  200. wasm_set_exception(module_inst, "native stack overflow");
  201. os_longjmp(jmpbuf_node->jmpbuf, 1);
  202. }
  203. #endif
  204. else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
  205. && (uint8 *)sig_addr
  206. < exec_env_tls->exce_check_guard_page + page_size) {
  207. bh_assert(wasm_copy_exception(module_inst, NULL));
  208. os_longjmp(jmpbuf_node->jmpbuf, 1);
  209. }
  210. }
  211. }
  212. #else /* else of BH_PLATFORM_WINDOWS */
  213. #if WASM_ENABLE_AOT != 0
  214. #include <Zydis/Zydis.h>
  215. static uint32
  216. decode_insn(uint8 *insn)
  217. {
  218. uint8 *data = (uint8 *)insn;
  219. uint32 length = 32; /* reserve enough size */
  220. /* Initialize decoder context */
  221. ZydisDecoder decoder;
  222. ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64,
  223. ZYDIS_STACK_WIDTH_64);
  224. /* Initialize formatter */
  225. ZydisFormatter formatter;
  226. ZydisFormatterInit(&formatter, ZYDIS_FORMATTER_STYLE_INTEL);
  227. /* Loop over the instructions in our buffer */
  228. ZyanU64 runtime_address = (ZyanU64)(uintptr_t)data;
  229. ZyanUSize offset = 0;
  230. ZydisDecodedInstruction instruction;
  231. ZydisDecodedOperand operands[ZYDIS_MAX_OPERAND_COUNT_VISIBLE];
  232. char buffer[256];
  233. if (ZYAN_SUCCESS(ZydisDecoderDecodeFull(
  234. &decoder, data + offset, length - offset, &instruction, operands,
  235. ZYDIS_MAX_OPERAND_COUNT_VISIBLE,
  236. ZYDIS_DFLAG_VISIBLE_OPERANDS_ONLY))) {
  237. /* Format & print the binary instruction structure to
  238. human readable format */
  239. ZydisFormatterFormatInstruction(&formatter, &instruction, operands,
  240. instruction.operand_count_visible,
  241. buffer, sizeof(buffer),
  242. runtime_address);
  243. #if 0
  244. /* Print current instruction */
  245. os_printf("%012" PRIX64 " ", runtime_address);
  246. puts(buffer);
  247. #endif
  248. return instruction.length;
  249. }
  250. /* Decode failed */
  251. return 0;
  252. }
  253. #endif /* end of WASM_ENABLE_AOT != 0 */
  254. static LONG
  255. next_action(WASMModuleInstance *module_inst, EXCEPTION_POINTERS *exce_info)
  256. {
  257. #if WASM_ENABLE_AOT != 0
  258. uint32 insn_size;
  259. #endif
  260. if (module_inst->module_type == Wasm_Module_Bytecode
  261. && module_inst->e->running_mode == Mode_Interp) {
  262. /* Continue to search next exception handler for
  263. interpreter mode as it can be caught by
  264. `__try { .. } __except { .. }` sentences in
  265. wasm_runtime.c */
  266. return EXCEPTION_CONTINUE_SEARCH;
  267. }
  268. #if WASM_ENABLE_AOT != 0
  269. /* Skip current instruction and continue to run for AOT/JIT mode.
  270. TODO: implement unwind support for AOT/JIT code in Windows platform */
  271. insn_size = decode_insn((uint8 *)exce_info->ContextRecord->Rip);
  272. if (insn_size > 0) {
  273. exce_info->ContextRecord->Rip += insn_size;
  274. return EXCEPTION_CONTINUE_EXECUTION;
  275. }
  276. #endif
  277. /* return different value from EXCEPTION_CONTINUE_SEARCH (= 0)
  278. and EXCEPTION_CONTINUE_EXECUTION (= -1) */
  279. return -2;
  280. }
  281. static LONG
  282. runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
  283. {
  284. PEXCEPTION_RECORD ExceptionRecord = exce_info->ExceptionRecord;
  285. uint8 *sig_addr = (uint8 *)ExceptionRecord->ExceptionInformation[1];
  286. WASMModuleInstance *module_inst;
  287. WASMMemoryInstance *memory_inst;
  288. WASMJmpBuf *jmpbuf_node;
  289. uint8 *mapped_mem_start_addr = NULL;
  290. uint8 *mapped_mem_end_addr = NULL;
  291. uint32 page_size = os_getpagesize();
  292. LONG ret;
  293. if (exec_env_tls && exec_env_tls->handle == os_self_thread()
  294. && (jmpbuf_node = exec_env_tls->jmpbuf_stack_top)) {
  295. module_inst = (WASMModuleInstance *)exec_env_tls->module_inst;
  296. if (ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
  297. /* Get the default memory instance */
  298. memory_inst = wasm_get_default_memory(module_inst);
  299. if (memory_inst) {
  300. mapped_mem_start_addr = memory_inst->memory_data;
  301. mapped_mem_end_addr =
  302. memory_inst->memory_data + 8 * (uint64)BH_GB;
  303. }
  304. if (memory_inst && mapped_mem_start_addr <= (uint8 *)sig_addr
  305. && (uint8 *)sig_addr < mapped_mem_end_addr) {
  306. /* The address which causes segmentation fault is inside
  307. the memory instance's guard regions.
  308. Set exception and let the wasm func continue to run, when
  309. the wasm func returns, the caller will check whether the
  310. exception is thrown and return to runtime. */
  311. wasm_set_exception(module_inst, "out of bounds memory access");
  312. ret = next_action(module_inst, exce_info);
  313. if (ret == EXCEPTION_CONTINUE_SEARCH
  314. || ret == EXCEPTION_CONTINUE_EXECUTION)
  315. return ret;
  316. }
  317. else if (exec_env_tls->exce_check_guard_page <= (uint8 *)sig_addr
  318. && (uint8 *)sig_addr
  319. < exec_env_tls->exce_check_guard_page + page_size) {
  320. bh_assert(wasm_copy_exception(module_inst, NULL));
  321. ret = next_action(module_inst, exce_info);
  322. if (ret == EXCEPTION_CONTINUE_SEARCH
  323. || ret == EXCEPTION_CONTINUE_EXECUTION)
  324. return ret;
  325. }
  326. }
  327. #if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
  328. else if (ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) {
  329. /* Set stack overflow exception and let the wasm func continue
  330. to run, when the wasm func returns, the caller will check
  331. whether the exception is thrown and return to runtime, and
  332. the damaged stack will be recovered by _resetstkoflw(). */
  333. wasm_set_exception(module_inst, "native stack overflow");
  334. ret = next_action(module_inst, exce_info);
  335. if (ret == EXCEPTION_CONTINUE_SEARCH
  336. || ret == EXCEPTION_CONTINUE_EXECUTION)
  337. return ret;
  338. }
  339. #endif
  340. }
  341. LOG_ERROR("Unhandled exception thrown: exception code: 0x%lx, "
  342. "exception address: %p, exception information: %p\n",
  343. ExceptionRecord->ExceptionCode, ExceptionRecord->ExceptionAddress,
  344. sig_addr);
  345. return EXCEPTION_CONTINUE_SEARCH;
  346. }
  347. #endif /* end of BH_PLATFORM_WINDOWS */
  348. static bool
  349. runtime_signal_init()
  350. {
  351. #ifndef BH_PLATFORM_WINDOWS
  352. return os_thread_signal_init(runtime_signal_handler) == 0 ? true : false;
  353. #else
  354. if (os_thread_signal_init() != 0)
  355. return false;
  356. if (!AddVectoredExceptionHandler(1, runtime_exception_handler)) {
  357. os_thread_signal_destroy();
  358. return false;
  359. }
  360. #endif
  361. return true;
  362. }
  363. static void
  364. runtime_signal_destroy()
  365. {
  366. #ifdef BH_PLATFORM_WINDOWS
  367. RemoveVectoredExceptionHandler(runtime_exception_handler);
  368. #endif
  369. os_thread_signal_destroy();
  370. }
  371. void
  372. wasm_runtime_set_exec_env_tls(WASMExecEnv *exec_env)
  373. {
  374. exec_env_tls = exec_env;
  375. }
  376. WASMExecEnv *
  377. wasm_runtime_get_exec_env_tls()
  378. {
  379. return exec_env_tls;
  380. }
  381. #endif /* end of OS_ENABLE_HW_BOUND_CHECK */
  382. static bool
  383. wasm_runtime_env_init()
  384. {
  385. if (bh_platform_init() != 0)
  386. return false;
  387. if (wasm_native_init() == false) {
  388. goto fail1;
  389. }
  390. #if WASM_ENABLE_MULTI_MODULE
  391. if (BHT_OK != os_mutex_init(&registered_module_list_lock)) {
  392. goto fail2;
  393. }
  394. if (BHT_OK != os_mutex_init(&loading_module_list_lock)) {
  395. goto fail3;
  396. }
  397. #endif
  398. #if WASM_ENABLE_SHARED_MEMORY
  399. if (!wasm_shared_memory_init()) {
  400. goto fail4;
  401. }
  402. #endif
  403. #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_THREAD_MGR != 0)
  404. if (!thread_manager_init()) {
  405. goto fail5;
  406. }
  407. #endif
  408. #ifdef OS_ENABLE_HW_BOUND_CHECK
  409. if (!runtime_signal_init()) {
  410. goto fail6;
  411. }
  412. #endif
  413. #if WASM_ENABLE_AOT != 0
  414. #if WASM_ENABLE_DEBUG_AOT != 0
  415. if (!jit_debug_engine_init()) {
  416. goto fail7;
  417. }
  418. #endif
  419. #endif
  420. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  421. if (!wasm_externref_map_init()) {
  422. goto fail8;
  423. }
  424. #endif
  425. #if WASM_ENABLE_FAST_JIT != 0
  426. if (!jit_compiler_init(&jit_options)) {
  427. goto fail9;
  428. }
  429. #endif
  430. #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
  431. if (!aot_compiler_init()) {
  432. goto fail10;
  433. }
  434. #endif
  435. #if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
  436. if (os_blocking_op_init() != BHT_OK) {
  437. goto fail11;
  438. }
  439. os_end_blocking_op();
  440. #endif
  441. return true;
  442. #if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
  443. fail11:
  444. #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
  445. aot_compiler_destroy();
  446. #endif
  447. #endif
  448. #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
  449. fail10:
  450. #if WASM_ENABLE_FAST_JIT != 0
  451. jit_compiler_destroy();
  452. #endif
  453. #endif
  454. #if WASM_ENABLE_FAST_JIT != 0
  455. fail9:
  456. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  457. wasm_externref_map_destroy();
  458. #endif
  459. #endif
  460. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  461. fail8:
  462. #endif
  463. #if WASM_ENABLE_AOT != 0
  464. #if WASM_ENABLE_DEBUG_AOT != 0
  465. jit_debug_engine_destroy();
  466. fail7:
  467. #endif
  468. #endif
  469. #ifdef OS_ENABLE_HW_BOUND_CHECK
  470. runtime_signal_destroy();
  471. fail6:
  472. #endif
  473. #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_THREAD_MGR != 0)
  474. thread_manager_destroy();
  475. fail5:
  476. #endif
  477. #if WASM_ENABLE_SHARED_MEMORY
  478. wasm_shared_memory_destroy();
  479. fail4:
  480. #endif
  481. #if WASM_ENABLE_MULTI_MODULE
  482. os_mutex_destroy(&loading_module_list_lock);
  483. fail3:
  484. os_mutex_destroy(&registered_module_list_lock);
  485. fail2:
  486. #endif
  487. wasm_native_destroy();
  488. fail1:
  489. bh_platform_destroy();
  490. return false;
  491. }
  492. static bool
  493. wasm_runtime_exec_env_check(WASMExecEnv *exec_env)
  494. {
  495. return exec_env && exec_env->module_inst && exec_env->wasm_stack_size > 0
  496. && exec_env->wasm_stack.top_boundary
  497. == exec_env->wasm_stack.bottom + exec_env->wasm_stack_size
  498. && exec_env->wasm_stack.top <= exec_env->wasm_stack.top_boundary;
  499. }
  500. #if defined(OS_THREAD_MUTEX_INITIALIZER)
  501. /**
  502. * lock for wasm_runtime_init/wasm_runtime_full_init and runtime_ref_count
  503. * Note: if the platform has mutex initializer, we use a global lock to
  504. * lock the operations of runtime init/full_init, otherwise when there are
  505. * operations happening simultaneously in multiple threads, developer
  506. * must create the lock by himself, and use it to lock the operations
  507. */
  508. static korp_mutex runtime_lock = OS_THREAD_MUTEX_INITIALIZER;
  509. #endif
  510. static int32 runtime_ref_count = 0;
  511. static bool
  512. wasm_runtime_init_internal()
  513. {
  514. if (!wasm_runtime_memory_init(Alloc_With_System_Allocator, NULL))
  515. return false;
  516. if (!wasm_runtime_env_init()) {
  517. wasm_runtime_memory_destroy();
  518. return false;
  519. }
  520. return true;
  521. }
  522. bool
  523. wasm_runtime_init()
  524. {
  525. bool ret = true;
  526. #if defined(OS_THREAD_MUTEX_INITIALIZER)
  527. os_mutex_lock(&runtime_lock);
  528. #endif
  529. bh_assert(runtime_ref_count >= 0);
  530. if (runtime_ref_count == 0) {
  531. ret = wasm_runtime_init_internal();
  532. }
  533. if (ret) {
  534. runtime_ref_count++;
  535. }
  536. #if defined(OS_THREAD_MUTEX_INITIALIZER)
  537. os_mutex_unlock(&runtime_lock);
  538. #endif
  539. return ret;
  540. }
  541. static void
  542. wasm_runtime_destroy_internal()
  543. {
  544. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  545. wasm_externref_map_destroy();
  546. #endif
  547. #if WASM_ENABLE_AOT != 0
  548. #if WASM_ENABLE_DEBUG_AOT != 0
  549. jit_debug_engine_destroy();
  550. #endif
  551. #endif
  552. #ifdef OS_ENABLE_HW_BOUND_CHECK
  553. runtime_signal_destroy();
  554. #endif
  555. /* runtime env destroy */
  556. #if WASM_ENABLE_MULTI_MODULE
  557. wasm_runtime_destroy_loading_module_list();
  558. os_mutex_destroy(&loading_module_list_lock);
  559. wasm_runtime_destroy_registered_module_list();
  560. os_mutex_destroy(&registered_module_list_lock);
  561. #endif
  562. #if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
  563. /* Destroy LLVM-JIT compiler after destroying the modules
  564. * loaded by multi-module feature, since these modules may
  565. * create backend threads to compile the wasm functions,
  566. * which may access the LLVM resources. We wait until they
  567. * finish the compilation to avoid accessing the destroyed
  568. * resources in the compilation threads.
  569. */
  570. aot_compiler_destroy();
  571. #endif
  572. #if WASM_ENABLE_FAST_JIT != 0
  573. /* Destroy Fast-JIT compiler after destroying the modules
  574. * loaded by multi-module feature, since the Fast JIT's
  575. * code cache allocator may be used by these modules.
  576. */
  577. jit_compiler_destroy();
  578. #endif
  579. #if WASM_ENABLE_SHARED_MEMORY
  580. wasm_shared_memory_destroy();
  581. #endif
  582. #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_THREAD_MGR != 0)
  583. #if WASM_ENABLE_DEBUG_INTERP != 0
  584. wasm_debug_engine_destroy();
  585. #endif
  586. thread_manager_destroy();
  587. #endif
  588. wasm_native_destroy();
  589. bh_platform_destroy();
  590. wasm_runtime_memory_destroy();
  591. }
  592. void
  593. wasm_runtime_destroy()
  594. {
  595. #if defined(OS_THREAD_MUTEX_INITIALIZER)
  596. os_mutex_lock(&runtime_lock);
  597. #endif
  598. bh_assert(runtime_ref_count > 0);
  599. runtime_ref_count--;
  600. if (runtime_ref_count == 0) {
  601. wasm_runtime_destroy_internal();
  602. }
  603. #if defined(OS_THREAD_MUTEX_INITIALIZER)
  604. os_mutex_unlock(&runtime_lock);
  605. #endif
  606. }
  607. RunningMode
  608. wasm_runtime_get_default_running_mode(void)
  609. {
  610. return runtime_running_mode;
  611. }
  612. #if WASM_ENABLE_JIT != 0
  613. LLVMJITOptions *
  614. wasm_runtime_get_llvm_jit_options(void)
  615. {
  616. return &llvm_jit_options;
  617. }
  618. #endif
  619. #if WASM_ENABLE_GC != 0
  620. uint32
  621. wasm_runtime_get_gc_heap_size_default(void)
  622. {
  623. return gc_heap_size_default;
  624. }
  625. #endif
  626. static bool
  627. wasm_runtime_full_init_internal(RuntimeInitArgs *init_args)
  628. {
  629. if (!wasm_runtime_memory_init(init_args->mem_alloc_type,
  630. &init_args->mem_alloc_option))
  631. return false;
  632. if (!wasm_runtime_set_default_running_mode(init_args->running_mode)) {
  633. wasm_runtime_memory_destroy();
  634. return false;
  635. }
  636. #if WASM_ENABLE_FAST_JIT != 0
  637. jit_options.code_cache_size = init_args->fast_jit_code_cache_size;
  638. #endif
  639. #if WASM_ENABLE_GC != 0
  640. gc_heap_size_default = init_args->gc_heap_size;
  641. #endif
  642. #if WASM_ENABLE_JIT != 0
  643. llvm_jit_options.size_level = init_args->llvm_jit_size_level;
  644. llvm_jit_options.opt_level = init_args->llvm_jit_opt_level;
  645. llvm_jit_options.segue_flags = init_args->segue_flags;
  646. #endif
  647. #if WASM_ENABLE_LINUX_PERF != 0
  648. wasm_runtime_set_linux_perf(init_args->enable_linux_perf);
  649. #else
  650. if (init_args->enable_linux_perf)
  651. LOG_WARNING("warning: to enable linux perf support, please recompile "
  652. "with -DWAMR_BUILD_LINUX_PERF=1");
  653. #endif
  654. if (!wasm_runtime_env_init()) {
  655. wasm_runtime_memory_destroy();
  656. return false;
  657. }
  658. #if WASM_ENABLE_DEBUG_INTERP != 0
  659. if (strlen(init_args->ip_addr))
  660. if (!wasm_debug_engine_init(init_args->ip_addr,
  661. init_args->instance_port)) {
  662. wasm_runtime_destroy();
  663. return false;
  664. }
  665. #endif
  666. if (init_args->n_native_symbols > 0
  667. && !wasm_runtime_register_natives(init_args->native_module_name,
  668. init_args->native_symbols,
  669. init_args->n_native_symbols)) {
  670. wasm_runtime_destroy();
  671. return false;
  672. }
  673. #if WASM_ENABLE_THREAD_MGR != 0
  674. wasm_cluster_set_max_thread_num(init_args->max_thread_num);
  675. #endif
  676. return true;
  677. }
  678. bool
  679. wasm_runtime_full_init(RuntimeInitArgs *init_args)
  680. {
  681. bool ret = true;
  682. #if defined(OS_THREAD_MUTEX_INITIALIZER)
  683. os_mutex_lock(&runtime_lock);
  684. #endif
  685. bh_assert(runtime_ref_count >= 0);
  686. if (runtime_ref_count == 0) {
  687. ret = wasm_runtime_full_init_internal(init_args);
  688. }
  689. if (ret) {
  690. runtime_ref_count++;
  691. }
  692. #if defined(OS_THREAD_MUTEX_INITIALIZER)
  693. os_mutex_unlock(&runtime_lock);
  694. #endif
  695. return ret;
  696. }
  697. void
  698. wasm_runtime_set_log_level(log_level_t level)
  699. {
  700. bh_log_set_verbose_level(level);
  701. }
  702. bool
  703. wasm_runtime_is_running_mode_supported(RunningMode running_mode)
  704. {
  705. if (running_mode == Mode_Default) {
  706. return true;
  707. }
  708. else if (running_mode == Mode_Interp) {
  709. #if WASM_ENABLE_INTERP != 0
  710. return true;
  711. #endif
  712. }
  713. else if (running_mode == Mode_Fast_JIT) {
  714. #if WASM_ENABLE_FAST_JIT != 0
  715. return true;
  716. #endif
  717. }
  718. else if (running_mode == Mode_LLVM_JIT) {
  719. #if WASM_ENABLE_JIT != 0
  720. return true;
  721. #endif
  722. }
  723. else if (running_mode == Mode_Multi_Tier_JIT) {
  724. #if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \
  725. && WASM_ENABLE_LAZY_JIT != 0
  726. return true;
  727. #endif
  728. }
  729. return false;
  730. }
  731. bool
  732. wasm_runtime_set_default_running_mode(RunningMode running_mode)
  733. {
  734. if (wasm_runtime_is_running_mode_supported(running_mode)) {
  735. runtime_running_mode = running_mode;
  736. return true;
  737. }
  738. return false;
  739. }
  740. PackageType
  741. get_package_type(const uint8 *buf, uint32 size)
  742. {
  743. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  744. uint32 buf32 = *(uint32 *)buf;
  745. buf = (const uint8 *)&buf32;
  746. #endif
  747. if (buf && size >= 4) {
  748. if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 's' && buf[3] == 'm')
  749. return Wasm_Module_Bytecode;
  750. if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 'o' && buf[3] == 't')
  751. return Wasm_Module_AoT;
  752. }
  753. return Package_Type_Unknown;
  754. }
  755. #if WASM_ENABLE_AOT != 0
  756. static uint8 *
  757. align_ptr(const uint8 *p, uint32 b)
  758. {
  759. uintptr_t v = (uintptr_t)p;
  760. uintptr_t m = b - 1;
  761. return (uint8 *)((v + m) & ~m);
  762. }
  763. #define CHECK_BUF(buf, buf_end, length) \
  764. do { \
  765. if ((uintptr_t)buf + length < (uintptr_t)buf \
  766. || (uintptr_t)buf + length > (uintptr_t)buf_end) \
  767. return false; \
  768. } while (0)
  769. /* NOLINTNEXTLINE */
  770. #define read_uint16(p, p_end, res) \
  771. do { \
  772. p = (uint8 *)align_ptr(p, sizeof(uint16)); \
  773. CHECK_BUF(p, p_end, sizeof(uint16)); \
  774. res = *(uint16 *)p; \
  775. p += sizeof(uint16); \
  776. } while (0)
  777. /* NOLINTNEXTLINE */
  778. #define read_uint32(p, p_end, res) \
  779. do { \
  780. p = (uint8 *)align_ptr(p, sizeof(uint32)); \
  781. CHECK_BUF(p, p_end, sizeof(uint32)); \
  782. res = *(uint32 *)p; \
  783. p += sizeof(uint32); \
  784. } while (0)
  785. bool
  786. wasm_runtime_is_xip_file(const uint8 *buf, uint32 size)
  787. {
  788. const uint8 *p = buf, *p_end = buf + size;
  789. uint32 section_type, section_size;
  790. uint16 e_type;
  791. if (get_package_type(buf, size) != Wasm_Module_AoT)
  792. return false;
  793. CHECK_BUF(p, p_end, 8);
  794. p += 8;
  795. while (p < p_end) {
  796. read_uint32(p, p_end, section_type);
  797. read_uint32(p, p_end, section_size);
  798. CHECK_BUF(p, p_end, section_size);
  799. if (section_type == AOT_SECTION_TYPE_TARGET_INFO) {
  800. p += 4;
  801. read_uint16(p, p_end, e_type);
  802. return (e_type == E_TYPE_XIP) ? true : false;
  803. }
  804. else if (section_type >= AOT_SECTION_TYPE_SIGNATURE) {
  805. return false;
  806. }
  807. p += section_size;
  808. }
  809. return false;
  810. }
  811. #endif /* end of WASM_ENABLE_AOT */
  812. #if (WASM_ENABLE_THREAD_MGR != 0) && (WASM_ENABLE_DEBUG_INTERP != 0)
  813. uint32
  814. wasm_runtime_start_debug_instance_with_port(WASMExecEnv *exec_env, int32_t port)
  815. {
  816. WASMModuleInstanceCommon *module_inst =
  817. wasm_runtime_get_module_inst(exec_env);
  818. WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
  819. bh_assert(module_inst);
  820. bh_assert(cluster);
  821. if (module_inst->module_type != Wasm_Module_Bytecode) {
  822. LOG_WARNING("Attempt to create a debug instance for an AOT module");
  823. return 0;
  824. }
  825. if (cluster->debug_inst) {
  826. LOG_WARNING("Cluster already bind to a debug instance");
  827. return cluster->debug_inst->control_thread->port;
  828. }
  829. if (wasm_debug_instance_create(cluster, port)) {
  830. return cluster->debug_inst->control_thread->port;
  831. }
  832. return 0;
  833. }
  834. uint32
  835. wasm_runtime_start_debug_instance(WASMExecEnv *exec_env)
  836. {
  837. return wasm_runtime_start_debug_instance_with_port(exec_env, -1);
  838. }
  839. #endif
  840. #if WASM_ENABLE_MULTI_MODULE != 0
  841. static module_reader reader;
  842. static module_destroyer destroyer;
  843. void
  844. wasm_runtime_set_module_reader(const module_reader reader_cb,
  845. const module_destroyer destroyer_cb)
  846. {
  847. reader = reader_cb;
  848. destroyer = destroyer_cb;
  849. }
  850. module_reader
  851. wasm_runtime_get_module_reader()
  852. {
  853. return reader;
  854. }
  855. module_destroyer
  856. wasm_runtime_get_module_destroyer()
  857. {
  858. return destroyer;
  859. }
  860. static WASMRegisteredModule *
  861. wasm_runtime_find_module_registered_by_reference(WASMModuleCommon *module)
  862. {
  863. WASMRegisteredModule *reg_module = NULL;
  864. os_mutex_lock(&registered_module_list_lock);
  865. reg_module = bh_list_first_elem(registered_module_list);
  866. while (reg_module && module != reg_module->module) {
  867. reg_module = bh_list_elem_next(reg_module);
  868. }
  869. os_mutex_unlock(&registered_module_list_lock);
  870. return reg_module;
  871. }
  872. bool
  873. wasm_runtime_register_module_internal(const char *module_name,
  874. WASMModuleCommon *module,
  875. uint8 *orig_file_buf,
  876. uint32 orig_file_buf_size,
  877. char *error_buf, uint32 error_buf_size)
  878. {
  879. WASMRegisteredModule *node = NULL;
  880. node = wasm_runtime_find_module_registered_by_reference(module);
  881. if (node) { /* module has been registered */
  882. if (node->module_name) { /* module has name */
  883. if (!module_name || strcmp(node->module_name, module_name)) {
  884. /* module has different name */
  885. LOG_DEBUG("module(%p) has been registered with name %s", module,
  886. node->module_name);
  887. set_error_buf(error_buf, error_buf_size,
  888. "Register module failed: "
  889. "failed to rename the module");
  890. return false;
  891. }
  892. else {
  893. /* module has the same name */
  894. LOG_DEBUG(
  895. "module(%p) has been registered with the same name %s",
  896. module, node->module_name);
  897. return true;
  898. }
  899. }
  900. else {
  901. /* module has empty name, reset it */
  902. node->module_name = module_name;
  903. return true;
  904. }
  905. }
  906. /* module hasn't been registered */
  907. node = runtime_malloc(sizeof(WASMRegisteredModule), NULL, NULL, 0);
  908. if (!node) {
  909. LOG_DEBUG("malloc WASMRegisteredModule failed. SZ=%zu",
  910. sizeof(WASMRegisteredModule));
  911. return false;
  912. }
  913. /* share the string and the module */
  914. node->module_name = module_name;
  915. node->module = module;
  916. node->orig_file_buf = orig_file_buf;
  917. node->orig_file_buf_size = orig_file_buf_size;
  918. os_mutex_lock(&registered_module_list_lock);
  919. bh_list_status ret = bh_list_insert(registered_module_list, node);
  920. bh_assert(BH_LIST_SUCCESS == ret);
  921. (void)ret;
  922. os_mutex_unlock(&registered_module_list_lock);
  923. return true;
  924. }
  925. bool
  926. wasm_runtime_register_module(const char *module_name, WASMModuleCommon *module,
  927. char *error_buf, uint32 error_buf_size)
  928. {
  929. if (!error_buf || !error_buf_size) {
  930. LOG_ERROR("error buffer is required");
  931. return false;
  932. }
  933. if (!module_name || !module) {
  934. LOG_DEBUG("module_name and module are required");
  935. set_error_buf(error_buf, error_buf_size,
  936. "Register module failed: "
  937. "module_name and module are required");
  938. return false;
  939. }
  940. if (wasm_runtime_is_built_in_module(module_name)) {
  941. LOG_DEBUG("%s is a built-in module name", module_name);
  942. set_error_buf(error_buf, error_buf_size,
  943. "Register module failed: "
  944. "can not register as a built-in module");
  945. return false;
  946. }
  947. return wasm_runtime_register_module_internal(module_name, module, NULL, 0,
  948. error_buf, error_buf_size);
  949. }
  950. void
  951. wasm_runtime_unregister_module(const WASMModuleCommon *module)
  952. {
  953. WASMRegisteredModule *registered_module = NULL;
  954. os_mutex_lock(&registered_module_list_lock);
  955. registered_module = bh_list_first_elem(registered_module_list);
  956. while (registered_module && module != registered_module->module) {
  957. registered_module = bh_list_elem_next(registered_module);
  958. }
  959. /* it does not matter if it is not exist. after all, it is gone */
  960. if (registered_module) {
  961. bh_list_remove(registered_module_list, registered_module);
  962. wasm_runtime_free(registered_module);
  963. }
  964. os_mutex_unlock(&registered_module_list_lock);
  965. }
  966. WASMModuleCommon *
  967. wasm_runtime_find_module_registered(const char *module_name)
  968. {
  969. WASMRegisteredModule *module = NULL, *module_next;
  970. os_mutex_lock(&registered_module_list_lock);
  971. module = bh_list_first_elem(registered_module_list);
  972. while (module) {
  973. module_next = bh_list_elem_next(module);
  974. if (module->module_name && !strcmp(module_name, module->module_name)) {
  975. break;
  976. }
  977. module = module_next;
  978. }
  979. os_mutex_unlock(&registered_module_list_lock);
  980. return module ? module->module : NULL;
  981. }
  982. /*
  983. * simply destroy all
  984. */
  985. static void
  986. wasm_runtime_destroy_registered_module_list()
  987. {
  988. WASMRegisteredModule *reg_module = NULL;
  989. os_mutex_lock(&registered_module_list_lock);
  990. reg_module = bh_list_first_elem(registered_module_list);
  991. while (reg_module) {
  992. WASMRegisteredModule *next_reg_module = bh_list_elem_next(reg_module);
  993. bh_list_remove(registered_module_list, reg_module);
  994. /* now, it is time to release every module in the runtime */
  995. if (reg_module->module->module_type == Wasm_Module_Bytecode) {
  996. #if WASM_ENABLE_INTERP != 0
  997. wasm_unload((WASMModule *)reg_module->module);
  998. #endif
  999. }
  1000. else {
  1001. #if WASM_ENABLE_AOT != 0
  1002. aot_unload((AOTModule *)reg_module->module);
  1003. #endif
  1004. }
  1005. /* destroy the file buffer */
  1006. if (destroyer && reg_module->orig_file_buf) {
  1007. destroyer(reg_module->orig_file_buf,
  1008. reg_module->orig_file_buf_size);
  1009. reg_module->orig_file_buf = NULL;
  1010. reg_module->orig_file_buf_size = 0;
  1011. }
  1012. wasm_runtime_free(reg_module);
  1013. reg_module = next_reg_module;
  1014. }
  1015. os_mutex_unlock(&registered_module_list_lock);
  1016. }
  1017. bool
  1018. wasm_runtime_add_loading_module(const char *module_name, char *error_buf,
  1019. uint32 error_buf_size)
  1020. {
  1021. LOG_DEBUG("add %s into a loading list", module_name);
  1022. LoadingModule *loadingModule =
  1023. runtime_malloc(sizeof(LoadingModule), NULL, error_buf, error_buf_size);
  1024. if (!loadingModule) {
  1025. return false;
  1026. }
  1027. /* share the incoming string */
  1028. loadingModule->module_name = module_name;
  1029. os_mutex_lock(&loading_module_list_lock);
  1030. bh_list_status ret = bh_list_insert(loading_module_list, loadingModule);
  1031. bh_assert(BH_LIST_SUCCESS == ret);
  1032. (void)ret;
  1033. os_mutex_unlock(&loading_module_list_lock);
  1034. return true;
  1035. }
  1036. void
  1037. wasm_runtime_delete_loading_module(const char *module_name)
  1038. {
  1039. LOG_DEBUG("delete %s from a loading list", module_name);
  1040. LoadingModule *module = NULL;
  1041. os_mutex_lock(&loading_module_list_lock);
  1042. module = bh_list_first_elem(loading_module_list);
  1043. while (module && strcmp(module->module_name, module_name)) {
  1044. module = bh_list_elem_next(module);
  1045. }
  1046. /* it does not matter if it is not exist. after all, it is gone */
  1047. if (module) {
  1048. bh_list_remove(loading_module_list, module);
  1049. wasm_runtime_free(module);
  1050. }
  1051. os_mutex_unlock(&loading_module_list_lock);
  1052. }
  1053. bool
  1054. wasm_runtime_is_loading_module(const char *module_name)
  1055. {
  1056. LOG_DEBUG("find %s in a loading list", module_name);
  1057. LoadingModule *module = NULL;
  1058. os_mutex_lock(&loading_module_list_lock);
  1059. module = bh_list_first_elem(loading_module_list);
  1060. while (module && strcmp(module_name, module->module_name)) {
  1061. module = bh_list_elem_next(module);
  1062. }
  1063. os_mutex_unlock(&loading_module_list_lock);
  1064. return module != NULL;
  1065. }
  1066. void
  1067. wasm_runtime_destroy_loading_module_list()
  1068. {
  1069. LoadingModule *module = NULL;
  1070. os_mutex_lock(&loading_module_list_lock);
  1071. module = bh_list_first_elem(loading_module_list);
  1072. while (module) {
  1073. LoadingModule *next_module = bh_list_elem_next(module);
  1074. bh_list_remove(loading_module_list, module);
  1075. /*
  1076. * will not free the module_name since it is
  1077. * shared one of the const string pool
  1078. */
  1079. wasm_runtime_free(module);
  1080. module = next_module;
  1081. }
  1082. os_mutex_unlock(&loading_module_list_lock);
  1083. }
  1084. #endif /* WASM_ENABLE_MULTI_MODULE */
  1085. bool
  1086. wasm_runtime_is_built_in_module(const char *module_name)
  1087. {
  1088. return (!strcmp("env", module_name) || !strcmp("wasi_unstable", module_name)
  1089. || !strcmp("wasi_snapshot_preview1", module_name)
  1090. #if WASM_ENABLE_SPEC_TEST != 0
  1091. || !strcmp("spectest", module_name)
  1092. #endif
  1093. || !strcmp("", module_name));
  1094. }
  1095. #if WASM_ENABLE_THREAD_MGR != 0
  1096. bool
  1097. wasm_exec_env_set_aux_stack(WASMExecEnv *exec_env, uint64 start_offset,
  1098. uint32 size)
  1099. {
  1100. WASMModuleInstanceCommon *module_inst =
  1101. wasm_exec_env_get_module_inst(exec_env);
  1102. #if WASM_ENABLE_INTERP != 0
  1103. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1104. return wasm_set_aux_stack(exec_env, start_offset, size);
  1105. }
  1106. #endif
  1107. #if WASM_ENABLE_AOT != 0
  1108. if (module_inst->module_type == Wasm_Module_AoT) {
  1109. return aot_set_aux_stack(exec_env, start_offset, size);
  1110. }
  1111. #endif
  1112. return false;
  1113. }
  1114. bool
  1115. wasm_exec_env_get_aux_stack(WASMExecEnv *exec_env, uint64 *start_offset,
  1116. uint32 *size)
  1117. {
  1118. WASMModuleInstanceCommon *module_inst =
  1119. wasm_exec_env_get_module_inst(exec_env);
  1120. #if WASM_ENABLE_INTERP != 0
  1121. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1122. return wasm_get_aux_stack(exec_env, start_offset, size);
  1123. }
  1124. #endif
  1125. #if WASM_ENABLE_AOT != 0
  1126. if (module_inst->module_type == Wasm_Module_AoT) {
  1127. return aot_get_aux_stack(exec_env, start_offset, size);
  1128. }
  1129. #endif
  1130. return false;
  1131. }
  1132. void
  1133. wasm_runtime_set_max_thread_num(uint32 num)
  1134. {
  1135. wasm_cluster_set_max_thread_num(num);
  1136. }
  1137. #endif /* end of WASM_ENABLE_THREAD_MGR */
  1138. static WASMModuleCommon *
  1139. register_module_with_null_name(WASMModuleCommon *module_common, char *error_buf,
  1140. uint32 error_buf_size)
  1141. {
  1142. #if WASM_ENABLE_MULTI_MODULE != 0
  1143. if (module_common) {
  1144. if (!wasm_runtime_register_module_internal(NULL, module_common, NULL, 0,
  1145. error_buf, error_buf_size)) {
  1146. wasm_runtime_unload(module_common);
  1147. return NULL;
  1148. }
  1149. return module_common;
  1150. }
  1151. else
  1152. return NULL;
  1153. #else
  1154. return module_common;
  1155. #endif
  1156. }
  1157. WASMModuleCommon *
  1158. wasm_runtime_load_ex(uint8 *buf, uint32 size, const LoadArgs *args,
  1159. char *error_buf, uint32 error_buf_size)
  1160. {
  1161. WASMModuleCommon *module_common = NULL;
  1162. if (!args) {
  1163. return NULL;
  1164. }
  1165. if (get_package_type(buf, size) == Wasm_Module_Bytecode) {
  1166. #if WASM_ENABLE_INTERP != 0
  1167. module_common =
  1168. (WASMModuleCommon *)wasm_load(buf, size,
  1169. #if WASM_ENABLE_MULTI_MODULE != 0
  1170. true,
  1171. #endif
  1172. args, error_buf, error_buf_size);
  1173. #endif
  1174. }
  1175. else if (get_package_type(buf, size) == Wasm_Module_AoT) {
  1176. #if WASM_ENABLE_AOT != 0
  1177. module_common = (WASMModuleCommon *)aot_load_from_aot_file(
  1178. buf, size, args, error_buf, error_buf_size);
  1179. #endif
  1180. }
  1181. else {
  1182. if (size < 4)
  1183. set_error_buf(error_buf, error_buf_size,
  1184. "WASM module load failed: unexpected end");
  1185. else
  1186. set_error_buf(error_buf, error_buf_size,
  1187. "WASM module load failed: magic header not detected");
  1188. return NULL;
  1189. }
  1190. if (!module_common) {
  1191. LOG_DEBUG("WASM module load failed");
  1192. return NULL;
  1193. }
  1194. /*TODO: use file name as name and register with name? */
  1195. return register_module_with_null_name(module_common, error_buf,
  1196. error_buf_size);
  1197. }
  1198. WASMModuleCommon *
  1199. wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
  1200. uint32 error_buf_size)
  1201. {
  1202. LoadArgs args = { 0 };
  1203. args.name = "";
  1204. return wasm_runtime_load_ex(buf, size, &args, error_buf, error_buf_size);
  1205. }
  1206. WASMModuleCommon *
  1207. wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
  1208. char *error_buf, uint32 error_buf_size)
  1209. {
  1210. WASMModuleCommon *module_common;
  1211. if (!is_aot) {
  1212. #if WASM_ENABLE_INTERP != 0
  1213. module_common = (WASMModuleCommon *)wasm_load_from_sections(
  1214. section_list, error_buf, error_buf_size);
  1215. if (!module_common) {
  1216. LOG_DEBUG("WASM module load failed from sections");
  1217. return NULL;
  1218. }
  1219. return register_module_with_null_name(module_common, error_buf,
  1220. error_buf_size);
  1221. #endif
  1222. }
  1223. else {
  1224. #if WASM_ENABLE_AOT != 0
  1225. module_common = (WASMModuleCommon *)aot_load_from_sections(
  1226. section_list, error_buf, error_buf_size);
  1227. if (!module_common) {
  1228. LOG_DEBUG("WASM module load failed from sections");
  1229. return NULL;
  1230. }
  1231. return register_module_with_null_name(module_common, error_buf,
  1232. error_buf_size);
  1233. #endif
  1234. }
  1235. #if WASM_ENABLE_INTERP == 0 || WASM_ENABLE_AOT == 0
  1236. set_error_buf(error_buf, error_buf_size,
  1237. "WASM module load failed: invalid section list type");
  1238. return NULL;
  1239. #endif
  1240. }
  1241. void
  1242. wasm_runtime_unload(WASMModuleCommon *module)
  1243. {
  1244. #if WASM_ENABLE_MULTI_MODULE != 0
  1245. /**
  1246. * since we will unload and free all module when runtime_destroy()
  1247. * we don't want users to unwillingly disrupt it
  1248. */
  1249. return;
  1250. #endif
  1251. #if WASM_ENABLE_INTERP != 0
  1252. if (module->module_type == Wasm_Module_Bytecode) {
  1253. wasm_unload((WASMModule *)module);
  1254. return;
  1255. }
  1256. #endif
  1257. #if WASM_ENABLE_AOT != 0
  1258. if (module->module_type == Wasm_Module_AoT) {
  1259. aot_unload((AOTModule *)module);
  1260. return;
  1261. }
  1262. #endif
  1263. }
  1264. uint32
  1265. wasm_runtime_get_max_mem(uint32 max_memory_pages, uint32 module_init_page_count,
  1266. uint32 module_max_page_count)
  1267. {
  1268. if (max_memory_pages == 0) {
  1269. /* Max memory not overwritten by runtime, use value from wasm module */
  1270. return module_max_page_count;
  1271. }
  1272. if (max_memory_pages < module_init_page_count) {
  1273. LOG_WARNING("Cannot override max memory with value lower than module "
  1274. "initial memory");
  1275. return module_init_page_count;
  1276. }
  1277. if (max_memory_pages > module_max_page_count) {
  1278. LOG_WARNING("Cannot override max memory with value greater than module "
  1279. "max memory");
  1280. return module_max_page_count;
  1281. }
  1282. return max_memory_pages;
  1283. }
  1284. WASMModuleInstanceCommon *
  1285. wasm_runtime_instantiate_internal(WASMModuleCommon *module,
  1286. WASMModuleInstanceCommon *parent,
  1287. WASMExecEnv *exec_env_main, uint32 stack_size,
  1288. uint32 heap_size, uint32 max_memory_pages,
  1289. char *error_buf, uint32 error_buf_size)
  1290. {
  1291. #if WASM_ENABLE_INTERP != 0
  1292. if (module->module_type == Wasm_Module_Bytecode)
  1293. return (WASMModuleInstanceCommon *)wasm_instantiate(
  1294. (WASMModule *)module, (WASMModuleInstance *)parent, exec_env_main,
  1295. stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
  1296. #endif
  1297. #if WASM_ENABLE_AOT != 0
  1298. if (module->module_type == Wasm_Module_AoT)
  1299. return (WASMModuleInstanceCommon *)aot_instantiate(
  1300. (AOTModule *)module, (AOTModuleInstance *)parent, exec_env_main,
  1301. stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
  1302. #endif
  1303. set_error_buf(error_buf, error_buf_size,
  1304. "Instantiate module failed, invalid module type");
  1305. return NULL;
  1306. }
  1307. WASMModuleInstanceCommon *
  1308. wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
  1309. uint32 heap_size, char *error_buf,
  1310. uint32 error_buf_size)
  1311. {
  1312. return wasm_runtime_instantiate_internal(module, NULL, NULL, stack_size,
  1313. heap_size, 0, error_buf,
  1314. error_buf_size);
  1315. }
  1316. WASMModuleInstanceCommon *
  1317. wasm_runtime_instantiate_ex(WASMModuleCommon *module,
  1318. const InstantiationArgs *args, char *error_buf,
  1319. uint32 error_buf_size)
  1320. {
  1321. return wasm_runtime_instantiate_internal(
  1322. module, NULL, NULL, args->default_stack_size,
  1323. args->host_managed_heap_size, args->max_memory_pages, error_buf,
  1324. error_buf_size);
  1325. }
  1326. void
  1327. wasm_runtime_deinstantiate_internal(WASMModuleInstanceCommon *module_inst,
  1328. bool is_sub_inst)
  1329. {
  1330. #if WASM_ENABLE_INTERP != 0
  1331. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1332. wasm_deinstantiate((WASMModuleInstance *)module_inst, is_sub_inst);
  1333. return;
  1334. }
  1335. #endif
  1336. #if WASM_ENABLE_AOT != 0
  1337. if (module_inst->module_type == Wasm_Module_AoT) {
  1338. aot_deinstantiate((AOTModuleInstance *)module_inst, is_sub_inst);
  1339. return;
  1340. }
  1341. #endif
  1342. }
  1343. bool
  1344. wasm_runtime_set_running_mode(wasm_module_inst_t module_inst,
  1345. RunningMode running_mode)
  1346. {
  1347. #if WASM_ENABLE_AOT != 0
  1348. if (module_inst->module_type == Wasm_Module_AoT)
  1349. return true;
  1350. #endif
  1351. #if WASM_ENABLE_INTERP != 0
  1352. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1353. WASMModuleInstance *module_inst_interp =
  1354. (WASMModuleInstance *)module_inst;
  1355. return wasm_set_running_mode(module_inst_interp, running_mode);
  1356. }
  1357. #endif
  1358. return false;
  1359. }
  1360. RunningMode
  1361. wasm_runtime_get_running_mode(wasm_module_inst_t module_inst)
  1362. {
  1363. #if WASM_ENABLE_INTERP != 0
  1364. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1365. WASMModuleInstance *module_inst_interp =
  1366. (WASMModuleInstance *)module_inst;
  1367. return module_inst_interp->e->running_mode;
  1368. }
  1369. #endif
  1370. return Mode_Default;
  1371. }
  1372. void
  1373. wasm_runtime_deinstantiate(WASMModuleInstanceCommon *module_inst)
  1374. {
  1375. wasm_runtime_deinstantiate_internal(module_inst, false);
  1376. }
  1377. WASMModuleCommon *
  1378. wasm_runtime_get_module(WASMModuleInstanceCommon *module_inst)
  1379. {
  1380. return (WASMModuleCommon *)((WASMModuleInstance *)module_inst)->module;
  1381. }
  1382. WASMExecEnv *
  1383. wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst,
  1384. uint32 stack_size)
  1385. {
  1386. return wasm_exec_env_create(module_inst, stack_size);
  1387. }
  1388. void
  1389. wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env)
  1390. {
  1391. wasm_exec_env_destroy(exec_env);
  1392. }
  1393. bool
  1394. wasm_runtime_init_thread_env(void)
  1395. {
  1396. #ifdef BH_PLATFORM_WINDOWS
  1397. if (os_thread_env_init() != 0)
  1398. return false;
  1399. #endif
  1400. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1401. if (!runtime_signal_init()) {
  1402. #ifdef BH_PLATFORM_WINDOWS
  1403. os_thread_env_destroy();
  1404. #endif
  1405. return false;
  1406. }
  1407. #endif
  1408. #if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
  1409. os_end_blocking_op();
  1410. #endif
  1411. return true;
  1412. }
  1413. void
  1414. wasm_runtime_destroy_thread_env(void)
  1415. {
  1416. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1417. runtime_signal_destroy();
  1418. #endif
  1419. #ifdef BH_PLATFORM_WINDOWS
  1420. os_thread_env_destroy();
  1421. #endif
  1422. }
  1423. bool
  1424. wasm_runtime_thread_env_inited(void)
  1425. {
  1426. #ifdef BH_PLATFORM_WINDOWS
  1427. if (!os_thread_env_inited())
  1428. return false;
  1429. #endif
  1430. #if WASM_ENABLE_AOT != 0
  1431. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1432. if (!os_thread_signal_inited())
  1433. return false;
  1434. #endif
  1435. #endif
  1436. return true;
  1437. }
  1438. #if (WASM_ENABLE_MEMORY_PROFILING != 0) || (WASM_ENABLE_MEMORY_TRACING != 0)
  1439. void
  1440. wasm_runtime_dump_module_mem_consumption(const WASMModuleCommon *module)
  1441. {
  1442. WASMModuleMemConsumption mem_conspn = { 0 };
  1443. #if WASM_ENABLE_INTERP != 0
  1444. if (module->module_type == Wasm_Module_Bytecode) {
  1445. wasm_get_module_mem_consumption((WASMModule *)module, &mem_conspn);
  1446. }
  1447. #endif
  1448. #if WASM_ENABLE_AOT != 0
  1449. if (module->module_type == Wasm_Module_AoT) {
  1450. aot_get_module_mem_consumption((AOTModule *)module, &mem_conspn);
  1451. }
  1452. #endif
  1453. os_printf("WASM module memory consumption, total size: %u\n",
  1454. mem_conspn.total_size);
  1455. os_printf(" module struct size: %u\n", mem_conspn.module_struct_size);
  1456. os_printf(" types size: %u\n", mem_conspn.types_size);
  1457. os_printf(" imports size: %u\n", mem_conspn.imports_size);
  1458. os_printf(" funcs size: %u\n", mem_conspn.functions_size);
  1459. os_printf(" tables size: %u\n", mem_conspn.tables_size);
  1460. os_printf(" memories size: %u\n", mem_conspn.memories_size);
  1461. os_printf(" globals size: %u\n", mem_conspn.globals_size);
  1462. os_printf(" exports size: %u\n", mem_conspn.exports_size);
  1463. os_printf(" table segs size: %u\n", mem_conspn.table_segs_size);
  1464. os_printf(" data segs size: %u\n", mem_conspn.data_segs_size);
  1465. os_printf(" const strings size: %u\n", mem_conspn.const_strs_size);
  1466. #if WASM_ENABLE_AOT != 0
  1467. os_printf(" aot code size: %u\n", mem_conspn.aot_code_size);
  1468. #endif
  1469. }
  1470. void
  1471. wasm_runtime_dump_module_inst_mem_consumption(
  1472. const WASMModuleInstanceCommon *module_inst)
  1473. {
  1474. WASMModuleInstMemConsumption mem_conspn = { 0 };
  1475. #if WASM_ENABLE_INTERP != 0
  1476. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1477. wasm_get_module_inst_mem_consumption((WASMModuleInstance *)module_inst,
  1478. &mem_conspn);
  1479. }
  1480. #endif
  1481. #if WASM_ENABLE_AOT != 0
  1482. if (module_inst->module_type == Wasm_Module_AoT) {
  1483. aot_get_module_inst_mem_consumption((AOTModuleInstance *)module_inst,
  1484. &mem_conspn);
  1485. }
  1486. #endif
  1487. os_printf("WASM module inst memory consumption, total size: %lu\n",
  1488. mem_conspn.total_size);
  1489. os_printf(" module inst struct size: %u\n",
  1490. mem_conspn.module_inst_struct_size);
  1491. os_printf(" memories size: %lu\n", mem_conspn.memories_size);
  1492. os_printf(" app heap size: %u\n", mem_conspn.app_heap_size);
  1493. os_printf(" tables size: %u\n", mem_conspn.tables_size);
  1494. os_printf(" functions size: %u\n", mem_conspn.functions_size);
  1495. os_printf(" globals size: %u\n", mem_conspn.globals_size);
  1496. os_printf(" exports size: %u\n", mem_conspn.exports_size);
  1497. }
  1498. void
  1499. wasm_runtime_dump_exec_env_mem_consumption(const WASMExecEnv *exec_env)
  1500. {
  1501. uint32 total_size =
  1502. offsetof(WASMExecEnv, wasm_stack_u.bottom) + exec_env->wasm_stack_size;
  1503. os_printf("Exec env memory consumption, total size: %u\n", total_size);
  1504. os_printf(" exec env struct size: %u\n",
  1505. offsetof(WASMExecEnv, wasm_stack_u.bottom));
  1506. #if WASM_ENABLE_INTERP != 0 && WASM_ENABLE_FAST_INTERP == 0
  1507. os_printf(" block addr cache size: %u\n",
  1508. sizeof(exec_env->block_addr_cache));
  1509. #endif
  1510. os_printf(" stack size: %u\n", exec_env->wasm_stack_size);
  1511. }
  1512. uint32
  1513. gc_get_heap_highmark_size(void *heap);
  1514. void
  1515. wasm_runtime_dump_mem_consumption(WASMExecEnv *exec_env)
  1516. {
  1517. WASMModuleInstMemConsumption module_inst_mem_consps;
  1518. WASMModuleMemConsumption module_mem_consps;
  1519. WASMModuleInstanceCommon *module_inst_common;
  1520. WASMModuleCommon *module_common = NULL;
  1521. void *heap_handle = NULL;
  1522. uint32 app_heap_peak_size = 0;
  1523. uint32 max_aux_stack_used = -1;
  1524. uint64 total_size = 0;
  1525. module_inst_common = exec_env->module_inst;
  1526. #if WASM_ENABLE_INTERP != 0
  1527. if (module_inst_common->module_type == Wasm_Module_Bytecode) {
  1528. WASMModuleInstance *wasm_module_inst =
  1529. (WASMModuleInstance *)module_inst_common;
  1530. WASMModule *wasm_module = wasm_module_inst->module;
  1531. module_common = (WASMModuleCommon *)wasm_module;
  1532. if (wasm_module_inst->memories) {
  1533. heap_handle = wasm_module_inst->memories[0]->heap_handle;
  1534. }
  1535. wasm_get_module_inst_mem_consumption(wasm_module_inst,
  1536. &module_inst_mem_consps);
  1537. wasm_get_module_mem_consumption(wasm_module, &module_mem_consps);
  1538. if (wasm_module_inst->module->aux_stack_top_global_index != (uint32)-1)
  1539. max_aux_stack_used = wasm_module_inst->e->max_aux_stack_used;
  1540. }
  1541. #endif
  1542. #if WASM_ENABLE_AOT != 0
  1543. if (module_inst_common->module_type == Wasm_Module_AoT) {
  1544. AOTModuleInstance *aot_module_inst =
  1545. (AOTModuleInstance *)module_inst_common;
  1546. AOTModule *aot_module = (AOTModule *)aot_module_inst->module;
  1547. module_common = (WASMModuleCommon *)aot_module;
  1548. if (aot_module_inst->memories) {
  1549. AOTMemoryInstance **memories = aot_module_inst->memories;
  1550. heap_handle = memories[0]->heap_handle;
  1551. }
  1552. aot_get_module_inst_mem_consumption(aot_module_inst,
  1553. &module_inst_mem_consps);
  1554. aot_get_module_mem_consumption(aot_module, &module_mem_consps);
  1555. }
  1556. #endif
  1557. bh_assert(module_common != NULL);
  1558. if (heap_handle) {
  1559. app_heap_peak_size = gc_get_heap_highmark_size(heap_handle);
  1560. }
  1561. total_size = offsetof(WASMExecEnv, wasm_stack_u.bottom)
  1562. + exec_env->wasm_stack_size + module_mem_consps.total_size
  1563. + module_inst_mem_consps.total_size;
  1564. os_printf("\nMemory consumption summary (bytes):\n");
  1565. wasm_runtime_dump_module_mem_consumption(module_common);
  1566. wasm_runtime_dump_module_inst_mem_consumption(module_inst_common);
  1567. wasm_runtime_dump_exec_env_mem_consumption(exec_env);
  1568. os_printf("\nTotal memory consumption of module, module inst and "
  1569. "exec env: %" PRIu64 "\n",
  1570. total_size);
  1571. os_printf("Total interpreter stack used: %u\n",
  1572. exec_env->max_wasm_stack_used);
  1573. if (max_aux_stack_used != (uint32)-1)
  1574. os_printf("Total auxiliary stack used: %u\n", max_aux_stack_used);
  1575. else
  1576. os_printf("Total aux stack used: no enough info to profile\n");
  1577. /*
  1578. * Report the native stack usage estimation.
  1579. *
  1580. * Unlike the aux stack above, we report the amount unused
  1581. * because we don't know the stack "bottom".
  1582. *
  1583. * Note that this is just about what the runtime itself observed.
  1584. * It doesn't cover host func implementations, signal handlers, etc.
  1585. */
  1586. if (exec_env->native_stack_top_min != (void *)UINTPTR_MAX)
  1587. os_printf("Native stack left: %zd\n",
  1588. exec_env->native_stack_top_min
  1589. - exec_env->native_stack_boundary);
  1590. else
  1591. os_printf("Native stack left: no enough info to profile\n");
  1592. os_printf("Total app heap used: %u\n", app_heap_peak_size);
  1593. }
  1594. #endif /* end of (WASM_ENABLE_MEMORY_PROFILING != 0) \
  1595. || (WASM_ENABLE_MEMORY_TRACING != 0) */
  1596. #if WASM_ENABLE_PERF_PROFILING != 0
  1597. void
  1598. wasm_runtime_dump_perf_profiling(WASMModuleInstanceCommon *module_inst)
  1599. {
  1600. #if WASM_ENABLE_INTERP != 0
  1601. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1602. wasm_dump_perf_profiling((WASMModuleInstance *)module_inst);
  1603. }
  1604. #endif
  1605. #if WASM_ENABLE_AOT != 0
  1606. if (module_inst->module_type == Wasm_Module_AoT) {
  1607. aot_dump_perf_profiling((AOTModuleInstance *)module_inst);
  1608. }
  1609. #endif
  1610. }
  1611. double
  1612. wasm_runtime_sum_wasm_exec_time(WASMModuleInstanceCommon *inst)
  1613. {
  1614. #if WASM_ENABLE_INTERP != 0
  1615. if (inst->module_type == Wasm_Module_Bytecode)
  1616. return wasm_summarize_wasm_execute_time((WASMModuleInstance *)inst);
  1617. #endif
  1618. #if WASM_ENABLE_AOT != 0
  1619. if (inst->module_type == Wasm_Module_AoT)
  1620. return aot_summarize_wasm_execute_time((AOTModuleInstance *)inst);
  1621. #endif
  1622. return 0.0;
  1623. }
  1624. double
  1625. wasm_runtime_get_wasm_func_exec_time(WASMModuleInstanceCommon *inst,
  1626. const char *func_name)
  1627. {
  1628. #if WASM_ENABLE_INTERP != 0
  1629. if (inst->module_type == Wasm_Module_Bytecode)
  1630. return wasm_get_wasm_func_exec_time((WASMModuleInstance *)inst,
  1631. func_name);
  1632. #endif
  1633. #if WASM_ENABLE_AOT != 0
  1634. if (inst->module_type == Wasm_Module_AoT)
  1635. return aot_get_wasm_func_exec_time((AOTModuleInstance *)inst,
  1636. func_name);
  1637. #endif
  1638. return 0.0;
  1639. }
  1640. #endif /* WASM_ENABLE_PERF_PROFILING != 0 */
  1641. WASMModuleInstanceCommon *
  1642. wasm_runtime_get_module_inst(WASMExecEnv *exec_env)
  1643. {
  1644. return wasm_exec_env_get_module_inst(exec_env);
  1645. }
  1646. void
  1647. wasm_runtime_set_module_inst(WASMExecEnv *exec_env,
  1648. WASMModuleInstanceCommon *const module_inst)
  1649. {
  1650. wasm_exec_env_set_module_inst(exec_env, module_inst);
  1651. }
  1652. void *
  1653. wasm_runtime_get_function_attachment(WASMExecEnv *exec_env)
  1654. {
  1655. return exec_env->attachment;
  1656. }
  1657. void
  1658. wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data)
  1659. {
  1660. exec_env->user_data = user_data;
  1661. }
  1662. void *
  1663. wasm_runtime_get_user_data(WASMExecEnv *exec_env)
  1664. {
  1665. return exec_env->user_data;
  1666. }
  1667. #ifdef OS_ENABLE_HW_BOUND_CHECK
  1668. void
  1669. wasm_runtime_access_exce_check_guard_page()
  1670. {
  1671. if (exec_env_tls && exec_env_tls->handle == os_self_thread()) {
  1672. uint32 page_size = os_getpagesize();
  1673. memset(exec_env_tls->exce_check_guard_page, 0, page_size);
  1674. }
  1675. }
  1676. #endif
  1677. WASMFuncType *
  1678. wasm_runtime_get_function_type(const WASMFunctionInstanceCommon *function,
  1679. uint32 module_type)
  1680. {
  1681. WASMFuncType *type = NULL;
  1682. #if WASM_ENABLE_INTERP != 0
  1683. if (module_type == Wasm_Module_Bytecode) {
  1684. WASMFunctionInstance *wasm_func = (WASMFunctionInstance *)function;
  1685. type = wasm_func->is_import_func ? wasm_func->u.func_import->func_type
  1686. : wasm_func->u.func->func_type;
  1687. }
  1688. #endif
  1689. #if WASM_ENABLE_AOT != 0
  1690. if (module_type == Wasm_Module_AoT) {
  1691. AOTFunctionInstance *aot_func = (AOTFunctionInstance *)function;
  1692. type = aot_func->is_import_func ? aot_func->u.func_import->func_type
  1693. : aot_func->u.func.func_type;
  1694. }
  1695. #endif
  1696. return type;
  1697. }
  1698. WASMFunctionInstanceCommon *
  1699. wasm_runtime_lookup_function(WASMModuleInstanceCommon *const module_inst,
  1700. const char *name)
  1701. {
  1702. #if WASM_ENABLE_INTERP != 0
  1703. if (module_inst->module_type == Wasm_Module_Bytecode)
  1704. return (WASMFunctionInstanceCommon *)wasm_lookup_function(
  1705. (const WASMModuleInstance *)module_inst, name);
  1706. #endif
  1707. #if WASM_ENABLE_AOT != 0
  1708. if (module_inst->module_type == Wasm_Module_AoT)
  1709. return (WASMFunctionInstanceCommon *)aot_lookup_function(
  1710. (const AOTModuleInstance *)module_inst, name);
  1711. #endif
  1712. return NULL;
  1713. }
  1714. uint32
  1715. wasm_func_get_param_count(WASMFunctionInstanceCommon *const func_inst,
  1716. WASMModuleInstanceCommon *const module_inst)
  1717. {
  1718. WASMFuncType *type =
  1719. wasm_runtime_get_function_type(func_inst, module_inst->module_type);
  1720. bh_assert(type);
  1721. return type->param_count;
  1722. }
  1723. uint32
  1724. wasm_func_get_result_count(WASMFunctionInstanceCommon *const func_inst,
  1725. WASMModuleInstanceCommon *const module_inst)
  1726. {
  1727. WASMFuncType *type =
  1728. wasm_runtime_get_function_type(func_inst, module_inst->module_type);
  1729. bh_assert(type);
  1730. return type->result_count;
  1731. }
  1732. static uint8
  1733. val_type_to_val_kind(uint8 value_type)
  1734. {
  1735. switch (value_type) {
  1736. case VALUE_TYPE_I32:
  1737. return WASM_I32;
  1738. case VALUE_TYPE_I64:
  1739. return WASM_I64;
  1740. case VALUE_TYPE_F32:
  1741. return WASM_F32;
  1742. case VALUE_TYPE_F64:
  1743. return WASM_F64;
  1744. case VALUE_TYPE_V128:
  1745. return WASM_V128;
  1746. case VALUE_TYPE_FUNCREF:
  1747. return WASM_FUNCREF;
  1748. case VALUE_TYPE_EXTERNREF:
  1749. return WASM_EXTERNREF;
  1750. default:
  1751. bh_assert(0);
  1752. return 0;
  1753. }
  1754. }
  1755. void
  1756. wasm_func_get_param_types(WASMFunctionInstanceCommon *const func_inst,
  1757. WASMModuleInstanceCommon *const module_inst,
  1758. wasm_valkind_t *param_types)
  1759. {
  1760. WASMFuncType *type =
  1761. wasm_runtime_get_function_type(func_inst, module_inst->module_type);
  1762. uint32 i;
  1763. bh_assert(type);
  1764. for (i = 0; i < type->param_count; i++) {
  1765. param_types[i] = val_type_to_val_kind(type->types[i]);
  1766. }
  1767. }
  1768. void
  1769. wasm_func_get_result_types(WASMFunctionInstanceCommon *const func_inst,
  1770. WASMModuleInstanceCommon *const module_inst,
  1771. wasm_valkind_t *result_types)
  1772. {
  1773. WASMFuncType *type =
  1774. wasm_runtime_get_function_type(func_inst, module_inst->module_type);
  1775. uint32 i;
  1776. bh_assert(type);
  1777. for (i = 0; i < type->result_count; i++) {
  1778. result_types[i] =
  1779. val_type_to_val_kind(type->types[type->param_count + i]);
  1780. }
  1781. }
  1782. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  1783. /* (uintptr_t)externref -> (uint32)index */
  1784. /* argv -> *ret_argv */
  1785. static bool
  1786. wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
  1787. WASMFunctionInstanceCommon *function,
  1788. uint32 *argv, uint32 argc, uint32 **ret_argv,
  1789. uint32 *ret_argc_param,
  1790. uint32 *ret_argc_result)
  1791. {
  1792. uint32 *new_argv = NULL, argv_i = 0, new_argv_i = 0, param_i = 0,
  1793. result_i = 0;
  1794. bool need_param_transform = false, need_result_transform = false;
  1795. uint64 size = 0;
  1796. WASMFuncType *func_type = wasm_runtime_get_function_type(
  1797. function, exec_env->module_inst->module_type);
  1798. bh_assert(func_type);
  1799. *ret_argc_param = func_type->param_cell_num;
  1800. *ret_argc_result = func_type->ret_cell_num;
  1801. for (param_i = 0; param_i < func_type->param_count; param_i++) {
  1802. if (VALUE_TYPE_EXTERNREF == func_type->types[param_i]) {
  1803. need_param_transform = true;
  1804. }
  1805. }
  1806. for (result_i = 0; result_i < func_type->result_count; result_i++) {
  1807. if (VALUE_TYPE_EXTERNREF
  1808. == func_type->types[func_type->param_count + result_i]) {
  1809. need_result_transform = true;
  1810. }
  1811. }
  1812. if (!need_param_transform && !need_result_transform) {
  1813. *ret_argv = argv;
  1814. return true;
  1815. }
  1816. if (func_type->param_cell_num >= func_type->ret_cell_num) {
  1817. size = sizeof(uint32) * func_type->param_cell_num;
  1818. }
  1819. else {
  1820. size = sizeof(uint32) * func_type->ret_cell_num;
  1821. }
  1822. if (!(new_argv = runtime_malloc(size, exec_env->module_inst, NULL, 0))) {
  1823. return false;
  1824. }
  1825. if (!need_param_transform) {
  1826. bh_memcpy_s(new_argv, (uint32)size, argv, (uint32)size);
  1827. }
  1828. else {
  1829. for (param_i = 0; param_i < func_type->param_count && argv_i < argc
  1830. && new_argv_i < func_type->param_cell_num;
  1831. param_i++) {
  1832. uint8 param_type = func_type->types[param_i];
  1833. if (VALUE_TYPE_EXTERNREF == param_type) {
  1834. void *externref_obj;
  1835. uint32 externref_index;
  1836. #if UINTPTR_MAX == UINT32_MAX
  1837. externref_obj = (void *)argv[argv_i];
  1838. #else
  1839. union {
  1840. uintptr_t val;
  1841. uint32 parts[2];
  1842. } u;
  1843. u.parts[0] = argv[argv_i];
  1844. u.parts[1] = argv[argv_i + 1];
  1845. externref_obj = (void *)u.val;
  1846. #endif
  1847. if (!wasm_externref_obj2ref(exec_env->module_inst,
  1848. externref_obj, &externref_index)) {
  1849. wasm_runtime_free(new_argv);
  1850. return false;
  1851. }
  1852. new_argv[new_argv_i] = externref_index;
  1853. argv_i += sizeof(uintptr_t) / sizeof(uint32);
  1854. new_argv_i++;
  1855. }
  1856. else {
  1857. uint16 param_cell_num = wasm_value_type_cell_num(param_type);
  1858. uint32 param_size = sizeof(uint32) * param_cell_num;
  1859. bh_memcpy_s(new_argv + new_argv_i, param_size, argv + argv_i,
  1860. param_size);
  1861. argv_i += param_cell_num;
  1862. new_argv_i += param_cell_num;
  1863. }
  1864. }
  1865. }
  1866. *ret_argv = new_argv;
  1867. return true;
  1868. }
  1869. /* (uintptr_t)externref <- (uint32)index */
  1870. /* argv <- new_argv */
  1871. static bool
  1872. wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
  1873. WASMFunctionInstanceCommon *function,
  1874. uint32 *argv, uint32 argc, uint32 *ret_argv)
  1875. {
  1876. uint32 argv_i = 0, result_i = 0, ret_argv_i = 0;
  1877. WASMFuncType *func_type;
  1878. bh_assert((argv && ret_argv) || (argc == 0));
  1879. if (argv == ret_argv) {
  1880. /* no need to transform externref results */
  1881. return true;
  1882. }
  1883. func_type = wasm_runtime_get_function_type(
  1884. function, exec_env->module_inst->module_type);
  1885. bh_assert(func_type);
  1886. for (result_i = 0; result_i < func_type->result_count && argv_i < argc;
  1887. result_i++) {
  1888. uint8 result_type = func_type->types[func_type->param_count + result_i];
  1889. if (result_type == VALUE_TYPE_EXTERNREF) {
  1890. void *externref_obj;
  1891. #if UINTPTR_MAX != UINT32_MAX
  1892. union {
  1893. uintptr_t val;
  1894. uint32 parts[2];
  1895. } u;
  1896. #endif
  1897. if (!wasm_externref_ref2obj(argv[argv_i], &externref_obj)) {
  1898. wasm_runtime_free(argv);
  1899. return false;
  1900. }
  1901. #if UINTPTR_MAX == UINT32_MAX
  1902. ret_argv[ret_argv_i] = (uintptr_t)externref_obj;
  1903. #else
  1904. u.val = (uintptr_t)externref_obj;
  1905. ret_argv[ret_argv_i] = u.parts[0];
  1906. ret_argv[ret_argv_i + 1] = u.parts[1];
  1907. #endif
  1908. argv_i += 1;
  1909. ret_argv_i += sizeof(uintptr_t) / sizeof(uint32);
  1910. }
  1911. else {
  1912. uint16 result_cell_num = wasm_value_type_cell_num(result_type);
  1913. uint32 result_size = sizeof(uint32) * result_cell_num;
  1914. bh_memcpy_s(ret_argv + ret_argv_i, result_size, argv + argv_i,
  1915. result_size);
  1916. argv_i += result_cell_num;
  1917. ret_argv_i += result_cell_num;
  1918. }
  1919. }
  1920. wasm_runtime_free(argv);
  1921. return true;
  1922. }
  1923. #endif
  1924. bool
  1925. wasm_runtime_call_wasm(WASMExecEnv *exec_env,
  1926. WASMFunctionInstanceCommon *function, uint32 argc,
  1927. uint32 argv[])
  1928. {
  1929. bool ret = false;
  1930. uint32 *new_argv = NULL, param_argc;
  1931. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  1932. uint32 result_argc = 0;
  1933. #endif
  1934. if (!wasm_runtime_exec_env_check(exec_env)) {
  1935. LOG_ERROR("Invalid exec env stack info.");
  1936. return false;
  1937. }
  1938. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  1939. if (!wasm_runtime_prepare_call_function(exec_env, function, argv, argc,
  1940. &new_argv, &param_argc,
  1941. &result_argc)) {
  1942. wasm_runtime_set_exception(exec_env->module_inst,
  1943. "the arguments conversion is failed");
  1944. return false;
  1945. }
  1946. #else
  1947. new_argv = argv;
  1948. param_argc = argc;
  1949. #endif
  1950. #if WASM_ENABLE_INTERP != 0
  1951. if (exec_env->module_inst->module_type == Wasm_Module_Bytecode)
  1952. ret = wasm_call_function(exec_env, (WASMFunctionInstance *)function,
  1953. param_argc, new_argv);
  1954. #endif
  1955. #if WASM_ENABLE_AOT != 0
  1956. if (exec_env->module_inst->module_type == Wasm_Module_AoT)
  1957. ret = aot_call_function(exec_env, (AOTFunctionInstance *)function,
  1958. param_argc, new_argv);
  1959. #endif
  1960. if (!ret) {
  1961. if (new_argv != argv) {
  1962. wasm_runtime_free(new_argv);
  1963. }
  1964. return false;
  1965. }
  1966. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  1967. if (!wasm_runtime_finalize_call_function(exec_env, function, new_argv,
  1968. result_argc, argv)) {
  1969. wasm_runtime_set_exception(exec_env->module_inst,
  1970. "the result conversion is failed");
  1971. return false;
  1972. }
  1973. #endif
  1974. return ret;
  1975. }
  1976. static void
  1977. parse_args_to_uint32_array(WASMFuncType *type, wasm_val_t *args,
  1978. uint32 *out_argv)
  1979. {
  1980. uint32 i, p;
  1981. for (i = 0, p = 0; i < type->param_count; i++) {
  1982. switch (args[i].kind) {
  1983. case WASM_I32:
  1984. out_argv[p++] = args[i].of.i32;
  1985. break;
  1986. case WASM_I64:
  1987. {
  1988. union {
  1989. uint64 val;
  1990. uint32 parts[2];
  1991. } u;
  1992. u.val = args[i].of.i64;
  1993. out_argv[p++] = u.parts[0];
  1994. out_argv[p++] = u.parts[1];
  1995. break;
  1996. }
  1997. case WASM_F32:
  1998. {
  1999. union {
  2000. float32 val;
  2001. uint32 part;
  2002. } u;
  2003. u.val = args[i].of.f32;
  2004. out_argv[p++] = u.part;
  2005. break;
  2006. }
  2007. case WASM_F64:
  2008. {
  2009. union {
  2010. float64 val;
  2011. uint32 parts[2];
  2012. } u;
  2013. u.val = args[i].of.f64;
  2014. out_argv[p++] = u.parts[0];
  2015. out_argv[p++] = u.parts[1];
  2016. break;
  2017. }
  2018. case WASM_V128:
  2019. {
  2020. bh_assert(0);
  2021. break;
  2022. }
  2023. #if WASM_ENABLE_REF_TYPES != 0
  2024. #if WASM_ENABLE_GC == 0
  2025. case WASM_FUNCREF:
  2026. {
  2027. out_argv[p++] = args[i].of.i32;
  2028. break;
  2029. }
  2030. #else
  2031. case WASM_FUNCREF:
  2032. #endif
  2033. case WASM_EXTERNREF:
  2034. {
  2035. #if UINTPTR_MAX == UINT32_MAX
  2036. out_argv[p++] = args[i].of.foreign;
  2037. #else
  2038. union {
  2039. uintptr_t val;
  2040. uint32 parts[2];
  2041. } u;
  2042. u.val = (uintptr_t)args[i].of.foreign;
  2043. out_argv[p++] = u.parts[0];
  2044. out_argv[p++] = u.parts[1];
  2045. #endif
  2046. break;
  2047. }
  2048. #endif
  2049. default:
  2050. bh_assert(0);
  2051. break;
  2052. }
  2053. }
  2054. }
  2055. static void
  2056. parse_uint32_array_to_results(WASMFuncType *type, uint32 *argv,
  2057. wasm_val_t *out_results)
  2058. {
  2059. uint32 i, p;
  2060. for (i = 0, p = 0; i < type->result_count; i++) {
  2061. switch (type->types[type->param_count + i]) {
  2062. case VALUE_TYPE_I32:
  2063. out_results[i].kind = WASM_I32;
  2064. out_results[i].of.i32 = (int32)argv[p++];
  2065. break;
  2066. case VALUE_TYPE_I64:
  2067. {
  2068. union {
  2069. uint64 val;
  2070. uint32 parts[2];
  2071. } u;
  2072. u.parts[0] = argv[p++];
  2073. u.parts[1] = argv[p++];
  2074. out_results[i].kind = WASM_I64;
  2075. out_results[i].of.i64 = u.val;
  2076. break;
  2077. }
  2078. case VALUE_TYPE_F32:
  2079. {
  2080. union {
  2081. float32 val;
  2082. uint32 part;
  2083. } u;
  2084. u.part = argv[p++];
  2085. out_results[i].kind = WASM_F32;
  2086. out_results[i].of.f32 = u.val;
  2087. break;
  2088. }
  2089. case VALUE_TYPE_F64:
  2090. {
  2091. union {
  2092. float64 val;
  2093. uint32 parts[2];
  2094. } u;
  2095. u.parts[0] = argv[p++];
  2096. u.parts[1] = argv[p++];
  2097. out_results[i].kind = WASM_F64;
  2098. out_results[i].of.f64 = u.val;
  2099. break;
  2100. }
  2101. case VALUE_TYPE_V128:
  2102. {
  2103. bh_assert(0);
  2104. break;
  2105. }
  2106. #if WASM_ENABLE_REF_TYPES != 0
  2107. #if WASM_ENABLE_GC == 0
  2108. case VALUE_TYPE_FUNCREF:
  2109. {
  2110. out_results[i].kind = WASM_I32;
  2111. out_results[i].of.i32 = (int32)argv[p++];
  2112. break;
  2113. }
  2114. case VALUE_TYPE_EXTERNREF:
  2115. #else
  2116. case REF_TYPE_FUNCREF:
  2117. case REF_TYPE_EXTERNREF:
  2118. case REF_TYPE_ANYREF:
  2119. case REF_TYPE_EQREF:
  2120. case REF_TYPE_HT_NULLABLE:
  2121. case REF_TYPE_HT_NON_NULLABLE:
  2122. case REF_TYPE_I31REF:
  2123. case REF_TYPE_NULLFUNCREF:
  2124. case REF_TYPE_NULLEXTERNREF:
  2125. case REF_TYPE_STRUCTREF:
  2126. case REF_TYPE_ARRAYREF:
  2127. case REF_TYPE_NULLREF:
  2128. #endif /* end of WASM_ENABLE_GC == 0 */
  2129. {
  2130. #if UINTPTR_MAX == UINT32_MAX
  2131. out_results[i].kind = WASM_EXTERNREF;
  2132. out_results[i].of.foreign = (uintptr_t)argv[p++];
  2133. #else
  2134. union {
  2135. uintptr_t val;
  2136. uint32 parts[2];
  2137. } u;
  2138. u.parts[0] = argv[p++];
  2139. u.parts[1] = argv[p++];
  2140. out_results[i].kind = WASM_EXTERNREF;
  2141. out_results[i].of.foreign = u.val;
  2142. #endif
  2143. break;
  2144. }
  2145. #endif /* end of WASM_ENABLE_REF_TYPES != 0 */
  2146. default:
  2147. bh_assert(0);
  2148. break;
  2149. }
  2150. }
  2151. }
  2152. bool
  2153. wasm_runtime_call_wasm_a(WASMExecEnv *exec_env,
  2154. WASMFunctionInstanceCommon *function,
  2155. uint32 num_results, wasm_val_t results[],
  2156. uint32 num_args, wasm_val_t args[])
  2157. {
  2158. uint32 argc, argv_buf[16] = { 0 }, *argv = argv_buf, cell_num, module_type;
  2159. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  2160. uint32 i, param_size_in_double_world = 0, result_size_in_double_world = 0;
  2161. #endif
  2162. uint64 total_size;
  2163. WASMFuncType *type;
  2164. bool ret = false;
  2165. module_type = exec_env->module_inst->module_type;
  2166. type = wasm_runtime_get_function_type(function, module_type);
  2167. if (!type) {
  2168. LOG_ERROR("Function type get failed, WAMR Interpreter and AOT must be "
  2169. "enabled at least one.");
  2170. goto fail1;
  2171. }
  2172. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  2173. for (i = 0; i < type->param_count; i++) {
  2174. param_size_in_double_world +=
  2175. wasm_value_type_cell_num_outside(type->types[i]);
  2176. }
  2177. for (i = 0; i < type->result_count; i++) {
  2178. result_size_in_double_world += wasm_value_type_cell_num_outside(
  2179. type->types[type->param_count + i]);
  2180. }
  2181. argc = param_size_in_double_world;
  2182. cell_num = (argc >= result_size_in_double_world)
  2183. ? argc
  2184. : result_size_in_double_world;
  2185. #else
  2186. argc = type->param_cell_num;
  2187. cell_num = (argc > type->ret_cell_num) ? argc : type->ret_cell_num;
  2188. #endif
  2189. if (num_results != type->result_count) {
  2190. LOG_ERROR(
  2191. "The result value number does not match the function declaration.");
  2192. goto fail1;
  2193. }
  2194. if (num_args != type->param_count) {
  2195. LOG_ERROR("The argument value number does not match the function "
  2196. "declaration.");
  2197. goto fail1;
  2198. }
  2199. total_size = sizeof(uint32) * (uint64)(cell_num > 2 ? cell_num : 2);
  2200. if (total_size > sizeof(argv_buf)) {
  2201. if (!(argv =
  2202. runtime_malloc(total_size, exec_env->module_inst, NULL, 0))) {
  2203. goto fail1;
  2204. }
  2205. }
  2206. parse_args_to_uint32_array(type, args, argv);
  2207. if (!(ret = wasm_runtime_call_wasm(exec_env, function, argc, argv)))
  2208. goto fail2;
  2209. parse_uint32_array_to_results(type, argv, results);
  2210. fail2:
  2211. if (argv != argv_buf)
  2212. wasm_runtime_free(argv);
  2213. fail1:
  2214. return ret;
  2215. }
  2216. bool
  2217. wasm_runtime_call_wasm_v(WASMExecEnv *exec_env,
  2218. WASMFunctionInstanceCommon *function,
  2219. uint32 num_results, wasm_val_t results[],
  2220. uint32 num_args, ...)
  2221. {
  2222. wasm_val_t args_buf[8] = { 0 }, *args = args_buf;
  2223. WASMFuncType *type = NULL;
  2224. bool ret = false;
  2225. uint64 total_size;
  2226. uint32 i = 0, module_type;
  2227. va_list vargs;
  2228. module_type = exec_env->module_inst->module_type;
  2229. type = wasm_runtime_get_function_type(function, module_type);
  2230. if (!type) {
  2231. LOG_ERROR("Function type get failed, WAMR Interpreter and AOT "
  2232. "must be enabled at least one.");
  2233. goto fail1;
  2234. }
  2235. if (num_args != type->param_count) {
  2236. LOG_ERROR("The argument value number does not match the "
  2237. "function declaration.");
  2238. goto fail1;
  2239. }
  2240. total_size = sizeof(wasm_val_t) * (uint64)num_args;
  2241. if (total_size > sizeof(args_buf)) {
  2242. if (!(args =
  2243. runtime_malloc(total_size, exec_env->module_inst, NULL, 0))) {
  2244. goto fail1;
  2245. }
  2246. }
  2247. va_start(vargs, num_args);
  2248. for (i = 0; i < num_args; i++) {
  2249. switch (type->types[i]) {
  2250. case VALUE_TYPE_I32:
  2251. args[i].kind = WASM_I32;
  2252. args[i].of.i32 = va_arg(vargs, uint32);
  2253. break;
  2254. case VALUE_TYPE_I64:
  2255. args[i].kind = WASM_I64;
  2256. args[i].of.i64 = va_arg(vargs, uint64);
  2257. break;
  2258. case VALUE_TYPE_F32:
  2259. args[i].kind = WASM_F32;
  2260. args[i].of.f32 = (float32)va_arg(vargs, float64);
  2261. break;
  2262. case VALUE_TYPE_F64:
  2263. args[i].kind = WASM_F64;
  2264. args[i].of.f64 = va_arg(vargs, float64);
  2265. break;
  2266. case VALUE_TYPE_V128:
  2267. bh_assert(0);
  2268. break;
  2269. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  2270. case VALUE_TYPE_FUNCREF:
  2271. {
  2272. args[i].kind = WASM_FUNCREF;
  2273. args[i].of.i32 = va_arg(vargs, uint32);
  2274. break;
  2275. }
  2276. case VALUE_TYPE_EXTERNREF:
  2277. {
  2278. args[i].kind = WASM_EXTERNREF;
  2279. args[i].of.foreign = va_arg(vargs, uintptr_t);
  2280. break;
  2281. }
  2282. #endif
  2283. default:
  2284. bh_assert(0);
  2285. break;
  2286. }
  2287. }
  2288. va_end(vargs);
  2289. ret = wasm_runtime_call_wasm_a(exec_env, function, num_results, results,
  2290. num_args, args);
  2291. if (args != args_buf)
  2292. wasm_runtime_free(args);
  2293. fail1:
  2294. return ret;
  2295. }
  2296. bool
  2297. wasm_runtime_create_exec_env_singleton(
  2298. WASMModuleInstanceCommon *module_inst_comm)
  2299. {
  2300. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  2301. WASMExecEnv *exec_env = NULL;
  2302. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  2303. || module_inst_comm->module_type == Wasm_Module_AoT);
  2304. if (module_inst->exec_env_singleton) {
  2305. return true;
  2306. }
  2307. exec_env = wasm_exec_env_create(module_inst_comm,
  2308. module_inst->default_wasm_stack_size);
  2309. if (exec_env)
  2310. module_inst->exec_env_singleton = exec_env;
  2311. return exec_env ? true : false;
  2312. }
  2313. WASMExecEnv *
  2314. wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst_comm)
  2315. {
  2316. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  2317. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  2318. || module_inst_comm->module_type == Wasm_Module_AoT);
  2319. if (!module_inst->exec_env_singleton) {
  2320. wasm_runtime_create_exec_env_singleton(module_inst_comm);
  2321. }
  2322. return module_inst->exec_env_singleton;
  2323. }
  2324. static void
  2325. wasm_set_exception_local(WASMModuleInstance *module_inst, const char *exception)
  2326. {
  2327. exception_lock(module_inst);
  2328. if (exception) {
  2329. snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception),
  2330. "Exception: %s", exception);
  2331. }
  2332. else {
  2333. module_inst->cur_exception[0] = '\0';
  2334. }
  2335. exception_unlock(module_inst);
  2336. }
  2337. void
  2338. wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
  2339. {
  2340. #if WASM_ENABLE_THREAD_MGR != 0
  2341. WASMExecEnv *exec_env =
  2342. wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst);
  2343. if (exec_env) {
  2344. wasm_cluster_set_exception(exec_env, exception);
  2345. }
  2346. else {
  2347. wasm_set_exception_local(module_inst, exception);
  2348. }
  2349. #else
  2350. wasm_set_exception_local(module_inst, exception);
  2351. #endif
  2352. }
  2353. /* clang-format off */
  2354. static const char *exception_msgs[] = {
  2355. "unreachable", /* EXCE_UNREACHABLE */
  2356. "allocate memory failed", /* EXCE_OUT_OF_MEMORY */
  2357. "out of bounds memory access", /* EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS */
  2358. "integer overflow", /* EXCE_INTEGER_OVERFLOW */
  2359. "integer divide by zero", /* EXCE_INTEGER_DIVIDE_BY_ZERO */
  2360. "invalid conversion to integer", /* EXCE_INVALID_CONVERSION_TO_INTEGER */
  2361. "indirect call type mismatch", /* EXCE_INVALID_FUNCTION_TYPE_INDEX */
  2362. "invalid function index", /* EXCE_INVALID_FUNCTION_INDEX */
  2363. "undefined element", /* EXCE_UNDEFINED_ELEMENT */
  2364. "uninitialized element", /* EXCE_UNINITIALIZED_ELEMENT */
  2365. "failed to call unlinked import function", /* EXCE_CALL_UNLINKED_IMPORT_FUNC */
  2366. "native stack overflow", /* EXCE_NATIVE_STACK_OVERFLOW */
  2367. "unaligned atomic", /* EXCE_UNALIGNED_ATOMIC */
  2368. "wasm auxiliary stack overflow", /* EXCE_AUX_STACK_OVERFLOW */
  2369. "wasm auxiliary stack underflow", /* EXCE_AUX_STACK_UNDERFLOW */
  2370. "out of bounds table access", /* EXCE_OUT_OF_BOUNDS_TABLE_ACCESS */
  2371. "wasm operand stack overflow", /* EXCE_OPERAND_STACK_OVERFLOW */
  2372. "failed to compile fast jit function", /* EXCE_FAILED_TO_COMPILE_FAST_JIT_FUNC */
  2373. /* GC related exceptions */
  2374. "null function object", /* EXCE_NULL_FUNC_OBJ */
  2375. "null structure object", /* EXCE_NULL_STRUCT_OBJ */
  2376. "null array reference", /* EXCE_NULL_ARRAY_OBJ */
  2377. "null i31 reference", /* EXCE_NULL_I31_OBJ */
  2378. "null reference", /* EXCE_NULL_REFERENCE */
  2379. "create rtt type failed", /* EXCE_FAILED_TO_CREATE_RTT_TYPE */
  2380. "create struct object failed", /* EXCE_FAILED_TO_CREATE_STRUCT_OBJ */
  2381. "create array object failed", /* EXCE_FAILED_TO_CREATE_ARRAY_OBJ */
  2382. "create externref object failed", /* EXCE_FAILED_TO_CREATE_EXTERNREF_OBJ */
  2383. "cast failure", /* EXCE_CAST_FAILURE */
  2384. "out of bounds array access", /* EXCE_ARRAY_IDX_OOB */
  2385. /* stringref related exceptions */
  2386. "create string object failed", /* EXCE_FAILED_TO_CREATE_STRING */
  2387. "create stringref failed", /* EXCE_FAILED_TO_CREATE_STRINGREF */
  2388. "create stringview failed", /* EXCE_FAILED_TO_CREATE_STRINGVIEW */
  2389. "encode failed", /* EXCE_FAILED_TO_ENCODE_STRING */
  2390. "", /* EXCE_ALREADY_THROWN */
  2391. };
  2392. /* clang-format on */
  2393. void
  2394. wasm_set_exception_with_id(WASMModuleInstance *module_inst, uint32 id)
  2395. {
  2396. if (id < EXCE_NUM)
  2397. wasm_set_exception(module_inst, exception_msgs[id]);
  2398. else
  2399. wasm_set_exception(module_inst, "unknown exception");
  2400. }
  2401. const char *
  2402. wasm_get_exception(WASMModuleInstance *module_inst)
  2403. {
  2404. if (module_inst->cur_exception[0] == '\0')
  2405. return NULL;
  2406. else
  2407. return module_inst->cur_exception;
  2408. }
  2409. bool
  2410. wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf)
  2411. {
  2412. bool has_exception = false;
  2413. exception_lock(module_inst);
  2414. if (module_inst->cur_exception[0] != '\0') {
  2415. /* NULL is passed if the caller is not interested in getting the
  2416. * exception content, but only in knowing if an exception has been
  2417. * raised
  2418. */
  2419. if (exception_buf != NULL)
  2420. bh_memcpy_s(exception_buf, sizeof(module_inst->cur_exception),
  2421. module_inst->cur_exception,
  2422. sizeof(module_inst->cur_exception));
  2423. has_exception = true;
  2424. }
  2425. exception_unlock(module_inst);
  2426. return has_exception;
  2427. }
  2428. void
  2429. wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst_comm,
  2430. const char *exception)
  2431. {
  2432. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  2433. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  2434. || module_inst_comm->module_type == Wasm_Module_AoT);
  2435. wasm_set_exception(module_inst, exception);
  2436. }
  2437. const char *
  2438. wasm_runtime_get_exception(WASMModuleInstanceCommon *module_inst_comm)
  2439. {
  2440. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  2441. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  2442. || module_inst_comm->module_type == Wasm_Module_AoT);
  2443. return wasm_get_exception(module_inst);
  2444. }
  2445. bool
  2446. wasm_runtime_copy_exception(WASMModuleInstanceCommon *module_inst_comm,
  2447. char *exception_buf)
  2448. {
  2449. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  2450. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  2451. || module_inst_comm->module_type == Wasm_Module_AoT);
  2452. return wasm_copy_exception(module_inst, exception_buf);
  2453. }
  2454. void
  2455. wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst_comm)
  2456. {
  2457. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  2458. || module_inst_comm->module_type == Wasm_Module_AoT);
  2459. wasm_runtime_set_exception(module_inst_comm, NULL);
  2460. }
  2461. void
  2462. wasm_runtime_terminate(WASMModuleInstanceCommon *module_inst_comm)
  2463. {
  2464. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  2465. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  2466. || module_inst_comm->module_type == Wasm_Module_AoT);
  2467. wasm_set_exception(module_inst, "terminated by user");
  2468. }
  2469. void
  2470. wasm_runtime_set_custom_data_internal(
  2471. WASMModuleInstanceCommon *module_inst_comm, void *custom_data)
  2472. {
  2473. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  2474. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  2475. || module_inst_comm->module_type == Wasm_Module_AoT);
  2476. module_inst->custom_data = custom_data;
  2477. }
  2478. void
  2479. wasm_runtime_set_custom_data(WASMModuleInstanceCommon *module_inst,
  2480. void *custom_data)
  2481. {
  2482. #if WASM_ENABLE_THREAD_MGR != 0
  2483. wasm_cluster_spread_custom_data(module_inst, custom_data);
  2484. #else
  2485. wasm_runtime_set_custom_data_internal(module_inst, custom_data);
  2486. #endif
  2487. }
  2488. void *
  2489. wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst_comm)
  2490. {
  2491. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  2492. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  2493. || module_inst_comm->module_type == Wasm_Module_AoT);
  2494. return module_inst->custom_data;
  2495. }
  2496. #if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0
  2497. void
  2498. wasm_runtime_set_bounds_checks(WASMModuleInstanceCommon *module_inst,
  2499. bool enable)
  2500. {
  2501. /* Always disable bounds checks if hw bounds checks is enabled */
  2502. #ifdef OS_ENABLE_HW_BOUND_CHECK
  2503. enable = false;
  2504. #endif
  2505. #if WASM_ENABLE_INTERP != 0
  2506. if (module_inst->module_type == Wasm_Module_Bytecode) {
  2507. ((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e)
  2508. ->common.disable_bounds_checks = enable ? false : true;
  2509. }
  2510. #endif
  2511. #if WASM_ENABLE_AOT != 0
  2512. if (module_inst->module_type == Wasm_Module_AoT) {
  2513. ((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
  2514. ->common.disable_bounds_checks = enable ? false : true;
  2515. }
  2516. #endif
  2517. }
  2518. bool
  2519. wasm_runtime_is_bounds_checks_enabled(WASMModuleInstanceCommon *module_inst)
  2520. {
  2521. #if WASM_ENABLE_INTERP != 0
  2522. if (module_inst->module_type == Wasm_Module_Bytecode) {
  2523. return !((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)
  2524. ->e)
  2525. ->common.disable_bounds_checks;
  2526. }
  2527. #endif
  2528. #if WASM_ENABLE_AOT != 0
  2529. if (module_inst->module_type == Wasm_Module_AoT) {
  2530. return !((AOTModuleInstanceExtra *)((WASMModuleInstance *)module_inst)
  2531. ->e)
  2532. ->common.disable_bounds_checks;
  2533. }
  2534. #endif
  2535. return true;
  2536. }
  2537. #endif
  2538. uint64
  2539. wasm_runtime_module_malloc_internal(WASMModuleInstanceCommon *module_inst,
  2540. WASMExecEnv *exec_env, uint64 size,
  2541. void **p_native_addr)
  2542. {
  2543. #if WASM_ENABLE_INTERP != 0
  2544. if (module_inst->module_type == Wasm_Module_Bytecode)
  2545. return wasm_module_malloc_internal((WASMModuleInstance *)module_inst,
  2546. exec_env, size, p_native_addr);
  2547. #endif
  2548. #if WASM_ENABLE_AOT != 0
  2549. if (module_inst->module_type == Wasm_Module_AoT)
  2550. return aot_module_malloc_internal((AOTModuleInstance *)module_inst,
  2551. exec_env, size, p_native_addr);
  2552. #endif
  2553. return 0;
  2554. }
  2555. uint64
  2556. wasm_runtime_module_realloc_internal(WASMModuleInstanceCommon *module_inst,
  2557. WASMExecEnv *exec_env, uint64 ptr,
  2558. uint64 size, void **p_native_addr)
  2559. {
  2560. #if WASM_ENABLE_INTERP != 0
  2561. if (module_inst->module_type == Wasm_Module_Bytecode)
  2562. return wasm_module_realloc_internal((WASMModuleInstance *)module_inst,
  2563. exec_env, ptr, size, p_native_addr);
  2564. #endif
  2565. #if WASM_ENABLE_AOT != 0
  2566. if (module_inst->module_type == Wasm_Module_AoT)
  2567. return aot_module_realloc_internal((AOTModuleInstance *)module_inst,
  2568. exec_env, ptr, size, p_native_addr);
  2569. #endif
  2570. return 0;
  2571. }
  2572. void
  2573. wasm_runtime_module_free_internal(WASMModuleInstanceCommon *module_inst,
  2574. WASMExecEnv *exec_env, uint64 ptr)
  2575. {
  2576. #if WASM_ENABLE_INTERP != 0
  2577. if (module_inst->module_type == Wasm_Module_Bytecode) {
  2578. wasm_module_free_internal((WASMModuleInstance *)module_inst, exec_env,
  2579. ptr);
  2580. return;
  2581. }
  2582. #endif
  2583. #if WASM_ENABLE_AOT != 0
  2584. if (module_inst->module_type == Wasm_Module_AoT) {
  2585. aot_module_free_internal((AOTModuleInstance *)module_inst, exec_env,
  2586. ptr);
  2587. return;
  2588. }
  2589. #endif
  2590. }
  2591. uint64
  2592. wasm_runtime_module_malloc(WASMModuleInstanceCommon *module_inst, uint64 size,
  2593. void **p_native_addr)
  2594. {
  2595. #if WASM_ENABLE_INTERP != 0
  2596. if (module_inst->module_type == Wasm_Module_Bytecode)
  2597. return wasm_module_malloc((WASMModuleInstance *)module_inst, size,
  2598. p_native_addr);
  2599. #endif
  2600. #if WASM_ENABLE_AOT != 0
  2601. if (module_inst->module_type == Wasm_Module_AoT)
  2602. return aot_module_malloc((AOTModuleInstance *)module_inst, size,
  2603. p_native_addr);
  2604. #endif
  2605. return 0;
  2606. }
  2607. uint64
  2608. wasm_runtime_module_realloc(WASMModuleInstanceCommon *module_inst, uint64 ptr,
  2609. uint64 size, void **p_native_addr)
  2610. {
  2611. #if WASM_ENABLE_INTERP != 0
  2612. if (module_inst->module_type == Wasm_Module_Bytecode)
  2613. return wasm_module_realloc((WASMModuleInstance *)module_inst, ptr, size,
  2614. p_native_addr);
  2615. #endif
  2616. #if WASM_ENABLE_AOT != 0
  2617. if (module_inst->module_type == Wasm_Module_AoT)
  2618. return aot_module_realloc((AOTModuleInstance *)module_inst, ptr, size,
  2619. p_native_addr);
  2620. #endif
  2621. return 0;
  2622. }
  2623. void
  2624. wasm_runtime_module_free(WASMModuleInstanceCommon *module_inst, uint64 ptr)
  2625. {
  2626. #if WASM_ENABLE_INTERP != 0
  2627. if (module_inst->module_type == Wasm_Module_Bytecode) {
  2628. wasm_module_free((WASMModuleInstance *)module_inst, ptr);
  2629. return;
  2630. }
  2631. #endif
  2632. #if WASM_ENABLE_AOT != 0
  2633. if (module_inst->module_type == Wasm_Module_AoT) {
  2634. aot_module_free((AOTModuleInstance *)module_inst, ptr);
  2635. return;
  2636. }
  2637. #endif
  2638. }
  2639. uint64
  2640. wasm_runtime_module_dup_data(WASMModuleInstanceCommon *module_inst,
  2641. const char *src, uint64 size)
  2642. {
  2643. #if WASM_ENABLE_INTERP != 0
  2644. if (module_inst->module_type == Wasm_Module_Bytecode) {
  2645. return wasm_module_dup_data((WASMModuleInstance *)module_inst, src,
  2646. size);
  2647. }
  2648. #endif
  2649. #if WASM_ENABLE_AOT != 0
  2650. if (module_inst->module_type == Wasm_Module_AoT) {
  2651. return aot_module_dup_data((AOTModuleInstance *)module_inst, src, size);
  2652. }
  2653. #endif
  2654. return 0;
  2655. }
  2656. #if WASM_ENABLE_LIBC_WASI != 0
  2657. static WASIArguments *
  2658. get_wasi_args_from_module(wasm_module_t module)
  2659. {
  2660. WASIArguments *wasi_args = NULL;
  2661. #if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
  2662. if (module->module_type == Wasm_Module_Bytecode)
  2663. wasi_args = &((WASMModule *)module)->wasi_args;
  2664. #endif
  2665. #if WASM_ENABLE_AOT != 0
  2666. if (module->module_type == Wasm_Module_AoT)
  2667. wasi_args = &((AOTModule *)module)->wasi_args;
  2668. #endif
  2669. return wasi_args;
  2670. }
  2671. void
  2672. wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[],
  2673. uint32 dir_count, const char *map_dir_list[],
  2674. uint32 map_dir_count, const char *env_list[],
  2675. uint32 env_count, char *argv[], int argc,
  2676. int64 stdinfd, int64 stdoutfd, int64 stderrfd)
  2677. {
  2678. WASIArguments *wasi_args = get_wasi_args_from_module(module);
  2679. bh_assert(wasi_args);
  2680. wasi_args->dir_list = dir_list;
  2681. wasi_args->dir_count = dir_count;
  2682. wasi_args->map_dir_list = map_dir_list;
  2683. wasi_args->map_dir_count = map_dir_count;
  2684. wasi_args->env = env_list;
  2685. wasi_args->env_count = env_count;
  2686. wasi_args->argv = argv;
  2687. wasi_args->argc = (uint32)argc;
  2688. wasi_args->stdio[0] = (os_raw_file_handle)stdinfd;
  2689. wasi_args->stdio[1] = (os_raw_file_handle)stdoutfd;
  2690. wasi_args->stdio[2] = (os_raw_file_handle)stderrfd;
  2691. #if WASM_ENABLE_MULTI_MODULE != 0
  2692. #if WASM_ENABLE_INTERP != 0
  2693. if (module->module_type == Wasm_Module_Bytecode) {
  2694. wasm_propagate_wasi_args((WASMModule *)module);
  2695. }
  2696. #endif
  2697. #endif
  2698. }
  2699. void
  2700. wasm_runtime_set_wasi_args(WASMModuleCommon *module, const char *dir_list[],
  2701. uint32 dir_count, const char *map_dir_list[],
  2702. uint32 map_dir_count, const char *env_list[],
  2703. uint32 env_count, char *argv[], int argc)
  2704. {
  2705. wasm_runtime_set_wasi_args_ex(module, dir_list, dir_count, map_dir_list,
  2706. map_dir_count, env_list, env_count, argv,
  2707. argc, -1, -1, -1);
  2708. }
  2709. void
  2710. wasm_runtime_set_wasi_addr_pool(wasm_module_t module, const char *addr_pool[],
  2711. uint32 addr_pool_size)
  2712. {
  2713. WASIArguments *wasi_args = get_wasi_args_from_module(module);
  2714. if (wasi_args) {
  2715. wasi_args->addr_pool = addr_pool;
  2716. wasi_args->addr_count = addr_pool_size;
  2717. }
  2718. }
  2719. void
  2720. wasm_runtime_set_wasi_ns_lookup_pool(wasm_module_t module,
  2721. const char *ns_lookup_pool[],
  2722. uint32 ns_lookup_pool_size)
  2723. {
  2724. WASIArguments *wasi_args = get_wasi_args_from_module(module);
  2725. if (wasi_args) {
  2726. wasi_args->ns_lookup_pool = ns_lookup_pool;
  2727. wasi_args->ns_lookup_count = ns_lookup_pool_size;
  2728. }
  2729. }
  2730. #if WASM_ENABLE_UVWASI == 0
  2731. static bool
  2732. copy_string_array(const char *array[], uint32 array_size, char **buf_ptr,
  2733. char ***list_ptr, uint64 *out_buf_size)
  2734. {
  2735. uint64 buf_size = 0, total_size;
  2736. uint32 buf_offset = 0, i;
  2737. char *buf = NULL, **list = NULL;
  2738. for (i = 0; i < array_size; i++)
  2739. buf_size += strlen(array[i]) + 1;
  2740. /* We add +1 to generate null-terminated array of strings */
  2741. total_size = sizeof(char *) * ((uint64)array_size + 1);
  2742. if (total_size >= UINT32_MAX
  2743. /* total_size must be larger than 0, don' check it again */
  2744. || !(list = wasm_runtime_malloc((uint32)total_size))
  2745. || buf_size >= UINT32_MAX
  2746. || (buf_size > 0 && !(buf = wasm_runtime_malloc((uint32)buf_size)))) {
  2747. if (buf)
  2748. wasm_runtime_free(buf);
  2749. if (list)
  2750. wasm_runtime_free(list);
  2751. return false;
  2752. }
  2753. for (i = 0; i < array_size; i++) {
  2754. list[i] = buf + buf_offset;
  2755. bh_strcpy_s(buf + buf_offset, (uint32)buf_size - buf_offset, array[i]);
  2756. buf_offset += (uint32)(strlen(array[i]) + 1);
  2757. }
  2758. list[array_size] = NULL;
  2759. *list_ptr = list;
  2760. *buf_ptr = buf;
  2761. if (out_buf_size)
  2762. *out_buf_size = buf_size;
  2763. return true;
  2764. }
  2765. bool
  2766. wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
  2767. const char *dir_list[], uint32 dir_count,
  2768. const char *map_dir_list[], uint32 map_dir_count,
  2769. const char *env[], uint32 env_count,
  2770. const char *addr_pool[], uint32 addr_pool_size,
  2771. const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
  2772. char *argv[], uint32 argc, os_raw_file_handle stdinfd,
  2773. os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
  2774. char *error_buf, uint32 error_buf_size)
  2775. {
  2776. WASIContext *wasi_ctx;
  2777. char *argv_buf = NULL;
  2778. char **argv_list = NULL;
  2779. char *env_buf = NULL;
  2780. char **env_list = NULL;
  2781. char *ns_lookup_buf = NULL;
  2782. char **ns_lookup_list = NULL;
  2783. uint64 argv_buf_size = 0, env_buf_size = 0;
  2784. struct fd_table *curfds = NULL;
  2785. struct fd_prestats *prestats = NULL;
  2786. struct argv_environ_values *argv_environ = NULL;
  2787. struct addr_pool *apool = NULL;
  2788. bool fd_table_inited = false, fd_prestats_inited = false;
  2789. bool argv_environ_inited = false;
  2790. bool addr_pool_inited = false;
  2791. __wasi_fd_t wasm_fd = 3;
  2792. os_file_handle file_handle;
  2793. char *path, resolved_path[PATH_MAX];
  2794. uint32 i;
  2795. if (!(wasi_ctx = runtime_malloc(sizeof(WASIContext), NULL, error_buf,
  2796. error_buf_size))) {
  2797. return false;
  2798. }
  2799. wasm_runtime_set_wasi_ctx(module_inst, wasi_ctx);
  2800. /* process argv[0], trip the path and suffix, only keep the program name
  2801. */
  2802. if (!copy_string_array((const char **)argv, argc, &argv_buf, &argv_list,
  2803. &argv_buf_size)) {
  2804. set_error_buf(error_buf, error_buf_size,
  2805. "Init wasi environment failed: allocate memory failed");
  2806. goto fail;
  2807. }
  2808. if (!copy_string_array(env, env_count, &env_buf, &env_list,
  2809. &env_buf_size)) {
  2810. set_error_buf(error_buf, error_buf_size,
  2811. "Init wasi environment failed: allocate memory failed");
  2812. goto fail;
  2813. }
  2814. if (!(curfds = wasm_runtime_malloc(sizeof(struct fd_table)))
  2815. || !(prestats = wasm_runtime_malloc(sizeof(struct fd_prestats)))
  2816. || !(argv_environ =
  2817. wasm_runtime_malloc(sizeof(struct argv_environ_values)))
  2818. || !(apool = wasm_runtime_malloc(sizeof(struct addr_pool)))) {
  2819. set_error_buf(error_buf, error_buf_size,
  2820. "Init wasi environment failed: allocate memory failed");
  2821. goto fail;
  2822. }
  2823. if (!fd_table_init(curfds)) {
  2824. set_error_buf(error_buf, error_buf_size,
  2825. "Init wasi environment failed: "
  2826. "init fd table failed");
  2827. goto fail;
  2828. }
  2829. fd_table_inited = true;
  2830. if (!fd_prestats_init(prestats)) {
  2831. set_error_buf(error_buf, error_buf_size,
  2832. "Init wasi environment failed: "
  2833. "init fd prestats failed");
  2834. goto fail;
  2835. }
  2836. fd_prestats_inited = true;
  2837. if (!argv_environ_init(argv_environ, argv_buf, argv_buf_size, argv_list,
  2838. argc, env_buf, env_buf_size, env_list, env_count)) {
  2839. set_error_buf(error_buf, error_buf_size,
  2840. "Init wasi environment failed: "
  2841. "init argument environment failed");
  2842. goto fail;
  2843. }
  2844. argv_environ_inited = true;
  2845. if (!addr_pool_init(apool)) {
  2846. set_error_buf(error_buf, error_buf_size,
  2847. "Init wasi environment failed: "
  2848. "init the address pool failed");
  2849. goto fail;
  2850. }
  2851. addr_pool_inited = true;
  2852. os_file_handle stdin_file_handle = os_convert_stdin_handle(stdinfd);
  2853. os_file_handle stdout_file_handle = os_convert_stdout_handle(stdoutfd);
  2854. os_file_handle stderr_file_handle = os_convert_stderr_handle(stderrfd);
  2855. if (!os_is_handle_valid(&stdin_file_handle)
  2856. || !os_is_handle_valid(&stdout_file_handle)
  2857. || !os_is_handle_valid(&stderr_file_handle))
  2858. goto fail;
  2859. /* Prepopulate curfds with stdin, stdout, and stderr file descriptors. */
  2860. if (!fd_table_insert_existing(curfds, 0, stdin_file_handle, true)
  2861. || !fd_table_insert_existing(curfds, 1, stdout_file_handle, true)
  2862. || !fd_table_insert_existing(curfds, 2, stderr_file_handle, true)) {
  2863. set_error_buf(error_buf, error_buf_size,
  2864. "Init wasi environment failed: init fd table failed");
  2865. goto fail;
  2866. }
  2867. wasm_fd = 3;
  2868. for (i = 0; i < dir_count; i++, wasm_fd++) {
  2869. path = os_realpath(dir_list[i], resolved_path);
  2870. if (!path) {
  2871. if (error_buf)
  2872. snprintf(error_buf, error_buf_size,
  2873. "error while pre-opening directory %s: %d\n",
  2874. dir_list[i], errno);
  2875. goto fail;
  2876. }
  2877. __wasi_errno_t error = os_open_preopendir(path, &file_handle);
  2878. if (error != __WASI_ESUCCESS) {
  2879. if (error_buf)
  2880. snprintf(error_buf, error_buf_size,
  2881. "error while pre-opening directory %s: %d\n",
  2882. dir_list[i], error);
  2883. goto fail;
  2884. }
  2885. if (!fd_table_insert_existing(curfds, wasm_fd, file_handle, false)) {
  2886. if (error_buf)
  2887. snprintf(error_buf, error_buf_size,
  2888. "error inserting preopen fd %u (directory %s) into fd "
  2889. "table",
  2890. (unsigned int)wasm_fd, dir_list[i]);
  2891. goto fail;
  2892. }
  2893. if (!fd_prestats_insert(prestats, dir_list[i], wasm_fd)) {
  2894. if (error_buf)
  2895. snprintf(error_buf, error_buf_size,
  2896. "error inserting preopen fd %u (directory %s) into "
  2897. "prestats table",
  2898. (unsigned int)wasm_fd, dir_list[i]);
  2899. goto fail;
  2900. }
  2901. }
  2902. for (i = 0; i < map_dir_count; i++, wasm_fd++) {
  2903. char mapping_copy_buf[256];
  2904. char *mapping_copy = mapping_copy_buf;
  2905. char *map_mapped = NULL, *map_host = NULL;
  2906. const unsigned long max_len = strlen(map_dir_list[i]) * 2 + 3;
  2907. /* Allocation limit for runtime environments with reduced stack size */
  2908. if (max_len > 256) {
  2909. if (!(mapping_copy = wasm_runtime_malloc(max_len))) {
  2910. snprintf(error_buf, error_buf_size,
  2911. "error while allocating for directory mapping\n");
  2912. goto fail;
  2913. }
  2914. }
  2915. bh_memcpy_s(mapping_copy, max_len, map_dir_list[i],
  2916. (uint32)(strlen(map_dir_list[i]) + 1));
  2917. map_mapped = strtok(mapping_copy, "::");
  2918. map_host = strtok(NULL, "::");
  2919. if (!map_mapped || !map_host) {
  2920. if (error_buf)
  2921. snprintf(error_buf, error_buf_size,
  2922. "error while pre-opening mapped directory: "
  2923. "invalid map\n");
  2924. if (mapping_copy != mapping_copy_buf)
  2925. wasm_runtime_free(mapping_copy);
  2926. goto fail;
  2927. }
  2928. path = os_realpath(map_host, resolved_path);
  2929. if (!path) {
  2930. if (error_buf)
  2931. snprintf(error_buf, error_buf_size,
  2932. "error while pre-opening mapped directory %s: %d\n",
  2933. map_host, errno);
  2934. if (mapping_copy != mapping_copy_buf)
  2935. wasm_runtime_free(mapping_copy);
  2936. goto fail;
  2937. }
  2938. __wasi_errno_t error = os_open_preopendir(path, &file_handle);
  2939. if (error != __WASI_ESUCCESS) {
  2940. if (error_buf)
  2941. snprintf(error_buf, error_buf_size,
  2942. "error while pre-opening mapped directory %s: %d\n",
  2943. map_host, errno);
  2944. if (mapping_copy != mapping_copy_buf)
  2945. wasm_runtime_free(mapping_copy);
  2946. goto fail;
  2947. }
  2948. if (!fd_table_insert_existing(curfds, wasm_fd, file_handle, false)
  2949. || !fd_prestats_insert(prestats, map_mapped, wasm_fd)) {
  2950. if (error_buf)
  2951. snprintf(error_buf, error_buf_size,
  2952. "error while pre-opening mapped directory %s: "
  2953. "insertion failed\n",
  2954. dir_list[i]);
  2955. if (mapping_copy != mapping_copy_buf)
  2956. wasm_runtime_free(mapping_copy);
  2957. goto fail;
  2958. }
  2959. if (mapping_copy != mapping_copy_buf)
  2960. wasm_runtime_free(mapping_copy);
  2961. }
  2962. /* addr_pool(textual) -> apool */
  2963. for (i = 0; i < addr_pool_size; i++) {
  2964. char *cp, *address, *mask;
  2965. bool ret = false;
  2966. cp = bh_strdup(addr_pool[i]);
  2967. if (!cp) {
  2968. set_error_buf(error_buf, error_buf_size,
  2969. "Init wasi environment failed: copy address failed");
  2970. goto fail;
  2971. }
  2972. address = strtok(cp, "/");
  2973. mask = strtok(NULL, "/");
  2974. ret = addr_pool_insert(apool, address, (uint8)(mask ? atoi(mask) : 0));
  2975. wasm_runtime_free(cp);
  2976. if (!ret) {
  2977. set_error_buf(error_buf, error_buf_size,
  2978. "Init wasi environment failed: store address failed");
  2979. goto fail;
  2980. }
  2981. }
  2982. if (!copy_string_array(ns_lookup_pool, ns_lookup_pool_size, &ns_lookup_buf,
  2983. &ns_lookup_list, NULL)) {
  2984. set_error_buf(error_buf, error_buf_size,
  2985. "Init wasi environment failed: allocate memory failed");
  2986. goto fail;
  2987. }
  2988. wasi_ctx->curfds = curfds;
  2989. wasi_ctx->prestats = prestats;
  2990. wasi_ctx->argv_environ = argv_environ;
  2991. wasi_ctx->addr_pool = apool;
  2992. wasi_ctx->argv_buf = argv_buf;
  2993. wasi_ctx->argv_list = argv_list;
  2994. wasi_ctx->env_buf = env_buf;
  2995. wasi_ctx->env_list = env_list;
  2996. wasi_ctx->ns_lookup_buf = ns_lookup_buf;
  2997. wasi_ctx->ns_lookup_list = ns_lookup_list;
  2998. return true;
  2999. fail:
  3000. if (argv_environ_inited)
  3001. argv_environ_destroy(argv_environ);
  3002. if (fd_prestats_inited)
  3003. fd_prestats_destroy(prestats);
  3004. if (fd_table_inited)
  3005. fd_table_destroy(curfds);
  3006. if (addr_pool_inited)
  3007. addr_pool_destroy(apool);
  3008. if (curfds)
  3009. wasm_runtime_free(curfds);
  3010. if (prestats)
  3011. wasm_runtime_free(prestats);
  3012. if (argv_environ)
  3013. wasm_runtime_free(argv_environ);
  3014. if (apool)
  3015. wasm_runtime_free(apool);
  3016. if (argv_buf)
  3017. wasm_runtime_free(argv_buf);
  3018. if (argv_list)
  3019. wasm_runtime_free(argv_list);
  3020. if (env_buf)
  3021. wasm_runtime_free(env_buf);
  3022. if (env_list)
  3023. wasm_runtime_free(env_list);
  3024. if (ns_lookup_buf)
  3025. wasm_runtime_free(ns_lookup_buf);
  3026. if (ns_lookup_list)
  3027. wasm_runtime_free(ns_lookup_list);
  3028. return false;
  3029. }
  3030. #else /* else of WASM_ENABLE_UVWASI == 0 */
  3031. static void *
  3032. wasm_uvwasi_malloc(size_t size, void *mem_user_data)
  3033. {
  3034. return runtime_malloc(size, NULL, NULL, 0);
  3035. (void)mem_user_data;
  3036. }
  3037. static void
  3038. wasm_uvwasi_free(void *ptr, void *mem_user_data)
  3039. {
  3040. if (ptr)
  3041. wasm_runtime_free(ptr);
  3042. (void)mem_user_data;
  3043. }
  3044. static void *
  3045. wasm_uvwasi_calloc(size_t nmemb, size_t size, void *mem_user_data)
  3046. {
  3047. uint64 total_size = (uint64)nmemb * size;
  3048. return runtime_malloc(total_size, NULL, NULL, 0);
  3049. (void)mem_user_data;
  3050. }
  3051. static void *
  3052. wasm_uvwasi_realloc(void *ptr, size_t size, void *mem_user_data)
  3053. {
  3054. if (size >= UINT32_MAX) {
  3055. return NULL;
  3056. }
  3057. return wasm_runtime_realloc(ptr, (uint32)size);
  3058. }
  3059. /* clang-format off */
  3060. static uvwasi_mem_t uvwasi_allocator = {
  3061. .mem_user_data = 0,
  3062. .malloc = wasm_uvwasi_malloc,
  3063. .free = wasm_uvwasi_free,
  3064. .calloc = wasm_uvwasi_calloc,
  3065. .realloc = wasm_uvwasi_realloc
  3066. };
  3067. /* clang-format on */
  3068. bool
  3069. wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
  3070. const char *dir_list[], uint32 dir_count,
  3071. const char *map_dir_list[], uint32 map_dir_count,
  3072. const char *env[], uint32 env_count,
  3073. const char *addr_pool[], uint32 addr_pool_size,
  3074. const char *ns_lookup_pool[], uint32 ns_lookup_pool_size,
  3075. char *argv[], uint32 argc, os_raw_file_handle stdinfd,
  3076. os_raw_file_handle stdoutfd, os_raw_file_handle stderrfd,
  3077. char *error_buf, uint32 error_buf_size)
  3078. {
  3079. WASIContext *ctx;
  3080. uvwasi_t *uvwasi;
  3081. uvwasi_options_t init_options;
  3082. const char **envp = NULL;
  3083. uint64 total_size;
  3084. uint32 i;
  3085. bool ret = false;
  3086. ctx = runtime_malloc(sizeof(*ctx), module_inst, error_buf, error_buf_size);
  3087. if (!ctx)
  3088. return false;
  3089. uvwasi = &ctx->uvwasi;
  3090. /* Setup the initialization options */
  3091. uvwasi_options_init(&init_options);
  3092. init_options.allocator = &uvwasi_allocator;
  3093. init_options.argc = argc;
  3094. init_options.argv = (const char **)argv;
  3095. init_options.in = (stdinfd != -1) ? (uvwasi_fd_t)stdinfd : init_options.in;
  3096. init_options.out =
  3097. (stdoutfd != -1) ? (uvwasi_fd_t)stdoutfd : init_options.out;
  3098. init_options.err =
  3099. (stderrfd != -1) ? (uvwasi_fd_t)stderrfd : init_options.err;
  3100. if (dir_count > 0) {
  3101. init_options.preopenc = dir_count;
  3102. total_size = sizeof(uvwasi_preopen_t) * (uint64)init_options.preopenc;
  3103. init_options.preopens = (uvwasi_preopen_t *)runtime_malloc(
  3104. total_size, module_inst, error_buf, error_buf_size);
  3105. if (init_options.preopens == NULL)
  3106. goto fail;
  3107. for (i = 0; i < init_options.preopenc; i++) {
  3108. init_options.preopens[i].real_path = dir_list[i];
  3109. init_options.preopens[i].mapped_path =
  3110. (i < map_dir_count) ? map_dir_list[i] : dir_list[i];
  3111. }
  3112. }
  3113. if (env_count > 0) {
  3114. total_size = sizeof(char *) * (uint64)(env_count + 1);
  3115. envp =
  3116. runtime_malloc(total_size, module_inst, error_buf, error_buf_size);
  3117. if (envp == NULL)
  3118. goto fail;
  3119. for (i = 0; i < env_count; i++) {
  3120. envp[i] = env[i];
  3121. }
  3122. envp[env_count] = NULL;
  3123. init_options.envp = envp;
  3124. }
  3125. if (UVWASI_ESUCCESS != uvwasi_init(uvwasi, &init_options)) {
  3126. set_error_buf(error_buf, error_buf_size, "uvwasi init failed");
  3127. goto fail;
  3128. }
  3129. wasm_runtime_set_wasi_ctx(module_inst, ctx);
  3130. ret = true;
  3131. fail:
  3132. if (envp)
  3133. wasm_runtime_free((void *)envp);
  3134. if (init_options.preopens)
  3135. wasm_runtime_free(init_options.preopens);
  3136. if (!ret && uvwasi)
  3137. wasm_runtime_free(uvwasi);
  3138. return ret;
  3139. }
  3140. #endif /* end of WASM_ENABLE_UVWASI */
  3141. bool
  3142. wasm_runtime_is_wasi_mode(WASMModuleInstanceCommon *module_inst)
  3143. {
  3144. #if WASM_ENABLE_INTERP != 0
  3145. if (module_inst->module_type == Wasm_Module_Bytecode
  3146. && ((WASMModuleInstance *)module_inst)->module->import_wasi_api)
  3147. return true;
  3148. #endif
  3149. #if WASM_ENABLE_AOT != 0
  3150. if (module_inst->module_type == Wasm_Module_AoT
  3151. && ((AOTModule *)((AOTModuleInstance *)module_inst)->module)
  3152. ->import_wasi_api)
  3153. return true;
  3154. #endif
  3155. return false;
  3156. }
  3157. WASMFunctionInstanceCommon *
  3158. wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst)
  3159. {
  3160. uint32 i;
  3161. #if WASM_ENABLE_INTERP != 0
  3162. if (module_inst->module_type == Wasm_Module_Bytecode) {
  3163. WASMModuleInstance *wasm_inst = (WASMModuleInstance *)module_inst;
  3164. WASMFunctionInstance *func;
  3165. for (i = 0; i < wasm_inst->export_func_count; i++) {
  3166. if (!strcmp(wasm_inst->export_functions[i].name, "_start")) {
  3167. func = wasm_inst->export_functions[i].function;
  3168. if (func->u.func->func_type->param_count != 0
  3169. || func->u.func->func_type->result_count != 0) {
  3170. LOG_ERROR("Lookup wasi _start function failed: "
  3171. "invalid function type.\n");
  3172. return NULL;
  3173. }
  3174. return (WASMFunctionInstanceCommon *)func;
  3175. }
  3176. }
  3177. return NULL;
  3178. }
  3179. #endif
  3180. #if WASM_ENABLE_AOT != 0
  3181. if (module_inst->module_type == Wasm_Module_AoT) {
  3182. AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst;
  3183. AOTFunctionInstance *export_funcs =
  3184. (AOTFunctionInstance *)aot_inst->export_functions;
  3185. for (i = 0; i < aot_inst->export_func_count; i++) {
  3186. if (!strcmp(export_funcs[i].func_name, "_start")) {
  3187. AOTFuncType *func_type = export_funcs[i].u.func.func_type;
  3188. if (func_type->param_count != 0
  3189. || func_type->result_count != 0) {
  3190. LOG_ERROR("Lookup wasi _start function failed: "
  3191. "invalid function type.\n");
  3192. return NULL;
  3193. }
  3194. return (WASMFunctionInstanceCommon *)&export_funcs[i];
  3195. }
  3196. }
  3197. return NULL;
  3198. }
  3199. #endif /* end of WASM_ENABLE_AOT */
  3200. return NULL;
  3201. }
  3202. #if WASM_ENABLE_UVWASI == 0
  3203. void
  3204. wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst)
  3205. {
  3206. WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
  3207. if (wasi_ctx) {
  3208. if (wasi_ctx->argv_environ) {
  3209. argv_environ_destroy(wasi_ctx->argv_environ);
  3210. wasm_runtime_free(wasi_ctx->argv_environ);
  3211. }
  3212. if (wasi_ctx->curfds) {
  3213. fd_table_destroy(wasi_ctx->curfds);
  3214. wasm_runtime_free(wasi_ctx->curfds);
  3215. }
  3216. if (wasi_ctx->prestats) {
  3217. fd_prestats_destroy(wasi_ctx->prestats);
  3218. wasm_runtime_free(wasi_ctx->prestats);
  3219. }
  3220. if (wasi_ctx->addr_pool) {
  3221. addr_pool_destroy(wasi_ctx->addr_pool);
  3222. wasm_runtime_free(wasi_ctx->addr_pool);
  3223. }
  3224. if (wasi_ctx->argv_buf)
  3225. wasm_runtime_free(wasi_ctx->argv_buf);
  3226. if (wasi_ctx->argv_list)
  3227. wasm_runtime_free(wasi_ctx->argv_list);
  3228. if (wasi_ctx->env_buf)
  3229. wasm_runtime_free(wasi_ctx->env_buf);
  3230. if (wasi_ctx->env_list)
  3231. wasm_runtime_free(wasi_ctx->env_list);
  3232. if (wasi_ctx->ns_lookup_buf)
  3233. wasm_runtime_free(wasi_ctx->ns_lookup_buf);
  3234. if (wasi_ctx->ns_lookup_list)
  3235. wasm_runtime_free(wasi_ctx->ns_lookup_list);
  3236. wasm_runtime_free(wasi_ctx);
  3237. }
  3238. }
  3239. #else
  3240. void
  3241. wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst)
  3242. {
  3243. WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
  3244. if (wasi_ctx) {
  3245. uvwasi_destroy(&wasi_ctx->uvwasi);
  3246. wasm_runtime_free(wasi_ctx);
  3247. }
  3248. }
  3249. #endif
  3250. uint32_t
  3251. wasm_runtime_get_wasi_exit_code(WASMModuleInstanceCommon *module_inst)
  3252. {
  3253. WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
  3254. #if WASM_ENABLE_THREAD_MGR != 0
  3255. WASMCluster *cluster;
  3256. WASMExecEnv *exec_env;
  3257. exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
  3258. if (exec_env && (cluster = wasm_exec_env_get_cluster(exec_env))) {
  3259. /**
  3260. * The main thread may exit earlier than other threads, and
  3261. * the exit_code of wasi_ctx may be changed by other thread
  3262. * when it runs into wasi_proc_exit, here we wait until all
  3263. * other threads exit to avoid getting invalid exit_code.
  3264. */
  3265. wasm_cluster_wait_for_all_except_self(cluster, exec_env);
  3266. }
  3267. #endif
  3268. return wasi_ctx->exit_code;
  3269. }
  3270. #endif /* end of WASM_ENABLE_LIBC_WASI */
  3271. WASMModuleCommon *
  3272. wasm_exec_env_get_module(WASMExecEnv *exec_env)
  3273. {
  3274. WASMModuleInstanceCommon *module_inst_comm =
  3275. wasm_runtime_get_module_inst(exec_env);
  3276. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  3277. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  3278. || module_inst_comm->module_type == Wasm_Module_AoT);
  3279. return (WASMModuleCommon *)module_inst->module;
  3280. }
  3281. #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
  3282. const uint8 *
  3283. wasm_runtime_get_custom_section(WASMModuleCommon *const module_comm,
  3284. const char *name, uint32 *len)
  3285. {
  3286. #if WASM_ENABLE_INTERP != 0
  3287. if (module_comm->module_type == Wasm_Module_Bytecode)
  3288. return wasm_loader_get_custom_section((WASMModule *)module_comm, name,
  3289. len);
  3290. #endif
  3291. #if WASM_ENABLE_AOT != 0
  3292. if (module_comm->module_type == Wasm_Module_AoT)
  3293. return aot_get_custom_section((AOTModule *)module_comm, name, len);
  3294. #endif
  3295. return NULL;
  3296. }
  3297. #endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */
  3298. static union {
  3299. int a;
  3300. char b;
  3301. } __ue = { .a = 1 };
  3302. #define is_little_endian() (__ue.b == 1) /* NOLINT */
  3303. int32
  3304. wasm_runtime_get_import_count(WASMModuleCommon *const module)
  3305. {
  3306. if (!module) {
  3307. bh_assert(0);
  3308. return -1;
  3309. }
  3310. #if WASM_ENABLE_AOT != 0
  3311. if (module->module_type == Wasm_Module_AoT) {
  3312. const AOTModule *aot_module = (const AOTModule *)module;
  3313. return (int32)(aot_module->import_func_count
  3314. + aot_module->import_global_count
  3315. + aot_module->import_table_count
  3316. + aot_module->import_memory_count);
  3317. }
  3318. #endif
  3319. #if WASM_ENABLE_INTERP != 0
  3320. if (module->module_type == Wasm_Module_Bytecode) {
  3321. const WASMModule *wasm_module = (const WASMModule *)module;
  3322. return (int32)wasm_module->import_count;
  3323. }
  3324. #endif
  3325. return -1;
  3326. }
  3327. void
  3328. wasm_runtime_get_import_type(WASMModuleCommon *const module, int32 import_index,
  3329. wasm_import_t *import_type)
  3330. {
  3331. if (!import_type) {
  3332. bh_assert(0);
  3333. return;
  3334. }
  3335. memset(import_type, 0, sizeof(wasm_import_t));
  3336. if (!module) {
  3337. bh_assert(0);
  3338. return;
  3339. }
  3340. #if WASM_ENABLE_AOT != 0
  3341. if (module->module_type == Wasm_Module_AoT) {
  3342. const AOTModule *aot_module = (const AOTModule *)module;
  3343. uint32 func_index = (uint32)import_index;
  3344. if (func_index < aot_module->import_func_count) {
  3345. const AOTImportFunc *aot_import_func =
  3346. &aot_module->import_funcs[func_index];
  3347. import_type->module_name = aot_import_func->module_name;
  3348. import_type->name = aot_import_func->func_name;
  3349. import_type->kind = WASM_IMPORT_EXPORT_KIND_FUNC;
  3350. import_type->linked =
  3351. aot_import_func->func_ptr_linked ? true : false;
  3352. import_type->u.func_type = aot_import_func->func_type;
  3353. return;
  3354. }
  3355. uint32 global_index = func_index - aot_module->import_func_count;
  3356. if (global_index < aot_module->import_global_count) {
  3357. const AOTImportGlobal *aot_import_global =
  3358. &aot_module->import_globals[global_index];
  3359. import_type->module_name = aot_import_global->module_name;
  3360. import_type->name = aot_import_global->global_name;
  3361. import_type->kind = WASM_IMPORT_EXPORT_KIND_GLOBAL;
  3362. import_type->linked = aot_import_global->is_linked;
  3363. import_type->u.global_type =
  3364. (WASMGlobalType *)&aot_import_global->type;
  3365. return;
  3366. }
  3367. uint32 table_index = global_index - aot_module->import_global_count;
  3368. if (table_index < aot_module->import_table_count) {
  3369. const AOTImportTable *aot_import_table =
  3370. &aot_module->import_tables[table_index];
  3371. import_type->module_name = aot_import_table->module_name;
  3372. import_type->name = aot_import_table->table_name;
  3373. import_type->kind = WASM_IMPORT_EXPORT_KIND_TABLE;
  3374. import_type->linked = false;
  3375. return;
  3376. }
  3377. uint32 memory_index = table_index - aot_module->import_table_count;
  3378. if (memory_index < aot_module->import_memory_count) {
  3379. const AOTImportMemory *aot_import_memory =
  3380. &aot_module->import_memories[memory_index];
  3381. import_type->module_name = aot_import_memory->module_name;
  3382. import_type->name = aot_import_memory->memory_name;
  3383. import_type->kind = WASM_IMPORT_EXPORT_KIND_MEMORY;
  3384. import_type->linked = false;
  3385. return;
  3386. }
  3387. bh_assert(0);
  3388. return;
  3389. }
  3390. #endif
  3391. #if WASM_ENABLE_INTERP != 0
  3392. if (module->module_type == Wasm_Module_Bytecode) {
  3393. const WASMModule *wasm_module = (const WASMModule *)module;
  3394. if ((uint32)import_index >= wasm_module->import_count) {
  3395. bh_assert(0);
  3396. return;
  3397. }
  3398. const WASMImport *wasm_import = &wasm_module->imports[import_index];
  3399. import_type->module_name = wasm_import->u.names.module_name;
  3400. import_type->name = wasm_import->u.names.field_name;
  3401. import_type->kind = wasm_import->kind;
  3402. switch (import_type->kind) {
  3403. case WASM_IMPORT_EXPORT_KIND_FUNC:
  3404. import_type->linked = wasm_import->u.function.func_ptr_linked;
  3405. import_type->u.func_type = wasm_import->u.function.func_type;
  3406. break;
  3407. case WASM_IMPORT_EXPORT_KIND_GLOBAL:
  3408. import_type->linked = wasm_import->u.global.is_linked;
  3409. import_type->u.global_type =
  3410. (WASMGlobalType *)&wasm_import->u.global.type;
  3411. break;
  3412. case WASM_IMPORT_EXPORT_KIND_TABLE:
  3413. /* not supported */
  3414. import_type->linked = false;
  3415. break;
  3416. case WASM_IMPORT_EXPORT_KIND_MEMORY:
  3417. /* not supported */
  3418. import_type->linked = false;
  3419. break;
  3420. default:
  3421. bh_assert(0);
  3422. break;
  3423. }
  3424. return;
  3425. }
  3426. #endif
  3427. }
  3428. int32
  3429. wasm_runtime_get_export_count(WASMModuleCommon *const module)
  3430. {
  3431. if (!module) {
  3432. bh_assert(0);
  3433. return -1;
  3434. }
  3435. #if WASM_ENABLE_AOT != 0
  3436. if (module->module_type == Wasm_Module_AoT) {
  3437. const AOTModule *aot_module = (const AOTModule *)module;
  3438. return (int32)aot_module->export_count;
  3439. }
  3440. #endif
  3441. #if WASM_ENABLE_INTERP != 0
  3442. if (module->module_type == Wasm_Module_Bytecode) {
  3443. const WASMModule *wasm_module = (const WASMModule *)module;
  3444. return (int32)wasm_module->export_count;
  3445. }
  3446. #endif
  3447. return -1;
  3448. }
  3449. void
  3450. wasm_runtime_get_export_type(WASMModuleCommon *const module, int32 export_index,
  3451. wasm_export_t *export_type)
  3452. {
  3453. if (!export_type) {
  3454. bh_assert(0);
  3455. return;
  3456. }
  3457. memset(export_type, 0, sizeof(wasm_export_t));
  3458. if (!module) {
  3459. bh_assert(0);
  3460. return;
  3461. }
  3462. #if WASM_ENABLE_AOT != 0
  3463. if (module->module_type == Wasm_Module_AoT) {
  3464. const AOTModule *aot_module = (const AOTModule *)module;
  3465. if ((uint32)export_index >= aot_module->export_count) {
  3466. bh_assert(0);
  3467. return;
  3468. }
  3469. const AOTExport *aot_export = &aot_module->exports[export_index];
  3470. export_type->name = aot_export->name;
  3471. export_type->kind = aot_export->kind;
  3472. switch (export_type->kind) {
  3473. case WASM_IMPORT_EXPORT_KIND_FUNC:
  3474. export_type->u.func_type =
  3475. (AOTFuncType *)aot_module
  3476. ->types[aot_module->func_type_indexes
  3477. [aot_export->index
  3478. - aot_module->import_func_count]];
  3479. break;
  3480. case WASM_IMPORT_EXPORT_KIND_GLOBAL:
  3481. export_type->u.global_type =
  3482. &aot_module
  3483. ->globals[aot_export->index
  3484. - aot_module->import_global_count]
  3485. .type;
  3486. break;
  3487. case WASM_IMPORT_EXPORT_KIND_TABLE:
  3488. /* not supported */
  3489. // export_type->linked = false;
  3490. break;
  3491. case WASM_IMPORT_EXPORT_KIND_MEMORY:
  3492. /* not supported */
  3493. // export_type->linked = false;
  3494. break;
  3495. default:
  3496. bh_assert(0);
  3497. break;
  3498. }
  3499. return;
  3500. }
  3501. #endif
  3502. #if WASM_ENABLE_INTERP != 0
  3503. if (module->module_type == Wasm_Module_Bytecode) {
  3504. const WASMModule *wasm_module = (const WASMModule *)module;
  3505. if ((uint32)export_index >= wasm_module->export_count) {
  3506. bh_assert(0);
  3507. return;
  3508. }
  3509. const WASMExport *wasm_export = &wasm_module->exports[export_index];
  3510. export_type->name = wasm_export->name;
  3511. export_type->kind = wasm_export->kind;
  3512. switch (export_type->kind) {
  3513. case WASM_IMPORT_EXPORT_KIND_FUNC:
  3514. export_type->u.func_type =
  3515. wasm_module
  3516. ->functions[wasm_export->index
  3517. - wasm_module->import_function_count]
  3518. ->func_type;
  3519. break;
  3520. case WASM_IMPORT_EXPORT_KIND_GLOBAL:
  3521. export_type->u.global_type =
  3522. &wasm_module
  3523. ->globals[wasm_export->index
  3524. - wasm_module->import_global_count]
  3525. .type;
  3526. break;
  3527. case WASM_IMPORT_EXPORT_KIND_TABLE:
  3528. /* not supported */
  3529. // export_type->linked = false;
  3530. break;
  3531. case WASM_IMPORT_EXPORT_KIND_MEMORY:
  3532. /* not supported */
  3533. // export_type->linked = false;
  3534. break;
  3535. bh_assert(0);
  3536. break;
  3537. }
  3538. return;
  3539. }
  3540. #endif
  3541. }
  3542. uint32
  3543. wasm_func_type_get_param_count(WASMFuncType *const func_type)
  3544. {
  3545. bh_assert(func_type);
  3546. return func_type->param_count;
  3547. }
  3548. wasm_valkind_t
  3549. wasm_func_type_get_param_valkind(WASMFuncType *const func_type,
  3550. uint32 param_index)
  3551. {
  3552. if (!func_type || (param_index >= func_type->param_count)) {
  3553. bh_assert(0);
  3554. return (wasm_valkind_t)-1;
  3555. }
  3556. switch (func_type->types[param_index]) {
  3557. case VALUE_TYPE_I32:
  3558. return WASM_I32;
  3559. case VALUE_TYPE_I64:
  3560. return WASM_I64;
  3561. case VALUE_TYPE_F32:
  3562. return WASM_F32;
  3563. case VALUE_TYPE_F64:
  3564. return WASM_F64;
  3565. case VALUE_TYPE_V128:
  3566. return WASM_V128;
  3567. case VALUE_TYPE_FUNCREF:
  3568. return WASM_FUNCREF;
  3569. case VALUE_TYPE_EXTERNREF:
  3570. case VALUE_TYPE_VOID:
  3571. default:
  3572. {
  3573. bh_assert(0);
  3574. return (wasm_valkind_t)-1;
  3575. }
  3576. }
  3577. }
  3578. uint32
  3579. wasm_func_type_get_result_count(WASMFuncType *const func_type)
  3580. {
  3581. bh_assert(func_type);
  3582. return func_type->result_count;
  3583. }
  3584. wasm_valkind_t
  3585. wasm_func_type_get_result_valkind(WASMFuncType *const func_type,
  3586. uint32 result_index)
  3587. {
  3588. if (!func_type || (result_index >= func_type->result_count)) {
  3589. bh_assert(0);
  3590. return (wasm_valkind_t)-1;
  3591. }
  3592. switch (func_type->types[func_type->param_count + result_index]) {
  3593. case VALUE_TYPE_I32:
  3594. return WASM_I32;
  3595. case VALUE_TYPE_I64:
  3596. return WASM_I64;
  3597. case VALUE_TYPE_F32:
  3598. return WASM_F32;
  3599. case VALUE_TYPE_F64:
  3600. return WASM_F64;
  3601. case VALUE_TYPE_FUNCREF:
  3602. return WASM_FUNCREF;
  3603. #if WASM_ENABLE_SIMD != 0
  3604. case VALUE_TYPE_V128:
  3605. return WASM_V128;
  3606. #endif
  3607. #if WASM_ENABLE_REF_TYPES != 0
  3608. case VALUE_TYPE_EXTERNREF:
  3609. #endif
  3610. case VALUE_TYPE_VOID:
  3611. default:
  3612. {
  3613. bh_assert(0);
  3614. return (wasm_valkind_t)-1;
  3615. }
  3616. }
  3617. }
  3618. wasm_valkind_t
  3619. wasm_global_type_get_valkind(const wasm_global_type_t global_type)
  3620. {
  3621. bh_assert(global_type);
  3622. return val_type_to_val_kind(global_type->val_type);
  3623. }
  3624. bool
  3625. wasm_global_type_get_mutable(const wasm_global_type_t global_type)
  3626. {
  3627. bh_assert(global_type);
  3628. return global_type->is_mutable;
  3629. }
  3630. bool
  3631. wasm_runtime_register_natives(const char *module_name,
  3632. NativeSymbol *native_symbols,
  3633. uint32 n_native_symbols)
  3634. {
  3635. return wasm_native_register_natives(module_name, native_symbols,
  3636. n_native_symbols);
  3637. }
  3638. bool
  3639. wasm_runtime_register_natives_raw(const char *module_name,
  3640. NativeSymbol *native_symbols,
  3641. uint32 n_native_symbols)
  3642. {
  3643. return wasm_native_register_natives_raw(module_name, native_symbols,
  3644. n_native_symbols);
  3645. }
  3646. bool
  3647. wasm_runtime_unregister_natives(const char *module_name,
  3648. NativeSymbol *native_symbols)
  3649. {
  3650. return wasm_native_unregister_natives(module_name, native_symbols);
  3651. }
  3652. bool
  3653. wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
  3654. const WASMFuncType *func_type,
  3655. const char *signature, void *attachment,
  3656. uint32 *argv, uint32 argc, uint32 *argv_ret)
  3657. {
  3658. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  3659. typedef void (*NativeRawFuncPtr)(WASMExecEnv *, uint64 *);
  3660. NativeRawFuncPtr invoke_native_raw = (NativeRawFuncPtr)func_ptr;
  3661. uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size, arg_i64;
  3662. uint32 *argv_src = argv, i, argc1, ptr_len;
  3663. uint32 arg_i32;
  3664. bool ret = false;
  3665. argc1 = func_type->param_count;
  3666. if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
  3667. size = sizeof(uint64) * (uint64)argc1;
  3668. if (!(argv1 = runtime_malloc((uint32)size, exec_env->module_inst, NULL,
  3669. 0))) {
  3670. return false;
  3671. }
  3672. }
  3673. argv_dst = argv1;
  3674. /* Traverse secondly to fill in each argument */
  3675. for (i = 0; i < func_type->param_count; i++, argv_dst++) {
  3676. switch (func_type->types[i]) {
  3677. case VALUE_TYPE_I32:
  3678. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  3679. case VALUE_TYPE_FUNCREF:
  3680. #endif
  3681. {
  3682. *(uint32 *)argv_dst = arg_i32 = *argv_src++;
  3683. /* TODO: memory64 if future there is a way for supporting
  3684. * wasm64 and wasm32 in libc at the same time, remove the
  3685. * macro control */
  3686. #if WASM_ENABLE_MEMORY64 == 0
  3687. if (signature) {
  3688. if (signature[i + 1] == '*') {
  3689. /* param is a pointer */
  3690. if (signature[i + 2] == '~')
  3691. /* pointer with length followed */
  3692. ptr_len = *argv_src;
  3693. else
  3694. /* pointer without length followed */
  3695. ptr_len = 1;
  3696. if (!wasm_runtime_validate_app_addr(
  3697. module, (uint64)arg_i32, (uint64)ptr_len))
  3698. goto fail;
  3699. *(uintptr_t *)argv_dst =
  3700. (uintptr_t)wasm_runtime_addr_app_to_native(
  3701. module, (uint64)arg_i32);
  3702. }
  3703. else if (signature[i + 1] == '$') {
  3704. /* param is a string */
  3705. if (!wasm_runtime_validate_app_str_addr(
  3706. module, (uint64)arg_i32))
  3707. goto fail;
  3708. *(uintptr_t *)argv_dst =
  3709. (uintptr_t)wasm_runtime_addr_app_to_native(
  3710. module, (uint64)arg_i32);
  3711. }
  3712. }
  3713. #endif
  3714. break;
  3715. }
  3716. case VALUE_TYPE_I64:
  3717. #if WASM_ENABLE_MEMORY64 != 0
  3718. {
  3719. PUT_I64_TO_ADDR((uint32 *)argv_dst,
  3720. GET_I64_FROM_ADDR(argv_src));
  3721. argv_src += 2;
  3722. arg_i64 = *argv_dst;
  3723. if (signature) {
  3724. /* TODO: memory64 pointer with length need a new symbol
  3725. * to represent type i64, with '~' still represent i32
  3726. * length */
  3727. if (signature[i + 1] == '*') {
  3728. /* param is a pointer */
  3729. if (signature[i + 2] == '~')
  3730. /* pointer with length followed */
  3731. ptr_len = *argv_src;
  3732. else
  3733. /* pointer without length followed */
  3734. ptr_len = 1;
  3735. if (!wasm_runtime_validate_app_addr(module, arg_i64,
  3736. (uint64)ptr_len))
  3737. goto fail;
  3738. *argv_dst = (uint64)wasm_runtime_addr_app_to_native(
  3739. module, arg_i64);
  3740. }
  3741. else if (signature[i + 1] == '$') {
  3742. /* param is a string */
  3743. if (!wasm_runtime_validate_app_str_addr(module,
  3744. arg_i64))
  3745. goto fail;
  3746. *argv_dst = (uint64)wasm_runtime_addr_app_to_native(
  3747. module, arg_i64);
  3748. }
  3749. }
  3750. break;
  3751. }
  3752. #endif
  3753. case VALUE_TYPE_F64:
  3754. bh_memcpy_s(argv_dst, sizeof(uint64), argv_src,
  3755. sizeof(uint32) * 2);
  3756. argv_src += 2;
  3757. break;
  3758. case VALUE_TYPE_F32:
  3759. *(float32 *)argv_dst = *(float32 *)argv_src++;
  3760. break;
  3761. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  3762. case VALUE_TYPE_EXTERNREF:
  3763. {
  3764. uint32 externref_idx = *argv_src++;
  3765. void *externref_obj;
  3766. if (!wasm_externref_ref2obj(externref_idx, &externref_obj))
  3767. goto fail;
  3768. bh_memcpy_s(argv_dst, sizeof(uintptr_t), argv_src,
  3769. sizeof(uintptr_t));
  3770. break;
  3771. }
  3772. #endif
  3773. #if WASM_ENABLE_GC != 0
  3774. case REF_TYPE_FUNCREF:
  3775. case REF_TYPE_EXTERNREF:
  3776. case REF_TYPE_ANYREF:
  3777. case REF_TYPE_EQREF:
  3778. case REF_TYPE_HT_NULLABLE:
  3779. case REF_TYPE_HT_NON_NULLABLE:
  3780. case REF_TYPE_I31REF:
  3781. case REF_TYPE_NULLFUNCREF:
  3782. case REF_TYPE_NULLEXTERNREF:
  3783. case REF_TYPE_STRUCTREF:
  3784. case REF_TYPE_ARRAYREF:
  3785. case REF_TYPE_NULLREF:
  3786. #if WASM_ENABLE_STRINGREF != 0
  3787. case REF_TYPE_STRINGREF:
  3788. case REF_TYPE_STRINGVIEWWTF8:
  3789. case REF_TYPE_STRINGVIEWWTF16:
  3790. case REF_TYPE_STRINGVIEWITER:
  3791. #endif
  3792. {
  3793. bh_memcpy_s(argv_dst, sizeof(uintptr_t), argv_src,
  3794. sizeof(uintptr_t));
  3795. argv_src += sizeof(uintptr_t) / sizeof(uint32);
  3796. break;
  3797. }
  3798. #endif
  3799. default:
  3800. bh_assert(0);
  3801. break;
  3802. }
  3803. }
  3804. exec_env->attachment = attachment;
  3805. invoke_native_raw(exec_env, argv1);
  3806. exec_env->attachment = NULL;
  3807. if (func_type->result_count > 0) {
  3808. switch (func_type->types[func_type->param_count]) {
  3809. case VALUE_TYPE_I32:
  3810. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  3811. case VALUE_TYPE_FUNCREF:
  3812. #endif
  3813. argv_ret[0] = *(uint32 *)argv1;
  3814. break;
  3815. case VALUE_TYPE_F32:
  3816. *(float32 *)argv_ret = *(float32 *)argv1;
  3817. break;
  3818. case VALUE_TYPE_I64:
  3819. case VALUE_TYPE_F64:
  3820. bh_memcpy_s(argv_ret, sizeof(uint32) * 2, argv1,
  3821. sizeof(uint64));
  3822. break;
  3823. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  3824. case VALUE_TYPE_EXTERNREF:
  3825. {
  3826. uint32 externref_idx;
  3827. uint64 externref_obj;
  3828. bh_memcpy_s(&externref_obj, sizeof(uint64), argv1,
  3829. sizeof(uint64));
  3830. if (!wasm_externref_obj2ref(exec_env->module_inst,
  3831. (void *)(uintptr_t)externref_obj,
  3832. &externref_idx))
  3833. goto fail;
  3834. argv_ret[0] = externref_idx;
  3835. break;
  3836. }
  3837. #endif
  3838. #if WASM_ENABLE_GC != 0
  3839. case REF_TYPE_FUNCREF:
  3840. case REF_TYPE_EXTERNREF:
  3841. case REF_TYPE_ANYREF:
  3842. case REF_TYPE_EQREF:
  3843. case REF_TYPE_HT_NULLABLE:
  3844. case REF_TYPE_HT_NON_NULLABLE:
  3845. case REF_TYPE_I31REF:
  3846. case REF_TYPE_NULLFUNCREF:
  3847. case REF_TYPE_NULLEXTERNREF:
  3848. case REF_TYPE_STRUCTREF:
  3849. case REF_TYPE_ARRAYREF:
  3850. case REF_TYPE_NULLREF:
  3851. #if WASM_ENABLE_STRINGREF != 0
  3852. case REF_TYPE_STRINGREF:
  3853. case REF_TYPE_STRINGVIEWWTF8:
  3854. case REF_TYPE_STRINGVIEWWTF16:
  3855. case REF_TYPE_STRINGVIEWITER:
  3856. #endif
  3857. {
  3858. bh_memcpy_s(argv_ret, sizeof(uintptr_t), argv1,
  3859. sizeof(uintptr_t));
  3860. break;
  3861. }
  3862. #endif
  3863. default:
  3864. bh_assert(0);
  3865. break;
  3866. }
  3867. }
  3868. ret = !wasm_runtime_copy_exception(module, NULL);
  3869. fail:
  3870. if (argv1 != argv_buf)
  3871. wasm_runtime_free(argv1);
  3872. #if WASM_ENABLE_MEMORY64 == 0
  3873. (void)arg_i64;
  3874. #endif
  3875. return ret;
  3876. }
  3877. /**
  3878. * Implementation of wasm_runtime_invoke_native()
  3879. */
  3880. /* The invoke native implementation on ARM platform with VFP co-processor */
  3881. #if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP) \
  3882. || defined(BUILD_TARGET_RISCV32_ILP32D) \
  3883. || defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_ARC)
  3884. typedef void (*GenericFunctionPointer)();
  3885. void
  3886. invokeNative(GenericFunctionPointer f, uint32 *args, uint32 n_stacks);
  3887. typedef float64 (*Float64FuncPtr)(GenericFunctionPointer, uint32 *, uint32);
  3888. typedef float32 (*Float32FuncPtr)(GenericFunctionPointer, uint32 *, uint32);
  3889. typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint32 *, uint32);
  3890. typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint32 *, uint32);
  3891. typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint32 *, uint32);
  3892. static volatile Float64FuncPtr invokeNative_Float64 =
  3893. (Float64FuncPtr)(uintptr_t)invokeNative;
  3894. static volatile Float32FuncPtr invokeNative_Float32 =
  3895. (Float32FuncPtr)(uintptr_t)invokeNative;
  3896. static volatile Int64FuncPtr invokeNative_Int64 =
  3897. (Int64FuncPtr)(uintptr_t)invokeNative;
  3898. static volatile Int32FuncPtr invokeNative_Int32 =
  3899. (Int32FuncPtr)(uintptr_t)invokeNative;
  3900. static volatile VoidFuncPtr invokeNative_Void =
  3901. (VoidFuncPtr)(uintptr_t)invokeNative;
  3902. #if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP)
  3903. #define MAX_REG_INTS 4
  3904. #define MAX_REG_FLOATS 16
  3905. #else
  3906. #define MAX_REG_INTS 8
  3907. #define MAX_REG_FLOATS 8
  3908. #endif
  3909. bool
  3910. wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
  3911. const WASMFuncType *func_type, const char *signature,
  3912. void *attachment, uint32 *argv, uint32 argc,
  3913. uint32 *argv_ret)
  3914. {
  3915. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  3916. /* argv buf layout: int args(fix cnt) + float args(fix cnt) + stack args
  3917. */
  3918. uint32 argv_buf[32], *argv1 = argv_buf, *ints, *stacks, size;
  3919. uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0;
  3920. uint32 arg_i32, ptr_len;
  3921. uint32 result_count = func_type->result_count;
  3922. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  3923. bool ret = false;
  3924. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  3925. bool is_aot_func = (NULL == signature);
  3926. #endif
  3927. #if !defined(BUILD_TARGET_RISCV32_ILP32) && !defined(BUILD_TARGET_ARC)
  3928. uint32 *fps;
  3929. int n_fps = 0;
  3930. #else
  3931. #define fps ints
  3932. #define n_fps n_ints
  3933. #endif
  3934. n_ints++; /* exec env */
  3935. /* Traverse firstly to calculate stack args count */
  3936. for (i = 0; i < func_type->param_count; i++) {
  3937. switch (func_type->types[i]) {
  3938. case VALUE_TYPE_I32:
  3939. #if WASM_ENABLE_GC != 0
  3940. case REF_TYPE_FUNCREF:
  3941. case REF_TYPE_EXTERNREF:
  3942. case REF_TYPE_ANYREF:
  3943. case REF_TYPE_EQREF:
  3944. case REF_TYPE_HT_NULLABLE:
  3945. case REF_TYPE_HT_NON_NULLABLE:
  3946. case REF_TYPE_I31REF:
  3947. case REF_TYPE_NULLFUNCREF:
  3948. case REF_TYPE_NULLEXTERNREF:
  3949. case REF_TYPE_STRUCTREF:
  3950. case REF_TYPE_ARRAYREF:
  3951. case REF_TYPE_NULLREF:
  3952. #if WASM_ENABLE_STRINGREF != 0
  3953. case REF_TYPE_STRINGREF:
  3954. case REF_TYPE_STRINGVIEWWTF8:
  3955. case REF_TYPE_STRINGVIEWWTF16:
  3956. case REF_TYPE_STRINGVIEWITER:
  3957. #endif
  3958. #endif
  3959. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  3960. case VALUE_TYPE_FUNCREF:
  3961. case VALUE_TYPE_EXTERNREF:
  3962. #endif
  3963. if (n_ints < MAX_REG_INTS)
  3964. n_ints++;
  3965. else
  3966. n_stacks++;
  3967. break;
  3968. case VALUE_TYPE_I64:
  3969. if (n_ints < MAX_REG_INTS - 1) {
  3970. #if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP)
  3971. /* 64-bit data must be 8 bytes aligned in arm */
  3972. if (n_ints & 1)
  3973. n_ints++;
  3974. #endif
  3975. n_ints += 2;
  3976. }
  3977. #if defined(BUILD_TARGET_RISCV32_ILP32) \
  3978. || defined(BUILD_TARGET_RISCV32_ILP32D) || defined(BUILD_TARGET_ARC)
  3979. /* part in register, part in stack */
  3980. else if (n_ints == MAX_REG_INTS - 1) {
  3981. n_ints++;
  3982. n_stacks++;
  3983. }
  3984. #endif
  3985. else {
  3986. /* 64-bit data in stack must be 8 bytes aligned
  3987. in arm and riscv32 */
  3988. #if !defined(BUILD_TARGET_ARC)
  3989. if (n_stacks & 1)
  3990. n_stacks++;
  3991. #endif
  3992. n_stacks += 2;
  3993. }
  3994. break;
  3995. #if !defined(BUILD_TARGET_RISCV32_ILP32D)
  3996. case VALUE_TYPE_F32:
  3997. if (n_fps < MAX_REG_FLOATS)
  3998. n_fps++;
  3999. else
  4000. n_stacks++;
  4001. break;
  4002. case VALUE_TYPE_F64:
  4003. if (n_fps < MAX_REG_FLOATS - 1) {
  4004. #if !defined(BUILD_TARGET_RISCV32_ILP32) && !defined(BUILD_TARGET_ARC)
  4005. /* 64-bit data must be 8 bytes aligned in arm */
  4006. if (n_fps & 1)
  4007. n_fps++;
  4008. #endif
  4009. n_fps += 2;
  4010. }
  4011. #if defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_ARC)
  4012. else if (n_fps == MAX_REG_FLOATS - 1) {
  4013. n_fps++;
  4014. n_stacks++;
  4015. }
  4016. #endif
  4017. else {
  4018. /* 64-bit data in stack must be 8 bytes aligned
  4019. in arm and riscv32 */
  4020. #if !defined(BUILD_TARGET_ARC)
  4021. if (n_stacks & 1)
  4022. n_stacks++;
  4023. #endif
  4024. n_stacks += 2;
  4025. }
  4026. break;
  4027. #else /* BUILD_TARGET_RISCV32_ILP32D */
  4028. case VALUE_TYPE_F32:
  4029. case VALUE_TYPE_F64:
  4030. if (n_fps < MAX_REG_FLOATS) {
  4031. n_fps++;
  4032. }
  4033. else if (func_type->types[i] == VALUE_TYPE_F32
  4034. && n_ints < MAX_REG_INTS) {
  4035. /* use int reg firstly if available */
  4036. n_ints++;
  4037. }
  4038. else if (func_type->types[i] == VALUE_TYPE_F64
  4039. && n_ints < MAX_REG_INTS - 1) {
  4040. /* use int regs firstly if available */
  4041. if (n_ints & 1)
  4042. n_ints++;
  4043. ints += 2;
  4044. }
  4045. else {
  4046. /* 64-bit data in stack must be 8 bytes aligned in riscv32
  4047. */
  4048. if (n_stacks & 1)
  4049. n_stacks++;
  4050. n_stacks += 2;
  4051. }
  4052. break;
  4053. #endif /* BUILD_TARGET_RISCV32_ILP32D */
  4054. default:
  4055. bh_assert(0);
  4056. break;
  4057. }
  4058. }
  4059. for (i = 0; i < ext_ret_count; i++) {
  4060. if (n_ints < MAX_REG_INTS)
  4061. n_ints++;
  4062. else
  4063. n_stacks++;
  4064. }
  4065. #if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP)
  4066. argc1 = MAX_REG_INTS + MAX_REG_FLOATS + n_stacks;
  4067. #elif defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_ARC)
  4068. argc1 = MAX_REG_INTS + n_stacks;
  4069. #else /* for BUILD_TARGET_RISCV32_ILP32D */
  4070. argc1 = MAX_REG_INTS + MAX_REG_FLOATS * 2 + n_stacks;
  4071. #endif
  4072. if (argc1 > sizeof(argv_buf) / sizeof(uint32)) {
  4073. size = sizeof(uint32) * (uint32)argc1;
  4074. if (!(argv1 = runtime_malloc((uint32)size, exec_env->module_inst, NULL,
  4075. 0))) {
  4076. return false;
  4077. }
  4078. }
  4079. ints = argv1;
  4080. #if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP)
  4081. fps = ints + MAX_REG_INTS;
  4082. stacks = fps + MAX_REG_FLOATS;
  4083. #elif defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_ARC)
  4084. stacks = ints + MAX_REG_INTS;
  4085. #else /* for BUILD_TARGET_RISCV32_ILP32D */
  4086. fps = ints + MAX_REG_INTS;
  4087. stacks = fps + MAX_REG_FLOATS * 2;
  4088. #endif
  4089. n_ints = 0;
  4090. n_fps = 0;
  4091. n_stacks = 0;
  4092. ints[n_ints++] = (uint32)(uintptr_t)exec_env;
  4093. /* Traverse secondly to fill in each argument */
  4094. for (i = 0; i < func_type->param_count; i++) {
  4095. switch (func_type->types[i]) {
  4096. case VALUE_TYPE_I32:
  4097. #if WASM_ENABLE_GC != 0
  4098. case REF_TYPE_FUNCREF:
  4099. case REF_TYPE_EXTERNREF:
  4100. case REF_TYPE_ANYREF:
  4101. case REF_TYPE_EQREF:
  4102. case REF_TYPE_HT_NULLABLE:
  4103. case REF_TYPE_HT_NON_NULLABLE:
  4104. case REF_TYPE_I31REF:
  4105. case REF_TYPE_NULLFUNCREF:
  4106. case REF_TYPE_NULLEXTERNREF:
  4107. case REF_TYPE_STRUCTREF:
  4108. case REF_TYPE_ARRAYREF:
  4109. case REF_TYPE_NULLREF:
  4110. #if WASM_ENABLE_STRINGREF != 0
  4111. case REF_TYPE_STRINGREF:
  4112. case REF_TYPE_STRINGVIEWWTF8:
  4113. case REF_TYPE_STRINGVIEWWTF16:
  4114. case REF_TYPE_STRINGVIEWITER:
  4115. #endif
  4116. #endif
  4117. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4118. case VALUE_TYPE_FUNCREF:
  4119. #endif
  4120. {
  4121. arg_i32 = *argv_src++;
  4122. if (signature) {
  4123. if (signature[i + 1] == '*') {
  4124. /* param is a pointer */
  4125. if (signature[i + 2] == '~')
  4126. /* pointer with length followed */
  4127. ptr_len = *argv_src;
  4128. else
  4129. /* pointer without length followed */
  4130. ptr_len = 1;
  4131. if (!wasm_runtime_validate_app_addr(
  4132. module, (uint64)arg_i32, (uint64)ptr_len))
  4133. goto fail;
  4134. arg_i32 = (uintptr_t)wasm_runtime_addr_app_to_native(
  4135. module, (uint64)arg_i32);
  4136. }
  4137. else if (signature[i + 1] == '$') {
  4138. /* param is a string */
  4139. if (!wasm_runtime_validate_app_str_addr(
  4140. module, (uint64)arg_i32))
  4141. goto fail;
  4142. arg_i32 = (uintptr_t)wasm_runtime_addr_app_to_native(
  4143. module, (uint64)arg_i32);
  4144. }
  4145. }
  4146. if (n_ints < MAX_REG_INTS)
  4147. ints[n_ints++] = arg_i32;
  4148. else
  4149. stacks[n_stacks++] = arg_i32;
  4150. break;
  4151. }
  4152. case VALUE_TYPE_I64:
  4153. {
  4154. if (n_ints < MAX_REG_INTS - 1) {
  4155. #if defined(BUILD_TARGET_ARM_VFP) || defined(BUILD_TARGET_THUMB_VFP)
  4156. /* 64-bit data must be 8 bytes aligned in arm */
  4157. if (n_ints & 1)
  4158. n_ints++;
  4159. #endif
  4160. ints[n_ints++] = *argv_src++;
  4161. ints[n_ints++] = *argv_src++;
  4162. }
  4163. #if defined(BUILD_TARGET_RISCV32_ILP32) \
  4164. || defined(BUILD_TARGET_RISCV32_ILP32D) || defined(BUILD_TARGET_ARC)
  4165. else if (n_ints == MAX_REG_INTS - 1) {
  4166. ints[n_ints++] = *argv_src++;
  4167. stacks[n_stacks++] = *argv_src++;
  4168. }
  4169. #endif
  4170. else {
  4171. /* 64-bit data in stack must be 8 bytes aligned
  4172. in arm and riscv32 */
  4173. #if !defined(BUILD_TARGET_ARC)
  4174. if (n_stacks & 1)
  4175. n_stacks++;
  4176. #endif
  4177. stacks[n_stacks++] = *argv_src++;
  4178. stacks[n_stacks++] = *argv_src++;
  4179. }
  4180. break;
  4181. }
  4182. #if !defined(BUILD_TARGET_RISCV32_ILP32D)
  4183. case VALUE_TYPE_F32:
  4184. {
  4185. if (n_fps < MAX_REG_FLOATS)
  4186. *(float32 *)&fps[n_fps++] = *(float32 *)argv_src++;
  4187. else
  4188. *(float32 *)&stacks[n_stacks++] = *(float32 *)argv_src++;
  4189. break;
  4190. }
  4191. case VALUE_TYPE_F64:
  4192. {
  4193. if (n_fps < MAX_REG_FLOATS - 1) {
  4194. #if !defined(BUILD_TARGET_RISCV32_ILP32) && !defined(BUILD_TARGET_ARC)
  4195. /* 64-bit data must be 8 bytes aligned in arm */
  4196. if (n_fps & 1)
  4197. n_fps++;
  4198. #endif
  4199. fps[n_fps++] = *argv_src++;
  4200. fps[n_fps++] = *argv_src++;
  4201. }
  4202. #if defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_ARC)
  4203. else if (n_fps == MAX_REG_FLOATS - 1) {
  4204. fps[n_fps++] = *argv_src++;
  4205. stacks[n_stacks++] = *argv_src++;
  4206. }
  4207. #endif
  4208. else {
  4209. /* 64-bit data in stack must be 8 bytes aligned
  4210. in arm and riscv32 */
  4211. #if !defined(BUILD_TARGET_ARC)
  4212. if (n_stacks & 1)
  4213. n_stacks++;
  4214. #endif
  4215. stacks[n_stacks++] = *argv_src++;
  4216. stacks[n_stacks++] = *argv_src++;
  4217. }
  4218. break;
  4219. }
  4220. #else /* BUILD_TARGET_RISCV32_ILP32D */
  4221. case VALUE_TYPE_F32:
  4222. case VALUE_TYPE_F64:
  4223. {
  4224. if (n_fps < MAX_REG_FLOATS) {
  4225. if (func_type->types[i] == VALUE_TYPE_F32) {
  4226. *(float32 *)&fps[n_fps * 2] = *(float32 *)argv_src++;
  4227. /* NaN boxing, the upper bits of a valid NaN-boxed
  4228. value must be all 1s. */
  4229. fps[n_fps * 2 + 1] = 0xFFFFFFFF;
  4230. }
  4231. else {
  4232. *(float64 *)&fps[n_fps * 2] = *(float64 *)argv_src;
  4233. argv_src += 2;
  4234. }
  4235. n_fps++;
  4236. }
  4237. else if (func_type->types[i] == VALUE_TYPE_F32
  4238. && n_ints < MAX_REG_INTS) {
  4239. /* use int reg firstly if available */
  4240. *(float32 *)&ints[n_ints++] = *(float32 *)argv_src++;
  4241. }
  4242. else if (func_type->types[i] == VALUE_TYPE_F64
  4243. && n_ints < MAX_REG_INTS - 1) {
  4244. /* use int regs firstly if available */
  4245. if (n_ints & 1)
  4246. n_ints++;
  4247. *(float64 *)&ints[n_ints] = *(float64 *)argv_src;
  4248. n_ints += 2;
  4249. argv_src += 2;
  4250. }
  4251. else {
  4252. /* 64-bit data in stack must be 8 bytes aligned in riscv32
  4253. */
  4254. if (n_stacks & 1)
  4255. n_stacks++;
  4256. if (func_type->types[i] == VALUE_TYPE_F32) {
  4257. *(float32 *)&stacks[n_stacks++] =
  4258. *(float32 *)argv_src++;
  4259. }
  4260. else {
  4261. *(float64 *)&stacks[n_stacks] = *(float64 *)argv_src;
  4262. argv_src += 2;
  4263. n_stacks += 2;
  4264. }
  4265. }
  4266. break;
  4267. }
  4268. #endif /* BUILD_TARGET_RISCV32_ILP32D */
  4269. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4270. case VALUE_TYPE_EXTERNREF:
  4271. {
  4272. uint32 externref_idx = *argv_src++;
  4273. if (is_aot_func) {
  4274. if (n_ints < MAX_REG_INTS)
  4275. ints[n_ints++] = externref_idx;
  4276. else
  4277. stacks[n_stacks++] = externref_idx;
  4278. }
  4279. else {
  4280. void *externref_obj;
  4281. if (!wasm_externref_ref2obj(externref_idx, &externref_obj))
  4282. goto fail;
  4283. if (n_ints < MAX_REG_INTS)
  4284. ints[n_ints++] = (uintptr_t)externref_obj;
  4285. else
  4286. stacks[n_stacks++] = (uintptr_t)externref_obj;
  4287. }
  4288. break;
  4289. }
  4290. #endif
  4291. default:
  4292. bh_assert(0);
  4293. break;
  4294. }
  4295. }
  4296. /* Save extra result values' address to argv1 */
  4297. for (i = 0; i < ext_ret_count; i++) {
  4298. if (n_ints < MAX_REG_INTS)
  4299. ints[n_ints++] = *(uint32 *)argv_src++;
  4300. else
  4301. stacks[n_stacks++] = *(uint32 *)argv_src++;
  4302. }
  4303. exec_env->attachment = attachment;
  4304. if (func_type->result_count == 0) {
  4305. invokeNative_Void(func_ptr, argv1, n_stacks);
  4306. }
  4307. else {
  4308. switch (func_type->types[func_type->param_count]) {
  4309. case VALUE_TYPE_I32:
  4310. #if WASM_ENABLE_GC != 0
  4311. case REF_TYPE_FUNCREF:
  4312. case REF_TYPE_EXTERNREF:
  4313. case REF_TYPE_ANYREF:
  4314. case REF_TYPE_EQREF:
  4315. case REF_TYPE_HT_NULLABLE:
  4316. case REF_TYPE_HT_NON_NULLABLE:
  4317. case REF_TYPE_I31REF:
  4318. case REF_TYPE_NULLFUNCREF:
  4319. case REF_TYPE_NULLEXTERNREF:
  4320. case REF_TYPE_STRUCTREF:
  4321. case REF_TYPE_ARRAYREF:
  4322. case REF_TYPE_NULLREF:
  4323. #if WASM_ENABLE_STRINGREF != 0
  4324. case REF_TYPE_STRINGREF:
  4325. case REF_TYPE_STRINGVIEWWTF8:
  4326. case REF_TYPE_STRINGVIEWWTF16:
  4327. case REF_TYPE_STRINGVIEWITER:
  4328. #endif
  4329. #endif
  4330. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4331. case VALUE_TYPE_FUNCREF:
  4332. #endif
  4333. argv_ret[0] =
  4334. (uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
  4335. break;
  4336. case VALUE_TYPE_I64:
  4337. PUT_I64_TO_ADDR(argv_ret,
  4338. invokeNative_Int64(func_ptr, argv1, n_stacks));
  4339. break;
  4340. case VALUE_TYPE_F32:
  4341. *(float32 *)argv_ret =
  4342. invokeNative_Float32(func_ptr, argv1, n_stacks);
  4343. break;
  4344. case VALUE_TYPE_F64:
  4345. PUT_F64_TO_ADDR(
  4346. argv_ret, invokeNative_Float64(func_ptr, argv1, n_stacks));
  4347. break;
  4348. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4349. case VALUE_TYPE_EXTERNREF:
  4350. {
  4351. if (is_aot_func) {
  4352. uint32 externref_idx =
  4353. (uint32)invokeNative_Int32(func_ptr, argv1, argc1);
  4354. argv_ret[0] = externref_idx;
  4355. }
  4356. else {
  4357. uint32 externref_idx;
  4358. void *externref_obj;
  4359. externref_obj = (void *)(uintptr_t)invokeNative_Int32(
  4360. func_ptr, argv1, argc1);
  4361. if (!wasm_externref_obj2ref(exec_env->module_inst,
  4362. externref_obj, &externref_idx))
  4363. goto fail;
  4364. argv_ret[0] = externref_idx;
  4365. }
  4366. break;
  4367. }
  4368. #endif
  4369. default:
  4370. bh_assert(0);
  4371. break;
  4372. }
  4373. }
  4374. exec_env->attachment = NULL;
  4375. ret = !wasm_runtime_copy_exception(module, NULL);
  4376. fail:
  4377. if (argv1 != argv_buf)
  4378. wasm_runtime_free(argv1);
  4379. return ret;
  4380. }
  4381. #endif /* end of defined(BUILD_TARGET_ARM_VFP) \
  4382. || defined(BUILD_TARGET_THUMB_VFP) \
  4383. || defined(BUILD_TARGET_RISCV32_ILP32D) \
  4384. || defined(BUILD_TARGET_RISCV32_ILP32) \
  4385. || defined(BUILD_TARGET_ARC) */
  4386. #if defined(BUILD_TARGET_X86_32) || defined(BUILD_TARGET_ARM) \
  4387. || defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_MIPS) \
  4388. || defined(BUILD_TARGET_XTENSA)
  4389. typedef void (*GenericFunctionPointer)();
  4390. void
  4391. invokeNative(GenericFunctionPointer f, uint32 *args, uint32 sz);
  4392. typedef float64 (*Float64FuncPtr)(GenericFunctionPointer f, uint32 *, uint32);
  4393. typedef float32 (*Float32FuncPtr)(GenericFunctionPointer f, uint32 *, uint32);
  4394. typedef int64 (*Int64FuncPtr)(GenericFunctionPointer f, uint32 *, uint32);
  4395. typedef int32 (*Int32FuncPtr)(GenericFunctionPointer f, uint32 *, uint32);
  4396. typedef void (*VoidFuncPtr)(GenericFunctionPointer f, uint32 *, uint32);
  4397. static volatile Int64FuncPtr invokeNative_Int64 =
  4398. (Int64FuncPtr)(uintptr_t)invokeNative;
  4399. static volatile Int32FuncPtr invokeNative_Int32 =
  4400. (Int32FuncPtr)(uintptr_t)invokeNative;
  4401. static volatile Float64FuncPtr invokeNative_Float64 =
  4402. (Float64FuncPtr)(uintptr_t)invokeNative;
  4403. static volatile Float32FuncPtr invokeNative_Float32 =
  4404. (Float32FuncPtr)(uintptr_t)invokeNative;
  4405. static volatile VoidFuncPtr invokeNative_Void =
  4406. (VoidFuncPtr)(uintptr_t)invokeNative;
  4407. static inline void
  4408. word_copy(uint32 *dest, uint32 *src, unsigned num)
  4409. {
  4410. for (; num > 0; num--)
  4411. *dest++ = *src++;
  4412. }
  4413. bool
  4414. wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
  4415. const WASMFuncType *func_type, const char *signature,
  4416. void *attachment, uint32 *argv, uint32 argc,
  4417. uint32 *argv_ret)
  4418. {
  4419. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  4420. uint32 argv_buf[32], *argv1 = argv_buf, argc1, i, j = 0;
  4421. uint32 arg_i32, ptr_len;
  4422. uint32 result_count = func_type->result_count;
  4423. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  4424. uint64 size;
  4425. bool ret = false;
  4426. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4427. bool is_aot_func = (NULL == signature);
  4428. #endif
  4429. #if defined(BUILD_TARGET_X86_32)
  4430. argc1 = argc + ext_ret_count + 2;
  4431. #else
  4432. /* arm/thumb/mips/xtensa, 64-bit data must be 8 bytes aligned,
  4433. so we need to allocate more memory. */
  4434. argc1 = func_type->param_count * 2 + ext_ret_count + 2;
  4435. #endif
  4436. if (argc1 > sizeof(argv_buf) / sizeof(uint32)) {
  4437. size = sizeof(uint32) * (uint64)argc1;
  4438. if (!(argv1 = runtime_malloc((uint32)size, exec_env->module_inst, NULL,
  4439. 0))) {
  4440. return false;
  4441. }
  4442. }
  4443. for (i = 0; i < sizeof(WASMExecEnv *) / sizeof(uint32); i++)
  4444. argv1[j++] = ((uint32 *)&exec_env)[i];
  4445. for (i = 0; i < func_type->param_count; i++) {
  4446. switch (func_type->types[i]) {
  4447. case VALUE_TYPE_I32:
  4448. #if WASM_ENABLE_GC != 0
  4449. case REF_TYPE_FUNCREF:
  4450. case REF_TYPE_EXTERNREF:
  4451. case REF_TYPE_ANYREF:
  4452. case REF_TYPE_EQREF:
  4453. case REF_TYPE_HT_NULLABLE:
  4454. case REF_TYPE_HT_NON_NULLABLE:
  4455. case REF_TYPE_I31REF:
  4456. case REF_TYPE_NULLFUNCREF:
  4457. case REF_TYPE_NULLEXTERNREF:
  4458. case REF_TYPE_STRUCTREF:
  4459. case REF_TYPE_ARRAYREF:
  4460. case REF_TYPE_NULLREF:
  4461. #if WASM_ENABLE_STRINGREF != 0
  4462. case REF_TYPE_STRINGREF:
  4463. case REF_TYPE_STRINGVIEWWTF8:
  4464. case REF_TYPE_STRINGVIEWWTF16:
  4465. case REF_TYPE_STRINGVIEWITER:
  4466. #endif
  4467. #endif
  4468. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4469. case VALUE_TYPE_FUNCREF:
  4470. #endif
  4471. {
  4472. arg_i32 = *argv++;
  4473. if (signature) {
  4474. if (signature[i + 1] == '*') {
  4475. /* param is a pointer */
  4476. if (signature[i + 2] == '~')
  4477. /* pointer with length followed */
  4478. ptr_len = *argv;
  4479. else
  4480. /* pointer without length followed */
  4481. ptr_len = 1;
  4482. if (!wasm_runtime_validate_app_addr(
  4483. module, (uint64)arg_i32, (uint64)ptr_len))
  4484. goto fail;
  4485. arg_i32 = (uintptr_t)wasm_runtime_addr_app_to_native(
  4486. module, (uint64)arg_i32);
  4487. }
  4488. else if (signature[i + 1] == '$') {
  4489. /* param is a string */
  4490. if (!wasm_runtime_validate_app_str_addr(
  4491. module, (uint64)arg_i32))
  4492. goto fail;
  4493. arg_i32 = (uintptr_t)wasm_runtime_addr_app_to_native(
  4494. module, (uint64)arg_i32);
  4495. }
  4496. }
  4497. argv1[j++] = arg_i32;
  4498. break;
  4499. }
  4500. case VALUE_TYPE_I64:
  4501. case VALUE_TYPE_F64:
  4502. #if !defined(BUILD_TARGET_X86_32)
  4503. /* 64-bit data must be 8 bytes aligned in arm, thumb, mips
  4504. and xtensa */
  4505. if (j & 1)
  4506. j++;
  4507. #endif
  4508. argv1[j++] = *argv++;
  4509. argv1[j++] = *argv++;
  4510. break;
  4511. case VALUE_TYPE_F32:
  4512. argv1[j++] = *argv++;
  4513. break;
  4514. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4515. case VALUE_TYPE_EXTERNREF:
  4516. {
  4517. uint32 externref_idx = *argv++;
  4518. if (is_aot_func) {
  4519. argv1[j++] = externref_idx;
  4520. }
  4521. else {
  4522. void *externref_obj;
  4523. if (!wasm_externref_ref2obj(externref_idx, &externref_obj))
  4524. goto fail;
  4525. argv1[j++] = (uintptr_t)externref_obj;
  4526. }
  4527. break;
  4528. }
  4529. #endif
  4530. default:
  4531. bh_assert(0);
  4532. break;
  4533. }
  4534. }
  4535. /* Save extra result values' address to argv1 */
  4536. word_copy(argv1 + j, argv, ext_ret_count);
  4537. argc1 = j + ext_ret_count;
  4538. exec_env->attachment = attachment;
  4539. if (func_type->result_count == 0) {
  4540. invokeNative_Void(func_ptr, argv1, argc1);
  4541. }
  4542. else {
  4543. switch (func_type->types[func_type->param_count]) {
  4544. case VALUE_TYPE_I32:
  4545. #if WASM_ENABLE_GC != 0
  4546. case REF_TYPE_FUNCREF:
  4547. case REF_TYPE_EXTERNREF:
  4548. case REF_TYPE_ANYREF:
  4549. case REF_TYPE_EQREF:
  4550. case REF_TYPE_HT_NULLABLE:
  4551. case REF_TYPE_HT_NON_NULLABLE:
  4552. case REF_TYPE_I31REF:
  4553. case REF_TYPE_NULLFUNCREF:
  4554. case REF_TYPE_NULLEXTERNREF:
  4555. case REF_TYPE_STRUCTREF:
  4556. case REF_TYPE_ARRAYREF:
  4557. case REF_TYPE_NULLREF:
  4558. #if WASM_ENABLE_STRINGREF != 0
  4559. case REF_TYPE_STRINGREF:
  4560. case REF_TYPE_STRINGVIEWWTF8:
  4561. case REF_TYPE_STRINGVIEWWTF16:
  4562. case REF_TYPE_STRINGVIEWITER:
  4563. #endif
  4564. #endif
  4565. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4566. case VALUE_TYPE_FUNCREF:
  4567. #endif
  4568. argv_ret[0] =
  4569. (uint32)invokeNative_Int32(func_ptr, argv1, argc1);
  4570. break;
  4571. case VALUE_TYPE_I64:
  4572. PUT_I64_TO_ADDR(argv_ret,
  4573. invokeNative_Int64(func_ptr, argv1, argc1));
  4574. break;
  4575. case VALUE_TYPE_F32:
  4576. *(float32 *)argv_ret =
  4577. invokeNative_Float32(func_ptr, argv1, argc1);
  4578. break;
  4579. case VALUE_TYPE_F64:
  4580. PUT_F64_TO_ADDR(argv_ret,
  4581. invokeNative_Float64(func_ptr, argv1, argc1));
  4582. break;
  4583. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4584. case VALUE_TYPE_EXTERNREF:
  4585. {
  4586. if (is_aot_func) {
  4587. uint32 externref_idx =
  4588. (uint32)invokeNative_Int32(func_ptr, argv1, argc1);
  4589. argv_ret[0] = externref_idx;
  4590. }
  4591. else {
  4592. void *externref_obj = (void *)(uintptr_t)invokeNative_Int32(
  4593. func_ptr, argv1, argc1);
  4594. uint32 externref_idx;
  4595. if (!wasm_externref_obj2ref(exec_env->module_inst,
  4596. externref_obj, &externref_idx))
  4597. goto fail;
  4598. argv_ret[0] = externref_idx;
  4599. }
  4600. break;
  4601. }
  4602. #endif
  4603. default:
  4604. bh_assert(0);
  4605. break;
  4606. }
  4607. }
  4608. exec_env->attachment = NULL;
  4609. ret = !wasm_runtime_copy_exception(module, NULL);
  4610. fail:
  4611. if (argv1 != argv_buf)
  4612. wasm_runtime_free(argv1);
  4613. return ret;
  4614. }
  4615. #endif /* end of defined(BUILD_TARGET_X86_32) \
  4616. || defined(BUILD_TARGET_ARM) \
  4617. || defined(BUILD_TARGET_THUMB) \
  4618. || defined(BUILD_TARGET_MIPS) \
  4619. || defined(BUILD_TARGET_XTENSA) */
  4620. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  4621. || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
  4622. || defined(BUILD_TARGET_RISCV64_LP64)
  4623. #if WASM_ENABLE_SIMD != 0
  4624. #ifdef v128
  4625. #undef v128
  4626. #endif
  4627. #if defined(_WIN32) || defined(_WIN32_)
  4628. typedef union __declspec(intrin_type) __declspec(align(8)) v128 {
  4629. __int8 m128i_i8[16];
  4630. __int16 m128i_i16[8];
  4631. __int32 m128i_i32[4];
  4632. __int64 m128i_i64[2];
  4633. unsigned __int8 m128i_u8[16];
  4634. unsigned __int16 m128i_u16[8];
  4635. unsigned __int32 m128i_u32[4];
  4636. unsigned __int64 m128i_u64[2];
  4637. } v128;
  4638. #elif defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  4639. || defined(BUILD_TARGET_RISCV64_LP64D) \
  4640. || defined(BUILD_TARGET_RISCV64_LP64)
  4641. typedef long long v128
  4642. __attribute__((__vector_size__(16), __may_alias__, __aligned__(1)));
  4643. #elif defined(BUILD_TARGET_AARCH64)
  4644. #include <arm_neon.h>
  4645. typedef uint32x4_t __m128i;
  4646. #define v128 __m128i
  4647. #endif
  4648. #endif /* end of WASM_ENABLE_SIMD != 0 */
  4649. typedef void (*GenericFunctionPointer)();
  4650. void
  4651. invokeNative(GenericFunctionPointer f, uint64 *args, uint64 n_stacks);
  4652. typedef float64 (*Float64FuncPtr)(GenericFunctionPointer, uint64 *, uint64);
  4653. typedef float32 (*Float32FuncPtr)(GenericFunctionPointer, uint64 *, uint64);
  4654. typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint64 *, uint64);
  4655. typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint64 *, uint64);
  4656. typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint64 *, uint64);
  4657. /* NOLINTBEGIN */
  4658. static volatile Float64FuncPtr invokeNative_Float64 =
  4659. (Float64FuncPtr)(uintptr_t)invokeNative;
  4660. static volatile Float32FuncPtr invokeNative_Float32 =
  4661. (Float32FuncPtr)(uintptr_t)invokeNative;
  4662. static volatile Int64FuncPtr invokeNative_Int64 =
  4663. (Int64FuncPtr)(uintptr_t)invokeNative;
  4664. static volatile Int32FuncPtr invokeNative_Int32 =
  4665. (Int32FuncPtr)(uintptr_t)invokeNative;
  4666. static volatile VoidFuncPtr invokeNative_Void =
  4667. (VoidFuncPtr)(uintptr_t)invokeNative;
  4668. #if WASM_ENABLE_SIMD != 0
  4669. typedef v128 (*V128FuncPtr)(GenericFunctionPointer, uint64 *, uint64);
  4670. static V128FuncPtr invokeNative_V128 = (V128FuncPtr)(uintptr_t)invokeNative;
  4671. #endif
  4672. /* NOLINTEND */
  4673. #if defined(_WIN32) || defined(_WIN32_)
  4674. #define MAX_REG_FLOATS 4
  4675. #define MAX_REG_INTS 4
  4676. #else /* else of defined(_WIN32) || defined(_WIN32_) */
  4677. #define MAX_REG_FLOATS 8
  4678. #if defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
  4679. || defined(BUILD_TARGET_RISCV64_LP64)
  4680. #define MAX_REG_INTS 8
  4681. #else
  4682. #define MAX_REG_INTS 6
  4683. #endif /* end of defined(BUILD_TARGET_AARCH64) \
  4684. || defined(BUILD_TARGET_RISCV64_LP64D) \
  4685. || defined(BUILD_TARGET_RISCV64_LP64) */
  4686. #endif /* end of defined(_WIN32) || defined(_WIN32_) */
  4687. /*
  4688. * ASAN is not designed to work with custom stack unwind or other low-level
  4689. * things. Ignore a function that does some low-level magic. (e.g. walking
  4690. * through the thread's stack bypassing the frame boundaries)
  4691. */
  4692. #if defined(__GNUC__) || defined(__clang__)
  4693. __attribute__((no_sanitize_address))
  4694. #endif
  4695. bool
  4696. wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
  4697. const WASMFuncType *func_type, const char *signature,
  4698. void *attachment, uint32 *argv, uint32 argc,
  4699. uint32 *argv_ret)
  4700. {
  4701. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  4702. uint64 argv_buf[32] = { 0 }, *argv1 = argv_buf, *ints, *stacks, size,
  4703. arg_i64;
  4704. uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0;
  4705. uint32 arg_i32, ptr_len;
  4706. uint32 result_count = func_type->result_count;
  4707. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  4708. bool ret = false;
  4709. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4710. bool is_aot_func = (NULL == signature);
  4711. #endif
  4712. #ifndef BUILD_TARGET_RISCV64_LP64
  4713. #if WASM_ENABLE_SIMD == 0
  4714. uint64 *fps;
  4715. #else
  4716. v128 *fps;
  4717. #endif
  4718. #else /* else of BUILD_TARGET_RISCV64_LP64 */
  4719. #define fps ints
  4720. #endif /* end of BUILD_TARGET_RISCV64_LP64 */
  4721. #if defined(_WIN32) || defined(_WIN32_) || defined(BUILD_TARGET_RISCV64_LP64)
  4722. /* important difference in calling conventions */
  4723. #define n_fps n_ints
  4724. #else
  4725. int n_fps = 0;
  4726. #endif
  4727. #if WASM_ENABLE_SIMD == 0
  4728. argc1 = 1 + MAX_REG_FLOATS + (uint32)func_type->param_count + ext_ret_count;
  4729. #else
  4730. argc1 = 1 + MAX_REG_FLOATS * 2 + (uint32)func_type->param_count * 2
  4731. + ext_ret_count;
  4732. #endif
  4733. if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
  4734. size = sizeof(uint64) * (uint64)argc1;
  4735. if (!(argv1 = runtime_malloc((uint32)size, exec_env->module_inst, NULL,
  4736. 0))) {
  4737. return false;
  4738. }
  4739. }
  4740. #ifndef BUILD_TARGET_RISCV64_LP64
  4741. #if WASM_ENABLE_SIMD == 0
  4742. fps = argv1;
  4743. ints = fps + MAX_REG_FLOATS;
  4744. #else
  4745. fps = (v128 *)argv1;
  4746. ints = (uint64 *)(fps + MAX_REG_FLOATS);
  4747. #endif
  4748. #else /* else of BUILD_TARGET_RISCV64_LP64 */
  4749. ints = argv1;
  4750. #endif /* end of BUILD_TARGET_RISCV64_LP64 */
  4751. stacks = ints + MAX_REG_INTS;
  4752. ints[n_ints++] = (uint64)(uintptr_t)exec_env;
  4753. for (i = 0; i < func_type->param_count; i++) {
  4754. switch (func_type->types[i]) {
  4755. case VALUE_TYPE_I32:
  4756. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4757. case VALUE_TYPE_FUNCREF:
  4758. #endif
  4759. {
  4760. arg_i32 = *argv_src++;
  4761. arg_i64 = arg_i32;
  4762. /* TODO: memory64 if future there is a way for supporting
  4763. * wasm64 and wasm32 in libc at the same time, remove the
  4764. * macro control */
  4765. #if WASM_ENABLE_MEMORY64 == 0
  4766. if (signature) {
  4767. if (signature[i + 1] == '*') {
  4768. /* param is a pointer */
  4769. if (signature[i + 2] == '~')
  4770. /* pointer with length followed */
  4771. ptr_len = *argv_src;
  4772. else
  4773. /* pointer without length followed */
  4774. ptr_len = 1;
  4775. if (!wasm_runtime_validate_app_addr(
  4776. module, (uint64)arg_i32, (uint64)ptr_len))
  4777. goto fail;
  4778. arg_i64 = (uintptr_t)wasm_runtime_addr_app_to_native(
  4779. module, (uint64)arg_i32);
  4780. }
  4781. else if (signature[i + 1] == '$') {
  4782. /* param is a string */
  4783. if (!wasm_runtime_validate_app_str_addr(
  4784. module, (uint64)arg_i32))
  4785. goto fail;
  4786. arg_i64 = (uintptr_t)wasm_runtime_addr_app_to_native(
  4787. module, (uint64)arg_i32);
  4788. }
  4789. }
  4790. #endif
  4791. if (n_ints < MAX_REG_INTS)
  4792. ints[n_ints++] = arg_i64;
  4793. else
  4794. stacks[n_stacks++] = arg_i64;
  4795. break;
  4796. }
  4797. case VALUE_TYPE_I64:
  4798. #if WASM_ENABLE_MEMORY64 != 0
  4799. {
  4800. arg_i64 = GET_I64_FROM_ADDR(argv_src);
  4801. argv_src += 2;
  4802. if (signature) {
  4803. /* TODO: memory64 pointer with length need a new symbol
  4804. * to represent type i64, with '~' still represent i32
  4805. * length */
  4806. if (signature[i + 1] == '*') {
  4807. /* param is a pointer */
  4808. if (signature[i + 2] == '~')
  4809. /* pointer with length followed */
  4810. ptr_len = *argv_src;
  4811. else
  4812. /* pointer without length followed */
  4813. ptr_len = 1;
  4814. if (!wasm_runtime_validate_app_addr(module, arg_i64,
  4815. (uint64)ptr_len))
  4816. goto fail;
  4817. arg_i64 = (uint64)wasm_runtime_addr_app_to_native(
  4818. module, arg_i64);
  4819. }
  4820. else if (signature[i + 1] == '$') {
  4821. /* param is a string */
  4822. if (!wasm_runtime_validate_app_str_addr(module,
  4823. arg_i64))
  4824. goto fail;
  4825. arg_i64 = (uint64)wasm_runtime_addr_app_to_native(
  4826. module, arg_i64);
  4827. }
  4828. }
  4829. if (n_ints < MAX_REG_INTS)
  4830. ints[n_ints++] = arg_i64;
  4831. else
  4832. stacks[n_stacks++] = arg_i64;
  4833. break;
  4834. }
  4835. #endif
  4836. #if WASM_ENABLE_GC != 0
  4837. case REF_TYPE_FUNCREF:
  4838. case REF_TYPE_EXTERNREF:
  4839. case REF_TYPE_ANYREF:
  4840. case REF_TYPE_EQREF:
  4841. case REF_TYPE_HT_NULLABLE:
  4842. case REF_TYPE_HT_NON_NULLABLE:
  4843. case REF_TYPE_I31REF:
  4844. case REF_TYPE_NULLFUNCREF:
  4845. case REF_TYPE_NULLEXTERNREF:
  4846. case REF_TYPE_STRUCTREF:
  4847. case REF_TYPE_ARRAYREF:
  4848. case REF_TYPE_NULLREF:
  4849. #if WASM_ENABLE_STRINGREF != 0
  4850. case REF_TYPE_STRINGREF:
  4851. case REF_TYPE_STRINGVIEWWTF8:
  4852. case REF_TYPE_STRINGVIEWWTF16:
  4853. case REF_TYPE_STRINGVIEWITER:
  4854. #endif
  4855. #endif
  4856. if (n_ints < MAX_REG_INTS)
  4857. ints[n_ints++] = *(uint64 *)argv_src;
  4858. else
  4859. stacks[n_stacks++] = *(uint64 *)argv_src;
  4860. argv_src += 2;
  4861. break;
  4862. case VALUE_TYPE_F32:
  4863. if (n_fps < MAX_REG_FLOATS) {
  4864. *(float32 *)&fps[n_fps++] = *(float32 *)argv_src++;
  4865. }
  4866. else {
  4867. *(float32 *)&stacks[n_stacks++] = *(float32 *)argv_src++;
  4868. }
  4869. break;
  4870. case VALUE_TYPE_F64:
  4871. if (n_fps < MAX_REG_FLOATS) {
  4872. *(float64 *)&fps[n_fps++] = *(float64 *)argv_src;
  4873. }
  4874. else {
  4875. *(float64 *)&stacks[n_stacks++] = *(float64 *)argv_src;
  4876. }
  4877. argv_src += 2;
  4878. break;
  4879. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4880. case VALUE_TYPE_EXTERNREF:
  4881. {
  4882. uint32 externref_idx = *argv_src++;
  4883. if (is_aot_func) {
  4884. if (n_ints < MAX_REG_INTS)
  4885. ints[n_ints++] = externref_idx;
  4886. else
  4887. stacks[n_stacks++] = externref_idx;
  4888. }
  4889. else {
  4890. void *externref_obj;
  4891. if (!wasm_externref_ref2obj(externref_idx, &externref_obj))
  4892. goto fail;
  4893. if (n_ints < MAX_REG_INTS)
  4894. ints[n_ints++] = (uintptr_t)externref_obj;
  4895. else
  4896. stacks[n_stacks++] = (uintptr_t)externref_obj;
  4897. }
  4898. break;
  4899. }
  4900. #endif
  4901. #if WASM_ENABLE_SIMD != 0
  4902. case VALUE_TYPE_V128:
  4903. if (n_fps < MAX_REG_FLOATS) {
  4904. *(v128 *)&fps[n_fps++] = *(v128 *)argv_src;
  4905. }
  4906. else {
  4907. *(v128 *)&stacks[n_stacks++] = *(v128 *)argv_src;
  4908. n_stacks++;
  4909. }
  4910. argv_src += 4;
  4911. break;
  4912. #endif
  4913. default:
  4914. bh_assert(0);
  4915. break;
  4916. }
  4917. }
  4918. /* Save extra result values' address to argv1 */
  4919. for (i = 0; i < ext_ret_count; i++) {
  4920. if (n_ints < MAX_REG_INTS)
  4921. ints[n_ints++] = *(uint64 *)argv_src;
  4922. else
  4923. stacks[n_stacks++] = *(uint64 *)argv_src;
  4924. argv_src += 2;
  4925. }
  4926. exec_env->attachment = attachment;
  4927. if (result_count == 0) {
  4928. invokeNative_Void(func_ptr, argv1, n_stacks);
  4929. }
  4930. else {
  4931. /* Invoke the native function and get the first result value */
  4932. switch (func_type->types[func_type->param_count]) {
  4933. case VALUE_TYPE_I32:
  4934. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4935. case VALUE_TYPE_FUNCREF:
  4936. #endif
  4937. argv_ret[0] =
  4938. (uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
  4939. break;
  4940. case VALUE_TYPE_I64:
  4941. #if WASM_ENABLE_GC != 0
  4942. case REF_TYPE_FUNCREF:
  4943. case REF_TYPE_EXTERNREF:
  4944. case REF_TYPE_ANYREF:
  4945. case REF_TYPE_EQREF:
  4946. case REF_TYPE_HT_NULLABLE:
  4947. case REF_TYPE_HT_NON_NULLABLE:
  4948. case REF_TYPE_I31REF:
  4949. case REF_TYPE_NULLFUNCREF:
  4950. case REF_TYPE_NULLEXTERNREF:
  4951. case REF_TYPE_STRUCTREF:
  4952. case REF_TYPE_ARRAYREF:
  4953. case REF_TYPE_NULLREF:
  4954. #if WASM_ENABLE_STRINGREF != 0
  4955. case REF_TYPE_STRINGREF:
  4956. case REF_TYPE_STRINGVIEWWTF8:
  4957. case REF_TYPE_STRINGVIEWWTF16:
  4958. case REF_TYPE_STRINGVIEWITER:
  4959. #endif
  4960. #endif
  4961. PUT_I64_TO_ADDR(argv_ret,
  4962. invokeNative_Int64(func_ptr, argv1, n_stacks));
  4963. break;
  4964. case VALUE_TYPE_F32:
  4965. *(float32 *)argv_ret =
  4966. invokeNative_Float32(func_ptr, argv1, n_stacks);
  4967. break;
  4968. case VALUE_TYPE_F64:
  4969. PUT_F64_TO_ADDR(
  4970. argv_ret, invokeNative_Float64(func_ptr, argv1, n_stacks));
  4971. break;
  4972. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  4973. case VALUE_TYPE_EXTERNREF:
  4974. {
  4975. if (is_aot_func) {
  4976. argv_ret[0] = invokeNative_Int32(func_ptr, argv1, n_stacks);
  4977. }
  4978. else {
  4979. uint32 externref_idx;
  4980. void *externref_obj = (void *)(uintptr_t)invokeNative_Int64(
  4981. func_ptr, argv1, n_stacks);
  4982. if (!wasm_externref_obj2ref(exec_env->module_inst,
  4983. externref_obj, &externref_idx))
  4984. goto fail;
  4985. argv_ret[0] = externref_idx;
  4986. }
  4987. break;
  4988. }
  4989. #endif
  4990. #if WASM_ENABLE_SIMD != 0
  4991. case VALUE_TYPE_V128:
  4992. *(v128 *)argv_ret =
  4993. invokeNative_V128(func_ptr, argv1, n_stacks);
  4994. break;
  4995. #endif
  4996. default:
  4997. bh_assert(0);
  4998. break;
  4999. }
  5000. }
  5001. exec_env->attachment = NULL;
  5002. ret = !wasm_runtime_copy_exception(module, NULL);
  5003. fail:
  5004. if (argv1 != argv_buf)
  5005. wasm_runtime_free(argv1);
  5006. return ret;
  5007. }
  5008. #endif /* end of defined(BUILD_TARGET_X86_64) \
  5009. || defined(BUILD_TARGET_AMD_64) \
  5010. || defined(BUILD_TARGET_AARCH64) \
  5011. || defined(BUILD_TARGET_RISCV64_LP64D) \
  5012. || defined(BUILD_TARGET_RISCV64_LP64) */
  5013. bool
  5014. wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32 element_index,
  5015. uint32 argc, uint32 argv[])
  5016. {
  5017. bool ret = false;
  5018. if (!wasm_runtime_exec_env_check(exec_env)) {
  5019. LOG_ERROR("Invalid exec env stack info.");
  5020. return false;
  5021. }
  5022. /* this function is called from native code, so exec_env->handle and
  5023. exec_env->native_stack_boundary must have been set, we don't set
  5024. it again */
  5025. #if WASM_ENABLE_INTERP != 0
  5026. if (exec_env->module_inst->module_type == Wasm_Module_Bytecode)
  5027. ret = wasm_call_indirect(exec_env, 0, element_index, argc, argv);
  5028. #endif
  5029. #if WASM_ENABLE_AOT != 0
  5030. if (exec_env->module_inst->module_type == Wasm_Module_AoT)
  5031. ret = aot_call_indirect(exec_env, 0, element_index, argc, argv);
  5032. #endif
  5033. return ret;
  5034. }
  5035. static void
  5036. exchange_uint32(uint8 *p_data)
  5037. {
  5038. uint8 value = *p_data;
  5039. *p_data = *(p_data + 3);
  5040. *(p_data + 3) = value;
  5041. value = *(p_data + 1);
  5042. *(p_data + 1) = *(p_data + 2);
  5043. *(p_data + 2) = value;
  5044. }
  5045. static void
  5046. exchange_uint64(uint8 *p_data)
  5047. {
  5048. uint32 value;
  5049. value = *(uint32 *)p_data;
  5050. *(uint32 *)p_data = *(uint32 *)(p_data + 4);
  5051. *(uint32 *)(p_data + 4) = value;
  5052. exchange_uint32(p_data);
  5053. exchange_uint32(p_data + 4);
  5054. }
  5055. void
  5056. wasm_runtime_read_v128(const uint8 *bytes, uint64 *ret1, uint64 *ret2)
  5057. {
  5058. uint64 u1, u2;
  5059. bh_memcpy_s(&u1, 8, bytes, 8);
  5060. bh_memcpy_s(&u2, 8, bytes + 8, 8);
  5061. if (!is_little_endian()) {
  5062. exchange_uint64((uint8 *)&u1);
  5063. exchange_uint64((uint8 *)&u2);
  5064. *ret1 = u2;
  5065. *ret2 = u1;
  5066. }
  5067. else {
  5068. *ret1 = u1;
  5069. *ret2 = u2;
  5070. }
  5071. }
  5072. #if WASM_ENABLE_THREAD_MGR != 0
  5073. typedef struct WASMThreadArg {
  5074. WASMExecEnv *new_exec_env;
  5075. wasm_thread_callback_t callback;
  5076. void *arg;
  5077. } WASMThreadArg;
  5078. WASMExecEnv *
  5079. wasm_runtime_spawn_exec_env(WASMExecEnv *exec_env)
  5080. {
  5081. return wasm_cluster_spawn_exec_env(exec_env);
  5082. }
  5083. void
  5084. wasm_runtime_destroy_spawned_exec_env(WASMExecEnv *exec_env)
  5085. {
  5086. wasm_cluster_destroy_spawned_exec_env(exec_env);
  5087. }
  5088. static void *
  5089. wasm_runtime_thread_routine(void *arg)
  5090. {
  5091. WASMThreadArg *thread_arg = (WASMThreadArg *)arg;
  5092. void *ret;
  5093. bh_assert(thread_arg->new_exec_env);
  5094. ret = thread_arg->callback(thread_arg->new_exec_env, thread_arg->arg);
  5095. wasm_runtime_destroy_spawned_exec_env(thread_arg->new_exec_env);
  5096. wasm_runtime_free(thread_arg);
  5097. os_thread_exit(ret);
  5098. return ret;
  5099. }
  5100. int32
  5101. wasm_runtime_spawn_thread(WASMExecEnv *exec_env, wasm_thread_t *tid,
  5102. wasm_thread_callback_t callback, void *arg)
  5103. {
  5104. WASMExecEnv *new_exec_env = wasm_runtime_spawn_exec_env(exec_env);
  5105. WASMThreadArg *thread_arg;
  5106. int32 ret;
  5107. if (!new_exec_env)
  5108. return -1;
  5109. if (!(thread_arg = wasm_runtime_malloc(sizeof(WASMThreadArg)))) {
  5110. wasm_runtime_destroy_spawned_exec_env(new_exec_env);
  5111. return -1;
  5112. }
  5113. thread_arg->new_exec_env = new_exec_env;
  5114. thread_arg->callback = callback;
  5115. thread_arg->arg = arg;
  5116. ret = os_thread_create((korp_tid *)tid, wasm_runtime_thread_routine,
  5117. thread_arg, APP_THREAD_STACK_SIZE_DEFAULT);
  5118. if (ret != 0) {
  5119. wasm_runtime_destroy_spawned_exec_env(new_exec_env);
  5120. wasm_runtime_free(thread_arg);
  5121. }
  5122. return ret;
  5123. }
  5124. int32
  5125. wasm_runtime_join_thread(wasm_thread_t tid, void **retval)
  5126. {
  5127. return os_thread_join((korp_tid)tid, retval);
  5128. }
  5129. #endif /* end of WASM_ENABLE_THREAD_MGR */
  5130. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  5131. static korp_mutex externref_lock;
  5132. static uint32 externref_global_id = 1;
  5133. static HashMap *externref_map;
  5134. typedef struct ExternRefMapNode {
  5135. /* The extern object from runtime embedder */
  5136. void *extern_obj;
  5137. /* The module instance it belongs to */
  5138. WASMModuleInstanceCommon *module_inst;
  5139. /* Whether it is retained */
  5140. bool retained;
  5141. /* Whether it is marked by runtime */
  5142. bool marked;
  5143. /* cleanup function called when the externref is freed */
  5144. void (*cleanup)(void *);
  5145. } ExternRefMapNode;
  5146. static uint32
  5147. wasm_externref_hash(const void *key)
  5148. {
  5149. uint32 externref_idx = (uint32)(uintptr_t)key;
  5150. return externref_idx;
  5151. }
  5152. static bool
  5153. wasm_externref_equal(void *key1, void *key2)
  5154. {
  5155. uint32 externref_idx1 = (uint32)(uintptr_t)key1;
  5156. uint32 externref_idx2 = (uint32)(uintptr_t)key2;
  5157. return externref_idx1 == externref_idx2 ? true : false;
  5158. }
  5159. static bool
  5160. wasm_externref_map_init()
  5161. {
  5162. if (os_mutex_init(&externref_lock) != 0)
  5163. return false;
  5164. if (!(externref_map = bh_hash_map_create(32, false, wasm_externref_hash,
  5165. wasm_externref_equal, NULL,
  5166. wasm_runtime_free))) {
  5167. os_mutex_destroy(&externref_lock);
  5168. return false;
  5169. }
  5170. externref_global_id = 1;
  5171. return true;
  5172. }
  5173. static void
  5174. wasm_externref_map_destroy()
  5175. {
  5176. bh_hash_map_destroy(externref_map);
  5177. os_mutex_destroy(&externref_lock);
  5178. }
  5179. typedef struct LookupExtObj_UserData {
  5180. ExternRefMapNode node;
  5181. bool found;
  5182. uint32 externref_idx;
  5183. } LookupExtObj_UserData;
  5184. static void
  5185. lookup_extobj_callback(void *key, void *value, void *user_data)
  5186. {
  5187. uint32 externref_idx = (uint32)(uintptr_t)key;
  5188. ExternRefMapNode *node = (ExternRefMapNode *)value;
  5189. LookupExtObj_UserData *user_data_lookup =
  5190. (LookupExtObj_UserData *)user_data;
  5191. if (node->extern_obj == user_data_lookup->node.extern_obj
  5192. && node->module_inst == user_data_lookup->node.module_inst) {
  5193. user_data_lookup->found = true;
  5194. user_data_lookup->externref_idx = externref_idx;
  5195. }
  5196. }
  5197. static void
  5198. delete_externref(void *key, ExternRefMapNode *node)
  5199. {
  5200. bh_hash_map_remove(externref_map, key, NULL, NULL);
  5201. if (node->cleanup) {
  5202. (*node->cleanup)(node->extern_obj);
  5203. }
  5204. wasm_runtime_free(node);
  5205. }
  5206. static void
  5207. delete_extobj_callback(void *key, void *value, void *user_data)
  5208. {
  5209. ExternRefMapNode *node = (ExternRefMapNode *)value;
  5210. LookupExtObj_UserData *lookup_user_data =
  5211. (LookupExtObj_UserData *)user_data;
  5212. if (node->extern_obj == lookup_user_data->node.extern_obj
  5213. && node->module_inst == lookup_user_data->node.module_inst) {
  5214. lookup_user_data->found = true;
  5215. delete_externref(key, node);
  5216. }
  5217. }
  5218. bool
  5219. wasm_externref_objdel(WASMModuleInstanceCommon *module_inst, void *extern_obj)
  5220. {
  5221. LookupExtObj_UserData lookup_user_data = { 0 };
  5222. bool ok = false;
  5223. /* in a wrapper, extern_obj could be any value */
  5224. lookup_user_data.node.extern_obj = extern_obj;
  5225. lookup_user_data.node.module_inst = module_inst;
  5226. lookup_user_data.found = false;
  5227. os_mutex_lock(&externref_lock);
  5228. /* Lookup hashmap firstly */
  5229. bh_hash_map_traverse(externref_map, delete_extobj_callback,
  5230. (void *)&lookup_user_data);
  5231. if (lookup_user_data.found) {
  5232. ok = true;
  5233. }
  5234. os_mutex_unlock(&externref_lock);
  5235. return ok;
  5236. }
  5237. bool
  5238. wasm_externref_set_cleanup(WASMModuleInstanceCommon *module_inst,
  5239. void *extern_obj, void (*extern_obj_cleanup)(void *))
  5240. {
  5241. LookupExtObj_UserData lookup_user_data = { 0 };
  5242. bool ok = false;
  5243. /* in a wrapper, extern_obj could be any value */
  5244. lookup_user_data.node.extern_obj = extern_obj;
  5245. lookup_user_data.node.module_inst = module_inst;
  5246. lookup_user_data.found = false;
  5247. os_mutex_lock(&externref_lock);
  5248. /* Lookup hashmap firstly */
  5249. bh_hash_map_traverse(externref_map, lookup_extobj_callback,
  5250. (void *)&lookup_user_data);
  5251. if (lookup_user_data.found) {
  5252. void *key = (void *)(uintptr_t)lookup_user_data.externref_idx;
  5253. ExternRefMapNode *node = bh_hash_map_find(externref_map, key);
  5254. bh_assert(node);
  5255. node->cleanup = extern_obj_cleanup;
  5256. ok = true;
  5257. }
  5258. os_mutex_unlock(&externref_lock);
  5259. return ok;
  5260. }
  5261. bool
  5262. wasm_externref_obj2ref(WASMModuleInstanceCommon *module_inst, void *extern_obj,
  5263. uint32 *p_externref_idx)
  5264. {
  5265. LookupExtObj_UserData lookup_user_data = { 0 };
  5266. ExternRefMapNode *node;
  5267. uint32 externref_idx;
  5268. /*
  5269. * to catch a parameter from `wasm_application_execute_func`,
  5270. * which represents a string 'null'
  5271. */
  5272. #if UINTPTR_MAX == UINT32_MAX
  5273. if ((uint32)-1 == (uintptr_t)extern_obj) {
  5274. #else
  5275. if ((uint64)-1LL == (uintptr_t)extern_obj) {
  5276. #endif
  5277. *p_externref_idx = NULL_REF;
  5278. return true;
  5279. }
  5280. /* in a wrapper, extern_obj could be any value */
  5281. lookup_user_data.node.extern_obj = extern_obj;
  5282. lookup_user_data.node.module_inst = module_inst;
  5283. lookup_user_data.found = false;
  5284. os_mutex_lock(&externref_lock);
  5285. /* Lookup hashmap firstly */
  5286. bh_hash_map_traverse(externref_map, lookup_extobj_callback,
  5287. (void *)&lookup_user_data);
  5288. if (lookup_user_data.found) {
  5289. *p_externref_idx = lookup_user_data.externref_idx;
  5290. os_mutex_unlock(&externref_lock);
  5291. return true;
  5292. }
  5293. /* Not found in hashmap */
  5294. if (externref_global_id == NULL_REF || externref_global_id == 0) {
  5295. goto fail1;
  5296. }
  5297. if (!(node = wasm_runtime_malloc(sizeof(ExternRefMapNode)))) {
  5298. goto fail1;
  5299. }
  5300. memset(node, 0, sizeof(ExternRefMapNode));
  5301. node->extern_obj = extern_obj;
  5302. node->module_inst = module_inst;
  5303. node->cleanup = NULL;
  5304. externref_idx = externref_global_id;
  5305. if (!bh_hash_map_insert(externref_map, (void *)(uintptr_t)externref_idx,
  5306. (void *)node)) {
  5307. goto fail2;
  5308. }
  5309. externref_global_id++;
  5310. *p_externref_idx = externref_idx;
  5311. os_mutex_unlock(&externref_lock);
  5312. return true;
  5313. fail2:
  5314. wasm_runtime_free(node);
  5315. fail1:
  5316. os_mutex_unlock(&externref_lock);
  5317. return false;
  5318. }
  5319. bool
  5320. wasm_externref_ref2obj(uint32 externref_idx, void **p_extern_obj)
  5321. {
  5322. ExternRefMapNode *node;
  5323. /* catch a `ref.null` variable */
  5324. if (externref_idx == NULL_REF) {
  5325. *p_extern_obj = NULL;
  5326. return true;
  5327. }
  5328. os_mutex_lock(&externref_lock);
  5329. node = bh_hash_map_find(externref_map, (void *)(uintptr_t)externref_idx);
  5330. os_mutex_unlock(&externref_lock);
  5331. if (!node)
  5332. return false;
  5333. *p_extern_obj = node->extern_obj;
  5334. return true;
  5335. }
  5336. static void
  5337. reclaim_extobj_callback(void *key, void *value, void *user_data)
  5338. {
  5339. ExternRefMapNode *node = (ExternRefMapNode *)value;
  5340. WASMModuleInstanceCommon *module_inst =
  5341. (WASMModuleInstanceCommon *)user_data;
  5342. if (node->module_inst == module_inst) {
  5343. if (!node->marked && !node->retained) {
  5344. delete_externref(key, node);
  5345. }
  5346. else {
  5347. node->marked = false;
  5348. }
  5349. }
  5350. }
  5351. static void
  5352. mark_externref(uint32 externref_idx)
  5353. {
  5354. ExternRefMapNode *node;
  5355. if (externref_idx != NULL_REF) {
  5356. node =
  5357. bh_hash_map_find(externref_map, (void *)(uintptr_t)externref_idx);
  5358. if (node) {
  5359. node->marked = true;
  5360. }
  5361. }
  5362. }
  5363. #if WASM_ENABLE_INTERP != 0
  5364. static void
  5365. interp_mark_all_externrefs(WASMModuleInstance *module_inst)
  5366. {
  5367. uint32 i, j, externref_idx;
  5368. table_elem_type_t *table_data;
  5369. uint8 *global_data = module_inst->global_data;
  5370. WASMGlobalInstance *global;
  5371. WASMTableInstance *table;
  5372. global = module_inst->e->globals;
  5373. for (i = 0; i < module_inst->e->global_count; i++, global++) {
  5374. if (global->type == VALUE_TYPE_EXTERNREF) {
  5375. externref_idx = *(uint32 *)(global_data + global->data_offset);
  5376. mark_externref(externref_idx);
  5377. }
  5378. }
  5379. for (i = 0; i < module_inst->table_count; i++) {
  5380. uint8 elem_type = 0;
  5381. uint32 init_size, max_size;
  5382. table = wasm_get_table_inst(module_inst, i);
  5383. (void)wasm_runtime_get_table_inst_elem_type(
  5384. (WASMModuleInstanceCommon *)module_inst, i, &elem_type, &init_size,
  5385. &max_size);
  5386. if (elem_type == VALUE_TYPE_EXTERNREF) {
  5387. table_data = table->elems;
  5388. for (j = 0; j < table->cur_size; j++) {
  5389. externref_idx = table_data[j];
  5390. mark_externref(externref_idx);
  5391. }
  5392. }
  5393. (void)init_size;
  5394. (void)max_size;
  5395. }
  5396. }
  5397. #endif
  5398. #if WASM_ENABLE_AOT != 0
  5399. static void
  5400. aot_mark_all_externrefs(AOTModuleInstance *module_inst)
  5401. {
  5402. uint32 i = 0, j = 0;
  5403. const AOTModule *module = (AOTModule *)module_inst->module;
  5404. const AOTTable *table = module->tables;
  5405. const AOTGlobal *global = module->globals;
  5406. const AOTTableInstance *table_inst;
  5407. for (i = 0; i < module->global_count; i++, global++) {
  5408. if (global->type.val_type == VALUE_TYPE_EXTERNREF) {
  5409. mark_externref(
  5410. *(uint32 *)(module_inst->global_data + global->data_offset));
  5411. }
  5412. }
  5413. for (i = 0; i < module->table_count; i++) {
  5414. table_inst = module_inst->tables[i];
  5415. if ((table + i)->elem_type == VALUE_TYPE_EXTERNREF) {
  5416. while (j < table_inst->cur_size) {
  5417. mark_externref(table_inst->elems[j++]);
  5418. }
  5419. }
  5420. }
  5421. }
  5422. #endif
  5423. void
  5424. wasm_externref_reclaim(WASMModuleInstanceCommon *module_inst)
  5425. {
  5426. os_mutex_lock(&externref_lock);
  5427. #if WASM_ENABLE_INTERP != 0
  5428. if (module_inst->module_type == Wasm_Module_Bytecode)
  5429. interp_mark_all_externrefs((WASMModuleInstance *)module_inst);
  5430. #endif
  5431. #if WASM_ENABLE_AOT != 0
  5432. if (module_inst->module_type == Wasm_Module_AoT)
  5433. aot_mark_all_externrefs((AOTModuleInstance *)module_inst);
  5434. #endif
  5435. bh_hash_map_traverse(externref_map, reclaim_extobj_callback,
  5436. (void *)module_inst);
  5437. os_mutex_unlock(&externref_lock);
  5438. }
  5439. static void
  5440. cleanup_extobj_callback(void *key, void *value, void *user_data)
  5441. {
  5442. ExternRefMapNode *node = (ExternRefMapNode *)value;
  5443. WASMModuleInstanceCommon *module_inst =
  5444. (WASMModuleInstanceCommon *)user_data;
  5445. if (node->module_inst == module_inst) {
  5446. delete_externref(key, node);
  5447. }
  5448. }
  5449. void
  5450. wasm_externref_cleanup(WASMModuleInstanceCommon *module_inst)
  5451. {
  5452. os_mutex_lock(&externref_lock);
  5453. bh_hash_map_traverse(externref_map, cleanup_extobj_callback,
  5454. (void *)module_inst);
  5455. os_mutex_unlock(&externref_lock);
  5456. }
  5457. bool
  5458. wasm_externref_retain(uint32 externref_idx)
  5459. {
  5460. ExternRefMapNode *node;
  5461. os_mutex_lock(&externref_lock);
  5462. if (externref_idx != NULL_REF) {
  5463. node =
  5464. bh_hash_map_find(externref_map, (void *)(uintptr_t)externref_idx);
  5465. if (node) {
  5466. node->retained = true;
  5467. os_mutex_unlock(&externref_lock);
  5468. return true;
  5469. }
  5470. }
  5471. os_mutex_unlock(&externref_lock);
  5472. return false;
  5473. }
  5474. #endif /* end of WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0 */
  5475. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  5476. uint32
  5477. wasm_runtime_dump_line_buf_impl(const char *line_buf, bool dump_or_print,
  5478. char **buf, uint32 *len)
  5479. {
  5480. if (dump_or_print) {
  5481. return (uint32)os_printf("%s", line_buf);
  5482. }
  5483. else if (*buf) {
  5484. uint32 dump_len;
  5485. dump_len = snprintf(*buf, *len, "%s", line_buf);
  5486. if (dump_len >= *len) {
  5487. dump_len = *len;
  5488. }
  5489. *len = *len - dump_len;
  5490. *buf = *buf + dump_len;
  5491. return dump_len;
  5492. }
  5493. else {
  5494. return (uint32)strlen(line_buf);
  5495. }
  5496. }
  5497. void
  5498. wasm_runtime_dump_call_stack(WASMExecEnv *exec_env)
  5499. {
  5500. WASMModuleInstanceCommon *module_inst =
  5501. wasm_exec_env_get_module_inst(exec_env);
  5502. #if WASM_ENABLE_INTERP != 0
  5503. if (module_inst->module_type == Wasm_Module_Bytecode) {
  5504. wasm_interp_dump_call_stack(exec_env, true, NULL, 0);
  5505. }
  5506. #endif
  5507. #if WASM_ENABLE_AOT != 0
  5508. if (module_inst->module_type == Wasm_Module_AoT) {
  5509. aot_dump_call_stack(exec_env, true, NULL, 0);
  5510. }
  5511. #endif
  5512. }
  5513. uint32
  5514. wasm_runtime_get_call_stack_buf_size(wasm_exec_env_t exec_env)
  5515. {
  5516. WASMModuleInstanceCommon *module_inst =
  5517. wasm_exec_env_get_module_inst(exec_env);
  5518. #if WASM_ENABLE_INTERP != 0
  5519. if (module_inst->module_type == Wasm_Module_Bytecode) {
  5520. return wasm_interp_dump_call_stack(exec_env, false, NULL, 0);
  5521. }
  5522. #endif
  5523. #if WASM_ENABLE_AOT != 0
  5524. if (module_inst->module_type == Wasm_Module_AoT) {
  5525. return aot_dump_call_stack(exec_env, false, NULL, 0);
  5526. }
  5527. #endif
  5528. return 0;
  5529. }
  5530. uint32
  5531. wasm_runtime_dump_call_stack_to_buf(wasm_exec_env_t exec_env, char *buf,
  5532. uint32 len)
  5533. {
  5534. WASMModuleInstanceCommon *module_inst =
  5535. wasm_exec_env_get_module_inst(exec_env);
  5536. #if WASM_ENABLE_INTERP != 0
  5537. if (module_inst->module_type == Wasm_Module_Bytecode) {
  5538. return wasm_interp_dump_call_stack(exec_env, false, buf, len);
  5539. }
  5540. #endif
  5541. #if WASM_ENABLE_AOT != 0
  5542. if (module_inst->module_type == Wasm_Module_AoT) {
  5543. return aot_dump_call_stack(exec_env, false, buf, len);
  5544. }
  5545. #endif
  5546. return 0;
  5547. }
  5548. #endif /* end of WASM_ENABLE_DUMP_CALL_STACK */
  5549. #if WASM_ENABLE_STATIC_PGO != 0
  5550. uint32
  5551. wasm_runtime_get_pgo_prof_data_size(WASMModuleInstanceCommon *module_inst)
  5552. {
  5553. #if WASM_ENABLE_AOT != 0
  5554. if (module_inst->module_type == Wasm_Module_AoT) {
  5555. AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst;
  5556. return aot_get_pgo_prof_data_size(aot_inst);
  5557. }
  5558. #endif
  5559. return 0;
  5560. }
  5561. uint32
  5562. wasm_runtime_dump_pgo_prof_data_to_buf(WASMModuleInstanceCommon *module_inst,
  5563. char *buf, uint32 len)
  5564. {
  5565. #if WASM_ENABLE_AOT != 0
  5566. if (module_inst->module_type == Wasm_Module_AoT) {
  5567. AOTModuleInstance *aot_inst = (AOTModuleInstance *)module_inst;
  5568. return aot_dump_pgo_prof_data_to_buf(aot_inst, buf, len);
  5569. }
  5570. #endif
  5571. return 0;
  5572. }
  5573. #endif /* end of WASM_ENABLE_STATIC_PGO != 0 */
  5574. bool
  5575. wasm_runtime_get_table_elem_type(const WASMModuleCommon *module_comm,
  5576. uint32 table_idx, uint8 *out_elem_type,
  5577. #if WASM_ENABLE_GC != 0
  5578. WASMRefType **out_ref_type,
  5579. #endif
  5580. uint32 *out_min_size, uint32 *out_max_size)
  5581. {
  5582. #if WASM_ENABLE_INTERP != 0
  5583. if (module_comm->module_type == Wasm_Module_Bytecode) {
  5584. WASMModule *module = (WASMModule *)module_comm;
  5585. if (table_idx < module->import_table_count) {
  5586. WASMTableImport *import_table =
  5587. &((module->import_tables + table_idx)->u.table);
  5588. *out_elem_type = import_table->elem_type;
  5589. #if WASM_ENABLE_GC != 0
  5590. *out_ref_type = import_table->elem_ref_type;
  5591. #endif
  5592. *out_min_size = import_table->init_size;
  5593. *out_max_size = import_table->max_size;
  5594. }
  5595. else {
  5596. WASMTable *table =
  5597. module->tables + (table_idx - module->import_table_count);
  5598. *out_elem_type = table->elem_type;
  5599. #if WASM_ENABLE_GC != 0
  5600. *out_ref_type = table->elem_ref_type;
  5601. #endif
  5602. *out_min_size = table->init_size;
  5603. *out_max_size = table->max_size;
  5604. }
  5605. return true;
  5606. }
  5607. #endif
  5608. #if WASM_ENABLE_AOT != 0
  5609. if (module_comm->module_type == Wasm_Module_AoT) {
  5610. AOTModule *module = (AOTModule *)module_comm;
  5611. if (table_idx < module->import_table_count) {
  5612. AOTImportTable *import_table = module->import_tables + table_idx;
  5613. *out_elem_type = import_table->elem_type;
  5614. #if WASM_ENABLE_GC != 0
  5615. *out_ref_type = NULL; /* TODO */
  5616. #endif
  5617. *out_min_size = import_table->table_init_size;
  5618. *out_max_size = import_table->table_max_size;
  5619. }
  5620. else {
  5621. AOTTable *table =
  5622. module->tables + (table_idx - module->import_table_count);
  5623. *out_elem_type = table->elem_type;
  5624. #if WASM_ENABLE_GC != 0
  5625. *out_ref_type = NULL; /* TODO */
  5626. #endif
  5627. *out_min_size = table->table_init_size;
  5628. *out_max_size = table->table_max_size;
  5629. }
  5630. return true;
  5631. }
  5632. #endif
  5633. return false;
  5634. }
  5635. bool
  5636. wasm_runtime_get_table_inst_elem_type(
  5637. const WASMModuleInstanceCommon *module_inst_comm, uint32 table_idx,
  5638. uint8 *out_elem_type,
  5639. #if WASM_ENABLE_GC != 0
  5640. WASMRefType **out_ref_type,
  5641. #endif
  5642. uint32 *out_min_size, uint32 *out_max_size)
  5643. {
  5644. WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
  5645. bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
  5646. || module_inst_comm->module_type == Wasm_Module_AoT);
  5647. return wasm_runtime_get_table_elem_type(
  5648. (WASMModuleCommon *)module_inst->module, table_idx, out_elem_type,
  5649. #if WASM_ENABLE_GC != 0
  5650. out_ref_type,
  5651. #endif
  5652. out_min_size, out_max_size);
  5653. }
  5654. bool
  5655. wasm_runtime_get_export_func_type(const WASMModuleCommon *module_comm,
  5656. const WASMExport *export, WASMFuncType **out)
  5657. {
  5658. #if WASM_ENABLE_INTERP != 0
  5659. if (module_comm->module_type == Wasm_Module_Bytecode) {
  5660. WASMModule *module = (WASMModule *)module_comm;
  5661. if (export->index < module->import_function_count) {
  5662. *out = module->import_functions[export->index].u.function.func_type;
  5663. }
  5664. else {
  5665. *out =
  5666. module->functions[export->index - module->import_function_count]
  5667. ->func_type;
  5668. }
  5669. return true;
  5670. }
  5671. #endif
  5672. #if WASM_ENABLE_AOT != 0
  5673. if (module_comm->module_type == Wasm_Module_AoT) {
  5674. AOTModule *module = (AOTModule *)module_comm;
  5675. if (export->index < module->import_func_count) {
  5676. *out = (WASMFuncType *)
  5677. module->types[module->import_funcs[export->index]
  5678. .func_type_index];
  5679. }
  5680. else {
  5681. *out = (WASMFuncType *)module
  5682. ->types[module->func_type_indexes
  5683. [export->index - module->import_func_count]];
  5684. }
  5685. return true;
  5686. }
  5687. #endif
  5688. return false;
  5689. }
  5690. bool
  5691. wasm_runtime_get_export_global_type(const WASMModuleCommon *module_comm,
  5692. const WASMExport *export,
  5693. uint8 *out_val_type, bool *out_mutability)
  5694. {
  5695. #if WASM_ENABLE_INTERP != 0
  5696. if (module_comm->module_type == Wasm_Module_Bytecode) {
  5697. WASMModule *module = (WASMModule *)module_comm;
  5698. if (export->index < module->import_global_count) {
  5699. WASMGlobalImport *import_global =
  5700. &((module->import_globals + export->index)->u.global);
  5701. *out_val_type = import_global->type.val_type;
  5702. *out_mutability = import_global->type.is_mutable;
  5703. }
  5704. else {
  5705. WASMGlobal *global =
  5706. module->globals + (export->index - module->import_global_count);
  5707. *out_val_type = global->type.val_type;
  5708. *out_mutability = global->type.is_mutable;
  5709. }
  5710. return true;
  5711. }
  5712. #endif
  5713. #if WASM_ENABLE_AOT != 0
  5714. if (module_comm->module_type == Wasm_Module_AoT) {
  5715. AOTModule *module = (AOTModule *)module_comm;
  5716. if (export->index < module->import_global_count) {
  5717. AOTImportGlobal *import_global =
  5718. module->import_globals + export->index;
  5719. *out_val_type = import_global->type.val_type;
  5720. *out_mutability = import_global->type.is_mutable;
  5721. }
  5722. else {
  5723. AOTGlobal *global =
  5724. module->globals + (export->index - module->import_global_count);
  5725. *out_val_type = global->type.val_type;
  5726. *out_mutability = global->type.is_mutable;
  5727. }
  5728. return true;
  5729. }
  5730. #endif
  5731. return false;
  5732. }
  5733. bool
  5734. wasm_runtime_get_export_memory_type(const WASMModuleCommon *module_comm,
  5735. const WASMExport *export,
  5736. uint32 *out_min_page, uint32 *out_max_page)
  5737. {
  5738. #if WASM_ENABLE_INTERP != 0
  5739. if (module_comm->module_type == Wasm_Module_Bytecode) {
  5740. WASMModule *module = (WASMModule *)module_comm;
  5741. if (export->index < module->import_memory_count) {
  5742. WASMMemoryImport *import_memory =
  5743. &((module->import_memories + export->index)->u.memory);
  5744. *out_min_page = import_memory->init_page_count;
  5745. *out_max_page = import_memory->max_page_count;
  5746. }
  5747. else {
  5748. WASMMemory *memory =
  5749. module->memories
  5750. + (export->index - module->import_memory_count);
  5751. *out_min_page = memory->init_page_count;
  5752. *out_max_page = memory->max_page_count;
  5753. }
  5754. return true;
  5755. }
  5756. #endif
  5757. #if WASM_ENABLE_AOT != 0
  5758. if (module_comm->module_type == Wasm_Module_AoT) {
  5759. AOTModule *module = (AOTModule *)module_comm;
  5760. if (export->index < module->import_memory_count) {
  5761. AOTImportMemory *import_memory =
  5762. module->import_memories + export->index;
  5763. *out_min_page = import_memory->mem_init_page_count;
  5764. *out_max_page = import_memory->mem_max_page_count;
  5765. }
  5766. else {
  5767. AOTMemory *memory = module->memories
  5768. + (export->index - module->import_memory_count);
  5769. *out_min_page = memory->mem_init_page_count;
  5770. *out_max_page = memory->mem_max_page_count;
  5771. }
  5772. return true;
  5773. }
  5774. #endif
  5775. return false;
  5776. }
  5777. bool
  5778. wasm_runtime_get_export_table_type(const WASMModuleCommon *module_comm,
  5779. const WASMExport *export,
  5780. uint8 *out_elem_type,
  5781. #if WASM_ENABLE_GC != 0
  5782. WASMRefType **out_ref_type,
  5783. #endif
  5784. uint32 *out_min_size, uint32 *out_max_size)
  5785. {
  5786. return wasm_runtime_get_table_elem_type(module_comm, export->index,
  5787. out_elem_type,
  5788. #if WASM_ENABLE_GC != 0
  5789. out_ref_type,
  5790. #endif
  5791. out_min_size, out_max_size);
  5792. }
  5793. static inline bool
  5794. argv_to_params(wasm_val_t *out_params, const uint32 *argv,
  5795. WASMFuncType *func_type)
  5796. {
  5797. wasm_val_t *param = out_params;
  5798. uint32 i = 0, *u32;
  5799. for (i = 0; i < func_type->param_count; i++, param++) {
  5800. switch (func_type->types[i]) {
  5801. case VALUE_TYPE_I32:
  5802. param->kind = WASM_I32;
  5803. param->of.i32 = *argv++;
  5804. break;
  5805. case VALUE_TYPE_I64:
  5806. param->kind = WASM_I64;
  5807. u32 = (uint32 *)&param->of.i64;
  5808. u32[0] = *argv++;
  5809. u32[1] = *argv++;
  5810. break;
  5811. case VALUE_TYPE_F32:
  5812. param->kind = WASM_F32;
  5813. param->of.f32 = *(float32 *)argv++;
  5814. break;
  5815. case VALUE_TYPE_F64:
  5816. param->kind = WASM_F64;
  5817. u32 = (uint32 *)&param->of.i64;
  5818. u32[0] = *argv++;
  5819. u32[1] = *argv++;
  5820. break;
  5821. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  5822. case VALUE_TYPE_EXTERNREF:
  5823. param->kind = WASM_EXTERNREF;
  5824. if (!wasm_externref_ref2obj(*argv,
  5825. (void **)&param->of.foreign)) {
  5826. return false;
  5827. }
  5828. argv++;
  5829. break;
  5830. #endif
  5831. default:
  5832. return false;
  5833. }
  5834. }
  5835. return true;
  5836. }
  5837. static inline bool
  5838. results_to_argv(WASMModuleInstanceCommon *module_inst, uint32 *out_argv,
  5839. const wasm_val_t *results, WASMFuncType *func_type)
  5840. {
  5841. const wasm_val_t *result = results;
  5842. uint32 *argv = out_argv, *u32, i;
  5843. uint8 *result_types = func_type->types + func_type->param_count;
  5844. for (i = 0; i < func_type->result_count; i++, result++) {
  5845. switch (result_types[i]) {
  5846. case VALUE_TYPE_I32:
  5847. case VALUE_TYPE_F32:
  5848. *(int32 *)argv++ = result->of.i32;
  5849. break;
  5850. case VALUE_TYPE_I64:
  5851. case VALUE_TYPE_F64:
  5852. u32 = (uint32 *)&result->of.i64;
  5853. *argv++ = u32[0];
  5854. *argv++ = u32[1];
  5855. break;
  5856. #if WASM_ENABLE_GC == 0 && WASM_ENABLE_REF_TYPES != 0
  5857. case VALUE_TYPE_EXTERNREF:
  5858. if (!wasm_externref_obj2ref(module_inst,
  5859. (void *)result->of.foreign,
  5860. (uint32 *)argv)) {
  5861. return false;
  5862. }
  5863. argv++;
  5864. break;
  5865. #endif
  5866. default:
  5867. return false;
  5868. }
  5869. }
  5870. return true;
  5871. }
  5872. bool
  5873. wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
  5874. void *func_ptr, WASMFuncType *func_type,
  5875. uint32 argc, uint32 *argv, bool with_env,
  5876. void *wasm_c_api_env)
  5877. {
  5878. wasm_val_t params_buf[16] = { 0 }, results_buf[4] = { 0 };
  5879. wasm_val_t *params = params_buf, *results = results_buf;
  5880. wasm_trap_t *trap = NULL;
  5881. bool ret = false;
  5882. wasm_val_vec_t params_vec = { 0 }, results_vec = { 0 };
  5883. if (func_type->param_count > 16) {
  5884. if (!(params =
  5885. runtime_malloc(sizeof(wasm_val_t) * func_type->param_count,
  5886. module_inst, NULL, 0))) {
  5887. wasm_runtime_set_exception(module_inst, "allocate memory failed");
  5888. return false;
  5889. }
  5890. }
  5891. if (!argv_to_params(params, argv, func_type)) {
  5892. wasm_runtime_set_exception(module_inst, "unsupported param type");
  5893. goto fail;
  5894. }
  5895. if (func_type->result_count > 4) {
  5896. if (!(results =
  5897. runtime_malloc(sizeof(wasm_val_t) * func_type->result_count,
  5898. module_inst, NULL, 0))) {
  5899. wasm_runtime_set_exception(module_inst, "allocate memory failed");
  5900. goto fail;
  5901. }
  5902. }
  5903. params_vec.data = params;
  5904. params_vec.num_elems = func_type->param_count;
  5905. params_vec.size = func_type->param_count;
  5906. results_vec.data = results;
  5907. results_vec.num_elems = 0;
  5908. results_vec.size = func_type->result_count;
  5909. if (!with_env) {
  5910. wasm_func_callback_t callback = (wasm_func_callback_t)func_ptr;
  5911. trap = callback(&params_vec, &results_vec);
  5912. }
  5913. else {
  5914. wasm_func_callback_with_env_t callback =
  5915. (wasm_func_callback_with_env_t)func_ptr;
  5916. trap = callback(wasm_c_api_env, &params_vec, &results_vec);
  5917. }
  5918. if (trap) {
  5919. if (trap->message->data) {
  5920. /* since trap->message->data does not end with '\0' */
  5921. char trap_message[108] = { 0 };
  5922. uint32 max_size_to_copy = (uint32)sizeof(trap_message) - 1;
  5923. uint32 size_to_copy = (trap->message->size < max_size_to_copy)
  5924. ? (uint32)trap->message->size
  5925. : max_size_to_copy;
  5926. bh_memcpy_s(trap_message, (uint32)sizeof(trap_message),
  5927. trap->message->data, size_to_copy);
  5928. wasm_runtime_set_exception(module_inst, trap_message);
  5929. }
  5930. else {
  5931. wasm_runtime_set_exception(
  5932. module_inst, "native function throw unknown exception");
  5933. }
  5934. wasm_trap_delete(trap);
  5935. goto fail;
  5936. }
  5937. if (!results_to_argv(module_inst, argv, results, func_type)) {
  5938. wasm_runtime_set_exception(module_inst, "unsupported result type");
  5939. goto fail;
  5940. }
  5941. ret = true;
  5942. fail:
  5943. if (params != params_buf)
  5944. wasm_runtime_free(params);
  5945. if (results != results_buf)
  5946. wasm_runtime_free(results);
  5947. return ret;
  5948. }
  5949. bool
  5950. wasm_runtime_quick_invoke_c_api_native(WASMModuleInstanceCommon *inst_comm,
  5951. CApiFuncImport *c_api_import,
  5952. wasm_val_t *params, uint32 param_count,
  5953. wasm_val_t *results, uint32 result_count)
  5954. {
  5955. WASMModuleInstance *module_inst = (WASMModuleInstance *)inst_comm;
  5956. void *func_ptr = c_api_import->func_ptr_linked;
  5957. bool with_env_arg = c_api_import->with_env_arg, ret = true;
  5958. wasm_val_vec_t params_vec = { 0 }, results_vec = { 0 };
  5959. wasm_trap_t *trap = NULL;
  5960. params_vec.data = params;
  5961. params_vec.num_elems = param_count;
  5962. params_vec.size = param_count;
  5963. results_vec.data = results;
  5964. results_vec.num_elems = 0;
  5965. results_vec.size = result_count;
  5966. if (!func_ptr) {
  5967. wasm_set_exception_with_id(module_inst, EXCE_CALL_UNLINKED_IMPORT_FUNC);
  5968. ret = false;
  5969. goto fail;
  5970. }
  5971. if (!with_env_arg) {
  5972. wasm_func_callback_t callback = (wasm_func_callback_t)func_ptr;
  5973. trap = callback(&params_vec, &results_vec);
  5974. }
  5975. else {
  5976. void *wasm_c_api_env = c_api_import->env_arg;
  5977. wasm_func_callback_with_env_t callback =
  5978. (wasm_func_callback_with_env_t)func_ptr;
  5979. trap = callback(wasm_c_api_env, &params_vec, &results_vec);
  5980. }
  5981. if (trap) {
  5982. if (trap->message->data) {
  5983. /* since trap->message->data does not end with '\0' */
  5984. char trap_message[108] = { 0 };
  5985. uint32 max_size_to_copy = (uint32)sizeof(trap_message) - 1;
  5986. uint32 size_to_copy = (trap->message->size < max_size_to_copy)
  5987. ? (uint32)trap->message->size
  5988. : max_size_to_copy;
  5989. bh_memcpy_s(trap_message, (uint32)sizeof(trap_message),
  5990. trap->message->data, size_to_copy);
  5991. wasm_set_exception(module_inst, trap_message);
  5992. }
  5993. else {
  5994. wasm_set_exception(module_inst,
  5995. "native function throw unknown exception");
  5996. }
  5997. wasm_trap_delete(trap);
  5998. ret = false;
  5999. }
  6000. fail:
  6001. #ifdef OS_ENABLE_HW_BOUND_CHECK
  6002. if (!ret)
  6003. wasm_runtime_access_exce_check_guard_page();
  6004. #endif
  6005. return ret;
  6006. }
  6007. void
  6008. wasm_runtime_show_app_heap_corrupted_prompt()
  6009. {
  6010. LOG_ERROR("Error: app heap is corrupted, if the wasm file "
  6011. "is compiled by wasi-sdk-12.0 or higher version, "
  6012. "please add -Wl,--export=malloc -Wl,--export=free "
  6013. "to export malloc and free functions. If it is "
  6014. "compiled by asc, please add --exportRuntime to "
  6015. "export the runtime helpers.");
  6016. }
  6017. #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
  6018. void
  6019. wasm_runtime_destroy_custom_sections(WASMCustomSection *section_list)
  6020. {
  6021. WASMCustomSection *section = section_list, *next;
  6022. while (section) {
  6023. next = section->next;
  6024. wasm_runtime_free(section);
  6025. section = next;
  6026. }
  6027. }
  6028. #endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION */
  6029. void
  6030. wasm_runtime_get_version(uint32_t *major, uint32_t *minor, uint32_t *patch)
  6031. {
  6032. *major = WAMR_VERSION_MAJOR;
  6033. *minor = WAMR_VERSION_MINOR;
  6034. *patch = WAMR_VERSION_PATCH;
  6035. }
  6036. bool
  6037. wasm_runtime_is_import_func_linked(const char *module_name,
  6038. const char *func_name)
  6039. {
  6040. return wasm_native_resolve_symbol(module_name, func_name, NULL, NULL, NULL,
  6041. NULL);
  6042. }
  6043. bool
  6044. wasm_runtime_is_import_global_linked(const char *module_name,
  6045. const char *global_name)
  6046. {
  6047. #if WASM_ENABLE_LIBC_BUILTIN != 0
  6048. WASMGlobalImport global = { 0 };
  6049. return wasm_native_lookup_libc_builtin_global(module_name, global_name,
  6050. &global);
  6051. #else
  6052. return false;
  6053. #endif
  6054. }
  6055. #if WASM_ENABLE_LIBC_WASI != 0 || WASM_ENABLE_MULTI_MODULE != 0
  6056. WASMExport *
  6057. loader_find_export(const WASMModuleCommon *module, const char *module_name,
  6058. const char *field_name, uint8 export_kind, char *error_buf,
  6059. uint32 error_buf_size)
  6060. {
  6061. WASMExport *exports = NULL, *result = NULL, *export;
  6062. uint32 export_count = 0, i;
  6063. #if WASM_ENABLE_AOT != 0
  6064. if (module->module_type == Wasm_Module_AoT) {
  6065. AOTModule *aot_module = (AOTModule *)module;
  6066. exports = (WASMExport *)aot_module->exports;
  6067. export_count = aot_module->export_count;
  6068. }
  6069. #endif
  6070. #if WASM_ENABLE_INTERP != 0
  6071. if (module->module_type == Wasm_Module_Bytecode) {
  6072. WASMModule *wasm_module = (WASMModule *)module;
  6073. exports = wasm_module->exports;
  6074. export_count = wasm_module->export_count;
  6075. }
  6076. #endif
  6077. for (i = 0, export = exports; i < export_count; ++i, ++export) {
  6078. if (export->kind == export_kind && !strcmp(field_name, export->name)) {
  6079. result = export;
  6080. goto exit;
  6081. }
  6082. }
  6083. if (i == export_count) {
  6084. LOG_DEBUG("can not find an export %d named %s in the module %s",
  6085. export_kind, field_name, module_name);
  6086. set_error_buf(error_buf, error_buf_size,
  6087. "unknown import or incompatible import type");
  6088. }
  6089. exit:
  6090. return result;
  6091. }
  6092. #endif
  6093. #if WASM_ENABLE_MULTI_MODULE != 0
  6094. WASMModuleCommon *
  6095. wasm_runtime_search_sub_module(const WASMModuleCommon *parent_module,
  6096. const char *sub_module_name)
  6097. {
  6098. WASMRegisteredModule *node = NULL;
  6099. #if WASM_ENABLE_AOT != 0
  6100. if (parent_module->module_type == Wasm_Module_AoT) {
  6101. node = bh_list_first_elem(
  6102. ((AOTModule *)parent_module)->import_module_list);
  6103. }
  6104. #endif
  6105. #if WASM_ENABLE_INTERP != 0
  6106. if (parent_module->module_type == Wasm_Module_Bytecode) {
  6107. node = bh_list_first_elem(
  6108. ((WASMModule *)parent_module)->import_module_list);
  6109. }
  6110. #endif
  6111. while (node && strcmp(sub_module_name, node->module_name)) {
  6112. node = bh_list_elem_next(node);
  6113. }
  6114. return node ? node->module : NULL;
  6115. }
  6116. bool
  6117. wasm_runtime_register_sub_module(const WASMModuleCommon *parent_module,
  6118. const char *sub_module_name,
  6119. WASMModuleCommon *sub_module)
  6120. {
  6121. /* register sub_module into its parent sub module list */
  6122. WASMRegisteredModule *node = NULL;
  6123. bh_list_status ret = BH_LIST_ERROR;
  6124. if (wasm_runtime_search_sub_module(parent_module, sub_module_name)) {
  6125. LOG_DEBUG("%s has been registered in its parent", sub_module_name);
  6126. return true;
  6127. }
  6128. node = loader_malloc(sizeof(WASMRegisteredModule), NULL, 0);
  6129. if (!node) {
  6130. return false;
  6131. }
  6132. node->module_name = sub_module_name;
  6133. node->module = sub_module;
  6134. #if WASM_ENABLE_AOT != 0
  6135. if (parent_module->module_type == Wasm_Module_AoT) {
  6136. ret = bh_list_insert(((AOTModule *)parent_module)->import_module_list,
  6137. node);
  6138. }
  6139. #endif
  6140. #if WASM_ENABLE_INTERP != 0
  6141. if (parent_module->module_type == Wasm_Module_Bytecode) {
  6142. ret = bh_list_insert(((WASMModule *)parent_module)->import_module_list,
  6143. node);
  6144. }
  6145. #endif
  6146. bh_assert(BH_LIST_SUCCESS == ret);
  6147. (void)ret;
  6148. return true;
  6149. }
  6150. WASMModuleCommon *
  6151. wasm_runtime_load_depended_module(const WASMModuleCommon *parent_module,
  6152. const char *sub_module_name, char *error_buf,
  6153. uint32 error_buf_size)
  6154. {
  6155. WASMModuleCommon *sub_module = NULL;
  6156. bool ret = false;
  6157. uint8 *buffer = NULL;
  6158. uint32 buffer_size = 0;
  6159. LoadArgs args = { 0 };
  6160. /* check the registered module list of the parent */
  6161. sub_module = wasm_runtime_search_sub_module(parent_module, sub_module_name);
  6162. if (sub_module) {
  6163. LOG_DEBUG("%s has been loaded before", sub_module_name);
  6164. return sub_module;
  6165. }
  6166. /* check the global registered module list */
  6167. sub_module = wasm_runtime_find_module_registered(sub_module_name);
  6168. if (sub_module) {
  6169. LOG_DEBUG("%s has been loaded", sub_module_name);
  6170. goto wasm_runtime_register_sub_module;
  6171. }
  6172. LOG_VERBOSE("loading %s", sub_module_name);
  6173. if (!reader) {
  6174. set_error_buf_v(parent_module, error_buf, error_buf_size,
  6175. "no sub module reader to load %s", sub_module_name);
  6176. return NULL;
  6177. }
  6178. /* start to maintain a loading module list */
  6179. ret = wasm_runtime_is_loading_module(sub_module_name);
  6180. if (ret) {
  6181. set_error_buf_v(parent_module, error_buf, error_buf_size,
  6182. "found circular dependency on %s", sub_module_name);
  6183. return NULL;
  6184. }
  6185. ret = wasm_runtime_add_loading_module(sub_module_name, error_buf,
  6186. error_buf_size);
  6187. if (!ret) {
  6188. LOG_DEBUG("can not add %s into loading module list\n", sub_module_name);
  6189. return NULL;
  6190. }
  6191. ret = reader(parent_module->module_type, sub_module_name, &buffer,
  6192. &buffer_size);
  6193. if (!ret) {
  6194. LOG_DEBUG("read the file of %s failed", sub_module_name);
  6195. set_error_buf_v(parent_module, error_buf, error_buf_size,
  6196. "unknown import %s", sub_module_name);
  6197. goto delete_loading_module;
  6198. }
  6199. if (get_package_type(buffer, buffer_size) != parent_module->module_type) {
  6200. LOG_DEBUG("module %s type error", sub_module_name);
  6201. goto destroy_file_buffer;
  6202. }
  6203. args.name = (char *)sub_module_name;
  6204. if (get_package_type(buffer, buffer_size) == Wasm_Module_Bytecode) {
  6205. #if WASM_ENABLE_INTERP != 0
  6206. sub_module = (WASMModuleCommon *)wasm_load(
  6207. buffer, buffer_size, false, &args, error_buf, error_buf_size);
  6208. #endif
  6209. }
  6210. else if (get_package_type(buffer, buffer_size) == Wasm_Module_AoT) {
  6211. #if WASM_ENABLE_AOT != 0
  6212. sub_module = (WASMModuleCommon *)aot_load_from_aot_file(
  6213. buffer, buffer_size, &args, error_buf, error_buf_size);
  6214. #endif
  6215. }
  6216. if (!sub_module) {
  6217. LOG_DEBUG("error: can not load the sub_module %s", sub_module_name);
  6218. /* others will be destroyed in runtime_destroy() */
  6219. goto destroy_file_buffer;
  6220. }
  6221. wasm_runtime_delete_loading_module(sub_module_name);
  6222. /* register on a global list */
  6223. ret = wasm_runtime_register_module_internal(
  6224. sub_module_name, (WASMModuleCommon *)sub_module, buffer, buffer_size,
  6225. error_buf, error_buf_size);
  6226. if (!ret) {
  6227. LOG_DEBUG("error: can not register module %s globally\n",
  6228. sub_module_name);
  6229. /* others will be unloaded in runtime_destroy() */
  6230. goto unload_module;
  6231. }
  6232. /* register into its parent list */
  6233. wasm_runtime_register_sub_module:
  6234. ret = wasm_runtime_register_sub_module(parent_module, sub_module_name,
  6235. sub_module);
  6236. if (!ret) {
  6237. set_error_buf_v(parent_module, error_buf, error_buf_size,
  6238. "failed to register sub module %s", sub_module_name);
  6239. /* since it is in the global module list, no need to
  6240. * unload the module. the runtime_destroy() will do it
  6241. */
  6242. return NULL;
  6243. }
  6244. return sub_module;
  6245. unload_module:
  6246. wasm_runtime_unload(sub_module);
  6247. destroy_file_buffer:
  6248. if (destroyer) {
  6249. destroyer(buffer, buffer_size);
  6250. }
  6251. else {
  6252. LOG_WARNING("need to release the reading buffer of %s manually",
  6253. sub_module_name);
  6254. }
  6255. delete_loading_module:
  6256. wasm_runtime_delete_loading_module(sub_module_name);
  6257. return NULL;
  6258. }
  6259. bool
  6260. wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
  6261. WASMModuleInstanceCommon *module_inst,
  6262. uint32 stack_size, uint32 heap_size,
  6263. uint32 max_memory_pages, char *error_buf,
  6264. uint32 error_buf_size)
  6265. {
  6266. bh_list *sub_module_inst_list = NULL;
  6267. WASMRegisteredModule *sub_module_list_node = NULL;
  6268. #if WASM_ENABLE_AOT != 0
  6269. if (module->module_type == Wasm_Module_AoT) {
  6270. sub_module_inst_list =
  6271. ((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
  6272. ->sub_module_inst_list;
  6273. sub_module_list_node =
  6274. bh_list_first_elem(((AOTModule *)module)->import_module_list);
  6275. }
  6276. #endif
  6277. #if WASM_ENABLE_INTERP != 0
  6278. if (module->module_type == Wasm_Module_Bytecode) {
  6279. sub_module_inst_list =
  6280. ((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e)
  6281. ->sub_module_inst_list;
  6282. sub_module_list_node =
  6283. bh_list_first_elem(((WASMModule *)module)->import_module_list);
  6284. }
  6285. #endif
  6286. while (sub_module_list_node) {
  6287. WASMSubModInstNode *sub_module_inst_list_node = NULL;
  6288. WASMModuleCommon *sub_module = sub_module_list_node->module;
  6289. WASMModuleInstanceCommon *sub_module_inst = NULL;
  6290. sub_module_inst = wasm_runtime_instantiate_internal(
  6291. sub_module, NULL, NULL, stack_size, heap_size, max_memory_pages,
  6292. error_buf, error_buf_size);
  6293. if (!sub_module_inst) {
  6294. LOG_DEBUG("instantiate %s failed",
  6295. sub_module_list_node->module_name);
  6296. return false;
  6297. }
  6298. sub_module_inst_list_node = loader_malloc(sizeof(WASMSubModInstNode),
  6299. error_buf, error_buf_size);
  6300. if (!sub_module_inst_list_node) {
  6301. LOG_DEBUG("Malloc WASMSubModInstNode failed, SZ: %zu",
  6302. sizeof(WASMSubModInstNode));
  6303. if (sub_module_inst)
  6304. wasm_runtime_deinstantiate_internal(sub_module_inst, false);
  6305. return false;
  6306. }
  6307. sub_module_inst_list_node->module_inst =
  6308. (WASMModuleInstance *)sub_module_inst;
  6309. sub_module_inst_list_node->module_name =
  6310. sub_module_list_node->module_name;
  6311. bh_list_status ret =
  6312. bh_list_insert(sub_module_inst_list, sub_module_inst_list_node);
  6313. bh_assert(BH_LIST_SUCCESS == ret);
  6314. (void)ret;
  6315. sub_module_list_node = bh_list_elem_next(sub_module_list_node);
  6316. }
  6317. return true;
  6318. }
  6319. void
  6320. wasm_runtime_sub_module_deinstantiate(WASMModuleInstanceCommon *module_inst)
  6321. {
  6322. bh_list *list = NULL;
  6323. #if WASM_ENABLE_AOT != 0
  6324. if (module_inst->module_type == Wasm_Module_AoT) {
  6325. list = ((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
  6326. ->sub_module_inst_list;
  6327. }
  6328. #endif
  6329. #if WASM_ENABLE_INTERP != 0
  6330. if (module_inst->module_type == Wasm_Module_Bytecode) {
  6331. list =
  6332. ((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e)
  6333. ->sub_module_inst_list;
  6334. }
  6335. #endif
  6336. WASMSubModInstNode *node = bh_list_first_elem(list);
  6337. while (node) {
  6338. WASMSubModInstNode *next_node = bh_list_elem_next(node);
  6339. bh_list_remove(list, node);
  6340. wasm_runtime_deinstantiate_internal(
  6341. (WASMModuleInstanceCommon *)node->module_inst, false);
  6342. wasm_runtime_free(node);
  6343. node = next_node;
  6344. }
  6345. }
  6346. #endif /* end of WASM_ENABLE_MULTI_MODULE */
  6347. #if WASM_ENABLE_MODULE_INST_CONTEXT != 0
  6348. void *
  6349. wasm_runtime_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
  6350. void *ctx))
  6351. {
  6352. return wasm_native_create_context_key(dtor);
  6353. }
  6354. void
  6355. wasm_runtime_destroy_context_key(void *key)
  6356. {
  6357. wasm_native_destroy_context_key(key);
  6358. }
  6359. void
  6360. wasm_runtime_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx)
  6361. {
  6362. wasm_native_set_context(inst, key, ctx);
  6363. }
  6364. void
  6365. wasm_runtime_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
  6366. void *ctx)
  6367. {
  6368. wasm_native_set_context_spread(inst, key, ctx);
  6369. }
  6370. void *
  6371. wasm_runtime_get_context(WASMModuleInstanceCommon *inst, void *key)
  6372. {
  6373. return wasm_native_get_context(inst, key);
  6374. }
  6375. #endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */
  6376. #if WASM_ENABLE_LINUX_PERF != 0
  6377. static bool enable_linux_perf = false;
  6378. bool
  6379. wasm_runtime_get_linux_perf(void)
  6380. {
  6381. return enable_linux_perf;
  6382. }
  6383. void
  6384. wasm_runtime_set_linux_perf(bool flag)
  6385. {
  6386. enable_linux_perf = flag;
  6387. }
  6388. #endif
  6389. bool
  6390. wasm_runtime_set_module_name(wasm_module_t module, const char *name,
  6391. char *error_buf, uint32_t error_buf_size)
  6392. {
  6393. if (!module)
  6394. return false;
  6395. #if WASM_ENABLE_INTERP != 0
  6396. if (module->module_type == Wasm_Module_Bytecode)
  6397. return wasm_set_module_name((WASMModule *)module, name, error_buf,
  6398. error_buf_size);
  6399. #endif
  6400. #if WASM_ENABLE_AOT != 0
  6401. if (module->module_type == Wasm_Module_AoT)
  6402. return aot_set_module_name((AOTModule *)module, name, error_buf,
  6403. error_buf_size);
  6404. #endif
  6405. return false;
  6406. }
  6407. const char *
  6408. wasm_runtime_get_module_name(wasm_module_t module)
  6409. {
  6410. if (!module)
  6411. return "";
  6412. #if WASM_ENABLE_INTERP != 0
  6413. if (module->module_type == Wasm_Module_Bytecode)
  6414. return wasm_get_module_name((WASMModule *)module);
  6415. #endif
  6416. #if WASM_ENABLE_AOT != 0
  6417. if (module->module_type == Wasm_Module_AoT)
  6418. return aot_get_module_name((AOTModule *)module);
  6419. #endif
  6420. return "";
  6421. }
  6422. /*
  6423. * wasm_runtime_detect_native_stack_overflow
  6424. *
  6425. * - raise "native stack overflow" exception if available native stack
  6426. * at this point is less than WASM_STACK_GUARD_SIZE. in that case,
  6427. * return false.
  6428. *
  6429. * - update native_stack_top_min.
  6430. */
  6431. bool
  6432. wasm_runtime_detect_native_stack_overflow(WASMExecEnv *exec_env)
  6433. {
  6434. uint8 *boundary = exec_env->native_stack_boundary;
  6435. RECORD_STACK_USAGE(exec_env, (uint8 *)&boundary);
  6436. if (boundary == NULL) {
  6437. /* the platform doesn't support os_thread_get_stack_boundary */
  6438. return true;
  6439. }
  6440. #if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
  6441. uint32 page_size = os_getpagesize();
  6442. uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
  6443. boundary = boundary + page_size * guard_page_count;
  6444. #endif
  6445. if ((uint8 *)&boundary < boundary) {
  6446. wasm_runtime_set_exception(wasm_runtime_get_module_inst(exec_env),
  6447. "native stack overflow");
  6448. return false;
  6449. }
  6450. return true;
  6451. }
  6452. bool
  6453. wasm_runtime_detect_native_stack_overflow_size(WASMExecEnv *exec_env,
  6454. uint32 requested_size)
  6455. {
  6456. uint8 *boundary = exec_env->native_stack_boundary;
  6457. RECORD_STACK_USAGE(exec_env, (uint8 *)&boundary);
  6458. if (boundary == NULL) {
  6459. /* the platform doesn't support os_thread_get_stack_boundary */
  6460. return true;
  6461. }
  6462. #if defined(OS_ENABLE_HW_BOUND_CHECK) && WASM_DISABLE_STACK_HW_BOUND_CHECK == 0
  6463. uint32 page_size = os_getpagesize();
  6464. uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
  6465. boundary = boundary + page_size * guard_page_count;
  6466. #endif
  6467. /* adjust the boundary for the requested size */
  6468. boundary = boundary - WASM_STACK_GUARD_SIZE + requested_size;
  6469. if ((uint8 *)&boundary < boundary) {
  6470. wasm_runtime_set_exception(wasm_runtime_get_module_inst(exec_env),
  6471. "native stack overflow");
  6472. return false;
  6473. }
  6474. return true;
  6475. }