wasm_runtime_common.c 256 KB

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