diff --git a/core/iwasm/aot/aot_loader.c b/core/iwasm/aot/aot_loader.c index 3e832c27..1634a897 100644 --- a/core/iwasm/aot/aot_loader.c +++ b/core/iwasm/aot/aot_loader.c @@ -289,55 +289,6 @@ loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size) return mem; } -static char * -const_str_set_insert(const uint8 *str, int32 len, AOTModule *module, -#if (WASM_ENABLE_WORD_ALIGN_READ != 0) - bool is_vram_word_align, -#endif - char *error_buf, uint32 error_buf_size) -{ - HashMap *set = module->const_str_set; - char *c_str, *value; - - /* Create const string set if it isn't created */ - if (!set - && !(set = module->const_str_set = bh_hash_map_create( - 32, false, (HashFunc)wasm_string_hash, - (KeyEqualFunc)wasm_string_equal, NULL, wasm_runtime_free))) { - set_error_buf(error_buf, error_buf_size, - "create const string set failed"); - return NULL; - } - - /* Lookup const string set, use the string if found */ - if (!(c_str = loader_malloc((uint32)len, error_buf, error_buf_size))) { - return NULL; - } -#if (WASM_ENABLE_WORD_ALIGN_READ != 0) - if (is_vram_word_align) { - bh_memcpy_wa(c_str, (uint32)len, str, (uint32)len); - } - else -#endif - { - bh_memcpy_s(c_str, len, str, (uint32)len); - } - - if ((value = bh_hash_map_find(set, c_str))) { - wasm_runtime_free(c_str); - return value; - } - - if (!bh_hash_map_insert(set, c_str, c_str)) { - set_error_buf(error_buf, error_buf_size, - "insert string to hash map failed"); - wasm_runtime_free(c_str); - return NULL; - } - - return c_str; -} - static char * load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module, bool is_load_from_file_buf, @@ -359,9 +310,9 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module, } #if (WASM_ENABLE_WORD_ALIGN_READ != 0) else if (is_vram_word_align) { - if (!(str = const_str_set_insert((uint8 *)p, str_len, module, - is_vram_word_align, error_buf, - error_buf_size))) { + if (!(str = aot_const_str_set_insert((uint8 *)p, str_len, module, + is_vram_word_align, error_buf, + error_buf_size))) { goto fail; } } @@ -378,11 +329,11 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module, after loading, we must create another string and insert it into const string set */ bh_assert(p[str_len - 1] == '\0'); - if (!(str = const_str_set_insert((uint8 *)p, str_len, module, + if (!(str = aot_const_str_set_insert((uint8 *)p, str_len, module, #if (WASM_ENABLE_WORD_ALIGN_READ != 0) - is_vram_word_align, + is_vram_word_align, #endif - error_buf, error_buf_size))) { + error_buf, error_buf_size))) { goto fail; } } @@ -3939,6 +3890,8 @@ create_module(char *error_buf, uint32 error_buf_size) module->module_type = Wasm_Module_AoT; + module->name = ""; + #if WASM_ENABLE_MULTI_MODULE != 0 module->import_module_list = &module->import_module_list_head; ret = bh_list_init(module->import_module_list); diff --git a/core/iwasm/aot/aot_runtime.c b/core/iwasm/aot/aot_runtime.c index cfca0f58..1489b626 100644 --- a/core/iwasm/aot/aot_runtime.c +++ b/core/iwasm/aot/aot_runtime.c @@ -4663,3 +4663,71 @@ aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap) return true; } #endif /* end of WASM_ENABLE_GC != 0 */ + +char * +aot_const_str_set_insert(const uint8 *str, int32 len, AOTModule *module, +#if (WASM_ENABLE_WORD_ALIGN_READ != 0) + bool is_vram_word_align, +#endif + char *error_buf, uint32 error_buf_size) +{ + HashMap *set = module->const_str_set; + char *c_str, *value; + + /* Create const string set if it isn't created */ + if (!set + && !(set = module->const_str_set = bh_hash_map_create( + 32, false, (HashFunc)wasm_string_hash, + (KeyEqualFunc)wasm_string_equal, NULL, wasm_runtime_free))) { + set_error_buf(error_buf, error_buf_size, + "create const string set failed"); + return NULL; + } + + /* Lookup const string set, use the string if found */ + if (!(c_str = runtime_malloc((uint32)len, error_buf, error_buf_size))) { + return NULL; + } +#if (WASM_ENABLE_WORD_ALIGN_READ != 0) + if (is_vram_word_align) { + bh_memcpy_wa(c_str, (uint32)len, str, (uint32)len); + } + else +#endif + { + bh_memcpy_s(c_str, len, str, (uint32)len); + } + + if ((value = bh_hash_map_find(set, c_str))) { + wasm_runtime_free(c_str); + return value; + } + + if (!bh_hash_map_insert(set, c_str, c_str)) { + set_error_buf(error_buf, error_buf_size, + "insert string to hash map failed"); + wasm_runtime_free(c_str); + return NULL; + } + + return c_str; +} + +bool +aot_set_module_name(AOTModule *module, const char *name, char *error_buf, + uint32_t error_buf_size) +{ + if (!name) + return false; + + module->name = + aot_const_str_set_insert((const uint8 *)name, strlen(name) + 1, module, + error_buf, error_buf_size); + return module->name != NULL; +} + +const char * +aot_get_module_name(AOTModule *module) +{ + return module->name; +} diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h index 1b5b610e..519c1edc 100644 --- a/core/iwasm/aot/aot_runtime.h +++ b/core/iwasm/aot/aot_runtime.h @@ -307,6 +307,9 @@ typedef struct AOTModule { #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 WASMCustomSection *custom_section_list; #endif + + /* user defined name */ + char *name; } AOTModule; #define AOTMemoryInstance WASMMemoryInstance @@ -761,6 +764,20 @@ bool aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap); #endif /* end of WASM_ENABLE_GC != 0 */ +char * +aot_const_str_set_insert(const uint8 *str, int32 len, AOTModule *module, +#if (WASM_ENABLE_WORD_ALIGN_READ != 0) + bool is_vram_word_align, +#endif + char *error_buf, uint32 error_buf_size); + +bool +aot_set_module_name(AOTModule *module, const char *name, char *error_buf, + uint32_t error_buf_size); + +const char * +aot_get_module_name(AOTModule *module); + #ifdef __cplusplus } /* end of extern "C" */ #endif diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index 39073984..10ceb758 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -2949,6 +2949,34 @@ wasm_shared_module_delete(own wasm_shared_module_t *shared_module) wasm_module_delete_internal((wasm_module_t *)shared_module); } +bool +wasm_module_set_name(wasm_module_t *module, const char *name) +{ + char error_buf[256] = { 0 }; + wasm_module_ex_t *module_ex = NULL; + + if (!module) + return false; + + module_ex = module_to_module_ext(module); + bool ret = wasm_runtime_set_module_name(module_ex->module_comm_rt, name, + error_buf, sizeof(error_buf) - 1); + if (!ret) + LOG_WARNING("set module name failed: %s", error_buf); + return ret; +} + +const char * +wasm_module_get_name(wasm_module_t *module) +{ + wasm_module_ex_t *module_ex = NULL; + if (!module) + return ""; + + module_ex = module_to_module_ext(module); + return wasm_runtime_get_module_name(module_ex->module_comm_rt); +} + static wasm_func_t * wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type, wasm_func_callback_t func_callback) diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 4191a672..b3ee4509 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -6585,3 +6585,44 @@ wasm_runtime_set_linux_perf(bool flag) enable_linux_perf = flag; } #endif + +bool +wasm_runtime_set_module_name(wasm_module_t module, const char *name, + char *error_buf, uint32_t error_buf_size) +{ + if (!module) + return false; + +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) + return wasm_set_module_name((WASMModule *)module, name, error_buf, + error_buf_size); +#endif + +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) + return aot_set_module_name((AOTModule *)module, name, error_buf, + error_buf_size); +#endif + + return false; +} + +const char * +wasm_runtime_get_module_name(wasm_module_t module) +{ + if (!module) + return ""; + +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) + return wasm_get_module_name((WASMModule *)module); +#endif + +#if WASM_ENABLE_AOT != 0 + if (module->module_type == Wasm_Module_AoT) + return aot_get_module_name((AOTModule *)module); +#endif + + return ""; +} \ No newline at end of file diff --git a/core/iwasm/compilation/aot_emit_aot_file.c b/core/iwasm/compilation/aot_emit_aot_file.c index 3bad41f3..7a6c668f 100644 --- a/core/iwasm/compilation/aot_emit_aot_file.c +++ b/core/iwasm/compilation/aot_emit_aot_file.c @@ -25,73 +25,6 @@ } \ } while (0) -#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 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); -} -#endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */ - /* Internal function in object file */ typedef struct AOTObjectFunc { char *func_name; @@ -1592,7 +1525,7 @@ get_name_section_size(AOTCompData *comp_data) return 0; } - if (!check_utf8_str(p, name_len)) { + if (!wasm_check_utf8_str(p, name_len)) { aot_set_last_error("invalid UTF-8 encoding"); return 0; } diff --git a/core/iwasm/include/wasm_c_api.h b/core/iwasm/include/wasm_c_api.h index 645a19a6..606b9ff8 100644 --- a/core/iwasm/include/wasm_c_api.h +++ b/core/iwasm/include/wasm_c_api.h @@ -536,6 +536,9 @@ WASM_API_EXTERN own wasm_shared_module_t* wasm_module_share(wasm_module_t*); WASM_API_EXTERN own wasm_module_t* wasm_module_obtain(wasm_store_t*, wasm_shared_module_t*); WASM_API_EXTERN void wasm_shared_module_delete(own wasm_shared_module_t*); +WASM_API_EXTERN bool wasm_module_set_name(wasm_module_t*, const char* name); +WASM_API_EXTERN const char *wasm_module_get_name(wasm_module_t*); + // Function Instances diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index f2099342..b40a3440 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -539,7 +539,7 @@ wasm_runtime_instantiate(const wasm_module_t module, /** * Instantiate a WASM module, with specified instantiation arguments - * + * * Same as wasm_runtime_instantiate, but it also allows overwriting maximum memory */ WASM_RUNTIME_API_EXTERN wasm_module_inst_t @@ -1669,6 +1669,15 @@ wasm_runtime_begin_blocking_op(wasm_exec_env_t exec_env); WASM_RUNTIME_API_EXTERN void wasm_runtime_end_blocking_op(wasm_exec_env_t exec_env); + +WASM_RUNTIME_API_EXTERN bool +wasm_runtime_set_module_name(wasm_module_t module, const char *name, + char *error_buf, uint32_t error_buf_size); + +/* return the most recently set module name or "" if never set before */ +WASM_RUNTIME_API_EXTERN const char* +wasm_runtime_get_module_name(wasm_module_t module); + /* clang-format on */ #ifdef __cplusplus diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index 683b40f6..56c8ebe7 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -1048,6 +1048,9 @@ struct WASMModule { bool is_ref_types_used; bool is_bulk_memory_used; #endif + + /* user defined name */ + char *name; }; typedef struct BlockType { diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 3edd7ff5..9837c08d 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -366,138 +366,6 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new, char *error_buf, mem = mem_new; \ } while (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 == 0) { - LOG_WARNING( - "LIMITATION: a string which contains '\\00' is unsupported"); - return false; - } - else 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 { /* 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 <= 0xF3) { /* and also chr >= 0xF1 */ - if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF - || p[3] < 0x80 || p[3] > 0xBF) { - return false; - } - } - else { /* 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); -} - -static char * -const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module, - bool is_load_from_file_buf, char *error_buf, - uint32 error_buf_size) -{ - StringNode *node, *node_next; - - if (!check_utf8_str(str, len)) { - set_error_buf(error_buf, error_buf_size, "invalid UTF-8 encoding"); - return NULL; - } - - if (len == 0) { - return ""; - } - else if (is_load_from_file_buf) { - /* As the file buffer can be referred to after loading, we use - the previous byte of leb encoded size to adjust the string: - move string 1 byte backward and then append '\0' */ - char *c_str = (char *)str - 1; - bh_memmove_s(c_str, len + 1, c_str + 1, len); - c_str[len] = '\0'; - return c_str; - } - - /* Search const str list */ - node = module->const_str_list; - while (node) { - node_next = node->next; - if (strlen(node->str) == len && !memcmp(node->str, str, len)) - break; - node = node_next; - } - - if (node) { - return node->str; - } - - if (!(node = loader_malloc(sizeof(StringNode) + len + 1, error_buf, - error_buf_size))) { - return NULL; - } - - node->str = ((char *)node) + sizeof(StringNode); - bh_memcpy_s(node->str, len + 1, str, len); - node->str[len] = '\0'; - - if (!module->const_str_list) { - /* set as head */ - module->const_str_list = node; - node->next = NULL; - } - else { - /* insert it */ - node->next = module->const_str_list; - module->const_str_list = node; - } - - return node->str; -} - #if WASM_ENABLE_GC != 0 static bool check_type_index(const WASMModule *module, uint32 type_index, char *error_buf, @@ -3370,7 +3238,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, /* load module name */ read_leb_uint32(p, p_end, name_len); CHECK_BUF(p, p_end, name_len); - if (!(sub_module_name = const_str_list_insert( + if (!(sub_module_name = wasm_const_str_list_insert( p, name_len, module, is_load_from_file_buf, error_buf, error_buf_size))) { return false; @@ -3380,7 +3248,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, /* load field name */ read_leb_uint32(p, p_end, name_len); CHECK_BUF(p, p_end, name_len); - if (!(field_name = const_str_list_insert( + if (!(field_name = wasm_const_str_list_insert( p, name_len, module, is_load_from_file_buf, error_buf, error_buf_size))) { return false; @@ -4103,7 +3971,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, } } - if (!(export->name = const_str_list_insert( + if (!(export->name = wasm_const_str_list_insert( p, str_len, module, is_load_from_file_buf, error_buf, error_buf_size))) { return false; @@ -4987,7 +4855,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, return false; } if (!(module->functions[func_index]->field_name = - const_str_list_insert( + wasm_const_str_list_insert( p, func_name_len, module, #if WASM_ENABLE_WAMR_COMPILER != 0 false, @@ -5039,7 +4907,7 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, return false; } - if (!check_utf8_str(p, name_len)) { + if (!wasm_check_utf8_str(p, name_len)) { set_error_buf(error_buf, error_buf_size, "invalid UTF-8 encoding"); return false; } @@ -6067,6 +5935,8 @@ create_module(char *error_buf, uint32 error_buf_size) /* Set start_function to -1, means no start function */ module->start_function = (uint32)-1; + module->name = ""; + #if WASM_ENABLE_FAST_INTERP == 0 module->br_table_cache_list = &module->br_table_cache_list_head; ret = bh_list_init(module->br_table_cache_list); diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index 21e44247..8d99f6ea 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -217,63 +217,6 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new, char *error_buf, mem = mem_new; \ } while (0) -static char * -const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module, - bool is_load_from_file_buf, char *error_buf, - uint32 error_buf_size) -{ - StringNode *node, *node_next; - - if (len == 0) { - return ""; - } - else if (is_load_from_file_buf) { - /* As the file buffer can be referred to after loading, we use - the previous byte of leb encoded size to adjust the string: - move string 1 byte backward and then append '\0' */ - char *c_str = (char *)str - 1; - bh_memmove_s(c_str, len + 1, c_str + 1, len); - c_str[len] = '\0'; - return c_str; - } - - /* Search const str list */ - node = module->const_str_list; - while (node) { - node_next = node->next; - if (strlen(node->str) == len && !memcmp(node->str, str, len)) - break; - node = node_next; - } - - if (node) { - LOG_DEBUG("reuse %s", node->str); - return node->str; - } - - if (!(node = loader_malloc(sizeof(StringNode) + len + 1, error_buf, - error_buf_size))) { - return NULL; - } - - node->str = ((char *)node) + sizeof(StringNode); - bh_memcpy_s(node->str, len + 1, str, len); - node->str[len] = '\0'; - - if (!module->const_str_list) { - /* set as head */ - module->const_str_list = node; - node->next = NULL; - } - else { - /* insert it */ - node->next = module->const_str_list; - module->const_str_list = node; - } - - return node->str; -} - static void destroy_wasm_type(WASMFuncType *type) { @@ -1008,7 +951,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, /* load module name */ read_leb_uint32(p, p_end, name_len); CHECK_BUF(p, p_end, name_len); - if (!(sub_module_name = const_str_list_insert( + if (!(sub_module_name = wasm_const_str_list_insert( p, name_len, module, is_load_from_file_buf, error_buf, error_buf_size))) { return false; @@ -1018,7 +961,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, /* load field name */ read_leb_uint32(p, p_end, name_len); CHECK_BUF(p, p_end, name_len); - if (!(field_name = const_str_list_insert( + if (!(field_name = wasm_const_str_list_insert( p, name_len, module, is_load_from_file_buf, error_buf, error_buf_size))) { return false; @@ -1426,7 +1369,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, && memcmp(name, p, str_len) == 0)); } - if (!(export->name = const_str_list_insert( + if (!(export->name = wasm_const_str_list_insert( p, str_len, module, is_load_from_file_buf, error_buf, error_buf_size))) { return false; @@ -1957,7 +1900,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, func_index -= module->import_function_count; bh_assert(func_index < module->function_count); if (!(module->functions[func_index]->field_name = - const_str_list_insert( + wasm_const_str_list_insert( p, func_name_len, module, is_load_from_file_buf, error_buf, error_buf_size))) { @@ -2983,6 +2926,8 @@ create_module(char *error_buf, uint32 error_buf_size) /* Set start_function to -1, means no start function */ module->start_function = (uint32)-1; + module->name = ""; + #if WASM_ENABLE_FAST_INTERP == 0 module->br_table_cache_list = &module->br_table_cache_list_head; ret = bh_list_init(module->br_table_cache_list); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 187a44f4..f80d182d 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -4400,3 +4400,154 @@ wasm_propagate_wasi_args(WASMModule *module) } } #endif + +bool +wasm_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 == 0) { + LOG_WARNING( + "LIMITATION: a string which contains '\\00' is unsupported"); + return false; + } + else 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 { /* 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 <= 0xF3) { /* and also chr >= 0xF1 */ + if (p[1] < 0x80 || p[1] > 0xBF || p[2] < 0x80 || p[2] > 0xBF + || p[3] < 0x80 || p[3] > 0xBF) { + return false; + } + } + else { /* 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); +} + +char * +wasm_const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module, + bool is_load_from_file_buf, char *error_buf, + uint32 error_buf_size) +{ + StringNode *node, *node_next; + + if (!wasm_check_utf8_str(str, len)) { + set_error_buf(error_buf, error_buf_size, "invalid UTF-8 encoding"); + return NULL; + } + + if (len == 0) { + return ""; + } + else if (is_load_from_file_buf) { + /* As the file buffer can be referred to after loading, we use + the previous byte of leb encoded size to adjust the string: + move string 1 byte backward and then append '\0' */ + char *c_str = (char *)str - 1; + bh_memmove_s(c_str, len + 1, c_str + 1, len); + c_str[len] = '\0'; + return c_str; + } + + /* Search const str list */ + node = module->const_str_list; + while (node) { + node_next = node->next; + if (strlen(node->str) == len && !memcmp(node->str, str, len)) + break; + node = node_next; + } + + if (node) { + return node->str; + } + + if (!(node = runtime_malloc(sizeof(StringNode) + len + 1, error_buf, + error_buf_size))) { + return NULL; + } + + node->str = ((char *)node) + sizeof(StringNode); + bh_memcpy_s(node->str, len + 1, str, len); + node->str[len] = '\0'; + + if (!module->const_str_list) { + /* set as head */ + module->const_str_list = node; + node->next = NULL; + } + else { + /* insert it */ + node->next = module->const_str_list; + module->const_str_list = node; + } + + return node->str; +} + +bool +wasm_set_module_name(WASMModule *module, const char *name, char *error_buf, + uint32_t error_buf_size) +{ + if (!name) + return false; + + module->name = + wasm_const_str_list_insert((const uint8 *)name, strlen(name), module, + false, error_buf, error_buf_size); + return module->name != NULL; +} + +const char * +wasm_get_module_name(WASMModule *module) +{ + return module->name; +} \ No newline at end of file diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 227b8dfd..5933e6a9 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -836,6 +836,21 @@ exception_unlock(WASMModuleInstance *module_inst); #define exception_unlock(module_inst) (void)(module_inst) #endif +bool +wasm_check_utf8_str(const uint8 *str, uint32 len); + +char * +wasm_const_str_list_insert(const uint8 *str, uint32 len, WASMModule *module, + bool is_load_from_file_buf, char *error_buf, + uint32 error_buf_size); + +bool +wasm_set_module_name(WASMModule *module, const char *name, char *error_buf, + uint32_t error_buf_size); + +const char * +wasm_get_module_name(WASMModule *module); + #ifdef __cplusplus } #endif diff --git a/samples/wasm-c-api/src/hello.c b/samples/wasm-c-api/src/hello.c index 966e141d..6650f348 100644 --- a/samples/wasm-c-api/src/hello.c +++ b/samples/wasm-c-api/src/hello.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -81,6 +82,8 @@ int main(int argc, const char* argv[]) { wasm_byte_vec_delete(&binary); + assert(wasm_module_set_name(module, "hello")); + // Create external print functions. printf("Creating callback...\n"); own wasm_functype_t* hello_type = wasm_functype_new_0_0(); @@ -117,6 +120,12 @@ int main(int argc, const char* argv[]) { return 1; } + { + const char* name = wasm_module_get_name(module); + assert(strncmp(name, "hello", 5) == 0); + printf("> removing module %s \n", name); + } + wasm_module_delete(module); wasm_instance_delete(instance);