| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836 |
- #include "bh_common.h"
- #include "bh_assert.h"
- #include "bh_log.h"
- #include "wasm_multimodules_program.h"
- #if WASM_ENABLE_INTERP != 0
- #include "../interpreter/wasm_runtime.h"
- #endif
- #if WASM_ENABLE_AOT != 0
- #include "../aot/aot_runtime.h"
- #endif
- #define RUNTIME_CONST_STR_POOL_INIT_SIZE 128
- #define RUNTIME_NAME_MODULE_MAP_INIT_SIZE 32
- #define PROGRAM_NAME_MODULE_INST_INIT_SIZE 16
- #define PROGRAM_INST_IDX_VECTOR_INIT_SIZE 64
- #define PROGRAM_INST_ID_HMAP_INIT_SIZE 32
- #define PROGRAM_INST_ID_TOP_BOUNARY MAX_INST_ID
- static WASMRuntime * g_runtime = NULL;
- inline static uint32
- inst_id_hash(void * node)
- {
- uint32 h = ((uintptr_t)node) & (PROGRAM_INST_ID_HMAP_INIT_SIZE - 1);
- return h;
- }
- inline static bool
- inst_id_equal(void * node1, void * node2)
- {
- return ((uintptr_t)node1 == (uintptr_t)node2);
- }
- static void
- set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
- {
- if (error_buf != NULL)
- snprintf(error_buf, error_buf_size, "%s", string);
- }
- #if WASM_ENABLE_DYNAMIC_LINKING != 0
- static void
- set_error_buf_v(char *error_buf, uint32 error_buf_size,
- const char *format, ...)
- {
- va_list args;
- char buf[128];
- if (error_buf != NULL) {
- va_start(args, format);
- vsnprintf(buf, sizeof(buf), format, args);
- va_end(args);
- snprintf(error_buf, error_buf_size,
- "WASM module instantiate failed: %s", buf);
- }
- }
- #endif
- static void *
- runtime_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
- {
- void *mem;
- if (size >= UINT32_MAX
- || !(mem = wasm_runtime_malloc((uint32)size))) {
- set_error_buf(error_buf, error_buf_size,
- "allocate memory failed");
- return NULL;
- }
- memset(mem, 0, (uint32)size);
- return mem;
- }
- inline static WASMModuleInstanceCommon *
- dylib_entries_map_find(const ConstStrDescription * key, HashMap *map)
- {
- return bh_hash_map_find(map, (void*)key);
- }
- inline static bool
- dylib_entries_map_insert(const ConstStrDescription * key,
- const WASMModuleInstanceCommon * module_inst,
- HashMap *map)
- {
- //char *value;
- //ConstStrDescription * key = NULL;
- //if ((bh_hash_map_find(map, (void*)tmp_key))) {
- // return true;
- //}
- //if (!(key = runtime_malloc(sizeof(ConstStrDescription),
- // NULL, 0))) {
- // return false;
- //}
- //bh_memcpy_s(key, sizeof(ConstStrDescription), tmp_key, sizeof(ConstStrDescription));
- if (!bh_hash_map_insert_with_dup(map, (void*)key, (void*)module_inst)) {
- // wasm_runtime_free(key);
- return false;
- }
- return true;
- }
- void
- wasm_runtime_set_module_reader(const module_reader reader_cb,
- const module_destroyer destroyer_cb)
- {
- g_runtime->reader = (void*)reader_cb;
- g_runtime->destroyer = (void*)destroyer_cb;
- }
- module_reader
- wasm_runtime_get_module_reader()
- {
- return (module_reader)g_runtime->reader;
- }
- module_destroyer
- wasm_runtime_get_module_destroyer()
- {
- return (module_destroyer)g_runtime->destroyer;
- }
- bool
- init_const_string_index_array(WASMRuntime * runtime)
- {
- ConstStrDescription * key = NULL;
- const char * c_str = NULL;
- uint32 index_array_size = WAMR_CSP_SYMBOLS_end;
- uint32 i = 0;
- runtime->global_const_str_index_array =
- wasm_runtime_malloc(sizeof(ConstStrDescription) * index_array_size);
- if (!runtime->global_const_str_index_array) {
- return false;
- }
- memset(runtime->global_const_str_index_array, 0, sizeof(ConstStrDescription) * index_array_size);
- c_str = wasm_init_symbols;
- for (i = 0; i < WAMR_CSP_SYMBOLS_end; i ++) {
- key = &runtime->global_const_str_index_array[i];
- key->len = strlen(c_str);
- key->str = c_str;
- key->hash = 0;
- key->is_sys_symbol = true;
- if (!bh_hash_map_insert_with_dup(runtime->global_const_str_pool, key, (void*)key))
- return false;
- c_str += (strlen(c_str) + 1);
- }
- runtime->csp_free_index = i;
- runtime->csp_strings_count = i;
- runtime->csp_size = index_array_size;
- return true;
- }
- bool
- wasm_runtime_is_system_symbol(WASMRuntime * runtime, const ConstStrDescription * key)
- {
- if (key >= &runtime->global_const_str_index_array[0] &&
- key <= &runtime->global_const_str_index_array[WAMR_CSP_SYMBOLS_end - 1])
- return true;
- return false;
- }
- bool
- wasm_runtime_is_memop_symbol(WASMRuntime * runtime, const ConstStrDescription * key)
- {
- if (key == CONST_STR_POOL_DESC(runtime, WAMR_CSP_malloc) ||
- key == CONST_STR_POOL_DESC(runtime, WAMR_CSP_free) ||
- key == CONST_STR_POOL_DESC(runtime, WAMR_CSP_realloc))
- return true;
- return false;
- }
- uint32
- wasm_runtime_get_syssymbol_id(WASMRuntime * runtime, const ConstStrDescription * key)
- {
- return (uint32)(key - runtime->global_const_str_index_array);
- }
- WASMModuleCommon *
- wasm_runtime_get_module_by_name(WASMRuntime * runtime, const ConstStrDescription * module_name)
- {
- WASMModuleCommon * module = NULL;
- module = bh_hash_map_find(runtime->all_loaded_modules, (void*)module_name);
- return module;
- }
- bool
- wasm_runtime_const_str_pool_init(WASMRuntime * runtime)
- {
- if (!runtime)
- return false;
- runtime->global_const_str_pool =
- bh_hash_map_create(RUNTIME_CONST_STR_POOL_INIT_SIZE,
- false,
- (HashFunc)const_str_hash,
- (KeyEqualFunc)const_str_equal,
- (ValueDestroyFunc)const_str_destroy_key,
- NULL);
- if (!runtime->global_const_str_pool)
- return false;
- if (!init_const_string_index_array(runtime)) {
- bh_hash_map_destroy(runtime->global_const_str_pool);
- return false;
- }
- return true;
- }
- void
- wasm_runtime_const_str_pool_destroy(WASMRuntime * runtime)
- {
- if (!runtime)
- return;
- if (runtime->global_const_str_pool)
- bh_hash_map_destroy(runtime->global_const_str_pool);
- if (runtime->global_const_str_index_array)
- wasm_runtime_free(runtime->global_const_str_index_array);
- runtime->global_const_str_pool = NULL;
- runtime->global_const_str_index_array = NULL;
- runtime->csp_size = 0;
- runtime->csp_free_index = 0;
- runtime->csp_strings_count = 0;
- }
- uint32
- records_const_string_index(WASMRuntime * runtime,
- const ConstStrDescription * csp_desc)
- {
- #if 0
- uint32 ret_index = 0;
- uint32 new_size = 0;
- if (runtime->csp_strings_count >= runtime->csp_size) {
- new_size = (runtime->csp_size * 3) / 2;
- runtime->global_const_str_index_array =
- wasm_runtime_realloc(runtime->global_const_str_index_array,
- sizeof(ConstStrDescription*) * new_size);
- if (!runtime->global_const_str_index_array)
- return 0;
- runtime->csp_size = new_size;
- }
- bh_assert(runtime->csp_strings_count < runtime->csp_size);
- ret_index = runtime->csp_free_index;
- runtime->global_const_str_index_array[ret_index] = (ConstStrDescription *)csp_desc;
- runtime->csp_strings_count ++;
- runtime->csp_free_index ++ ;
- return ret_index;
- #endif
- return 0;
- }
- static bool
- check_utf8_str(const uint8* str, uint32 len)
- {
- /* The valid ranges are taken from page 125, below link
- https://www.unicode.org/versions/Unicode9.0.0/ch03.pdf */
- const uint8 *p = str, *p_end = str + len;
- uint8 chr;
- while (p < p_end) {
- chr = *p;
- if (chr < 0x80) {
- p++;
- }
- else if (chr >= 0xC2 && chr <= 0xDF && p + 1 < p_end) {
- if (p[1] < 0x80 || p[1] > 0xBF) {
- return false;
- }
- p += 2;
- }
- else if (chr >= 0xE0 && chr <= 0xEF && p + 2 < p_end) {
- if (chr == 0xE0) {
- if (p[1] < 0xA0 || p[1] > 0xBF
- || p[2] < 0x80 || p[2] > 0xBF) {
- return false;
- }
- }
- else if (chr == 0xED) {
- if (p[1] < 0x80 || p[1] > 0x9F
- || p[2] < 0x80 || p[2] > 0xBF) {
- return false;
- }
- }
- else if (chr >= 0xE1 && chr <= 0xEF) {
- if (p[1] < 0x80 || p[1] > 0xBF
- || p[2] < 0x80 || p[2] > 0xBF) {
- return false;
- }
- }
- p += 3;
- }
- else if (chr >= 0xF0 && chr <= 0xF4 && p + 3 < p_end) {
- if (chr == 0xF0) {
- if (p[1] < 0x90 || p[1] > 0xBF
- || p[2] < 0x80 || p[2] > 0xBF
- || p[3] < 0x80 || p[3] > 0xBF) {
- return false;
- }
- }
- else if (chr >= 0xF1 && chr <= 0xF3) {
- if (p[1] < 0x80 || p[1] > 0xBF
- || p[2] < 0x80 || p[2] > 0xBF
- || p[3] < 0x80 || p[3] > 0xBF) {
- return false;
- }
- }
- else if (chr == 0xF4) {
- if (p[1] < 0x80 || p[1] > 0x8F
- || p[2] < 0x80 || p[2] > 0xBF
- || p[3] < 0x80 || p[3] > 0xBF) {
- return false;
- }
- }
- p += 4;
- }
- else {
- return false;
- }
- }
- return (p == p_end);
- }
- const ConstStrDescription *
- wasm_runtime_records_const_filename_string(WASMRuntime * runtime,
- const char * str, const uint32 len,
- char* error_buf, uint32 error_buf_size)
- {
- int no_postfix_len = len;
- for (int i = len - 1; i >= 0; i --) {
- if (str[i] == '.') {
- no_postfix_len = i;
- break;
- }
- }
- if (!no_postfix_len)
- no_postfix_len = len;
- return wasm_runtime_records_const_string(runtime, str, no_postfix_len,
- error_buf, error_buf_size);
- }
- const ConstStrDescription *
- wasm_runtime_records_const_string(WASMRuntime * runtime,
- const char * str, const uint32 len,
- char* error_buf, uint32 error_buf_size)
- {
- HashMap * pool = NULL;
- char *c_str, *value;
- ConstStrDescription temp_key;
- ConstStrDescription * key = NULL;
- uint32 req_size = 0;
- if (!runtime)
- return NULL;
- pool = runtime->global_const_str_pool;
- if (!pool)
- return NULL;
- if (!check_utf8_str((const uint8 *)str, len)) {
- set_error_buf(error_buf, error_buf_size,
- "invalid UTF-8 encoding");
- return NULL;
- }
- bh_assert(len < (UINT_MAX/2));
- temp_key.str = (void*)str;
- temp_key.is_sys_symbol = false;
- temp_key.len = len;
- temp_key.hash = 0;
- if ((value = bh_hash_map_find(pool, &temp_key))) {
- return (ConstStrDescription *)value;
- }
- req_size = sizeof(ConstStrDescription) + (uint32)len + 1;
- if (!(key = runtime_malloc(req_size, error_buf, error_buf_size))) {
- return NULL;
- }
- memset(key, 0, req_size);
- //c_str = key->data;
- c_str = (char*)(key + 1);
- bh_memcpy_s(c_str, (uint32)(len + 1), str, (uint32)len);
- key->str = c_str;
- key->len = len;
- key->hash = temp_key.hash;
- key->is_sys_symbol = false;
- if (!bh_hash_map_insert(pool, key, key)) {
- set_error_buf(error_buf, error_buf_size,
- "failed to insert string to hash map");
- wasm_runtime_free(key);
- return NULL;
- }
- return key;
- }
- WASMRuntime *
- wasm_runtime_get_runtime()
- {
- return g_runtime;
- }
- bool
- wasm_runtime_runtime_init(bool standalone, bool auto_ext_name)
- {
- if (g_runtime)
- return false;
- WASMRuntime * runtime = NULL;
- runtime = wasm_runtime_malloc(sizeof(WASMRuntime));
- if (!runtime)
- return false;
- memset(runtime, 0, sizeof(WASMRuntime));
- runtime->config.need_load_dependencies = !standalone;
- runtime->config.auto_update_extension = auto_ext_name;
- #if WASM_ENABLE_DYNAMIC_LINKING != 0
- runtime->cur_loading_program = NULL;
- #endif
- runtime->reader = NULL;
- runtime->destroyer = NULL;
- runtime->all_loaded_modules = NULL;
- if (!standalone) {
- runtime->all_loaded_modules =
- bh_hash_map_create(RUNTIME_NAME_MODULE_MAP_INIT_SIZE,
- false,
- (HashFunc)const_str_hash,
- (KeyEqualFunc)const_str_equal,
- NULL,
- (ValueDestroyFunc)const_str_destroy_module);
- if (!runtime->all_loaded_modules) {
- wasm_runtime_free(runtime);
- return false;
- }
- }
- if (!wasm_runtime_const_str_pool_init(runtime)) {
- wasm_runtime_runtime_destroy();
- return false;
- }
- g_runtime = runtime;
- return true;
- }
- void
- wasm_runtime_runtime_destroy()
- {
- if (!g_runtime)
- return;
- if (g_runtime->all_loaded_modules)
- bh_hash_map_destroy(g_runtime->all_loaded_modules);
- wasm_runtime_const_str_pool_destroy(g_runtime);
- wasm_runtime_free(g_runtime);
- g_runtime = NULL;
- }
- // shared module means built with -Wl,--shared.
- // dependency module means opened explicitly or implicitly by other module.
- // root module means the first module instantiated by a program.
- bool
- wasm_runtime_is_shared_module(const WASMModuleCommon * module)
- {
- WASMDylinkSection * dylink_section = NULL;
- if (module->module_type == Wasm_Module_Bytecode) {
- dylink_section = ((WASMModule*)module)->dylink_section;
- } else {
- #if WASM_ENABLE_AOT != 0
- dylink_section = ((AOTModule*)module)->dylink_section;
- #endif
- }
- if (dylink_section)
- return true;
- return false;
- }
- bool
- wasm_runtime_is_shared_module_instance(const WASMModuleInstanceCommon * module_inst)
- {
- WASMDylinkSection * dylink_section = NULL;
- if (module_inst->module_type == Wasm_Module_Bytecode) {
- WASMModule * module = (WASMModule *)(((WASMModuleInstance*)module_inst)->module);
- dylink_section = (module)->dylink_section;
- } else {
- #if WASM_ENABLE_AOT != 0
- AOTModule * module = (AOTModule*)(((AOTModuleInstance*)module_inst)->aot_module.ptr);
- dylink_section = (module)->dylink_section;
- #endif
- }
- if (dylink_section)
- return true;
- return false;
- }
- #if WASM_ENABLE_DYNAMIC_LINKING != 0
- inline bool
- wasm_program_is_root_module(const WASMModuleInstanceCommon * module_inst)
- {
- const WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
- if (module_inst_head->program) {
- if (module_inst_head->program->root_module_inst)
- return module_inst_head->program->root_module_inst == module_inst;
- else
- return true;
- } else
- return true;
- }
- inline WASMModuleInstanceCommon *
- wasm_program_get_root_module_from_inst(const WASMModuleInstanceCommon * module_inst)
- {
- WASMProgramInstance * program = ((WASMModuleInstanceHead*)module_inst)->program;
- if (!program)
- return (WASMModuleInstanceCommon *)module_inst;
- return program->root_module_inst;
- }
- inline WASMModuleInstanceCommon *
- wasm_program_get_root_module(const WASMProgramInstance * program)
- {
- return program->root_module_inst;
- }
- inline void
- wasm_program_set_root_module(WASMProgramInstance * program, const WASMModuleInstanceCommon * module_inst)
- {
- program->root_module_inst = (WASMModuleInstanceCommon*)module_inst;
- }
- bool
- wasm_program_validate_mode_compatiability(WASMProgramInstance * program)
- {
- WASMRuntime * runtime = program->runtime;
- WASMModuleInstanceCommon * root_module_inst = program->root_module_inst;
- const char * symbol_name = NULL;
- bool malloc_exist = false;
- bool free_exist = false;
- bool realloc_exist = false;
- bool export_sp_exist = false;
- WASMModuleInstance * wasm_module_inst = NULL;
- #if WASM_ENABLE_AOT != 0
- AOTModuleInstance * aot_module_inst = NULL;
- #endif
- if (root_module_inst->module_type == Wasm_Module_Bytecode) {
- wasm_module_inst = (WASMModuleInstance *)root_module_inst;
- for (uint32 i = 0; i < wasm_module_inst->export_func_count; i ++) {
- symbol_name = wasm_module_inst->export_functions[i].name;
- if (symbol_name) {
- if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_malloc)))
- malloc_exist = true;
- else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_free)))
- free_exist = true;
- else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_realloc)))
- realloc_exist = true;
- if (program->config.root_is_AS_module) {
- if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___alloc)))
- malloc_exist = true;
- else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___free)))
- free_exist = true;
- else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___realloc)))
- realloc_exist = true;
- }
- if (malloc_exist && free_exist && realloc_exist)
- break;
- }
- }
- for (uint32 i = 0; i < wasm_module_inst->export_glob_count; i++) {
- symbol_name = wasm_module_inst->export_globals[i].name;
- if (!program->config.root_is_AS_module) {
- if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_stack_pointer)))
- export_sp_exist = true;
- } else {
- if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_user_stack_pointer)))
- export_sp_exist = true;
- }
- if (export_sp_exist)
- break;
- }
- } else {
- #if WASM_ENABLE_AOT != 0
- aot_module_inst = (AOTModuleInstance *)root_module_inst;
- AOTModule * aot_module = (AOTModule*)(aot_module_inst->aot_module.ptr);
- uint32 export_func_count = aot_module->export_func_count;
- uint32 exports_count = aot_module->export_count;
- AOTExportFunctionInstance * export_funcs = aot_module_inst->export_funcs.ptr;
- for (uint32 i = 0; i < export_func_count; i ++) {
- symbol_name = export_funcs[i].func_name;
- if (symbol_name) {
- if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_malloc)))
- malloc_exist = true;
- else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_free)))
- free_exist = true;
- else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_realloc)))
- realloc_exist = true;
- if (program->config.root_is_AS_module) {
- if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___alloc)))
- malloc_exist = true;
- else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___free)))
- free_exist = true;
- else if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP___realloc)))
- realloc_exist = true;
- }
- if (malloc_exist && free_exist && realloc_exist)
- break;
- }
- }
- for (uint32 i = 0; i < exports_count; i++) {
- if (aot_module->exports[i].kind != EXPORT_KIND_GLOBAL)
- continue;
- symbol_name = aot_module->exports[i].name;
- if (!program->config.root_is_AS_module) {
- if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_stack_pointer)))
- export_sp_exist = true;
- } else {
- if (!strcmp(symbol_name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_user_stack_pointer)))
- export_sp_exist = true;
- }
- if (export_sp_exist)
- break;
- }
- #endif
- }
- if (program->config.import_memop_mode == FROM_ROOT) {
- if (!malloc_exist || !free_exist || !realloc_exist) {
- LOG_WARNING("Select memory from root module, but not found the functions exported:");
- if (!malloc_exist)
- LOG_WARNING("malloc");
- if (!free_exist)
- LOG_WARNING("free");
- if (!realloc_exist)
- LOG_WARNING("realloc");
- return false;
- }
- } else {
- if (malloc_exist || free_exist || realloc_exist) {
- LOG_WARNING("Select memory from VM, but found memory functions exported:");
- if (malloc_exist)
- LOG_WARNING("malloc");
- if (free_exist)
- LOG_WARNING("free");
- if (realloc_exist)
- LOG_WARNING("realloc");
- }
- return false;
- }
- if (!export_sp_exist) {
- LOG_WARNING("Can't find global __stack_pointer exported, link error might happen.");
- return false;
- }
- return true;
- }
- WASMProgramInstance *
- wasm_runtime_create_program_internal(char * error_buf, uint32 error_buf_size, uint32 dlopen_mode)
- {
- WASMProgramInstance * program = NULL;
- if (!(program = runtime_malloc(sizeof(WASMProgramInstance), error_buf, error_buf_size)))
- return NULL;
- program->clean_all = false;
- program->config.binding_mode = LAZY_BINDING; // currently always lazy binding, ignore user setting
- program->config.import_memop_mode = (dlopen_mode & MEM_ALLOCATOR_MASK) ? FROM_ROOT: FROM_BUILTIN_LIBC;
- program->config.use_tbl_as_cache = (dlopen_mode & USE_TBL_AS_CACHE_MASK);
- program->config.root_is_AS_module = (dlopen_mode & ROOT_IS_AS_MODULE_MASK);
- program->config.use_resolve_cache = false; // currently alwasy false, no optimiation implemented.
- program->runtime = wasm_runtime_get_runtime();
- // bh_list_init(&program->loading_modules_list);
- program->resolving_cache = runtime_malloc(sizeof(wasm_resolving_cache_entry) * PROGRAM_RESOLVING_CACHE_LINE_LEN * PROGRAM_RESOLVING_CACHE_LINE_COUNT,
- error_buf, error_buf_size);
- if (!program->resolving_cache) {
- wasm_runtime_free(program);
- return NULL;
- }
- // create a local map to record dependencies.
- // hash map is not responsible to reclaim the key
- // they are allocated/free by const string pool.
- program->global_modules_inst_name_hmap =
- bh_hash_map_create(PROGRAM_NAME_MODULE_INST_INIT_SIZE,
- false,
- (HashFunc)const_str_hash,
- (KeyEqualFunc)const_str_equal,
- NULL,
- (ValueDestroyFunc)const_str_destroy_module_inst);
- if (!program->global_modules_inst_name_hmap) {
- wasm_runtime_free(program->resolving_cache);
- wasm_runtime_free(program);
- return NULL;
- }
- program->global_modules_inst_id_hmap =
- bh_hash_map_create(PROGRAM_INST_ID_HMAP_INIT_SIZE,
- false,
- (HashFunc)inst_id_hash,
- (KeyEqualFunc)inst_id_equal,
- NULL,
- NULL);
- if (!program->global_modules_inst_id_hmap) {
- bh_hash_map_destroy(program->global_modules_inst_name_hmap);
- wasm_runtime_free(program->resolving_cache);
- wasm_runtime_free(program);
- return NULL;
- }
- // index 0 is reserved for error handling.
- program->next_free_inst_id = 1;
- program->builtin_libc_funcs = NULL;
- program->builtin_libc_funcs_count = 0;
- program->builtin_libc_funcs_size = 0;
- program->exception_inst = NULL;
- program->error_buf = error_buf;
- program->error_buf_size = error_buf_size;
- return program;
- }
- void
- wasm_program_remove_module_inst_from_name_hmap(WASMProgramInstance * program, WASMModuleInstance * module_inst)
- {
- bh_hash_map_remove(program->global_modules_inst_name_hmap, (void*)module_inst->module->module_name, NULL, NULL);
- }
- void
- wasm_program_cache_resolve_result(WASMProgramInstance * program, int32 id, void * result_func, void * module_inst)
- {
- wasm_resolving_cache_entry * cache_line = NULL;
- wasm_resolving_cache_entry * p_empty_entry = NULL;
- int32 index = id & (PROGRAM_RESOLVING_CACHE_LINE_COUNT - 1);
- if (!program)
- return;
- cache_line = program->resolving_cache + (PROGRAM_RESOLVING_CACHE_LINE_LEN * index);
- if (!cache_line[0].func_inst) {
- p_empty_entry = &cache_line[0];
- } else if (!cache_line[1].func_inst)
- p_empty_entry = &cache_line[1];
- else
- p_empty_entry = &cache_line[0];
- p_empty_entry->index = id;
- p_empty_entry->func_inst = result_func;
- #if WASM_ENABLE_AOT != 0
- p_empty_entry->module_inst = module_inst;
- #endif
- }
- void *
- wasm_program_lookup_cached_resolving_func(WASMProgramInstance * program, int32 id)
- {
- wasm_resolving_cache_entry * cache_line = NULL;
- int32 index = id & (PROGRAM_RESOLVING_CACHE_LINE_COUNT - 1);
- if (!program)
- return NULL;
- cache_line = program->resolving_cache + (PROGRAM_RESOLVING_CACHE_LINE_LEN * index);
- if (cache_line[0].index == id)
- return cache_line[0].func_inst;
- else if (cache_line[1].index == id)
- return cache_line[1].func_inst;
- return NULL;
- }
- void
- wasm_program_invalidate_cached_wasm_func(WASMProgramInstance * program, wasm_module_inst_t module_inst)
- {
- if (!program)
- return;
- wasm_resolving_cache_entry * cache_entry = program->resolving_cache;
- if (!module_inst)
- return;
- for (int i = 0; i < PROGRAM_RESOLVING_CACHE_LINE_LEN * PROGRAM_RESOLVING_CACHE_LINE_COUNT; i ++) {
- WASMFunctionInstance * func_inst = cache_entry[i].func_inst;
- if (!func_inst)
- continue;
- if ((wasm_module_inst_t)func_inst->module_inst != module_inst)
- continue;
- memset(&cache_entry[i], 0, sizeof(wasm_resolving_cache_entry));
- }
- }
- uint32
- wasm_program_create_dlopen_session(WASMProgramInstance * program, WASMModuleInstanceCommon * module_inst)
- {
- WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
- module_inst_head->exp_ref_cnt ++;
- //if (module_inst->module_type == Wasm_Module_Bytecode) {
- // WASMModuleInstance * wasm_module_inst = (WASMModuleInstance *)module_inst;
- // printf("module %s, exp ref = %d, imp ref = %d\n", wasm_module_inst->module->module_name->str,
- // wasm_module_inst->exp_ref_cnt, wasm_module_inst->imp_ref_cnt);
- //} else {
- // AOTModuleInstance * aot_module_inst = (AOTModuleInstance *)module_inst;
- // printf("module %s, exp ref = %d, imp ref = %d\n", ((AOTModule*)(aot_module_inst->aot_module.ptr))->module_name->str,
- // aot_module_inst->exp_ref_cnt, aot_module_inst->imp_ref_cnt);
- //}
- return module_inst_head->inst_id;
- }
- WASMModuleInstanceCommon *
- wasm_program_destroy_dlopen_session(WASMProgramInstance * program, uint32 inst_id)
- {
- WASMModuleInstanceCommon * module_inst = wasm_program_get_module_inst_by_id(program, inst_id);
- WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
- if (!module_inst)
- return NULL;
- if (module_inst_head->exp_ref_cnt > 0)
- module_inst_head->exp_ref_cnt -- ;
- //if (module_inst->module_type == Wasm_Module_Bytecode)
- // printf("module %s, exp ref = %d, imp ref = %d\n", ((WASMModuleInstance*)module_inst)->module->module_name->str,
- // module_inst_head->exp_ref_cnt, module_inst_head->imp_ref_cnt);
- //else
- // printf("module %s, exp ref = %d, imp ref = %d\n", ((AOTModule*)((AOTModuleInstance*)module_inst)->aot_module.ptr)->module_name->str,
- // module_inst_head->exp_ref_cnt, module_inst_head->imp_ref_cnt);
- return module_inst;
- }
- uint32
- wasm_program_alloc_module_instance_id(WASMProgramInstance * program, WASMModuleInstanceCommon * module_inst)
- {
- uint32 id = 0;
- void * p = NULL;
- WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
- id = program->next_free_inst_id;
- p = (void*)(uintptr_t)id;
- while (bh_hash_map_find(program->global_modules_inst_id_hmap, p)) {
- id ++;
- if (id == PROGRAM_INST_ID_TOP_BOUNARY)
- id = 2;
- p = (void*)(uintptr_t)id;
- }
- if (!bh_hash_map_insert(program->global_modules_inst_id_hmap, p, (void*)module_inst))
- return 0;
- program->next_free_inst_id = id + 1;
- if (program->next_free_inst_id == PROGRAM_INST_ID_TOP_BOUNARY)
- program->next_free_inst_id = 2;
- module_inst_head->inst_id = id;
- return id;
- }
- void
- wasm_program_free_module_instance_id(WASMProgramInstance * program, uint32 inst_id)
- {
- void * key = (void*)(uintptr_t)inst_id;
- bh_hash_map_remove(program->global_modules_inst_id_hmap, key, NULL, NULL);
- }
- WASMModuleInstanceCommon *
- wasm_program_get_module_inst_by_id(WASMProgramInstance * program, uint32 inst_idx)
- {
- WASMModuleInstanceCommon * module_inst = NULL;
- void * key = (void*)(uintptr_t)inst_idx;
- module_inst = bh_hash_map_find(program->global_modules_inst_id_hmap, key);
- if (!module_inst) {
- return NULL;
- }
- return module_inst;
- }
- WASMModuleInstanceCommon *
- wasm_program_get_module_inst_by_name(WASMProgramInstance * program, const ConstStrDescription * module_name)
- {
- WASMModuleInstanceCommon * module_inst = NULL;
- if (module_name == CONST_STR_POOL_DESC(program->runtime, WAMR_CSP_env))
- return NULL;
- module_inst = bh_hash_map_find(program->global_modules_inst_name_hmap, (void*)module_name);
- return module_inst;
- }
- WASMModuleInstanceCommon *
- wasm_program_get_dep_module_inst_by_name(WASMModuleInstanceCommon * caller_module_inst, const ConstStrDescription * module_name)
- {
- WASMModuleInstanceCommon * module_inst = NULL;
- WASMModuleInstanceHead * caller_module_inst_head = (WASMModuleInstanceHead *)caller_module_inst;
- if (module_name == CONST_STR_POOL_DESC(caller_module_inst_head->runtime, WAMR_CSP_env))
- return NULL;
- if (caller_module_inst->module_type == Wasm_Module_Bytecode)
- module_inst = bh_hash_map_find(
- caller_module_inst_head->local_implicit_dependency_modules_name_hmap,
- (void*)module_name);
- else {
- module_inst = bh_hash_map_find(
- caller_module_inst_head->local_implicit_dependency_modules_name_hmap,
- (void*)module_name);
- }
- return module_inst;
- }
- bool
- wasm_program_insert_module_inst_by_name(WASMProgramInstance * program,
- WASMModuleInstanceCommon * module_inst,
- const ConstStrDescription * module_name)
- {
- return bh_hash_map_insert_with_dup(program->global_modules_inst_name_hmap,
- (void*)module_name,
- (void*)module_inst);
- }
- #if WASM_ENABLE_LIBC_BUILTIN != 0
- static void
- wasm_program_destroy_internal_libc_module(WASMProgramInstance * program);
- #endif
- void
- wasm_runtime_destroy_program_internal(WASMProgramInstance * program)
- {
- program->clean_all = true;
- #if WASM_ENABLE_LIBC_BUILTIN != 0
- wasm_program_destroy_internal_libc_module(program);
- #endif
- if (program->resolving_cache)
- wasm_runtime_free(program->resolving_cache);
- if (program->global_modules_inst_name_hmap)
- bh_hash_map_destroy(program->global_modules_inst_name_hmap);
- if (program->global_modules_inst_id_hmap)
- bh_hash_map_destroy(program->global_modules_inst_id_hmap);
- wasm_runtime_free(program);
- }
- const ConstStrDescription *
- upgrade_module_extension(const WASMRuntime *runtime,
- const ConstStrDescription * key_module_name,
- const package_type_t expected_module_type,
- char * error_buf,
- uint32 error_buf_size)
- {
- uint32 offset = 0, new_name_len = 0;
- const ConstStrDescription * key_new_module_name = NULL;
- char * extension_name = NULL, *new_module_name = NULL;
- if (!runtime->config.auto_update_extension)
- return key_module_name;
- offset = key_module_name->len;
- extension_name = strrchr(key_module_name->str, '.');
- if (!extension_name)
- return key_module_name;
- offset = extension_name - key_module_name->str;
- new_name_len = offset + sizeof(".wasm") + 1;
- new_module_name = (char*)wasm_runtime_malloc(new_name_len);
- memset(new_module_name, 0, new_name_len);
- memcpy(new_module_name, key_module_name->str, offset);
- if (expected_module_type == Wasm_Module_Bytecode)
- strncat(new_module_name, ".wasm", new_name_len);
- else
- strncat(new_module_name, ".aot", new_name_len);
- key_new_module_name = wasm_runtime_records_const_string((WASMRuntime*)runtime, new_module_name,
- strlen(new_module_name), error_buf, error_buf_size);
- wasm_runtime_free(new_module_name);
- return key_new_module_name;
- }
- static WASMModuleCommon *
- load_dependency_module(const WASMRuntime *runtime,
- const ConstStrDescription * key,
- const package_type_t expected_module_type,
- char * error_buf,
- uint32 error_buf_size)
- {
- WASMModuleCommon * new_module = NULL;
- // bh_list * new_modules_list = NULL;
- const module_reader reader = wasm_runtime_get_module_reader();
- const module_destroyer destroyer = wasm_runtime_get_module_destroyer();
- // LoadingModuleElem * loading_module_elem = NULL;
- if (!reader || !destroyer) {
- return NULL;
- }
- // check if already loaded
- new_module = bh_hash_map_find(runtime->all_loaded_modules, (void*)key);
- if (new_module &&
- new_module->module_type == expected_module_type) {
- if (!wasm_runtime_is_shared_module(new_module))
- return NULL;
- return new_module;
- }
- if (new_module &&
- new_module->module_type != expected_module_type) {
- return NULL; //currently, VM won't replace the extension automatically on user's behalf
- //key = upgrade_module_extension(runtime, key, expected_module_type, error_buf, error_buf_size);
- //new_module = bh_hash_map_find(runtime->all_loaded_modules, (void*)key);
- //if (new_module &&
- // new_module->module_type == expected_module_type) {
- // return new_module;
- //}
- }
- bh_assert(!new_module);
- if (!(new_module = load_dependency_module_internal(reader, destroyer, key->str,
- key->len, expected_module_type, error_buf, error_buf_size))) {
- return NULL;
- }
- if (new_module->module_type == Wasm_Module_Bytecode)
- ((WASMModule*)new_module)->module_name = key;
- else
- ((AOTModule*)new_module)->module_name = key;
- if (!bh_hash_map_insert(runtime->all_loaded_modules, (void*)key, new_module)) {
- return NULL;
- }
- return new_module;
- }
- /**
- * Return export function count in module export section.
- */
- static uint32
- get_export_count_by_kind(const WASMModuleCommon *module, const uint8 kind)
- {
- uint32 count = 0;
- if (module->module_type == Wasm_Module_Bytecode) {
- WASMExport *export = ((WASMModule*)module)->exports;
- for (uint32 i = 0; i < ((WASMModule*)module)->export_count; i++, export++) {
- if (export->kind == kind)
- count ++;
- }
- } else {
- AOTExport * export = ((AOTModule*)module)->exports;
- for (uint32 i = 0; i < ((AOTModule*)module)->export_count; i++, export++) {
- if (export->kind == kind)
- count ++;
- }
- }
- return count;
- }
- WASMModuleCommon *
- load_explicit_dependency_module(const WASMModuleInstanceCommon *parent_module,
- const ConstStrDescription * key)
- {
- WASMModuleInstanceHead * parent_module_inst_head = (WASMModuleInstanceHead *)parent_module;
- WASMRuntime * runtime = parent_module_inst_head->runtime;
- WASMProgramInstance * program = parent_module_inst_head->program;
- // all new loaded modules will be recorded into program, so that
- // can be easy to instantiate them later.
- runtime->cur_loading_program = program;
- return load_dependency_module(runtime, key,
- parent_module_inst_head->module_type,
- program->error_buf,
- program->error_buf_size);
- }
- WASMModuleCommon *
- load_implicit_dependency_module(const WASMModuleCommon *parent_module,
- const ConstStrDescription * key,
- char * error_buf,
- uint32 error_buf_size)
- {
- WASMRuntime * runtime = NULL;
- if (parent_module->module_type == Wasm_Module_Bytecode)
- runtime = ((WASMModule*)parent_module)->runtime;
- else {
- runtime = ((AOTModule*)parent_module)->runtime;
- key = upgrade_module_extension(runtime, key, Wasm_Module_AoT, error_buf, error_buf_size);
- }
- return load_dependency_module(runtime, key, parent_module->module_type, error_buf, error_buf_size);
- }
- void
- decrement_ref_module_inst_callback(ConstStrDescription * key, void * value, void * user_data)
- {
- ConstStrDescription ** unused_module_list = (ConstStrDescription **)user_data;
- WASMModuleInstanceCommon * module_inst = (WASMModuleInstanceCommon *)value;
- WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
- const ConstStrDescription * module_name = NULL;
- if (module_inst_head && module_inst_head->imp_ref_cnt ) {
- module_inst_head->imp_ref_cnt --;
- if (module_inst_head->module_type == Wasm_Module_Bytecode) {
- module_name = ((WASMModuleInstance*)module_inst)->module->module_name;
- } else {
- module_name = ((AOTModule*)((AOTModuleInstance*)module_inst)->aot_module.ptr)->module_name;
- }
- (void)module_name;
- //printf("module %s, exp ref = %d, imp ref = %d\n",
- // module_name->str,
- // module_inst_head->exp_ref_cnt,
- // module_inst_head->imp_ref_cnt);
- if (!module_inst_head->imp_ref_cnt) {
- if (!(*unused_module_list)) {
- *unused_module_list = key;
- } else {
- (*unused_module_list)->next = key;
- (*unused_module_list) = key;
- }
- }
- }
- }
- void
- wasm_program_close_dependencies(wasm_module_inst_t module_inst,
- uint32 inst_id)
- {
- WASMModuleInstance * caller_module_inst = (WASMModuleInstance*)module_inst;
- WASMProgramInstance * program = caller_module_inst->program;
- WASMModuleInstanceCommon * callee_module_inst = NULL, * iter_module_inst = NULL;
- WASMModuleInstanceHead * callee_module_inst_head = NULL, *iter_module_inst_head = NULL;
- HashMap * implicit_dep_hmap = NULL;
- const ConstStrDescription * list_end = NULL, * list_head = NULL,
- * cur_processing_node = NULL;
- ConstStrDescription * key = NULL;
- const ConstStrDescription *module_name = NULL;
- void * p = NULL;
- if (!program)
- return;
- callee_module_inst = wasm_program_destroy_dlopen_session(program, inst_id);
- callee_module_inst_head = (WASMModuleInstanceHead *)callee_module_inst;
- if (!callee_module_inst)
- return;
- // a FIFO list stores the modules on which no modules depends implicitly.
- // implement a breath first ref count update.
- if (!callee_module_inst_head->exp_ref_cnt &&
- !callee_module_inst_head->imp_ref_cnt) {
- implicit_dep_hmap = callee_module_inst_head->local_implicit_dependency_modules_name_hmap;
- if (callee_module_inst_head->module_type == Wasm_Module_Bytecode) {
- module_name = ((WASMModuleInstance*)callee_module_inst)->module->module_name;
- } else {
- module_name = ((AOTModule*)((AOTModuleInstance*)callee_module_inst)->aot_module.ptr)->module_name;
- }
- //printf("************** possible to clear deps of %s ***********************\n",
- // module_name->str);
- list_head = list_end = module_name;
- if (implicit_dep_hmap) {
- //list_head = list_end = module_name;
- // handle current module's dependency
- bh_hash_map_traverse(implicit_dep_hmap,
- (TraverseCallbackFunc)decrement_ref_module_inst_callback, &list_end);
- }
- // we have handle the callee module, so start from its deps in the following loop.
- cur_processing_node = list_head->next;
- // handle dependencies's deps recursively
- while (cur_processing_node) {
- key = (ConstStrDescription*)cur_processing_node;
- iter_module_inst = bh_hash_map_find(program->global_modules_inst_name_hmap, (void*)key);
- iter_module_inst_head = (WASMModuleInstanceHead*)iter_module_inst;
- if (iter_module_inst_head) {
- bh_assert(iter_module_inst_head->imp_ref_cnt == 0);
- if (iter_module_inst_head->local_implicit_dependency_modules_name_hmap)
- bh_hash_map_traverse(iter_module_inst_head->local_implicit_dependency_modules_name_hmap,
- (TraverseCallbackFunc)decrement_ref_module_inst_callback, &list_end);
- }
- cur_processing_node = cur_processing_node->next;
- }
- }
- // remove the modules which both exp_ref and imp_ref are zero.
- // Note: currently, we don't handle cycle-dependency case, it's responsible for application user.
- cur_processing_node = list_head;
- while(cur_processing_node) {
- key = (ConstStrDescription*)cur_processing_node;
- iter_module_inst = bh_hash_map_find(program->global_modules_inst_name_hmap, (void*)key);
- iter_module_inst_head = (WASMModuleInstanceHead*)iter_module_inst;
- if (iter_module_inst_head && !iter_module_inst_head->exp_ref_cnt) {
- p = (void*)(uintptr_t)iter_module_inst_head->inst_id;
- bh_hash_map_remove(program->global_modules_inst_id_hmap,
- p,
- NULL,
- NULL);
- bh_hash_map_remove(program->global_modules_inst_name_hmap, (void*)key, NULL, NULL);
- if (iter_module_inst_head->module_type == Wasm_Module_Bytecode) {
- module_name = ((WASMModuleInstance*)iter_module_inst)->module->module_name;
- } else {
- module_name = ((AOTModule*)((AOTModuleInstance*)iter_module_inst)->aot_module.ptr)->module_name;
- }
- //printf("module %s deinstantiating\n", module_name->str);
- // wasm_program_free_module_instance_id(program, iter_module_inst->inst_id);
- // wasm_program_remove_module_inst_from_name_hmap(program, iter_module_inst);
- wasm_program_invalidate_cached_wasm_func(program, (wasm_module_inst_t)iter_module_inst);
- wasm_runtime_module_free(program->root_module_inst, iter_module_inst_head->init_globals.actual_memory_base);
- wasm_runtime_deinstantiate((wasm_module_inst_t)iter_module_inst);
- }
- cur_processing_node = cur_processing_node->next;
- // unlink current working list
- key->next = NULL;
- }
- }
- // Note: it will be implemented as thread-safe.
- // only one thread could open a dependency wasm and its dependency per time.
- // will add contention protection (lock/mutex etc) later.
- uint32
- wasm_program_open_dependencies(wasm_module_inst_t module_inst,
- const char * path)
- {
- WASMModuleInstanceHead * module_inst_head = (WASMModuleInstanceHead *)module_inst;
- WASMProgramInstance * program_inst = module_inst_head->program;
- WASMRuntime * runtime = module_inst_head->runtime;
- WASMModuleInstanceCommon * callee_module_inst = NULL;
- if (!program_inst)
- return 0;
- callee_module_inst = wasm_program_open_dependencies_general(runtime,
- program_inst,
- module_inst,
- path);
- if (!callee_module_inst)
- return 0;
- if (callee_module_inst == module_inst)
- return 0;
- return wasm_program_create_dlopen_session(program_inst, callee_module_inst);
- }
- WASMModuleInstanceCommon *
- wasm_program_instantiate_dependencies(WASMRuntime * runtime,
- WASMProgramInstance * program_inst,
- WASMModuleInstanceCommon * caller_module_inst,
- WASMModuleCommon * module)
- {
- WASMModuleInstanceCommon * new_module_inst = NULL;
- WASMModuleInstanceCommon *root_module_inst = NULL;
- WASMModule * wasm_module = (WASMModule*)module;
- AOTModule * aot_module = (AOTModule*)module;
- DependencyModuleInitGlobals init_globals;
- int32 init_size = 0, export_func_count = 0, stack_size = 0;
- uint32 offset = 0;
- void * native_addr = NULL;
- bool is_aot = !(module->module_type == Wasm_Module_Bytecode);
- root_module_inst = program_inst->root_module_inst;
- if (!is_aot && !wasm_module->dylink_section) {
- set_error_buf_v(program_inst->error_buf, program_inst->error_buf_size,
- "%s isn't a valid shared wasm module.\n", wasm_module->module_name->str);
- return NULL;
- } else if (is_aot && !aot_module->dylink_section) {
- set_error_buf_v(program_inst->error_buf, program_inst->error_buf_size,
- "%s isn't a valid shared wasm module.\n", aot_module->module_name->str);
- return NULL;
- }
- if (root_module_inst->module_type == Wasm_Module_Bytecode)
- stack_size = ((WASMModuleInstance*)root_module_inst)->default_wasm_stack_size;
- else
- stack_size = ((AOTModuleInstance*)root_module_inst)->default_wasm_stack_size;
- memset(&init_globals, 0, sizeof(DependencyModuleInitGlobals));
- // lazy instantiation
- // the idea is to load all dependencies first (so we can check if all of them exist),
- // but only instantiate the first one, and other modules will be instantiated as needed.
- export_func_count = get_export_count_by_kind(module, EXPORT_KIND_FUNC);
- // allocate init mem space for dependency module
- if (!is_aot) {
- if (!wasm_module->dylink_section->table_alignment)
- wasm_module->dylink_section->table_alignment = 1;
- init_size = wasm_module->dylink_section->table_size + export_func_count;
- init_size += wasm_module->dylink_section->table_alignment - 1;
- // will calcuate it by instance id
- init_globals.table_alignment = wasm_module->dylink_section->table_alignment;
- if (!wasm_module->dylink_section->memory_alignment)
- wasm_module->dylink_section->memory_alignment = 1;
- bh_assert(wasm_module->dylink_section->memory_alignment > 0);
- } else {
- if (!aot_module->dylink_section->table_alignment)
- aot_module->dylink_section->table_alignment = 1;
- init_size = aot_module->dylink_section->table_size + export_func_count;
- init_size += aot_module->dylink_section->table_alignment - 1;
- // will calcuate it by instance id
- init_globals.table_alignment = aot_module->dylink_section->table_alignment;
- if (!aot_module->dylink_section->memory_alignment)
- aot_module->dylink_section->memory_alignment = 1;
- bh_assert(aot_module->dylink_section->memory_alignment > 0);
- }
- bh_assert(init_size <= TABLE_SPACE_SLOT_SIZE);
- init_globals.table_size = init_size;
- init_globals.table_base = 0;
- // assumpt stack_pointer is the first global.
- // if root module is opened by dlopen, global[0] should be __stack_pointer
- // else if root module is a library module, its global[0] is also __stack_pointer
- if (caller_module_inst->module_type == Wasm_Module_Bytecode) {
- //bh_assert(((WASMModuleInstance*)caller_module_inst)->globals[0].is_mutable == true &&
- // ((WASMModuleInstance*)caller_module_inst)->globals[0].type == VALUE_TYPE_I32);
- } else {
- AOTModule * root_aot_module = (AOTModule*)((AOTModuleInstance*)caller_module_inst)->aot_module.ptr;
- (void)root_aot_module;
- if (root_aot_module->dylink_section)
- bh_assert(root_aot_module->import_globals[0].is_mutable == true &&
- root_aot_module->import_globals[0].type == VALUE_TYPE_I32);
- //else
- // bh_assert(root_aot_module->globals[0].is_mutable == true &&
- // root_aot_module->globals[0].type == VALUE_TYPE_I32);
- }
- if (!is_aot) {
- init_size = wasm_module->dylink_section->memory_size + wasm_module->dylink_section->memory_alignment - 1;
- offset = wasm_runtime_module_malloc((wasm_module_inst_t)root_module_inst,
- init_size, &native_addr);
- if (!offset)
- return NULL;
- init_globals.actual_memory_base = offset;
- init_globals.memory_base = (offset + wasm_module->dylink_section->memory_alignment - 1) &
- (~(wasm_module->dylink_section->memory_alignment - 1));
- new_module_inst = (WASMModuleInstanceCommon*)wasm_instantiate_dependency((WASMModule*)module, program_inst,
- stack_size, &init_globals);
- } else {
- init_size = aot_module->dylink_section->memory_size + aot_module->dylink_section->memory_alignment - 1;
- offset = wasm_runtime_module_malloc((wasm_module_inst_t)root_module_inst,
- init_size, &native_addr);
- if (!offset)
- return NULL;
- init_globals.actual_memory_base = offset;
- init_globals.memory_base = (offset + aot_module->dylink_section->memory_alignment - 1) &
- (~(aot_module->dylink_section->memory_alignment - 1));
- new_module_inst = (WASMModuleInstanceCommon*)aot_instantiate_dependency((AOTModule*)module, program_inst,
- stack_size, &init_globals);
- }
- if (!new_module_inst)
- return NULL;
- return new_module_inst;
- }
- WASMModuleInstanceCommon *
- wasm_program_open_dependencies_general(WASMRuntime * runtime,
- WASMProgramInstance * program_inst,
- WASMModuleInstanceCommon * caller_module_inst,
- const char * path)
- {
- const ConstStrDescription * key = NULL;
- WASMModuleCommon * new_module = NULL;
- WASMModuleInstanceCommon *root_module_inst = NULL, *new_module_inst = NULL;
- // bh_list loading_modules_list;
- //LoadingModuleElem * elem = NULL;
- root_module_inst = program_inst->root_module_inst;
- // records string into const string pool
- key = wasm_runtime_records_const_string(
- runtime, path,
- strlen(path),
- program_inst->error_buf,
- program_inst->error_buf_size);
- if (!key) {
- return NULL;
- }
- // check if opened by the current program.
- new_module_inst = dylib_entries_map_find(key, program_inst->global_modules_inst_name_hmap);
- if (new_module_inst) {
- if (new_module_inst->module_type != caller_module_inst->module_type)
- return NULL;
- if (!wasm_runtime_is_shared_module_instance(new_module_inst)) {
- return NULL;
- }
- return new_module_inst;
- }
- // start to load all dependency modules.
- new_module = load_explicit_dependency_module(root_module_inst, key);
- if (!new_module)
- return NULL;
- // currently only supports wasm->wasm, aot->aot
- if (new_module->module_type != caller_module_inst->module_type)
- return NULL;
- if (!wasm_runtime_is_shared_module(new_module)) {
- return NULL;
- }
- // can exit the program lock scope from here.
- new_module_inst = (WASMModuleInstanceCommon*)wasm_program_instantiate_dependencies(
- runtime, program_inst, (WASMModuleInstanceCommon*)caller_module_inst, new_module);
- if (!new_module_inst)
- return NULL;
- if (!dylib_entries_map_insert(key, new_module_inst,
- program_inst->global_modules_inst_name_hmap))
- return NULL;
- return new_module_inst;
- }
- uint32
- wasm_program_lookup_symbol_from_module(wasm_module_inst_t caller_module,
- uint32 inst_id, const char * symbol)
- {
- WASMModuleInstanceHead * caller_module_inst_head = (WASMModuleInstanceHead *)caller_module;
- WASMModuleInstanceCommon * callee_module_inst = NULL;
- WASMModuleInstance * wasm_inst = NULL;
- AOTModuleInstance * aot_inst = NULL;
- AOTModule * aot_module = NULL;
- uint32 table_slot = 0, i = 0;
- void * key = NULL;
- if (!caller_module_inst_head->program)
- return 0;
- key = (void*)(uintptr_t)inst_id;
- callee_module_inst = bh_hash_map_find(caller_module_inst_head->program->global_modules_inst_id_hmap, key);
- if (!callee_module_inst)
- return 0;
- if (callee_module_inst->module_type == Wasm_Module_Bytecode) {
- wasm_inst = (WASMModuleInstance *)callee_module_inst;
- for (i = 0; i < wasm_inst->export_func_count; i++) {
- if (!strcmp(wasm_inst->export_functions[i].name, symbol)) {
- table_slot = i;
- break;
- }
- }
- if (i == wasm_inst->export_func_count)
- return 0;
- table_slot += (wasm_inst->inst_id *
- TABLE_SPACE_SLOT_SIZE) - wasm_inst->export_func_count;
- } else {
- aot_inst = (AOTModuleInstance *)callee_module_inst;
- aot_module = (AOTModule*)aot_inst->aot_module.ptr;
- for (i = 0; i < aot_module->export_func_count; i++) {
- if (!strcmp(((AOTExportFunctionInstance*)aot_inst->export_funcs.ptr)[i].func_name, symbol)) {
- table_slot = i;
- break;
- }
- }
- if (i == aot_module->export_func_count)
- return 0;
- table_slot += (aot_inst->inst_id *
- TABLE_SPACE_SLOT_SIZE) - aot_module->export_func_count;
- }
- return table_slot;
- }
- bool
- wasm_program_resolve_aot_function(WASMProgramInstance * program,
- AOTModuleInstance * resolve_module_inst,
- AOTModuleInstance ** p_callee_module_inst,
- uint32 import_func_id)
- {
- WASMRuntime * runtime = resolve_module_inst->runtime;
- const ConstStrDescription * module_name = NULL, * func_name = NULL;
- AOTModule * module = resolve_module_inst->aot_module.ptr;
- AOTModule * callee_module = NULL;
- AOTImportFunc * import_func = &module->import_funcs[import_func_id];
- AOTFuncType * cur_type = NULL, *cur_func_type = NULL;
- AOTModuleInstance *caller_module_inst = resolve_module_inst, *callee_module_inst = NULL;
- AOTExportFunctionInstance * export_funcs = NULL, *callee_function_inst = NULL;
- uint32 i = 0;
- bool resolve_memop_func = false;
- cur_type = import_func->func_type;
- while(1) {
- resolve_memop_func = false;
- module_name = import_func->module_name;
- func_name = import_func->func_name;
- if (module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_env) &&
- (program->config.import_memop_mode != FROM_ROOT ||
- !wasm_runtime_is_memop_symbol(runtime, func_name))) {
- *p_callee_module_inst = caller_module_inst;
- return true;
- }
- if (module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_env)) {
- resolve_memop_func = true;
- bh_assert(caller_module_inst != (AOTModuleInstance*)program->root_module_inst);
- callee_module_inst = (AOTModuleInstance*)program->root_module_inst;
- }
- if (!callee_module_inst) {
- module_name = upgrade_module_extension(runtime,
- module_name, Wasm_Module_AoT, program->error_buf, program->error_buf_size);
- callee_module_inst = (AOTModuleInstance*)wasm_program_get_module_inst_by_name(program, module_name);
- }
- if (!callee_module_inst) {
- callee_module = (AOTModule*)wasm_runtime_get_module_by_name(runtime, module_name);
- if (!callee_module) {
- aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
- return false;
- }
- callee_module_inst = (AOTModuleInstance*)wasm_program_instantiate_dependencies(runtime,
- program, (WASMModuleInstanceCommon*)caller_module_inst, (WASMModuleCommon*)callee_module);
- if (!callee_module_inst) {
- aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
- return false;
- }
- if (!bh_hash_map_insert_with_dup(program->global_modules_inst_name_hmap,
- (void*)module_name, (void*)callee_module_inst)) {
- aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
- return false;
- }
- }
- if (!resolve_memop_func) {
- if (!caller_module_inst->local_implicit_dependency_modules_name_hmap) {
- caller_module_inst->local_implicit_dependency_modules_name_hmap =
- bh_hash_map_create(8, false,
- (HashFunc)const_str_hash,
- (KeyEqualFunc)const_str_equal,
- NULL,
- NULL);
- if (!caller_module_inst->local_implicit_dependency_modules_name_hmap) {
- aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
- return false;
- }
- if (!bh_hash_map_insert(caller_module_inst->local_implicit_dependency_modules_name_hmap,
- (void*)module_name, (void*)callee_module_inst)) {
- aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
- return false;
- }
- callee_module_inst->imp_ref_cnt ++;
- } else {
- if (!bh_hash_map_find(caller_module_inst->local_implicit_dependency_modules_name_hmap,
- (void*)module_name)) {
- if (!bh_hash_map_insert(caller_module_inst->local_implicit_dependency_modules_name_hmap,
- (void*)module_name, (void*)callee_module_inst)) {
- aot_set_exception_with_id(caller_module_inst, EXEC_CALL_UNLINKED_MODULE);
- return false;
- }
- callee_module_inst->imp_ref_cnt ++;
- }
- }
- }
- //printf("module %s, exp ref = %d, imp ref = %d\n",
- // module_name->str,
- // callee_module_inst->exp_ref_cnt,
- // callee_module_inst->imp_ref_cnt);
- export_funcs = (AOTExportFunctionInstance*)callee_module_inst->export_funcs.ptr;
- if (!callee_module)
- callee_module = (AOTModule*)callee_module_inst->aot_module.ptr;
- for (i = 0; i < callee_module->export_func_count; i++) {
- if (!strcmp(export_funcs[i].func_name, import_func->func_name->str)) {
- break;
- }
- }
- if (i == callee_module->export_func_count) {
- aot_set_exception_with_id(caller_module_inst, EXCE_CALL_UNLINKED_IMPORT_FUNC);
- return false;
- }
- callee_function_inst = &export_funcs[i];
- if (callee_function_inst->is_import_func)
- cur_func_type = callee_function_inst->u.func_import->func_type;
- else
- cur_func_type = callee_function_inst->u.func.func_type;
- if (!wasm_type_equal(cur_type, cur_func_type)) {
- aot_set_exception_with_id(caller_module_inst, EXCE_INVALID_FUNCTION_TYPE_INDEX);
- return false;
- }
- if (!callee_function_inst->is_import_func)
- break;
- if (callee_function_inst->u.func_import->func_ptr_linked)
- break;
- caller_module_inst = callee_module_inst;
- import_func = callee_function_inst->u.func_import;
- }
- ((void**)resolve_module_inst->func_ptrs.ptr)[import_func_id] = callee_function_inst->u.func.func_ptr;
- *p_callee_module_inst = callee_module_inst;
- return true;
- }
- // TODO: the resolve algorithm need to improved to update the resolving result for other intermediate modules.
- static bool
- wasm_program_resolve_wasm_function(WASMProgramInstance * program,
- WASMModuleInstance * caller_module_inst,
- WASMFunctionInstance * import_func)
- {
- WASMModule * callee_module = NULL;
- const ConstStrDescription * module_name = NULL, *func_name = NULL;
- WASMModuleInstance * callee_module_inst = NULL;
- WASMFunctionInstance * callee_function_inst = NULL;
- WASMRuntime * runtime = caller_module_inst->runtime;
- WASMType *cur_type = NULL, *cur_func_type = NULL;
- bool resolve_memop_func = false;
- uint32 i = 0;
- if (!import_func->is_import_func)
- return true;
- callee_function_inst = import_func;
- cur_type = callee_function_inst->u.func_import->func_type;
- while (1) {
- resolve_memop_func = false;
- module_name = callee_function_inst->u.func_import->module_name;
- func_name = callee_function_inst->u.func_import->field_name;
- if (module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_env) &&
- (program->config.import_memop_mode != FROM_ROOT ||
- !wasm_runtime_is_memop_symbol(runtime, func_name))) {
- break;
- }
- if (module_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_env)) {
- resolve_memop_func = true;
- bh_assert(caller_module_inst != (WASMModuleInstance*)program->root_module_inst);
- callee_module_inst = (WASMModuleInstance*)program->root_module_inst;
- }
- if (!callee_module_inst)
- callee_module_inst = (WASMModuleInstance*)wasm_program_get_module_inst_by_name(program, module_name);
- if (!callee_module_inst) {
- callee_module = (WASMModule*)wasm_runtime_get_module_by_name(runtime, module_name);
- if (!callee_module)
- return false;
- callee_module_inst = (WASMModuleInstance*)wasm_program_instantiate_dependencies(runtime,
- program, (WASMModuleInstanceCommon*)caller_module_inst, (WASMModuleCommon*)callee_module);
- if (!callee_module_inst)
- return false;
- if (!bh_hash_map_insert_with_dup(program->global_modules_inst_name_hmap,
- (void*)module_name, (void*)callee_module_inst))
- return false;
- }
- if (!resolve_memop_func) {
- if (!caller_module_inst->local_implicit_dependency_modules_name_hmap) {
- caller_module_inst->local_implicit_dependency_modules_name_hmap =
- bh_hash_map_create(8, false,
- (HashFunc)const_str_hash,
- (KeyEqualFunc)const_str_equal,
- NULL,
- NULL);
- if (!caller_module_inst->local_implicit_dependency_modules_name_hmap)
- return false;
- if (!bh_hash_map_insert(caller_module_inst->local_implicit_dependency_modules_name_hmap,
- (void*)module_name, (void*)callee_module_inst))
- return false;
- callee_module_inst->imp_ref_cnt ++;
- } else {
- if (!bh_hash_map_find(caller_module_inst->local_implicit_dependency_modules_name_hmap,
- (void*)module_name)) {
- if (!bh_hash_map_insert(caller_module_inst->local_implicit_dependency_modules_name_hmap,
- (void*)module_name, (void*)callee_module_inst))
- return false;
- callee_module_inst->imp_ref_cnt ++;
- }
- }
- }
- //printf("module %s, exp ref = %d, imp ref = %d\n",
- // callee_module_inst->module->module_name->str,
- // callee_module_inst->exp_ref_cnt,
- // callee_module_inst->imp_ref_cnt);
- #if 0
- if (program->config.root_is_AS_module) {
- if (func_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_malloc))
- func_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___alloc);
- else if (func_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_free))
- func_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___free);
- else if (func_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_realloc))
- func_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___realloc);
- }
- #endif
- for (i = 0; i < callee_module_inst->export_func_count; i++) {
- if (!strcmp(callee_module_inst->export_functions[i].name, func_name->str)) {
- break;
- }
- }
- if (i == callee_module_inst->export_func_count) {
- return false;
- }
- callee_function_inst = callee_module_inst->export_functions[i].function;
- if (callee_function_inst->is_import_func)
- cur_func_type = callee_function_inst->u.func_import->func_type;
- else
- cur_func_type = callee_function_inst->u.func->func_type;
- if (!wasm_type_equal(cur_type, cur_func_type)) {
- return false;
- }
- if (!callee_function_inst->is_import_func)
- break;
- if (callee_function_inst->u.func_import->func_ptr_linked)
- break;
- caller_module_inst = callee_module_inst;
- }
- import_func->import_module_inst = callee_module_inst;
- import_func->import_func_inst = callee_function_inst;
- return true;
- }
- bool
- wasm_program_resolve_op_call(WASMProgramInstance * program,
- WASMModuleInstance * caller_module_inst,
- WASMModuleInstance ** p_callee_module_inst,
- WASMFunctionInstance ** p_call_func)
- {
- WASMModuleInstance * callee_module_inst = NULL;
- WASMFunctionInstance * call_func = *p_call_func;
- // lazy link, resolve the import function.
- if (program &&
- //caller_module_inst != (WASMModuleInstance*)program->root_module_inst &&
- call_func->is_import_func &&
- !call_func->u.func_import->func_ptr_linked) {
- if (!call_func->import_module_inst &&
- !call_func->import_func_inst) {
- if (program->config.binding_mode != LAZY_BINDING) {
- wasm_set_exception(caller_module_inst, "uninitialized import function.");
- return false;
- }
- if (!wasm_program_resolve_wasm_function(program, caller_module_inst, call_func)) {
- char buf[128];
- snprintf(buf, sizeof(buf),
- "failed to call unlinked import function (%s, %s)",
- (char*)call_func->u.func_import->module_name->str,
- (char*)call_func->u.func_import->field_name->str);
- wasm_set_exception(caller_module_inst, buf);
- return false;
- }
- }
- callee_module_inst = call_func->import_module_inst;
- call_func = call_func->import_func_inst;
- *p_callee_module_inst = callee_module_inst;
- *p_call_func = call_func;
- }
- return true;
- }
- uint32
- wasm_program_alloc_table_space_by_size(uint32 inst_id,
- uint32 needed_size)
- {
- uint32 table_space_start = 0;
- bh_assert(needed_size <= TABLE_SPACE_SLOT_SIZE);
- table_space_start = ((inst_id - 1)<< TABLE_SPACE_BITS_LEN);
- return table_space_start;
- }
- uint32
- wasm_program_alloc_table_space_by_table(WASMModuleInstance * module_inst,
- WASMTableInstance * table)
- {
- uint32 needed_size = table->max_size;
- uint32 inst_id = module_inst->inst_id;
- return wasm_program_alloc_table_space_by_size(inst_id, needed_size);
- }
- #if WASM_ENABLE_LIBC_BUILTIN != 0
- uint32
- get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis);
- #define BUILTIN_FUNC_ALLOC_STEP 4
- // create an internal libc module, but not create func instance until link GOT.func global
- static int
- wasm_program_link_internal_builtin_libc_func(WASMProgramInstance * program, const ConstStrDescription * func_name)
- {
- WASMRuntime * runtime = program->runtime;
- WASMFunctionInstance ** functions = (WASMFunctionInstance**)program->builtin_libc_funcs, *linked_func = NULL;
- WASMFunctionImport * func_import = NULL;
- NativeSymbol * native_symbols = NULL;
- uint32 i = 0, func_id = 0, func_offset = 0;
- int32 ret_id = -1;
- uint32 libc_funcs_count = get_libc_builtin_export_apis(&native_symbols);
- (void)(libc_funcs_count);
- if (!functions) {
- functions = wasm_runtime_malloc(sizeof(WASMFunctionInstance *) * BUILTIN_FUNC_ALLOC_STEP);
- if (!functions)
- return -1;
- program->builtin_libc_funcs = (void**)functions;
- program->builtin_libc_funcs_size = BUILTIN_FUNC_ALLOC_STEP;
- }
- for (i = 0; i < program->builtin_libc_funcs_count; i ++) {
- if (func_name == functions[i]->u.func_import->field_name)
- break;
- }
- if (i < program->builtin_libc_funcs_count) {
- return i;
- }
- func_id = wasm_runtime_get_syssymbol_id(runtime, func_name);
- if (func_id < WAMR_CSP_iprintf ||
- func_id > WAMR_CSP_dlclose)
- return -1;
- func_import = wasm_runtime_malloc(sizeof(WASMFunctionImport));
- if (!func_import)
- return -1;
- linked_func = wasm_runtime_malloc(sizeof(WASMFunctionInstance));
- if (!linked_func) {
- wasm_runtime_free(func_import);
- return -1;
- }
- memset(func_import, 0, sizeof(WASMFunctionImport));
- memset(linked_func, 0, sizeof(WASMFunctionInstance));
- func_offset = func_id - WAMR_CSP_iprintf;
- bh_assert(func_name == native_symbols[func_offset].u.symbol);
- func_import->module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_env);
- func_import->field_name = func_name;
- func_import->signature = native_symbols[func_offset].signature;
- func_import->func_type = NULL;
- func_import->attachment = native_symbols[func_offset].attachment;
- func_import->call_conv_raw = false;
- func_import->call_conv_wasm_c_api = false;
- func_import->wasm_c_api_with_env = false;
- func_import->func_ptr_linked = native_symbols[func_offset].func_ptr;
- linked_func->is_import_func = true;
- linked_func->func_type = NULL;
- linked_func->local_count = 0;
- linked_func->local_cell_num = 0;
- #if WASM_ENABLE_FAST_INTERP != 0
- linked_func->const_cell_num = 0;
- #endif
- linked_func->local_offsets = 0;
- linked_func->local_types = NULL;
- linked_func->u.func_import = func_import;
- if ((program->builtin_libc_funcs_count + 1) > program->builtin_libc_funcs_size) {
- functions = wasm_runtime_realloc(functions,
- sizeof(WASMFunctionInstance *) * (program->builtin_libc_funcs_size + BUILTIN_FUNC_ALLOC_STEP));
- if (!functions) {
- wasm_runtime_free(func_import);
- wasm_runtime_free(linked_func);
- return -1;
- }
- program->builtin_libc_funcs_size += BUILTIN_FUNC_ALLOC_STEP;
- program->builtin_libc_funcs = (void**)functions;
- }
- functions[program->builtin_libc_funcs_count] = linked_func;
- ret_id = program->builtin_libc_funcs_count;
- program->builtin_libc_funcs_count ++;
- return ret_id;
- }
- #if WASM_ENABLE_AOT != 0
- static int
- wasm_program_link_aot_internal_builtin_libc_func(WASMProgramInstance * program, const ConstStrDescription * func_name)
- {
- WASMRuntime * runtime = program->runtime;
- AOTExportFunctionInstance ** functions = (AOTExportFunctionInstance **)program->builtin_libc_funcs, *linked_func = NULL;
- AOTImportFunc * func_import = NULL;
- NativeSymbol * native_symbols = NULL;
- uint32 i = 0, func_id = 0, func_offset = 0;
- int32 ret_id = -1;
- uint32 libc_funcs_count = get_libc_builtin_export_apis(&native_symbols);
- (void)(libc_funcs_count);
- if (!functions) {
- functions = wasm_runtime_malloc(sizeof(AOTExportFunctionInstance *) * BUILTIN_FUNC_ALLOC_STEP);
- if (!functions)
- return -1;
- program->builtin_libc_funcs = (void**)functions;
- program->builtin_libc_funcs_size = BUILTIN_FUNC_ALLOC_STEP;
- }
- for (i = 0; i < program->builtin_libc_funcs_count; i ++) {
- if (func_name == functions[i]->u.func_import->func_name)
- break;
- }
- if (i < program->builtin_libc_funcs_count) {
- return i;
- }
- func_id = wasm_runtime_get_syssymbol_id(runtime, func_name);
- if (func_id < WAMR_CSP_iprintf ||
- func_id > WAMR_CSP_dlclose)
- return -1;
- func_import = wasm_runtime_malloc(sizeof(AOTImportFunc));
- if (!func_import)
- return -1;
- linked_func = wasm_runtime_malloc(sizeof(AOTExportFunctionInstance));
- if (!linked_func) {
- wasm_runtime_free(func_import);
- return -1;
- }
- memset(func_import, 0, sizeof(AOTImportFunc));
- memset(linked_func, 0, sizeof(AOTExportFunctionInstance));
- func_offset = func_id - WAMR_CSP_iprintf;
- bh_assert(func_name == native_symbols[func_offset].u.symbol);
- func_import->module_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP_env);
- func_import->func_name = func_name;
- func_import->signature = native_symbols[func_offset].signature;
- func_import->func_type = NULL;
- func_import->func_type_index = 0;
- func_import->attachment = native_symbols[func_offset].attachment;
- func_import->call_conv_raw = false;
- func_import->call_conv_wasm_c_api = false;
- func_import->wasm_c_api_with_env = false;
- func_import->func_ptr_linked = native_symbols[func_offset].func_ptr;
- linked_func->is_import_func = true;
- linked_func->u.func_import = func_import;
- linked_func->func_index = 0;
- if ((program->builtin_libc_funcs_count + 1) > program->builtin_libc_funcs_size) {
- functions = wasm_runtime_realloc(functions,
- sizeof(WASMFunctionInstance *) * (program->builtin_libc_funcs_size + BUILTIN_FUNC_ALLOC_STEP));
- if (!functions) {
- wasm_runtime_free(func_import);
- wasm_runtime_free(linked_func);
- return -1;
- }
- program->builtin_libc_funcs_size += BUILTIN_FUNC_ALLOC_STEP;
- program->builtin_libc_funcs = (void**)functions;
- }
- functions[program->builtin_libc_funcs_count] = linked_func;
- ret_id = program->builtin_libc_funcs_count;
- program->builtin_libc_funcs_count ++;
- return ret_id;
- }
- #endif
- #undef BUILTIN_FUNC_ALLOC_STEP
- static void
- wasm_program_destroy_internal_libc_module(WASMProgramInstance * program)
- {
- if (!program->builtin_libc_funcs)
- return;
- for(uint32 i = 0; i < program->builtin_libc_funcs_count; i++) {
- if (!program->builtin_libc_funcs[i])
- continue;
- //WASMFunctionImport * func_import = program->builtin_libc_funcs[i]->u.func_import;
- //if (func_import)
- // wasm_runtime_free(func_import);
- wasm_runtime_free(program->builtin_libc_funcs[i]);
- }
- wasm_runtime_free(program->builtin_libc_funcs);
- }
- #endif
- bool
- wasm_program_link_sp_wasm_globals(WASMProgramInstance * program,
- WASMGlobalInstance * global,
- const ConstStrDescription * field_name)
- {
- WASMRuntime * runtime = program->runtime;
- WASMModuleInstance * root_module_inst = (WASMModuleInstance *)program->root_module_inst;
- WASMGlobalInstance * export_global = NULL;
- (void)runtime;
- for (uint32 i = 0; i < root_module_inst->export_glob_count; i++) {
- if (!program->config.root_is_AS_module) {
- if (!strcmp(root_module_inst->export_globals[i].name, field_name->str)) {
- export_global = root_module_inst->export_globals[i].global;
- }
- } else {
- if (!strcmp(root_module_inst->export_globals[i].name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_user_stack_pointer))) {
- export_global = root_module_inst->export_globals[i].global;
- }
- }
- if (!export_global)
- continue;
- if (export_global->type != global->type ||
- export_global->is_mutable != global->is_mutable)
- return false;
- // global->data_offset = root_module_inst->globals->data_offset;
- if (export_global->is_mutable)
- global->data = export_global->data;
- else {
- global->data = (uint8*)&root_module_inst->init_globals.stack_pointer;
- }
- return true;
- }
- return false;
- }
- #if WASM_ENABLE_AOT != 0
- bool
- wasm_program_link_sp_aot_globals(WASMProgramInstance * program,
- uint8 * p_global_data,
- const ConstStrDescription * global_name)
- {
- WASMRuntime * runtime = program->runtime;
- AOTModuleInstance * root_module_inst = (AOTModuleInstance *)program->root_module_inst;
- AOTModule * root_module = (AOTModule *)root_module_inst->aot_module.ptr;
- uint32 global_id = 0, global_offset = 0;
- uint8 * p_data = NULL;
- if (root_module->export_sp_global_id >= root_module->export_count)
- return false;
- if (!program->config.root_is_AS_module) {
- if (strcmp(root_module->exports[root_module->export_sp_global_id].name, global_name->str)) {
- return false;
- }
- } else {
- if (strcmp(root_module->exports[root_module->export_sp_global_id].name, CONST_STR_POOL_STR(runtime, WAMR_CSP_var_user_stack_pointer))) {
- return false;
- }
- }
- global_id = root_module->exports[root_module->export_sp_global_id].index;
- global_offset = root_module->globals[global_id].data_offset;
- p_data = (uint8*)root_module_inst->global_data.ptr + global_offset;
- #if __WORDSIZE == 32
- if (root_module->dylink_section)
- *(uint32*)p_global_data = *(uint32*)p_data;
- else
- *(uint32*)p_global_data = (uintptr_t)p_data;
- #else
- if (root_module->dylink_section)
- *(uint64*)p_global_data = *(uint64*)p_data;
- else
- *(uint64*)p_global_data = (uintptr_t)p_data;
- #endif
- return true;
- }
- bool
- wasm_program_link_aot_got_globals(WASMProgramInstance * program,
- AOTModuleInstance * module_inst,
- uint8 * p_global_data,
- const ConstStrDescription * field_name)
- {
- WASMRuntime * runtime = program->runtime;
- AOTModuleInstance * root_module_inst = NULL;
- AOTModule * root_module = NULL;
- bool is_sys_symbol = wasm_runtime_is_system_symbol(runtime, field_name);
- bool is_memop_symbol = wasm_runtime_is_memop_symbol(runtime, field_name);
- int32 import_func_id = -1;
- uint32 i = 0;
- if (is_sys_symbol &&
- (!is_memop_symbol ||
- program->config.import_memop_mode == FROM_BUILTIN_LIBC)) {
- #if WASM_ENABLE_LIBC_BUILTIN != 0
- import_func_id = wasm_program_link_aot_internal_builtin_libc_func(program, field_name);
- if (import_func_id < 0) {
- return false;
- }
- *(uint32*)p_global_data = import_func_id + TABLE_SPACE_FOR_BUILTIN_LIBC;
- return true;
- #else
- return false;
- #endif
- }
- if (is_memop_symbol) {
- bh_assert(program->config.import_memop_mode == FROM_ROOT);
- root_module_inst = (AOTModuleInstance*)program->root_module_inst;
- root_module = (AOTModule*)root_module_inst->aot_module.ptr;
- AOTExportFunctionInstance * export_funcs = (AOTExportFunctionInstance *)root_module_inst->export_funcs.ptr;
- for (i = 0; i < root_module->export_func_count; i++) {
- if (!strcmp(export_funcs[i].func_name, field_name->str)) {
- import_func_id = (int32)i;
- break;
- }
- }
- if (import_func_id == -1)
- return false;
- import_func_id += TABLE_SPACE_SLOT_SIZE - root_module->export_func_count;
- *(uint32*)p_global_data = import_func_id;
- return true;
- }
- // not sys symbol
- // other module's export
- return false;
- }
- #endif
- bool
- wasm_program_link_got_globals(WASMProgramInstance * program,
- WASMModuleInstance * module_inst,
- WASMGlobalInstance * global,
- const ConstStrDescription * field_name)
- {
- WASMRuntime * runtime = program->runtime;
- // WASMModule * wasm_module = module_inst->module;
- // uint32 import_func_count = wasm_module->import_function_count;
- int32 import_func_id = -1;
- uint32 i = 0;
- WASMModuleInstance * root_module_inst = NULL;
- bool is_sys_symbol = wasm_runtime_is_system_symbol(runtime, field_name);
- bool is_memop_symbol = wasm_runtime_is_memop_symbol(runtime, field_name);
- if (is_sys_symbol &&
- (!is_memop_symbol ||
- program->config.import_memop_mode == FROM_BUILTIN_LIBC)) {
- #if WASM_ENABLE_LIBC_BUILTIN != 0
- import_func_id = wasm_program_link_internal_builtin_libc_func(program, field_name);
- if (import_func_id < 0) {
- return false;
- }
- global->initial_value.u32 = import_func_id + TABLE_SPACE_FOR_BUILTIN_LIBC;
- return true;
- #else
- return false;
- #endif
- }
- if (is_memop_symbol) {
- bh_assert(program->config.import_memop_mode == FROM_ROOT);
- root_module_inst = (WASMModuleInstance*)program->root_module_inst;
- #if 0
- if (program->config.root_is_AS_module) {
- if (field_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_malloc))
- field_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___alloc);
- else if (field_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_free))
- field_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___free);
- else if (field_name == CONST_STR_POOL_DESC(runtime, WAMR_CSP_realloc))
- field_name = CONST_STR_POOL_DESC(runtime, WAMR_CSP___realloc);
- }
- #endif
- for (i = 0; i < root_module_inst->export_func_count; i++) {
- if (!strcmp(root_module_inst->export_functions[i].name, field_name->str)) {
- import_func_id = (int32)i;
- break;
- }
- }
- if (import_func_id == -1)
- return false;
- import_func_id += TABLE_SPACE_SLOT_SIZE - root_module_inst->export_func_count;
- global->initial_value.u32 = import_func_id;
- return true;
- }
- // not sys symbol
- // other module's export
- return false;
- }
- bool
- check_symbol_signature(const WASMType *type, const char *signature);
- bool
- wasm_program_resolve_op_call_indirect(WASMProgramInstance * program,
- WASMModuleInstance * module_inst,
- uint32 tbl_idx,
- int32 tbl_slot_id,
- WASMType * func_type,
- WASMModuleInstance ** p_callee_module_inst,
- WASMFunctionInstance ** p_call_func)
- {
- uint32 inst_idx = 0, fidx = 0, export_func_id = 0;
- WASMModuleInstance * callee_module_inst = NULL;
- WASMFunctionInstance * call_func = NULL;
- WASMTableInstance * tbl_inst = NULL;
- WASMType * cur_func_type = NULL;
- int32 origin_slot_id = 0;
- bool is_local_func = true;
- if (tbl_slot_id < 0) {
- wasm_set_exception(module_inst, "undefined element");
- return false;
- }
- inst_idx = (tbl_slot_id >> TABLE_SPACE_BITS_LEN) + 1;
- origin_slot_id = tbl_slot_id;
- if (program) {
- // set --enable-dlopen
- if (inst_idx == module_inst->inst_id) { // call self-module
- callee_module_inst = module_inst;
- tbl_slot_id -= (inst_idx - 1) * TABLE_SPACE_SLOT_SIZE;
- tbl_inst = wasm_get_table_inst(callee_module_inst, tbl_idx);
- } else if (inst_idx == BUILTIN_LIBC_INST_ID) { // call libc function pointer
- is_local_func = false;
- fidx = tbl_slot_id - (inst_idx - 1) * TABLE_SPACE_SLOT_SIZE;
- if (fidx >= program->builtin_libc_funcs_count) {
- wasm_set_exception(module_inst, "undefined element");
- return false;
- }
- call_func = program->builtin_libc_funcs[fidx];
- if (!call_func) {
- wasm_set_exception(module_inst, "undefined element");
- return false;
- }
- if (call_func->u.func_import->func_type) {
- if (!wasm_type_equal(func_type, call_func->u.func_import->func_type)) {
- wasm_set_exception(module_inst, "indirect call type mismatch");
- return false;
- }
- } else {
- if (!check_symbol_signature(func_type, call_func->u.func_import->signature))
- return false;
- call_func->u.func_import->func_type = func_type;
- call_func->func_type = func_type;
- }
- callee_module_inst = module_inst;
- *p_callee_module_inst = callee_module_inst;
- *p_call_func = call_func;
- wasm_program_cache_resolve_result(program, origin_slot_id, call_func, callee_module_inst);
- return true;
- } else if (inst_idx > 1) { // call dependency module
- // call export function by non root module
- callee_module_inst = (WASMModuleInstance*)wasm_program_get_module_inst_by_id(program, inst_idx);
- if (!callee_module_inst) {
- wasm_set_exception(module_inst, "undefined element");
- return false;
- }
- bh_assert(callee_module_inst->module->dylink_section);
- tbl_slot_id -= (inst_idx - 1) * TABLE_SPACE_SLOT_SIZE;
- if (program->config.use_tbl_as_cache) {
- //if (tbl_slot_id >= (int32)callee_module_inst->module->dylink_section->table_size) {
- tbl_slot_id -= TABLE_SPACE_SLOT_SIZE - callee_module_inst->default_table->max_size;
- if ((uint32)tbl_slot_id < (callee_module_inst->default_table->max_size -
- callee_module_inst->export_func_count)) {
- wasm_set_exception(module_inst, "wrong export function id");
- return false;
- }
- //}
- tbl_inst = wasm_get_table_inst(callee_module_inst, tbl_idx);
- } else {
- is_local_func = false;
- tbl_slot_id = callee_module_inst->export_func_count - (TABLE_SPACE_SLOT_SIZE - tbl_slot_id);
- }
- } else {
- // call root module
- if (!tbl_slot_id) {
- wasm_set_exception(module_inst, "uninitialized element");
- return false;
- }
- callee_module_inst = (WASMModuleInstance*)program->root_module_inst;
- if (callee_module_inst->module->dylink_section &&
- program->config.use_tbl_as_cache) {
- tbl_inst = wasm_get_table_inst(callee_module_inst, tbl_idx);
- bh_assert(program->config.import_memop_mode != FROM_ROOT);
- if (tbl_slot_id > ((int32)callee_module_inst->module->dylink_section->table_size)) {
- tbl_slot_id -= TABLE_SPACE_SLOT_SIZE - callee_module_inst->default_table->max_size;
- }
- } else if (program->config.import_memop_mode == FROM_ROOT ||
- !program->config.use_tbl_as_cache) {
- is_local_func = false;
- tbl_slot_id = callee_module_inst->export_func_count - (TABLE_SPACE_SLOT_SIZE - tbl_slot_id);
- } else {
- wasm_set_exception(module_inst, "root module is not shared module");
- return false;
- }
- }
- } else {
- callee_module_inst = module_inst;
- tbl_inst = wasm_get_table_inst(callee_module_inst, tbl_idx);
- }
- if (!tbl_inst) { // func not in table
- if (!callee_module_inst->export_functions[tbl_slot_id].function) {
- wasm_set_exception(module_inst, "uninitialized element");
- return false;
- }
- fidx = (callee_module_inst->export_functions[tbl_slot_id].function -
- callee_module_inst->functions);
- } else {
- if (tbl_slot_id < 0 ||
- (tbl_slot_id >= (int32)tbl_inst->cur_size
- )) {
- wasm_set_exception(module_inst, "undefined element");
- return false;
- }
- fidx = ((uint32*)tbl_inst->base_addr)[tbl_slot_id];
- }
- if (fidx == (uint32)-1) {
- if (!program) {
- wasm_set_exception(module_inst, "uninitialized element");
- return false;
- }
- if (inst_idx < 1) {
- wasm_set_exception(module_inst, "uninitialized element");
- return false;
- }
- if (callee_module_inst->module->dylink_section) {
- if (tbl_slot_id < (int32)(tbl_inst->cur_size - callee_module_inst->export_func_count)) {
- wasm_set_exception(module_inst, "uninitialized element");
- return false;
- }
- } else if (tbl_slot_id < (int32)tbl_inst->cur_size) {
- wasm_set_exception(module_inst, "uninitialized element");
- return false;
- }
- if (program->config.binding_mode != LAZY_BINDING) {
- wasm_set_exception(module_inst, "uninitialized element");
- return false;
- }
- export_func_id = tbl_slot_id - (callee_module_inst->default_table->max_size -
- callee_module_inst->export_func_count);
- if (!callee_module_inst->export_functions[export_func_id].function) {
- wasm_set_exception(module_inst, "uninitialized element");
- return false;
- }
- // lazy link
- fidx = (callee_module_inst->export_functions[export_func_id].function -
- callee_module_inst->functions);
- ((uint32*)tbl_inst->base_addr)[tbl_slot_id] = fidx;
- }
- if (fidx >= callee_module_inst->function_count) {
- wasm_set_exception(module_inst, "unknown function");
- return false;
- }
- /* always call module own functions */
- call_func = callee_module_inst->functions + fidx;
- cur_func_type = call_func->func_type;
- if (!wasm_type_equal(func_type, cur_func_type)) {
- wasm_set_exception(module_inst, "indirect call type mismatch");
- return false;
- }
- *p_callee_module_inst = callee_module_inst;
- *p_call_func = call_func;
- if (!is_local_func) {
- wasm_program_cache_resolve_result(program, origin_slot_id, call_func, callee_module_inst);
- }
- return true;
- }
- #if WASM_ENABLE_AOT != 0
- bool
- wasm_program_resolve_aot_op_call_indirect(WASMExecEnv *exec_env,
- WASMProgramInstance * program,
- AOTModuleInstance * module_inst,
- uint32 tbl_idx,
- int32 table_elem_idx,
- uint32 expected_type_idx,
- AOTFuncType * expected_func_type,
- AOTModuleInstance ** p_callee_module_inst,
- AOTModule ** p_callee_module,
- uint32 * p_call_func_index,
- AOTImportFunc ** p_import_func)
- {
- AOTModuleInstance * callee_module_inst = NULL;
- AOTModule* callee_module = NULL;
- AOTModule *aot_module = (AOTModule*)module_inst->aot_module.ptr;
- AOTExportFunctionInstance * export_funcs = NULL, *call_func = NULL;
- AOTFuncType * func_type = NULL;
- AOTTableInstance *tbl_inst = NULL;
- uint32 inst_id = 0, export_func_id, local_table_elem_cnt;
- uint32 func_idx = 0, func_type_idx;
- void **func_ptrs = NULL, *func_ptr = NULL;
- AOTImportFunc *import_func = NULL;
- uint32 *func_type_indexes = NULL;
- char buf[96];
- int32 origin_elem_idx = table_elem_idx;
- if (table_elem_idx < 0) {
- aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
- return false;
- }
- inst_id = (table_elem_idx >> TABLE_SPACE_BITS_LEN) + 1;
- if (program) {
- if (inst_id == module_inst->inst_id) {
- callee_module_inst = module_inst;
- callee_module = (AOTModule*)callee_module_inst->aot_module.ptr;
- table_elem_idx -= (inst_id - 1) * TABLE_SPACE_SLOT_SIZE;
- tbl_inst = aot_get_table_inst(callee_module_inst, tbl_idx);
- } else if (inst_id == BUILTIN_LIBC_INST_ID) { // call libc function pointer
- //is_intable_func = false;
- func_idx = table_elem_idx - (inst_id - 1) * TABLE_SPACE_SLOT_SIZE;
- if (func_idx >= program->builtin_libc_funcs_count) {
- aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
- return false;
- }
- call_func = program->builtin_libc_funcs[func_idx];
- if (!call_func) {
- aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
- return false;
- }
- if (call_func->u.func_import->func_type) {
- if (!wasm_type_equal(expected_func_type, call_func->u.func_import->func_type)) {
- aot_set_exception(module_inst, "indirect call type mismatch");
- return false;
- }
- } else {
- if (!check_symbol_signature(expected_func_type, call_func->u.func_import->signature))
- return false;
- call_func->u.func_import->func_type = expected_func_type;
- }
- callee_module_inst = module_inst;
- *p_callee_module_inst = callee_module_inst;
- *p_call_func_index = 0;
- *p_import_func = call_func->u.func_import;
- wasm_program_cache_resolve_result(program, origin_elem_idx, (*p_import_func)->func_ptr_linked, callee_module_inst);
- return true;
- } else if (inst_id > 1) {
- callee_module_inst = (AOTModuleInstance*)wasm_program_get_module_inst_by_id(program, inst_id);
- if (!callee_module_inst) {
- aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
- return false;
- }
- callee_module = (AOTModule*)callee_module_inst->aot_module.ptr;
- table_elem_idx -= (inst_id - 1) * TABLE_SPACE_SLOT_SIZE;
- if (program->config.use_tbl_as_cache) {
- tbl_inst = aot_get_table_inst(callee_module_inst, tbl_idx);
- bh_assert(tbl_inst);
- local_table_elem_cnt = (uint32)callee_module->dylink_section->table_size;
- if (wasm_program_is_root_module((WASMModuleInstanceCommon*)callee_module_inst))
- local_table_elem_cnt ++;
- if ((uint32)table_elem_idx >= local_table_elem_cnt) {
- table_elem_idx -= TABLE_SPACE_SLOT_SIZE - tbl_inst->max_size;
- if ((uint32)table_elem_idx < (tbl_inst->max_size -
- callee_module->export_func_count)) {
- aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
- return false;
- }
- }
- } else {
- table_elem_idx = callee_module->export_func_count - (TABLE_SPACE_SLOT_SIZE - table_elem_idx);
- }
- } else {
- if (!table_elem_idx) {
- aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
- return false;
- }
- callee_module_inst = (AOTModuleInstance*)program->root_module_inst;
- callee_module = (AOTModule*)callee_module_inst->aot_module.ptr;
- if (callee_module->dylink_section &&
- program->config.use_tbl_as_cache) {
- tbl_inst = aot_get_table_inst(callee_module_inst, tbl_idx);
- if ((uint32)table_elem_idx > callee_module->dylink_section->table_size) {
- table_elem_idx -= TABLE_SPACE_SLOT_SIZE - tbl_inst->max_size;
- }
- } else if (program->config.import_memop_mode == FROM_ROOT ||
- !program->config.use_tbl_as_cache) {
- table_elem_idx = callee_module->export_func_count - (TABLE_SPACE_SLOT_SIZE - table_elem_idx);
- } else {
- aot_set_exception(module_inst, "root module is not shared module");
- return false;
- }
- }
- } else {
- callee_module_inst = module_inst;
- callee_module = aot_module;
- /* this function is called from native code, so exec_env->handle and
- exec_env->native_stack_boundary must have been set, we don't set
- it again */
- if ((uint8*)&callee_module_inst < exec_env->native_stack_boundary) {
- aot_set_exception_with_id(module_inst, EXCE_NATIVE_STACK_OVERFLOW);
- return false;
- }
- tbl_inst = aot_get_table_inst(callee_module_inst, tbl_idx);
- bh_assert(tbl_inst);
- if ((uint32)table_elem_idx >= tbl_inst->cur_size) {
- aot_set_exception_with_id(callee_module_inst, EXCE_UNDEFINED_ELEMENT);
- return false;
- }
- }
- if (!tbl_inst) {
- export_funcs = (AOTExportFunctionInstance*)callee_module_inst->export_funcs.ptr;
- func_idx = export_funcs[table_elem_idx].func_index;
- } else {
- if (table_elem_idx < 0 ||
- table_elem_idx >= (int32)tbl_inst->cur_size) {
- aot_set_exception_with_id(callee_module_inst, EXCE_UNDEFINED_ELEMENT);
- return false;
- }
- bh_assert( ((uint32*)tbl_inst->data + table_elem_idx) < (uint32*)callee_module_inst->global_table_data_end.ptr);
- func_idx = ((uint32*)tbl_inst->data)[table_elem_idx];
- }
- if (func_idx == (uint32)-1) {
- if (!program) {
- aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
- return false;
- }
- if (inst_id < 1) {
- aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
- return false;
- }
- if (callee_module->dylink_section) {
- if ((uint32)table_elem_idx < (tbl_inst->cur_size - callee_module->export_func_count)) {
- aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
- return false;
- }
- } else if ((uint32)table_elem_idx < tbl_inst->cur_size) {
- aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
- return false;
- }
- if (program->config.binding_mode != LAZY_BINDING) {
- aot_set_exception_with_id(module_inst, EXCE_UNINITIALIZED_ELEMENT);
- return false;
- }
- export_func_id = table_elem_idx - (tbl_inst->max_size -
- callee_module->export_func_count);
- export_funcs = (AOTExportFunctionInstance*)callee_module_inst->export_funcs.ptr;
- if (export_func_id >= callee_module->export_func_count) {
- aot_set_exception_with_id(module_inst, EXCE_UNDEFINED_ELEMENT);
- return false;
- }
- // lazy link
- func_idx = export_funcs[export_func_id].func_index;
- ((uint32*)tbl_inst->data)[table_elem_idx] = func_idx;
- }
- // aot_module = (AOTModule*)callee_module_inst->aot_module.ptr;
- func_ptrs = (void**)callee_module_inst->func_ptrs.ptr;
- func_type_indexes = (uint32*)callee_module_inst->func_type_indexes.ptr;
- func_type_idx = func_type_indexes[func_idx];
- func_type = callee_module->func_types[func_type_idx];
- if (!(func_ptr = func_ptrs[func_idx])) {
- bh_assert(func_idx < callee_module->import_func_count);
- import_func = callee_module->import_funcs + func_idx;
- snprintf(buf, sizeof(buf),
- "failed to call unlinked import function (%s, %s)",
- import_func->module_name->str, import_func->func_name->str);
- aot_set_exception(module_inst, buf);
- return false;
- }
- if (module_inst->inst_id == callee_module_inst->inst_id && expected_type_idx != func_type_idx) {
- aot_set_exception_with_id(module_inst, EXCE_INVALID_FUNCTION_TYPE_INDEX);
- return false;
- } else if (module_inst->inst_id != callee_module_inst->inst_id) {
- if (!wasm_type_equal(expected_func_type, func_type)) {
- aot_set_exception_with_id(module_inst, EXCE_INVALID_FUNCTION_TYPE_INDEX);
- return false;
- }
- }
- *p_callee_module_inst = callee_module_inst;
- *p_callee_module = callee_module;
- *p_call_func_index = func_idx;
- *p_import_func = NULL;
- wasm_program_cache_resolve_result(program, origin_elem_idx,
- ((void**)(*p_callee_module_inst)->func_ptrs.ptr)[func_idx],
- callee_module_inst);
- return true;
- }
- #if WASM_ENABLE_LIBC_BUILTIN != 0
- uint32
- wasm_program_get_ctype_tolower_mem(WASMModuleInstanceCommon * module_inst)
- {
- WASMProgramInstance * program = ((WASMModuleInstanceHead*)module_inst)->program;
- if (!program)
- return 0;
- return program->ctype_tolower_loc_space;
- }
- void
- wasm_program_set_ctype_tolower_mem(WASMModuleInstanceCommon * module_inst, uint32 addr)
- {
- WASMProgramInstance * program = ((WASMModuleInstanceHead*)module_inst)->program;
- if (!program)
- return;
- program->ctype_tolower_loc_space = addr;
- }
- #endif
- #endif
- #endif
|