Allow missing imports in wasm loader and report error in wasm instantiation instead (#3539)

The wasm loader is failing when multi-module support is on and the dependent
modules are not found; this enforces the AOT compiler integrations to prepare
dependent modules while it isn't necessary.

This PR allows allows missing imports in wasm loader and report error in wasm
instantiation instead, which enables the integrated AOT compiler to work as if
the multi-module support isn't turned on.
This commit is contained in:
Xenia Lu
2024-06-25 10:04:39 +08:00
committed by GitHub
parent 54b87cb097
commit f7d2826772
9 changed files with 241 additions and 183 deletions

View File

@ -363,6 +363,10 @@
#define WASM_ENABLE_SPEC_TEST 0
#endif
#ifndef WASM_ENABLE_WASI_TEST
#define WASM_ENABLE_WASI_TEST 0
#endif
/* Global heap pool size in bytes */
#ifndef WASM_GLOBAL_HEAP_SIZE
#define WASM_GLOBAL_HEAP_SIZE (10 * 1024 * 1024)

View File

@ -1267,6 +1267,9 @@ wasm_runtime_is_built_in_module(const char *module_name)
|| !strcmp("wasi_snapshot_preview1", module_name)
#if WASM_ENABLE_SPEC_TEST != 0
|| !strcmp("spectest", module_name)
#endif
#if WASM_ENABLE_WASI_TEST != 0
|| !strcmp("foo", module_name)
#endif
|| !strcmp("", module_name));
}

View File

