Support muti-module for AOT mode (#2482)
Support muti-module for AOT mode, currently only implement the multi-module's function import feature for AOT, the memory/table/ global import are not implemented yet. And update wamr-test-suites scripts, multi-module sample and some CIs accordingly.
This commit is contained in:
committed by
GitHub
parent
fff0e2ad1c
commit
79b27c1934
@ -558,6 +558,56 @@ str2uint32(const char *buf, uint32 *p_res);
|
||||
static bool
|
||||
str2uint64(const char *buf, uint64 *p_res);
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
static void *
|
||||
aot_loader_resolve_function(const char *module_name, const char *function_name,
|
||||
const AOTFuncType *expected_function_type,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMModuleCommon *module_reg;
|
||||
void *function = NULL;
|
||||
AOTExport *export = NULL;
|
||||
AOTModule *module = NULL;
|
||||
AOTFuncType *target_function_type = NULL;
|
||||
|
||||
module_reg = wasm_runtime_find_module_registered(module_name);
|
||||
if (!module_reg || module_reg->module_type != Wasm_Module_AoT) {
|
||||
LOG_DEBUG("can not find a module named %s for function %s", module_name,
|
||||
function_name);
|
||||
set_error_buf(error_buf, error_buf_size, "unknown import");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
module = (AOTModule *)module_reg;
|
||||
export = loader_find_export(module_reg, module_name, function_name,
|
||||
EXPORT_KIND_FUNC, error_buf, error_buf_size);
|
||||
if (!export) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* resolve function type and function */
|
||||
if (export->index < module->import_func_count) {
|
||||
target_function_type = module->import_funcs[export->index].func_type;
|
||||
function = module->import_funcs[export->index].func_ptr_linked;
|
||||
}
|
||||
else {
|
||||
target_function_type =
|
||||
module->func_types[module->func_type_indexes
|
||||
[export->index - module->import_func_count]];
|
||||
function =
|
||||
(module->func_ptrs[export->index - module->import_func_count]);
|
||||
}
|
||||
/* check function type */
|
||||
if (!wasm_type_equal(expected_function_type, target_function_type)) {
|
||||
LOG_DEBUG("%s.%s failed the type check", module_name, function_name);
|
||||
set_error_buf(error_buf, error_buf_size, "incompatible import type");
|
||||
return NULL;
|
||||
}
|
||||
return function;
|
||||
}
|
||||
|
||||
#endif /* end of WASM_ENABLE_MULTI_MODULE */
|
||||
|
||||
static bool
|
||||
load_native_symbol_section(const uint8 *buf, const uint8 *buf_end,
|
||||
AOTModule *module, bool is_load_from_file_buf,
|
||||
@ -1357,11 +1407,16 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
bool is_load_from_file_buf, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
const char *module_name, *field_name;
|
||||
char *module_name, *field_name;
|
||||
const uint8 *buf = *p_buf;
|
||||
AOTImportFunc *import_funcs;
|
||||
uint64 size;
|
||||
uint32 i;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
AOTModule *sub_module = NULL;
|
||||
AOTFunc *linked_func = NULL;
|
||||
WASMType *declare_func_type = NULL;
|
||||
#endif
|
||||
|
||||
/* Allocate memory */
|
||||
size = sizeof(AOTImportFunc) * (uint64)module->import_func_count;
|
||||
@ -1377,17 +1432,46 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
|
||||
set_error_buf(error_buf, error_buf_size, "unknown type");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
declare_func_type = module->func_types[import_funcs[i].func_type_index];
|
||||
read_string(buf, buf_end, module_name);
|
||||
read_string(buf, buf_end, field_name);
|
||||
|
||||
import_funcs[i].module_name = module_name;
|
||||
import_funcs[i].func_name = field_name;
|
||||
linked_func = wasm_native_resolve_symbol(
|
||||
module_name, field_name, declare_func_type,
|
||||
&import_funcs[i].signature, &import_funcs[i].attachment,
|
||||
&import_funcs[i].call_conv_raw);
|
||||
if (!linked_func) {
|
||||
if (!wasm_runtime_is_built_in_module(module_name)) {
|
||||
sub_module = (AOTModule *)wasm_runtime_load_depended_module(
|
||||
(WASMModuleCommon *)module, module_name, error_buf,
|
||||
error_buf_size);
|
||||
if (!sub_module) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
linked_func = aot_loader_resolve_function(
|
||||
module_name, field_name, declare_func_type, error_buf,
|
||||
error_buf_size);
|
||||
}
|
||||
import_funcs[i].func_ptr_linked = linked_func;
|
||||
import_funcs[i].func_type = declare_func_type;
|
||||
|
||||
#else
|
||||
import_funcs[i].func_type =
|
||||
module->func_types[import_funcs[i].func_type_index];
|
||||
read_string(buf, buf_end, import_funcs[i].module_name);
|
||||
read_string(buf, buf_end, import_funcs[i].func_name);
|
||||
|
||||
module_name = import_funcs[i].module_name;
|
||||
field_name = import_funcs[i].func_name;
|
||||
import_funcs[i].func_ptr_linked = wasm_native_resolve_symbol(
|
||||
module_name, field_name, import_funcs[i].func_type,
|
||||
&import_funcs[i].signature, &import_funcs[i].attachment,
|
||||
&import_funcs[i].call_conv_raw);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
if (!strcmp(import_funcs[i].module_name, "wasi_unstable")
|
||||
@ -2872,12 +2956,17 @@ create_module(char *error_buf, uint32 error_buf_size)
|
||||
AOTModule *module =
|
||||
loader_malloc(sizeof(AOTModule), error_buf, error_buf_size);
|
||||
|
||||
bh_list_status ret;
|
||||
if (!module) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
module->module_type = Wasm_Module_AoT;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
module->import_module_list = &module->import_module_list_head;
|
||||
ret = bh_list_init(module->import_module_list);
|
||||
bh_assert(ret == BH_LIST_SUCCESS);
|
||||
#endif
|
||||
(void)ret;
|
||||
return module;
|
||||
}
|
||||
|
||||
@ -3201,6 +3290,19 @@ aot_unload(AOTModule *module)
|
||||
|
||||
if (module->const_str_set)
|
||||
bh_hash_map_destroy(module->const_str_set);
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
/* just release the sub module list */
|
||||
if (module->import_module_list) {
|
||||
WASMRegisteredModule *node =
|
||||
bh_list_first_elem(module->import_module_list);
|
||||
while (node) {
|
||||
WASMRegisteredModule *next = bh_list_elem_next(node);
|
||||
bh_list_remove(module->import_module_list, node);
|
||||
wasm_runtime_free(node);
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (module->code && !module->is_indirect_mode) {
|
||||
/* The layout is: literal size + literal + code (with plt table) */
|
||||
|
||||
@ -1091,6 +1091,9 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
|
||||
uint8 *p;
|
||||
uint32 i, extra_info_offset;
|
||||
const bool is_sub_inst = parent != NULL;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
bool ret = false;
|
||||
#endif
|
||||
|
||||
/* Check heap size */
|
||||
heap_size = align_uint(heap_size, 8);
|
||||
@ -1134,6 +1137,18 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
|
||||
module_inst->e =
|
||||
(WASMModuleInstanceExtra *)((uint8 *)module_inst + extra_info_offset);
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list =
|
||||
&((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list_head;
|
||||
ret = wasm_runtime_sub_module_instantiate(
|
||||
(WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst,
|
||||
stack_size, heap_size, error_buf, error_buf_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("build a sub module list failed");
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Initialize global info */
|
||||
p = (uint8 *)module_inst + module_inst_struct_size
|
||||
+ module_inst_mem_inst_size;
|
||||
@ -1256,6 +1271,11 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
wasm_runtime_sub_module_deinstantiate(
|
||||
(WASMModuleInstanceCommon *)module_inst);
|
||||
#endif
|
||||
|
||||
if (module_inst->tables)
|
||||
wasm_runtime_free(module_inst->tables);
|
||||
|
||||
@ -1411,10 +1431,43 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
|
||||
unsigned argc, uint32 argv[])
|
||||
{
|
||||
AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
|
||||
AOTFuncType *func_type = function->u.func.func_type;
|
||||
AOTFuncType *func_type = function->is_import_func
|
||||
? function->u.func_import->func_type
|
||||
: function->u.func.func_type;
|
||||
uint32 result_count = func_type->result_count;
|
||||
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
|
||||
bool ret;
|
||||
void *func_ptr = function->is_import_func
|
||||
? function->u.func_import->func_ptr_linked
|
||||
: function->u.func.func_ptr;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
bh_list *sub_module_list_node = NULL;
|
||||
const char *sub_inst_name = NULL;
|
||||
const char *func_name = function->u.func_import->module_name;
|
||||
if (function->is_import_func) {
|
||||
sub_module_list_node =
|
||||
((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list;
|
||||
sub_module_list_node = bh_list_first_elem(sub_module_list_node);
|
||||
while (sub_module_list_node) {
|
||||
sub_inst_name =
|
||||
((AOTSubModInstNode *)sub_module_list_node)->module_name;
|
||||
if (strcmp(sub_inst_name, func_name) == 0) {
|
||||
exec_env = wasm_runtime_get_exec_env_singleton(
|
||||
(WASMModuleInstanceCommon *)((AOTSubModInstNode *)
|
||||
sub_module_list_node)
|
||||
->module_inst);
|
||||
module_inst = (AOTModuleInstance *)exec_env->module_inst;
|
||||
break;
|
||||
}
|
||||
sub_module_list_node = bh_list_elem_next(sub_module_list_node);
|
||||
}
|
||||
if (exec_env == NULL) {
|
||||
wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst,
|
||||
"create singleton exec_env failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (argc < func_type->param_cell_num) {
|
||||
char buf[108];
|
||||
@ -1436,8 +1489,7 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
|
||||
#endif
|
||||
|
||||
/* func pointer was looked up previously */
|
||||
bh_assert(function->u.func.func_ptr != NULL);
|
||||
|
||||
bh_assert(func_ptr != NULL);
|
||||
/* set thread handle and stack boundary */
|
||||
wasm_exec_env_set_thread_info(exec_env);
|
||||
|
||||
@ -1546,8 +1598,8 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
|
||||
func_type, NULL, NULL, argv, argc, argv);
|
||||
ret = invoke_native_internal(exec_env, func_ptr, func_type, NULL, NULL,
|
||||
argv, argc, argv);
|
||||
|
||||
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||
if (aot_copy_exception(module_inst, NULL)) {
|
||||
@ -1939,7 +1991,10 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
|
||||
void *attachment;
|
||||
char buf[96];
|
||||
bool ret = false;
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
bh_list *sub_module_list_node = NULL;
|
||||
const char *sub_inst_name = NULL;
|
||||
#endif
|
||||
bh_assert(func_idx < aot_module->import_func_count);
|
||||
|
||||
import_func = aot_module->import_funcs + func_idx;
|
||||
@ -1963,6 +2018,28 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
|
||||
}
|
||||
else if (!import_func->call_conv_raw) {
|
||||
signature = import_func->signature;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
sub_module_list_node =
|
||||
((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list;
|
||||
sub_module_list_node = bh_list_first_elem(sub_module_list_node);
|
||||
while (sub_module_list_node) {
|
||||
sub_inst_name =
|
||||
((AOTSubModInstNode *)sub_module_list_node)->module_name;
|
||||
if (strcmp(sub_inst_name, import_func->module_name) == 0) {
|
||||
exec_env = wasm_runtime_get_exec_env_singleton(
|
||||
(WASMModuleInstanceCommon *)((AOTSubModInstNode *)
|
||||
sub_module_list_node)
|
||||
->module_inst);
|
||||
break;
|
||||
}
|
||||
sub_module_list_node = bh_list_elem_next(sub_module_list_node);
|
||||
}
|
||||
if (exec_env == NULL) {
|
||||
wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst,
|
||||
"create singleton exec_env failed");
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
ret =
|
||||
wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature,
|
||||
attachment, argv, argc, argv);
|
||||
|
||||
@ -90,6 +90,10 @@ typedef struct AOTFunctionInstance {
|
||||
typedef struct AOTModuleInstanceExtra {
|
||||
DefPointer(const uint32 *, stack_sizes);
|
||||
WASMModuleInstanceExtraCommon common;
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
bh_list sub_module_inst_list_head;
|
||||
bh_list *sub_module_inst_list;
|
||||
#endif
|
||||
} AOTModuleInstanceExtra;
|
||||
|
||||
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||
@ -229,6 +233,12 @@ typedef struct AOTModule {
|
||||
WASIArguments wasi_args;
|
||||
bool import_wasi_api;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
/* TODO: add mutex for mutli-thread? */
|
||||
bh_list import_module_list_head;
|
||||
bh_list *import_module_list;
|
||||
#endif
|
||||
#if WASM_ENABLE_DEBUG_AOT != 0
|
||||
void *elf_hdr;
|
||||
uint32 elf_size;
|
||||
@ -247,6 +257,10 @@ typedef struct AOTModule {
|
||||
#define AOTTableInstance WASMTableInstance
|
||||
#define AOTModuleInstance WASMModuleInstance
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
#define AOTSubModInstNode WASMSubModInstNode
|
||||
#endif
|
||||
|
||||
/* Target info, read from ELF header of object file */
|
||||
typedef struct AOTTargetInfo {
|
||||
/* Binary type, elf32l/elf32b/elf64l/elf64b */
|
||||
|
||||
Reference in New Issue
Block a user