Add wasm_runtime_get_wasi_exit_code (#1748)

Refer to https://github.com/bytecodealliance/wasm-micro-runtime/issues/1738
This commit is contained in:
YAMAMOTO Takashi 2022-11-24 21:26:18 +09:00 committed by GitHub
parent 8dc9d6dc4f
commit 1032aac60b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 103 additions and 28 deletions

View File

@ -2675,17 +2675,18 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
char *argv[], uint32 argc, int stdinfd, int stdoutfd,
int stderrfd, char *error_buf, uint32 error_buf_size)
{
uvwasi_t *uvwasi = NULL;
WASIContext *ctx;
uvwasi_t *uvwasi;
uvwasi_options_t init_options;
const char **envp = NULL;
uint64 total_size;
uint32 i;
bool ret = false;
uvwasi = runtime_malloc(sizeof(uvwasi_t), module_inst, error_buf,
error_buf_size);
if (!uvwasi)
ctx = runtime_malloc(sizeof(*ctx), module_inst, error_buf, error_buf_size);
if (!ctx)
return false;
uvwasi = &ctx->uvwasi;
/* Setup the initialization options */
uvwasi_options_init(&init_options);
@ -2733,7 +2734,7 @@ wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
goto fail;
}
wasm_runtime_set_wasi_ctx(module_inst, uvwasi);
wasm_runtime_set_wasi_ctx(module_inst, ctx);
ret = true;
@ -2863,12 +2864,19 @@ wasm_runtime_destroy_wasi(WASMModuleInstanceCommon *module_inst)
WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
if (wasi_ctx) {
uvwasi_destroy(wasi_ctx);
uvwasi_destroy(&wasi_ctx->uvwasi);
wasm_runtime_free(wasi_ctx);
}
}
#endif
uint32_t
wasm_runtime_get_wasi_exit_code(WASMModuleInstanceCommon *module_inst)
{
WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
return wasi_ctx->exit_code;
}
WASIContext *
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm)
{

View File

@ -369,9 +369,13 @@ typedef struct WASIContext {
char **argv_list;
char *env_buf;
char **env_list;
uint32_t exit_code;
} WASIContext;
#else
typedef uvwasi_t WASIContext;
typedef struct WASIContext {
uvwasi_t uvwasi;
uint32_t exit_code;
} WASIContext;
#endif
#endif
@ -768,6 +772,10 @@ wasm_runtime_is_wasi_mode(WASMModuleInstanceCommon *module_inst);
WASM_RUNTIME_API_EXTERN WASMFunctionInstanceCommon *
wasm_runtime_lookup_wasi_start_function(WASMModuleInstanceCommon *module_inst);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN uint32_t
wasm_runtime_get_wasi_exit_code(WASMModuleInstanceCommon *module_inst);
bool
wasm_runtime_init_wasi(WASMModuleInstanceCommon *module_inst,
const char *dir_list[], uint32 dir_count,

View File

@ -450,6 +450,18 @@ wasm_runtime_is_wasi_mode(wasm_module_inst_t module_inst);
WASM_RUNTIME_API_EXTERN wasm_function_inst_t
wasm_runtime_lookup_wasi_start_function(wasm_module_inst_t module_inst);
/**
* Get WASI exit code.
*
* After a WASI command completed its execution, an embedder can
* call this function to get its exit code. (that is, the value given
* to proc_exit.)
*
* @param module_inst the module instance
*/
WASM_RUNTIME_API_EXTERN uint32_t
wasm_runtime_get_wasi_exit_code(wasm_module_inst_t module_inst);
/**
* Lookup an exported function in the WASM module instance.
*

View File

@ -11,9 +11,6 @@
#define get_module_inst(exec_env) \
wasm_runtime_get_module_inst(exec_env)
#define get_wasi_ctx(module_inst) \
wasm_runtime_get_wasi_ctx(module_inst)
#define validate_app_addr(offset, size) \
wasm_runtime_validate_app_addr(module_inst, offset, size)
@ -72,9 +69,24 @@ typedef struct iovec_app {
uint32 buf_len;
} iovec_app_t;
typedef struct WASIContext {
uvwasi_t uvwasi;
uint32_t exit_code;
} WASIContext;
void *
wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
static uvwasi_t *
get_wasi_ctx(wasm_module_inst_t module_inst)
{
WASIContext *ctx = wasm_runtime_get_wasi_ctx(module_inst);
if (ctx == NULL) {
return NULL;
}
return &ctx->uvwasi;
}
static wasi_errno_t
wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_buf)
{
@ -924,10 +936,12 @@ static void
wasi_proc_exit(wasm_exec_env_t exec_env, wasi_exitcode_t rval)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
/* Here throwing exception is just to let wasm app exit,
the upper layer should clear the exception and return
as normal */
wasm_runtime_set_exception(module_inst, "wasi proc exit");
wasi_ctx->exit_code = rval;
}
static wasi_errno_t

View File

@ -57,6 +57,7 @@ typedef struct WASIContext {
char **argv_list;
char *env_buf;
char **env_list;
uint32_t exit_code;
} * wasi_ctx_t;
wasi_ctx_t
@ -980,10 +981,12 @@ static void
wasi_proc_exit(wasm_exec_env_t exec_env, wasi_exitcode_t rval)
{
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasi_ctx_t wasi_ctx = get_wasi_ctx(module_inst);
/* Here throwing exception is just to let wasm app exit,
the upper layer should clear the exception and return
as normal */
wasm_runtime_set_exception(module_inst, "wasi proc exit");
wasi_ctx->exit_code = rval;
}
static wasi_errno_t

View File

@ -86,7 +86,7 @@ app_instance_main(wasm_module_inst_t module_inst)
wasm_application_execute_main(module_inst, app_argc, app_argv);
if ((exception = wasm_runtime_get_exception(module_inst)))
printf("%s\n", exception);
return NULL;
return exception;
}
static void *
@ -96,7 +96,7 @@ app_instance_func(wasm_module_inst_t module_inst, const char *func_name)
app_argv + 1);
/* The result of wasm function or exception info was output inside
wasm_application_execute_func(), here we don't output them again. */
return NULL;
return wasm_runtime_get_exception(module_inst);
}
/**
@ -643,14 +643,29 @@ main(int argc, char *argv[])
}
#endif
if (is_repl_mode)
app_instance_repl(wasm_module_inst);
else if (func_name)
app_instance_func(wasm_module_inst, func_name);
else
app_instance_main(wasm_module_inst);
ret = 0;
if (is_repl_mode) {
app_instance_repl(wasm_module_inst);
}
else if (func_name) {
if (app_instance_func(wasm_module_inst, func_name)) {
/* got an exception */
ret = 1;
}
}
else {
if (app_instance_main(wasm_module_inst)) {
/* got an exception */
ret = 1;
}
}
#if WASM_ENABLE_LIBC_WASI != 0
if (ret == 0) {
/* propagate wasi exit code. */
ret = wasm_runtime_get_wasi_exit_code(wasm_module_inst);
}
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
fail4:

