wasm_runtime_common.c 129 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "bh_platform.h"
  6. #include "bh_common.h"
  7. #include "bh_assert.h"
  8. #include "bh_log.h"
  9. #include "wasm_runtime_common.h"
  10. #include "wasm_memory.h"
  11. #if WASM_ENABLE_INTERP != 0
  12. #include "../interpreter/wasm_runtime.h"
  13. #endif
  14. #if WASM_ENABLE_AOT != 0
  15. #include "../aot/aot_runtime.h"
  16. #endif
  17. #if WASM_ENABLE_THREAD_MGR != 0
  18. #include "../libraries/thread-mgr/thread_manager.h"
  19. #endif
  20. #if WASM_ENABLE_SHARED_MEMORY != 0
  21. #include "wasm_shared_memory.h"
  22. #endif
  23. #include "../common/wasm_c_api_internal.h"
  24. #if WASM_ENABLE_MULTI_MODULE != 0
  25. /*
  26. * a safety insurance to prevent
  27. * circular depencies leading a stack overflow
  28. * try break early
  29. */
  30. typedef struct LoadingModule {
  31. bh_list_link l;
  32. /* point to a string pool */
  33. const char *module_name;
  34. } LoadingModule;
  35. static bh_list loading_module_list_head;
  36. static bh_list *const loading_module_list = &loading_module_list_head;
  37. static korp_mutex loading_module_list_lock;
  38. /*
  39. * a list about all exported functions, globals, memories, tables of every
  40. * fully loaded module
  41. */
  42. static bh_list registered_module_list_head;
  43. static bh_list *const registered_module_list = &registered_module_list_head;
  44. static korp_mutex registered_module_list_lock;
  45. static void
  46. wasm_runtime_destroy_registered_module_list();
  47. #endif /* WASM_ENABLE_MULTI_MODULE */
  48. #if WASM_ENABLE_REF_TYPES != 0
  49. /* Initialize externref hashmap */
  50. static bool
  51. wasm_externref_map_init();
  52. /* Destroy externref hashmap */
  53. static void
  54. wasm_externref_map_destroy();
  55. #endif /* WASM_ENABLE_REF_TYPES */
  56. static void
  57. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  58. {
  59. if (error_buf != NULL)
  60. snprintf(error_buf, error_buf_size, "%s", string);
  61. }
  62. static void *
  63. runtime_malloc(uint64 size, WASMModuleInstanceCommon *module_inst,
  64. char *error_buf, uint32 error_buf_size)
  65. {
  66. void *mem;
  67. if (size >= UINT32_MAX
  68. || !(mem = wasm_runtime_malloc((uint32)size))) {
  69. if (module_inst != NULL) {
  70. wasm_runtime_set_exception(module_inst,
  71. "allocate memory failed");
  72. }
  73. else if (error_buf != NULL) {
  74. set_error_buf(error_buf, error_buf_size,
  75. "allocate memory failed");
  76. }
  77. return NULL;
  78. }
  79. memset(mem, 0, (uint32)size);
  80. return mem;
  81. }
  82. static bool
  83. wasm_runtime_env_init()
  84. {
  85. if (bh_platform_init() != 0)
  86. return false;
  87. if (wasm_native_init() == false) {
  88. goto fail1;
  89. }
  90. #if WASM_ENABLE_MULTI_MODULE
  91. if (BHT_OK != os_mutex_init(&registered_module_list_lock)) {
  92. goto fail2;
  93. }
  94. if (BHT_OK != os_mutex_init(&loading_module_list_lock)) {
  95. goto fail3;
  96. }
  97. #endif
  98. #if WASM_ENABLE_SHARED_MEMORY
  99. if (!wasm_shared_memory_init()) {
  100. goto fail4;
  101. }
  102. #endif
  103. #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_THREAD_MGR != 0)
  104. if (!thread_manager_init()) {
  105. goto fail5;
  106. }
  107. #endif
  108. #if WASM_ENABLE_AOT != 0
  109. #ifdef OS_ENABLE_HW_BOUND_CHECK
  110. if (!aot_signal_init()) {
  111. goto fail6;
  112. }
  113. #endif
  114. #endif
  115. #if WASM_ENABLE_REF_TYPES != 0
  116. if (!wasm_externref_map_init()) {
  117. goto fail7;
  118. }
  119. #endif
  120. return true;
  121. #if WASM_ENABLE_REF_TYPES != 0
  122. fail7:
  123. #endif
  124. #if WASM_ENABLE_AOT != 0
  125. #ifdef OS_ENABLE_HW_BOUND_CHECK
  126. aot_signal_destroy();
  127. fail6:
  128. #endif
  129. #endif
  130. #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_THREAD_MGR != 0)
  131. thread_manager_destroy();
  132. fail5:
  133. #endif
  134. #if WASM_ENABLE_SHARED_MEMORY
  135. wasm_shared_memory_destroy();
  136. fail4:
  137. #endif
  138. #if WASM_ENABLE_MULTI_MODULE
  139. os_mutex_destroy(&loading_module_list_lock);
  140. fail3:
  141. os_mutex_destroy(&registered_module_list_lock);
  142. fail2:
  143. #endif
  144. wasm_native_destroy();
  145. fail1:
  146. bh_platform_destroy();
  147. return false;
  148. }
  149. static bool
  150. wasm_runtime_exec_env_check(WASMExecEnv *exec_env)
  151. {
  152. return exec_env
  153. && exec_env->module_inst
  154. && exec_env->wasm_stack_size > 0
  155. && exec_env->wasm_stack.s.top_boundary ==
  156. exec_env->wasm_stack.s.bottom + exec_env->wasm_stack_size
  157. && exec_env->wasm_stack.s.top <= exec_env->wasm_stack.s.top_boundary;
  158. }
  159. bool
  160. wasm_runtime_init()
  161. {
  162. if (!wasm_runtime_memory_init(Alloc_With_System_Allocator, NULL))
  163. return false;
  164. if (!wasm_runtime_env_init()) {
  165. wasm_runtime_memory_destroy();
  166. return false;
  167. }
  168. return true;
  169. }
  170. void
  171. wasm_runtime_destroy()
  172. {
  173. #if WASM_ENABLE_REF_TYPES != 0
  174. wasm_externref_map_destroy();
  175. #endif
  176. #if WASM_ENABLE_AOT != 0
  177. #ifdef OS_ENABLE_HW_BOUND_CHECK
  178. aot_signal_destroy();
  179. #endif
  180. #endif
  181. /* runtime env destroy */
  182. #if WASM_ENABLE_MULTI_MODULE
  183. wasm_runtime_destroy_loading_module_list();
  184. os_mutex_destroy(&loading_module_list_lock);
  185. wasm_runtime_destroy_registered_module_list();
  186. os_mutex_destroy(&registered_module_list_lock);
  187. #endif
  188. #if WASM_ENABLE_SHARED_MEMORY
  189. wasm_shared_memory_destroy();
  190. #endif
  191. #if (WASM_ENABLE_WAMR_COMPILER == 0) && (WASM_ENABLE_THREAD_MGR != 0)
  192. thread_manager_destroy();
  193. #endif
  194. wasm_native_destroy();
  195. bh_platform_destroy();
  196. wasm_runtime_memory_destroy();
  197. }
  198. bool
  199. wasm_runtime_full_init(RuntimeInitArgs *init_args)
  200. {
  201. if (!wasm_runtime_memory_init(init_args->mem_alloc_type,
  202. &init_args->mem_alloc_option))
  203. return false;
  204. if (!wasm_runtime_env_init()) {
  205. wasm_runtime_memory_destroy();
  206. return false;
  207. }
  208. if (init_args->n_native_symbols > 0
  209. && !wasm_runtime_register_natives(init_args->native_module_name,
  210. init_args->native_symbols,
  211. init_args->n_native_symbols)) {
  212. wasm_runtime_destroy();
  213. return false;
  214. }
  215. #if WASM_ENABLE_THREAD_MGR != 0
  216. wasm_cluster_set_max_thread_num(init_args->max_thread_num);
  217. #endif
  218. return true;
  219. }
  220. PackageType
  221. get_package_type(const uint8 *buf, uint32 size)
  222. {
  223. if (buf && size >= 4) {
  224. if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 's' && buf[3] == 'm')
  225. return Wasm_Module_Bytecode;
  226. if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 'o' && buf[3] == 't')
  227. return Wasm_Module_AoT;
  228. }
  229. return Package_Type_Unknown;
  230. }
  231. #if WASM_ENABLE_MULTI_MODULE != 0
  232. static module_reader reader;
  233. static module_destroyer destroyer;
  234. void
  235. wasm_runtime_set_module_reader(const module_reader reader_cb,
  236. const module_destroyer destroyer_cb)
  237. {
  238. reader = reader_cb;
  239. destroyer = destroyer_cb;
  240. }
  241. module_reader
  242. wasm_runtime_get_module_reader()
  243. {
  244. return reader;
  245. }
  246. module_destroyer
  247. wasm_runtime_get_module_destroyer()
  248. {
  249. return destroyer;
  250. }
  251. static WASMRegisteredModule *
  252. wasm_runtime_find_module_registered_by_reference(WASMModuleCommon *module)
  253. {
  254. WASMRegisteredModule *reg_module = NULL;
  255. os_mutex_lock(&registered_module_list_lock);
  256. reg_module = bh_list_first_elem(registered_module_list);
  257. while (reg_module && module != reg_module->module) {
  258. reg_module = bh_list_elem_next(reg_module);
  259. }
  260. os_mutex_unlock(&registered_module_list_lock);
  261. return reg_module;
  262. }
  263. bool
  264. wasm_runtime_register_module_internal(const char *module_name,
  265. WASMModuleCommon *module,
  266. uint8 *orig_file_buf,
  267. uint32 orig_file_buf_size,
  268. char *error_buf,
  269. uint32_t error_buf_size)
  270. {
  271. WASMRegisteredModule *node = NULL;
  272. node = wasm_runtime_find_module_registered_by_reference(module);
  273. if (node) { /* module has been registered */
  274. if (node->module_name) { /* module has name */
  275. if (!module_name || strcmp(node->module_name, module_name)) {
  276. /* module has different name */
  277. LOG_DEBUG("module(%p) has been registered with name %s",
  278. module, node->module_name);
  279. set_error_buf(error_buf, error_buf_size,
  280. "Register module failed: "
  281. "failed to rename the module");
  282. return false;
  283. }
  284. else {
  285. /* module has the same name */
  286. LOG_DEBUG("module(%p) has been registered with the same name %s",
  287. module, node->module_name);
  288. return true;
  289. }
  290. }
  291. else {
  292. /* module has empyt name, reset it */
  293. node->module_name = module_name;
  294. return true;
  295. }
  296. }
  297. /* module hasn't been registered */
  298. node = runtime_malloc(sizeof(WASMRegisteredModule), NULL, NULL, 0);
  299. if (!node) {
  300. LOG_DEBUG("malloc WASMRegisteredModule failed. SZ=%d",
  301. sizeof(WASMRegisteredModule));
  302. return false;
  303. }
  304. /* share the string and the module */
  305. node->module_name = module_name;
  306. node->module = module;
  307. node->orig_file_buf = orig_file_buf;
  308. node->orig_file_buf_size = orig_file_buf_size;
  309. os_mutex_lock(&registered_module_list_lock);
  310. bh_list_status ret = bh_list_insert(registered_module_list, node);
  311. bh_assert(BH_LIST_SUCCESS == ret);
  312. (void)ret;
  313. os_mutex_unlock(&registered_module_list_lock);
  314. return true;
  315. }
  316. bool
  317. wasm_runtime_register_module(const char *module_name, WASMModuleCommon *module,
  318. char *error_buf, uint32_t error_buf_size)
  319. {
  320. if (!error_buf || !error_buf_size) {
  321. LOG_ERROR("error buffer is required");
  322. return false;
  323. }
  324. if (!module_name || !module) {
  325. LOG_DEBUG("module_name and module are required");
  326. set_error_buf(error_buf, error_buf_size,
  327. "Register module failed: "
  328. "module_name and module are required");
  329. return false;
  330. }
  331. if (wasm_runtime_is_built_in_module(module_name)) {
  332. LOG_DEBUG("%s is a built-in module name", module_name);
  333. set_error_buf(error_buf, error_buf_size,
  334. "Register module failed: "
  335. "can not register as a built-in module");
  336. return false;
  337. }
  338. return wasm_runtime_register_module_internal(
  339. module_name, module, NULL, 0,
  340. error_buf, error_buf_size);
  341. }
  342. void
  343. wasm_runtime_unregister_module(const WASMModuleCommon *module)
  344. {
  345. WASMRegisteredModule *registered_module = NULL;
  346. os_mutex_lock(&registered_module_list_lock);
  347. registered_module = bh_list_first_elem(registered_module_list);
  348. while (registered_module && module != registered_module->module) {
  349. registered_module = bh_list_elem_next(registered_module);
  350. }
  351. /* it does not matter if it is not exist. after all, it is gone */
  352. if (registered_module) {
  353. bh_list_remove(registered_module_list, registered_module);
  354. wasm_runtime_free(registered_module);
  355. }
  356. os_mutex_unlock(&registered_module_list_lock);
  357. }
  358. WASMModuleCommon *
  359. wasm_runtime_find_module_registered(const char *module_name)
  360. {
  361. WASMRegisteredModule *module = NULL, *module_next;
  362. os_mutex_lock(&registered_module_list_lock);
  363. module = bh_list_first_elem(registered_module_list);
  364. while (module) {
  365. module_next = bh_list_elem_next(module);
  366. if (module->module_name
  367. && !strcmp(module_name, module->module_name)) {
  368. break;
  369. }
  370. module = module_next;
  371. }
  372. os_mutex_unlock(&registered_module_list_lock);
  373. return module ? module->module : NULL;
  374. }
  375. bool
  376. wasm_runtime_is_module_registered(const char *module_name)
  377. {
  378. return NULL != wasm_runtime_find_module_registered(module_name);
  379. }
  380. /*
  381. * simply destroy all
  382. */
  383. static void
  384. wasm_runtime_destroy_registered_module_list()
  385. {
  386. WASMRegisteredModule *reg_module = NULL;
  387. os_mutex_lock(&registered_module_list_lock);
  388. reg_module = bh_list_first_elem(registered_module_list);
  389. while (reg_module) {
  390. WASMRegisteredModule *next_reg_module = bh_list_elem_next(reg_module);
  391. bh_list_remove(registered_module_list, reg_module);
  392. /* now, it is time to release every module in the runtime */
  393. if (reg_module->module->module_type == Wasm_Module_Bytecode) {
  394. #if WASM_ENABLE_INTERP != 0
  395. wasm_unload((WASMModule *)reg_module->module);
  396. #endif
  397. }
  398. else {
  399. #if WASM_ENABLE_AOT != 0
  400. aot_unload((AOTModule *)reg_module->module);
  401. #endif
  402. }
  403. /* destroy the file buffer */
  404. if (destroyer && reg_module->orig_file_buf) {
  405. destroyer(reg_module->orig_file_buf,
  406. reg_module->orig_file_buf_size);
  407. reg_module->orig_file_buf = NULL;
  408. reg_module->orig_file_buf_size = 0;
  409. }
  410. wasm_runtime_free(reg_module);
  411. reg_module = next_reg_module;
  412. }
  413. os_mutex_unlock(&registered_module_list_lock);
  414. }
  415. bool
  416. wasm_runtime_add_loading_module(const char *module_name,
  417. char *error_buf, uint32 error_buf_size)
  418. {
  419. LOG_DEBUG("add %s into a loading list", module_name);
  420. LoadingModule *loadingModule =
  421. runtime_malloc(sizeof(LoadingModule), NULL,
  422. error_buf, error_buf_size);
  423. if (!loadingModule) {
  424. return false;
  425. }
  426. /* share the incoming string */
  427. loadingModule->module_name = module_name;
  428. os_mutex_lock(&loading_module_list_lock);
  429. bh_list_status ret = bh_list_insert(loading_module_list, loadingModule);
  430. bh_assert(BH_LIST_SUCCESS == ret);
  431. (void)ret;
  432. os_mutex_unlock(&loading_module_list_lock);
  433. return true;
  434. }
  435. void
  436. wasm_runtime_delete_loading_module(const char *module_name)
  437. {
  438. LOG_DEBUG("delete %s from a loading list", module_name);
  439. LoadingModule *module = NULL;
  440. os_mutex_lock(&loading_module_list_lock);
  441. module = bh_list_first_elem(loading_module_list);
  442. while (module && strcmp(module->module_name, module_name)) {
  443. module = bh_list_elem_next(module);
  444. }
  445. /* it does not matter if it is not exist. after all, it is gone */
  446. if (module) {
  447. bh_list_remove(loading_module_list, module);
  448. wasm_runtime_free(module);
  449. }
  450. os_mutex_unlock(&loading_module_list_lock);
  451. }
  452. bool
  453. wasm_runtime_is_loading_module(const char *module_name)
  454. {
  455. LOG_DEBUG("find %s in a loading list", module_name);
  456. LoadingModule *module = NULL;
  457. os_mutex_lock(&loading_module_list_lock);
  458. module = bh_list_first_elem(loading_module_list);
  459. while (module && strcmp(module_name, module->module_name)) {
  460. module = bh_list_elem_next(module);
  461. }
  462. os_mutex_unlock(&loading_module_list_lock);
  463. return module != NULL;
  464. }
  465. void
  466. wasm_runtime_destroy_loading_module_list()
  467. {
  468. LoadingModule *module = NULL;
  469. os_mutex_lock(&loading_module_list_lock);
  470. module = bh_list_first_elem(loading_module_list);
  471. while (module) {
  472. LoadingModule *next_module = bh_list_elem_next(module);
  473. bh_list_remove(loading_module_list, module);
  474. /*
  475. * will not free the module_name since it is
  476. * shared one of the const string pool
  477. */
  478. wasm_runtime_free(module);
  479. module = next_module;
  480. }
  481. os_mutex_unlock(&loading_module_list_lock);
  482. }
  483. #endif /* WASM_ENABLE_MULTI_MODULE */
  484. bool
  485. wasm_runtime_is_built_in_module(const char *module_name)
  486. {
  487. return (!strcmp("env", module_name)
  488. || !strcmp("wasi_unstable", module_name)
  489. || !strcmp("wasi_snapshot_preview1", module_name)
  490. #if WASM_ENABLE_SPEC_TEST != 0
  491. || !strcmp("spectest", module_name)
  492. #endif
  493. || !strcmp("", module_name));
  494. }
  495. #if WASM_ENABLE_THREAD_MGR != 0
  496. bool
  497. wasm_exec_env_set_aux_stack(WASMExecEnv *exec_env,
  498. uint32 start_offset, uint32 size)
  499. {
  500. WASMModuleInstanceCommon *module_inst
  501. = wasm_exec_env_get_module_inst(exec_env);
  502. #if WASM_ENABLE_INTERP != 0
  503. if (module_inst->module_type == Wasm_Module_Bytecode) {
  504. return wasm_set_aux_stack(exec_env, start_offset, size);
  505. }
  506. #endif
  507. #if WASM_ENABLE_AOT != 0
  508. if (module_inst->module_type == Wasm_Module_AoT) {
  509. return aot_set_aux_stack(exec_env, start_offset, size);
  510. }
  511. #endif
  512. return false;
  513. }
  514. bool
  515. wasm_exec_env_get_aux_stack(WASMExecEnv *exec_env,
  516. uint32 *start_offset, uint32 *size)
  517. {
  518. WASMModuleInstanceCommon *module_inst
  519. = wasm_exec_env_get_module_inst(exec_env);
  520. #if WASM_ENABLE_INTERP != 0
  521. if (module_inst->module_type == Wasm_Module_Bytecode) {
  522. return wasm_get_aux_stack(exec_env, start_offset, size);
  523. }
  524. #endif
  525. #if WASM_ENABLE_AOT != 0
  526. if (module_inst->module_type == Wasm_Module_AoT) {
  527. return aot_get_aux_stack(exec_env, start_offset, size);
  528. }
  529. #endif
  530. return false;
  531. }
  532. void
  533. wasm_runtime_set_max_thread_num(uint32 num)
  534. {
  535. wasm_cluster_set_max_thread_num(num);
  536. }
  537. #endif /* end of WASM_ENABLE_THREAD_MGR */
  538. static WASMModuleCommon *
  539. register_module_with_null_name(WASMModuleCommon *module_common,
  540. char *error_buf, uint32 error_buf_size)
  541. {
  542. #if WASM_ENABLE_MULTI_MODULE != 0
  543. if (module_common) {
  544. if (!wasm_runtime_register_module_internal(NULL, module_common,
  545. NULL, 0,
  546. error_buf,
  547. error_buf_size)) {
  548. wasm_runtime_unload(module_common);
  549. return NULL;
  550. }
  551. return module_common;
  552. }
  553. else
  554. return NULL;
  555. #else
  556. return module_common;
  557. #endif
  558. }
  559. WASMModuleCommon *
  560. wasm_runtime_load(const uint8 *buf, uint32 size,
  561. char *error_buf, uint32 error_buf_size)
  562. {
  563. WASMModuleCommon *module_common = NULL;
  564. if (get_package_type(buf, size) == Wasm_Module_Bytecode) {
  565. #if WASM_ENABLE_AOT != 0 && WASM_ENABLE_JIT != 0
  566. AOTModule *aot_module;
  567. WASMModule *module = wasm_load(buf, size, error_buf, error_buf_size);
  568. if (!module)
  569. return NULL;
  570. if (!(aot_module = aot_convert_wasm_module(module,
  571. error_buf, error_buf_size))) {
  572. wasm_unload(module);
  573. return NULL;
  574. }
  575. module_common = (WASMModuleCommon*)aot_module;
  576. return register_module_with_null_name(module_common,
  577. error_buf, error_buf_size);
  578. #elif WASM_ENABLE_INTERP != 0
  579. module_common = (WASMModuleCommon*)
  580. wasm_load(buf, size, error_buf, error_buf_size);
  581. return register_module_with_null_name(module_common,
  582. error_buf, error_buf_size);
  583. #endif
  584. }
  585. else if (get_package_type(buf, size) == Wasm_Module_AoT) {
  586. #if WASM_ENABLE_AOT != 0
  587. module_common = (WASMModuleCommon*)
  588. aot_load_from_aot_file(buf, size, error_buf, error_buf_size);
  589. return register_module_with_null_name(module_common,
  590. error_buf, error_buf_size);
  591. #endif
  592. }
  593. if (size < 4)
  594. set_error_buf(error_buf, error_buf_size,
  595. "WASM module load failed: unexpected end");
  596. else
  597. set_error_buf(error_buf, error_buf_size,
  598. "WASM module load failed: magic header not detected");
  599. return NULL;
  600. }
  601. WASMModuleCommon *
  602. wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
  603. char *error_buf, uint32_t error_buf_size)
  604. {
  605. WASMModuleCommon *module_common;
  606. #if WASM_ENABLE_INTERP != 0
  607. if (!is_aot) {
  608. module_common = (WASMModuleCommon*)
  609. wasm_load_from_sections(section_list,
  610. error_buf, error_buf_size);
  611. return register_module_with_null_name(module_common,
  612. error_buf, error_buf_size);
  613. }
  614. #endif
  615. #if WASM_ENABLE_AOT != 0
  616. if (is_aot) {
  617. module_common = (WASMModuleCommon*)
  618. aot_load_from_sections(section_list,
  619. error_buf, error_buf_size);
  620. return register_module_with_null_name(module_common,
  621. error_buf, error_buf_size);
  622. }
  623. #endif
  624. set_error_buf(error_buf, error_buf_size,
  625. "WASM module load failed: invalid section list type");
  626. return NULL;
  627. }
  628. void
  629. wasm_runtime_unload(WASMModuleCommon *module)
  630. {
  631. #if WASM_ENABLE_MULTI_MODULE != 0
  632. /**
  633. * since we will unload and free all module when runtime_destroy()
  634. * we don't want users to unwillingly disrupt it
  635. */
  636. return;
  637. #endif
  638. #if WASM_ENABLE_INTERP != 0
  639. if (module->module_type == Wasm_Module_Bytecode) {
  640. wasm_unload((WASMModule*)module);
  641. return;
  642. }
  643. #endif
  644. #if WASM_ENABLE_AOT != 0
  645. if (module->module_type == Wasm_Module_AoT) {
  646. aot_unload((AOTModule*)module);
  647. return;
  648. }
  649. #endif
  650. }
  651. WASMModuleInstanceCommon *
  652. wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
  653. uint32 stack_size, uint32 heap_size,
  654. char *error_buf, uint32 error_buf_size)
  655. {
  656. #if WASM_ENABLE_INTERP != 0
  657. if (module->module_type == Wasm_Module_Bytecode)
  658. return (WASMModuleInstanceCommon*)
  659. wasm_instantiate((WASMModule*)module, is_sub_inst,
  660. stack_size, heap_size,
  661. error_buf, error_buf_size);
  662. #endif
  663. #if WASM_ENABLE_AOT != 0
  664. if (module->module_type == Wasm_Module_AoT)
  665. return (WASMModuleInstanceCommon*)
  666. aot_instantiate((AOTModule*)module, is_sub_inst,
  667. stack_size, heap_size,
  668. error_buf, error_buf_size);
  669. #endif
  670. set_error_buf(error_buf, error_buf_size,
  671. "Instantiate module failed, invalid module type");
  672. return NULL;
  673. }
  674. WASMModuleInstanceCommon *
  675. wasm_runtime_instantiate(WASMModuleCommon *module,
  676. uint32 stack_size, uint32 heap_size,
  677. char *error_buf, uint32 error_buf_size)
  678. {
  679. return wasm_runtime_instantiate_internal(module, false,
  680. stack_size, heap_size,
  681. error_buf, error_buf_size);
  682. }
  683. void
  684. wasm_runtime_deinstantiate_internal(WASMModuleInstanceCommon *module_inst,
  685. bool is_sub_inst)
  686. {
  687. #if WASM_ENABLE_INTERP != 0
  688. if (module_inst->module_type == Wasm_Module_Bytecode) {
  689. wasm_deinstantiate((WASMModuleInstance*)module_inst, is_sub_inst);
  690. return;
  691. }
  692. #endif
  693. #if WASM_ENABLE_AOT != 0
  694. if (module_inst->module_type == Wasm_Module_AoT) {
  695. aot_deinstantiate((AOTModuleInstance*)module_inst, is_sub_inst);
  696. return;
  697. }
  698. #endif
  699. }
  700. void
  701. wasm_runtime_deinstantiate(WASMModuleInstanceCommon *module_inst)
  702. {
  703. wasm_runtime_deinstantiate_internal(module_inst, false);
  704. }
  705. WASMExecEnv *
  706. wasm_runtime_create_exec_env(WASMModuleInstanceCommon *module_inst,
  707. uint32 stack_size)
  708. {
  709. return wasm_exec_env_create(module_inst, stack_size);
  710. }
  711. void
  712. wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env)
  713. {
  714. wasm_exec_env_destroy(exec_env);
  715. }
  716. bool
  717. wasm_runtime_init_thread_env()
  718. {
  719. #if WASM_ENABLE_AOT != 0
  720. #ifdef OS_ENABLE_HW_BOUND_CHECK
  721. return aot_signal_init();
  722. #endif
  723. #endif
  724. return true;
  725. }
  726. void
  727. wasm_runtime_destroy_thread_env()
  728. {
  729. #if WASM_ENABLE_AOT != 0
  730. #ifdef OS_ENABLE_HW_BOUND_CHECK
  731. aot_signal_destroy();
  732. #endif
  733. #endif
  734. }
  735. #if (WASM_ENABLE_MEMORY_PROFILING != 0) || (WASM_ENABLE_MEMORY_TRACING != 0)
  736. void
  737. wasm_runtime_dump_module_mem_consumption(const WASMModuleCommon *module)
  738. {
  739. WASMModuleMemConsumption mem_conspn = { 0 };
  740. #if WASM_ENABLE_INTERP != 0
  741. if (module->module_type == Wasm_Module_Bytecode) {
  742. wasm_get_module_mem_consumption((WASMModule*)module, &mem_conspn);
  743. }
  744. #endif
  745. #if WASM_ENABLE_AOT != 0
  746. if (module->module_type == Wasm_Module_AoT) {
  747. aot_get_module_mem_consumption((AOTModule*)module, &mem_conspn);
  748. }
  749. #endif
  750. os_printf("WASM module memory consumption, total size: %u\n",
  751. mem_conspn.total_size);
  752. os_printf(" module struct size: %u\n", mem_conspn.module_struct_size);
  753. os_printf(" types size: %u\n", mem_conspn.types_size);
  754. os_printf(" imports size: %u\n", mem_conspn.imports_size);
  755. os_printf(" funcs size: %u\n", mem_conspn.functions_size);
  756. os_printf(" tables size: %u\n", mem_conspn.tables_size);
  757. os_printf(" memories size: %u\n", mem_conspn.memories_size);
  758. os_printf(" globals size: %u\n", mem_conspn.globals_size);
  759. os_printf(" exports size: %u\n", mem_conspn.exports_size);
  760. os_printf(" table segs size: %u\n", mem_conspn.table_segs_size);
  761. os_printf(" data segs size: %u\n", mem_conspn.data_segs_size);
  762. os_printf(" const strings size: %u\n", mem_conspn.const_strs_size);
  763. #if WASM_ENABLE_AOT != 0
  764. os_printf(" aot code size: %u\n", mem_conspn.aot_code_size);
  765. #endif
  766. }
  767. void
  768. wasm_runtime_dump_module_inst_mem_consumption(const WASMModuleInstanceCommon
  769. *module_inst)
  770. {
  771. WASMModuleInstMemConsumption mem_conspn = { 0 };
  772. #if WASM_ENABLE_INTERP != 0
  773. if (module_inst->module_type == Wasm_Module_Bytecode) {
  774. wasm_get_module_inst_mem_consumption((WASMModuleInstance*)module_inst,
  775. &mem_conspn);
  776. }
  777. #endif
  778. #if WASM_ENABLE_AOT != 0
  779. if (module_inst->module_type == Wasm_Module_AoT) {
  780. aot_get_module_inst_mem_consumption((AOTModuleInstance*)module_inst,
  781. &mem_conspn);
  782. }
  783. #endif
  784. os_printf("WASM module inst memory consumption, total size: %u\n",
  785. mem_conspn.total_size);
  786. os_printf(" module inst struct size: %u\n",
  787. mem_conspn.module_inst_struct_size);
  788. os_printf(" memories size: %u\n", mem_conspn.memories_size);
  789. os_printf(" app heap size: %u\n", mem_conspn.app_heap_size);
  790. os_printf(" tables size: %u\n", mem_conspn.tables_size);
  791. os_printf(" functions size: %u\n", mem_conspn.functions_size);
  792. os_printf(" globals size: %u\n", mem_conspn.globals_size);
  793. os_printf(" exports size: %u\n", mem_conspn.exports_size);
  794. }
  795. void
  796. wasm_runtime_dump_exec_env_mem_consumption(const WASMExecEnv *exec_env)
  797. {
  798. uint32 total_size = offsetof(WASMExecEnv, wasm_stack.s.bottom)
  799. + exec_env->wasm_stack_size;
  800. os_printf("Exec env memory consumption, total size: %u\n", total_size);
  801. os_printf(" exec env struct size: %u\n",
  802. offsetof(WASMExecEnv, wasm_stack.s.bottom));
  803. #if WASM_ENABLE_INTERP != 0 && WASM_ENABLE_FAST_INTERP == 0
  804. os_printf(" block addr cache size: %u\n",
  805. sizeof(exec_env->block_addr_cache));
  806. #endif
  807. os_printf(" stack size: %u\n", exec_env->wasm_stack_size);
  808. }
  809. uint32
  810. gc_get_heap_highmark_size(void *heap);
  811. void
  812. wasm_runtime_dump_mem_consumption(WASMExecEnv *exec_env)
  813. {
  814. WASMModuleInstMemConsumption module_inst_mem_consps;
  815. WASMModuleMemConsumption module_mem_consps;
  816. WASMModuleInstanceCommon *module_inst_common;
  817. WASMModuleCommon *module_common = NULL;
  818. void *heap_handle = NULL;
  819. uint32 total_size = 0, app_heap_peak_size = 0;
  820. uint32 max_aux_stack_used = -1;
  821. module_inst_common = exec_env->module_inst;
  822. #if WASM_ENABLE_INTERP != 0
  823. if (module_inst_common->module_type == Wasm_Module_Bytecode) {
  824. WASMModuleInstance *wasm_module_inst =
  825. (WASMModuleInstance*)module_inst_common;
  826. WASMModule *wasm_module = wasm_module_inst->module;
  827. module_common = (WASMModuleCommon*)wasm_module;
  828. if (wasm_module_inst->memories) {
  829. heap_handle = wasm_module_inst->memories[0]->heap_handle;
  830. }
  831. wasm_get_module_inst_mem_consumption
  832. (wasm_module_inst, &module_inst_mem_consps);
  833. wasm_get_module_mem_consumption
  834. (wasm_module, &module_mem_consps);
  835. if (wasm_module_inst->module->aux_stack_top_global_index != (uint32)-1)
  836. max_aux_stack_used = wasm_module_inst->max_aux_stack_used;
  837. }
  838. #endif
  839. #if WASM_ENABLE_AOT != 0
  840. if (module_inst_common->module_type == Wasm_Module_AoT) {
  841. AOTModuleInstance *aot_module_inst =
  842. (AOTModuleInstance*)module_inst_common;
  843. AOTModule *aot_module =
  844. (AOTModule*)aot_module_inst->aot_module.ptr;
  845. module_common = (WASMModuleCommon*)aot_module;
  846. if (aot_module_inst->memories.ptr) {
  847. AOTMemoryInstance **memories =
  848. (AOTMemoryInstance **)aot_module_inst->memories.ptr;
  849. heap_handle = memories[0]->heap_handle.ptr;
  850. }
  851. aot_get_module_inst_mem_consumption
  852. (aot_module_inst, &module_inst_mem_consps);
  853. aot_get_module_mem_consumption
  854. (aot_module, &module_mem_consps);
  855. }
  856. #endif
  857. bh_assert(module_common != NULL);
  858. if (heap_handle) {
  859. app_heap_peak_size = gc_get_heap_highmark_size(heap_handle);
  860. }
  861. total_size = offsetof(WASMExecEnv, wasm_stack.s.bottom)
  862. + exec_env->wasm_stack_size
  863. + module_mem_consps.total_size
  864. + module_inst_mem_consps.total_size;
  865. os_printf("\nMemory consumption summary (bytes):\n");
  866. wasm_runtime_dump_module_mem_consumption(module_common);
  867. wasm_runtime_dump_module_inst_mem_consumption(module_inst_common);
  868. wasm_runtime_dump_exec_env_mem_consumption(exec_env);
  869. os_printf("\nTotal memory consumption of module, module inst and "
  870. "exec env: %u\n", total_size);
  871. os_printf("Total interpreter stack used: %u\n",
  872. exec_env->max_wasm_stack_used);
  873. if (max_aux_stack_used != (uint32)-1)
  874. os_printf("Total auxiliary stack used: %u\n", max_aux_stack_used);
  875. else
  876. os_printf("Total aux stack used: no enough info to profile\n");
  877. os_printf("Total app heap used: %u\n", app_heap_peak_size);
  878. }
  879. #endif /* end of (WASM_ENABLE_MEMORY_PROFILING != 0)
  880. || (WASM_ENABLE_MEMORY_TRACING != 0) */
  881. #if WASM_ENABLE_PERF_PROFILING != 0
  882. void
  883. wasm_runtime_dump_perf_profiling(WASMModuleInstanceCommon *module_inst)
  884. {
  885. #if WASM_ENABLE_INTERP != 0
  886. if (module_inst->module_type == Wasm_Module_Bytecode) {
  887. wasm_dump_perf_profiling((WASMModuleInstance*)module_inst);
  888. }
  889. #endif
  890. #if WASM_ENABLE_AOT != 0
  891. if (module_inst->module_type == Wasm_Module_AoT) {
  892. aot_dump_perf_profiling((AOTModuleInstance*)module_inst);
  893. }
  894. #endif
  895. }
  896. #endif
  897. WASMModuleInstanceCommon *
  898. wasm_runtime_get_module_inst(WASMExecEnv *exec_env)
  899. {
  900. return wasm_exec_env_get_module_inst(exec_env);
  901. }
  902. void *
  903. wasm_runtime_get_function_attachment(WASMExecEnv *exec_env)
  904. {
  905. return exec_env->attachment;
  906. }
  907. void
  908. wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data)
  909. {
  910. exec_env->user_data = user_data;
  911. }
  912. void *
  913. wasm_runtime_get_user_data(WASMExecEnv *exec_env)
  914. {
  915. return exec_env->user_data;
  916. }
  917. WASMType *
  918. wasm_runtime_get_function_type(const WASMFunctionInstanceCommon *function,
  919. uint32 module_type)
  920. {
  921. WASMType *type = NULL;
  922. #if WASM_ENABLE_INTERP != 0
  923. if (module_type == Wasm_Module_Bytecode) {
  924. WASMFunctionInstance *wasm_func = (WASMFunctionInstance *)function;
  925. type = wasm_func->is_import_func
  926. ? wasm_func->u.func_import->func_type
  927. : wasm_func->u.func->func_type;
  928. }
  929. #endif
  930. #if WASM_ENABLE_AOT != 0
  931. if (module_type == Wasm_Module_AoT) {
  932. AOTFunctionInstance *aot_func = (AOTFunctionInstance *)function;
  933. type = aot_func->is_import_func
  934. ? aot_func->u.func_import->func_type
  935. : aot_func->u.func.func_type;
  936. }
  937. #endif
  938. return type;
  939. }
  940. WASMFunctionInstanceCommon *
  941. wasm_runtime_lookup_function(WASMModuleInstanceCommon * const module_inst,
  942. const char *name, const char *signature)
  943. {
  944. #if WASM_ENABLE_INTERP != 0
  945. if (module_inst->module_type == Wasm_Module_Bytecode)
  946. return (WASMFunctionInstanceCommon*)
  947. wasm_lookup_function((const WASMModuleInstance*)module_inst,
  948. name, signature);
  949. #endif
  950. #if WASM_ENABLE_AOT != 0
  951. if (module_inst->module_type == Wasm_Module_AoT)
  952. return (WASMFunctionInstanceCommon*)
  953. aot_lookup_function((const AOTModuleInstance*)module_inst,
  954. name, signature);
  955. #endif
  956. return NULL;
  957. }
  958. #if WASM_ENABLE_REF_TYPES != 0
  959. static void
  960. wasm_runtime_reclaim_externref(WASMExecEnv *exec_env,
  961. WASMFunctionInstanceCommon *function,
  962. uint32 *argv)
  963. {
  964. uint32 i = 0, cell_num = 0;
  965. WASMType *func_type = wasm_runtime_get_function_type(
  966. function, exec_env->module_inst->module_type);
  967. bh_assert(func_type);
  968. while (i < func_type->result_count) {
  969. uint8 result_type = func_type->types[func_type->param_count + i];
  970. if (result_type == VALUE_TYPE_EXTERNREF && argv[i] != NULL_REF) {
  971. /* Retain the externref returned to runtime embedder */
  972. (void)wasm_externref_retain(argv[i]);
  973. }
  974. cell_num += wasm_value_type_cell_num(result_type);
  975. i++;
  976. }
  977. wasm_externref_reclaim(exec_env->module_inst);
  978. }
  979. void
  980. wasm_runtime_prepare_call_function(WASMExecEnv *exec_env,
  981. WASMFunctionInstanceCommon *function)
  982. {
  983. exec_env->nested_calling_depth++;
  984. }
  985. void
  986. wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
  987. WASMFunctionInstanceCommon *function,
  988. bool ret, uint32 *argv)
  989. {
  990. exec_env->nested_calling_depth--;
  991. if (!exec_env->nested_calling_depth && ret) {
  992. wasm_runtime_reclaim_externref(exec_env, function, argv);
  993. }
  994. }
  995. #endif
  996. bool
  997. wasm_runtime_call_wasm(WASMExecEnv *exec_env,
  998. WASMFunctionInstanceCommon *function,
  999. uint32 argc, uint32 argv[])
  1000. {
  1001. bool ret = false;
  1002. if (!wasm_runtime_exec_env_check(exec_env)) {
  1003. LOG_ERROR("Invalid exec env stack info.");
  1004. return false;
  1005. }
  1006. #if WASM_ENABLE_REF_TYPES != 0
  1007. wasm_runtime_prepare_call_function(exec_env, function);
  1008. #endif
  1009. #if WASM_ENABLE_INTERP != 0
  1010. if (exec_env->module_inst->module_type == Wasm_Module_Bytecode)
  1011. ret = wasm_call_function(exec_env,
  1012. (WASMFunctionInstance*)function,
  1013. argc, argv);
  1014. #endif
  1015. #if WASM_ENABLE_AOT != 0
  1016. if (exec_env->module_inst->module_type == Wasm_Module_AoT)
  1017. ret = aot_call_function(exec_env,
  1018. (AOTFunctionInstance*)function,
  1019. argc, argv);
  1020. #endif
  1021. #if WASM_ENABLE_REF_TYPES != 0
  1022. wasm_runtime_finalize_call_function(exec_env, function, ret, argv);
  1023. #endif
  1024. return ret;
  1025. }
  1026. static uint32
  1027. parse_args_to_uint32_array(WASMType *type,
  1028. uint32 num_args, wasm_val_t *args,
  1029. uint32 *out_argv)
  1030. {
  1031. uint32 i, p;
  1032. for (i = 0, p = 0; i < num_args; i++) {
  1033. switch (args[i].kind) {
  1034. case WASM_I32:
  1035. out_argv[p++] = args[i].of.i32;
  1036. break;
  1037. case WASM_I64:
  1038. {
  1039. union { uint64 val; uint32 parts[2]; } u;
  1040. u.val = args[i].of.i64;
  1041. out_argv[p++] = u.parts[0];
  1042. out_argv[p++] = u.parts[1];
  1043. break;
  1044. }
  1045. case WASM_F32:
  1046. {
  1047. union { float32 val; uint32 part; } u;
  1048. u.val = args[i].of.f32;
  1049. out_argv[p++] = u.part;
  1050. break;
  1051. }
  1052. case WASM_F64:
  1053. {
  1054. union { float64 val; uint32 parts[2]; } u;
  1055. u.val = args[i].of.f64;
  1056. out_argv[p++] = u.parts[0];
  1057. out_argv[p++] = u.parts[1];
  1058. break;
  1059. }
  1060. default:
  1061. bh_assert(0);
  1062. break;
  1063. }
  1064. }
  1065. return p;
  1066. }
  1067. static uint32
  1068. parse_uint32_array_to_results(WASMType *type,
  1069. uint32 argc, uint32 *argv,
  1070. wasm_val_t *out_results)
  1071. {
  1072. uint32 i, p;
  1073. for (i = 0, p = 0; i < type->result_count; i++) {
  1074. switch (type->types[type->param_count + i]) {
  1075. case VALUE_TYPE_I32:
  1076. out_results[i].kind = WASM_I32;
  1077. out_results[i].of.i32 = (int32)argv[p++];
  1078. break;
  1079. case VALUE_TYPE_I64:
  1080. {
  1081. union { uint64 val; uint32 parts[2]; } u;
  1082. u.parts[0] = argv[p++];
  1083. u.parts[1] = argv[p++];
  1084. out_results[i].kind = WASM_I64;
  1085. out_results[i].of.i64 = u.val;
  1086. break;
  1087. }
  1088. case VALUE_TYPE_F32:
  1089. {
  1090. union { float32 val; uint32 part; } u;
  1091. u.part = argv[p++];
  1092. out_results[i].kind = WASM_F32;
  1093. out_results[i].of.f32 = u.val;
  1094. break;
  1095. }
  1096. case VALUE_TYPE_F64:
  1097. {
  1098. union { float64 val; uint32 parts[2]; } u;
  1099. u.parts[0] = argv[p++];
  1100. u.parts[1] = argv[p++];
  1101. out_results[i].kind = WASM_F64;
  1102. out_results[i].of.f64 = u.val;
  1103. break;
  1104. }
  1105. default:
  1106. bh_assert(0);
  1107. break;
  1108. }
  1109. }
  1110. bh_assert(argc == p);
  1111. return type->result_count;
  1112. }
  1113. bool
  1114. wasm_runtime_call_wasm_a(WASMExecEnv *exec_env,
  1115. WASMFunctionInstanceCommon *function,
  1116. uint32 num_results, wasm_val_t results[],
  1117. uint32 num_args, wasm_val_t args[])
  1118. {
  1119. uint32 argc, *argv, ret_num, cell_num, total_size, module_type;
  1120. WASMType *type;
  1121. bool ret = false;
  1122. module_type = exec_env->module_inst->module_type;
  1123. type = wasm_runtime_get_function_type(function, module_type);
  1124. if (!type) {
  1125. LOG_ERROR("Function type get failed, WAMR Interpreter and AOT must be enabled at least one.");
  1126. goto fail1;
  1127. }
  1128. argc = type->param_cell_num;
  1129. cell_num = (argc > type->ret_cell_num) ? argc : type->ret_cell_num;
  1130. if (num_results != type->result_count) {
  1131. LOG_ERROR("The result value number does not match the function declaration.");
  1132. goto fail1;
  1133. }
  1134. if (num_args != type->param_count) {
  1135. LOG_ERROR("The argument value number does not match the function declaration.");
  1136. goto fail1;
  1137. }
  1138. total_size = sizeof(uint32) * (uint64)(cell_num > 2 ? cell_num : 2);
  1139. if (!(argv = runtime_malloc((uint32)total_size, exec_env->module_inst, NULL, 0))) {
  1140. wasm_runtime_set_exception(exec_env->module_inst, "allocate memory failed");
  1141. goto fail1;
  1142. }
  1143. argc = parse_args_to_uint32_array(type, num_args, args, argv);
  1144. if (!(ret = wasm_runtime_call_wasm(exec_env, function, argc, argv)))
  1145. goto fail2;
  1146. ret_num = parse_uint32_array_to_results(type, type->ret_cell_num, argv, results);
  1147. bh_assert(ret_num == num_results);
  1148. (void)ret_num;
  1149. fail2:
  1150. wasm_runtime_free(argv);
  1151. fail1:
  1152. return ret;
  1153. }
  1154. bool
  1155. wasm_runtime_call_wasm_v(WASMExecEnv *exec_env,
  1156. WASMFunctionInstanceCommon *function,
  1157. uint32 num_results, wasm_val_t results[],
  1158. uint32 num_args, ...)
  1159. {
  1160. wasm_val_t *args = NULL;
  1161. WASMType *type = NULL;
  1162. bool ret = false;
  1163. uint32 i = 0, module_type;
  1164. va_list vargs;
  1165. module_type = exec_env->module_inst->module_type;
  1166. type = wasm_runtime_get_function_type(function, module_type);
  1167. if (!type) {
  1168. LOG_ERROR("Function type get failed, WAMR Interpreter and AOT "
  1169. "must be enabled at least one.");
  1170. goto fail1;
  1171. }
  1172. if (num_args != type->param_count) {
  1173. LOG_ERROR("The argument value number does not match the "
  1174. "function declaration.");
  1175. goto fail1;
  1176. }
  1177. if (!(args = runtime_malloc(sizeof(wasm_val_t) * num_args, NULL, NULL, 0))) {
  1178. wasm_runtime_set_exception(exec_env->module_inst, "allocate memory failed");
  1179. goto fail1;
  1180. }
  1181. va_start(vargs, num_args);
  1182. for (i = 0; i < num_args; i++) {
  1183. switch (type->types[i]) {
  1184. case VALUE_TYPE_I32:
  1185. args[i].kind = WASM_I32;
  1186. args[i].of.i32 = va_arg(vargs, uint32);
  1187. break;
  1188. case VALUE_TYPE_I64:
  1189. args[i].kind = WASM_I64;
  1190. args[i].of.i64 = va_arg(vargs, uint64);
  1191. break;
  1192. case VALUE_TYPE_F32:
  1193. args[i].kind = WASM_F32;
  1194. args[i].of.f32 = (float32)va_arg(vargs, float64);
  1195. break;
  1196. case VALUE_TYPE_F64:
  1197. args[i].kind = WASM_F64;
  1198. args[i].of.f64 = va_arg(vargs, float64);;
  1199. break;
  1200. default:
  1201. bh_assert(0);
  1202. break;
  1203. }
  1204. }
  1205. va_end(vargs);
  1206. ret = wasm_runtime_call_wasm_a(exec_env, function, num_results, results,
  1207. num_args, args);
  1208. wasm_runtime_free(args);
  1209. fail1:
  1210. return ret;
  1211. }
  1212. bool
  1213. wasm_runtime_create_exec_env_and_call_wasm(WASMModuleInstanceCommon *module_inst,
  1214. WASMFunctionInstanceCommon *function,
  1215. uint32 argc, uint32 argv[])
  1216. {
  1217. bool ret = false;
  1218. #if WASM_ENABLE_INTERP != 0
  1219. if (module_inst->module_type == Wasm_Module_Bytecode)
  1220. ret = wasm_create_exec_env_and_call_function(
  1221. (WASMModuleInstance *)module_inst, (WASMFunctionInstance *)function,
  1222. argc, argv);
  1223. #endif
  1224. #if WASM_ENABLE_AOT != 0
  1225. if (module_inst->module_type == Wasm_Module_AoT)
  1226. ret = aot_create_exec_env_and_call_function(
  1227. (AOTModuleInstance *)module_inst, (AOTFunctionInstance *)function,
  1228. argc, argv);
  1229. #endif
  1230. return ret;
  1231. }
  1232. bool
  1233. wasm_runtime_create_exec_env_singleton(WASMModuleInstanceCommon *module_inst)
  1234. {
  1235. #if WASM_ENABLE_INTERP != 0
  1236. if (module_inst->module_type == Wasm_Module_Bytecode)
  1237. return wasm_create_exec_env_singleton((WASMModuleInstance *)module_inst);
  1238. #endif
  1239. #if WASM_ENABLE_AOT != 0
  1240. if (module_inst->module_type == Wasm_Module_AoT)
  1241. return aot_create_exec_env_singleton((AOTModuleInstance *)module_inst);
  1242. #endif
  1243. return false;
  1244. }
  1245. WASMExecEnv *
  1246. wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst)
  1247. {
  1248. #if WASM_ENABLE_INTERP != 0
  1249. if (module_inst->module_type == Wasm_Module_Bytecode)
  1250. return ((WASMModuleInstance *)module_inst)->exec_env_singleton;
  1251. #endif
  1252. #if WASM_ENABLE_AOT != 0
  1253. if (module_inst->module_type == Wasm_Module_AoT)
  1254. return (WASMExecEnv *)
  1255. ((AOTModuleInstance *)module_inst)->exec_env_singleton.ptr;
  1256. #endif
  1257. return NULL;
  1258. }
  1259. void
  1260. wasm_runtime_set_exception(WASMModuleInstanceCommon *module_inst,
  1261. const char *exception)
  1262. {
  1263. #if WASM_ENABLE_INTERP != 0
  1264. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1265. wasm_set_exception((WASMModuleInstance*)module_inst, exception);
  1266. return;
  1267. }
  1268. #endif
  1269. #if WASM_ENABLE_AOT != 0
  1270. if (module_inst->module_type == Wasm_Module_AoT) {
  1271. aot_set_exception((AOTModuleInstance*)module_inst, exception);
  1272. return;
  1273. }
  1274. #endif
  1275. }
  1276. const char*
  1277. wasm_runtime_get_exception(WASMModuleInstanceCommon *module_inst)
  1278. {
  1279. #if WASM_ENABLE_INTERP != 0
  1280. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1281. return wasm_get_exception((WASMModuleInstance*)module_inst);
  1282. }
  1283. #endif
  1284. #if WASM_ENABLE_AOT != 0
  1285. if (module_inst->module_type == Wasm_Module_AoT) {
  1286. return aot_get_exception((AOTModuleInstance*)module_inst);
  1287. }
  1288. #endif
  1289. return NULL;
  1290. }
  1291. void
  1292. wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst)
  1293. {
  1294. wasm_runtime_set_exception(module_inst, NULL);
  1295. }
  1296. void
  1297. wasm_runtime_set_custom_data_internal(WASMModuleInstanceCommon *module_inst,
  1298. void *custom_data)
  1299. {
  1300. #if WASM_ENABLE_INTERP != 0
  1301. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1302. ((WASMModuleInstance*)module_inst)->custom_data = custom_data;
  1303. return;
  1304. }
  1305. #endif
  1306. #if WASM_ENABLE_AOT != 0
  1307. if (module_inst->module_type == Wasm_Module_AoT) {
  1308. ((AOTModuleInstance*)module_inst)->custom_data.ptr = custom_data;
  1309. return;
  1310. }
  1311. #endif
  1312. }
  1313. void
  1314. wasm_runtime_set_custom_data(WASMModuleInstanceCommon *module_inst,
  1315. void *custom_data)
  1316. {
  1317. #if WASM_ENABLE_THREAD_MGR != 0
  1318. wasm_cluster_spread_custom_data(module_inst, custom_data);
  1319. #else
  1320. wasm_runtime_set_custom_data_internal(module_inst, custom_data);
  1321. #endif
  1322. }
  1323. void*
  1324. wasm_runtime_get_custom_data(WASMModuleInstanceCommon *module_inst)
  1325. {
  1326. #if WASM_ENABLE_INTERP != 0
  1327. if (module_inst->module_type == Wasm_Module_Bytecode)
  1328. return ((WASMModuleInstance*)module_inst)->custom_data;
  1329. #endif
  1330. #if WASM_ENABLE_AOT != 0
  1331. if (module_inst->module_type == Wasm_Module_AoT)
  1332. return ((AOTModuleInstance*)module_inst)->custom_data.ptr;
  1333. #endif
  1334. return NULL;
  1335. }
  1336. uint32
  1337. wasm_runtime_module_malloc(WASMModuleInstanceCommon *module_inst, uint32 size,
  1338. void **p_native_addr)
  1339. {
  1340. #if WASM_ENABLE_INTERP != 0
  1341. if (module_inst->module_type == Wasm_Module_Bytecode)
  1342. return wasm_module_malloc((WASMModuleInstance*)module_inst, size,
  1343. p_native_addr);
  1344. #endif
  1345. #if WASM_ENABLE_AOT != 0
  1346. if (module_inst->module_type == Wasm_Module_AoT)
  1347. return aot_module_malloc((AOTModuleInstance*)module_inst, size,
  1348. p_native_addr);
  1349. #endif
  1350. return 0;
  1351. }
  1352. uint32
  1353. wasm_runtime_module_realloc(WASMModuleInstanceCommon *module_inst, uint32 ptr,
  1354. uint32 size, void **p_native_addr)
  1355. {
  1356. #if WASM_ENABLE_INTERP != 0
  1357. if (module_inst->module_type == Wasm_Module_Bytecode)
  1358. return wasm_module_realloc((WASMModuleInstance*)module_inst, ptr,
  1359. size, p_native_addr);
  1360. #endif
  1361. #if WASM_ENABLE_AOT != 0
  1362. if (module_inst->module_type == Wasm_Module_AoT)
  1363. return aot_module_realloc((AOTModuleInstance*)module_inst, ptr,
  1364. size, p_native_addr);
  1365. #endif
  1366. return 0;
  1367. }
  1368. void
  1369. wasm_runtime_module_free(WASMModuleInstanceCommon *module_inst, uint32 ptr)
  1370. {
  1371. #if WASM_ENABLE_INTERP != 0
  1372. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1373. wasm_module_free((WASMModuleInstance*)module_inst, ptr);
  1374. return;
  1375. }
  1376. #endif
  1377. #if WASM_ENABLE_AOT != 0
  1378. if (module_inst->module_type == Wasm_Module_AoT) {
  1379. aot_module_free((AOTModuleInstance*)module_inst, ptr);
  1380. return;
  1381. }
  1382. #endif
  1383. }
  1384. uint32
  1385. wasm_runtime_module_dup_data(WASMModuleInstanceCommon *module_inst,
  1386. const char *src, uint32 size)
  1387. {
  1388. #if WASM_ENABLE_INTERP != 0
  1389. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1390. return wasm_module_dup_data((WASMModuleInstance*)module_inst, src, size);
  1391. }
  1392. #endif
  1393. #if WASM_ENABLE_AOT != 0
  1394. if (module_inst->module_type == Wasm_Module_AoT) {
  1395. return aot_module_dup_data((AOTModuleInstance*)module_inst, src, size);
  1396. }
  1397. #endif
  1398. return 0;
  1399. }
  1400. bool
  1401. wasm_runtime_validate_app_addr(WASMModuleInstanceCommon *module_inst,
  1402. uint32 app_offset, uint32 size)
  1403. {
  1404. #if WASM_ENABLE_INTERP != 0
  1405. if (module_inst->module_type == Wasm_Module_Bytecode)
  1406. return wasm_validate_app_addr((WASMModuleInstance*)module_inst,
  1407. app_offset, size);
  1408. #endif
  1409. #if WASM_ENABLE_AOT != 0
  1410. if (module_inst->module_type == Wasm_Module_AoT)
  1411. return aot_validate_app_addr((AOTModuleInstance*)module_inst,
  1412. app_offset, size);
  1413. #endif
  1414. return false;
  1415. }
  1416. bool
  1417. wasm_runtime_validate_app_str_addr(WASMModuleInstanceCommon *module_inst,
  1418. uint32 app_str_offset)
  1419. {
  1420. uint32 app_end_offset;
  1421. char *str, *str_end;
  1422. if (!wasm_runtime_get_app_addr_range(module_inst, app_str_offset,
  1423. NULL, &app_end_offset))
  1424. goto fail;
  1425. str = wasm_runtime_addr_app_to_native(module_inst, app_str_offset);
  1426. str_end = str + (app_end_offset - app_str_offset);
  1427. while (str < str_end && *str != '\0')
  1428. str++;
  1429. if (str == str_end)
  1430. goto fail;
  1431. return true;
  1432. fail:
  1433. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  1434. return false;
  1435. }
  1436. bool
  1437. wasm_runtime_validate_native_addr(WASMModuleInstanceCommon *module_inst,
  1438. void *native_ptr, uint32 size)
  1439. {
  1440. #if WASM_ENABLE_INTERP != 0
  1441. if (module_inst->module_type == Wasm_Module_Bytecode)
  1442. return wasm_validate_native_addr((WASMModuleInstance*)module_inst,
  1443. native_ptr, size);
  1444. #endif
  1445. #if WASM_ENABLE_AOT != 0
  1446. if (module_inst->module_type == Wasm_Module_AoT)
  1447. return aot_validate_native_addr((AOTModuleInstance*)module_inst,
  1448. native_ptr, size);
  1449. #endif
  1450. return false;
  1451. }
  1452. void *
  1453. wasm_runtime_addr_app_to_native(WASMModuleInstanceCommon *module_inst,
  1454. uint32 app_offset)
  1455. {
  1456. #if WASM_ENABLE_INTERP != 0
  1457. if (module_inst->module_type == Wasm_Module_Bytecode)
  1458. return wasm_addr_app_to_native((WASMModuleInstance*)module_inst,
  1459. app_offset);
  1460. #endif
  1461. #if WASM_ENABLE_AOT != 0
  1462. if (module_inst->module_type == Wasm_Module_AoT)
  1463. return aot_addr_app_to_native((AOTModuleInstance*)module_inst,
  1464. app_offset);
  1465. #endif
  1466. return NULL;
  1467. }
  1468. uint32
  1469. wasm_runtime_addr_native_to_app(WASMModuleInstanceCommon *module_inst,
  1470. void *native_ptr)
  1471. {
  1472. #if WASM_ENABLE_INTERP != 0
  1473. if (module_inst->module_type == Wasm_Module_Bytecode)
  1474. return wasm_addr_native_to_app((WASMModuleInstance*)module_inst,
  1475. native_ptr);
  1476. #endif
  1477. #if WASM_ENABLE_AOT != 0
  1478. if (module_inst->module_type == Wasm_Module_AoT)
  1479. return aot_addr_native_to_app((AOTModuleInstance*)module_inst,
  1480. native_ptr);
  1481. #endif
  1482. return 0;
  1483. }
  1484. bool
  1485. wasm_runtime_get_app_addr_range(WASMModuleInstanceCommon *module_inst,
  1486. uint32 app_offset,
  1487. uint32 *p_app_start_offset,
  1488. uint32 *p_app_end_offset)
  1489. {
  1490. #if WASM_ENABLE_INTERP != 0
  1491. if (module_inst->module_type == Wasm_Module_Bytecode)
  1492. return wasm_get_app_addr_range((WASMModuleInstance*)module_inst,
  1493. app_offset, p_app_start_offset,
  1494. p_app_end_offset);
  1495. #endif
  1496. #if WASM_ENABLE_AOT != 0
  1497. if (module_inst->module_type == Wasm_Module_AoT)
  1498. return aot_get_app_addr_range((AOTModuleInstance*)module_inst,
  1499. app_offset, p_app_start_offset,
  1500. p_app_end_offset);
  1501. #endif
  1502. return false;
  1503. }
  1504. bool
  1505. wasm_runtime_get_native_addr_range(WASMModuleInstanceCommon *module_inst,
  1506. uint8 *native_ptr,
  1507. uint8 **p_native_start_addr,
  1508. uint8 **p_native_end_addr)
  1509. {
  1510. #if WASM_ENABLE_INTERP != 0
  1511. if (module_inst->module_type == Wasm_Module_Bytecode)
  1512. return wasm_get_native_addr_range((WASMModuleInstance*)module_inst,
  1513. native_ptr, p_native_start_addr,
  1514. p_native_end_addr);
  1515. #endif
  1516. #if WASM_ENABLE_AOT != 0
  1517. if (module_inst->module_type == Wasm_Module_AoT)
  1518. return aot_get_native_addr_range((AOTModuleInstance*)module_inst,
  1519. native_ptr, p_native_start_addr,
  1520. p_native_end_addr);
  1521. #endif
  1522. return false;
  1523. }
  1524. uint32
  1525. wasm_runtime_get_temp_ret(WASMModuleInstanceCommon *module_inst)
  1526. {
  1527. #if WASM_ENABLE_INTERP != 0
  1528. if (module_inst->module_type == Wasm_Module_Bytecode)
  1529. return ((WASMModuleInstance*)module_inst)->temp_ret;
  1530. #endif
  1531. #if WASM_ENABLE_AOT != 0
  1532. if (module_inst->module_type == Wasm_Module_AoT)
  1533. return ((AOTModuleInstance*)module_inst)->temp_ret;
  1534. #endif
  1535. return 0;
  1536. }
  1537. void
  1538. wasm_runtime_set_temp_ret(WASMModuleInstanceCommon *module_inst,
  1539. uint32 temp_ret)
  1540. {
  1541. #if WASM_ENABLE_INTERP != 0
  1542. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1543. ((WASMModuleInstance*)module_inst)->temp_ret = temp_ret;
  1544. return;
  1545. }
  1546. #endif
  1547. #if WASM_ENABLE_AOT != 0
  1548. if (module_inst->module_type == Wasm_Module_AoT) {
  1549. ((AOTModuleInstance*)module_inst)->temp_ret = temp_ret;
  1550. return;
  1551. }
  1552. #endif
  1553. }
  1554. uint32
  1555. wasm_runtime_get_llvm_stack(WASMModuleInstanceCommon *module_inst)
  1556. {
  1557. #if WASM_ENABLE_INTERP != 0
  1558. if (module_inst->module_type == Wasm_Module_Bytecode)
  1559. return ((WASMModuleInstance*)module_inst)->llvm_stack;
  1560. #endif
  1561. #if WASM_ENABLE_AOT != 0
  1562. if (module_inst->module_type == Wasm_Module_AoT)
  1563. return ((AOTModuleInstance*)module_inst)->llvm_stack;
  1564. #endif
  1565. return 0;
  1566. }
  1567. void
  1568. wasm_runtime_set_llvm_stack(WASMModuleInstanceCommon *module_inst,
  1569. uint32 llvm_stack)
  1570. {
  1571. #if WASM_ENABLE_INTERP != 0
  1572. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1573. ((WASMModuleInstance*)module_inst)->llvm_stack = llvm_stack;
  1574. return;
  1575. }
  1576. #endif
  1577. #if WASM_ENABLE_AOT != 0
  1578. if (module_inst->module_type == Wasm_Module_AoT) {
  1579. ((AOTModuleInstance*)module_inst)->llvm_stack = llvm_stack;
  1580. return;
  1581. }
  1582. #endif
  1583. }
  1584. bool
  1585. wasm_runtime_enlarge_memory(WASMModuleInstanceCommon *module,
  1586. uint32 inc_page_count)
  1587. {
  1588. #if WASM_ENABLE_INTERP != 0
  1589. if (module->module_type == Wasm_Module_Bytecode)
  1590. return wasm_enlarge_memory((WASMModuleInstance*)module,
  1591. inc_page_count);
  1592. #endif
  1593. #if WASM_ENABLE_AOT != 0
  1594. if (module->module_type == Wasm_Module_AoT)
  1595. return aot_enlarge_memory((AOTModuleInstance*)module,
  1596. inc_page_count);
  1597. #endif
  1598. return false;
  1599. }
  1600. #if WASM_ENABLE_LIBC_WASI != 0
  1601. void
  1602. wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module,
  1603. const char *dir_list[], uint32 dir_count,
  1604. const char *map_dir_list[], uint32 map_dir_count,
  1605. const char *env_list[], uint32 env_count,
  1606. char *argv[], int argc,
  1607. int stdinfd, int stdoutfd, int stderrfd)
  1608. {
  1609. WASIArguments *wasi_args = NULL;
  1610. #if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
  1611. if (module->module_type == Wasm_Module_Bytecode)
  1612. wasi_args = &((WASMModule*)module)->wasi_args;
  1613. #endif
  1614. #if WASM_ENABLE_AOT != 0
  1615. if (module->module_type == Wasm_Module_AoT)
  1616. wasi_args = &((AOTModule*)module)->wasi_args;
  1617. #endif
  1618. if (wasi_args) {
  1619. wasi_args->dir_list = dir_list;
  1620. wasi_args->dir_count = dir_count;
  1621. wasi_args->map_dir_list = map_dir_list;
  1622. wasi_args->map_dir_count = map_dir_count;
  1623. wasi_args->env = env_list;
  1624. wasi_args->env_count = env_count;
  1625. wasi_args->argv = argv;
  1626. wasi_args->argc = (uint32)argc;
  1627. wasi_args->stdio[0] = stdinfd;
  1628. wasi_args->stdio[1] = stdoutfd;
  1629. wasi_args->stdio[2] = stderrfd;
  1630. }
  1631. }
  1632. void
  1633. wasm_runtime_set_wasi_args(WASMModuleCommon *module,
  1634. const char *dir_list[], uint32 dir_count,
  1635. const char *map_dir_list[], uint32 map_dir_count,
  1636. const char *env_list[], uint32 env_count,
  1637. char *argv[], int argc)
  1638. {
  1639. wasm_runtime_set_wasi_args_ex(module,
  1640. dir_list, dir_count,
  1641. map_dir_list, map_dir_count,
  1642. env_list, env_count,
  1643. argv, argc,
  1644. -1, -1, -1);
  1645. }
  1646. #if WASM_ENABLE_UVWASI == 0
  1647. bool
  1648. wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
  1649. const char *dir_list[], uint32 dir_count,
  1650. const char *map_dir_list[], uint32 map_dir_count,
  1651. const char *env[], uint32 env_count,
  1652. char *argv[], uint32 argc,
  1653. int stdinfd, int stdoutfd, int stderrfd,
  1654. char *error_buf, uint32 error_buf_size)
  1655. {
  1656. WASIContext *wasi_ctx;
  1657. char *argv_buf = NULL;
  1658. char **argv_list = NULL;
  1659. char *env_buf = NULL;
  1660. char **env_list = NULL;
  1661. uint64 argv_buf_size = 0, env_buf_size = 0, total_size;
  1662. uint32 argv_buf_offset = 0, env_buf_offset = 0;
  1663. struct fd_table *curfds = NULL;
  1664. struct fd_prestats *prestats = NULL;
  1665. struct argv_environ_values *argv_environ = NULL;
  1666. bool fd_table_inited = false, fd_prestats_inited = false;
  1667. bool argv_environ_inited = false;
  1668. __wasi_fd_t wasm_fd = 3;
  1669. int32 raw_fd;
  1670. char *path, resolved_path[PATH_MAX];
  1671. uint32 i;
  1672. if (!(wasi_ctx = runtime_malloc(sizeof(WASIContext), NULL,
  1673. error_buf, error_buf_size))) {
  1674. return false;
  1675. }
  1676. wasm_runtime_set_wasi_ctx(module_inst, wasi_ctx);
  1677. #if WASM_ENABLE_INTERP != 0
  1678. if (module_inst->module_type == Wasm_Module_Bytecode
  1679. && !((WASMModuleInstance*)module_inst)->default_memory)
  1680. return true;
  1681. #endif
  1682. #if WASM_ENABLE_AOT != 0
  1683. if (module_inst->module_type == Wasm_Module_AoT
  1684. && !((AOTModuleInstance*)module_inst)->
  1685. global_table_data.memory_instances[0].memory_data.ptr)
  1686. return true;
  1687. #endif
  1688. /* process argv[0], trip the path and suffix, only keep the program name */
  1689. for (i = 0; i < argc; i++)
  1690. argv_buf_size += strlen(argv[i]) + 1;
  1691. total_size = sizeof(char *) * (uint64)argc;
  1692. if (total_size >= UINT32_MAX
  1693. || (total_size > 0 &&
  1694. !(argv_list = wasm_runtime_malloc((uint32)total_size)))
  1695. || argv_buf_size >= UINT32_MAX
  1696. || (argv_buf_size > 0 &&
  1697. !(argv_buf = wasm_runtime_malloc((uint32)argv_buf_size)))) {
  1698. set_error_buf(error_buf, error_buf_size,
  1699. "Init wasi environment failed: allocate memory failed");
  1700. goto fail;
  1701. }
  1702. for (i = 0; i < argc; i++) {
  1703. argv_list[i] = argv_buf + argv_buf_offset;
  1704. bh_strcpy_s(argv_buf + argv_buf_offset,
  1705. (uint32)argv_buf_size - argv_buf_offset, argv[i]);
  1706. argv_buf_offset += (uint32)(strlen(argv[i]) + 1);
  1707. }
  1708. for (i = 0; i < env_count; i++)
  1709. env_buf_size += strlen(env[i]) + 1;
  1710. total_size = sizeof(char *) * (uint64)env_count;
  1711. if (total_size >= UINT32_MAX
  1712. || (total_size > 0
  1713. && !(env_list = wasm_runtime_malloc((uint32)total_size)))
  1714. || env_buf_size >= UINT32_MAX
  1715. || (env_buf_size > 0
  1716. && !(env_buf = wasm_runtime_malloc((uint32)env_buf_size)))) {
  1717. set_error_buf(error_buf, error_buf_size,
  1718. "Init wasi environment failed: allocate memory failed");
  1719. goto fail;
  1720. }
  1721. for (i = 0; i < env_count; i++) {
  1722. env_list[i] = env_buf + env_buf_offset;
  1723. bh_strcpy_s(env_buf + env_buf_offset,
  1724. (uint32)env_buf_size - env_buf_offset, env[i]);
  1725. env_buf_offset += (uint32)(strlen(env[i]) + 1);
  1726. }
  1727. if (!(curfds = wasm_runtime_malloc(sizeof(struct fd_table)))
  1728. || !(prestats = wasm_runtime_malloc(sizeof(struct fd_prestats)))
  1729. || !(argv_environ =
  1730. wasm_runtime_malloc(sizeof(struct argv_environ_values)))) {
  1731. set_error_buf(error_buf, error_buf_size,
  1732. "Init wasi environment failed: allocate memory failed");
  1733. goto fail;
  1734. }
  1735. if (!fd_table_init(curfds)) {
  1736. set_error_buf(error_buf, error_buf_size,
  1737. "Init wasi environment failed: "
  1738. "init fd table failed");
  1739. goto fail;
  1740. }
  1741. fd_table_inited = true;
  1742. if (!fd_prestats_init(prestats)) {
  1743. set_error_buf(error_buf, error_buf_size,
  1744. "Init wasi environment failed: "
  1745. "init fd prestats failed");
  1746. goto fail;
  1747. }
  1748. fd_prestats_inited = true;
  1749. if (!argv_environ_init(argv_environ,
  1750. argv_buf, argv_buf_size,
  1751. argv_list, argc,
  1752. env_buf, env_buf_size,
  1753. env_list, env_count)) {
  1754. set_error_buf(error_buf, error_buf_size,
  1755. "Init wasi environment failed: "
  1756. "init argument environment failed");
  1757. goto fail;
  1758. }
  1759. argv_environ_inited = true;
  1760. /* Prepopulate curfds with stdin, stdout, and stderr file descriptors. */
  1761. if (!fd_table_insert_existing(curfds, 0, (stdinfd != -1) ? stdinfd : 0)
  1762. || !fd_table_insert_existing(curfds, 1, (stdoutfd != -1) ? stdoutfd : 1)
  1763. || !fd_table_insert_existing(curfds, 2, (stderrfd != -1) ? stderrfd : 2)) {
  1764. set_error_buf(error_buf, error_buf_size,
  1765. "Init wasi environment failed: init fd table failed");
  1766. goto fail;
  1767. }
  1768. wasm_fd = 3;
  1769. for (i = 0; i < dir_count; i++, wasm_fd++) {
  1770. path = realpath(dir_list[i], resolved_path);
  1771. if (!path) {
  1772. if (error_buf)
  1773. snprintf(error_buf, error_buf_size,
  1774. "error while pre-opening directory %s: %d\n",
  1775. dir_list[i], errno);
  1776. goto fail;
  1777. }
  1778. raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
  1779. if (raw_fd == -1) {
  1780. if (error_buf)
  1781. snprintf(error_buf, error_buf_size,
  1782. "error while pre-opening directory %s: %d\n",
  1783. dir_list[i], errno);
  1784. goto fail;
  1785. }
  1786. fd_table_insert_existing(curfds, wasm_fd, raw_fd);
  1787. fd_prestats_insert(prestats, dir_list[i], wasm_fd);
  1788. }
  1789. wasi_ctx->curfds = curfds;
  1790. wasi_ctx->prestats = prestats;
  1791. wasi_ctx->argv_environ = argv_environ;
  1792. wasi_ctx->argv_buf = argv_buf;
  1793. wasi_ctx->argv_list = argv_list;
  1794. wasi_ctx->env_buf = env_buf;
  1795. wasi_ctx->env_list = env_list;
  1796. return true;
  1797. fail:
  1798. if (argv_environ_inited)
  1799. argv_environ_destroy(argv_environ);
  1800. if (fd_prestats_inited)
  1801. fd_prestats_destroy(prestats);
  1802. if (fd_table_inited)
  1803. fd_table_destroy(curfds);
  1804. if (curfds)
  1805. wasm_runtime_free(curfds);
  1806. if (prestats)
  1807. wasm_runtime_free(prestats);
  1808. if (argv_environ)
  1809. wasm_runtime_free(argv_environ);
  1810. if (argv_buf)
  1811. wasm_runtime_free(argv_buf);
  1812. if (argv_list)
  1813. wasm_runtime_free(argv_list);
  1814. if (env_buf)
  1815. wasm_runtime_free(env_buf);
  1816. if (env_list)
  1817. wasm_runtime_free(env_list);
  1818. return false;
  1819. }
  1820. #else /* else of WASM_ENABLE_UVWASI == 0 */
  1821. static void *
  1822. wasm_uvwasi_malloc(size_t size, void *mem_user_data)
  1823. {
  1824. return runtime_malloc(size, NULL, NULL, 0);
  1825. (void)mem_user_data;
  1826. }
  1827. static void
  1828. wasm_uvwasi_free(void *ptr, void *mem_user_data)
  1829. {
  1830. if (ptr)
  1831. wasm_runtime_free(ptr);
  1832. (void)mem_user_data;
  1833. }
  1834. static void *
  1835. wasm_uvwasi_calloc(size_t nmemb, size_t size,
  1836. void *mem_user_data)
  1837. {
  1838. uint64 total_size = (uint64)nmemb * size;
  1839. return runtime_malloc(total_size, NULL, NULL, 0);
  1840. (void)mem_user_data;
  1841. }
  1842. static void *
  1843. wasm_uvwasi_realloc(void *ptr, size_t size,
  1844. void *mem_user_data)
  1845. {
  1846. if (size >= UINT32_MAX) {
  1847. return NULL;
  1848. }
  1849. return wasm_runtime_realloc(ptr, (uint32)size);
  1850. }
  1851. static uvwasi_mem_t uvwasi_allocator = {
  1852. .mem_user_data = 0,
  1853. .malloc = wasm_uvwasi_malloc,
  1854. .free = wasm_uvwasi_free,
  1855. .calloc = wasm_uvwasi_calloc,
  1856. .realloc = wasm_uvwasi_realloc
  1857. };
  1858. bool
  1859. wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
  1860. const char *dir_list[], uint32 dir_count,
  1861. const char *map_dir_list[], uint32 map_dir_count,
  1862. const char *env[], uint32 env_count,
  1863. char *argv[], uint32 argc,
  1864. int stdinfd, int stdoutfd, int stderrfd,
  1865. char *error_buf, uint32 error_buf_size)
  1866. {
  1867. uvwasi_t *uvwasi = NULL;
  1868. uvwasi_options_t init_options;
  1869. const char **envp = NULL;
  1870. uint64 total_size;
  1871. uint32 i;
  1872. bool ret = false;
  1873. uvwasi = runtime_malloc(sizeof(uvwasi_t), module_inst,
  1874. error_buf, error_buf_size);
  1875. if (!uvwasi)
  1876. return false;
  1877. /* Setup the initialization options */
  1878. uvwasi_options_init(&init_options);
  1879. init_options.allocator = &uvwasi_allocator;
  1880. init_options.argc = argc;
  1881. init_options.argv = (const char **)argv;
  1882. init_options.in = (stdinfd != -1) ? (uvwasi_fd_t)stdinfd : init_options.in;
  1883. init_options.out = (stdoutfd != -1) ? (uvwasi_fd_t)stdoutfd : init_options.out;
  1884. init_options.err = (stderrfd != -1) ? (uvwasi_fd_t)stderrfd : init_options.err;
  1885. if (dir_count > 0) {
  1886. init_options.preopenc = dir_count;
  1887. total_size = sizeof(uvwasi_preopen_t) * (uint64)init_options.preopenc;
  1888. init_options.preopens =
  1889. (uvwasi_preopen_t *)runtime_malloc(total_size, module_inst,
  1890. error_buf, error_buf_size);
  1891. if (init_options.preopens == NULL)
  1892. goto fail;
  1893. for (i = 0; i < init_options.preopenc; i++) {
  1894. init_options.preopens[i].real_path = dir_list[i];
  1895. init_options.preopens[i].mapped_path =
  1896. (i < map_dir_count) ? map_dir_list[i] : dir_list[i];
  1897. }
  1898. }
  1899. if (env_count > 0) {
  1900. total_size = sizeof(char *) * (uint64)(env_count + 1);
  1901. envp = runtime_malloc(total_size, module_inst,
  1902. error_buf, error_buf_size);
  1903. if (envp == NULL)
  1904. goto fail;
  1905. for (i = 0; i < env_count; i++) {
  1906. envp[i] = env[i];
  1907. }
  1908. envp[env_count] = NULL;
  1909. init_options.envp = envp;
  1910. }
  1911. if (UVWASI_ESUCCESS != uvwasi_init(uvwasi, &init_options)) {
  1912. set_error_buf(error_buf, error_buf_size, "uvwasi init failed");
  1913. goto fail;
  1914. }
  1915. wasm_runtime_set_wasi_ctx(module_inst, uvwasi);
  1916. ret = true;
  1917. fail:
  1918. if (envp)
  1919. wasm_runtime_free((void*)envp);
  1920. if (init_options.preopens)
  1921. wasm_runtime_free(init_options.preopens);
  1922. if (!ret && uvwasi)
  1923. wasm_runtime_free(uvwasi);
  1924. return ret;
  1925. }
  1926. #endif /* end of WASM_ENABLE_UVWASI */
  1927. bool
  1928. wasm_runtime_is_wasi_mode(WASMModuleInstanceCommon *module_inst)
  1929. {
  1930. #if WASM_ENABLE_INTERP != 0
  1931. if (module_inst->module_type == Wasm_Module_Bytecode
  1932. && ((WASMModuleInstance*)module_inst)->module->is_wasi_module)
  1933. return true;
  1934. #endif
  1935. #if WASM_ENABLE_AOT != 0
  1936. if (module_inst->module_type == Wasm_Module_AoT
  1937. && ((AOTModule*)((AOTModuleInstance*)module_inst)->aot_module.ptr)
  1938. ->is_wasi_module)
  1939. return true;
  1940. #endif
  1941. return false;
  1942. }
  1943. WASMFunctionInstanceCommon *
  1944. wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst)
  1945. {
  1946. uint32 i;
  1947. #if WASM_ENABLE_INTERP != 0
  1948. if (module_inst->module_type == Wasm_Module_Bytecode) {
  1949. WASMModuleInstance *wasm_inst = (WASMModuleInstance*)module_inst;
  1950. WASMFunctionInstance *func;
  1951. for (i = 0; i < wasm_inst->export_func_count; i++) {
  1952. if (!strcmp(wasm_inst->export_functions[i].name, "_start")) {
  1953. func = wasm_inst->export_functions[i].function;
  1954. if (func->u.func->func_type->param_count != 0
  1955. || func->u.func->func_type->result_count != 0) {
  1956. LOG_ERROR("Lookup wasi _start function failed: "
  1957. "invalid function type.\n");
  1958. return NULL;
  1959. }
  1960. return (WASMFunctionInstanceCommon*)func;
  1961. }
  1962. }
  1963. return NULL;
  1964. }
  1965. #endif
  1966. #if WASM_ENABLE_AOT != 0
  1967. if (module_inst->module_type == Wasm_Module_AoT) {
  1968. AOTModuleInstance *aot_inst = (AOTModuleInstance*)module_inst;
  1969. AOTFunctionInstance *export_funcs = (AOTFunctionInstance *)
  1970. aot_inst->export_funcs.ptr;
  1971. for (i = 0; i < aot_inst->export_func_count; i++) {
  1972. if (!strcmp(export_funcs[i].func_name, "_start")) {
  1973. AOTFuncType *func_type = export_funcs[i].u.func.func_type;
  1974. if (func_type->param_count != 0
  1975. || func_type->result_count != 0) {
  1976. LOG_ERROR("Lookup wasi _start function failed: "
  1977. "invalid function type.\n");
  1978. return NULL;
  1979. }
  1980. return (WASMFunctionInstanceCommon*)&export_funcs[i];
  1981. }
  1982. }
  1983. return NULL;
  1984. }
  1985. #endif /* end of WASM_ENABLE_AOT */
  1986. return NULL;
  1987. }
  1988. #if WASM_ENABLE_UVWASI == 0
  1989. void
  1990. wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst)
  1991. {
  1992. WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
  1993. if (wasi_ctx) {
  1994. if (wasi_ctx->argv_environ) {
  1995. argv_environ_destroy(wasi_ctx->argv_environ);
  1996. wasm_runtime_free(wasi_ctx->argv_environ);
  1997. }
  1998. if (wasi_ctx->curfds) {
  1999. fd_table_destroy(wasi_ctx->curfds);
  2000. wasm_runtime_free(wasi_ctx->curfds);
  2001. }
  2002. if (wasi_ctx->prestats) {
  2003. fd_prestats_destroy(wasi_ctx->prestats);
  2004. wasm_runtime_free(wasi_ctx->prestats);
  2005. }
  2006. if (wasi_ctx->argv_buf)
  2007. wasm_runtime_free(wasi_ctx->argv_buf);
  2008. if (wasi_ctx->argv_list)
  2009. wasm_runtime_free(wasi_ctx->argv_list);
  2010. if (wasi_ctx->env_buf)
  2011. wasm_runtime_free(wasi_ctx->env_buf);
  2012. if (wasi_ctx->env_list)
  2013. wasm_runtime_free(wasi_ctx->env_list);
  2014. wasm_runtime_free(wasi_ctx);
  2015. }
  2016. }
  2017. #else
  2018. void
  2019. wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst)
  2020. {
  2021. WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
  2022. if (wasi_ctx) {
  2023. uvwasi_destroy(wasi_ctx);
  2024. wasm_runtime_free(wasi_ctx);
  2025. }
  2026. }
  2027. #endif
  2028. WASIContext *
  2029. wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst)
  2030. {
  2031. #if WASM_ENABLE_INTERP != 0
  2032. if (module_inst->module_type == Wasm_Module_Bytecode)
  2033. return ((WASMModuleInstance*)module_inst)->wasi_ctx;
  2034. #endif
  2035. #if WASM_ENABLE_AOT != 0
  2036. if (module_inst->module_type == Wasm_Module_AoT)
  2037. return ((AOTModuleInstance*)module_inst)->wasi_ctx.ptr;
  2038. #endif
  2039. return NULL;
  2040. }
  2041. void
  2042. wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst,
  2043. WASIContext *wasi_ctx)
  2044. {
  2045. #if WASM_ENABLE_INTERP != 0
  2046. if (module_inst->module_type == Wasm_Module_Bytecode)
  2047. ((WASMModuleInstance*)module_inst)->wasi_ctx = wasi_ctx;
  2048. #endif
  2049. #if WASM_ENABLE_AOT != 0
  2050. if (module_inst->module_type == Wasm_Module_AoT)
  2051. ((AOTModuleInstance*)module_inst)->wasi_ctx.ptr = wasi_ctx;
  2052. #endif
  2053. }
  2054. #endif /* end of WASM_ENABLE_LIBC_WASI */
  2055. WASMModuleCommon*
  2056. wasm_exec_env_get_module(WASMExecEnv *exec_env)
  2057. {
  2058. WASMModuleInstanceCommon *module_inst =
  2059. wasm_runtime_get_module_inst(exec_env);
  2060. #if WASM_ENABLE_INTERP != 0
  2061. if (module_inst->module_type == Wasm_Module_Bytecode)
  2062. return (WASMModuleCommon*)
  2063. ((WASMModuleInstance*)module_inst)->module;
  2064. #endif
  2065. #if WASM_ENABLE_AOT != 0
  2066. if (module_inst->module_type == Wasm_Module_AoT)
  2067. return (WASMModuleCommon*)
  2068. ((AOTModuleInstance*)module_inst)->aot_module.ptr;
  2069. #endif
  2070. return NULL;
  2071. }
  2072. static union {
  2073. int a;
  2074. char b;
  2075. } __ue = { .a = 1 };
  2076. #define is_little_endian() (__ue.b == 1)
  2077. bool
  2078. wasm_runtime_register_natives(const char *module_name,
  2079. NativeSymbol *native_symbols,
  2080. uint32 n_native_symbols)
  2081. {
  2082. return wasm_native_register_natives(module_name,
  2083. native_symbols, n_native_symbols);
  2084. }
  2085. bool
  2086. wasm_runtime_register_natives_raw(const char *module_name,
  2087. NativeSymbol *native_symbols,
  2088. uint32 n_native_symbols)
  2089. {
  2090. return wasm_native_register_natives_raw(module_name,
  2091. native_symbols, n_native_symbols);
  2092. }
  2093. bool
  2094. wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
  2095. const WASMType *func_type, const char *signature,
  2096. void *attachment,
  2097. uint32 *argv, uint32 argc, uint32 *argv_ret)
  2098. {
  2099. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  2100. typedef void (*NativeRawFuncPtr)(WASMExecEnv*, uint64*);
  2101. NativeRawFuncPtr invokeNativeRaw = (NativeRawFuncPtr)func_ptr;
  2102. uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size;
  2103. uint32 *argv_src = argv, i, argc1, ptr_len;
  2104. uint32 arg_i32;
  2105. bool ret = false;
  2106. argc1 = func_type->param_count;
  2107. if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
  2108. size = sizeof(uint64) * (uint64)argc1;
  2109. if (!(argv1 = runtime_malloc((uint32)size, exec_env->module_inst,
  2110. NULL, 0))) {
  2111. return false;
  2112. }
  2113. }
  2114. argv_dst = argv1;
  2115. /* Traverse secondly to fill in each argument */
  2116. for (i = 0; i < func_type->param_count; i++, argv_dst++) {
  2117. switch (func_type->types[i]) {
  2118. case VALUE_TYPE_I32:
  2119. {
  2120. *(uint32*)argv_dst = arg_i32 = *argv_src++;
  2121. if (signature) {
  2122. if (signature[i + 1] == '*') {
  2123. /* param is a pointer */
  2124. if (signature[i + 2] == '~')
  2125. /* pointer with length followed */
  2126. ptr_len = *argv_src;
  2127. else
  2128. /* pointer without length followed */
  2129. ptr_len = 1;
  2130. if (!wasm_runtime_validate_app_addr(module, arg_i32, ptr_len))
  2131. goto fail;
  2132. *(uintptr_t*)argv_dst = (uintptr_t)
  2133. wasm_runtime_addr_app_to_native(module, arg_i32);
  2134. }
  2135. else if (signature[i + 1] == '$') {
  2136. /* param is a string */
  2137. if (!wasm_runtime_validate_app_str_addr(module, arg_i32))
  2138. goto fail;
  2139. *(uintptr_t*)argv_dst = (uintptr_t)
  2140. wasm_runtime_addr_app_to_native(module, arg_i32);
  2141. }
  2142. }
  2143. break;
  2144. }
  2145. case VALUE_TYPE_I64:
  2146. case VALUE_TYPE_F64:
  2147. bh_memcpy_s(argv_dst, sizeof(uint64), argv_src, sizeof(uint32) * 2);
  2148. argv_src += 2;
  2149. break;
  2150. case VALUE_TYPE_F32:
  2151. *(float32*)argv_dst = *(float32*)argv_src++;
  2152. break;
  2153. #if WASM_ENABLE_REF_TYPES != 0
  2154. case VALUE_TYPE_FUNCREF:
  2155. case VALUE_TYPE_EXTERNREF:
  2156. *(uint32*)argv_dst = *argv_src++;
  2157. break;
  2158. #endif
  2159. default:
  2160. bh_assert(0);
  2161. break;
  2162. }
  2163. }
  2164. exec_env->attachment = attachment;
  2165. invokeNativeRaw(exec_env, argv1);
  2166. exec_env->attachment = NULL;
  2167. if (func_type->result_count > 0) {
  2168. switch (func_type->types[func_type->param_count]) {
  2169. case VALUE_TYPE_I32:
  2170. #if WASM_ENABLE_REF_TYPES != 0
  2171. case VALUE_TYPE_FUNCREF:
  2172. case VALUE_TYPE_EXTERNREF:
  2173. #endif
  2174. argv_ret[0] = *(uint32*)argv1;
  2175. break;
  2176. case VALUE_TYPE_F32:
  2177. *(float32*)argv_ret = *(float32*)argv1;
  2178. break;
  2179. case VALUE_TYPE_I64:
  2180. case VALUE_TYPE_F64:
  2181. bh_memcpy_s(argv_ret, sizeof(uint32) * 2, argv1, sizeof(uint64));
  2182. break;
  2183. default:
  2184. bh_assert(0);
  2185. break;
  2186. }
  2187. }
  2188. ret = !wasm_runtime_get_exception(module) ? true : false;
  2189. fail:
  2190. if (argv1 != argv_buf)
  2191. wasm_runtime_free(argv1);
  2192. return ret;
  2193. }
  2194. /**
  2195. * Implementation of wasm_runtime_invoke_native()
  2196. */
  2197. /* The invoke native implementation on ARM platform with VFP co-processor */
  2198. #if defined(BUILD_TARGET_ARM_VFP) \
  2199. || defined(BUILD_TARGET_THUMB_VFP) \
  2200. || defined(BUILD_TARGET_RISCV32_ILP32D) \
  2201. || defined(BUILD_TARGET_RISCV32_ILP32)
  2202. typedef void (*GenericFunctionPointer)();
  2203. int64 invokeNative(GenericFunctionPointer f, uint32 *args, uint32 n_stacks);
  2204. typedef float64 (*Float64FuncPtr)(GenericFunctionPointer, uint32*, uint32);
  2205. typedef float32 (*Float32FuncPtr)(GenericFunctionPointer, uint32*, uint32);
  2206. typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint32*,uint32);
  2207. typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint32*, uint32);
  2208. typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint32*, uint32);
  2209. static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)(uintptr_t)invokeNative;
  2210. static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)(uintptr_t)invokeNative;
  2211. static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)(uintptr_t)invokeNative;
  2212. static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)(uintptr_t)invokeNative;
  2213. static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)(uintptr_t)invokeNative;
  2214. #if !defined(BUILD_TARGET_RISCV32_ILP32D) \
  2215. && !defined(BUILD_TARGET_RISCV32_ILP32)
  2216. #define MAX_REG_INTS 4
  2217. #define MAX_REG_FLOATS 16
  2218. #else
  2219. #define MAX_REG_INTS 8
  2220. #define MAX_REG_FLOATS 8
  2221. #endif
  2222. bool
  2223. wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
  2224. const WASMType *func_type, const char *signature,
  2225. void *attachment,
  2226. uint32 *argv, uint32 argc, uint32 *argv_ret)
  2227. {
  2228. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  2229. /* argv buf layout: int args(fix cnt) + float args(fix cnt) + stack args */
  2230. uint32 argv_buf[32], *argv1 = argv_buf, *ints, *stacks, size;
  2231. uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0;
  2232. uint32 arg_i32, ptr_len;
  2233. uint32 result_count = func_type->result_count;
  2234. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  2235. bool ret = false;
  2236. #if !defined(BUILD_TARGET_RISCV32_ILP32)
  2237. uint32 *fps;
  2238. int n_fps = 0;
  2239. #else
  2240. #define fps ints
  2241. #define n_fps n_ints
  2242. #endif
  2243. n_ints++; /* exec env */
  2244. /* Traverse firstly to calculate stack args count */
  2245. for (i = 0; i < func_type->param_count; i++) {
  2246. switch (func_type->types[i]) {
  2247. case VALUE_TYPE_I32:
  2248. #if WASM_ENABLE_REF_TYPES != 0
  2249. case VALUE_TYPE_FUNCREF:
  2250. case VALUE_TYPE_EXTERNREF:
  2251. #endif
  2252. if (n_ints < MAX_REG_INTS)
  2253. n_ints++;
  2254. else
  2255. n_stacks++;
  2256. break;
  2257. case VALUE_TYPE_I64:
  2258. if (n_ints < MAX_REG_INTS - 1) {
  2259. #if !defined(BUILD_TARGET_RISCV32_ILP32) && !defined(BUILD_TARGET_RISCV32_ILP32D)
  2260. /* 64-bit data must be 8 bytes aligned in arm */
  2261. if (n_ints & 1)
  2262. n_ints++;
  2263. #endif
  2264. n_ints += 2;
  2265. }
  2266. #if defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_RISCV32_ILP32D)
  2267. /* part in register, part in stack */
  2268. else if (n_ints == MAX_REG_INTS - 1) {
  2269. n_ints++;
  2270. n_stacks++;
  2271. }
  2272. #endif
  2273. else {
  2274. /* 64-bit data in stack must be 8 bytes aligned
  2275. in arm and riscv32 */
  2276. if (n_stacks & 1)
  2277. n_stacks++;
  2278. n_stacks += 2;
  2279. }
  2280. break;
  2281. #if !defined(BUILD_TARGET_RISCV32_ILP32D)
  2282. case VALUE_TYPE_F32:
  2283. if (n_fps < MAX_REG_FLOATS)
  2284. n_fps++;
  2285. else
  2286. n_stacks++;
  2287. break;
  2288. case VALUE_TYPE_F64:
  2289. if (n_fps < MAX_REG_FLOATS - 1) {
  2290. #if !defined(BUILD_TARGET_RISCV32_ILP32)
  2291. /* 64-bit data must be 8 bytes aligned in arm */
  2292. if (n_fps & 1)
  2293. n_fps++;
  2294. #endif
  2295. n_fps += 2;
  2296. }
  2297. #if defined(BUILD_TARGET_RISCV32_ILP32)
  2298. else if (n_fps == MAX_REG_FLOATS - 1) {
  2299. n_fps++;
  2300. n_stacks++;
  2301. }
  2302. #endif
  2303. else {
  2304. /* 64-bit data must be 8 bytes aligned in arm */
  2305. if (n_stacks & 1)
  2306. n_stacks++;
  2307. n_stacks += 2;
  2308. }
  2309. break;
  2310. #else /* BUILD_TARGET_RISCV32_ILP32D */
  2311. case VALUE_TYPE_F32:
  2312. case VALUE_TYPE_F64:
  2313. if (n_fps < MAX_REG_FLOATS) {
  2314. n_fps++;
  2315. }
  2316. else if (func_type->types[i] == VALUE_TYPE_F32
  2317. && n_ints < MAX_REG_INTS) {
  2318. /* use int reg firstly if available */
  2319. n_ints++;
  2320. }
  2321. else if (func_type->types[i] == VALUE_TYPE_F64
  2322. && n_ints < MAX_REG_INTS - 1) {
  2323. /* use int regs firstly if available */
  2324. if (n_ints & 1)
  2325. n_ints++;
  2326. ints += 2;
  2327. }
  2328. else {
  2329. /* 64-bit data in stack must be 8 bytes aligned in riscv32 */
  2330. if (n_stacks & 1)
  2331. n_stacks++;
  2332. n_stacks += 2;
  2333. }
  2334. break;
  2335. #endif /* BUILD_TARGET_RISCV32_ILP32D */
  2336. default:
  2337. bh_assert(0);
  2338. break;
  2339. }
  2340. }
  2341. for (i = 0; i < ext_ret_count; i++) {
  2342. if (n_ints < MAX_REG_INTS)
  2343. n_ints++;
  2344. else
  2345. n_stacks++;
  2346. }
  2347. #if !defined(BUILD_TARGET_RISCV32_ILP32) && !defined(BUILD_TARGET_RISCV32_ILP32D)
  2348. argc1 = MAX_REG_INTS + MAX_REG_FLOATS + n_stacks;
  2349. #elif defined(BUILD_TARGET_RISCV32_ILP32)
  2350. argc1 = MAX_REG_INTS + n_stacks;
  2351. #else
  2352. argc1 = MAX_REG_INTS + MAX_REG_FLOATS * 2 + n_stacks;
  2353. #endif
  2354. if (argc1 > sizeof(argv_buf) / sizeof(uint32)) {
  2355. size = sizeof(uint32) * (uint32)argc1;
  2356. if (!(argv1 = runtime_malloc((uint32)size, exec_env->module_inst,
  2357. NULL, 0))) {
  2358. return false;
  2359. }
  2360. }
  2361. ints = argv1;
  2362. #if !defined(BUILD_TARGET_RISCV32_ILP32) && !defined(BUILD_TARGET_RISCV32_ILP32D)
  2363. fps = ints + MAX_REG_INTS;
  2364. stacks = fps + MAX_REG_FLOATS;
  2365. #elif defined(BUILD_TARGET_RISCV32_ILP32)
  2366. stacks = ints + MAX_REG_INTS;
  2367. #else
  2368. fps = ints + MAX_REG_INTS;
  2369. stacks = fps + MAX_REG_FLOATS * 2;
  2370. #endif
  2371. n_ints = 0;
  2372. n_fps = 0;
  2373. n_stacks = 0;
  2374. ints[n_ints++] = (uint32)(uintptr_t)exec_env;
  2375. /* Traverse secondly to fill in each argument */
  2376. for (i = 0; i < func_type->param_count; i++) {
  2377. switch (func_type->types[i]) {
  2378. case VALUE_TYPE_I32:
  2379. {
  2380. arg_i32 = *argv_src++;
  2381. if (signature) {
  2382. if (signature[i + 1] == '*') {
  2383. /* param is a pointer */
  2384. if (signature[i + 2] == '~')
  2385. /* pointer with length followed */
  2386. ptr_len = *argv_src;
  2387. else
  2388. /* pointer without length followed */
  2389. ptr_len = 1;
  2390. if (!wasm_runtime_validate_app_addr(module, arg_i32, ptr_len))
  2391. goto fail;
  2392. arg_i32 = (uintptr_t)
  2393. wasm_runtime_addr_app_to_native(module, arg_i32);
  2394. }
  2395. else if (signature[i + 1] == '$') {
  2396. /* param is a string */
  2397. if (!wasm_runtime_validate_app_str_addr(module, arg_i32))
  2398. goto fail;
  2399. arg_i32 = (uintptr_t)
  2400. wasm_runtime_addr_app_to_native(module, arg_i32);
  2401. }
  2402. }
  2403. if (n_ints < MAX_REG_INTS)
  2404. ints[n_ints++] = arg_i32;
  2405. else
  2406. stacks[n_stacks++] = arg_i32;
  2407. break;
  2408. }
  2409. #if WASM_ENABLE_REF_TYPES != 0
  2410. case VALUE_TYPE_FUNCREF:
  2411. case VALUE_TYPE_EXTERNREF:
  2412. {
  2413. if (n_ints < MAX_REG_INTS)
  2414. ints[n_ints++] = *argv_src++;
  2415. else
  2416. stacks[n_stacks++] = *argv_src++;
  2417. break;
  2418. }
  2419. #endif
  2420. case VALUE_TYPE_I64:
  2421. {
  2422. if (n_ints < MAX_REG_INTS - 1) {
  2423. #if !defined(BUILD_TARGET_RISCV32_ILP32) && !defined(BUILD_TARGET_RISCV32_ILP32D)
  2424. /* 64-bit data must be 8 bytes aligned in arm */
  2425. if (n_ints & 1)
  2426. n_ints++;
  2427. #endif
  2428. *(uint64*)&ints[n_ints] = *(uint64*)argv_src;
  2429. n_ints += 2;
  2430. argv_src += 2;
  2431. }
  2432. #if defined(BUILD_TARGET_RISCV32_ILP32) || defined(BUILD_TARGET_RISCV32_ILP32D)
  2433. else if (n_ints == MAX_REG_INTS - 1) {
  2434. ints[n_ints++] = *argv_src++;
  2435. stacks[n_stacks++] = *argv_src++;
  2436. }
  2437. #endif
  2438. else {
  2439. /* 64-bit data in stack must be 8 bytes aligned
  2440. in arm and riscv32 */
  2441. if (n_stacks & 1)
  2442. n_stacks++;
  2443. *(uint64*)&stacks[n_stacks] = *(uint64*)argv_src;
  2444. n_stacks += 2;
  2445. argv_src += 2;
  2446. }
  2447. break;
  2448. }
  2449. #if !defined(BUILD_TARGET_RISCV32_ILP32D)
  2450. case VALUE_TYPE_F32:
  2451. {
  2452. if (n_fps < MAX_REG_FLOATS)
  2453. *(float32*)&fps[n_fps++] = *(float32*)argv_src++;
  2454. else
  2455. *(float32*)&stacks[n_stacks++] = *(float32*)argv_src++;
  2456. break;
  2457. }
  2458. case VALUE_TYPE_F64:
  2459. {
  2460. if (n_fps < MAX_REG_FLOATS - 1) {
  2461. #if !defined(BUILD_TARGET_RISCV32_ILP32)
  2462. /* 64-bit data must be 8 bytes aligned in arm */
  2463. if (n_fps & 1)
  2464. n_fps++;
  2465. #endif
  2466. *(float64*)&fps[n_fps] = *(float64*)argv_src;
  2467. n_fps += 2;
  2468. argv_src += 2;
  2469. }
  2470. #if defined(BUILD_TARGET_RISCV32_ILP32)
  2471. else if (n_fps == MAX_REG_FLOATS - 1) {
  2472. fps[n_fps++] = *argv_src++;
  2473. stacks[n_stacks++] = *argv_src++;
  2474. }
  2475. #endif
  2476. else {
  2477. /* 64-bit data must be 8 bytes aligned in arm */
  2478. if (n_stacks & 1)
  2479. n_stacks++;
  2480. *(float64*)&stacks[n_stacks] = *(float64*)argv_src;
  2481. n_stacks += 2;
  2482. argv_src += 2;
  2483. }
  2484. break;
  2485. }
  2486. #else /* BUILD_TARGET_RISCV32_ILP32D */
  2487. case VALUE_TYPE_F32:
  2488. case VALUE_TYPE_F64:
  2489. {
  2490. if (n_fps < MAX_REG_FLOATS) {
  2491. if (func_type->types[i] == VALUE_TYPE_F32) {
  2492. *(float32*)&fps[n_fps * 2] = *(float32*)argv_src++;
  2493. /* NaN boxing, the upper bits of a valid NaN-boxed
  2494. value must be all 1s. */
  2495. fps[n_fps * 2 + 1] = 0xFFFFFFFF;
  2496. }
  2497. else {
  2498. *(float64*)&fps[n_fps * 2] = *(float64*)argv_src;
  2499. argv_src += 2;
  2500. }
  2501. n_fps++;
  2502. }
  2503. else if (func_type->types[i] == VALUE_TYPE_F32
  2504. && n_ints < MAX_REG_INTS) {
  2505. /* use int reg firstly if available */
  2506. *(float32*)&ints[n_ints++] = *(float32*)argv_src++;
  2507. }
  2508. else if (func_type->types[i] == VALUE_TYPE_F64
  2509. && n_ints < MAX_REG_INTS - 1) {
  2510. /* use int regs firstly if available */
  2511. if (n_ints & 1)
  2512. n_ints++;
  2513. *(float64*)&ints[n_ints] = *(float64*)argv_src;
  2514. n_ints += 2;
  2515. argv_src += 2;
  2516. }
  2517. else {
  2518. /* 64-bit data in stack must be 8 bytes aligned in riscv32 */
  2519. if (n_stacks & 1)
  2520. n_stacks++;
  2521. if (func_type->types[i] == VALUE_TYPE_F32) {
  2522. *(float32*)&stacks[n_stacks] = *(float32*)argv_src++;
  2523. /* NaN boxing, the upper bits of a valid NaN-boxed
  2524. value must be all 1s. */
  2525. stacks[n_stacks + 1] = 0xFFFFFFFF;
  2526. }
  2527. else {
  2528. *(float64*)&stacks[n_stacks] = *(float64*)argv_src;
  2529. argv_src += 2;
  2530. }
  2531. n_stacks += 2;
  2532. }
  2533. break;
  2534. }
  2535. #endif /* BUILD_TARGET_RISCV32_ILP32D */
  2536. default:
  2537. bh_assert(0);
  2538. break;
  2539. }
  2540. }
  2541. /* Save extra result values' address to argv1 */
  2542. for (i = 0; i < ext_ret_count; i++) {
  2543. if (n_ints < MAX_REG_INTS)
  2544. ints[n_ints++] = *(uint32*)argv_src++;
  2545. else
  2546. stacks[n_stacks++] = *(uint32*)argv_src++;
  2547. }
  2548. exec_env->attachment = attachment;
  2549. if (func_type->result_count == 0) {
  2550. invokeNative_Void(func_ptr, argv1, n_stacks);
  2551. }
  2552. else {
  2553. switch (func_type->types[func_type->param_count]) {
  2554. case VALUE_TYPE_I32:
  2555. #if WASM_ENABLE_REF_TYPES != 0
  2556. case VALUE_TYPE_FUNCREF:
  2557. case VALUE_TYPE_EXTERNREF:
  2558. #endif
  2559. argv_ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
  2560. break;
  2561. case VALUE_TYPE_I64:
  2562. PUT_I64_TO_ADDR(argv_ret, invokeNative_Int64(func_ptr, argv1, n_stacks));
  2563. break;
  2564. case VALUE_TYPE_F32:
  2565. *(float32*)argv_ret = invokeNative_Float32(func_ptr, argv1, n_stacks);
  2566. break;
  2567. case VALUE_TYPE_F64:
  2568. PUT_F64_TO_ADDR(argv_ret, invokeNative_Float64(func_ptr, argv1, n_stacks));
  2569. break;
  2570. default:
  2571. bh_assert(0);
  2572. break;
  2573. }
  2574. }
  2575. exec_env->attachment = NULL;
  2576. ret = !wasm_runtime_get_exception(module) ? true : false;
  2577. fail:
  2578. if (argv1 != argv_buf)
  2579. wasm_runtime_free(argv1);
  2580. return ret;
  2581. }
  2582. #endif /* end of defined(BUILD_TARGET_ARM_VFP)
  2583. || defined(BUILD_TARGET_THUMB_VFP) \
  2584. || defined(BUILD_TARGET_RISCV32_ILP32D)
  2585. || defined(BUILD_TARGET_RISCV32_ILP32) */
  2586. #if defined(BUILD_TARGET_X86_32) \
  2587. || defined(BUILD_TARGET_ARM) \
  2588. || defined(BUILD_TARGET_THUMB) \
  2589. || defined(BUILD_TARGET_MIPS) \
  2590. || defined(BUILD_TARGET_XTENSA)
  2591. typedef void (*GenericFunctionPointer)();
  2592. int64 invokeNative(GenericFunctionPointer f, uint32 *args, uint32 sz);
  2593. typedef float64 (*Float64FuncPtr)(GenericFunctionPointer f, uint32*, uint32);
  2594. typedef float32 (*Float32FuncPtr)(GenericFunctionPointer f, uint32*, uint32);
  2595. typedef int64 (*Int64FuncPtr)(GenericFunctionPointer f, uint32*, uint32);
  2596. typedef int32 (*Int32FuncPtr)(GenericFunctionPointer f, uint32*, uint32);
  2597. typedef void (*VoidFuncPtr)(GenericFunctionPointer f, uint32*, uint32);
  2598. static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative;
  2599. static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative;
  2600. static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative;
  2601. static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative;
  2602. static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
  2603. static inline void
  2604. word_copy(uint32 *dest, uint32 *src, unsigned num)
  2605. {
  2606. for (; num > 0; num--)
  2607. *dest++ = *src++;
  2608. }
  2609. bool
  2610. wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
  2611. const WASMType *func_type, const char *signature,
  2612. void *attachment,
  2613. uint32 *argv, uint32 argc, uint32 *argv_ret)
  2614. {
  2615. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  2616. uint32 argv_buf[32], *argv1 = argv_buf, argc1, i, j = 0;
  2617. uint32 arg_i32, ptr_len;
  2618. uint32 result_count = func_type->result_count;
  2619. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  2620. uint64 size;
  2621. bool ret = false;
  2622. #if defined(BUILD_TARGET_X86_32)
  2623. argc1 = argc + ext_ret_count + 2;
  2624. #else
  2625. /* arm/thumb/mips/xtensa, 64-bit data must be 8 bytes aligned,
  2626. so we need to allocate more memory. */
  2627. argc1 = func_type->param_count * 2 + ext_ret_count + 2;
  2628. #endif
  2629. if (argc1 > sizeof(argv_buf) / sizeof(uint32)) {
  2630. size = sizeof(uint32) * (uint64)argc1;
  2631. if (!(argv1 = runtime_malloc((uint32)size, exec_env->module_inst,
  2632. NULL, 0))) {
  2633. return false;
  2634. }
  2635. }
  2636. for (i = 0; i < sizeof(WASMExecEnv*) / sizeof(uint32); i++)
  2637. argv1[j++] = ((uint32*)&exec_env)[i];
  2638. for (i = 0; i < func_type->param_count; i++) {
  2639. switch (func_type->types[i]) {
  2640. case VALUE_TYPE_I32:
  2641. {
  2642. arg_i32 = *argv++;
  2643. if (signature) {
  2644. if (signature[i + 1] == '*') {
  2645. /* param is a pointer */
  2646. if (signature[i + 2] == '~')
  2647. /* pointer with length followed */
  2648. ptr_len = *argv;
  2649. else
  2650. /* pointer without length followed */
  2651. ptr_len = 1;
  2652. if (!wasm_runtime_validate_app_addr(module, arg_i32, ptr_len))
  2653. goto fail;
  2654. arg_i32 = (uintptr_t)
  2655. wasm_runtime_addr_app_to_native(module, arg_i32);
  2656. }
  2657. else if (signature[i + 1] == '$') {
  2658. /* param is a string */
  2659. if (!wasm_runtime_validate_app_str_addr(module, arg_i32))
  2660. goto fail;
  2661. arg_i32 = (uintptr_t)
  2662. wasm_runtime_addr_app_to_native(module, arg_i32);
  2663. }
  2664. }
  2665. argv1[j++] = arg_i32;
  2666. break;
  2667. }
  2668. case VALUE_TYPE_I64:
  2669. case VALUE_TYPE_F64:
  2670. #if !defined(BUILD_TARGET_X86_32)
  2671. /* 64-bit data must be 8 bytes aligned in arm, thumb, mips
  2672. and xtensa */
  2673. if (j & 1)
  2674. j++;
  2675. #endif
  2676. argv1[j++] = *argv++;
  2677. argv1[j++] = *argv++;
  2678. break;
  2679. case VALUE_TYPE_F32:
  2680. #if WASM_ENABLE_REF_TYPES != 0
  2681. case VALUE_TYPE_FUNCREF:
  2682. case VALUE_TYPE_EXTERNREF:
  2683. #endif
  2684. argv1[j++] = *argv++;
  2685. break;
  2686. default:
  2687. bh_assert(0);
  2688. break;
  2689. }
  2690. }
  2691. /* Save extra result values' address to argv1 */
  2692. word_copy(argv1 + j, argv, ext_ret_count);
  2693. argc1 = j + ext_ret_count;
  2694. exec_env->attachment = attachment;
  2695. if (func_type->result_count == 0) {
  2696. invokeNative_Void(func_ptr, argv1, argc1);
  2697. }
  2698. else {
  2699. switch (func_type->types[func_type->param_count]) {
  2700. case VALUE_TYPE_I32:
  2701. #if WASM_ENABLE_REF_TYPES != 0
  2702. case VALUE_TYPE_FUNCREF:
  2703. case VALUE_TYPE_EXTERNREF:
  2704. #endif
  2705. argv_ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, argc1);
  2706. break;
  2707. case VALUE_TYPE_I64:
  2708. PUT_I64_TO_ADDR(argv_ret, invokeNative_Int64(func_ptr, argv1, argc1));
  2709. break;
  2710. case VALUE_TYPE_F32:
  2711. *(float32*)argv_ret = invokeNative_Float32(func_ptr, argv1, argc1);
  2712. break;
  2713. case VALUE_TYPE_F64:
  2714. PUT_F64_TO_ADDR(argv_ret, invokeNative_Float64(func_ptr, argv1, argc1));
  2715. break;
  2716. default:
  2717. bh_assert(0);
  2718. break;
  2719. }
  2720. }
  2721. exec_env->attachment = NULL;
  2722. ret = !wasm_runtime_get_exception(module) ? true : false;
  2723. fail:
  2724. if (argv1 != argv_buf)
  2725. wasm_runtime_free(argv1);
  2726. return ret;
  2727. }
  2728. #endif /* end of defined(BUILD_TARGET_X86_32) \
  2729. || defined(BUILD_TARGET_ARM) \
  2730. || defined(BUILD_TARGET_THUMB) \
  2731. || defined(BUILD_TARGET_MIPS) \
  2732. || defined(BUILD_TARGET_XTENSA) */
  2733. #if defined(BUILD_TARGET_X86_64) \
  2734. || defined(BUILD_TARGET_AMD_64) \
  2735. || defined(BUILD_TARGET_AARCH64) \
  2736. || defined(BUILD_TARGET_RISCV64_LP64D) \
  2737. || defined(BUILD_TARGET_RISCV64_LP64)
  2738. #if WASM_ENABLE_SIMD != 0
  2739. #ifdef v128
  2740. #undef v128
  2741. #endif
  2742. #if defined(_WIN32) || defined(_WIN32_)
  2743. typedef union __declspec(intrin_type) __declspec(align(8)) v128 {
  2744. __int8 m128i_i8[16];
  2745. __int16 m128i_i16[8];
  2746. __int32 m128i_i32[4];
  2747. __int64 m128i_i64[2];
  2748. unsigned __int8 m128i_u8[16];
  2749. unsigned __int16 m128i_u16[8];
  2750. unsigned __int32 m128i_u32[4];
  2751. unsigned __int64 m128i_u64[2];
  2752. } v128;
  2753. #elif defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  2754. || defined(BUILD_TARGET_RISCV64_LP64D) || defined(BUILD_TARGET_RISCV64_LP64)
  2755. typedef long long v128 __attribute__ ((__vector_size__ (16),
  2756. __may_alias__, __aligned__ (1)));
  2757. #elif defined(BUILD_TARGET_AARCH64)
  2758. #include <arm_neon.h>
  2759. typedef uint32x4_t __m128i;
  2760. #define v128 __m128i
  2761. #endif
  2762. #endif /* end of WASM_ENABLE_SIMD != 0 */
  2763. typedef void (*GenericFunctionPointer)();
  2764. int64 invokeNative(GenericFunctionPointer f, uint64 *args, uint64 n_stacks);
  2765. typedef float64 (*Float64FuncPtr)(GenericFunctionPointer, uint64*, uint64);
  2766. typedef float32 (*Float32FuncPtr)(GenericFunctionPointer, uint64*, uint64);
  2767. typedef int64 (*Int64FuncPtr)(GenericFunctionPointer, uint64*, uint64);
  2768. typedef int32 (*Int32FuncPtr)(GenericFunctionPointer, uint64*, uint64);
  2769. typedef void (*VoidFuncPtr)(GenericFunctionPointer, uint64*, uint64);
  2770. static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)(uintptr_t)invokeNative;
  2771. static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)(uintptr_t)invokeNative;
  2772. static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)(uintptr_t)invokeNative;
  2773. static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)(uintptr_t)invokeNative;
  2774. static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)(uintptr_t)invokeNative;
  2775. #if WASM_ENABLE_SIMD != 0
  2776. typedef v128 (*V128FuncPtr)(GenericFunctionPointer, uint64*, uint64);
  2777. static V128FuncPtr invokeNative_V128 = (V128FuncPtr)(uintptr_t)invokeNative;
  2778. #endif
  2779. #if defined(_WIN32) || defined(_WIN32_)
  2780. #define MAX_REG_FLOATS 4
  2781. #define MAX_REG_INTS 4
  2782. #else /* else of defined(_WIN32) || defined(_WIN32_) */
  2783. #define MAX_REG_FLOATS 8
  2784. #if defined(BUILD_TARGET_AARCH64) \
  2785. || defined(BUILD_TARGET_RISCV64_LP64D) \
  2786. || defined(BUILD_TARGET_RISCV64_LP64)
  2787. #define MAX_REG_INTS 8
  2788. #else
  2789. #define MAX_REG_INTS 6
  2790. #endif /* end of defined(BUILD_TARGET_AARCH64) \
  2791. || defined(BUILD_TARGET_RISCV64_LP64D) \
  2792. || defined(BUILD_TARGET_RISCV64_LP64) */
  2793. #endif /* end of defined(_WIN32) || defined(_WIN32_) */
  2794. bool
  2795. wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
  2796. const WASMType *func_type, const char *signature,
  2797. void *attachment,
  2798. uint32 *argv, uint32 argc, uint32 *argv_ret)
  2799. {
  2800. WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
  2801. uint64 argv_buf[32], *argv1 = argv_buf, *ints, *stacks, size, arg_i64;
  2802. uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0;
  2803. uint32 arg_i32, ptr_len;
  2804. uint32 result_count = func_type->result_count;
  2805. uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
  2806. bool ret = false;
  2807. #ifndef BUILD_TARGET_RISCV64_LP64
  2808. #if WASM_ENABLE_SIMD == 0
  2809. uint64 *fps;
  2810. #else
  2811. v128 *fps;
  2812. #endif
  2813. #else /* else of BUILD_TARGET_RISCV64_LP64 */
  2814. #define fps ints
  2815. #endif /* end of BUILD_TARGET_RISCV64_LP64 */
  2816. #if defined(_WIN32) || defined(_WIN32_) || defined(BUILD_TARGET_RISCV64_LP64)
  2817. /* important difference in calling conventions */
  2818. #define n_fps n_ints
  2819. #else
  2820. int n_fps = 0;
  2821. #endif
  2822. #if WASM_ENABLE_SIMD == 0
  2823. argc1 = 1 + MAX_REG_FLOATS + (uint32)func_type->param_count
  2824. + ext_ret_count;
  2825. #else
  2826. argc1 = 1 + MAX_REG_FLOATS * 2 + (uint32)func_type->param_count * 2
  2827. + ext_ret_count;
  2828. #endif
  2829. if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
  2830. size = sizeof(uint64) * (uint64)argc1;
  2831. if (!(argv1 = runtime_malloc((uint32)size, exec_env->module_inst,
  2832. NULL, 0))) {
  2833. return false;
  2834. }
  2835. }
  2836. #ifndef BUILD_TARGET_RISCV64_LP64
  2837. #if WASM_ENABLE_SIMD == 0
  2838. fps = argv1;
  2839. ints = fps + MAX_REG_FLOATS;
  2840. #else
  2841. fps = (v128 *)argv1;
  2842. ints = (uint64 *)(fps + MAX_REG_FLOATS);
  2843. #endif
  2844. #else /* else of BUILD_TARGET_RISCV64_LP64 */
  2845. ints = argv1;
  2846. #endif /* end of BUILD_TARGET_RISCV64_LP64 */
  2847. stacks = ints + MAX_REG_INTS;
  2848. ints[n_ints++] = (uint64)(uintptr_t)exec_env;
  2849. for (i = 0; i < func_type->param_count; i++) {
  2850. switch (func_type->types[i]) {
  2851. case VALUE_TYPE_I32:
  2852. {
  2853. arg_i32 = *argv_src++;
  2854. arg_i64 = arg_i32;
  2855. if (signature) {
  2856. if (signature[i + 1] == '*') {
  2857. /* param is a pointer */
  2858. if (signature[i + 2] == '~')
  2859. /* pointer with length followed */
  2860. ptr_len = *argv_src;
  2861. else
  2862. /* pointer without length followed */
  2863. ptr_len = 1;
  2864. if (!wasm_runtime_validate_app_addr(module, arg_i32, ptr_len))
  2865. goto fail;
  2866. arg_i64 = (uintptr_t)
  2867. wasm_runtime_addr_app_to_native(module, arg_i32);
  2868. }
  2869. else if (signature[i + 1] == '$') {
  2870. /* param is a string */
  2871. if (!wasm_runtime_validate_app_str_addr(module, arg_i32))
  2872. goto fail;
  2873. arg_i64 = (uintptr_t)
  2874. wasm_runtime_addr_app_to_native(module, arg_i32);
  2875. }
  2876. }
  2877. if (n_ints < MAX_REG_INTS)
  2878. ints[n_ints++] = arg_i64;
  2879. else
  2880. stacks[n_stacks++] = arg_i64;
  2881. break;
  2882. }
  2883. case VALUE_TYPE_I64:
  2884. if (n_ints < MAX_REG_INTS)
  2885. ints[n_ints++] = *(uint64*)argv_src;
  2886. else
  2887. stacks[n_stacks++] = *(uint64*)argv_src;
  2888. argv_src += 2;
  2889. break;
  2890. case VALUE_TYPE_F32:
  2891. if (n_fps < MAX_REG_FLOATS) {
  2892. *(float32*)&fps[n_fps++] = *(float32*)argv_src++;
  2893. }
  2894. else {
  2895. *(float32*)&stacks[n_stacks++] = *(float32*)argv_src++;
  2896. }
  2897. break;
  2898. case VALUE_TYPE_F64:
  2899. if (n_fps < MAX_REG_FLOATS) {
  2900. *(float64*)&fps[n_fps++] = *(float64*)argv_src;
  2901. }
  2902. else {
  2903. *(float64*)&stacks[n_stacks++] = *(float64*)argv_src;
  2904. }
  2905. argv_src += 2;
  2906. break;
  2907. #if WASM_ENABLE_REF_TYPES != 0
  2908. case VALUE_TYPE_FUNCREF:
  2909. case VALUE_TYPE_EXTERNREF:
  2910. if (n_ints < MAX_REG_INTS)
  2911. ints[n_ints++] = *argv_src++;
  2912. else
  2913. stacks[n_stacks++] = *argv_src++;
  2914. break;
  2915. #endif
  2916. #if WASM_ENABLE_SIMD != 0
  2917. case VALUE_TYPE_V128:
  2918. if (n_fps < MAX_REG_FLOATS) {
  2919. *(v128*)&fps[n_fps++] = *(v128*)argv_src;
  2920. }
  2921. else {
  2922. *(v128*)&stacks[n_stacks++] = *(v128*)argv_src;
  2923. n_stacks++;
  2924. }
  2925. argv_src += 4;
  2926. break;
  2927. #endif
  2928. default:
  2929. bh_assert(0);
  2930. break;
  2931. }
  2932. }
  2933. /* Save extra result values' address to argv1 */
  2934. for (i = 0; i < ext_ret_count; i++) {
  2935. if (n_ints < MAX_REG_INTS)
  2936. ints[n_ints++] = *(uint64*)argv_src;
  2937. else
  2938. stacks[n_stacks++] = *(uint64*)argv_src;
  2939. argv_src += 2;
  2940. }
  2941. exec_env->attachment = attachment;
  2942. if (result_count == 0) {
  2943. invokeNative_Void(func_ptr, argv1, n_stacks);
  2944. }
  2945. else {
  2946. /* Invoke the native function and get the first result value */
  2947. switch (func_type->types[func_type->param_count]) {
  2948. case VALUE_TYPE_I32:
  2949. #if WASM_ENABLE_REF_TYPES != 0
  2950. case VALUE_TYPE_FUNCREF:
  2951. case VALUE_TYPE_EXTERNREF:
  2952. #endif
  2953. argv_ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
  2954. break;
  2955. case VALUE_TYPE_I64:
  2956. PUT_I64_TO_ADDR(argv_ret, invokeNative_Int64(func_ptr, argv1, n_stacks));
  2957. break;
  2958. case VALUE_TYPE_F32:
  2959. *(float32*)argv_ret = invokeNative_Float32(func_ptr, argv1, n_stacks);
  2960. break;
  2961. case VALUE_TYPE_F64:
  2962. PUT_F64_TO_ADDR(argv_ret, invokeNative_Float64(func_ptr, argv1, n_stacks));
  2963. break;
  2964. #if WASM_ENABLE_SIMD != 0
  2965. case VALUE_TYPE_V128:
  2966. *(v128*)argv_ret = invokeNative_V128(func_ptr, argv1, n_stacks);
  2967. break;
  2968. #endif
  2969. default:
  2970. bh_assert(0);
  2971. break;
  2972. }
  2973. }
  2974. exec_env->attachment = NULL;
  2975. ret = !wasm_runtime_get_exception(module) ? true : false;
  2976. fail:
  2977. if (argv1 != argv_buf)
  2978. wasm_runtime_free(argv1);
  2979. return ret;
  2980. }
  2981. #endif /* end of defined(BUILD_TARGET_X86_64) \
  2982. || defined(BUILD_TARGET_AMD_64) \
  2983. || defined(BUILD_TARGET_AARCH64) \
  2984. || defined(BUILD_TARGET_RISCV64_LP64D) \
  2985. || defined(BUILD_TARGET_RISCV64_LP64) */
  2986. bool
  2987. wasm_runtime_call_indirect(WASMExecEnv *exec_env,
  2988. uint32_t element_indices,
  2989. uint32_t argc, uint32_t argv[])
  2990. {
  2991. if (!wasm_runtime_exec_env_check(exec_env)) {
  2992. LOG_ERROR("Invalid exec env stack info.");
  2993. return false;
  2994. }
  2995. /* this function is called from native code, so exec_env->handle and
  2996. exec_env->native_stack_boundary must have been set, we don't set
  2997. it again */
  2998. #if WASM_ENABLE_INTERP != 0
  2999. if (exec_env->module_inst->module_type == Wasm_Module_Bytecode)
  3000. return wasm_call_indirect(exec_env, 0, element_indices, argc, argv);
  3001. #endif
  3002. #if WASM_ENABLE_AOT != 0
  3003. if (exec_env->module_inst->module_type == Wasm_Module_AoT)
  3004. return aot_call_indirect(exec_env, 0, element_indices, argc, argv);
  3005. #endif
  3006. return false;
  3007. }
  3008. static void
  3009. exchange_uint32(uint8 *p_data)
  3010. {
  3011. uint8 value = *p_data;
  3012. *p_data = *(p_data + 3);
  3013. *(p_data + 3) = value;
  3014. value = *(p_data + 1);
  3015. *(p_data + 1) = *(p_data + 2);
  3016. *(p_data + 2) = value;
  3017. }
  3018. static void
  3019. exchange_uint64(uint8 *p_data)
  3020. {
  3021. uint32 value;
  3022. value = *(uint32 *)p_data;
  3023. *(uint32 *)p_data = *(uint32 *)(p_data + 4);
  3024. *(uint32 *)(p_data + 4) = value;
  3025. exchange_uint32(p_data);
  3026. exchange_uint32(p_data + 4);
  3027. }
  3028. void
  3029. wasm_runtime_read_v128(const uint8 *bytes, uint64 *ret1, uint64 *ret2)
  3030. {
  3031. uint64 u1, u2;
  3032. bh_memcpy_s(&u1, 8, bytes, 8);
  3033. bh_memcpy_s(&u2, 8, bytes + 8, 8);
  3034. if (!is_little_endian()) {
  3035. exchange_uint64((uint8*)&u1);
  3036. exchange_uint64((uint8*)&u2);
  3037. *ret1 = u2;
  3038. *ret2 = u1;
  3039. }
  3040. else {
  3041. *ret1 = u1;
  3042. *ret2 = u2;
  3043. }
  3044. }
  3045. #if WASM_ENABLE_THREAD_MGR != 0
  3046. typedef struct WASMThreadArg {
  3047. WASMExecEnv *new_exec_env;
  3048. wasm_thread_callback_t callback;
  3049. void *arg;
  3050. } WASMThreadArg;
  3051. WASMExecEnv *
  3052. wasm_runtime_spawn_exec_env(WASMExecEnv *exec_env)
  3053. {
  3054. return wasm_cluster_spawn_exec_env(exec_env);
  3055. }
  3056. void
  3057. wasm_runtime_destroy_spawned_exec_env(WASMExecEnv *exec_env)
  3058. {
  3059. wasm_cluster_destroy_spawned_exec_env(exec_env);
  3060. }
  3061. static void*
  3062. wasm_runtime_thread_routine(void *arg)
  3063. {
  3064. WASMThreadArg *thread_arg = (WASMThreadArg *)arg;
  3065. void *ret;
  3066. bh_assert(thread_arg->new_exec_env);
  3067. ret = thread_arg->callback(thread_arg->new_exec_env, thread_arg->arg);
  3068. wasm_runtime_destroy_spawned_exec_env(thread_arg->new_exec_env);
  3069. wasm_runtime_free(thread_arg);
  3070. os_thread_exit(ret);
  3071. return ret;
  3072. }
  3073. int32
  3074. wasm_runtime_spawn_thread(WASMExecEnv *exec_env, wasm_thread_t *tid,
  3075. wasm_thread_callback_t callback, void *arg)
  3076. {
  3077. WASMExecEnv *new_exec_env = wasm_runtime_spawn_exec_env(exec_env);
  3078. WASMThreadArg *thread_arg;
  3079. int32 ret;
  3080. if (!new_exec_env)
  3081. return -1;
  3082. if (!(thread_arg = wasm_runtime_malloc(sizeof(WASMThreadArg)))) {
  3083. wasm_runtime_destroy_spawned_exec_env(new_exec_env);
  3084. return -1;
  3085. }
  3086. thread_arg->new_exec_env = new_exec_env;
  3087. thread_arg->callback = callback;
  3088. thread_arg->arg = arg;
  3089. ret = os_thread_create((korp_tid *)tid, wasm_runtime_thread_routine,
  3090. thread_arg, APP_THREAD_STACK_SIZE_DEFAULT);
  3091. if (ret != 0) {
  3092. wasm_runtime_destroy_spawned_exec_env(new_exec_env);
  3093. wasm_runtime_free(thread_arg);
  3094. }
  3095. return ret;
  3096. }
  3097. int32
  3098. wasm_runtime_join_thread(wasm_thread_t tid, void **retval)
  3099. {
  3100. return os_thread_join((korp_tid)tid, retval);
  3101. }
  3102. #endif /* end of WASM_ENABLE_THREAD_MGR */
  3103. #if WASM_ENABLE_REF_TYPES != 0
  3104. static korp_mutex externref_lock;
  3105. static uint32 externref_global_id = 1;
  3106. static HashMap *externref_map;
  3107. typedef struct ExternRefMapNode {
  3108. /* The extern object from runtime embedder */
  3109. void *extern_obj;
  3110. /* The module instance it belongs to */
  3111. WASMModuleInstanceCommon *module_inst;
  3112. /* Whether it is retained */
  3113. bool retained;
  3114. /* Whether it is marked by runtime */
  3115. bool marked;
  3116. } ExternRefMapNode;
  3117. static uint32
  3118. wasm_externref_hash(const void *key)
  3119. {
  3120. uint32 externref_idx = (uint32)(uintptr_t)key;
  3121. return externref_idx;
  3122. }
  3123. static bool
  3124. wasm_externref_equal(void *key1, void *key2)
  3125. {
  3126. uint32 externref_idx1 = (uint32)(uintptr_t)key1;
  3127. uint32 externref_idx2 = (uint32)(uintptr_t)key2;
  3128. return externref_idx1 == externref_idx2 ? true : false;
  3129. }
  3130. static bool
  3131. wasm_externref_map_init()
  3132. {
  3133. if (os_mutex_init(&externref_lock) != 0)
  3134. return false;
  3135. if (!(externref_map = bh_hash_map_create(32, false,
  3136. wasm_externref_hash,
  3137. wasm_externref_equal,
  3138. NULL,
  3139. wasm_runtime_free))) {
  3140. os_mutex_destroy(&externref_lock);
  3141. return false;
  3142. }
  3143. externref_global_id = 1;
  3144. return true;
  3145. }
  3146. static void
  3147. wasm_externref_map_destroy()
  3148. {
  3149. bh_hash_map_destroy(externref_map);
  3150. os_mutex_destroy(&externref_lock);
  3151. }
  3152. typedef struct LookupExtObj_UserData {
  3153. ExternRefMapNode node;
  3154. bool found;
  3155. uint32 externref_idx;
  3156. } LookupExtObj_UserData;
  3157. static void
  3158. lookup_extobj_callback(void *key, void *value, void *user_data)
  3159. {
  3160. uint32 externref_idx = (uint32)(uintptr_t)key;
  3161. ExternRefMapNode *node = (ExternRefMapNode *)value;
  3162. LookupExtObj_UserData *user_data_lookup = (LookupExtObj_UserData *)
  3163. user_data;
  3164. if (node->extern_obj == user_data_lookup->node.extern_obj
  3165. && node->module_inst == user_data_lookup->node.module_inst) {
  3166. user_data_lookup->found = true;
  3167. user_data_lookup->externref_idx = externref_idx;
  3168. }
  3169. }
  3170. bool
  3171. wasm_externref_obj2ref(WASMModuleInstanceCommon *module_inst,
  3172. void *extern_obj, uint32 *p_externref_idx)
  3173. {
  3174. LookupExtObj_UserData lookup_user_data;
  3175. ExternRefMapNode *node;
  3176. uint32 externref_idx;
  3177. lookup_user_data.node.extern_obj = extern_obj;
  3178. lookup_user_data.node.module_inst = module_inst;
  3179. lookup_user_data.found = false;
  3180. os_mutex_lock(&externref_lock);
  3181. /* Lookup hashmap firstly */
  3182. bh_hash_map_traverse(externref_map, lookup_extobj_callback,
  3183. (void*)&lookup_user_data);
  3184. if (lookup_user_data.found) {
  3185. *p_externref_idx = lookup_user_data.externref_idx;
  3186. os_mutex_unlock(&externref_lock);
  3187. return true;
  3188. }
  3189. /* Not found in hashmap */
  3190. if (externref_global_id == NULL_REF
  3191. || externref_global_id == 0) {
  3192. goto fail1;
  3193. }
  3194. if (!(node = wasm_runtime_malloc(sizeof(ExternRefMapNode)))) {
  3195. goto fail1;
  3196. }
  3197. memset(node, 0, sizeof(ExternRefMapNode));
  3198. node->extern_obj = extern_obj;
  3199. node->module_inst = module_inst;
  3200. externref_idx = externref_global_id;
  3201. if (!bh_hash_map_insert(externref_map,
  3202. (void*)(uintptr_t)externref_idx,
  3203. (void*)node)) {
  3204. goto fail2;
  3205. }
  3206. externref_global_id++;
  3207. *p_externref_idx = externref_idx;
  3208. os_mutex_unlock(&externref_lock);
  3209. return true;
  3210. fail2:
  3211. wasm_runtime_free(node);
  3212. fail1:
  3213. os_mutex_unlock(&externref_lock);
  3214. return false;
  3215. }
  3216. bool
  3217. wasm_externref_ref2obj(uint32 externref_idx, void **p_extern_obj)
  3218. {
  3219. ExternRefMapNode *node;
  3220. if (externref_idx == NULL_REF) {
  3221. return false;
  3222. }
  3223. os_mutex_lock(&externref_lock);
  3224. node = bh_hash_map_find(externref_map,
  3225. (void*)(uintptr_t)externref_idx);
  3226. os_mutex_unlock(&externref_lock);
  3227. if (!node)
  3228. return false;
  3229. *p_extern_obj = node->extern_obj;
  3230. return true;
  3231. }
  3232. static void
  3233. reclaim_extobj_callback(void *key, void *value, void *user_data)
  3234. {
  3235. ExternRefMapNode *node = (ExternRefMapNode *)value;
  3236. WASMModuleInstanceCommon *module_inst = (WASMModuleInstanceCommon *)
  3237. user_data;
  3238. if (node->module_inst == module_inst) {
  3239. if (!node->marked && !node->retained) {
  3240. bh_hash_map_remove(externref_map, key, NULL, NULL);
  3241. wasm_runtime_free(value);
  3242. }
  3243. else {
  3244. node->marked = false;
  3245. }
  3246. }
  3247. }
  3248. static void
  3249. mark_externref(uint32 externref_idx)
  3250. {
  3251. ExternRefMapNode *node;
  3252. if (externref_idx != NULL_REF) {
  3253. node = bh_hash_map_find(externref_map,
  3254. (void*)(uintptr_t)externref_idx);
  3255. if (node) {
  3256. node->marked = true;
  3257. }
  3258. }
  3259. }
  3260. #if WASM_ENABLE_INTERP != 0
  3261. static void
  3262. interp_mark_all_externrefs(WASMModuleInstance *module_inst)
  3263. {
  3264. uint32 i, j, externref_idx, *table_data;
  3265. uint8 *global_data = module_inst->global_data;
  3266. WASMGlobalInstance *global;
  3267. WASMTableInstance *table;
  3268. global = module_inst->globals;
  3269. for (i = 0; i < module_inst->global_count; i++, global++) {
  3270. if (global->type == VALUE_TYPE_EXTERNREF) {
  3271. externref_idx = *(uint32*)(global_data + global->data_offset);
  3272. mark_externref(externref_idx);
  3273. }
  3274. }
  3275. for (i = 0; i < module_inst->table_count; i++) {
  3276. table = wasm_get_table_inst(module_inst, i);
  3277. if (table->elem_type == VALUE_TYPE_EXTERNREF) {
  3278. table_data = (uint32 *)table->base_addr;
  3279. for (j = 0; j < table->cur_size; j++) {
  3280. externref_idx = table_data[j];
  3281. mark_externref(externref_idx);
  3282. }
  3283. }
  3284. }
  3285. }
  3286. #endif
  3287. #if WASM_ENABLE_AOT != 0
  3288. static void
  3289. aot_mark_all_externrefs(AOTModuleInstance *module_inst)
  3290. {
  3291. uint32 i = 0, j = 0;
  3292. const AOTModule *module = (AOTModule *)(module_inst->aot_module.ptr);
  3293. const AOTTable *table = module->tables;
  3294. const AOTGlobal *global = module->globals;
  3295. const AOTTableInstance *table_inst =
  3296. (AOTTableInstance *)module_inst->tables.ptr;
  3297. for (i = 0; i < module->global_count; i++, global++) {
  3298. if (global->type == VALUE_TYPE_EXTERNREF) {
  3299. mark_externref(*(uint32 *)((uint8 *)module_inst->global_data.ptr
  3300. + global->data_offset));
  3301. }
  3302. }
  3303. for (i = 0; i < module->table_count;
  3304. i++, table_inst = aot_next_tbl_inst(table_inst)) {
  3305. if ((table + i)->elem_type == VALUE_TYPE_EXTERNREF) {
  3306. while (j < table_inst->cur_size) {
  3307. mark_externref(table_inst->data[j++]);
  3308. }
  3309. }
  3310. }
  3311. }
  3312. #endif
  3313. void
  3314. wasm_externref_reclaim(WASMModuleInstanceCommon *module_inst)
  3315. {
  3316. os_mutex_lock(&externref_lock);
  3317. #if WASM_ENABLE_INTERP != 0
  3318. if (module_inst->module_type == Wasm_Module_Bytecode)
  3319. interp_mark_all_externrefs((WASMModuleInstance*)module_inst);
  3320. #endif
  3321. #if WASM_ENABLE_AOT != 0
  3322. if (module_inst->module_type == Wasm_Module_AoT)
  3323. aot_mark_all_externrefs((AOTModuleInstance*)module_inst);
  3324. #endif
  3325. bh_hash_map_traverse(externref_map, reclaim_extobj_callback,
  3326. (void*)module_inst);
  3327. os_mutex_unlock(&externref_lock);
  3328. }
  3329. static void
  3330. cleanup_extobj_callback(void *key, void *value, void *user_data)
  3331. {
  3332. ExternRefMapNode *node = (ExternRefMapNode *)value;
  3333. WASMModuleInstanceCommon *module_inst = (WASMModuleInstanceCommon *)
  3334. user_data;
  3335. if (node->module_inst == module_inst) {
  3336. bh_hash_map_remove(externref_map, key, NULL, NULL);
  3337. wasm_runtime_free(value);
  3338. }
  3339. }
  3340. void
  3341. wasm_externref_cleanup(WASMModuleInstanceCommon *module_inst)
  3342. {
  3343. os_mutex_lock(&externref_lock);
  3344. bh_hash_map_traverse(externref_map, cleanup_extobj_callback,
  3345. (void*)module_inst);
  3346. os_mutex_unlock(&externref_lock);
  3347. }
  3348. bool
  3349. wasm_externref_retain(uint32 externref_idx)
  3350. {
  3351. ExternRefMapNode *node;
  3352. os_mutex_lock(&externref_lock);
  3353. if (externref_idx != NULL_REF) {
  3354. node = bh_hash_map_find(externref_map,
  3355. (void*)(uintptr_t)externref_idx);
  3356. if (node) {
  3357. node->retained = true;
  3358. os_mutex_unlock(&externref_lock);
  3359. return true;
  3360. }
  3361. }
  3362. os_mutex_unlock(&externref_lock);
  3363. return false;
  3364. }
  3365. #endif /* end of WASM_ENABLE_REF_TYPES */
  3366. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  3367. void
  3368. wasm_runtime_dump_call_stack(WASMExecEnv *exec_env)
  3369. {
  3370. WASMModuleInstanceCommon *module_inst
  3371. = wasm_exec_env_get_module_inst(exec_env);
  3372. #if WASM_ENABLE_INTERP != 0
  3373. if (module_inst->module_type == Wasm_Module_Bytecode) {
  3374. wasm_interp_dump_call_stack(exec_env);
  3375. }
  3376. #endif
  3377. #if WASM_ENABLE_AOT != 0
  3378. if (module_inst->module_type == Wasm_Module_AoT) {
  3379. aot_dump_call_stack(exec_env);
  3380. }
  3381. #endif
  3382. }
  3383. #endif /* end of WASM_ENABLE_DUMP_CALL_STACK */
  3384. bool
  3385. wasm_runtime_get_export_func_type(const WASMModuleCommon *module_comm,
  3386. const WASMExport *export,
  3387. WASMType **out)
  3388. {
  3389. #if WASM_ENABLE_INTERP != 0
  3390. if (module_comm->module_type == Wasm_Module_Bytecode) {
  3391. WASMModule *module = (WASMModule *)module_comm;
  3392. if (export->index < module->import_function_count) {
  3393. *out =
  3394. module->import_functions[export->index].u.function.func_type;
  3395. }
  3396. else {
  3397. *out =
  3398. module->functions[export->index - module->import_function_count]
  3399. ->func_type;
  3400. }
  3401. return true;
  3402. }
  3403. #endif
  3404. #if WASM_ENABLE_AOT != 0
  3405. if (module_comm->module_type == Wasm_Module_AoT) {
  3406. AOTModule *module = (AOTModule *)module_comm;
  3407. if (export->index < module->import_func_count) {
  3408. *out = module->func_types[module->import_funcs[export->index]
  3409. .func_type_index];
  3410. }
  3411. else {
  3412. *out =
  3413. module->func_types[module->func_type_indexes
  3414. [export->index - module->import_func_count]];
  3415. }
  3416. return true;
  3417. }
  3418. #endif
  3419. return false;
  3420. }
  3421. bool
  3422. wasm_runtime_get_export_global_type(const WASMModuleCommon *module_comm,
  3423. const WASMExport *export,
  3424. uint8 *out_val_type,
  3425. bool *out_mutability)
  3426. {
  3427. #if WASM_ENABLE_INTERP != 0
  3428. if (module_comm->module_type == Wasm_Module_Bytecode) {
  3429. WASMModule *module = (WASMModule *)module_comm;
  3430. if (export->index < module->import_global_count) {
  3431. WASMGlobalImport *import_global =
  3432. &((module->import_globals + export->index)->u.global);
  3433. *out_val_type = import_global->type;
  3434. *out_mutability = import_global->is_mutable;
  3435. }
  3436. else {
  3437. WASMGlobal *global =
  3438. module->globals + (export->index - module->import_global_count);
  3439. *out_val_type = global->type;
  3440. *out_mutability = global->is_mutable;
  3441. }
  3442. return true;
  3443. }
  3444. #endif
  3445. #if WASM_ENABLE_AOT != 0
  3446. if (module_comm->module_type == Wasm_Module_AoT) {
  3447. AOTModule *module = (AOTModule *)module_comm;
  3448. if (export->index < module->import_global_count) {
  3449. AOTImportGlobal *import_global =
  3450. module->import_globals + export->index;
  3451. *out_val_type = import_global->type;
  3452. *out_mutability = import_global->is_mutable;
  3453. }
  3454. else {
  3455. AOTGlobal *global =
  3456. module->globals + (export->index - module->import_global_count);
  3457. *out_val_type = global->type;
  3458. *out_mutability = global->is_mutable;
  3459. }
  3460. return true;
  3461. }
  3462. #endif
  3463. return false;
  3464. }
  3465. bool
  3466. wasm_runtime_get_export_memory_type(const WASMModuleCommon *module_comm,
  3467. const WASMExport *export,
  3468. uint32 *out_min_page,
  3469. uint32 *out_max_page)
  3470. {
  3471. #if WASM_ENABLE_INTERP != 0
  3472. if (module_comm->module_type == Wasm_Module_Bytecode) {
  3473. WASMModule *module = (WASMModule *)module_comm;
  3474. if (export->index < module->import_memory_count) {
  3475. WASMMemoryImport *import_memory =
  3476. &((module->import_memories + export->index)->u.memory);
  3477. *out_min_page = import_memory->init_page_count;
  3478. *out_max_page = import_memory->max_page_count;
  3479. }
  3480. else {
  3481. WASMMemory *memory =
  3482. module->memories + (export->index - module->import_memory_count);
  3483. *out_min_page = memory->init_page_count;
  3484. *out_max_page = memory->max_page_count;
  3485. }
  3486. return true;
  3487. }
  3488. #endif
  3489. #if WASM_ENABLE_AOT != 0
  3490. if (module_comm->module_type == Wasm_Module_AoT) {
  3491. AOTModule *module = (AOTModule *)module_comm;
  3492. if (export->index < module->import_memory_count) {
  3493. AOTImportMemory *import_memory =
  3494. module->import_memories + export->index;
  3495. *out_min_page = import_memory->mem_init_page_count;
  3496. *out_max_page = import_memory->mem_max_page_count;
  3497. }
  3498. else {
  3499. AOTMemory *memory =
  3500. module->memories + (export->index - module->import_memory_count);
  3501. *out_min_page = memory->mem_init_page_count;
  3502. *out_max_page = memory->mem_max_page_count;
  3503. }
  3504. return true;
  3505. }
  3506. #endif
  3507. return false;
  3508. }
  3509. bool
  3510. wasm_runtime_get_export_table_type(const WASMModuleCommon *module_comm,
  3511. const WASMExport *export,
  3512. uint8 *out_elem_type,
  3513. uint32 *out_min_size,
  3514. uint32 *out_max_size)
  3515. {
  3516. #if WASM_ENABLE_INTERP != 0
  3517. if (module_comm->module_type == Wasm_Module_Bytecode) {
  3518. WASMModule *module = (WASMModule *)module_comm;
  3519. if (export->index < module->import_table_count) {
  3520. WASMTableImport *import_table =
  3521. &((module->import_tables + export->index)->u.table);
  3522. *out_elem_type = import_table->elem_type;
  3523. *out_min_size = import_table->init_size;
  3524. *out_max_size = import_table->max_size;
  3525. }
  3526. else {
  3527. WASMTable *table =
  3528. module->tables + (export->index - module->import_table_count);
  3529. *out_elem_type = table->elem_type;
  3530. *out_min_size = table->init_size;
  3531. *out_max_size = table->max_size;
  3532. }
  3533. return true;
  3534. }
  3535. #endif
  3536. #if WASM_ENABLE_AOT != 0
  3537. if (module_comm->module_type == Wasm_Module_AoT) {
  3538. AOTModule *module = (AOTModule *)module_comm;
  3539. if (export->index < module->import_table_count) {
  3540. AOTImportTable *import_table =
  3541. module->import_tables + export->index;
  3542. *out_elem_type = VALUE_TYPE_FUNCREF;
  3543. *out_min_size = import_table->table_init_size;
  3544. *out_max_size = import_table->table_max_size;
  3545. }
  3546. else {
  3547. AOTTable *table =
  3548. module->tables + (export->index - module->import_table_count);
  3549. *out_elem_type = table->elem_type;
  3550. *out_min_size = table->table_init_size;
  3551. *out_max_size = table->table_max_size;
  3552. }
  3553. return true;
  3554. }
  3555. #endif
  3556. return false;
  3557. }
  3558. static inline bool
  3559. argv_to_params(wasm_val_t *out_params,
  3560. const uint32 *argv,
  3561. WASMType *func_type)
  3562. {
  3563. wasm_val_t *param = out_params;
  3564. uint32 i = 0, *u32;
  3565. for (i = 0; i < func_type->param_count; i++, param++) {
  3566. switch (func_type->types[i]) {
  3567. case VALUE_TYPE_I32:
  3568. param->kind = WASM_I32;
  3569. param->of.i32 = *argv++;
  3570. break;
  3571. case VALUE_TYPE_I64:
  3572. param->kind = WASM_I64;
  3573. u32 = (uint32 *)&param->of.i64;
  3574. u32[0] = *argv++;
  3575. u32[1] = *argv++;
  3576. break;
  3577. case VALUE_TYPE_F32:
  3578. param->kind = WASM_F32;
  3579. param->of.f32 = *(float32 *)argv++;
  3580. break;
  3581. case VALUE_TYPE_F64:
  3582. param->kind = WASM_F64;
  3583. u32 = (uint32 *)&param->of.i64;
  3584. u32[0] = *argv++;
  3585. u32[1] = *argv++;
  3586. break;
  3587. #if WASM_ENABLE_REF_TYPES != 0
  3588. case VALUE_TYPE_EXTERNREF:
  3589. param->kind = WASM_ANYREF;
  3590. if (NULL_REF == *argv) {
  3591. param->of.ref = NULL;
  3592. }
  3593. else {
  3594. if (!wasm_externref_ref2obj(*argv,
  3595. (void **)&param->of.ref)) {
  3596. return false;
  3597. }
  3598. }
  3599. argv++;
  3600. break;
  3601. #endif
  3602. default:
  3603. return false;
  3604. }
  3605. }
  3606. return true;
  3607. }
  3608. static inline bool
  3609. results_to_argv(WASMModuleInstanceCommon *module_inst,
  3610. uint32 *out_argv,
  3611. const wasm_val_t *results,
  3612. WASMType *func_type)
  3613. {
  3614. const wasm_val_t *result = results;
  3615. uint32 *argv = out_argv, *u32, i;
  3616. uint8 *result_types = func_type->types + func_type->param_count;
  3617. for (i = 0; i < func_type->result_count; i++, result++) {
  3618. switch (result_types[i]) {
  3619. case VALUE_TYPE_I32:
  3620. case VALUE_TYPE_F32:
  3621. *(int32 *)argv++ = result->of.i32;
  3622. break;
  3623. case VALUE_TYPE_I64:
  3624. case VALUE_TYPE_F64:
  3625. u32 = (uint32 *)&result->of.i64;
  3626. *argv++ = u32[0];
  3627. *argv++ = u32[1];
  3628. break;
  3629. #if WASM_ENABLE_REF_TYPES != 0
  3630. case VALUE_TYPE_EXTERNREF:
  3631. if (!wasm_externref_obj2ref(module_inst, result->of.ref,
  3632. argv)) {
  3633. return false;
  3634. }
  3635. argv++;
  3636. break;
  3637. #endif
  3638. default:
  3639. return false;
  3640. }
  3641. }
  3642. return true;
  3643. }
  3644. bool
  3645. wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
  3646. void *func_ptr, WASMType *func_type,
  3647. uint32 argc, uint32 *argv,
  3648. bool with_env, void *wasm_c_api_env)
  3649. {
  3650. wasm_val_t params_buf[16], results_buf[4];
  3651. wasm_val_t *params = params_buf, *results = results_buf;
  3652. wasm_trap_t *trap = NULL;
  3653. bool ret = false;
  3654. if (func_type->param_count > 16
  3655. && !(params = wasm_runtime_malloc(sizeof(wasm_val_t)
  3656. * func_type->param_count))) {
  3657. wasm_runtime_set_exception(module_inst, "allocate memory failed");
  3658. return false;
  3659. }
  3660. if (!argv_to_params(params, argv, func_type)) {
  3661. wasm_runtime_set_exception(module_inst, "unsupported param type");
  3662. goto fail;
  3663. }
  3664. if (!with_env) {
  3665. wasm_func_callback_t callback = (wasm_func_callback_t)func_ptr;
  3666. trap = callback(params, results);
  3667. }
  3668. else {
  3669. wasm_func_callback_with_env_t callback =
  3670. (wasm_func_callback_with_env_t)func_ptr;
  3671. trap = callback(wasm_c_api_env, params, results);
  3672. }
  3673. if (trap) {
  3674. if (trap->message->data) {
  3675. /* since trap->message->data does not end with '\0' */
  3676. char trap_message[128] = { 0 };
  3677. bh_memcpy_s(
  3678. trap_message, 127, trap->message->data,
  3679. (trap->message->size < 127 ? (uint32)trap->message->size : 127));
  3680. wasm_runtime_set_exception(module_inst, trap_message);
  3681. }
  3682. else {
  3683. wasm_runtime_set_exception(
  3684. module_inst, "native function throw unknown exception");
  3685. }
  3686. wasm_trap_delete(trap);
  3687. goto fail;
  3688. }
  3689. if (func_type->result_count > 4
  3690. && !(results = wasm_runtime_malloc(sizeof(wasm_val_t)
  3691. * func_type->result_count))) {
  3692. wasm_runtime_set_exception(module_inst, "allocate memory failed");
  3693. goto fail;
  3694. }
  3695. if (!results_to_argv(module_inst, argv, results, func_type)) {
  3696. wasm_runtime_set_exception(module_inst, "unsupported result type");
  3697. goto fail;
  3698. }
  3699. ret = true;
  3700. fail:
  3701. if (params != params_buf)
  3702. wasm_runtime_free(params);
  3703. if (results != results_buf)
  3704. wasm_runtime_free(results);
  3705. return ret;
  3706. }