mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-03-12 08:55:28 +00:00
Allow finer control of start function on instantiation
Tries to address https://github.com/bytecodealliance/wasm-micro-runtime/issues/4047. Before this change, wasm_runtime_instantiate would execute the start function unconditionally, correctly implementing the spec. However, if there is an infinite loop in the start function, there was no way to interrupt execution. This change introduces a parameter to InstantiationArgs indicating whether the start function should be immediately invoked. If not, wasm_runtime_instantiate returns a module instance that is initialized except for the start function. This change adds a wasm_runtime_instantiate_run_start_func function which performs this last instantiation step. The user may prepare a timeout in advance of calling this to guard against expensive/infinite loops. This change also demonstrates a possible technique for doing this in iwasm.c.
This commit is contained in:
parent
7b724e2382
commit
b8e57c6ec3
|
@ -1622,13 +1622,24 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module,
|
|||
WASMModuleInstanceCommon *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, uint32 max_memory_pages,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
bool run_start_function, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode)
|
||||
return (WASMModuleInstanceCommon *)wasm_instantiate(
|
||||
(WASMModule *)module, (WASMModuleInstance *)parent, exec_env_main,
|
||||
stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
|
||||
if (module->module_type == Wasm_Module_Bytecode) {
|
||||
if (run_start_function) {
|
||||
return (WASMModuleInstanceCommon *)wasm_instantiate(
|
||||
(WASMModule *)module, (WASMModuleInstance *)parent,
|
||||
exec_env_main, stack_size, heap_size, max_memory_pages,
|
||||
error_buf, error_buf_size);
|
||||
}
|
||||
|
||||
return (WASMModuleInstanceCommon *)
|
||||
wasm_instantiate_without_start_function(
|
||||
(WASMModule *)module, (WASMModuleInstance *)parent,
|
||||
exec_env_main, stack_size, heap_size, max_memory_pages,
|
||||
error_buf, error_buf_size);
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
|
@ -1647,7 +1658,7 @@ wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
|
|||
uint32 error_buf_size)
|
||||
{
|
||||
return wasm_runtime_instantiate_internal(module, NULL, NULL, stack_size,
|
||||
heap_size, 0, error_buf,
|
||||
heap_size, 0, true, error_buf,
|
||||
error_buf_size);
|
||||
}
|
||||
|
||||
|
@ -1658,8 +1669,8 @@ wasm_runtime_instantiate_ex(WASMModuleCommon *module,
|
|||
{
|
||||
return wasm_runtime_instantiate_internal(
|
||||
module, NULL, NULL, args->default_stack_size,
|
||||
args->host_managed_heap_size, args->max_memory_pages, error_buf,
|
||||
error_buf_size);
|
||||
args->host_managed_heap_size, args->max_memory_pages,
|
||||
args->run_start_function, error_buf, error_buf_size);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -7562,7 +7573,7 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
|
|||
WASMModuleInstanceCommon *sub_module_inst = NULL;
|
||||
sub_module_inst = wasm_runtime_instantiate_internal(
|
||||
sub_module, NULL, NULL, stack_size, heap_size, max_memory_pages,
|
||||
error_buf, error_buf_size);
|
||||
true, error_buf, error_buf_size);
|
||||
if (!sub_module_inst) {
|
||||
LOG_DEBUG("instantiate %s failed",
|
||||
sub_module_list_node->module_name);
|
||||
|
|
|
@ -575,7 +575,8 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module,
|
|||
WASMModuleInstanceCommon *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, uint32 max_memory_pages,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
bool run_start_function, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
|
||||
/* Internal API */
|
||||
void
|
||||
|
|
|
@ -273,6 +273,8 @@ typedef struct InstantiationArgs {
|
|||
uint32_t default_stack_size;
|
||||
uint32_t host_managed_heap_size;
|
||||
uint32_t max_memory_pages;
|
||||
|
||||
bool run_start_function;
|
||||
} InstantiationArgs;
|
||||
#endif /* INSTANTIATION_ARGS_OPTION_DEFINED */
|
||||
|
||||
|
@ -719,6 +721,17 @@ wasm_runtime_instantiate_ex(const wasm_module_t module,
|
|||
const InstantiationArgs *args, char *error_buf,
|
||||
uint32_t error_buf_size);
|
||||
|
||||
/**
|
||||
* Run the start function of an otherwise instantiated module. See
|
||||
* InstantiationArgs.run_start_function.
|
||||
*/
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_instantiate_run_start_func(wasm_module_inst_t module,
|
||||
wasm_module_inst_t parent,
|
||||
wasm_exec_env_t exec_env,
|
||||
char *error_buf,
|
||||
uint32_t error_buf_size);
|
||||
|
||||
/**
|
||||
* Set the running mode of a WASM module instance, override the
|
||||
* default running mode of the runtime. Note that it only makes sense when
|
||||
|
|
|
@ -2333,6 +2333,25 @@ wasm_set_running_mode(WASMModuleInstance *module_inst, RunningMode running_mode)
|
|||
return set_running_mode(module_inst, running_mode, false);
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_instantiate_run_start_func(wasm_module_inst_t module_inst,
|
||||
wasm_module_inst_t parent,
|
||||
wasm_exec_env_t exec_env,
|
||||
char *error_buf,
|
||||
uint32_t error_buf_size)
|
||||
{
|
||||
const bool is_sub_inst = parent != NULL;
|
||||
if (!execute_post_instantiate_functions((WASMModuleInstance *)module_inst,
|
||||
is_sub_inst, exec_env)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
((WASMModuleInstance *)module_inst)->cur_exception);
|
||||
wasm_runtime_deinstantiate(module_inst);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate module
|
||||
*/
|
||||
|
@ -2341,6 +2360,41 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
|||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, uint32 max_memory_pages, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMModuleInstance *module_inst = wasm_instantiate_without_start_function(
|
||||
module, parent, exec_env_main, stack_size, heap_size, max_memory_pages,
|
||||
error_buf, error_buf_size);
|
||||
|
||||
if (!module_inst) {
|
||||
// wasm_instantiate_without_start_function will deinstantiate on
|
||||
// failure.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!wasm_runtime_instantiate_run_start_func(
|
||||
(WASMModuleInstanceCommon *)module_inst,
|
||||
(WASMModuleInstanceCommon *)parent, exec_env_main, error_buf,
|
||||
error_buf_size)) {
|
||||
// run_start_func will deinstantiate on failure.
|
||||
set_error_buf(error_buf, error_buf_size, module_inst->cur_exception);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MEMORY_TRACING != 0
|
||||
wasm_runtime_dump_module_inst_mem_consumption(
|
||||
(WASMModuleInstanceCommon *)module_inst);
|
||||
#endif
|
||||
|
||||
return module_inst;
|
||||
}
|
||||
|
||||
WASMModuleInstance *
|
||||
wasm_instantiate_without_start_function(WASMModule *module,
|
||||
WASMModuleInstance *parent,
|
||||
WASMExecEnv *exec_env_main,
|
||||
uint32 stack_size, uint32 heap_size,
|
||||
uint32 max_memory_pages,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMModuleInstance *module_inst;
|
||||
WASMGlobalInstance *globals = NULL, *global;
|
||||
|
@ -3257,17 +3311,6 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
|||
&module_inst->e->functions[module->start_function];
|
||||
}
|
||||
|
||||
if (!execute_post_instantiate_functions(module_inst, is_sub_inst,
|
||||
exec_env_main)) {
|
||||
set_error_buf(error_buf, error_buf_size, module_inst->cur_exception);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MEMORY_TRACING != 0
|
||||
wasm_runtime_dump_module_inst_mem_consumption(
|
||||
(WASMModuleInstanceCommon *)module_inst);
|
||||
#endif
|
||||
|
||||
(void)global_data_end;
|
||||
return module_inst;
|
||||
|
||||
|
|
|
@ -543,6 +543,14 @@ bool
|
|||
wasm_resolve_import_func(const WASMModule *module,
|
||||
WASMFunctionImport *function);
|
||||
|
||||
WASMModuleInstance *
|
||||
wasm_instantiate_without_start_function(WASMModule *module,
|
||||
WASMModuleInstance *parent,
|
||||
WASMExecEnv *exec_env_main,
|
||||
uint32 stack_size, uint32 heap_size,
|
||||
uint32 max_memory_pages,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
|
||||
WASMModuleInstance *
|
||||
wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
|
|
|
@ -580,7 +580,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
|
|||
#endif
|
||||
|
||||
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
||||
module, module_inst, exec_env, stack_size, 0, 0, NULL, 0)))
|
||||
module, module_inst, exec_env, stack_size, 0, 0, true, NULL, 0)))
|
||||
return -1;
|
||||
|
||||
/* Set custom_data to new module instance */
|
||||
|
|
|
@ -87,7 +87,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
|
|||
stack_size = ((WASMModuleInstance *)module_inst)->default_wasm_stack_size;
|
||||
|
||||
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
||||
module, module_inst, exec_env, stack_size, 0, 0, NULL, 0)))
|
||||
module, module_inst, exec_env, stack_size, 0, 0, true, NULL, 0)))
|
||||
return -1;
|
||||
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
|
|
|
@ -506,7 +506,8 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
|||
}
|
||||
|
||||
if (!(new_module_inst = wasm_runtime_instantiate_internal(
|
||||
module, module_inst, exec_env, stack_size, 0, 0, NULL, 0))) {
|
||||
module, module_inst, exec_env, stack_size, 0, 0, true, NULL,
|
||||
0))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -945,10 +945,38 @@ main(int argc, char *argv[])
|
|||
libc_wasi_init(wasm_module, argc, argv, &wasi_parse_ctx);
|
||||
#endif
|
||||
|
||||
InstantiationArgs args = {
|
||||
.default_stack_size = stack_size,
|
||||
.host_managed_heap_size = heap_size,
|
||||
.max_memory_pages = 0,
|
||||
.run_start_function = false,
|
||||
};
|
||||
|
||||
/* instantiate the module */
|
||||
if (!(wasm_module_inst =
|
||||
wasm_runtime_instantiate(wasm_module, stack_size, heap_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
if (!(wasm_module_inst = wasm_runtime_instantiate_ex(
|
||||
wasm_module, &args, error_buf, sizeof(error_buf)))) {
|
||||
printf("%s\n", error_buf);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
struct timeout_arg timeout_arg;
|
||||
korp_tid timeout_tid;
|
||||
if (timeout_ms >= 0) {
|
||||
timeout_arg.timeout_ms = timeout_ms;
|
||||
timeout_arg.inst = wasm_module_inst;
|
||||
timeout_arg.cancel = false;
|
||||
ret = os_thread_create(&timeout_tid, timeout_thread, &timeout_arg,
|
||||
APP_THREAD_STACK_SIZE_DEFAULT);
|
||||
if (ret != 0) {
|
||||
printf("Failed to start timeout\n");
|
||||
goto fail4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!wasm_runtime_instantiate_run_start_func(
|
||||
wasm_module_inst, NULL, NULL, error_buf, sizeof(error_buf))) {
|
||||
printf("%s\n", error_buf);
|
||||
goto fail3;
|
||||
}
|
||||
|
@ -966,27 +994,11 @@ main(int argc, char *argv[])
|
|||
uint32_t debug_port;
|
||||
if (exec_env == NULL) {
|
||||
printf("%s\n", wasm_runtime_get_exception(wasm_module_inst));
|
||||
goto fail4;
|
||||
goto fail5;
|
||||
}
|
||||
debug_port = wasm_runtime_start_debug_instance(exec_env);
|
||||
if (debug_port == 0) {
|
||||
printf("Failed to start debug instance\n");
|
||||
goto fail4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
struct timeout_arg timeout_arg;
|
||||
korp_tid timeout_tid;
|
||||
if (timeout_ms >= 0) {
|
||||
timeout_arg.timeout_ms = timeout_ms;
|
||||
timeout_arg.inst = wasm_module_inst;
|
||||
timeout_arg.cancel = false;
|
||||
ret = os_thread_create(&timeout_tid, timeout_thread, &timeout_arg,
|
||||
APP_THREAD_STACK_SIZE_DEFAULT);
|
||||
if (ret != 0) {
|
||||
printf("Failed to start timeout\n");
|
||||
goto fail5;
|
||||
}
|
||||
}
|
||||
|
@ -1035,10 +1047,10 @@ main(int argc, char *argv[])
|
|||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
fail5:
|
||||
#endif
|
||||
#if WASM_ENABLE_DEBUG_INTERP != 0
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
fail4:
|
||||
#endif
|
||||
/* destroy the module instance */
|
||||
|
|
Loading…
Reference in New Issue
Block a user