@ -2533,6 +2533,7 @@ load_function_import(const uint8 **p_buf, const uint8 *buf_end,
WASMFunction *linked_func = NULL;
#if WASM_ENABLE_MULTI_MODULE != 0
WASMModule *sub_module = NULL;
bool is_built_in_module = false;
#endif
const char *linked_signature = NULL;
void *linked_attachment = NULL;
@ -2568,17 +2569,16 @@ load_function_import(const uint8 **p_buf, const uint8 *buf_end,
}
#if WASM_ENABLE_MULTI_MODULE != 0
else {
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
if (!(is_built_in_module =
wasm_runtime_is_built_in_module(sub_module_name))) {
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
if (!sub_module) {
return false;
}
}
linked_func = wasm_loader_resolve_function(
sub_module_name, function_name, declare_func_type, error_buf,
error_buf_size);
if (is_built_in_module || sub_module)
linked_func = wasm_loader_resolve_function(
sub_module_name, function_name, declare_func_type, error_buf,
error_buf_size);
}
#endif
@ -2691,24 +2691,20 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
if (!sub_module) {
return false;
if (sub_module) {
linked_table = wasm_loader_resolve_table(
sub_module_name, table_name, declare_init_size,
declare_max_size, error_buf, error_buf_size);
if (linked_table) {
/* reset with linked table limit */
declare_elem_type = linked_table->table_type.elem_type;
declare_init_size = linked_table->table_type.init_size;
declare_max_size = linked_table->table_type.max_size;
declare_max_size_flag = linked_table->table_type.flags;
table->import_table_linked = linked_table;
table->import_module = sub_module;
}
}
linked_table = wasm_loader_resolve_table(
sub_module_name, table_name, declare_init_size, declare_max_size,
error_buf, error_buf_size);
if (!linked_table) {
return false;
}
/* reset with linked table limit */
declare_elem_type = linked_table->table_type.elem_type;
declare_init_size = linked_table->table_type.init_size;
declare_max_size = linked_table->table_type.max_size;
declare_max_size_flag = linked_table->table_type.flags;
table->import_table_linked = linked_table;
table->import_module = sub_module;
}
#endif /* WASM_ENABLE_MULTI_MODULE != 0 */
@ -2870,31 +2866,19 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
if (!sub_module) {
#if WASM_ENABLE_LIB_WASI_THREADS != 0
/* Avoid memory import failure when wasi-threads is enabled
and the memory is shared */
if (!(mem_flag & SHARED_MEMORY_FLAG))
return false;
#else
return false;
#endif /* WASM_ENABLE_LIB_WASI_THREADS */
}
else {
if (sub_module) {
linked_memory = wasm_loader_resolve_memory(
sub_module_name, memory_name, declare_init_page_count,
declare_max_page_count, error_buf, error_buf_size);
if (!linked_memory) {
return false;
if (linked_memory) {
/**
* reset with linked memory limit
*/
memory->import_module = sub_module;
memory->import_memory_linked = linked_memory;
declare_init_page_count = linked_memory->init_page_count;
declare_max_page_count = linked_memory->max_page_count;
}
/**
* reset with linked memory limit
*/
memory->import_module = sub_module;
memory->import_memory_linked = linked_memory;
declare_init_page_count = linked_memory->init_page_count;
declare_max_page_count = linked_memory->max_page_count;
}
}
#endif
@ -2920,6 +2904,29 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
declare_init_page_count = spectest_memory_init_page;
declare_max_page_count = spectest_memory_max_page;
}
#if WASM_ENABLE_WASI_TEST != 0
/* a case in wasi-testsuite which imports ("foo" "bar") */
else if (!strcmp("foo", sub_module_name)) {
uint32 spectest_memory_init_page = 1;
uint32 spectest_memory_max_page = 1;
if (strcmp("bar", memory_name)) {
set_error_buf(error_buf, error_buf_size,
"incompatible import type or unknown import");
return false;
}
if (declare_init_page_count > spectest_memory_init_page
|| declare_max_page_count < spectest_memory_max_page) {
set_error_buf(error_buf, error_buf_size,
"incompatible import type");
return false;
}
declare_init_page_count = spectest_memory_init_page;
declare_max_page_count = spectest_memory_max_page;
}
#endif
/* now we believe all declaration are ok */
memory->mem_type.flags = mem_flag;
@ -2983,20 +2990,19 @@ load_tag_import(const uint8 **p_buf, const uint8 *buf_end,
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
if (!sub_module) {
return false;
}
/* wasm_loader_resolve_tag checks, that the imported tag
* and the declared tag have the same type
*/
uint32 linked_tag_index = 0;
WASMTag *linked_tag = wasm_loader_resolve_tag(
sub_module_name, tag_name, declare_tag_type,
&linked_tag_index /* out */, error_buf, error_buf_size);
if (linked_tag) {
tag->import_module = sub_module;
tag->import_tag_linked = linked_tag;
tag->import_tag_index_linked = linked_tag_index;
if (sub_module) {
/* wasm_loader_resolve_tag checks, that the imported tag
* and the declared tag have the same type
*/
uint32 linked_tag_index = 0;
WASMTag *linked_tag = wasm_loader_resolve_tag(
sub_module_name, tag_name, declare_tag_type,
&linked_tag_index /* out */, error_buf, error_buf_size);
if (linked_tag) {
tag->import_module = sub_module;
tag->import_tag_linked = linked_tag;
tag->import_tag_index_linked = linked_tag_index;
}
}
}
#endif
@ -3095,18 +3101,16 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
if (!sub_module) {
return false;
}
/* check sub modules */
linked_global = wasm_loader_resolve_global(
sub_module_name, global_name, declare_type, declare_mutable,
error_buf, error_buf_size);
if (linked_global) {
global->import_module = sub_module;
global->import_global_linked = linked_global;
global->is_linked = true;
if (sub_module) {
/* check sub modules */
linked_global = wasm_loader_resolve_global(
sub_module_name, global_name, declare_type, declare_mutable,
error_buf, error_buf_size);
if (linked_global) {
global->import_module = sub_module;
global->import_global_linked = linked_global;
global->is_linked = true;
}
}
}
#endif

View File

@ -1710,36 +1710,73 @@ check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf,
&& !func->import_func_linked
#endif
) {
#if WASM_ENABLE_WAMR_COMPILER == 0
LOG_WARNING("warning: failed to link import function (%s, %s)",
func->module_name, func->field_name);
/* will throw exception only if calling */
#else
/* do nothing to avoid confused message */
#endif /* WASM_ENABLE_WAMR_COMPILER == 0 */
}
}
for (i = 0; i < module->import_global_count; i++) {
WASMGlobalImport *global = &((module->import_globals + i)->u.global);
if (!global->is_linked) {
#if WASM_ENABLE_SPEC_TEST != 0
set_error_buf(error_buf, error_buf_size,
"unknown import or incompatible import type");
return false;
#else
#if WASM_ENABLE_WAMR_COMPILER == 0
set_error_buf_v(error_buf, error_buf_size,
"failed to link import global (%s, %s)",
global->module_name, global->field_name);
return false;
#else
/* do nothing to avoid confused message */
#endif /* WASM_ENABLE_WAMR_COMPILER == 0 */
#endif /* WASM_ENABLE_SPEC_TEST != 0 */
}
}
for (i = 0; i < module->import_table_count; i++) {
WASMTableImport *table = &((module->import_tables + i)->u.table);
if (!wasm_runtime_is_built_in_module(table->module_name)
#if WASM_ENABLE_MULTI_MODULE != 0
&& !table->import_table_linked
#endif
) {
set_error_buf_v(error_buf, error_buf_size,
"failed to link import table (%s, %s)",
table->module_name, table->field_name);
return false;
}
}
for (i = 0; i < module->import_memory_count; i++) {
WASMMemoryImport *memory = &((module->import_memories + i)->u.memory);
if (!wasm_runtime_is_built_in_module(memory->module_name)
#if WASM_ENABLE_MULTI_MODULE != 0
&& !memory->import_memory_linked
#endif
) {
set_error_buf_v(error_buf, error_buf_size,
"failed to link import memory (%s, %s)",
memory->module_name, memory->field_name);
return false;
}
}
#if WASM_ENABLE_MULTI_MODULE != 0
#if WASM_ENABLE_TAGS != 0
for (i = 0; i < module->import_tag_count; i++) {
WASMTagImport *tag = &((module->import_tags + i)->u.tag);
if (!tag->import_tag_linked) {
set_error_buf_v(error_buf, error_buf_size,
"failed to link import tag (%s, %s)",
tag->module_name, tag->field_name);
return false;
}
}
#endif /* WASM_ENABLE_TAGS != 0 */
#endif
return true;
}