mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-09 13:16:26 +00:00
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.
This commit is contained in:
parent
ca364eb5d7
commit
d8d8f8ce04
|
@ -289,55 +289,6 @@ loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
|
||||||
return mem;
|
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 *
|
static char *
|
||||||
load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
bool is_load_from_file_buf,
|
bool is_load_from_file_buf,
|
||||||
|
@ -359,7 +310,7 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
}
|
}
|
||||||
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
|
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
|
||||||
else if (is_vram_word_align) {
|
else if (is_vram_word_align) {
|
||||||
if (!(str = const_str_set_insert((uint8 *)p, str_len, module,
|
if (!(str = aot_const_str_set_insert((uint8 *)p, str_len, module,
|
||||||
is_vram_word_align, error_buf,
|
is_vram_word_align, error_buf,
|
||||||
error_buf_size))) {
|
error_buf_size))) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -378,7 +329,7 @@ load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||||
after loading, we must create another string and insert it
|
after loading, we must create another string and insert it
|
||||||
into const string set */
|
into const string set */
|
||||||
bh_assert(p[str_len - 1] == '\0');
|
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)
|
#if (WASM_ENABLE_WORD_ALIGN_READ != 0)
|
||||||
is_vram_word_align,
|
is_vram_word_align,
|
||||||
#endif
|
#endif
|
||||||
|
@ -3939,6 +3890,8 @@ create_module(char *error_buf, uint32 error_buf_size)
|
||||||
|
|
||||||
module->module_type = Wasm_Module_AoT;
|
module->module_type = Wasm_Module_AoT;
|
||||||
|
|
||||||
|
module->name = "";
|
||||||
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
module->import_module_list = &module->import_module_list_head;
|
module->import_module_list = &module->import_module_list_head;
|
||||||
ret = bh_list_init(module->import_module_list);
|
ret = bh_list_init(module->import_module_list);
|
||||||
|
|
|
@ -4663,3 +4663,71 @@ aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif /* end of WASM_ENABLE_GC != 0 */
|
#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;
|
||||||
|
}
|
||||||
|
|
|
@ -307,6 +307,9 @@ typedef struct AOTModule {
|
||||||
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
|
#if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
|
||||||
WASMCustomSection *custom_section_list;
|
WASMCustomSection *custom_section_list;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* user defined name */
|
||||||
|
char *name;
|
||||||
} AOTModule;
|
} AOTModule;
|
||||||
|
|
||||||
#define AOTMemoryInstance WASMMemoryInstance
|
#define AOTMemoryInstance WASMMemoryInstance
|
||||||
|
@ -761,6 +764,20 @@ bool
|
||||||
aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap);
|
aot_traverse_gc_rootset(WASMExecEnv *exec_env, void *heap);
|
||||||
#endif /* end of WASM_ENABLE_GC != 0 */
|
#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
|
#ifdef __cplusplus
|
||||||
} /* end of extern "C" */
|
} /* end of extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2949,6 +2949,34 @@ wasm_shared_module_delete(own wasm_shared_module_t *shared_module)
|
||||||
wasm_module_delete_internal((wasm_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 *
|
static wasm_func_t *
|
||||||
wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type,
|
wasm_func_new_basic(wasm_store_t *store, const wasm_functype_t *type,
|
||||||
wasm_func_callback_t func_callback)
|
wasm_func_callback_t func_callback)
|
||||||
|
|
|
@ -6585,3 +6585,44 @@ wasm_runtime_set_linux_perf(bool flag)
|
||||||
enable_linux_perf = flag;
|
enable_linux_perf = flag;
|
||||||
}
|
}
|
||||||
#endif
|
#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 "";
|
||||||
|
}
|
|
@ -25,73 +25,6 @@
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} 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 */
|
/* Internal function in object file */
|
||||||
typedef struct AOTObjectFunc {
|
typedef struct AOTObjectFunc {
|
||||||
char *func_name;
|
char *func_name;
|
||||||
|
@ -1592,7 +1525,7 @@ get_name_section_size(AOTCompData *comp_data)
|
||||||
return 0;
|
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");
|
aot_set_last_error("invalid UTF-8 encoding");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 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 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
|
// Function Instances
|
||||||
|
|
||||||
|
|
|
@ -1669,6 +1669,15 @@ wasm_runtime_begin_blocking_op(wasm_exec_env_t exec_env);
|
||||||
WASM_RUNTIME_API_EXTERN void
|
WASM_RUNTIME_API_EXTERN void
|
||||||
wasm_runtime_end_blocking_op(wasm_exec_env_t exec_env);
|
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 */
|
/* clang-format on */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -1048,6 +1048,9 @@ struct WASMModule {
|
||||||
bool is_ref_types_used;
|
bool is_ref_types_used;
|
||||||
bool is_bulk_memory_used;
|
bool is_bulk_memory_used;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* user defined name */
|
||||||
|
char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct BlockType {
|
typedef struct BlockType {
|
||||||
|
|
|
@ -366,138 +366,6 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new, char *error_buf,
|
||||||
mem = mem_new; \
|
mem = mem_new; \
|
||||||
} while (0)
|
} 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
|
#if WASM_ENABLE_GC != 0
|
||||||
static bool
|
static bool
|
||||||
check_type_index(const WASMModule *module, uint32 type_index, char *error_buf,
|
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 */
|
/* load module name */
|
||||||
read_leb_uint32(p, p_end, name_len);
|
read_leb_uint32(p, p_end, name_len);
|
||||||
CHECK_BUF(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,
|
p, name_len, module, is_load_from_file_buf, error_buf,
|
||||||
error_buf_size))) {
|
error_buf_size))) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -3380,7 +3248,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
/* load field name */
|
/* load field name */
|
||||||
read_leb_uint32(p, p_end, name_len);
|
read_leb_uint32(p, p_end, name_len);
|
||||||
CHECK_BUF(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,
|
p, name_len, module, is_load_from_file_buf, error_buf,
|
||||||
error_buf_size))) {
|
error_buf_size))) {
|
||||||
return false;
|
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,
|
p, str_len, module, is_load_from_file_buf, error_buf,
|
||||||
error_buf_size))) {
|
error_buf_size))) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -4987,7 +4855,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!(module->functions[func_index]->field_name =
|
if (!(module->functions[func_index]->field_name =
|
||||||
const_str_list_insert(
|
wasm_const_str_list_insert(
|
||||||
p, func_name_len, module,
|
p, func_name_len, module,
|
||||||
#if WASM_ENABLE_WAMR_COMPILER != 0
|
#if WASM_ENABLE_WAMR_COMPILER != 0
|
||||||
false,
|
false,
|
||||||
|
@ -5039,7 +4907,7 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
return false;
|
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");
|
set_error_buf(error_buf, error_buf_size, "invalid UTF-8 encoding");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -6067,6 +5935,8 @@ create_module(char *error_buf, uint32 error_buf_size)
|
||||||
/* Set start_function to -1, means no start function */
|
/* Set start_function to -1, means no start function */
|
||||||
module->start_function = (uint32)-1;
|
module->start_function = (uint32)-1;
|
||||||
|
|
||||||
|
module->name = "";
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_INTERP == 0
|
#if WASM_ENABLE_FAST_INTERP == 0
|
||||||
module->br_table_cache_list = &module->br_table_cache_list_head;
|
module->br_table_cache_list = &module->br_table_cache_list_head;
|
||||||
ret = bh_list_init(module->br_table_cache_list);
|
ret = bh_list_init(module->br_table_cache_list);
|
||||||
|
|
|
@ -217,63 +217,6 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new, char *error_buf,
|
||||||
mem = mem_new; \
|
mem = mem_new; \
|
||||||
} while (0)
|
} 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
|
static void
|
||||||
destroy_wasm_type(WASMFuncType *type)
|
destroy_wasm_type(WASMFuncType *type)
|
||||||
{
|
{
|
||||||
|
@ -1008,7 +951,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
/* load module name */
|
/* load module name */
|
||||||
read_leb_uint32(p, p_end, name_len);
|
read_leb_uint32(p, p_end, name_len);
|
||||||
CHECK_BUF(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,
|
p, name_len, module, is_load_from_file_buf, error_buf,
|
||||||
error_buf_size))) {
|
error_buf_size))) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1018,7 +961,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
/* load field name */
|
/* load field name */
|
||||||
read_leb_uint32(p, p_end, name_len);
|
read_leb_uint32(p, p_end, name_len);
|
||||||
CHECK_BUF(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,
|
p, name_len, module, is_load_from_file_buf, error_buf,
|
||||||
error_buf_size))) {
|
error_buf_size))) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1426,7 +1369,7 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
&& memcmp(name, p, str_len) == 0));
|
&& 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,
|
p, str_len, module, is_load_from_file_buf, error_buf,
|
||||||
error_buf_size))) {
|
error_buf_size))) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1957,7 +1900,7 @@ handle_name_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||||
func_index -= module->import_function_count;
|
func_index -= module->import_function_count;
|
||||||
bh_assert(func_index < module->function_count);
|
bh_assert(func_index < module->function_count);
|
||||||
if (!(module->functions[func_index]->field_name =
|
if (!(module->functions[func_index]->field_name =
|
||||||
const_str_list_insert(
|
wasm_const_str_list_insert(
|
||||||
p, func_name_len, module,
|
p, func_name_len, module,
|
||||||
is_load_from_file_buf, error_buf,
|
is_load_from_file_buf, error_buf,
|
||||||
error_buf_size))) {
|
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 */
|
/* Set start_function to -1, means no start function */
|
||||||
module->start_function = (uint32)-1;
|
module->start_function = (uint32)-1;
|
||||||
|
|
||||||
|
module->name = "";
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_INTERP == 0
|
#if WASM_ENABLE_FAST_INTERP == 0
|
||||||
module->br_table_cache_list = &module->br_table_cache_list_head;
|
module->br_table_cache_list = &module->br_table_cache_list_head;
|
||||||
ret = bh_list_init(module->br_table_cache_list);
|
ret = bh_list_init(module->br_table_cache_list);
|
||||||
|
|
|
@ -4400,3 +4400,154 @@ wasm_propagate_wasi_args(WASMModule *module)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
||||||
|
}
|
|
@ -836,6 +836,21 @@ exception_unlock(WASMModuleInstance *module_inst);
|
||||||
#define exception_unlock(module_inst) (void)(module_inst)
|
#define exception_unlock(module_inst) (void)(module_inst)
|
||||||
#endif
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -81,6 +82,8 @@ int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
wasm_byte_vec_delete(&binary);
|
wasm_byte_vec_delete(&binary);
|
||||||
|
|
||||||
|
assert(wasm_module_set_name(module, "hello"));
|
||||||
|
|
||||||
// Create external print functions.
|
// Create external print functions.
|
||||||
printf("Creating callback...\n");
|
printf("Creating callback...\n");
|
||||||
own wasm_functype_t* hello_type = wasm_functype_new_0_0();
|
own wasm_functype_t* hello_type = wasm_functype_new_0_0();
|
||||||
|
@ -117,6 +120,12 @@ int main(int argc, const char* argv[]) {
|
||||||
return 1;
|
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_module_delete(module);
|
||||||
wasm_instance_delete(instance);
|
wasm_instance_delete(instance);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user