View File

@ -63,7 +63,7 @@ app_instance_main(wasm_module_inst_t module_inst)
wasm_application_execute_main(module_inst, app_argc, app_argv);
if ((exception = wasm_runtime_get_exception(module_inst)))
printf("%s\n", exception);
return NULL;
return exception;
}
static void *
@ -73,7 +73,7 @@ app_instance_func(wasm_module_inst_t module_inst, const char *func_name)
app_argv + 1);
/* The result of wasm function or exception info was output inside
wasm_application_execute_func(), here we don't output them again. */
return NULL;
return wasm_runtime_get_exception(module_inst);
}
/**
@ -451,14 +451,29 @@ main(int argc, char *argv[])
}
#endif
if (is_repl_mode)
app_instance_repl(wasm_module_inst);
else if (func_name)
app_instance_func(wasm_module_inst, func_name);
else
app_instance_main(wasm_module_inst);
ret = 0;
if (is_repl_mode) {
app_instance_repl(wasm_module_inst);
}
else if (func_name) {
if (app_instance_func(wasm_module_inst, func_name)) {
/* got an exception */
ret = 1;
}
}
else {
if (app_instance_main(wasm_module_inst)) {
/* got an exception */
ret = 1;
}
}
#if WASM_ENABLE_LIBC_WASI != 0
if (ret == 0) {
/* propagate wasi exit code. */
ret = wasm_runtime_get_wasi_exit_code(wasm_module_inst);
}
#endif
#if WASM_ENABLE_DEBUG_INTERP != 0
fail4: