Merge branch main into dev/wasi-libc-windows
This commit is contained in:
@ -107,7 +107,34 @@ execute_main(WASMModuleInstanceCommon *module_inst, int32 argc, char *argv[])
|
||||
the actual main function. Directly calling main function
|
||||
may cause exception thrown. */
|
||||
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 */
|
||||
|
||||
@ -204,7 +231,7 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
|
||||
char *argv[])
|
||||
{
|
||||
bool ret;
|
||||
#if (WASM_ENABLE_MEMORY_PROFILING != 0) || (WASM_ENABLE_DUMP_CALL_STACK != 0)
|
||||
#if (WASM_ENABLE_MEMORY_PROFILING != 0)
|
||||
WASMExecEnv *exec_env;
|
||||
#endif
|
||||
|
||||
@ -224,14 +251,6 @@ wasm_application_execute_main(WASMModuleInstanceCommon *module_inst, int32 argc,
|
||||
if (ret)
|
||||
ret = wasm_runtime_get_exception(module_inst) == NULL;
|
||||
|
||||
#if WASM_ENABLE_DUMP_CALL_STACK != 0
|
||||
if (!ret) {
|
||||
exec_env = wasm_runtime_get_exec_env_singleton(module_inst);
|
||||
if (exec_env)
|
||||
wasm_runtime_dump_call_stack(exec_env);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
92
core/iwasm/common/wasm_blocking_op.c
Normal file
92
core/iwasm/common/wasm_blocking_op.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "wasm_runtime_common.h"
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "bh_common.h"
|
||||
#include "bh_assert.h"
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
|
||||
|
||||
#define LOCK(env) WASM_SUSPEND_FLAGS_LOCK((env)->wait_lock)
|
||||
#define UNLOCK(env) WASM_SUSPEND_FLAGS_UNLOCK((env)->wait_lock)
|
||||
|
||||
#define ISSET(env, bit) \
|
||||
((WASM_SUSPEND_FLAGS_GET((env)->suspend_flags) & WASM_SUSPEND_FLAG_##bit) \
|
||||
!= 0)
|
||||
#define SET(env, bit) \
|
||||
WASM_SUSPEND_FLAGS_FETCH_OR((env)->suspend_flags, WASM_SUSPEND_FLAG_##bit)
|
||||
#define CLR(env, bit) \
|
||||
WASM_SUSPEND_FLAGS_FETCH_AND((env)->suspend_flags, ~WASM_SUSPEND_FLAG_##bit)
|
||||
|
||||
bool
|
||||
wasm_runtime_begin_blocking_op(wasm_exec_env_t env)
|
||||
{
|
||||
LOCK(env);
|
||||
bh_assert(!ISSET(env, BLOCKING));
|
||||
SET(env, BLOCKING);
|
||||
if (ISSET(env, TERMINATE)) {
|
||||
CLR(env, BLOCKING);
|
||||
UNLOCK(env);
|
||||
return false;
|
||||
}
|
||||
UNLOCK(env);
|
||||
os_begin_blocking_op();
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_end_blocking_op(wasm_exec_env_t env)
|
||||
{
|
||||
int saved_errno = errno;
|
||||
LOCK(env);
|
||||
bh_assert(ISSET(env, BLOCKING));
|
||||
CLR(env, BLOCKING);
|
||||
UNLOCK(env);
|
||||
os_end_blocking_op();
|
||||
errno = saved_errno;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_interrupt_blocking_op(wasm_exec_env_t env)
|
||||
{
|
||||
/*
|
||||
* ISSET(BLOCKING) here means that the target thread
|
||||
* is in somewhere between wasm_begin_blocking_op and
|
||||
* wasm_end_blocking_op.
|
||||
* keep waking it up until it reaches wasm_end_blocking_op,
|
||||
* which clears the BLOCKING bit.
|
||||
*
|
||||
* this dumb loop is necessary because posix doesn't provide
|
||||
* a way to unmask signal and block atomically.
|
||||
*/
|
||||
|
||||
LOCK(env);
|
||||
SET(env, TERMINATE);
|
||||
while (ISSET(env, BLOCKING)) {
|
||||
UNLOCK(env);
|
||||
os_wakeup_blocking_op(env->handle);
|
||||
|
||||
/* relax a bit */
|
||||
os_usleep(50 * 1000);
|
||||
LOCK(env);
|
||||
}
|
||||
UNLOCK(env);
|
||||
}
|
||||
|
||||
#else /* WASM_ENABLE_THREAD_MGR && OS_ENABLE_WAKEUP_BLOCKING_OP */
|
||||
|
||||
bool
|
||||
wasm_runtime_begin_blocking_op(wasm_exec_env_t env)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_end_blocking_op(wasm_exec_env_t env)
|
||||
{}
|
||||
|
||||
#endif /* WASM_ENABLE_THREAD_MGR && OS_ENABLE_WAKEUP_BLOCKING_OP */
|
||||
@ -8,6 +8,7 @@
|
||||
#include "../aot/aot_runtime.h"
|
||||
#include "bh_platform.h"
|
||||
#include "mem_alloc.h"
|
||||
#include "wasm_memory.h"
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
#include "../common/wasm_shared_memory.h"
|
||||
@ -24,6 +25,9 @@ static Memory_Mode memory_mode = MEMORY_MODE_UNKNOWN;
|
||||
|
||||
static mem_allocator_t pool_allocator = NULL;
|
||||
|
||||
static enlarge_memory_error_callback_t enlarge_memory_error_cb;
|
||||
static void *enlarge_memory_error_user_data;
|
||||
|
||||
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
|
||||
static void *allocator_user_data = NULL;
|
||||
static void *(*malloc_func)(void *user_data, unsigned int size) = NULL;
|
||||
@ -570,13 +574,16 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
{
|
||||
WASMMemoryInstance *memory = wasm_get_default_memory(module);
|
||||
uint8 *memory_data_old, *memory_data_new, *heap_data_old;
|
||||
uint32 num_bytes_per_page, heap_size, total_size_old;
|
||||
uint32 num_bytes_per_page, heap_size, total_size_old = 0;
|
||||
uint32 cur_page_count, max_page_count, total_page_count;
|
||||
uint64 total_size_new;
|
||||
bool ret = true;
|
||||
enlarge_memory_error_reason_t failure_reason = INTERNAL_ERROR;
|
||||
|
||||
if (!memory)
|
||||
return false;
|
||||
if (!memory) {
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
heap_data_old = memory->heap_data;
|
||||
heap_size = (uint32)(memory->heap_data_end - memory->heap_data);
|
||||
@ -594,9 +601,15 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
/* No need to enlarge memory */
|
||||
return true;
|
||||
|
||||
if (total_page_count < cur_page_count /* integer overflow */
|
||||
|| total_page_count > max_page_count) {
|
||||
return false;
|
||||
if (total_page_count < cur_page_count) { /* integer overflow */
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
if (total_page_count > max_page_count) {
|
||||
failure_reason = MAX_SIZE_REACHED;
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
bh_assert(total_size_new <= 4 * (uint64)BH_GB);
|
||||
@ -622,14 +635,16 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
if (heap_size > 0) {
|
||||
if (mem_allocator_is_heap_corrupted(memory->heap_handle)) {
|
||||
wasm_runtime_show_app_heap_corrupted_prompt();
|
||||
return false;
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(memory_data_new =
|
||||
wasm_runtime_realloc(memory_data_old, (uint32)total_size_new))) {
|
||||
if (!(memory_data_new = wasm_runtime_malloc((uint32)total_size_new))) {
|
||||
return false;
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
if (memory_data_old) {
|
||||
bh_memcpy_s(memory_data_new, (uint32)total_size_new,
|
||||
@ -685,6 +700,27 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
os_writegsbase(memory_data_new);
|
||||
#endif
|
||||
|
||||
return_func:
|
||||
if (!ret && enlarge_memory_error_cb) {
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode)
|
||||
exec_env =
|
||||
((WASMModuleInstanceExtra *)module->e)->common.cur_exec_env;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
exec_env =
|
||||
((AOTModuleInstanceExtra *)module->e)->common.cur_exec_env;
|
||||
#endif
|
||||
|
||||
enlarge_memory_error_cb(inc_page_count, total_size_old, 0,
|
||||
failure_reason,
|
||||
(WASMModuleInstanceCommon *)module, exec_env,
|
||||
enlarge_memory_error_user_data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
@ -692,12 +728,16 @@ bool
|
||||
wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
{
|
||||
WASMMemoryInstance *memory = wasm_get_default_memory(module);
|
||||
uint32 num_bytes_per_page, total_size_old;
|
||||
uint32 num_bytes_per_page, total_size_old = 0;
|
||||
uint32 cur_page_count, max_page_count, total_page_count;
|
||||
uint64 total_size_new;
|
||||
bool ret = true;
|
||||
enlarge_memory_error_reason_t failure_reason = INTERNAL_ERROR;
|
||||
|
||||
if (!memory)
|
||||
return false;
|
||||
if (!memory) {
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
num_bytes_per_page = memory->num_bytes_per_page;
|
||||
cur_page_count = memory->cur_page_count;
|
||||
@ -710,9 +750,15 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
/* No need to enlarge memory */
|
||||
return true;
|
||||
|
||||
if (total_page_count < cur_page_count /* integer overflow */
|
||||
|| total_page_count > max_page_count) {
|
||||
return false;
|
||||
if (total_page_count < cur_page_count) { /* integer overflow */
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
if (total_page_count > max_page_count) {
|
||||
failure_reason = MAX_SIZE_REACHED;
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
bh_assert(total_size_new <= 4 * (uint64)BH_GB);
|
||||
@ -727,7 +773,8 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
if (!os_mem_commit(memory->memory_data_end,
|
||||
(uint32)total_size_new - total_size_old,
|
||||
MMAP_PROT_READ | MMAP_PROT_WRITE)) {
|
||||
return false;
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -739,7 +786,8 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
os_mem_decommit(memory->memory_data_end,
|
||||
(uint32)total_size_new - total_size_old);
|
||||
#endif
|
||||
return false;
|
||||
ret = false;
|
||||
goto return_func;
|
||||
}
|
||||
|
||||
/* The increased pages are filled with zero by the OS when os_mmap,
|
||||
@ -759,10 +807,39 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
memory->mem_bound_check_16bytes.u64 = total_size_new - 16;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
return_func:
|
||||
if (!ret && enlarge_memory_error_cb) {
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode)
|
||||
exec_env =
|
||||
((WASMModuleInstanceExtra *)module->e)->common.cur_exec_env;
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
exec_env =
|
||||
((AOTModuleInstanceExtra *)module->e)->common.cur_exec_env;
|
||||
#endif
|
||||
|
||||
enlarge_memory_error_cb(inc_page_count, total_size_old, 0,
|
||||
failure_reason,
|
||||
(WASMModuleInstanceCommon *)module, exec_env,
|
||||
enlarge_memory_error_user_data);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* end of OS_ENABLE_HW_BOUND_CHECK */
|
||||
|
||||
void
|
||||
wasm_runtime_set_enlarge_mem_error_callback(
|
||||
const enlarge_memory_error_callback_t callback, void *user_data)
|
||||
{
|
||||
enlarge_memory_error_cb = callback;
|
||||
enlarge_memory_error_user_data = user_data;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
{
|
||||
|
||||
@ -24,6 +24,10 @@ wasm_runtime_memory_destroy();
|
||||
unsigned
|
||||
wasm_runtime_memory_pool_size();
|
||||
|
||||
void
|
||||
wasm_runtime_set_enlarge_mem_error_callback(
|
||||
const enlarge_memory_error_callback_t callback, void *user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -6,6 +6,15 @@
|
||||
#include "wasm_native.h"
|
||||
#include "wasm_runtime_common.h"
|
||||
#include "bh_log.h"
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
#include "../interpreter/wasm_runtime.h"
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
#include "../aot/aot_runtime.h"
|
||||
#endif
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
#include "../libraries/thread-mgr/thread_manager.h"
|
||||
#endif
|
||||
|
||||
#if !defined(BH_PLATFORM_ZEPHYR) && !defined(BH_PLATFORM_ALIOS_THINGS) \
|
||||
&& !defined(BH_PLATFORM_OPENRTOS) && !defined(BH_PLATFORM_ESP_IDF)
|
||||
@ -22,6 +31,10 @@
|
||||
|
||||
static NativeSymbolsList g_native_symbols_list = NULL;
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
static void *g_wasi_context_key;
|
||||
#endif /* WASM_ENABLE_LIBC_WASI */
|
||||
|
||||
uint32
|
||||
get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis);
|
||||
|
||||
@ -394,6 +407,155 @@ wasm_native_unregister_natives(const char *module_name,
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
|
||||
static uint32
|
||||
context_key_to_idx(void *key)
|
||||
{
|
||||
bh_assert(key != NULL);
|
||||
uint32 idx = (uint32)(uintptr_t)key;
|
||||
bh_assert(idx > 0);
|
||||
bh_assert(idx <= WASM_MAX_INSTANCE_CONTEXTS);
|
||||
return idx - 1;
|
||||
}
|
||||
|
||||
static void *
|
||||
context_idx_to_key(uint32 idx)
|
||||
{
|
||||
bh_assert(idx < WASM_MAX_INSTANCE_CONTEXTS);
|
||||
return (void *)(uintptr_t)(idx + 1);
|
||||
}
|
||||
|
||||
typedef void (*dtor_t)(WASMModuleInstanceCommon *, void *);
|
||||
static dtor_t g_context_dtors[WASM_MAX_INSTANCE_CONTEXTS];
|
||||
|
||||
static void
|
||||
dtor_noop(WASMModuleInstanceCommon *inst, void *ctx)
|
||||
{}
|
||||
|
||||
void *
|
||||
wasm_native_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
|
||||
void *ctx))
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < WASM_MAX_INSTANCE_CONTEXTS; i++) {
|
||||
if (g_context_dtors[i] == NULL) {
|
||||
if (dtor == NULL) {
|
||||
dtor = dtor_noop;
|
||||
}
|
||||
g_context_dtors[i] = dtor;
|
||||
return context_idx_to_key(i);
|
||||
}
|
||||
}
|
||||
LOG_ERROR("failed to allocate instance context key");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_native_destroy_context_key(void *key)
|
||||
{
|
||||
uint32 idx = context_key_to_idx(key);
|
||||
bh_assert(g_context_dtors[idx] != NULL);
|
||||
g_context_dtors[idx] = NULL;
|
||||
}
|
||||
|
||||
static WASMModuleInstanceExtraCommon *
|
||||
wasm_module_inst_extra_common(WASMModuleInstanceCommon *inst)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (inst->module_type == Wasm_Module_Bytecode) {
|
||||
return &((WASMModuleInstance *)inst)->e->common;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (inst->module_type == Wasm_Module_AoT) {
|
||||
return &((AOTModuleInstanceExtra *)((AOTModuleInstance *)inst)->e)
|
||||
->common;
|
||||
}
|
||||
#endif
|
||||
bh_assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_native_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx)
|
||||
{
|
||||
uint32 idx = context_key_to_idx(key);
|
||||
WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
|
||||
common->contexts[idx] = ctx;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_native_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
|
||||
void *ctx)
|
||||
{
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
wasm_cluster_set_context(inst, key, ctx);
|
||||
#else
|
||||
wasm_native_set_context(inst, key, ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *
|
||||
wasm_native_get_context(WASMModuleInstanceCommon *inst, void *key)
|
||||
{
|
||||
uint32 idx = context_key_to_idx(key);
|
||||
WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
|
||||
return common->contexts[idx];
|
||||
}
|
||||
|
||||
void
|
||||
wasm_native_call_context_dtors(WASMModuleInstanceCommon *inst)
|
||||
{
|
||||
WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
|
||||
uint32 i;
|
||||
for (i = 0; i < WASM_MAX_INSTANCE_CONTEXTS; i++) {
|
||||
dtor_t dtor = g_context_dtors[i];
|
||||
if (dtor != NULL) {
|
||||
dtor(inst, common->contexts[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wasm_native_inherit_contexts(WASMModuleInstanceCommon *child,
|
||||
WASMModuleInstanceCommon *parent)
|
||||
{
|
||||
WASMModuleInstanceExtraCommon *parent_common =
|
||||
wasm_module_inst_extra_common(parent);
|
||||
WASMModuleInstanceExtraCommon *child_common =
|
||||
wasm_module_inst_extra_common(child);
|
||||
bh_memcpy_s(child_common->contexts,
|
||||
sizeof(*child_common->contexts) * WASM_MAX_INSTANCE_CONTEXTS,
|
||||
parent_common->contexts,
|
||||
sizeof(*parent_common->contexts) * WASM_MAX_INSTANCE_CONTEXTS);
|
||||
}
|
||||
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
WASIContext *
|
||||
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
return wasm_native_get_context(module_inst_comm, g_wasi_context_key);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
|
||||
WASIContext *wasi_ctx)
|
||||
{
|
||||
return wasm_native_set_context(module_inst_comm, g_wasi_context_key,
|
||||
wasi_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
wasi_context_dtor(WASMModuleInstanceCommon *inst, void *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
wasm_runtime_destroy_wasi(inst);
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_LIBC_WASI */
|
||||
|
||||
bool
|
||||
wasm_native_init()
|
||||
{
|
||||
@ -420,6 +582,10 @@ wasm_native_init()
|
||||
#endif /* WASM_ENABLE_SPEC_TEST */
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
g_wasi_context_key = wasm_native_create_context_key(wasi_context_dtor);
|
||||
if (g_wasi_context_key == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
n_native_symbols = get_libc_wasi_export_apis(&native_symbols);
|
||||
if (!wasm_native_register_natives("wasi_unstable", native_symbols,
|
||||
n_native_symbols))
|
||||
@ -507,6 +673,12 @@ wasm_native_destroy()
|
||||
{
|
||||
NativeSymbolsNode *node, *node_next;
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
if (g_wasi_context_key != NULL) {
|
||||
wasm_native_destroy_context_key(g_wasi_context_key);
|
||||
g_wasi_context_key = NULL;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_LIB_PTHREAD != 0
|
||||
lib_pthread_destroy();
|
||||
#endif
|
||||
|
||||
@ -68,6 +68,36 @@ bool
|
||||
wasm_native_unregister_natives(const char *module_name,
|
||||
NativeSymbol *native_symbols);
|
||||
|
||||
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
|
||||
struct WASMModuleInstanceCommon;
|
||||
|
||||
void *
|
||||
wasm_native_create_context_key(
|
||||
void (*dtor)(struct WASMModuleInstanceCommon *inst, void *ctx));
|
||||
|
||||
void
|
||||
wasm_native_destroy_context_key(void *key);
|
||||
|
||||
void
|
||||
wasm_native_set_context(struct WASMModuleInstanceCommon *inst, void *key,
|
||||
void *ctx);
|
||||
void
|
||||
wasm_native_set_context_spread(struct WASMModuleInstanceCommon *inst, void *key,
|
||||
void *ctx);
|
||||
void *
|
||||
wasm_native_get_context(struct WASMModuleInstanceCommon *inst, void *key);
|
||||
|
||||
void
|
||||
wasm_native_call_context_dtors(struct WASMModuleInstanceCommon *inst);
|
||||
|
||||
void
|
||||
wasm_native_inherit_contexts(struct WASMModuleInstanceCommon *child,
|
||||
struct WASMModuleInstanceCommon *parent);
|
||||
#else /* WASM_ENABLE_MODULE_INST_CONTEXT */
|
||||
#define wasm_native_call_context_dtors(inst) (void)(inst)
|
||||
#define wasm_native_inherit_contexts(child, parent) (void)(parent)
|
||||
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT */
|
||||
|
||||
bool
|
||||
wasm_native_init();
|
||||
|
||||
|
||||
@ -125,6 +125,34 @@ runtime_malloc(uint64 size, WASMModuleInstanceCommon *module_inst,
|
||||
return mem;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
/* TODO: Let loader_malloc be a general API both for AOT and WASM. */
|
||||
|
||||
#define loader_malloc(size, error_buf, error_buf_size) \
|
||||
runtime_malloc(size, NULL, error_buf, error_buf_size)
|
||||
|
||||
static void
|
||||
set_error_buf_v(const WASMModuleCommon *module, char *error_buf,
|
||||
uint32 error_buf_size, const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[128];
|
||||
if (error_buf != NULL) {
|
||||
va_start(args, format);
|
||||
vsnprintf(buf, sizeof(buf), format, args);
|
||||
va_end(args);
|
||||
if (module->module_type == Wasm_Module_AoT) {
|
||||
snprintf(error_buf, error_buf_size, "AOT module load failed: %s",
|
||||
buf);
|
||||
}
|
||||
else if (module->module_type == Wasm_Module_Bytecode) {
|
||||
snprintf(error_buf, error_buf_size, "WASM module load failed: %s",
|
||||
buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
static JitCompOptions jit_options = { 0 };
|
||||
#endif
|
||||
@ -457,8 +485,21 @@ wasm_runtime_env_init()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
|
||||
if (os_blocking_op_init() != BHT_OK) {
|
||||
goto fail11;
|
||||
}
|
||||
os_end_blocking_op();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
|
||||
fail11:
|
||||
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||
aot_compiler_destroy();
|
||||
#endif
|
||||
#endif
|
||||
#if WASM_ENABLE_JIT != 0 || WASM_ENABLE_WAMR_COMPILER != 0
|
||||
fail10:
|
||||
#if WASM_ENABLE_FAST_JIT != 0
|
||||
@ -1185,27 +1226,34 @@ wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
||||
if (get_package_type(buf, size) == Wasm_Module_Bytecode) {
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
module_common =
|
||||
(WASMModuleCommon *)wasm_load(buf, size, error_buf, error_buf_size);
|
||||
return register_module_with_null_name(module_common, error_buf,
|
||||
error_buf_size);
|
||||
(WASMModuleCommon *)wasm_load(buf, size,
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
true,
|
||||
#endif
|
||||
error_buf, error_buf_size);
|
||||
#endif
|
||||
}
|
||||
else if (get_package_type(buf, size) == Wasm_Module_AoT) {
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
module_common = (WASMModuleCommon *)aot_load_from_aot_file(
|
||||
buf, size, error_buf, error_buf_size);
|
||||
return register_module_with_null_name(module_common, error_buf,
|
||||
error_buf_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (size < 4)
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"WASM module load failed: unexpected end");
|
||||
else
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"WASM module load failed: magic header not detected");
|
||||
return NULL;
|
||||
else {
|
||||
if (size < 4)
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"WASM module load failed: unexpected end");
|
||||
else
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"WASM module load failed: magic header not detected");
|
||||
return NULL;
|
||||
}
|
||||
if (!module_common) {
|
||||
LOG_DEBUG("WASM module load failed");
|
||||
return NULL;
|
||||
}
|
||||
return register_module_with_null_name(module_common, error_buf,
|
||||
error_buf_size);
|
||||
}
|
||||
|
||||
WASMModuleCommon *
|
||||
@ -1218,6 +1266,10 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
module_common = (WASMModuleCommon *)wasm_load_from_sections(
|
||||
section_list, error_buf, error_buf_size);
|
||||
if (!module_common) {
|
||||
LOG_DEBUG("WASM module load failed from sections");
|
||||
return NULL;
|
||||
}
|
||||
return register_module_with_null_name(module_common, error_buf,
|
||||
error_buf_size);
|
||||
#endif
|
||||
@ -1226,6 +1278,10 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
module_common = (WASMModuleCommon *)aot_load_from_sections(
|
||||
section_list, error_buf, error_buf_size);
|
||||
if (!module_common) {
|
||||
LOG_DEBUG("WASM module load failed from sections");
|
||||
return NULL;
|
||||
}
|
||||
return register_module_with_null_name(module_common, error_buf,
|
||||
error_buf_size);
|
||||
#endif
|
||||
@ -1392,6 +1448,10 @@ wasm_runtime_init_thread_env(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0 && defined(OS_ENABLE_WAKEUP_BLOCKING_OP)
|
||||
os_end_blocking_op();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1938,33 +1998,6 @@ wasm_runtime_finalize_call_function(WASMExecEnv *exec_env,
|
||||
}
|
||||
#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
|
||||
wasm_runtime_call_wasm(WASMExecEnv *exec_env,
|
||||
WASMFunctionInstanceCommon *function, uint32 argc,
|
||||
@ -2005,15 +2038,10 @@ wasm_runtime_call_wasm(WASMExecEnv *exec_env,
|
||||
param_argc, new_argv);
|
||||
#endif
|
||||
if (!ret) {
|
||||
if (clear_wasi_proc_exit_exception(exec_env->module_inst)) {
|
||||
ret = true;
|
||||
}
|
||||
else {
|
||||
if (new_argv != argv) {
|
||||
wasm_runtime_free(new_argv);
|
||||
}
|
||||
return false;
|
||||
if (new_argv != argv) {
|
||||
wasm_runtime_free(new_argv);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_REF_TYPES != 0
|
||||
@ -2374,15 +2402,10 @@ wasm_runtime_get_exec_env_singleton(WASMModuleInstanceCommon *module_inst_comm)
|
||||
return module_inst->exec_env_singleton;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
static void
|
||||
wasm_set_exception_local(WASMModuleInstance *module_inst, const char *exception)
|
||||
{
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (module_inst->memory_count > 0)
|
||||
shared_memory_lock(module_inst->memories[0]);
|
||||
#endif
|
||||
exception_lock(module_inst);
|
||||
if (exception) {
|
||||
snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception),
|
||||
"Exception: %s", exception);
|
||||
@ -2390,19 +2413,23 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
else {
|
||||
module_inst->cur_exception[0] = '\0';
|
||||
}
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (module_inst->memory_count > 0)
|
||||
shared_memory_unlock(module_inst->memories[0]);
|
||||
#endif
|
||||
exception_unlock(module_inst);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
{
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
exec_env =
|
||||
WASMExecEnv *exec_env =
|
||||
wasm_clusters_search_exec_env((WASMModuleInstanceCommon *)module_inst);
|
||||
if (exec_env) {
|
||||
wasm_cluster_spread_exception(exec_env, exception ? false : true);
|
||||
wasm_cluster_set_exception(exec_env, exception);
|
||||
}
|
||||
else {
|
||||
wasm_set_exception_local(module_inst, exception);
|
||||
}
|
||||
#else
|
||||
(void)exec_env;
|
||||
wasm_set_exception_local(module_inst, exception);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2453,10 +2480,7 @@ wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf)
|
||||
{
|
||||
bool has_exception = false;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (module_inst->memory_count > 0)
|
||||
shared_memory_lock(module_inst->memories[0]);
|
||||
#endif
|
||||
exception_lock(module_inst);
|
||||
if (module_inst->cur_exception[0] != '\0') {
|
||||
/* NULL is passed if the caller is not interested in getting the
|
||||
* exception content, but only in knowing if an exception has been
|
||||
@ -2468,10 +2492,7 @@ wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf)
|
||||
sizeof(module_inst->cur_exception));
|
||||
has_exception = true;
|
||||
}
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (module_inst->memory_count > 0)
|
||||
shared_memory_unlock(module_inst->memories[0]);
|
||||
#endif
|
||||
exception_unlock(module_inst);
|
||||
|
||||
return has_exception;
|
||||
}
|
||||
@ -2516,6 +2537,18 @@ wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst_comm)
|
||||
wasm_runtime_set_exception(module_inst_comm, NULL);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
void
|
||||
wasm_runtime_terminate(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
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);
|
||||
wasm_set_exception(module_inst, "terminated by user");
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
WASMModuleInstanceCommon *module_inst_comm, void *custom_data)
|
||||
@ -3338,27 +3371,6 @@ wasm_runtime_get_wasi_exit_code(WASMModuleInstanceCommon *module_inst)
|
||||
#endif
|
||||
return wasi_ctx->exit_code;
|
||||
}
|
||||
|
||||
WASIContext *
|
||||
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
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);
|
||||
return module_inst->wasi_ctx;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
|
||||
WASIContext *wasi_ctx)
|
||||
{
|
||||
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);
|
||||
module_inst->wasi_ctx = wasi_ctx;
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_LIBC_WASI */
|
||||
|
||||
WASMModuleCommon *
|
||||
@ -4621,10 +4633,6 @@ wasm_runtime_call_indirect(WASMExecEnv *exec_env, uint32 element_index,
|
||||
ret = aot_call_indirect(exec_env, 0, element_index, argc, argv);
|
||||
#endif
|
||||
|
||||
if (!ret && clear_wasi_proc_exit_exception(exec_env->module_inst)) {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -5708,3 +5716,345 @@ wasm_runtime_is_import_global_linked(const char *module_name,
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0 || WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMExport *
|
||||
loader_find_export(const WASMModuleCommon *module, const char *module_name,
|
||||
const char *field_name, uint8 export_kind, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMExport *exports = NULL, *result = NULL, *export;
|
||||
uint32 export_count = 0, i;
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT) {
|
||||
AOTModule *aot_module = (AOTModule *)module;
|
||||
exports = (WASMExport *)aot_module->exports;
|
||||
export_count = aot_module->export_count;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode) {
|
||||
WASMModule *wasm_module = (WASMModule *)module;
|
||||
exports = wasm_module->exports;
|
||||
export_count = wasm_module->export_count;
|
||||
}
|
||||
#endif
|
||||
for (i = 0, export = exports; i < export_count; ++i, ++export) {
|
||||
if (export->kind == export_kind && !strcmp(field_name, export->name)) {
|
||||
result = export;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
if (i == export_count) {
|
||||
LOG_DEBUG("can not find an export %d named %s in the module %s",
|
||||
export_kind, field_name, module_name);
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"unknown import or incompatible import type");
|
||||
}
|
||||
exit:
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMModuleCommon *
|
||||
wasm_runtime_search_sub_module(const WASMModuleCommon *parent_module,
|
||||
const char *sub_module_name)
|
||||
{
|
||||
WASMRegisteredModule *node = NULL;
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (parent_module->module_type == Wasm_Module_AoT) {
|
||||
node = bh_list_first_elem(
|
||||
((AOTModule *)parent_module)->import_module_list);
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (parent_module->module_type == Wasm_Module_Bytecode) {
|
||||
node = bh_list_first_elem(
|
||||
((WASMModule *)parent_module)->import_module_list);
|
||||
}
|
||||
#endif
|
||||
while (node && strcmp(sub_module_name, node->module_name)) {
|
||||
node = bh_list_elem_next(node);
|
||||
}
|
||||
return node ? node->module : NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_register_sub_module(const WASMModuleCommon *parent_module,
|
||||
const char *sub_module_name,
|
||||
WASMModuleCommon *sub_module)
|
||||
{
|
||||
/* register sub_module into its parent sub module list */
|
||||
WASMRegisteredModule *node = NULL;
|
||||
bh_list_status ret;
|
||||
|
||||
if (wasm_runtime_search_sub_module(parent_module, sub_module_name)) {
|
||||
LOG_DEBUG("%s has been registered in its parent", sub_module_name);
|
||||
return true;
|
||||
}
|
||||
|
||||
node = loader_malloc(sizeof(WASMRegisteredModule), NULL, 0);
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
node->module_name = sub_module_name;
|
||||
node->module = sub_module;
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (parent_module->module_type == Wasm_Module_AoT) {
|
||||
ret = bh_list_insert(((AOTModule *)parent_module)->import_module_list,
|
||||
node);
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (parent_module->module_type == Wasm_Module_Bytecode) {
|
||||
ret = bh_list_insert(((WASMModule *)parent_module)->import_module_list,
|
||||
node);
|
||||
}
|
||||
#endif
|
||||
bh_assert(BH_LIST_SUCCESS == ret);
|
||||
(void)ret;
|
||||
return true;
|
||||
}
|
||||
|
||||
WASMModuleCommon *
|
||||
wasm_runtime_load_depended_module(const WASMModuleCommon *parent_module,
|
||||
const char *sub_module_name, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
WASMModuleCommon *sub_module = NULL;
|
||||
bool ret = false;
|
||||
uint8 *buffer = NULL;
|
||||
uint32 buffer_size = 0;
|
||||
|
||||
/* check the registered module list of the parent */
|
||||
sub_module = wasm_runtime_search_sub_module(parent_module, sub_module_name);
|
||||
if (sub_module) {
|
||||
LOG_DEBUG("%s has been loaded before", sub_module_name);
|
||||
return sub_module;
|
||||
}
|
||||
|
||||
/* check the global registered module list */
|
||||
sub_module = wasm_runtime_find_module_registered(sub_module_name);
|
||||
if (sub_module) {
|
||||
LOG_DEBUG("%s has been loaded", sub_module_name);
|
||||
goto wasm_runtime_register_sub_module;
|
||||
}
|
||||
LOG_VERBOSE("loading %s", sub_module_name);
|
||||
if (!reader) {
|
||||
set_error_buf_v(parent_module, error_buf, error_buf_size,
|
||||
"no sub module reader to load %s", sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
/* start to maintain a loading module list */
|
||||
ret = wasm_runtime_is_loading_module(sub_module_name);
|
||||
if (ret) {
|
||||
set_error_buf_v(parent_module, error_buf, error_buf_size,
|
||||
"found circular dependency on %s", sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
ret = wasm_runtime_add_loading_module(sub_module_name, error_buf,
|
||||
error_buf_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("can not add %s into loading module list\n", sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = reader(parent_module->module_type, sub_module_name, &buffer,
|
||||
&buffer_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("read the file of %s failed", sub_module_name);
|
||||
set_error_buf_v(parent_module, error_buf, error_buf_size,
|
||||
"unknown import", sub_module_name);
|
||||
goto delete_loading_module;
|
||||
}
|
||||
if (get_package_type(buffer, buffer_size) != parent_module->module_type) {
|
||||
LOG_DEBUG("moudle %s type error", sub_module_name);
|
||||
goto delete_loading_module;
|
||||
}
|
||||
if (get_package_type(buffer, buffer_size) == Wasm_Module_Bytecode) {
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
sub_module = (WASMModuleCommon *)wasm_load(buffer, buffer_size, false,
|
||||
error_buf, error_buf_size);
|
||||
#endif
|
||||
}
|
||||
else if (get_package_type(buffer, buffer_size) == Wasm_Module_AoT) {
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
sub_module = (WASMModuleCommon *)aot_load_from_aot_file(
|
||||
buffer, buffer_size, error_buf, error_buf_size);
|
||||
#endif
|
||||
}
|
||||
if (!sub_module) {
|
||||
LOG_DEBUG("error: can not load the sub_module %s", sub_module_name);
|
||||
/* others will be destroyed in runtime_destroy() */
|
||||
goto destroy_file_buffer;
|
||||
}
|
||||
wasm_runtime_delete_loading_module(sub_module_name);
|
||||
/* register on a global list */
|
||||
ret = wasm_runtime_register_module_internal(
|
||||
sub_module_name, (WASMModuleCommon *)sub_module, buffer, buffer_size,
|
||||
error_buf, error_buf_size);
|
||||
if (!ret) {
|
||||
LOG_DEBUG("error: can not register module %s globally\n",
|
||||
sub_module_name);
|
||||
/* others will be unloaded in runtime_destroy() */
|
||||
goto unload_module;
|
||||
}
|
||||
|
||||
/* register into its parent list */
|
||||
wasm_runtime_register_sub_module:
|
||||
ret = wasm_runtime_register_sub_module(parent_module, sub_module_name,
|
||||
sub_module);
|
||||
if (!ret) {
|
||||
set_error_buf_v(parent_module, error_buf, error_buf_size,
|
||||
"failed to register sub module %s", sub_module_name);
|
||||
/* since it is in the global module list, no need to
|
||||
* unload the module. the runtime_destroy() will do it
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sub_module;
|
||||
|
||||
unload_module:
|
||||
wasm_runtime_unload(sub_module);
|
||||
|
||||
destroy_file_buffer:
|
||||
if (destroyer) {
|
||||
destroyer(buffer, buffer_size);
|
||||
}
|
||||
else {
|
||||
LOG_WARNING("need to release the reading buffer of %s manually",
|
||||
sub_module_name);
|
||||
}
|
||||
|
||||
delete_loading_module:
|
||||
wasm_runtime_delete_loading_module(sub_module_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
|
||||
WASMModuleInstanceCommon *module_inst,
|
||||
uint32 stack_size, uint32 heap_size,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
bh_list *sub_module_inst_list = NULL;
|
||||
WASMRegisteredModule *sub_module_list_node = NULL;
|
||||
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT) {
|
||||
sub_module_inst_list =
|
||||
((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
|
||||
->sub_module_inst_list;
|
||||
sub_module_list_node =
|
||||
bh_list_first_elem(((AOTModule *)module)->import_module_list);
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode) {
|
||||
sub_module_inst_list =
|
||||
((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e)
|
||||
->sub_module_inst_list;
|
||||
sub_module_list_node =
|
||||
bh_list_first_elem(((WASMModule *)module)->import_module_list);
|
||||
}
|
||||
#endif
|
||||
while (sub_module_list_node) {
|
||||
WASMSubModInstNode *sub_module_inst_list_node = NULL;
|
||||
WASMModuleCommon *sub_module = sub_module_list_node->module;
|
||||
WASMModuleInstanceCommon *sub_module_inst = NULL;
|
||||
sub_module_inst = wasm_runtime_instantiate_internal(
|
||||
sub_module, NULL, NULL, stack_size, heap_size, error_buf,
|
||||
error_buf_size);
|
||||
if (!sub_module_inst) {
|
||||
LOG_DEBUG("instantiate %s failed",
|
||||
sub_module_list_node->module_name);
|
||||
return false;
|
||||
}
|
||||
sub_module_inst_list_node = loader_malloc(sizeof(WASMSubModInstNode),
|
||||
error_buf, error_buf_size);
|
||||
if (!sub_module_inst_list_node) {
|
||||
LOG_DEBUG("Malloc WASMSubModInstNode failed, SZ:%d",
|
||||
sizeof(WASMSubModInstNode));
|
||||
if (sub_module_inst)
|
||||
wasm_runtime_deinstantiate_internal(sub_module_inst, false);
|
||||
return false;
|
||||
}
|
||||
sub_module_inst_list_node->module_inst =
|
||||
(WASMModuleInstance *)sub_module_inst;
|
||||
sub_module_inst_list_node->module_name =
|
||||
sub_module_list_node->module_name;
|
||||
bh_list_status ret =
|
||||
bh_list_insert(sub_module_inst_list, sub_module_inst_list_node);
|
||||
bh_assert(BH_LIST_SUCCESS == ret);
|
||||
(void)ret;
|
||||
sub_module_list_node = bh_list_elem_next(sub_module_list_node);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_sub_module_deinstantiate(WASMModuleInstanceCommon *module_inst)
|
||||
{
|
||||
bh_list *list = NULL;
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module_inst->module_type == Wasm_Module_AoT) {
|
||||
list = ((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
|
||||
->sub_module_inst_list;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module_inst->module_type == Wasm_Module_Bytecode) {
|
||||
list =
|
||||
((WASMModuleInstanceExtra *)((WASMModuleInstance *)module_inst)->e)
|
||||
->sub_module_inst_list;
|
||||
}
|
||||
#endif
|
||||
|
||||
WASMSubModInstNode *node = bh_list_first_elem(list);
|
||||
while (node) {
|
||||
WASMSubModInstNode *next_node = bh_list_elem_next(node);
|
||||
bh_list_remove(list, node);
|
||||
wasm_runtime_deinstantiate_internal(
|
||||
(WASMModuleInstanceCommon *)node->module_inst, false);
|
||||
wasm_runtime_free(node);
|
||||
node = next_node;
|
||||
}
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_MULTI_MODULE */
|
||||
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
|
||||
void *
|
||||
wasm_runtime_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
|
||||
void *ctx))
|
||||
{
|
||||
return wasm_native_create_context_key(dtor);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_destroy_context_key(void *key)
|
||||
{
|
||||
wasm_native_destroy_context_key(key);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx)
|
||||
{
|
||||
wasm_native_set_context(inst, key, ctx);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
|
||||
void *ctx)
|
||||
{
|
||||
wasm_native_set_context_spread(inst, key, ctx);
|
||||
}
|
||||
|
||||
void *
|
||||
wasm_runtime_get_context(WASMModuleInstanceCommon *inst, void *key)
|
||||
{
|
||||
return wasm_native_get_context(inst, key);
|
||||
}
|
||||
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */
|
||||
|
||||
@ -675,6 +675,10 @@ wasm_runtime_get_exception(WASMModuleInstanceCommon *module);
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_clear_exception(WASMModuleInstanceCommon *module_inst);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_terminate(WASMModuleInstanceCommon *module);
|
||||
|
||||
/* Internal API */
|
||||
void
|
||||
wasm_runtime_set_custom_data_internal(WASMModuleInstanceCommon *module_inst,
|
||||
@ -784,6 +788,9 @@ wasm_runtime_register_module_internal(const char *module_name,
|
||||
void
|
||||
wasm_runtime_unregister_module(const WASMModuleCommon *module);
|
||||
|
||||
WASMModuleCommon *
|
||||
wasm_runtime_find_module_registered(const char *module_name);
|
||||
|
||||
bool
|
||||
wasm_runtime_add_loading_module(const char *module_name, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
@ -796,6 +803,35 @@ wasm_runtime_is_loading_module(const char *module_name);
|
||||
|
||||
void
|
||||
wasm_runtime_destroy_loading_module_list();
|
||||
|
||||
WASMModuleCommon *
|
||||
wasm_runtime_search_sub_module(const WASMModuleCommon *parent_module,
|
||||
const char *sub_module_name);
|
||||
|
||||
bool
|
||||
wasm_runtime_register_sub_module(const WASMModuleCommon *parent_module,
|
||||
const char *sub_module_name,
|
||||
WASMModuleCommon *sub_module);
|
||||
|
||||
WASMModuleCommon *
|
||||
wasm_runtime_load_depended_module(const WASMModuleCommon *parent_module,
|
||||
const char *sub_module_name, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
|
||||
bool
|
||||
wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
|
||||
WASMModuleInstanceCommon *module_inst,
|
||||
uint32 stack_size, uint32 heap_size,
|
||||
char *error_buf, uint32 error_buf_size);
|
||||
void
|
||||
wasm_runtime_sub_module_deinstantiate(WASMModuleInstanceCommon *module_inst);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0 || WASM_ENABLE_MULTI_MODULE != 0
|
||||
WASMExport *
|
||||
loader_find_export(const WASMModuleCommon *module, const char *module_name,
|
||||
const char *field_name, uint8 export_kind, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
#endif /* WASM_ENALBE_MULTI_MODULE */
|
||||
|
||||
bool
|
||||
@ -939,6 +975,26 @@ WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_unregister_natives(const char *module_name,
|
||||
NativeSymbol *native_symbols);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void *
|
||||
wasm_runtime_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
|
||||
void *ctx));
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_destroy_context_key(void *key);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx);
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
|
||||
void *ctx);
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void *
|
||||
wasm_runtime_get_context(WASMModuleInstanceCommon *inst, void *key);
|
||||
|
||||
bool
|
||||
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||
const WASMType *func_type, const char *signature,
|
||||
@ -1016,6 +1072,15 @@ WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_is_import_global_linked(const char *module_name,
|
||||
const char *global_name);
|
||||
|
||||
WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_begin_blocking_op(WASMExecEnv *exec_env);
|
||||
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_end_blocking_op(WASMExecEnv *exec_env);
|
||||
|
||||
void
|
||||
wasm_runtime_interrupt_blocking_op(WASMExecEnv *exec_env);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -20,6 +20,8 @@ extern "C" {
|
||||
#define WASM_SUSPEND_FLAG_BREAKPOINT 0x4
|
||||
/* Return from pthread_exit */
|
||||
#define WASM_SUSPEND_FLAG_EXIT 0x8
|
||||
/* The thread might be blocking */
|
||||
#define WASM_SUSPEND_FLAG_BLOCKING 0x10
|
||||
|
||||
typedef union WASMSuspendFlags {
|
||||
bh_atomic_32_t flags;
|
||||
|
||||
Reference in New Issue
Block a user