wasm_runtime_common.c 247 KB

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