wasm_runtime_common.c 198 KB

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