From 676c3c7b04aa96a8fc98c372455f2b52af0ceda2 Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Tue, 27 Dec 2022 12:59:17 +0800 Subject: [PATCH] Fix failure about preopen of reactor modules (#1816) Support modes: - run a commander module only - run a reactor module only - run a commander module and a/multiple reactor modules together commander propagates WASIArguments to reactors --- core/iwasm/common/wasm_c_api.c | 7 +++ core/iwasm/common/wasm_runtime_common.c | 38 ++++++++----- core/iwasm/interpreter/wasm_loader.c | 60 +++++++++++++++----- core/iwasm/interpreter/wasm_runtime.c | 74 +++++++++++++++++-------- core/iwasm/interpreter/wasm_runtime.h | 5 ++ 5 files changed, 132 insertions(+), 52 deletions(-) diff --git a/core/iwasm/common/wasm_c_api.c b/core/iwasm/common/wasm_c_api.c index ae4ceaf9..1f148ee5 100644 --- a/core/iwasm/common/wasm_c_api.c +++ b/core/iwasm/common/wasm_c_api.c @@ -1628,6 +1628,8 @@ wasm_val_to_rt_val(WASMModuleInstanceCommon *inst_comm_rt, uint8 val_type_rt, ret = wasm_externref_obj2ref(inst_comm_rt, v->of.ref, (uint32 *)data); break; +#else + (void)inst_comm_rt; #endif default: LOG_WARNING("unexpected value type %d", val_type_rt); @@ -1907,6 +1909,9 @@ wasm_trap_new_internal(wasm_store_t *store, frame_instance; } } +#else + (void)store; + (void)inst_comm_rt; #endif /* WASM_ENABLE_DUMP_CALL_STACK != 0 */ return trap; @@ -2034,6 +2039,7 @@ wasm_foreign_new_internal(wasm_store_t *store, uint32 foreign_idx_rt, } foreign->ref_cnt++; + (void)inst_comm_rt; return foreign; } @@ -4291,6 +4297,7 @@ interp_link_func(const wasm_instance_t *inst, const WASMModule *module_interp, imported_func_interp->u.function.func_ptr_linked = import->u.cb; import->func_idx_rt = func_idx_rt; + (void)inst; return true; } diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index fab9b59f..88dd1c19 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -2359,19 +2359,27 @@ wasm_runtime_set_wasi_args_ex(WASMModuleCommon *module, const char *dir_list[], { WASIArguments *wasi_args = get_wasi_args_from_module(module); - if (wasi_args) { - wasi_args->dir_list = dir_list; - wasi_args->dir_count = dir_count; - wasi_args->map_dir_list = map_dir_list; - wasi_args->map_dir_count = map_dir_count; - wasi_args->env = env_list; - wasi_args->env_count = env_count; - wasi_args->argv = argv; - wasi_args->argc = (uint32)argc; - wasi_args->stdio[0] = stdinfd; - wasi_args->stdio[1] = stdoutfd; - wasi_args->stdio[2] = stderrfd; + bh_assert(wasi_args); + + wasi_args->dir_list = dir_list; + wasi_args->dir_count = dir_count; + wasi_args->map_dir_list = map_dir_list; + wasi_args->map_dir_count = map_dir_count; + wasi_args->env = env_list; + wasi_args->env_count = env_count; + wasi_args->argv = argv; + wasi_args->argc = (uint32)argc; + wasi_args->stdio[0] = stdinfd; + wasi_args->stdio[1] = stdoutfd; + wasi_args->stdio[2] = stderrfd; + +#if WASM_ENABLE_MULTI_MODULE != 0 +#if WASM_ENABLE_INTERP != 0 + if (module->module_type == Wasm_Module_Bytecode) { + wasm_propagate_wasi_args((WASMModule *)module); } +#endif +#endif } void @@ -2488,7 +2496,8 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst, wasm_runtime_set_wasi_ctx(module_inst, wasi_ctx); - /* process argv[0], trip the path and suffix, only keep the program name */ + /* process argv[0], trip the path and suffix, only keep the program name + */ if (!copy_string_array((const char **)argv, argc, &argv_buf, &argv_list, &argv_buf_size)) { set_error_buf(error_buf, error_buf_size, @@ -3188,7 +3197,8 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr, uint32 *argv_ret) { WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env); - /* argv buf layout: int args(fix cnt) + float args(fix cnt) + stack args */ + /* argv buf layout: int args(fix cnt) + float args(fix cnt) + stack args + */ uint32 argv_buf[32], *argv1 = argv_buf, *ints, *stacks, size; uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0; uint32 arg_i32, ptr_len; diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index ef7df8e0..6a39d368 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -684,7 +684,7 @@ adjust_table_max_size(uint32 init_size, uint32 max_size_flag, uint32 *max_size) } } -#if WASM_ENABLE_MULTI_MODULE != 0 +#if WASM_ENABLE_LIBC_WASI != 0 || WASM_ENABLE_MULTI_MODULE != 0 /** * Find export item of a module with export info: * module name, field name and export kind @@ -718,11 +718,15 @@ wasm_loader_find_export(const WASMModule *module, const char *module_name, return NULL; } + (void)module_name; + /* since there is a validation in load_export_section(), it is for sure * export->index is valid*/ return export; } +#endif +#if WASM_ENABLE_MULTI_MODULE != 0 static WASMFunction * wasm_loader_resolve_function(const char *module_name, const char *function_name, const WASMType *expected_function_type, @@ -1240,6 +1244,8 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end, table->init_size = declare_init_size; table->flags = declare_max_size_flag; table->max_size = declare_max_size; + + (void)parent_module; return true; fail: return false; @@ -1373,6 +1379,8 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end, memory->num_bytes_per_page = DEFAULT_NUM_BYTES_PER_PAGE; *p_buf = p; + + (void)parent_module; return true; fail: return false; @@ -1439,6 +1447,8 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end, global->field_name = global_name; global->type = declare_type; global->is_mutable = (declare_mutable == 1); + + (void)parent_module; return true; fail: return false; @@ -2381,6 +2391,7 @@ load_func_index_vec(const uint8 **p_buf, const uint8 *buf_end, } #else read_leb_uint32(p, p_end, function_index); + (void)use_init_expr; #endif /* since we are using -1 to indicate ref.null */ @@ -2690,6 +2701,7 @@ load_code_section(const uint8 *buf, const uint8 *buf_end, const uint8 *buf_func, } LOG_VERBOSE("Load code segment section success.\n"); + (void)module; return true; fail: return false; @@ -2900,6 +2912,8 @@ load_user_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module, LOG_VERBOSE("Ignore custom section [%s].", section_name); + (void)is_load_from_file_buf; + (void)module; return true; fail: return false; @@ -4054,24 +4068,19 @@ fail: return false; } -#if (WASM_ENABLE_MULTI_MODULE != 0) && (WASM_ENABLE_LIBC_WASI != 0) +#if WASM_ENABLE_LIBC_WASI != 0 /** * refer to * https://github.com/WebAssembly/WASI/blob/main/design/application-abi.md */ static bool -check_wasi_abi_compatibility(const WASMModule *module, bool main_module, +check_wasi_abi_compatibility(const WASMModule *module, +#if WASM_ENABLE_MULTI_MODULE != 0 + bool main_module, +#endif char *error_buf, uint32 error_buf_size) { /** - * need to handle: - * - non-wasi compatiable modules - * - a fake wasi compatiable module - * - a command acts as a main_module - * - a command acts as a sub_module - * - a reactor acts as a main_module - * - a reactor acts as a sub_module - * * be careful with: * wasi compatiable modules(command/reactor) which don't import any wasi * APIs. Usually, a command has to import a "prox_exit" at least, but a @@ -4087,8 +4096,20 @@ check_wasi_abi_compatibility(const WASMModule *module, bool main_module, * - no one will define either `_start` or `_initialize` on purpose * - `_start` should always be `void _start(void)` * - `_initialize` should always be `void _initialize(void)` + * */ + /* clang-format off */ + /** + * + * | | import_wasi_api True | | import_wasi_api False | | + * | ----------- | -------------------- | ---------------- | --------------------- | ---------------- | + * | | \_initialize() Y | \_initialize() N | \_initialize() Y | \_initialize() N | + * | \_start() Y | N | COMMANDER | N | COMMANDER | + * | \_start() N | REACTOR | N | REACTOR | OTHERS | + */ + /* clang-format on */ + WASMExport *initialize = NULL, *memory = NULL, *start = NULL; /* (func (export "_start") (...) */ @@ -4147,6 +4168,7 @@ check_wasi_abi_compatibility(const WASMModule *module, bool main_module, return false; } +#if WASM_ENABLE_MULTI_MODULE != 0 /* filter out commands (with `_start`) cases */ if (start && !main_module) { set_error_buf( @@ -4154,6 +4176,7 @@ check_wasi_abi_compatibility(const WASMModule *module, bool main_module, "a command (with _start function) can not be a sub-module"); return false; } +#endif /* * it is ok a reactor acts as a main module, @@ -4193,10 +4216,13 @@ wasm_loader_load(uint8 *buf, uint32 size, goto fail; } -#if (WASM_ENABLE_MULTI_MODULE != 0) && (WASM_ENABLE_LIBC_WASI != 0) +#if WASM_ENABLE_LIBC_WASI != 0 /* Check the WASI application ABI */ - if (!check_wasi_abi_compatibility(module, main_module, error_buf, - error_buf_size)) { + if (!check_wasi_abi_compatibility(module, +#if WASM_ENABLE_MULTI_MODULE != 0 + main_module, +#endif + error_buf, error_buf_size)) { goto fail; } #endif @@ -4971,6 +4997,7 @@ wasm_loader_find_block_addr(WASMExecEnv *exec_env, BlockAddr *block_addr_cache, } (void)u8; + (void)exec_env; return false; fail: return false; @@ -5834,6 +5861,8 @@ preserve_referenced_local(WASMLoaderContext *loader_ctx, uint8 opcode, i += 2; } + (void)error_buf; + (void)error_buf_size; return true; #if WASM_ENABLE_LABELS_AS_VALUES != 0 #if WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 @@ -6098,6 +6127,9 @@ wasm_loader_pop_frame_offset(WASMLoaderContext *ctx, uint8 type, ctx->dynamic_offset -= 2; } emit_operand(ctx, *(ctx->frame_offset)); + + (void)error_buf; + (void)error_buf_size; return true; } diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 438dd59c..fd85b71b 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -983,6 +983,18 @@ export_globals_instantiate(const WASMModule *module, } #endif +#if WASM_ENABLE_LIBC_WASI != 0 +static bool +execute_initialize_function(WASMModuleInstance *module_inst) +{ + WASMFunctionInstance *initialize = + wasm_lookup_function(module_inst, "_initialize", NULL); + return !initialize + || wasm_create_exec_env_and_call_function(module_inst, initialize, 0, + NULL); +} +#endif + static bool execute_post_inst_function(WASMModuleInstance *module_inst) { @@ -1175,28 +1187,6 @@ sub_module_instantiate(WASMModule *module, WASMModuleInstance *module_inst, sub_module_list_node = bh_list_elem_next(sub_module_list_node); -#if WASM_ENABLE_LIBC_WASI != 0 - { - /* - * reactor instances may assume that _initialize will be called by - * the environment at most once, and that none of their other - * exports are accessed before that call. - * - * let the loader decide how to act if there is no _initialize - * in a reactor - */ - WASMFunctionInstance *initialize = - wasm_lookup_function(sub_module_inst, "_initialize", NULL); - if (initialize - && !wasm_create_exec_env_and_call_function( - sub_module_inst, initialize, 0, NULL)) { - set_error_buf(error_buf, error_buf_size, - "Call _initialize failed "); - goto failed; - } - } -#endif - continue; failed: if (sub_module_inst_list_node) { @@ -1844,8 +1834,21 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size, &module_inst->e->functions[module->start_function]; } - /* Execute __post_instantiate function */ - if (!execute_post_inst_function(module_inst) + if ( +#if WASM_ENABLE_LIBC_WASI != 0 + /* + * reactor instances may assume that _initialize will be called by + * the environment at most once, and that none of their other + * exports are accessed before that call. + * + * let the loader decide how to act if there is no _initialize + * in a reactor + */ + !execute_initialize_function(module_inst) || +#endif + /* Execute __post_instantiate function */ + !execute_post_inst_function(module_inst) + /* Execute the function in "start" section */ || !execute_start_function(module_inst)) { set_error_buf(error_buf, error_buf_size, module_inst->cur_exception); goto fail; @@ -3231,3 +3234,26 @@ llvm_jit_free_frame(WASMExecEnv *exec_env) || WASM_ENABLE_PERF_PROFILING != 0 */ #endif /* end of WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 */ + +#if WASM_ENABLE_LIBC_WASI != 0 && WASM_ENABLE_MULTI_MODULE != 0 +void +wasm_propagate_wasi_args(WASMModule *module) +{ + if (!module->import_count) + return; + + bh_assert(&module->import_module_list_head); + + WASMRegisteredModule *node = + bh_list_first_elem(&module->import_module_list_head); + while (node) { + WASIArguments *wasi_args_impt_mod = + &((WASMModule *)(node->module))->wasi_args; + bh_assert(wasi_args_impt_mod); + + bh_memcpy_s(wasi_args_impt_mod, sizeof(WASIArguments), + &module->wasi_args, sizeof(WASIArguments)); + node = bh_list_elem_next(node); + } +} +#endif diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 6d1a5340..5bf09bb8 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -626,6 +626,11 @@ llvm_jit_free_frame(WASMExecEnv *exec_env); #endif #endif /* end of WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0 */ +#if WASM_ENABLE_LIBC_WASI != 0 && WASM_ENABLE_MULTI_MODULE != 0 +void +wasm_propagate_wasi_args(WASMModule *module); +#endif + #ifdef __cplusplus } #endif