wasm_runtime_common.c 159 KB

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