mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-13 13:11:25 +00:00
Handle a return from wasi _start function correctly (#2529)
This fixes a few test cases in wasi-threads testsuite like wasi_threads_return_main_block. And also move the special handling for "wasi proc exit" to a more appropriate place.
This commit is contained in:
parent
6c846acc59
commit
534a8cf9f4
|
@ -107,7 +107,34 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
|
||||||
the actual main function. Directly calling main function
|
the actual main function. Directly calling main function
|
||||||
may cause exception thrown. */
|
may cause exception thrown. */
|
||||||
if ((func = wasm_runtime_lookup_wasi_start_function(module_inst))) {
|
if ((func = wasm_runtime_lookup_wasi_start_function(module_inst))) {
|
||||||
return wasm_runtime_call_wasm(exec_env, func, 0, NULL);
|
const char *wasi_proc_exit_exception = "wasi proc exit";
|
||||||
|
|
||||||
|
ret = wasm_runtime_call_wasm(exec_env, func, 0, NULL);
|
||||||
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
if (ret) {
|
||||||
|
/* On a successful return from the `_start` function,
|
||||||
|
we terminate other threads by mimicing wasi:proc_exit(0).
|
||||||
|
|
||||||
|
Note:
|
||||||
|
- A return from the `main` function is an equivalent of
|
||||||
|
exit(). (C standard)
|
||||||
|
- When exit code is 0, wasi-libc's `_start` function just
|
||||||
|
returns w/o calling `proc_exit`.
|
||||||
|
- A process termination should terminate threads in
|
||||||
|
the process. */
|
||||||
|
|
||||||
|
wasm_runtime_set_exception(module_inst, wasi_proc_exit_exception);
|
||||||
|
/* exit_code is zero-initialized */
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* report wasm proc exit as a success */
|
||||||
|
WASMModuleInstance *inst = (WASMModuleInstance *)module_inst;
|
||||||
|
if (!ret && strstr(inst->cur_exception, wasi_proc_exit_exception)) {
|
||||||
|
inst->cur_exception[0] = 0;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* end of WASM_ENABLE_LIBC_WASI */
|
#endif /* end of WASM_ENABLE_LIBC_WASI */
|
||||||
|
|
||||||
|
|
|
@ -1938,33 +1938,6 @@ wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool
|
|
||||||
clear_wasi_proc_exit_exception(WASMModuleInstanceCommon *module_inst_comm)
|
|
||||||
{
|
|
||||||
#if WASM_ENABLE_LIBC_WASI != 0
|
|
||||||
bool has_exception;
|
|
||||||
char exception[EXCEPTION_BUF_LEN];
|
|
||||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
|
||||||
|
|
||||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
|
||||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
|
||||||
|
|
||||||
has_exception = wasm_copy_exception(module_inst, exception);
|
|
||||||
if (has_exception && !strcmp(exception, "Exception: wasi proc exit")) {
|
|
||||||
/* The "wasi proc exit" exception is thrown by native lib to
|
|
||||||
let wasm app exit, which is a normal behavior, we clear
|
|
||||||
the exception here. And just clear the exception of current
|
|
||||||
thread, don't call `wasm_set_exception(module_inst, NULL)`
|
|
||||||
which will clear the exception of all threads. */
|
|
||||||
module_inst->cur_exception[0] = '\0';
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_runtime_call_wasm(WASMExecEnv *exec_env,
|
wasm_runtime_call_wasm(WASMExecEnv *exec_env,
|
||||||
WASMFunctionInstanceCommon *function, uint32 argc,
|
WASMFunctionInstanceCommon *function, uint32 argc,
|
||||||
|
@ -2005,16 +1978,11 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
|
||||||
param_argc, new_argv);
|
param_argc, new_argv);
|
||||||
#endif
|
#endif
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
if (clear_wasi_proc_exit_exception(exec_env->module_inst)) {
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (new_argv != argv) {
|
if (new_argv != argv) {
|
||||||
wasm_runtime_free(new_argv);
|
wasm_runtime_free(new_argv);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#if WASM_ENABLE_REF_TYPES != 0
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
if (!wasm_runtime_finalize_call_function(exec_env, function, new_argv,
|
if (!wasm_runtime_finalize_call_function(exec_env, function, new_argv,
|
||||||
|
@ -4573,10 +4541,6 @@ wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32 element_index,
|
||||||
ret = aot_call_indirect(exec_env, 0, element_index, argc, argv);
|
ret = aot_call_indirect(exec_env, 0, element_index, argc, argv);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!ret && clear_wasi_proc_exit_exception(exec_env->module_inst)) {
|
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user