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:
liang.he
2024-03-26 12:10:13 +08:00
committed by GitHub
parent ca364eb5d7
commit d8d8f8ce04
14 changed files with 367 additions and 322 deletions

View File

@ -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 {

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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