Explorar el Código

Implement apis to set and get the name of a wasm module (#3254)

Add API wasm_runtime_set_module_name and wasm_runtime_get_module_name,
and by default, a module's name is "" if the set module name api isn't called.
liang.he hace 1 año
padre
commit
d8d8f8ce04

+ 8 - 55
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);

+ 68 - 0
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;
+}

+ 17 - 0
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

+ 28 - 0
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)

+ 41 - 0
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 "";
+}

+ 1 - 68
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;
     }

+ 3 - 0
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
 

+ 10 - 1
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

+ 3 - 0
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 {

+ 7 - 137
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);

+ 6 - 61
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);

+ 151 - 0
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;
+}

+ 15 - 0
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

+ 9 - 0
samples/wasm-c-api/src/hello.c

@@ -1,3 +1,4 @@
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -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);