wasm_multimodules_program.c 100 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836
  1. #include "bh_common.h"
  2. #include "bh_assert.h"
  3. #include "bh_log.h"
  4. #include "wasm_multimodules_program.h"
  5. #if WASM_ENABLE_INTERP != 0
  6. #include "../interpreter/wasm_runtime.h"
  7. #endif
  8. #if WASM_ENABLE_AOT != 0
  9. #include "../aot/aot_runtime.h"
  10. #endif
  11. #define RUNTIME_CONST_STR_POOL_INIT_SIZE 128
  12. #define RUNTIME_NAME_MODULE_MAP_INIT_SIZE 32
  13. #define PROGRAM_NAME_MODULE_INST_INIT_SIZE 16
  14. #define PROGRAM_INST_IDX_VECTOR_INIT_SIZE 64
  15. #define PROGRAM_INST_ID_HMAP_INIT_SIZE 32
  16. #define PROGRAM_INST_ID_TOP_BOUNARY MAX_INST_ID
  17. static WASMRuntime * g_runtime = NULL;
  18. inline static uint32
  19. inst_id_hash(void * node)
  20. {
  21. uint32 h = ((uintptr_t)node) & (PROGRAM_INST_ID_HMAP_INIT_SIZE - 1);
  22. return h;
  23. }
  24. inline static bool
  25. inst_id_equal(void * node1, void * node2)
  26. {
  27. return ((uintptr_t)node1 == (uintptr_t)node2);
  28. }
  29. static void
  30. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  31. {
  32. if (error_buf != NULL)
  33. snprintf(error_buf, error_buf_size, "%s", string);
  34. }
  35. #if WASM_ENABLE_DYNAMIC_LINKING != 0
  36. static void
  37. set_error_buf_v(char *error_buf, uint32 error_buf_size,
  38. const char *format, ...)
  39. {
  40. va_list args;
  41. char buf[128];
  42. if (error_buf != NULL) {
  43. va_start(args, format);
  44. vsnprintf(buf, sizeof(buf), format, args);
  45. va_end(args);
  46. snprintf(error_buf, error_buf_size,
  47. "WASM module instantiate failed: %s", buf);
  48. }
  49. }
  50. #endif
  51. static void *
  52. runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
  53. {
  54. void *mem;
  55. if (size >= UINT32_MAX
  56. || !(mem = wasm_runtime_malloc((uint32)size))) {
  57. set_error_buf(error_buf, error_buf_size,
  58. "allocate memory failed");
  59. return NULL;
  60. }
  61. memset(mem, 0, (uint32)size);
  62. return mem;
  63. }
  64. inline static WASMModuleInstanceCommon *
  65. dylib_entries_map_find(const ConstStrDescription * key, HashMap *map)
  66. {
  67. return bh_hash_map_find(map, (void*)key);
  68. }
  69. inline static bool
  70. dylib_entries_map_insert(const ConstStrDescription * key,
  71. const WASMModuleInstanceCommon * module_inst,
  72. HashMap *map)
  73. {
  74. //char *value;
  75. //ConstStrDescription * key = NULL;
  76. //if ((bh_hash_map_find(map, (void*)tmp_key))) {
  77. // return true;
  78. //}
  79. //if (!(key = runtime_malloc(sizeof(ConstStrDescription),
  80. // NULL, 0))) {
  81. // return false;
  82. //}
  83. //bh_memcpy_s(key, sizeof(ConstStrDescription), tmp_key, sizeof(ConstStrDescription));
  84. if (!bh_hash_map_insert_with_dup(map, (void*)key, (void*)module_inst)) {
  85. // wasm_runtime_free(key);
  86. return false;
  87. }
  88. return true;
  89. }
  90. void
  91. wasm_runtime_set_module_reader(const module_reader reader_cb,
  92. const module_destroyer destroyer_cb)
  93. {
  94. g_runtime->reader = (void*)reader_cb;
  95. g_runtime->destroyer = (void*)destroyer_cb;
  96. }
  97. module_reader
  98. wasm_runtime_get_module_reader()
  99. {
  100. return (module_reader)g_runtime->reader;
  101. }
  102. module_destroyer
  103. wasm_runtime_get_module_destroyer()
  104. {
  105. return (module_destroyer)g_runtime->destroyer;
  106. }
  107. bool
  108. init_const_string_index_array(WASMRuntime * runtime)
  109. {
  110. ConstStrDescription * key = NULL;
  111. const char * c_str = NULL;
  112. uint32 index_array_size = WAMR_CSP_SYMBOLS_end;
  113. uint32 i = 0;
  114. runtime->global_const_str_index_array =
  115. wasm_runtime_malloc(sizeof(ConstStrDescription) * index_array_size);
  116. if (!runtime->global_const_str_index_array) {
  117. return false;
  118. }
  119. memset(runtime->global_const_str_index_array, 0, sizeof(ConstStrDescription) * index_array_size);
  120. c_str = wasm_init_symbols;
  121. for (i = 0; i < WAMR_CSP_SYMBOLS_end; i ++) {
  122. key = &runtime->global_const_str_index_array[i];
  123. key->len = strlen(c_str);
  124. key->str = c_str;
  125. key->hash = 0;
  126. key->is_sys_symbol = true;
  127. if (!bh_hash_map_insert_with_dup(runtime->global_const_str_pool, key, (void*)key))
  128. return false;
  129. c_str += (strlen(c_str) + 1);
  130. }
  131. runtime->csp_free_index = i;
  132. runtime->csp_strings_count = i;
  133. runtime->csp_size = index_array_size;
  134. return true;
  135. }
  136. bool
  137. wasm_runtime_is_system_symbol(WASMRuntime * runtime, const ConstStrDescription * key)
  138. {
  139. if (key >= &runtime->global_const_str_index_array[0] &&
  140. key <= &runtime->global_const_str_index_array[WAMR_CSP_SYMBOLS_end - 1])
  141. return true;
  142. return false;
  143. }
  144. bool
  145. wasm_runtime_is_memop_symbol(WASMRuntime * runtime, const ConstStrDescription * key)
  146. {
  147. if (key == CONST_STR_POOL_DESC(runtime, WAMR_CSP_malloc) ||
  148. key == CONST_STR_POOL_DESC(runtime, WAMR_CSP_free) ||
  149. key == CONST_STR_POOL_DESC(runtime, WAMR_CSP_realloc))
  150. return true;
  151. return false;
  152. }
  153. uint32
  154. wasm_runtime_get_syssymbol_id(WASMRuntime * runtime, const ConstStrDescription * key)
  155. {
  156. return (uint32)(key - runtime->global_const_str_index_array);
  157. }
  158. WASMModuleCommon *
  159. wasm_runtime_get_module_by_name(WASMRuntime * runtime, const ConstStrDescription * module_name)
  160. {
  161. WASMModuleCommon * module = NULL;
  162. module = bh_hash_map_find(runtime->all_loaded_modules, (void*)module_name);
  163. return module;
  164. }
  165. bool
  166. wasm_runtime_const_str_pool_init(WASMRuntime * runtime)
  167. {
  168. if (!runtime)
  169. return false;
  170. runtime->global_const_str_pool =
  171. bh_hash_map_create(RUNTIME_CONST_STR_POOL_INIT_SIZE,
  172. false,
  173. (HashFunc)const_str_hash,
  174. (KeyEqualFunc)const_str_equal,
  175. (ValueDestroyFunc)const_str_destroy_key,
  176. NULL);
  177. if (!runtime->global_const_str_pool)
  178. return false;
  179. if (!init_const_string_index_array(runtime)) {
  180. bh_hash_map_destroy(runtime->global_const_str_pool);
  181. return false;
  182. }
  183. return true;
  184. }
  185. void
  186. wasm_runtime_const_str_pool_destroy(WASMRuntime * runtime)
  187. {
  188. if (!runtime)
  189. return;
  190. if (runtime->global_const_str_pool)
  191. bh_hash_map_destroy(runtime->global_const_str_pool);
  192. if (runtime->global_const_str_index_array)
  193. wasm_runtime_free(runtime->global_const_str_index_array);
  194. runtime->global_const_str_pool = NULL;
  195. runtime->global_const_str_index_array = NULL;
  196. runtime->csp_size = 0;
  197. runtime->csp_free_index = 0;
  198. runtime->csp_strings_count = 0;
  199. }
  200. uint32
  201. records_const_string_index(WASMRuntime * runtime,
  202. const ConstStrDescription * csp_desc)
  203. {
  204. #if 0
  205. uint32 ret_index = 0;
  206. uint32 new_size = 0;
  207. if (runtime->csp_strings_count >= runtime->csp_size) {
  208. new_size = (runtime->csp_size * 3) / 2;
  209. runtime->global_const_str_index_array =
  210. wasm_runtime_realloc(runtime->global_const_str_index_array,
  211. sizeof(ConstStrDescription*) * new_size);
  212. if (!runtime->global_const_str_index_array)
  213. return 0;
  214. runtime->csp_size = new_size;
  215. }
  216. bh_assert(runtime->csp_strings_count < runtime->csp_size);
  217. ret_index = runtime->csp_free_index;
  218. runtime->global_const_str_index_array[ret_index] = (ConstStrDescription *)csp_desc;
  219. runtime->csp_strings_count ++;
  220. runtime->csp_free_index ++ ;
  221. return ret_index;
  222. #endif
  223. return 0;
  224. }
  225. static bool
  226. check_utf8_str(const uint8* str, uint32 len)
  227. {
  228. /* The valid ranges are taken from page 125, below link
  229. https://www.unicode.org/versions/Unicode9.0.0/ch03.pdf */
  230. const uint8 *p = str, *p_end = str + len;
  231. uint8 chr;
  232. while (p < p_end) {
  233. chr = *p;
  234. if (chr < 0x80) {
  235. p++;
  236. }
  237. else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
  238. if (p[1] < 0x80 || p[1] > 0xBF) {
  239. return false;
  240. }
  241. p += 2;
  242. }
  243. else if (chr >= 0xE0 && chr <= 0xEF && p + 2 < p_end) {
  244. if (chr == 0xE0) {
  245. if (p[1] < 0xA0 || p[1] > 0xBF
  246. || p[2] < 0x80 || p[2] > 0xBF) {
  247. return false;
  248. }
  249. }
  250. else if (chr == 0xED) {
  251. if (p[1] < 0x80 || p[1] > 0x9F
  252. || p[2] < 0x80 || p[2] > 0xBF) {
  253. return false;
  254. }
  255. }
  256. else if (chr >= 0xE1 && chr <= 0xEF) {
  257. if (p[1] < 0x80 || p[1] > 0xBF
  258. || p[2] < 0x80 || p[2] > 0xBF) {
  259. return false;
  260. }
  261. }
  262. p += 3;
  263. }
  264. else if (chr >= 0xF0 && chr <= 0xF4 && p + 3 < p_end) {
  265. if (chr == 0xF0) {
  266. if (p[1] < 0x90 || p[1] > 0xBF
  267. || p[2] < 0x80 || p[2] > 0xBF
  268. || p[3] < 0x80 || p[3] > 0xBF) {
  269. return false;
  270. }
  271. }
  272. else if (chr >= 0xF1 && chr <= 0xF3) {
  273. if (p[1] < 0x80 || p[1] > 0xBF
  274. || p[2] < 0x80 || p[2] > 0xBF
  275. || p[3] < 0x80 || p[3] > 0xBF) {
  276. return false;
  277. }
  278. }
  279. else if (chr == 0xF4) {
  280. if (p[1] < 0x80 || p[1] > 0x8F
  281. || p[2] < 0x80 || p[2] > 0xBF
  282. || p[3] < 0x80 || p[3] > 0xBF) {
  283. return false;
  284. }
  285. }
  286. p += 4;
  287. }
  288. else {
  289. return false;
  290. }
  291. }
  292. return (p == p_end);
  293. }
  294. const ConstStrDescription *
  295. wasm_runtime_records_const_filename_string(WASMRuntime * runtime,
  296. const char * str, const uint32 len,
  297. char* error_buf, uint32 error_buf_size)
  298. {
  299. int no_postfix_len = len;
  300. for (int i = len - 1; i >= 0; i --) {
  301. if (str[i] == '.') {
  302. no_postfix_len = i;
  303. break;
  304. }
  305. }
  306. if (!no_postfix_len)
  307. no_postfix_len = len;
  308. return wasm_runtime_records_const_string(runtime, str, no_postfix_len,
  309. error_buf, error_buf_size);
  310. }
  311. const ConstStrDescription *
  312. wasm_runtime_records_const_string(WASMRuntime * runtime,
  313. const char * str, const uint32 len,
  314. char* error_buf, uint32 error_buf_size)
  315. {
  316. HashMap * pool = NULL;
  317. char *c_str, *value;
  318. ConstStrDescription temp_key;
  319. ConstStrDescription * key = NULL;
  320. uint32 req_size = 0;
  321. if (!runtime)
  322. return NULL;
  323. pool = runtime->global_const_str_pool;
  324. if (!pool)
  325. return NULL;
  326. if (!check_utf8_str((const uint8 *)str, len)) {
  327. set_error_buf(error_buf, error_buf_size,
  328. "invalid UTF-8 encoding");
  329. return NULL;
  330. }
  331. bh_assert(len < (UINT_MAX/2));
  332. temp_key.str = (void*)str;
  333. temp_key.is_sys_symbol = false;
  334. temp_key.len = len;
  335. temp_key.hash = 0;
  336. if ((value = bh_hash_map_find(pool, &temp_key))) {
  337. return (ConstStrDescription *)value;
  338. }
  339. req_size = sizeof(ConstStrDescription) + (uint32)len + 1;
  340. if (!(key = runtime_malloc(req_size, error_buf, error_buf_size))) {
  341. return NULL;
  342. }
  343. memset(key, 0, req_size);
  344. //c_str = key->data;
  345. c_str = (char*)(key + 1);
  346. bh_memcpy_s(c_str, (uint32)(len + 1), str, (uint32)len);
  347. key->str = c_str;
  348. key->len = len;
  349. key->hash = temp_key.hash;
  350. key->is_sys_symbol = false;
  351. if (!bh_hash_map_insert(pool, key, key)) {
  352. set_error_buf(error_buf, error_buf_size,
  353. "failed to insert string to hash map");
  354. wasm_runtime_free(key);
  355. return NULL;
  356. }
  357. return key;
  358. }
  359. WASMRuntime *
  360. wasm_runtime_get_runtime()
  361. {
  362. return g_runtime;
  363. }
  364. bool
  365. wasm_runtime_runtime_init(bool standalone, bool auto_ext_name)
  366. {
  367. if (g_runtime)
  368. return false;
  369. WASMRuntime * runtime = NULL;
  370. runtime = wasm_runtime_malloc(sizeof(WASMRuntime));
  371. if (!runtime)
  372. return false;
  373. memset(runtime, 0, sizeof(WASMRuntime));
  374. runtime->config.need_load_dependencies = !standalone;
  375. runtime->config.auto_update_extension = auto_ext_name;
  376. #if WASM_ENABLE_DYNAMIC_LINKING != 0
  377. runtime->cur_loading_program = NULL;
  378. #endif
  379. runtime->reader = NULL;
  380. runtime->destroyer = NULL;
  381. runtime->all_loaded_modules = NULL;
  382. if (!standalone) {
  383. runtime->all_loaded_modules =
  384. bh_hash_map_create(RUNTIME_NAME_MODULE_MAP_INIT_SIZE,
  385. false,
  386. (HashFunc)const_str_hash,
  387. (KeyEqualFunc)const_str_equal,
  388. NULL,
  389. (ValueDestroyFunc)const_str_destroy_module);
  390. if (!runtime->all_loaded_modules) {
  391. wasm_runtime_free(runtime);
  392. return false;
  393. }
  394. }
  395. if (!wasm_runtime_const_str_pool_init(runtime)) {
  396. wasm_runtime_runtime_destroy();
  397. return false;
  398. }
  399. g_runtime = runtime;
  400. return true;
  401. }
  402. void
  403. wasm_runtime_runtime_destroy()
  404. {
  405. if (!g_runtime)
  406. return;
  407. if (g_runtime->all_loaded_modules)
  408. bh_hash_map_destroy(g_runtime->all_loaded_modules);
  409. wasm_runtime_const_str_pool_destroy(g_runtime);
  410. wasm_runtime_free(g_runtime);
  411. g_runtime = NULL;
  412. }
  413. // shared module means built with -Wl,--shared.
  414. // dependency module means opened explicitly or implicitly by other module.
  415. // root module means the first module instantiated by a program.
  416. bool
  417. wasm_runtime_is_shared_module(const WASMModuleCommon * module)
  418. {
  419. WASMDylinkSection * dylink_section = NULL;
  420. if (module->module_type == Wasm_Module_Bytecode) {
  421. dylink_section = ((WASMModule*)module)->dylink_section;
  422. } else {
  423. #if WASM_ENABLE_AOT != 0
  424. dylink_section = ((AOTModule*)module)->dylink_section;
  425. #endif
  426. }
  427. if (dylink_section)
  428. return true;
  429. return false;
  430. }
  431. bool
  432. wasm_runtime_is_shared_module_instance(const WASMModuleInstanceCommon * module_inst)
  433. {
  434. WASMDylinkSection * dylink_section = NULL;
  435. if (module_inst->module_type == Wasm_Module_Bytecode) {
  436. WASMModule * module = (WASMModule *)(((WASMModuleInstance*)module_inst)->module);
  437. dylink_section = (module)->dylink_section;
  438. } else {
  439. #if WASM_ENABLE_AOT != 0
  440. AOTModule * module = (AOTModule*)(((AOTModuleInstance*)module_inst)->aot_module.ptr);
  441. dylink_section = (module)->dylink_section;
  442. #endif
  443. }
  444. if (dylink_section)
  445. return true;
  446. return false;
  447. }
  448. #if WASM_ENABLE_DYNAMIC_LINKING != 0
  449. inline bool
  450. wasm_program_is_root_module(const WASMModuleInstanceCommon * module_inst)
  451. {
  452. const WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
  453. if (module_inst_head->program) {
  454. if (module_inst_head->program->root_module_inst)
  455. return module_inst_head->program->root_module_inst == module_inst;
  456. else
  457. return true;
  458. } else
  459. return true;
  460. }
  461. inline WASMModuleInstanceCommon *
  462. wasm_program_get_root_module_from_inst(const WASMModuleInstanceCommon * module_inst)
  463. {
  464. WASMProgramInstance * program = ((WASMModuleInstanceHead*)module_inst)->program;
  465. if (!program)
  466. return (WASMModuleInstanceCommon *)module_inst;
  467. return program->root_module_inst;
  468. }
  469. inline WASMModuleInstanceCommon *
  470. wasm_program_get_root_module(const WASMProgramInstance * program)
  471. {
  472. return program->root_module_inst;
  473. }
  474. inline void
  475. wasm_program_set_root_module(WASMProgramInstance * program, const WASMModuleInstanceCommon * module_inst)
  476. {
  477. program->root_module_inst = (WASMModuleInstanceCommon*)module_inst;
  478. }
  479. bool
  480. wasm_program_validate_mode_compatiability(WASMProgramInstance * program)
  481. {
  482. WASMRuntime * runtime = program->runtime;
  483. WASMModuleInstanceCommon * root_module_inst = program->root_module_inst;
  484. const char * symbol_name = NULL;
  485. bool malloc_exist = false;
  486. bool free_exist = false;
  487. bool realloc_exist = false;
  488. bool export_sp_exist = false;
  489. WASMModuleInstance * wasm_module_inst = NULL;
  490. #if WASM_ENABLE_AOT != 0
  491. AOTModuleInstance * aot_module_inst = NULL;
  492. #endif
  493. if (root_module_inst->module_type == Wasm_Module_Bytecode) {
  494. wasm_module_inst = (WASMModuleInstance *)root_module_inst;
  495. for (uint32 i = 0; i < wasm_module_inst->export_func_count; i ++) {
  496. symbol_name = wasm_module_inst->export_functions[i].name;
  497. if (symbol_name) {
  498. if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_malloc)))
  499. malloc_exist = true;
  500. else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_free)))
  501. free_exist = true;
  502. else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_realloc)))
  503. realloc_exist = true;
  504. if (program->config.root_is_AS_module) {
  505. if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___alloc)))
  506. malloc_exist = true;
  507. else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___free)))
  508. free_exist = true;
  509. else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___realloc)))
  510. realloc_exist = true;
  511. }
  512. if (malloc_exist && free_exist && realloc_exist)
  513. break;
  514. }
  515. }
  516. for (uint32 i = 0; i < wasm_module_inst->export_glob_count; i++) {
  517. symbol_name = wasm_module_inst->export_globals[i].name;
  518. if (!program->config.root_is_AS_module) {
  519. if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_stack_pointer)))
  520. export_sp_exist = true;
  521. } else {
  522. if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_user_stack_pointer)))
  523. export_sp_exist = true;
  524. }
  525. if (export_sp_exist)
  526. break;
  527. }
  528. } else {
  529. #if WASM_ENABLE_AOT != 0
  530. aot_module_inst = (AOTModuleInstance *)root_module_inst;
  531. AOTModule * aot_module = (AOTModule*)(aot_module_inst->aot_module.ptr);
  532. uint32 export_func_count = aot_module->export_func_count;
  533. uint32 exports_count = aot_module->export_count;
  534. AOTExportFunctionInstance * export_funcs = aot_module_inst->export_funcs.ptr;
  535. for (uint32 i = 0; i < export_func_count; i ++) {
  536. symbol_name = export_funcs[i].func_name;
  537. if (symbol_name) {
  538. if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_malloc)))
  539. malloc_exist = true;
  540. else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_free)))
  541. free_exist = true;
  542. else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_realloc)))
  543. realloc_exist = true;
  544. if (program->config.root_is_AS_module) {
  545. if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___alloc)))
  546. malloc_exist = true;
  547. else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___free)))
  548. free_exist = true;
  549. else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___realloc)))
  550. realloc_exist = true;
  551. }
  552. if (malloc_exist && free_exist && realloc_exist)
  553. break;
  554. }
  555. }
  556. for (uint32 i = 0; i < exports_count; i++) {
  557. if (aot_module->exports[i].kind != EXPORT_KIND_GLOBAL)
  558. continue;
  559. symbol_name = aot_module->exports[i].name;
  560. if (!program->config.root_is_AS_module) {
  561. if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_stack_pointer)))
  562. export_sp_exist = true;
  563. } else {
  564. if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_user_stack_pointer)))
  565. export_sp_exist = true;
  566. }
  567. if (export_sp_exist)
  568. break;
  569. }
  570. #endif
  571. }
  572. if (program->config.import_memop_mode == FROM_ROOT) {
  573. if (!malloc_exist || !free_exist || !realloc_exist) {
  574. LOG_WARNING("Select memory from root module, but not found the functions exported:");
  575. if (!malloc_exist)
  576. LOG_WARNING("malloc");
  577. if (!free_exist)
  578. LOG_WARNING("free");
  579. if (!realloc_exist)
  580. LOG_WARNING("realloc");
  581. return false;
  582. }
  583. } else {
  584. if (malloc_exist || free_exist || realloc_exist) {
  585. LOG_WARNING("Select memory from VM, but found memory functions exported:");
  586. if (malloc_exist)
  587. LOG_WARNING("malloc");
  588. if (free_exist)
  589. LOG_WARNING("free");
  590. if (realloc_exist)
  591. LOG_WARNING("realloc");
  592. }
  593. return false;
  594. }
  595. if (!export_sp_exist) {
  596. LOG_WARNING("Can't find global __stack_pointer exported, link error might happen.");
  597. return false;
  598. }
  599. return true;
  600. }
  601. WASMProgramInstance *
  602. wasm_runtime_create_program_internal(char * error_buf, uint32 error_buf_size, uint32 dlopen_mode)
  603. {
  604. WASMProgramInstance * program = NULL;
  605. if (!(program = runtime_malloc(sizeof(WASMProgramInstance), error_buf, error_buf_size)))
  606. return NULL;
  607. program->clean_all = false;
  608. program->config.binding_mode = LAZY_BINDING; // currently always lazy binding, ignore user setting
  609. program->config.import_memop_mode = (dlopen_mode & MEM_ALLOCATOR_MASK) ? FROM_ROOT: FROM_BUILTIN_LIBC;
  610. program->config.use_tbl_as_cache = (dlopen_mode & USE_TBL_AS_CACHE_MASK);
  611. program->config.root_is_AS_module = (dlopen_mode & ROOT_IS_AS_MODULE_MASK);
  612. program->config.use_resolve_cache = false; // currently alwasy false, no optimiation implemented.
  613. program->runtime = wasm_runtime_get_runtime();
  614. // bh_list_init(&program->loading_modules_list);
  615. program->resolving_cache = runtime_malloc(sizeof(wasm_resolving_cache_entry) * PROGRAM_RESOLVING_CACHE_LINE_LEN * PROGRAM_RESOLVING_CACHE_LINE_COUNT,
  616. error_buf, error_buf_size);
  617. if (!program->resolving_cache) {
  618. wasm_runtime_free(program);
  619. return NULL;
  620. }
  621. // create a local map to record dependencies.
  622. // hash map is not responsible to reclaim the key
  623. // they are allocated/free by const string pool.
  624. program->global_modules_inst_name_hmap =
  625. bh_hash_map_create(PROGRAM_NAME_MODULE_INST_INIT_SIZE,
  626. false,
  627. (HashFunc)const_str_hash,
  628. (KeyEqualFunc)const_str_equal,
  629. NULL,
  630. (ValueDestroyFunc)const_str_destroy_module_inst);
  631. if (!program->global_modules_inst_name_hmap) {
  632. wasm_runtime_free(program->resolving_cache);
  633. wasm_runtime_free(program);
  634. return NULL;
  635. }
  636. program->global_modules_inst_id_hmap =
  637. bh_hash_map_create(PROGRAM_INST_ID_HMAP_INIT_SIZE,
  638. false,
  639. (HashFunc)inst_id_hash,
  640. (KeyEqualFunc)inst_id_equal,
  641. NULL,
  642. NULL);
  643. if (!program->global_modules_inst_id_hmap) {
  644. bh_hash_map_destroy(program->global_modules_inst_name_hmap);
  645. wasm_runtime_free(program->resolving_cache);
  646. wasm_runtime_free(program);
  647. return NULL;
  648. }
  649. // index 0 is reserved for error handling.
  650. program->next_free_inst_id = 1;
  651. program->builtin_libc_funcs = NULL;
  652. program->builtin_libc_funcs_count = 0;
  653. program->builtin_libc_funcs_size = 0;
  654. program->exception_inst = NULL;
  655. program->error_buf = error_buf;
  656. program->error_buf_size = error_buf_size;
  657. return program;
  658. }
  659. void
  660. wasm_program_remove_module_inst_from_name_hmap(WASMProgramInstance * program, WASMModuleInstance * module_inst)
  661. {
  662. bh_hash_map_remove(program->global_modules_inst_name_hmap, (void*)module_inst->module->module_name, NULL, NULL);
  663. }
  664. void
  665. wasm_program_cache_resolve_result(WASMProgramInstance * program, int32 id, void * result_func, void * module_inst)
  666. {
  667. wasm_resolving_cache_entry * cache_line = NULL;
  668. wasm_resolving_cache_entry * p_empty_entry = NULL;
  669. int32 index = id & (PROGRAM_RESOLVING_CACHE_LINE_COUNT - 1);
  670. if (!program)
  671. return;
  672. cache_line = program->resolving_cache + (PROGRAM_RESOLVING_CACHE_LINE_LEN * index);
  673. if (!cache_line[0].func_inst) {
  674. p_empty_entry = &cache_line[0];
  675. } else if (!cache_line[1].func_inst)
  676. p_empty_entry = &cache_line[1];
  677. else
  678. p_empty_entry = &cache_line[0];
  679. p_empty_entry->index = id;
  680. p_empty_entry->func_inst = result_func;
  681. #if WASM_ENABLE_AOT != 0
  682. p_empty_entry->module_inst = module_inst;
  683. #endif
  684. }
  685. void *
  686. wasm_program_lookup_cached_resolving_func(WASMProgramInstance * program, int32 id)
  687. {
  688. wasm_resolving_cache_entry * cache_line = NULL;
  689. int32 index = id & (PROGRAM_RESOLVING_CACHE_LINE_COUNT - 1);
  690. if (!program)
  691. return NULL;
  692. cache_line = program->resolving_cache + (PROGRAM_RESOLVING_CACHE_LINE_LEN * index);
  693. if (cache_line[0].index == id)
  694. return cache_line[0].func_inst;
  695. else if (cache_line[1].index == id)
  696. return cache_line[1].func_inst;
  697. return NULL;
  698. }
  699. void
  700. wasm_program_invalidate_cached_wasm_func(WASMProgramInstance * program, wasm_module_inst_t module_inst)
  701. {
  702. if (!program)
  703. return;
  704. wasm_resolving_cache_entry * cache_entry = program->resolving_cache;
  705. if (!module_inst)
  706. return;
  707. for (int i = 0; i < PROGRAM_RESOLVING_CACHE_LINE_LEN * PROGRAM_RESOLVING_CACHE_LINE_COUNT; i ++) {
  708. WASMFunctionInstance * func_inst = cache_entry[i].func_inst;
  709. if (!func_inst)
  710. continue;
  711. if ((wasm_module_inst_t)func_inst->module_inst != module_inst)
  712. continue;
  713. memset(&cache_entry[i], 0, sizeof(wasm_resolving_cache_entry));
  714. }
  715. }
  716. uint32
  717. wasm_program_create_dlopen_session(WASMProgramInstance * program, WASMModuleInstanceCommon * module_inst)
  718. {
  719. WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
  720. module_inst_head->exp_ref_cnt ++;
  721. //if (module_inst->module_type == Wasm_Module_Bytecode) {
  722. // WASMModuleInstance * wasm_module_inst = (WASMModuleInstance *)module_inst;
  723. // printf("module %s, exp ref = %d, imp ref = %d\n", wasm_module_inst->module->module_name->str,
  724. // wasm_module_inst->exp_ref_cnt, wasm_module_inst->imp_ref_cnt);
  725. //} else {
  726. // AOTModuleInstance * aot_module_inst = (AOTModuleInstance *)module_inst;
  727. // printf("module %s, exp ref = %d, imp ref = %d\n", ((AOTModule*)(aot_module_inst->aot_module.ptr))->module_name->str,
  728. // aot_module_inst->exp_ref_cnt, aot_module_inst->imp_ref_cnt);
  729. //}
  730. return module_inst_head->inst_id;
  731. }
  732. WASMModuleInstanceCommon *
  733. wasm_program_destroy_dlopen_session(WASMProgramInstance * program, uint32 inst_id)
  734. {
  735. WASMModuleInstanceCommon * module_inst = wasm_program_get_module_inst_by_id(program, inst_id);
  736. WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
  737. if (!module_inst)
  738. return NULL;
  739. if (module_inst_head->exp_ref_cnt > 0)
  740. module_inst_head->exp_ref_cnt -- ;
  741. //if (module_inst->module_type == Wasm_Module_Bytecode)
  742. // printf("module %s, exp ref = %d, imp ref = %d\n", ((WASMModuleInstance*)module_inst)->module->module_name->str,
  743. // module_inst_head->exp_ref_cnt, module_inst_head->imp_ref_cnt);
  744. //else
  745. // printf("module %s, exp ref = %d, imp ref = %d\n", ((AOTModule*)((AOTModuleInstance*)module_inst)->aot_module.ptr)->module_name->str,
  746. // module_inst_head->exp_ref_cnt, module_inst_head->imp_ref_cnt);
  747. return module_inst;
  748. }
  749. uint32
  750. wasm_program_alloc_module_instance_id(WASMProgramInstance * program, WASMModuleInstanceCommon * module_inst)
  751. {
  752. uint32 id = 0;
  753. void * p = NULL;
  754. WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
  755. id = program->next_free_inst_id;
  756. p = (void*)(uintptr_t)id;
  757. while (bh_hash_map_find(program->global_modules_inst_id_hmap, p)) {
  758. id ++;
  759. if (id == PROGRAM_INST_ID_TOP_BOUNARY)
  760. id = 2;
  761. p = (void*)(uintptr_t)id;
  762. }
  763. if (!bh_hash_map_insert(program->global_modules_inst_id_hmap, p, (void*)module_inst))
  764. return 0;
  765. program->next_free_inst_id = id + 1;
  766. if (program->next_free_inst_id == PROGRAM_INST_ID_TOP_BOUNARY)
  767. program->next_free_inst_id = 2;
  768. module_inst_head->inst_id = id;
  769. return id;
  770. }
  771. void
  772. wasm_program_free_module_instance_id(WASMProgramInstance * program, uint32 inst_id)
  773. {
  774. void * key = (void*)(uintptr_t)inst_id;
  775. bh_hash_map_remove(program->global_modules_inst_id_hmap, key, NULL, NULL);
  776. }
  777. WASMModuleInstanceCommon *
  778. wasm_program_get_module_inst_by_id(WASMProgramInstance * program, uint32 inst_idx)
  779. {
  780. WASMModuleInstanceCommon * module_inst = NULL;
  781. void * key = (void*)(uintptr_t)inst_idx;
  782. module_inst = bh_hash_map_find(program->global_modules_inst_id_hmap, key);
  783. if (!module_inst) {
  784. return NULL;
  785. }
  786. return module_inst;
  787. }
  788. WASMModuleInstanceCommon *
  789. wasm_program_get_module_inst_by_name(WASMProgramInstance * program, const ConstStrDescription * module_name)
  790. {
  791. WASMModuleInstanceCommon * module_inst = NULL;
  792. if (module_name == CONST_STR_POOL_DESC(program->runtime, WAMR_CSP_env))
  793. return NULL;
  794. module_inst = bh_hash_map_find(program->global_modules_inst_name_hmap, (void*)module_name);
  795. return module_inst;
  796. }
  797. WASMModuleInstanceCommon *
  798. wasm_program_get_dep_module_inst_by_name(WASMModuleInstanceCommon * caller_module_inst, const ConstStrDescription * module_name)
  799. {
  800. WASMModuleInstanceCommon * module_inst = NULL;
  801. WASMModuleInstanceHead * caller_module_inst_head = (WASMModuleInstanceHead *)caller_module_inst;
  802. if (module_name == CONST_STR_POOL_DESC(caller_module_inst_head->runtime, WAMR_CSP_env))
  803. return NULL;
  804. if (caller_module_inst->module_type == Wasm_Module_Bytecode)
  805. module_inst = bh_hash_map_find(
  806. caller_module_inst_head->local_implicit_dependency_modules_name_hmap,
  807. (void*)module_name);
  808. else {
  809. module_inst = bh_hash_map_find(
  810. caller_module_inst_head->local_implicit_dependency_modules_name_hmap,
  811. (void*)module_name);
  812. }
  813. return module_inst;
  814. }
  815. bool
  816. wasm_program_insert_module_inst_by_name(WASMProgramInstance * program,
  817. WASMModuleInstanceCommon * module_inst,
  818. const ConstStrDescription * module_name)
  819. {
  820. return bh_hash_map_insert_with_dup(program->global_modules_inst_name_hmap,
  821. (void*)module_name,
  822. (void*)module_inst);
  823. }
  824. #if WASM_ENABLE_LIBC_BUILTIN != 0
  825. static void
  826. wasm_program_destroy_internal_libc_module(WASMProgramInstance * program);
  827. #endif
  828. void
  829. wasm_runtime_destroy_program_internal(WASMProgramInstance * program)
  830. {
  831. program->clean_all = true;
  832. #if WASM_ENABLE_LIBC_BUILTIN != 0
  833. wasm_program_destroy_internal_libc_module(program);
  834. #endif
  835. if (program->resolving_cache)
  836. wasm_runtime_free(program->resolving_cache);
  837. if (program->global_modules_inst_name_hmap)
  838. bh_hash_map_destroy(program->global_modules_inst_name_hmap);
  839. if (program->global_modules_inst_id_hmap)
  840. bh_hash_map_destroy(program->global_modules_inst_id_hmap);
  841. wasm_runtime_free(program);
  842. }
  843. const ConstStrDescription *
  844. upgrade_module_extension(const WASMRuntime *runtime,
  845. const ConstStrDescription * key_module_name,
  846. const package_type_t expected_module_type,
  847. char * error_buf,
  848. uint32 error_buf_size)
  849. {
  850. uint32 offset = 0, new_name_len = 0;
  851. const ConstStrDescription * key_new_module_name = NULL;
  852. char * extension_name = NULL, *new_module_name = NULL;
  853. if (!runtime->config.auto_update_extension)
  854. return key_module_name;
  855. offset = key_module_name->len;
  856. extension_name = strrchr(key_module_name->str, '.');
  857. if (!extension_name)
  858. return key_module_name;
  859. offset = extension_name - key_module_name->str;
  860. new_name_len = offset + sizeof(".wasm") + 1;
  861. new_module_name = (char*)wasm_runtime_malloc(new_name_len);
  862. memset(new_module_name, 0, new_name_len);
  863. memcpy(new_module_name, key_module_name->str, offset);
  864. if (expected_module_type == Wasm_Module_Bytecode)
  865. strncat(new_module_name, ".wasm", new_name_len);
  866. else
  867. strncat(new_module_name, ".aot", new_name_len);
  868. key_new_module_name = wasm_runtime_records_const_string((WASMRuntime*)runtime, new_module_name,
  869. strlen(new_module_name), error_buf, error_buf_size);
  870. wasm_runtime_free(new_module_name);
  871. return key_new_module_name;
  872. }
  873. static WASMModuleCommon *
  874. load_dependency_module(const WASMRuntime *runtime,
  875. const ConstStrDescription * key,
  876. const package_type_t expected_module_type,
  877. char * error_buf,
  878. uint32 error_buf_size)
  879. {
  880. WASMModuleCommon * new_module = NULL;
  881. // bh_list * new_modules_list = NULL;
  882. const module_reader reader = wasm_runtime_get_module_reader();
  883. const module_destroyer destroyer = wasm_runtime_get_module_destroyer();
  884. // LoadingModuleElem * loading_module_elem = NULL;
  885. if (!reader || !destroyer) {
  886. return NULL;
  887. }
  888. // check if already loaded
  889. new_module = bh_hash_map_find(runtime->all_loaded_modules, (void*)key);
  890. if (new_module &&
  891. new_module->module_type == expected_module_type) {
  892. if (!wasm_runtime_is_shared_module(new_module))
  893. return NULL;
  894. return new_module;
  895. }
  896. if (new_module &&
  897. new_module->module_type != expected_module_type) {
  898. return NULL; //currently, VM won't replace the extension automatically on user's behalf
  899. //key = upgrade_module_extension(runtime, key, expected_module_type, error_buf, error_buf_size);
  900. //new_module = bh_hash_map_find(runtime->all_loaded_modules, (void*)key);
  901. //if (new_module &&
  902. // new_module->module_type == expected_module_type) {
  903. // return new_module;
  904. //}
  905. }
  906. bh_assert(!new_module);
  907. if (!(new_module = load_dependency_module_internal(reader, destroyer, key->str,
  908. key->len, expected_module_type, error_buf, error_buf_size))) {
  909. return NULL;
  910. }
  911. if (new_module->module_type == Wasm_Module_Bytecode)
  912. ((WASMModule*)new_module)->module_name = key;
  913. else
  914. ((AOTModule*)new_module)->module_name = key;
  915. if (!bh_hash_map_insert(runtime->all_loaded_modules, (void*)key, new_module)) {
  916. return NULL;
  917. }
  918. return new_module;
  919. }
  920. /**
  921. * Return export function count in module export section.
  922. */
  923. static uint32
  924. get_export_count_by_kind(const WASMModuleCommon *module, const uint8 kind)
  925. {
  926. uint32 count = 0;
  927. if (module->module_type == Wasm_Module_Bytecode) {
  928. WASMExport *export = ((WASMModule*)module)->exports;
  929. for (uint32 i = 0; i < ((WASMModule*)module)->export_count; i++, export++) {
  930. if (export->kind == kind)
  931. count ++;
  932. }
  933. } else {
  934. AOTExport * export = ((AOTModule*)module)->exports;
  935. for (uint32 i = 0; i < ((AOTModule*)module)->export_count; i++, export++) {
  936. if (export->kind == kind)
  937. count ++;
  938. }
  939. }
  940. return count;
  941. }
  942. WASMModuleCommon *
  943. load_explicit_dependency_module(const WASMModuleInstanceCommon *parent_module,
  944. const ConstStrDescription * key)
  945. {
  946. WASMModuleInstanceHead * parent_module_inst_head = (WASMModuleInstanceHead *)parent_module;
  947. WASMRuntime * runtime = parent_module_inst_head->runtime;
  948. WASMProgramInstance * program = parent_module_inst_head->program;
  949. // all new loaded modules will be recorded into program, so that
  950. // can be easy to instantiate them later.
  951. runtime->cur_loading_program = program;
  952. return load_dependency_module(runtime, key,
  953. parent_module_inst_head->module_type,
  954. program->error_buf,
  955. program->error_buf_size);
  956. }
  957. WASMModuleCommon *
  958. load_implicit_dependency_module(const WASMModuleCommon *parent_module,
  959. const ConstStrDescription * key,
  960. char * error_buf,
  961. uint32 error_buf_size)
  962. {
  963. WASMRuntime * runtime = NULL;
  964. if (parent_module->module_type == Wasm_Module_Bytecode)
  965. runtime = ((WASMModule*)parent_module)->runtime;
  966. else {
  967. runtime = ((AOTModule*)parent_module)->runtime;
  968. key = upgrade_module_extension(runtime, key, Wasm_Module_AoT, error_buf, error_buf_size);
  969. }
  970. return load_dependency_module(runtime, key, parent_module->module_type, error_buf, error_buf_size);
  971. }
  972. void
  973. decrement_ref_module_inst_callback(ConstStrDescription * key, void * value, void * user_data)
  974. {
  975. ConstStrDescription ** unused_module_list = (ConstStrDescription **)user_data;
  976. WASMModuleInstanceCommon * module_inst = (WASMModuleInstanceCommon *)value;
  977. WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
  978. const ConstStrDescription * module_name = NULL;
  979. if (module_inst_head && module_inst_head->imp_ref_cnt ) {
  980. module_inst_head->imp_ref_cnt --;
  981. if (module_inst_head->module_type == Wasm_Module_Bytecode) {
  982. module_name = ((WASMModuleInstance*)module_inst)->module->module_name;
  983. } else {
  984. module_name = ((AOTModule*)((AOTModuleInstance*)module_inst)->aot_module.ptr)->module_name;
  985. }
  986. (void)module_name;
  987. //printf("module %s, exp ref = %d, imp ref = %d\n",
  988. // module_name->str,
  989. // module_inst_head->exp_ref_cnt,
  990. // module_inst_head->imp_ref_cnt);
  991. if (!module_inst_head->imp_ref_cnt) {
  992. if (!(*unused_module_list)) {
  993. *unused_module_list = key;
  994. } else {
  995. (*unused_module_list)->next = key;
  996. (*unused_module_list) = key;
  997. }
  998. }
  999. }
  1000. }
  1001. void
  1002. wasm_program_close_dependencies(wasm_module_inst_t module_inst,
  1003. uint32 inst_id)
  1004. {
  1005. WASMModuleInstance * caller_module_inst = (WASMModuleInstance*)module_inst;
  1006. WASMProgramInstance * program = caller_module_inst->program;
  1007. WASMModuleInstanceCommon * callee_module_inst = NULL, * iter_module_inst = NULL;
  1008. WASMModuleInstanceHead * callee_module_inst_head = NULL, *iter_module_inst_head = NULL;
  1009. HashMap * implicit_dep_hmap = NULL;
  1010. const ConstStrDescription * list_end = NULL, * list_head = NULL,
  1011. * cur_processing_node = NULL;
  1012. ConstStrDescription * key = NULL;
  1013. const ConstStrDescription *module_name = NULL;
  1014. void * p = NULL;
  1015. if (!program)
  1016. return;
  1017. callee_module_inst = wasm_program_destroy_dlopen_session(program, inst_id);
  1018. callee_module_inst_head = (WASMModuleInstanceHead *)callee_module_inst;
  1019. if (!callee_module_inst)
  1020. return;
  1021. // a FIFO list stores the modules on which no modules depends implicitly.
  1022. // implement a breath first ref count update.
  1023. if (!callee_module_inst_head->exp_ref_cnt &&
  1024. !callee_module_inst_head->imp_ref_cnt) {
  1025. implicit_dep_hmap = callee_module_inst_head->local_implicit_dependency_modules_name_hmap;
  1026. if (callee_module_inst_head->module_type == Wasm_Module_Bytecode) {
  1027. module_name = ((WASMModuleInstance*)callee_module_inst)->module->module_name;
  1028. } else {
  1029. module_name = ((AOTModule*)((AOTModuleInstance*)callee_module_inst)->aot_module.ptr)->module_name;
  1030. }
  1031. //printf("************** possible to clear deps of %s ***********************\n",
  1032. // module_name->str);
  1033. list_head = list_end = module_name;
  1034. if (implicit_dep_hmap) {
  1035. //list_head = list_end = module_name;
  1036. // handle current module's dependency
  1037. bh_hash_map_traverse(implicit_dep_hmap,
  1038. (TraverseCallbackFunc)decrement_ref_module_inst_callback, &list_end);
  1039. }
  1040. // we have handle the callee module, so start from its deps in the following loop.
  1041. cur_processing_node = list_head->next;
  1042. // handle dependencies's deps recursively
  1043. while (cur_processing_node) {
  1044. key = (ConstStrDescription*)cur_processing_node;
  1045. iter_module_inst = bh_hash_map_find(program->global_modules_inst_name_hmap, (void*)key);
  1046. iter_module_inst_head = (WASMModuleInstanceHead*)iter_module_inst;
  1047. if (iter_module_inst_head) {
  1048. bh_assert(iter_module_inst_head->imp_ref_cnt == 0);
  1049. if (iter_module_inst_head->local_implicit_dependency_modules_name_hmap)
  1050. bh_hash_map_traverse(iter_module_inst_head->local_implicit_dependency_modules_name_hmap,
  1051. (TraverseCallbackFunc)decrement_ref_module_inst_callback, &list_end);
  1052. }
  1053. cur_processing_node = cur_processing_node->next;
  1054. }
  1055. }
  1056. // remove the modules which both exp_ref and imp_ref are zero.
  1057. // Note: currently, we don't handle cycle-dependency case, it's responsible for application user.
  1058. cur_processing_node = list_head;
  1059. while(cur_processing_node) {
  1060. key = (ConstStrDescription*)cur_processing_node;
  1061. iter_module_inst = bh_hash_map_find(program->global_modules_inst_name_hmap, (void*)key);
  1062. iter_module_inst_head = (WASMModuleInstanceHead*)iter_module_inst;
  1063. if (iter_module_inst_head && !iter_module_inst_head->exp_ref_cnt) {
  1064. p = (void*)(uintptr_t)iter_module_inst_head->inst_id;
  1065. bh_hash_map_remove(program->global_modules_inst_id_hmap,
  1066. p,
  1067. NULL,
  1068. NULL);
  1069. bh_hash_map_remove(program->global_modules_inst_name_hmap, (void*)key, NULL, NULL);
  1070. if (iter_module_inst_head->module_type == Wasm_Module_Bytecode) {
  1071. module_name = ((WASMModuleInstance*)iter_module_inst)->module->module_name;
  1072. } else {
  1073. module_name = ((AOTModule*)((AOTModuleInstance*)iter_module_inst)->aot_module.ptr)->module_name;
  1074. }
  1075. //printf("module %s deinstantiating\n", module_name->str);
  1076. // wasm_program_free_module_instance_id(program, iter_module_inst->inst_id);
  1077. // wasm_program_remove_module_inst_from_name_hmap(program, iter_module_inst);
  1078. wasm_program_invalidate_cached_wasm_func(program, (wasm_module_inst_t)iter_module_inst);
  1079. wasm_runtime_module_free(program->root_module_inst, iter_module_inst_head->init_globals.actual_memory_base);
  1080. wasm_runtime_deinstantiate((wasm_module_inst_t)iter_module_inst);
  1081. }
  1082. cur_processing_node = cur_processing_node->next;
  1083. // unlink current working list
  1084. key->next = NULL;
  1085. }
  1086. }
  1087. // Note: it will be implemented as thread-safe.
  1088. // only one thread could open a dependency wasm and its dependency per time.
  1089. // will add contention protection (lock/mutex etc) later.
  1090. uint32
  1091. wasm_program_open_dependencies(wasm_module_inst_t module_inst,
  1092. const char * path)
  1093. {
  1094. WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
  1095. WASMProgramInstance * program_inst = module_inst_head->program;
  1096. WASMRuntime * runtime = module_inst_head->runtime;
  1097. WASMModuleInstanceCommon * callee_module_inst = NULL;
  1098. if (!program_inst)
  1099. return 0;
  1100. callee_module_inst = wasm_program_open_dependencies_general(runtime,
  1101. program_inst,
  1102. module_inst,
  1103. path);
  1104. if (!callee_module_inst)
  1105. return 0;
  1106. if (callee_module_inst == module_inst)
  1107. return 0;
  1108. return wasm_program_create_dlopen_session(program_inst, callee_module_inst);
  1109. }
  1110. WASMModuleInstanceCommon *
  1111. wasm_program_instantiate_dependencies(WASMRuntime * runtime,
  1112. WASMProgramInstance * program_inst,
  1113. WASMModuleInstanceCommon * caller_module_inst,
  1114. WASMModuleCommon * module)
  1115. {
  1116. WASMModuleInstanceCommon * new_module_inst = NULL;
  1117. WASMModuleInstanceCommon *root_module_inst = NULL;
  1118. WASMModule * wasm_module = (WASMModule*)module;
  1119. AOTModule * aot_module = (AOTModule*)module;
  1120. DependencyModuleInitGlobals init_globals;
  1121. int32 init_size = 0, export_func_count = 0, stack_size = 0;
  1122. uint32 offset = 0;
  1123. void * native_addr = NULL;
  1124. bool is_aot = !(module->module_type == Wasm_Module_Bytecode);
  1125. root_module_inst = program_inst->root_module_inst;
  1126. if (!is_aot && !wasm_module->dylink_section) {
  1127. set_error_buf_v(program_inst->error_buf, program_inst->error_buf_size,
  1128. "%s isn't a valid shared wasm module.\n", wasm_module->module_name->str);
  1129. return NULL;
  1130. } else if (is_aot && !aot_module->dylink_section) {
  1131. set_error_buf_v(program_inst->error_buf, program_inst->error_buf_size,
  1132. "%s isn't a valid shared wasm module.\n", aot_module->module_name->str);
  1133. return NULL;
  1134. }
  1135. if (root_module_inst->module_type == Wasm_Module_Bytecode)
  1136. stack_size = ((WASMModuleInstance*)root_module_inst)->default_wasm_stack_size;
  1137. else
  1138. stack_size = ((AOTModuleInstance*)root_module_inst)->default_wasm_stack_size;
  1139. memset(&init_globals, 0, sizeof(DependencyModuleInitGlobals));
  1140. // lazy instantiation
  1141. // the idea is to load all dependencies first (so we can check if all of them exist),
  1142. // but only instantiate the first one, and other modules will be instantiated as needed.
  1143. export_func_count = get_export_count_by_kind(module, EXPORT_KIND_FUNC);
  1144. // allocate init mem space for dependency module
  1145. if (!is_aot) {
  1146. if (!wasm_module->dylink_section->table_alignment)
  1147. wasm_module->dylink_section->table_alignment = 1;
  1148. init_size = wasm_module->dylink_section->table_size + export_func_count;
  1149. init_size += wasm_module->dylink_section->table_alignment - 1;
  1150. // will calcuate it by instance id
  1151. init_globals.table_alignment = wasm_module->dylink_section->table_alignment;
  1152. if (!wasm_module->dylink_section->memory_alignment)
  1153. wasm_module->dylink_section->memory_alignment = 1;
  1154. bh_assert(wasm_module->dylink_section->memory_alignment > 0);
  1155. } else {
  1156. if (!aot_module->dylink_section->table_alignment)
  1157. aot_module->dylink_section->table_alignment = 1;
  1158. init_size = aot_module->dylink_section->table_size + export_func_count;
  1159. init_size += aot_module->dylink_section->table_alignment - 1;
  1160. // will calcuate it by instance id
  1161. init_globals.table_alignment = aot_module->dylink_section->table_alignment;
  1162. if (!aot_module->dylink_section->memory_alignment)
  1163. aot_module->dylink_section->memory_alignment = 1;
  1164. bh_assert(aot_module->dylink_section->memory_alignment > 0);
  1165. }
  1166. bh_assert(init_size <= TABLE_SPACE_SLOT_SIZE);
  1167. init_globals.table_size = init_size;
  1168. init_globals.table_base = 0;
  1169. // assumpt stack_pointer is the first global.
  1170. // if root module is opened by dlopen, global[0] should be __stack_pointer
  1171. // else if root module is a library module, its global[0] is also __stack_pointer
  1172. if (caller_module_inst->module_type == Wasm_Module_Bytecode) {
  1173. //bh_assert(((WASMModuleInstance*)caller_module_inst)->globals[0].is_mutable == true &&
  1174. // ((WASMModuleInstance*)caller_module_inst)->globals[0].type == VALUE_TYPE_I32);
  1175. } else {
  1176. AOTModule * root_aot_module = (AOTModule*)((AOTModuleInstance*)caller_module_inst)->aot_module.ptr;
  1177. (void)root_aot_module;
  1178. if (root_aot_module->dylink_section)
  1179. bh_assert(root_aot_module->import_globals[0].is_mutable == true &&
  1180. root_aot_module->import_globals[0].type == VALUE_TYPE_I32);
  1181. //else
  1182. // bh_assert(root_aot_module->globals[0].is_mutable == true &&
  1183. // root_aot_module->globals[0].type == VALUE_TYPE_I32);
  1184. }
  1185. if (!is_aot) {
  1186. init_size = wasm_module->dylink_section->memory_size + wasm_module->dylink_section->memory_alignment - 1;
  1187. offset = wasm_runtime_module_malloc((wasm_module_inst_t)root_module_inst,
  1188. init_size, &native_addr);
  1189. if (!offset)
  1190. return NULL;
  1191. init_globals.actual_memory_base = offset;
  1192. init_globals.memory_base = (offset + wasm_module->dylink_section->memory_alignment - 1) &
  1193. (~(wasm_module->dylink_section->memory_alignment - 1));
  1194. new_module_inst = (WASMModuleInstanceCommon*)wasm_instantiate_dependency((WASMModule*)module, program_inst,
  1195. stack_size, &init_globals);
  1196. } else {
  1197. init_size = aot_module->dylink_section->memory_size + aot_module->dylink_section->memory_alignment - 1;
  1198. offset = wasm_runtime_module_malloc((wasm_module_inst_t)root_module_inst,
  1199. init_size, &native_addr);
  1200. if (!offset)
  1201. return NULL;
  1202. init_globals.actual_memory_base = offset;
  1203. init_globals.memory_base = (offset + aot_module->dylink_section->memory_alignment - 1) &
  1204. (~(aot_module->dylink_section->memory_alignment - 1));
  1205. new_module_inst = (WASMModuleInstanceCommon*)aot_instantiate_dependency((AOTModule*)module, program_inst,
  1206. stack_size, &init_globals);
  1207. }
  1208. if (!new_module_inst)
  1209. return NULL;
  1210. return new_module_inst;
  1211. }
  1212. WASMModuleInstanceCommon *
  1213. wasm_program_open_dependencies_general(WASMRuntime * runtime,
  1214. WASMProgramInstance * program_inst,
  1215. WASMModuleInstanceCommon * caller_module_inst,
  1216. const char * path)
  1217. {
  1218. const ConstStrDescription * key = NULL;
  1219. WASMModuleCommon * new_module = NULL;
  1220. WASMModuleInstanceCommon *root_module_inst = NULL, *new_module_inst = NULL;
  1221. // bh_list loading_modules_list;
  1222. //LoadingModuleElem * elem = NULL;
  1223. root_module_inst = program_inst->root_module_inst;
  1224. // records string into const string pool
  1225. key = wasm_runtime_records_const_string(
  1226. runtime, path,
  1227. strlen(path),
  1228. program_inst->error_buf,
  1229. program_inst->error_buf_size);
  1230. if (!key) {
  1231. return NULL;
  1232. }
  1233. // check if opened by the current program.
  1234. new_module_inst = dylib_entries_map_find(key, program_inst->global_modules_inst_name_hmap);
  1235. if (new_module_inst) {
  1236. if (new_module_inst->module_type != caller_module_inst->module_type)
  1237. return NULL;
  1238. if (!wasm_runtime_is_shared_module_instance(new_module_inst)) {
  1239. return NULL;
  1240. }
  1241. return new_module_inst;
  1242. }
  1243. // start to load all dependency modules.
  1244. new_module = load_explicit_dependency_module(root_module_inst, key);
  1245. if (!new_module)
  1246. return NULL;
  1247. // currently only supports wasm->wasm, aot->aot
  1248. if (new_module->module_type != caller_module_inst->module_type)
  1249. return NULL;
  1250. if (!wasm_runtime_is_shared_module(new_module)) {
  1251. return NULL;
  1252. }
  1253. // can exit the program lock scope from here.
  1254. new_module_inst = (WASMModuleInstanceCommon*)wasm_program_instantiate_dependencies(
  1255. runtime, program_inst, (WASMModuleInstanceCommon*)caller_module_inst, new_module);
  1256. if (!new_module_inst)
  1257. return NULL;
  1258. if (!dylib_entries_map_insert(key, new_module_inst,
  1259. program_inst->global_modules_inst_name_hmap))
  1260. return NULL;
  1261. return new_module_inst;
  1262. }
  1263. uint32
  1264. wasm_program_lookup_symbol_from_module(wasm_module_inst_t caller_module,
  1265. uint32 inst_id, const char * symbol)
  1266. {
  1267. WASMModuleInstanceHead * caller_module_inst_head = (WASMModuleInstanceHead *)caller_module;
  1268. WASMModuleInstanceCommon * callee_module_inst = NULL;
  1269. WASMModuleInstance * wasm_inst = NULL;
  1270. AOTModuleInstance * aot_inst = NULL;
  1271. AOTModule * aot_module = NULL;
  1272. uint32 table_slot = 0, i = 0;
  1273. void * key = NULL;
  1274. if (!caller_module_inst_head->program)
  1275. return 0;
  1276. key = (void*)(uintptr_t)inst_id;
  1277. callee_module_inst = bh_hash_map_find(caller_module_inst_head->program->global_modules_inst_id_hmap, key);
  1278. if (!callee_module_inst)
  1279. return 0;
  1280. if (callee_module_inst->module_type == Wasm_Module_Bytecode) {
  1281. wasm_inst = (WASMModuleInstance *)callee_module_inst;
  1282. for (i = 0; i < wasm_inst->export_func_count; i++) {
  1283. if (!strcmp(wasm_inst->export_functions[i].name, symbol)) {
  1284. table_slot = i;
  1285. break;
  1286. }
  1287. }
  1288. if (i == wasm_inst->export_func_count)
  1289. return 0;
  1290. table_slot += (wasm_inst->inst_id *
  1291. TABLE_SPACE_SLOT_SIZE) - wasm_inst->export_func_count;
  1292. } else {
  1293. aot_inst = (AOTModuleInstance *)callee_module_inst;
  1294. aot_module = (AOTModule*)aot_inst->aot_module.ptr;
  1295. for (i = 0; i < aot_module->export_func_count; i++) {
  1296. if (!strcmp(((AOTExportFunctionInstance*)aot_inst->export_funcs.ptr)[i].func_name, symbol)) {
  1297. table_slot = i;
  1298. break;
  1299. }
  1300. }
  1301. if (i == aot_module->export_func_count)
  1302. return 0;
  1303. table_slot += (aot_inst->inst_id *
  1304. TABLE_SPACE_SLOT_SIZE) - aot_module->export_func_count;
  1305. }
  1306. return table_slot;
  1307. }
  1308. bool
  1309. wasm_program_resolve_aot_function(WASMProgramInstance * program,
  1310. AOTModuleInstance * resolve_module_inst,
  1311. AOTModuleInstance ** p_callee_module_inst,
  1312. uint32 import_func_id)
  1313. {
  1314. WASMRuntime * runtime = resolve_module_inst->runtime;
  1315. const ConstStrDescription * module_name = NULL, * func_name = NULL;
  1316. AOTModule * module = resolve_module_inst->aot_module.ptr;
  1317. AOTModule * callee_module = NULL;
  1318. AOTImportFunc * import_func = &module->import_funcs[import_func_id];
  1319. AOTFuncType * cur_type = NULL, *cur_func_type = NULL;
  1320. AOTModuleInstance *caller_module_inst = resolve_module_inst, *callee_module_inst = NULL;
  1321. AOTExportFunctionInstance * export_funcs = NULL, *callee_function_inst = NULL;
  1322. uint32 i = 0;
  1323. bool resolve_memop_func = false;
  1324. cur_type = import_func->func_type;
  1325. while(1) {
  1326. resolve_memop_func = false;
  1327. module_name = import_func->module_name;
  1328. func_name = import_func->func_name;
  1329. if (module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_env) &&
  1330. (program->config.import_memop_mode != FROM_ROOT ||
  1331. !wasm_runtime_is_memop_symbol(runtime, func_name))) {
  1332. *p_callee_module_inst = caller_module_inst;
  1333. return true;
  1334. }
  1335. if (module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_env)) {
  1336. resolve_memop_func = true;
  1337. bh_assert(caller_module_inst != (AOTModuleInstance*)program->root_module_inst);
  1338. callee_module_inst = (AOTModuleInstance*)program->root_module_inst;
  1339. }
  1340. if (!callee_module_inst) {
  1341. module_name = upgrade_module_extension(runtime,
  1342. module_name, Wasm_Module_AoT, program->error_buf, program->error_buf_size);
  1343. callee_module_inst = (AOTModuleInstance*)wasm_program_get_module_inst_by_name(program, module_name);
  1344. }
  1345. if (!callee_module_inst) {
  1346. callee_module = (AOTModule*)wasm_runtime_get_module_by_name(runtime, module_name);
  1347. if (!callee_module) {
  1348. aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
  1349. return false;
  1350. }
  1351. callee_module_inst = (AOTModuleInstance*)wasm_program_instantiate_dependencies(runtime,
  1352. program, (WASMModuleInstanceCommon*)caller_module_inst, (WASMModuleCommon*)callee_module);
  1353. if (!callee_module_inst) {
  1354. aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
  1355. return false;
  1356. }
  1357. if (!bh_hash_map_insert_with_dup(program->global_modules_inst_name_hmap,
  1358. (void*)module_name, (void*)callee_module_inst)) {
  1359. aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
  1360. return false;
  1361. }
  1362. }
  1363. if (!resolve_memop_func) {
  1364. if (!caller_module_inst->local_implicit_dependency_modules_name_hmap) {
  1365. caller_module_inst->local_implicit_dependency_modules_name_hmap =
  1366. bh_hash_map_create(8, false,
  1367. (HashFunc)const_str_hash,
  1368. (KeyEqualFunc)const_str_equal,
  1369. NULL,
  1370. NULL);
  1371. if (!caller_module_inst->local_implicit_dependency_modules_name_hmap) {
  1372. aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
  1373. return false;
  1374. }
  1375. if (!bh_hash_map_insert(caller_module_inst->local_implicit_dependency_modules_name_hmap,
  1376. (void*)module_name, (void*)callee_module_inst)) {
  1377. aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
  1378. return false;
  1379. }
  1380. callee_module_inst->imp_ref_cnt ++;
  1381. } else {
  1382. if (!bh_hash_map_find(caller_module_inst->local_implicit_dependency_modules_name_hmap,
  1383. (void*)module_name)) {
  1384. if (!bh_hash_map_insert(caller_module_inst->local_implicit_dependency_modules_name_hmap,
  1385. (void*)module_name, (void*)callee_module_inst)) {
  1386. aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
  1387. return false;
  1388. }
  1389. callee_module_inst->imp_ref_cnt ++;
  1390. }
  1391. }
  1392. }
  1393. //printf("module %s, exp ref = %d, imp ref = %d\n",
  1394. // module_name->str,
  1395. // callee_module_inst->exp_ref_cnt,
  1396. // callee_module_inst->imp_ref_cnt);
  1397. export_funcs = (AOTExportFunctionInstance*)callee_module_inst->export_funcs.ptr;
  1398. if (!callee_module)
  1399. callee_module = (AOTModule*)callee_module_inst->aot_module.ptr;
  1400. for (i = 0; i < callee_module->export_func_count; i++) {
  1401. if (!strcmp(export_funcs[i].func_name, import_func->func_name->str)) {
  1402. break;
  1403. }
  1404. }
  1405. if (i == callee_module->export_func_count) {
  1406. aot_set_exception_with_id(caller_module_inst, EXCE_CALL_UNLINKED_IMPORT_FUNC);
  1407. return false;
  1408. }
  1409. callee_function_inst = &export_funcs[i];
  1410. if (callee_function_inst->is_import_func)
  1411. cur_func_type = callee_function_inst->u.func_import->func_type;
  1412. else
  1413. cur_func_type = callee_function_inst->u.func.func_type;
  1414. if (!wasm_type_equal(cur_type, cur_func_type)) {
  1415. aot_set_exception_with_id(caller_module_inst, EXCE_INVALID_FUNCTION_TYPE_INDEX);
  1416. return false;
  1417. }
  1418. if (!callee_function_inst->is_import_func)
  1419. break;
  1420. if (callee_function_inst->u.func_import->func_ptr_linked)
  1421. break;
  1422. caller_module_inst = callee_module_inst;
  1423. import_func = callee_function_inst->u.func_import;
  1424. }
  1425. ((void**)resolve_module_inst->func_ptrs.ptr)[import_func_id] = callee_function_inst->u.func.func_ptr;
  1426. *p_callee_module_inst = callee_module_inst;
  1427. return true;
  1428. }
  1429. // TODO: the resolve algorithm need to improved to update the resolving result for other intermediate modules.
  1430. static bool
  1431. wasm_program_resolve_wasm_function(WASMProgramInstance * program,
  1432. WASMModuleInstance * caller_module_inst,
  1433. WASMFunctionInstance * import_func)
  1434. {
  1435. WASMModule * callee_module = NULL;
  1436. const ConstStrDescription * module_name = NULL, *func_name = NULL;
  1437. WASMModuleInstance * callee_module_inst = NULL;
  1438. WASMFunctionInstance * callee_function_inst = NULL;
  1439. WASMRuntime * runtime = caller_module_inst->runtime;
  1440. WASMType *cur_type = NULL, *cur_func_type = NULL;
  1441. bool resolve_memop_func = false;
  1442. uint32 i = 0;
  1443. if (!import_func->is_import_func)
  1444. return true;
  1445. callee_function_inst = import_func;
  1446. cur_type = callee_function_inst->u.func_import->func_type;
  1447. while (1) {
  1448. resolve_memop_func = false;
  1449. module_name = callee_function_inst->u.func_import->module_name;
  1450. func_name = callee_function_inst->u.func_import->field_name;
  1451. if (module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_env) &&
  1452. (program->config.import_memop_mode != FROM_ROOT ||
  1453. !wasm_runtime_is_memop_symbol(runtime, func_name))) {
  1454. break;
  1455. }
  1456. if (module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_env)) {
  1457. resolve_memop_func = true;
  1458. bh_assert(caller_module_inst != (WASMModuleInstance*)program->root_module_inst);
  1459. callee_module_inst = (WASMModuleInstance*)program->root_module_inst;
  1460. }
  1461. if (!callee_module_inst)
  1462. callee_module_inst = (WASMModuleInstance*)wasm_program_get_module_inst_by_name(program, module_name);
  1463. if (!callee_module_inst) {
  1464. callee_module = (WASMModule*)wasm_runtime_get_module_by_name(runtime, module_name);
  1465. if (!callee_module)
  1466. return false;
  1467. callee_module_inst = (WASMModuleInstance*)wasm_program_instantiate_dependencies(runtime,
  1468. program, (WASMModuleInstanceCommon*)caller_module_inst, (WASMModuleCommon*)callee_module);
  1469. if (!callee_module_inst)
  1470. return false;
  1471. if (!bh_hash_map_insert_with_dup(program->global_modules_inst_name_hmap,
  1472. (void*)module_name, (void*)callee_module_inst))
  1473. return false;
  1474. }
  1475. if (!resolve_memop_func) {
  1476. if (!caller_module_inst->local_implicit_dependency_modules_name_hmap) {
  1477. caller_module_inst->local_implicit_dependency_modules_name_hmap =
  1478. bh_hash_map_create(8, false,
  1479. (HashFunc)const_str_hash,
  1480. (KeyEqualFunc)const_str_equal,
  1481. NULL,
  1482. NULL);
  1483. if (!caller_module_inst->local_implicit_dependency_modules_name_hmap)
  1484. return false;
  1485. if (!bh_hash_map_insert(caller_module_inst->local_implicit_dependency_modules_name_hmap,
  1486. (void*)module_name, (void*)callee_module_inst))
  1487. return false;
  1488. callee_module_inst->imp_ref_cnt ++;
  1489. } else {
  1490. if (!bh_hash_map_find(caller_module_inst->local_implicit_dependency_modules_name_hmap,
  1491. (void*)module_name)) {
  1492. if (!bh_hash_map_insert(caller_module_inst->local_implicit_dependency_modules_name_hmap,
  1493. (void*)module_name, (void*)callee_module_inst))
  1494. return false;
  1495. callee_module_inst->imp_ref_cnt ++;
  1496. }
  1497. }
  1498. }
  1499. //printf("module %s, exp ref = %d, imp ref = %d\n",
  1500. // callee_module_inst->module->module_name->str,
  1501. // callee_module_inst->exp_ref_cnt,
  1502. // callee_module_inst->imp_ref_cnt);
  1503. #if 0
  1504. if (program->config.root_is_AS_module) {
  1505. if (func_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_malloc))
  1506. func_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___alloc);
  1507. else if (func_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_free))
  1508. func_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___free);
  1509. else if (func_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_realloc))
  1510. func_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___realloc);
  1511. }
  1512. #endif
  1513. for (i = 0; i < callee_module_inst->export_func_count; i++) {
  1514. if (!strcmp(callee_module_inst->export_functions[i].name, func_name->str)) {
  1515. break;
  1516. }
  1517. }
  1518. if (i == callee_module_inst->export_func_count) {
  1519. return false;
  1520. }
  1521. callee_function_inst = callee_module_inst->export_functions[i].function;
  1522. if (callee_function_inst->is_import_func)
  1523. cur_func_type = callee_function_inst->u.func_import->func_type;
  1524. else
  1525. cur_func_type = callee_function_inst->u.func->func_type;
  1526. if (!wasm_type_equal(cur_type, cur_func_type)) {
  1527. return false;
  1528. }
  1529. if (!callee_function_inst->is_import_func)
  1530. break;
  1531. if (callee_function_inst->u.func_import->func_ptr_linked)
  1532. break;
  1533. caller_module_inst = callee_module_inst;
  1534. }
  1535. import_func->import_module_inst = callee_module_inst;
  1536. import_func->import_func_inst = callee_function_inst;
  1537. return true;
  1538. }
  1539. bool
  1540. wasm_program_resolve_op_call(WASMProgramInstance * program,
  1541. WASMModuleInstance * caller_module_inst,
  1542. WASMModuleInstance ** p_callee_module_inst,
  1543. WASMFunctionInstance ** p_call_func)
  1544. {
  1545. WASMModuleInstance * callee_module_inst = NULL;
  1546. WASMFunctionInstance * call_func = *p_call_func;
  1547. // lazy link, resolve the import function.
  1548. if (program &&
  1549. //caller_module_inst != (WASMModuleInstance*)program->root_module_inst &&
  1550. call_func->is_import_func &&
  1551. !call_func->u.func_import->func_ptr_linked) {
  1552. if (!call_func->import_module_inst &&
  1553. !call_func->import_func_inst) {
  1554. if (program->config.binding_mode != LAZY_BINDING) {
  1555. wasm_set_exception(caller_module_inst, "uninitialized import function.");
  1556. return false;
  1557. }
  1558. if (!wasm_program_resolve_wasm_function(program, caller_module_inst, call_func)) {
  1559. char buf[128];
  1560. snprintf(buf, sizeof(buf),
  1561. "failed to call unlinked import function (%s, %s)",
  1562. (char*)call_func->u.func_import->module_name->str,
  1563. (char*)call_func->u.func_import->field_name->str);
  1564. wasm_set_exception(caller_module_inst, buf);
  1565. return false;
  1566. }
  1567. }
  1568. callee_module_inst = call_func->import_module_inst;
  1569. call_func = call_func->import_func_inst;
  1570. *p_callee_module_inst = callee_module_inst;
  1571. *p_call_func = call_func;
  1572. }
  1573. return true;
  1574. }
  1575. uint32
  1576. wasm_program_alloc_table_space_by_size(uint32 inst_id,
  1577. uint32 needed_size)
  1578. {
  1579. uint32 table_space_start = 0;
  1580. bh_assert(needed_size <= TABLE_SPACE_SLOT_SIZE);
  1581. table_space_start = ((inst_id - 1)<< TABLE_SPACE_BITS_LEN);
  1582. return table_space_start;
  1583. }
  1584. uint32
  1585. wasm_program_alloc_table_space_by_table(WASMModuleInstance * module_inst,
  1586. WASMTableInstance * table)
  1587. {
  1588. uint32 needed_size = table->max_size;
  1589. uint32 inst_id = module_inst->inst_id;
  1590. return wasm_program_alloc_table_space_by_size(inst_id, needed_size);
  1591. }
  1592. #if WASM_ENABLE_LIBC_BUILTIN != 0
  1593. uint32
  1594. get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis);
  1595. #define BUILTIN_FUNC_ALLOC_STEP 4
  1596. // create an internal libc module, but not create func instance until link GOT.func global
  1597. static int
  1598. wasm_program_link_internal_builtin_libc_func(WASMProgramInstance * program, const ConstStrDescription * func_name)
  1599. {
  1600. WASMRuntime * runtime = program->runtime;
  1601. WASMFunctionInstance ** functions = (WASMFunctionInstance**)program->builtin_libc_funcs, *linked_func = NULL;
  1602. WASMFunctionImport * func_import = NULL;
  1603. NativeSymbol * native_symbols = NULL;
  1604. uint32 i = 0, func_id = 0, func_offset = 0;
  1605. int32 ret_id = -1;
  1606. uint32 libc_funcs_count = get_libc_builtin_export_apis(&native_symbols);
  1607. (void)(libc_funcs_count);
  1608. if (!functions) {
  1609. functions = wasm_runtime_malloc(sizeof(WASMFunctionInstance *) * BUILTIN_FUNC_ALLOC_STEP);
  1610. if (!functions)
  1611. return -1;
  1612. program->builtin_libc_funcs = (void**)functions;
  1613. program->builtin_libc_funcs_size = BUILTIN_FUNC_ALLOC_STEP;
  1614. }
  1615. for (i = 0; i < program->builtin_libc_funcs_count; i ++) {
  1616. if (func_name == functions[i]->u.func_import->field_name)
  1617. break;
  1618. }
  1619. if (i < program->builtin_libc_funcs_count) {
  1620. return i;
  1621. }
  1622. func_id = wasm_runtime_get_syssymbol_id(runtime, func_name);
  1623. if (func_id < WAMR_CSP_iprintf ||
  1624. func_id > WAMR_CSP_dlclose)
  1625. return -1;
  1626. func_import = wasm_runtime_malloc(sizeof(WASMFunctionImport));
  1627. if (!func_import)
  1628. return -1;
  1629. linked_func = wasm_runtime_malloc(sizeof(WASMFunctionInstance));
  1630. if (!linked_func) {
  1631. wasm_runtime_free(func_import);
  1632. return -1;
  1633. }
  1634. memset(func_import, 0, sizeof(WASMFunctionImport));
  1635. memset(linked_func, 0, sizeof(WASMFunctionInstance));
  1636. func_offset = func_id - WAMR_CSP_iprintf;
  1637. bh_assert(func_name == native_symbols[func_offset].u.symbol);
  1638. func_import->module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_env);
  1639. func_import->field_name = func_name;
  1640. func_import->signature = native_symbols[func_offset].signature;
  1641. func_import->func_type = NULL;
  1642. func_import->attachment = native_symbols[func_offset].attachment;
  1643. func_import->call_conv_raw = false;
  1644. func_import->call_conv_wasm_c_api = false;
  1645. func_import->wasm_c_api_with_env = false;
  1646. func_import->func_ptr_linked = native_symbols[func_offset].func_ptr;
  1647. linked_func->is_import_func = true;
  1648. linked_func->func_type = NULL;
  1649. linked_func->local_count = 0;
  1650. linked_func->local_cell_num = 0;
  1651. #if WASM_ENABLE_FAST_INTERP != 0
  1652. linked_func->const_cell_num = 0;
  1653. #endif
  1654. linked_func->local_offsets = 0;
  1655. linked_func->local_types = NULL;
  1656. linked_func->u.func_import = func_import;
  1657. if ((program->builtin_libc_funcs_count + 1) > program->builtin_libc_funcs_size) {
  1658. functions = wasm_runtime_realloc(functions,
  1659. sizeof(WASMFunctionInstance *) * (program->builtin_libc_funcs_size + BUILTIN_FUNC_ALLOC_STEP));
  1660. if (!functions) {
  1661. wasm_runtime_free(func_import);
  1662. wasm_runtime_free(linked_func);
  1663. return -1;
  1664. }
  1665. program->builtin_libc_funcs_size += BUILTIN_FUNC_ALLOC_STEP;
  1666. program->builtin_libc_funcs = (void**)functions;
  1667. }
  1668. functions[program->builtin_libc_funcs_count] = linked_func;
  1669. ret_id = program->builtin_libc_funcs_count;
  1670. program->builtin_libc_funcs_count ++;
  1671. return ret_id;
  1672. }
  1673. #if WASM_ENABLE_AOT != 0
  1674. static int
  1675. wasm_program_link_aot_internal_builtin_libc_func(WASMProgramInstance * program, const ConstStrDescription * func_name)
  1676. {
  1677. WASMRuntime * runtime = program->runtime;
  1678. AOTExportFunctionInstance ** functions = (AOTExportFunctionInstance **)program->builtin_libc_funcs, *linked_func = NULL;
  1679. AOTImportFunc * func_import = NULL;
  1680. NativeSymbol * native_symbols = NULL;
  1681. uint32 i = 0, func_id = 0, func_offset = 0;
  1682. int32 ret_id = -1;
  1683. uint32 libc_funcs_count = get_libc_builtin_export_apis(&native_symbols);
  1684. (void)(libc_funcs_count);
  1685. if (!functions) {
  1686. functions = wasm_runtime_malloc(sizeof(AOTExportFunctionInstance *) * BUILTIN_FUNC_ALLOC_STEP);
  1687. if (!functions)
  1688. return -1;
  1689. program->builtin_libc_funcs = (void**)functions;
  1690. program->builtin_libc_funcs_size = BUILTIN_FUNC_ALLOC_STEP;
  1691. }
  1692. for (i = 0; i < program->builtin_libc_funcs_count; i ++) {
  1693. if (func_name == functions[i]->u.func_import->func_name)
  1694. break;
  1695. }
  1696. if (i < program->builtin_libc_funcs_count) {
  1697. return i;
  1698. }
  1699. func_id = wasm_runtime_get_syssymbol_id(runtime, func_name);
  1700. if (func_id < WAMR_CSP_iprintf ||
  1701. func_id > WAMR_CSP_dlclose)
  1702. return -1;
  1703. func_import = wasm_runtime_malloc(sizeof(AOTImportFunc));
  1704. if (!func_import)
  1705. return -1;
  1706. linked_func = wasm_runtime_malloc(sizeof(AOTExportFunctionInstance));
  1707. if (!linked_func) {
  1708. wasm_runtime_free(func_import);
  1709. return -1;
  1710. }
  1711. memset(func_import, 0, sizeof(AOTImportFunc));
  1712. memset(linked_func, 0, sizeof(AOTExportFunctionInstance));
  1713. func_offset = func_id - WAMR_CSP_iprintf;
  1714. bh_assert(func_name == native_symbols[func_offset].u.symbol);
  1715. func_import->module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_env);
  1716. func_import->func_name = func_name;
  1717. func_import->signature = native_symbols[func_offset].signature;
  1718. func_import->func_type = NULL;
  1719. func_import->func_type_index = 0;
  1720. func_import->attachment = native_symbols[func_offset].attachment;
  1721. func_import->call_conv_raw = false;
  1722. func_import->call_conv_wasm_c_api = false;
  1723. func_import->wasm_c_api_with_env = false;
  1724. func_import->func_ptr_linked = native_symbols[func_offset].func_ptr;
  1725. linked_func->is_import_func = true;
  1726. linked_func->u.func_import = func_import;
  1727. linked_func->func_index = 0;
  1728. if ((program->builtin_libc_funcs_count + 1) > program->builtin_libc_funcs_size) {
  1729. functions = wasm_runtime_realloc(functions,
  1730. sizeof(WASMFunctionInstance *) * (program->builtin_libc_funcs_size + BUILTIN_FUNC_ALLOC_STEP));
  1731. if (!functions) {
  1732. wasm_runtime_free(func_import);
  1733. wasm_runtime_free(linked_func);
  1734. return -1;
  1735. }
  1736. program->builtin_libc_funcs_size += BUILTIN_FUNC_ALLOC_STEP;
  1737. program->builtin_libc_funcs = (void**)functions;
  1738. }
  1739. functions[program->builtin_libc_funcs_count] = linked_func;
  1740. ret_id = program->builtin_libc_funcs_count;
  1741. program->builtin_libc_funcs_count ++;
  1742. return ret_id;
  1743. }
  1744. #endif
  1745. #undef BUILTIN_FUNC_ALLOC_STEP
  1746. static void
  1747. wasm_program_destroy_internal_libc_module(WASMProgramInstance * program)
  1748. {
  1749. if (!program->builtin_libc_funcs)
  1750. return;
  1751. for(uint32 i = 0; i < program->builtin_libc_funcs_count; i++) {
  1752. if (!program->builtin_libc_funcs[i])
  1753. continue;
  1754. //WASMFunctionImport * func_import = program->builtin_libc_funcs[i]->u.func_import;
  1755. //if (func_import)
  1756. // wasm_runtime_free(func_import);
  1757. wasm_runtime_free(program->builtin_libc_funcs[i]);
  1758. }
  1759. wasm_runtime_free(program->builtin_libc_funcs);
  1760. }
  1761. #endif
  1762. bool
  1763. wasm_program_link_sp_wasm_globals(WASMProgramInstance * program,
  1764. WASMGlobalInstance * global,
  1765. const ConstStrDescription * field_name)
  1766. {
  1767. WASMRuntime * runtime = program->runtime;
  1768. WASMModuleInstance * root_module_inst = (WASMModuleInstance *)program->root_module_inst;
  1769. WASMGlobalInstance * export_global = NULL;
  1770. (void)runtime;
  1771. for (uint32 i = 0; i < root_module_inst->export_glob_count; i++) {
  1772. if (!program->config.root_is_AS_module) {
  1773. if (!strcmp(root_module_inst->export_globals[i].name, field_name->str)) {
  1774. export_global = root_module_inst->export_globals[i].global;
  1775. }
  1776. } else {
  1777. if (!strcmp(root_module_inst->export_globals[i].name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_user_stack_pointer))) {
  1778. export_global = root_module_inst->export_globals[i].global;
  1779. }
  1780. }
  1781. if (!export_global)
  1782. continue;
  1783. if (export_global->type != global->type ||
  1784. export_global->is_mutable != global->is_mutable)
  1785. return false;
  1786. // global->data_offset = root_module_inst->globals->data_offset;
  1787. if (export_global->is_mutable)
  1788. global->data = export_global->data;
  1789. else {
  1790. global->data = (uint8*)&root_module_inst->init_globals.stack_pointer;
  1791. }
  1792. return true;
  1793. }
  1794. return false;
  1795. }
  1796. #if WASM_ENABLE_AOT != 0
  1797. bool
  1798. wasm_program_link_sp_aot_globals(WASMProgramInstance * program,
  1799. uint8 * p_global_data,
  1800. const ConstStrDescription * global_name)
  1801. {
  1802. WASMRuntime * runtime = program->runtime;
  1803. AOTModuleInstance * root_module_inst = (AOTModuleInstance *)program->root_module_inst;
  1804. AOTModule * root_module = (AOTModule *)root_module_inst->aot_module.ptr;
  1805. uint32 global_id = 0, global_offset = 0;
  1806. uint8 * p_data = NULL;
  1807. if (root_module->export_sp_global_id >= root_module->export_count)
  1808. return false;
  1809. if (!program->config.root_is_AS_module) {
  1810. if (strcmp(root_module->exports[root_module->export_sp_global_id].name, global_name->str)) {
  1811. return false;
  1812. }
  1813. } else {
  1814. if (strcmp(root_module->exports[root_module->export_sp_global_id].name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_user_stack_pointer))) {
  1815. return false;
  1816. }
  1817. }
  1818. global_id = root_module->exports[root_module->export_sp_global_id].index;
  1819. global_offset = root_module->globals[global_id].data_offset;
  1820. p_data = (uint8*)root_module_inst->global_data.ptr + global_offset;
  1821. #if __WORDSIZE == 32
  1822. if (root_module->dylink_section)
  1823. *(uint32*)p_global_data = *(uint32*)p_data;
  1824. else
  1825. *(uint32*)p_global_data = (uintptr_t)p_data;
  1826. #else
  1827. if (root_module->dylink_section)
  1828. *(uint64*)p_global_data = *(uint64*)p_data;
  1829. else
  1830. *(uint64*)p_global_data = (uintptr_t)p_data;
  1831. #endif
  1832. return true;
  1833. }
  1834. bool
  1835. wasm_program_link_aot_got_globals(WASMProgramInstance * program,
  1836. AOTModuleInstance * module_inst,
  1837. uint8 * p_global_data,
  1838. const ConstStrDescription * field_name)
  1839. {
  1840. WASMRuntime * runtime = program->runtime;
  1841. AOTModuleInstance * root_module_inst = NULL;
  1842. AOTModule * root_module = NULL;
  1843. bool is_sys_symbol = wasm_runtime_is_system_symbol(runtime, field_name);
  1844. bool is_memop_symbol = wasm_runtime_is_memop_symbol(runtime, field_name);
  1845. int32 import_func_id = -1;
  1846. uint32 i = 0;
  1847. if (is_sys_symbol &&
  1848. (!is_memop_symbol ||
  1849. program->config.import_memop_mode == FROM_BUILTIN_LIBC)) {
  1850. #if WASM_ENABLE_LIBC_BUILTIN != 0
  1851. import_func_id = wasm_program_link_aot_internal_builtin_libc_func(program, field_name);
  1852. if (import_func_id < 0) {
  1853. return false;
  1854. }
  1855. *(uint32*)p_global_data = import_func_id + TABLE_SPACE_FOR_BUILTIN_LIBC;
  1856. return true;
  1857. #else
  1858. return false;
  1859. #endif
  1860. }
  1861. if (is_memop_symbol) {
  1862. bh_assert(program->config.import_memop_mode == FROM_ROOT);
  1863. root_module_inst = (AOTModuleInstance*)program->root_module_inst;
  1864. root_module = (AOTModule*)root_module_inst->aot_module.ptr;
  1865. AOTExportFunctionInstance * export_funcs = (AOTExportFunctionInstance *)root_module_inst->export_funcs.ptr;
  1866. for (i = 0; i < root_module->export_func_count; i++) {
  1867. if (!strcmp(export_funcs[i].func_name, field_name->str)) {
  1868. import_func_id = (int32)i;
  1869. break;
  1870. }
  1871. }
  1872. if (import_func_id == -1)
  1873. return false;
  1874. import_func_id += TABLE_SPACE_SLOT_SIZE - root_module->export_func_count;
  1875. *(uint32*)p_global_data = import_func_id;
  1876. return true;
  1877. }
  1878. // not sys symbol
  1879. // other module's export
  1880. return false;
  1881. }
  1882. #endif
  1883. bool
  1884. wasm_program_link_got_globals(WASMProgramInstance * program,
  1885. WASMModuleInstance * module_inst,
  1886. WASMGlobalInstance * global,
  1887. const ConstStrDescription * field_name)
  1888. {
  1889. WASMRuntime * runtime = program->runtime;
  1890. // WASMModule * wasm_module = module_inst->module;
  1891. // uint32 import_func_count = wasm_module->import_function_count;
  1892. int32 import_func_id = -1;
  1893. uint32 i = 0;
  1894. WASMModuleInstance * root_module_inst = NULL;
  1895. bool is_sys_symbol = wasm_runtime_is_system_symbol(runtime, field_name);
  1896. bool is_memop_symbol = wasm_runtime_is_memop_symbol(runtime, field_name);
  1897. if (is_sys_symbol &&
  1898. (!is_memop_symbol ||
  1899. program->config.import_memop_mode == FROM_BUILTIN_LIBC)) {
  1900. #if WASM_ENABLE_LIBC_BUILTIN != 0
  1901. import_func_id = wasm_program_link_internal_builtin_libc_func(program, field_name);
  1902. if (import_func_id < 0) {
  1903. return false;
  1904. }
  1905. global->initial_value.u32 = import_func_id + TABLE_SPACE_FOR_BUILTIN_LIBC;
  1906. return true;
  1907. #else
  1908. return false;
  1909. #endif
  1910. }
  1911. if (is_memop_symbol) {
  1912. bh_assert(program->config.import_memop_mode == FROM_ROOT);
  1913. root_module_inst = (WASMModuleInstance*)program->root_module_inst;
  1914. #if 0
  1915. if (program->config.root_is_AS_module) {
  1916. if (field_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_malloc))
  1917. field_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___alloc);
  1918. else if (field_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_free))
  1919. field_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___free);
  1920. else if (field_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_realloc))
  1921. field_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___realloc);
  1922. }
  1923. #endif
  1924. for (i = 0; i < root_module_inst->export_func_count; i++) {
  1925. if (!strcmp(root_module_inst->export_functions[i].name, field_name->str)) {
  1926. import_func_id = (int32)i;
  1927. break;
  1928. }
  1929. }
  1930. if (import_func_id == -1)
  1931. return false;
  1932. import_func_id += TABLE_SPACE_SLOT_SIZE - root_module_inst->export_func_count;
  1933. global->initial_value.u32 = import_func_id;
  1934. return true;
  1935. }
  1936. // not sys symbol
  1937. // other module's export
  1938. return false;
  1939. }
  1940. bool
  1941. check_symbol_signature(const WASMType *type, const char *signature);
  1942. bool
  1943. wasm_program_resolve_op_call_indirect(WASMProgramInstance * program,
  1944. WASMModuleInstance * module_inst,
  1945. uint32 tbl_idx,
  1946. int32 tbl_slot_id,
  1947. WASMType * func_type,
  1948. WASMModuleInstance ** p_callee_module_inst,
  1949. WASMFunctionInstance ** p_call_func)
  1950. {
  1951. uint32 inst_idx = 0, fidx = 0, export_func_id = 0;
  1952. WASMModuleInstance * callee_module_inst = NULL;
  1953. WASMFunctionInstance * call_func = NULL;
  1954. WASMTableInstance * tbl_inst = NULL;
  1955. WASMType * cur_func_type = NULL;
  1956. int32 origin_slot_id = 0;
  1957. bool is_local_func = true;
  1958. if (tbl_slot_id < 0) {
  1959. wasm_set_exception(module_inst, "undefined element");
  1960. return false;
  1961. }
  1962. inst_idx = (tbl_slot_id >> TABLE_SPACE_BITS_LEN) + 1;
  1963. origin_slot_id = tbl_slot_id;
  1964. if (program) {
  1965. // set --enable-dlopen
  1966. if (inst_idx == module_inst->inst_id) { // call self-module
  1967. callee_module_inst = module_inst;
  1968. tbl_slot_id -= (inst_idx - 1) * TABLE_SPACE_SLOT_SIZE;
  1969. tbl_inst = wasm_get_table_inst(callee_module_inst, tbl_idx);
  1970. } else if (inst_idx == BUILTIN_LIBC_INST_ID) { // call libc function pointer
  1971. is_local_func = false;
  1972. fidx = tbl_slot_id - (inst_idx - 1) * TABLE_SPACE_SLOT_SIZE;
  1973. if (fidx >= program->builtin_libc_funcs_count) {
  1974. wasm_set_exception(module_inst, "undefined element");
  1975. return false;
  1976. }
  1977. call_func = program->builtin_libc_funcs[fidx];
  1978. if (!call_func) {
  1979. wasm_set_exception(module_inst, "undefined element");
  1980. return false;
  1981. }
  1982. if (call_func->u.func_import->func_type) {
  1983. if (!wasm_type_equal(func_type, call_func->u.func_import->func_type)) {
  1984. wasm_set_exception(module_inst, "indirect call type mismatch");
  1985. return false;
  1986. }
  1987. } else {
  1988. if (!check_symbol_signature(func_type, call_func->u.func_import->signature))
  1989. return false;
  1990. call_func->u.func_import->func_type = func_type;
  1991. call_func->func_type = func_type;
  1992. }
  1993. callee_module_inst = module_inst;
  1994. *p_callee_module_inst = callee_module_inst;
  1995. *p_call_func = call_func;
  1996. wasm_program_cache_resolve_result(program, origin_slot_id, call_func, callee_module_inst);
  1997. return true;
  1998. } else if (inst_idx > 1) { // call dependency module
  1999. // call export function by non root module
  2000. callee_module_inst = (WASMModuleInstance*)wasm_program_get_module_inst_by_id(program, inst_idx);
  2001. if (!callee_module_inst) {
  2002. wasm_set_exception(module_inst, "undefined element");
  2003. return false;
  2004. }
  2005. bh_assert(callee_module_inst->module->dylink_section);
  2006. tbl_slot_id -= (inst_idx - 1) * TABLE_SPACE_SLOT_SIZE;
  2007. if (program->config.use_tbl_as_cache) {
  2008. //if (tbl_slot_id >= (int32)callee_module_inst->module->dylink_section->table_size) {
  2009. tbl_slot_id -= TABLE_SPACE_SLOT_SIZE - callee_module_inst->default_table->max_size;
  2010. if ((uint32)tbl_slot_id < (callee_module_inst->default_table->max_size -
  2011. callee_module_inst->export_func_count)) {
  2012. wasm_set_exception(module_inst, "wrong export function id");
  2013. return false;
  2014. }
  2015. //}
  2016. tbl_inst = wasm_get_table_inst(callee_module_inst, tbl_idx);
  2017. } else {
  2018. is_local_func = false;
  2019. tbl_slot_id = callee_module_inst->export_func_count - (TABLE_SPACE_SLOT_SIZE - tbl_slot_id);
  2020. }
  2021. } else {
  2022. // call root module
  2023. if (!tbl_slot_id) {
  2024. wasm_set_exception(module_inst, "uninitialized element");
  2025. return false;
  2026. }
  2027. callee_module_inst = (WASMModuleInstance*)program->root_module_inst;
  2028. if (callee_module_inst->module->dylink_section &&
  2029. program->config.use_tbl_as_cache) {
  2030. tbl_inst = wasm_get_table_inst(callee_module_inst, tbl_idx);
  2031. bh_assert(program->config.import_memop_mode != FROM_ROOT);
  2032. if (tbl_slot_id > ((int32)callee_module_inst->module->dylink_section->table_size)) {
  2033. tbl_slot_id -= TABLE_SPACE_SLOT_SIZE - callee_module_inst->default_table->max_size;
  2034. }
  2035. } else if (program->config.import_memop_mode == FROM_ROOT ||
  2036. !program->config.use_tbl_as_cache) {
  2037. is_local_func = false;
  2038. tbl_slot_id = callee_module_inst->export_func_count - (TABLE_SPACE_SLOT_SIZE - tbl_slot_id);
  2039. } else {
  2040. wasm_set_exception(module_inst, "root module is not shared module");
  2041. return false;
  2042. }
  2043. }
  2044. } else {
  2045. callee_module_inst = module_inst;
  2046. tbl_inst = wasm_get_table_inst(callee_module_inst, tbl_idx);
  2047. }
  2048. if (!tbl_inst) { // func not in table
  2049. if (!callee_module_inst->export_functions[tbl_slot_id].function) {
  2050. wasm_set_exception(module_inst, "uninitialized element");
  2051. return false;
  2052. }
  2053. fidx = (callee_module_inst->export_functions[tbl_slot_id].function -
  2054. callee_module_inst->functions);
  2055. } else {
  2056. if (tbl_slot_id < 0 ||
  2057. (tbl_slot_id >= (int32)tbl_inst->cur_size
  2058. )) {
  2059. wasm_set_exception(module_inst, "undefined element");
  2060. return false;
  2061. }
  2062. fidx = ((uint32*)tbl_inst->base_addr)[tbl_slot_id];
  2063. }
  2064. if (fidx == (uint32)-1) {
  2065. if (!program) {
  2066. wasm_set_exception(module_inst, "uninitialized element");
  2067. return false;
  2068. }
  2069. if (inst_idx < 1) {
  2070. wasm_set_exception(module_inst, "uninitialized element");
  2071. return false;
  2072. }
  2073. if (callee_module_inst->module->dylink_section) {
  2074. if (tbl_slot_id < (int32)(tbl_inst->cur_size - callee_module_inst->export_func_count)) {
  2075. wasm_set_exception(module_inst, "uninitialized element");
  2076. return false;
  2077. }
  2078. } else if (tbl_slot_id < (int32)tbl_inst->cur_size) {
  2079. wasm_set_exception(module_inst, "uninitialized element");
  2080. return false;
  2081. }
  2082. if (program->config.binding_mode != LAZY_BINDING) {
  2083. wasm_set_exception(module_inst, "uninitialized element");
  2084. return false;
  2085. }
  2086. export_func_id = tbl_slot_id - (callee_module_inst->default_table->max_size -
  2087. callee_module_inst->export_func_count);
  2088. if (!callee_module_inst->export_functions[export_func_id].function) {
  2089. wasm_set_exception(module_inst, "uninitialized element");
  2090. return false;
  2091. }
  2092. // lazy link
  2093. fidx = (callee_module_inst->export_functions[export_func_id].function -
  2094. callee_module_inst->functions);
  2095. ((uint32*)tbl_inst->base_addr)[tbl_slot_id] = fidx;
  2096. }
  2097. if (fidx >= callee_module_inst->function_count) {
  2098. wasm_set_exception(module_inst, "unknown function");
  2099. return false;
  2100. }
  2101. /* always call module own functions */
  2102. call_func = callee_module_inst->functions + fidx;
  2103. cur_func_type = call_func->func_type;
  2104. if (!wasm_type_equal(func_type, cur_func_type)) {
  2105. wasm_set_exception(module_inst, "indirect call type mismatch");
  2106. return false;
  2107. }
  2108. *p_callee_module_inst = callee_module_inst;
  2109. *p_call_func = call_func;
  2110. if (!is_local_func) {
  2111. wasm_program_cache_resolve_result(program, origin_slot_id, call_func, callee_module_inst);
  2112. }
  2113. return true;
  2114. }
  2115. #if WASM_ENABLE_AOT != 0
  2116. bool
  2117. wasm_program_resolve_aot_op_call_indirect(WASMExecEnv *exec_env,
  2118. WASMProgramInstance * program,
  2119. AOTModuleInstance * module_inst,
  2120. uint32 tbl_idx,
  2121. int32 table_elem_idx,
  2122. uint32 expected_type_idx,
  2123. AOTFuncType * expected_func_type,
  2124. AOTModuleInstance ** p_callee_module_inst,
  2125. AOTModule ** p_callee_module,
  2126. uint32 * p_call_func_index,
  2127. AOTImportFunc ** p_import_func)
  2128. {
  2129. AOTModuleInstance * callee_module_inst = NULL;
  2130. AOTModule* callee_module = NULL;
  2131. AOTModule *aot_module = (AOTModule*)module_inst->aot_module.ptr;
  2132. AOTExportFunctionInstance * export_funcs = NULL, *call_func = NULL;
  2133. AOTFuncType * func_type = NULL;
  2134. AOTTableInstance *tbl_inst = NULL;
  2135. uint32 inst_id = 0, export_func_id, local_table_elem_cnt;
  2136. uint32 func_idx = 0, func_type_idx;
  2137. void **func_ptrs = NULL, *func_ptr = NULL;
  2138. AOTImportFunc *import_func = NULL;
  2139. uint32 *func_type_indexes = NULL;
  2140. char buf[96];
  2141. int32 origin_elem_idx = table_elem_idx;
  2142. if (table_elem_idx < 0) {
  2143. aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
  2144. return false;
  2145. }
  2146. inst_id = (table_elem_idx >> TABLE_SPACE_BITS_LEN) + 1;
  2147. if (program) {
  2148. if (inst_id == module_inst->inst_id) {
  2149. callee_module_inst = module_inst;
  2150. callee_module = (AOTModule*)callee_module_inst->aot_module.ptr;
  2151. table_elem_idx -= (inst_id - 1) * TABLE_SPACE_SLOT_SIZE;
  2152. tbl_inst = aot_get_table_inst(callee_module_inst, tbl_idx);
  2153. } else if (inst_id == BUILTIN_LIBC_INST_ID) { // call libc function pointer
  2154. //is_intable_func = false;
  2155. func_idx = table_elem_idx - (inst_id - 1) * TABLE_SPACE_SLOT_SIZE;
  2156. if (func_idx >= program->builtin_libc_funcs_count) {
  2157. aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
  2158. return false;
  2159. }
  2160. call_func = program->builtin_libc_funcs[func_idx];
  2161. if (!call_func) {
  2162. aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
  2163. return false;
  2164. }
  2165. if (call_func->u.func_import->func_type) {
  2166. if (!wasm_type_equal(expected_func_type, call_func->u.func_import->func_type)) {
  2167. aot_set_exception(module_inst, "indirect call type mismatch");
  2168. return false;
  2169. }
  2170. } else {
  2171. if (!check_symbol_signature(expected_func_type, call_func->u.func_import->signature))
  2172. return false;
  2173. call_func->u.func_import->func_type = expected_func_type;
  2174. }
  2175. callee_module_inst = module_inst;
  2176. *p_callee_module_inst = callee_module_inst;
  2177. *p_call_func_index = 0;
  2178. *p_import_func = call_func->u.func_import;
  2179. wasm_program_cache_resolve_result(program, origin_elem_idx, (*p_import_func)->func_ptr_linked, callee_module_inst);
  2180. return true;
  2181. } else if (inst_id > 1) {
  2182. callee_module_inst = (AOTModuleInstance*)wasm_program_get_module_inst_by_id(program, inst_id);
  2183. if (!callee_module_inst) {
  2184. aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
  2185. return false;
  2186. }
  2187. callee_module = (AOTModule*)callee_module_inst->aot_module.ptr;
  2188. table_elem_idx -= (inst_id - 1) * TABLE_SPACE_SLOT_SIZE;
  2189. if (program->config.use_tbl_as_cache) {
  2190. tbl_inst = aot_get_table_inst(callee_module_inst, tbl_idx);
  2191. bh_assert(tbl_inst);
  2192. local_table_elem_cnt = (uint32)callee_module->dylink_section->table_size;
  2193. if (wasm_program_is_root_module((WASMModuleInstanceCommon*)callee_module_inst))
  2194. local_table_elem_cnt ++;
  2195. if ((uint32)table_elem_idx >= local_table_elem_cnt) {
  2196. table_elem_idx -= TABLE_SPACE_SLOT_SIZE - tbl_inst->max_size;
  2197. if ((uint32)table_elem_idx < (tbl_inst->max_size -
  2198. callee_module->export_func_count)) {
  2199. aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
  2200. return false;
  2201. }
  2202. }
  2203. } else {
  2204. table_elem_idx = callee_module->export_func_count - (TABLE_SPACE_SLOT_SIZE - table_elem_idx);
  2205. }
  2206. } else {
  2207. if (!table_elem_idx) {
  2208. aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
  2209. return false;
  2210. }
  2211. callee_module_inst = (AOTModuleInstance*)program->root_module_inst;
  2212. callee_module = (AOTModule*)callee_module_inst->aot_module.ptr;
  2213. if (callee_module->dylink_section &&
  2214. program->config.use_tbl_as_cache) {
  2215. tbl_inst = aot_get_table_inst(callee_module_inst, tbl_idx);
  2216. if ((uint32)table_elem_idx > callee_module->dylink_section->table_size) {
  2217. table_elem_idx -= TABLE_SPACE_SLOT_SIZE - tbl_inst->max_size;
  2218. }
  2219. } else if (program->config.import_memop_mode == FROM_ROOT ||
  2220. !program->config.use_tbl_as_cache) {
  2221. table_elem_idx = callee_module->export_func_count - (TABLE_SPACE_SLOT_SIZE - table_elem_idx);
  2222. } else {
  2223. aot_set_exception(module_inst, "root module is not shared module");
  2224. return false;
  2225. }
  2226. }
  2227. } else {
  2228. callee_module_inst = module_inst;
  2229. callee_module = aot_module;
  2230. /* this function is called from native code, so exec_env->handle and
  2231. exec_env->native_stack_boundary must have been set, we don't set
  2232. it again */
  2233. if ((uint8*)&callee_module_inst < exec_env->native_stack_boundary) {
  2234. aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
  2235. return false;
  2236. }
  2237. tbl_inst = aot_get_table_inst(callee_module_inst, tbl_idx);
  2238. bh_assert(tbl_inst);
  2239. if ((uint32)table_elem_idx >= tbl_inst->cur_size) {
  2240. aot_set_exception_with_id(callee_module_inst, EXCE_UNDEFINED_ELEMENT);
  2241. return false;
  2242. }
  2243. }
  2244. if (!tbl_inst) {
  2245. export_funcs = (AOTExportFunctionInstance*)callee_module_inst->export_funcs.ptr;
  2246. func_idx = export_funcs[table_elem_idx].func_index;
  2247. } else {
  2248. if (table_elem_idx < 0 ||
  2249. table_elem_idx >= (int32)tbl_inst->cur_size) {
  2250. aot_set_exception_with_id(callee_module_inst, EXCE_UNDEFINED_ELEMENT);
  2251. return false;
  2252. }
  2253. bh_assert( ((uint32*)tbl_inst->data + table_elem_idx) < (uint32*)callee_module_inst->global_table_data_end.ptr);
  2254. func_idx = ((uint32*)tbl_inst->data)[table_elem_idx];
  2255. }
  2256. if (func_idx == (uint32)-1) {
  2257. if (!program) {
  2258. aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
  2259. return false;
  2260. }
  2261. if (inst_id < 1) {
  2262. aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
  2263. return false;
  2264. }
  2265. if (callee_module->dylink_section) {
  2266. if ((uint32)table_elem_idx < (tbl_inst->cur_size - callee_module->export_func_count)) {
  2267. aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
  2268. return false;
  2269. }
  2270. } else if ((uint32)table_elem_idx < tbl_inst->cur_size) {
  2271. aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
  2272. return false;
  2273. }
  2274. if (program->config.binding_mode != LAZY_BINDING) {
  2275. aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
  2276. return false;
  2277. }
  2278. export_func_id = table_elem_idx - (tbl_inst->max_size -
  2279. callee_module->export_func_count);
  2280. export_funcs = (AOTExportFunctionInstance*)callee_module_inst->export_funcs.ptr;
  2281. if (export_func_id >= callee_module->export_func_count) {
  2282. aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
  2283. return false;
  2284. }
  2285. // lazy link
  2286. func_idx = export_funcs[export_func_id].func_index;
  2287. ((uint32*)tbl_inst->data)[table_elem_idx] = func_idx;
  2288. }
  2289. // aot_module = (AOTModule*)callee_module_inst->aot_module.ptr;
  2290. func_ptrs = (void**)callee_module_inst->func_ptrs.ptr;
  2291. func_type_indexes = (uint32*)callee_module_inst->func_type_indexes.ptr;
  2292. func_type_idx = func_type_indexes[func_idx];
  2293. func_type = callee_module->func_types[func_type_idx];
  2294. if (!(func_ptr = func_ptrs[func_idx])) {
  2295. bh_assert(func_idx < callee_module->import_func_count);
  2296. import_func = callee_module->import_funcs + func_idx;
  2297. snprintf(buf, sizeof(buf),
  2298. "failed to call unlinked import function (%s, %s)",
  2299. import_func->module_name->str, import_func->func_name->str);
  2300. aot_set_exception(module_inst, buf);
  2301. return false;
  2302. }
  2303. if (module_inst->inst_id == callee_module_inst->inst_id && expected_type_idx != func_type_idx) {
  2304. aot_set_exception_with_id(module_inst, EXCE_INVALID_FUNCTION_TYPE_INDEX);
  2305. return false;
  2306. } else if (module_inst->inst_id != callee_module_inst->inst_id) {
  2307. if (!wasm_type_equal(expected_func_type, func_type)) {
  2308. aot_set_exception_with_id(module_inst, EXCE_INVALID_FUNCTION_TYPE_INDEX);
  2309. return false;
  2310. }
  2311. }
  2312. *p_callee_module_inst = callee_module_inst;
  2313. *p_callee_module = callee_module;
  2314. *p_call_func_index = func_idx;
  2315. *p_import_func = NULL;
  2316. wasm_program_cache_resolve_result(program, origin_elem_idx,
  2317. ((void**)(*p_callee_module_inst)->func_ptrs.ptr)[func_idx],
  2318. callee_module_inst);
  2319. return true;
  2320. }
  2321. #if WASM_ENABLE_LIBC_BUILTIN != 0
  2322. uint32
  2323. wasm_program_get_ctype_tolower_mem(WASMModuleInstanceCommon * module_inst)
  2324. {
  2325. WASMProgramInstance * program = ((WASMModuleInstanceHead*)module_inst)->program;
  2326. if (!program)
  2327. return 0;
  2328. return program->ctype_tolower_loc_space;
  2329. }
  2330. void
  2331. wasm_program_set_ctype_tolower_mem(WASMModuleInstanceCommon * module_inst, uint32 addr)
  2332. {
  2333. WASMProgramInstance * program = ((WASMModuleInstanceHead*)module_inst)->program;
  2334. if (!program)
  2335. return;
  2336. program->ctype_tolower_loc_space = addr;
  2337. }
  2338. #endif
  2339. #endif
  2340. #endif