wasm_runtime_common.c 179 KB

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