Merge branch main into dev/wasi-libc-windows

This commit is contained in:
Wenyong Huang 2023-10-08 15:03:35 +08:00
commit e222955f31
151 changed files with 5909 additions and 2046 deletions

View File

@ -16,7 +16,7 @@ concurrency:
jobs:
compliance_job:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- name: checkout
uses: actions/checkout@v3

View File

@ -65,6 +65,7 @@ env:
THREADS_TEST_OPTIONS: "-s spec -b -p -P"
X86_32_TARGET_TEST_OPTIONS: "-m x86_32 -P"
WASI_TEST_OPTIONS: "-s wasi_certification -w"
WAMR_COMPILER_TEST_OPTIONS: "-s wamr_compiler -b -P"
jobs:
build_llvm_libraries_on_ubuntu_2204:
@ -150,9 +151,7 @@ jobs:
exclude:
# uncompatiable feature and platform
# uncompatiable mode and feature
# MULTI_MODULE only on INTERP mode
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
# MULTI_MODULE only on INTERP mode and AOT mode
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
@ -241,6 +240,14 @@ jobs:
cmake --build . --config Release --parallel 4
working-directory: product-mini/platforms/${{ matrix.platform }}
- name: Build and run unit tests
run: |
mkdir build-unittests && cd build-unittests
cmake .. ${{ matrix.make_options_run_mode }} ${{ matrix.make_options_feature }}
cmake --build . --config Release --parallel 4
ctest
working-directory: tests/unit
build_samples_wasm_c_api:
needs:
[
@ -320,7 +327,12 @@ jobs:
working-directory: samples/wasm-c-api
build_samples_others:
needs: [build_iwasm]
needs:
[
build_iwasm,
build_llvm_libraries_on_ubuntu_2204,
build_wamrc,
]
runs-on: ${{ matrix.os }}
strategy:
matrix:
@ -333,6 +345,9 @@ jobs:
[
"https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz",
]
include:
- os: ubuntu-22.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
steps:
- name: checkout
uses: actions/checkout@v3
@ -350,7 +365,23 @@ jobs:
sudo wget ${{ matrix.wabt_release }}
sudo tar -xzf wabt-1.0.31-*.tar.gz
sudo mv wabt-1.0.31 wabt
- name: Get LLVM libraries
id: retrieve_llvm_libs
uses: actions/cache@v3
with:
path: |
./core/deps/llvm/build/bin
./core/deps/llvm/build/include
./core/deps/llvm/build/lib
./core/deps/llvm/build/libexec
./core/deps/llvm/build/share
key: ${{ matrix.llvm_cache_key }}
- name: Build wamrc
run: |
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
working-directory: wamr-compiler
- name: Build Sample [basic]
run: |
cd samples/basic
@ -377,9 +408,10 @@ jobs:
run: |
cd samples/multi-module
mkdir build && cd build
cmake ..
cmake .. -DWAMR_BUILD_AOT=1
cmake --build . --config Release --parallel 4
./multi_module
./multi_module mC.wasm
./multi_module mC.aot
- name: Build Sample [spawn-thread]
run: |
@ -449,6 +481,10 @@ jobs:
- os: ubuntu-22.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
ubuntu_version: "22.04"
- os: ubuntu-22.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2204.outputs.cache_key }}
running_mode: aot
test_option: $WAMR_COMPILER_TEST_OPTIONS
exclude:
# uncompatiable modes and features
# classic-interp and fast-interp don't support simd
@ -456,9 +492,7 @@ jobs:
test_option: $SIMD_TEST_OPTIONS
- running_mode: "fast-interp"
test_option: $SIMD_TEST_OPTIONS
# aot and jit don't support multi module
- running_mode: "aot"
test_option: $MULTI_MODULES_TEST_OPTIONS
# llvm jit doesn't support multi module
- running_mode: "jit"
test_option: $MULTI_MODULES_TEST_OPTIONS
# fast-jit doesn't support multi module, simd

View File

@ -133,13 +133,11 @@ jobs:
exclude:
# uncompatiable feature and platform
# uncompatiable mode and feature
# MULTI_MODULE only on INTERP mode
# MULTI_MODULE only on INTERP mode and AOT mode
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
- make_options_run_mode: $LLVM_EAGER_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
# SIMD only on JIT/AOT mode
- make_options_run_mode: $CLASSIC_INTERP_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_SIMD=1"
@ -245,7 +243,7 @@ jobs:
working-directory: samples/wasm-c-api
build_samples_others:
needs: [build_iwasm]
needs: [build_iwasm, build_wamrc]
runs-on: ${{ matrix.os }}
strategy:
matrix:
@ -304,7 +302,7 @@ jobs:
mkdir build && cd build
cmake ..
cmake --build . --config Release --parallel 4
./multi_module
./multi_module mC.wasm
- name: Build Sample [spawn-thread]
run: |

View File

@ -101,9 +101,6 @@ jobs:
platform: [linux-sgx]
exclude:
# uncompatiable mode and feature
# MULTI_MODULE only on INTERP mode
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
# MINI_LOADER only on INTERP mode
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MINI_LOADER=1"

View File

@ -8,9 +8,11 @@ on:
types:
- opened
- synchronize
#running nightly pipeline if you're changing it
# running nightly pipeline if you're changing it
# stress tests are run only in nightly at the moment, so running them in they are changed
paths:
- ".github/workflows/nightly_run.yml"
- "core/iwasm/libraries/lib-wasi-threads/stress-test/**"
# midnight UTC
schedule:
@ -125,9 +127,7 @@ jobs:
exclude:
# uncompatiable feature and platform
# uncompatiable mode and feature
# MULTI_MODULE only on INTERP mode
- make_options_run_mode: $AOT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
# MULTI_MODULE only on INTERP mode and AOT mode
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
- make_options_run_mode: $LLVM_LAZY_JIT_BUILD_OPTIONS
@ -250,7 +250,7 @@ jobs:
exclude:
# uncompatiable feature and platform
# uncompatiable mode and feature
# MULTI_MODULE only on INTERP mode
# MULTI_MODULE only on INTERP mode and AOT mode
- make_options_run_mode: $FAST_JIT_BUILD_OPTIONS
make_options_feature: "-DWAMR_BUILD_MULTI_MODULE=1"
# SIMD only on JIT/AOT mode
@ -380,7 +380,12 @@ jobs:
working-directory: samples/wasm-c-api
build_samples_others:
needs: [build_iwasm]
needs:
[
build_iwasm,
build_llvm_libraries_on_ubuntu_2004,
build_wamrc,
]
runs-on: ${{ matrix.os }}
strategy:
matrix:
@ -393,6 +398,9 @@ jobs:
[
"https://github.com/WebAssembly/wabt/releases/download/1.0.31/wabt-1.0.31-ubuntu.tar.gz",
]
include:
- os: ubuntu-20.04
llvm_cache_key: ${{ needs.build_llvm_libraries_on_ubuntu_2004.outputs.cache_key }}
steps:
- name: checkout
uses: actions/checkout@v3
@ -409,6 +417,26 @@ jobs:
sudo wget ${{ matrix.wabt_release }}
sudo tar -xzf wabt-1.0.31-*.tar.gz
sudo mv wabt-1.0.31 wabt
- name: Get LLVM libraries
id: retrieve_llvm_libs
uses: actions/cache@v3
with:
path: |
./core/deps/llvm/build/bin
./core/deps/llvm/build/include
./core/deps/llvm/build/lib
./core/deps/llvm/build/libexec
./core/deps/llvm/build/share
key: ${{ matrix.llvm_cache_key }}
- name: Build wamrc
run: |
mkdir build && cd build
cmake -D WAMR_BUILD_SANITIZER="${{matrix.sanitizer}}" ..
cmake --build . --config Release --parallel 4
working-directory: wamr-compiler
- name: Build Sample [basic]
run: |
cd samples/basic
@ -432,9 +460,10 @@ jobs:
run: |
cd samples/multi-module
mkdir build && cd build
cmake ..
cmake .. -DWAMR_BUILD_AOT=1
cmake --build . --config Release --parallel 4
./multi_module
./multi_module mC.wasm
./multi_module mC.aot
- name: Build Sample [spawn-thread]
run: |
cd samples/spawn-thread
@ -522,9 +551,7 @@ jobs:
test_option: $SIMD_TEST_OPTIONS
- running_mode: "fast-interp"
test_option: $SIMD_TEST_OPTIONS
# aot and jit don't support multi module
- running_mode: "aot"
test_option: $MULTI_MODULES_TEST_OPTIONS
# llvm jit doesn't support multi module
- running_mode: "jit"
test_option: $MULTI_MODULES_TEST_OPTIONS
# fast-jit doesn't support multi module, simd
@ -599,6 +626,11 @@ jobs:
run: bash build.sh --sysroot "$SYSROOT_PATH"
working-directory: ./core/iwasm/libraries/lib-wasi-threads/test/
- name: Build WASI thread stress tests
if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: bash build.sh --sysroot "$SYSROOT_PATH"
working-directory: ./core/iwasm/libraries/lib-wasi-threads/stress-test/
- name: build socket api tests
if: matrix.test_option == '$WASI_TEST_OPTIONS'
run: bash build.sh

View File

@ -273,6 +273,13 @@ else ()
add_definitions (-DWASM_DISABLE_STACK_HW_BOUND_CHECK=0)
endif ()
endif ()
if (WAMR_DISABLE_WAKEUP_BLOCKING_OP EQUAL 1)
add_definitions (-DWASM_DISABLE_WAKEUP_BLOCKING_OP=1)
message (" Wakeup of blocking operations disabled")
else ()
add_definitions (-DWASM_DISABLE_WAKEUP_BLOCKING_OP=0)
message (" Wakeup of blocking operations enabled")
endif ()
if (WAMR_BUILD_SIMD EQUAL 1)
if (NOT WAMR_BUILD_TARGET MATCHES "RISCV64.*")
add_definitions (-DWASM_ENABLE_SIMD=1)
@ -378,6 +385,10 @@ if (WAMR_BUILD_WASM_CACHE EQUAL 1)
add_definitions (-DWASM_ENABLE_WASM_CACHE=1)
message (" Wasm files cache enabled")
endif ()
if (WAMR_BUILD_MODULE_INST_CONTEXT EQUAL 1)
add_definitions (-DWASM_ENABLE_MODULE_INST_CONTEXT=1)
message (" Module instance context enabled")
endif ()
if (WAMR_BUILD_GC_HEAP_VERIFY EQUAL 1)
add_definitions (-DWASM_ENABLE_GC_VERIFY=1)
message (" GC heap verification enabled")

View File

@ -91,8 +91,10 @@ endif ()
if (WAMR_BUILD_LIBC_UVWASI EQUAL 1)
include (${IWASM_DIR}/libraries/libc-uvwasi/libc_uvwasi.cmake)
set (WAMR_BUILD_MODULE_INST_CONTEXT 1)
elseif (WAMR_BUILD_LIBC_WASI EQUAL 1)
include (${IWASM_DIR}/libraries/libc-wasi/libc_wasi.cmake)
set (WAMR_BUILD_MODULE_INST_CONTEXT 1)
endif ()
if (WAMR_BUILD_LIB_PTHREAD_SEMAPHORE EQUAL 1)

View File

@ -480,4 +480,9 @@
#define WASM_MEM_DUAL_BUS_MIRROR 0
#endif
/* The max number of module instance contexts. */
#ifndef WASM_MAX_INSTANCE_CONTEXTS
#define WASM_MAX_INSTANCE_CONTEXTS 8
#endif
#endif /* end of _CONFIG_H_ */

View File

@ -558,6 +558,56 @@ str2uint32(const char *buf, uint32 *p_res);
static bool
str2uint64(const char *buf, uint64 *p_res);
#if WASM_ENABLE_MULTI_MODULE != 0
static void *
aot_loader_resolve_function(const char *module_name, const char *function_name,
const AOTFuncType *expected_function_type,
char *error_buf, uint32 error_buf_size)
{
WASMModuleCommon *module_reg;
void *function = NULL;
AOTExport *export = NULL;
AOTModule *module = NULL;
AOTFuncType *target_function_type = NULL;
module_reg = wasm_runtime_find_module_registered(module_name);
if (!module_reg || module_reg->module_type != Wasm_Module_AoT) {
LOG_DEBUG("can not find a module named %s for function %s", module_name,
function_name);
set_error_buf(error_buf, error_buf_size, "unknown import");
return NULL;
}
module = (AOTModule *)module_reg;
export = loader_find_export(module_reg, module_name, function_name,
EXPORT_KIND_FUNC, error_buf, error_buf_size);
if (!export) {
return NULL;
}
/* resolve function type and function */
if (export->index < module->import_func_count) {
target_function_type = module->import_funcs[export->index].func_type;
function = module->import_funcs[export->index].func_ptr_linked;
}
else {
target_function_type =
module->func_types[module->func_type_indexes
[export->index - module->import_func_count]];
function =
(module->func_ptrs[export->index - module->import_func_count]);
}
/* check function type */
if (!wasm_type_equal(expected_function_type, target_function_type)) {
LOG_DEBUG("%s.%s failed the type check", module_name, function_name);
set_error_buf(error_buf, error_buf_size, "incompatible import type");
return NULL;
}
return function;
}
#endif /* end of WASM_ENABLE_MULTI_MODULE */
static bool
load_native_symbol_section(const uint8 *buf, const uint8 *buf_end,
AOTModule *module, bool is_load_from_file_buf,
@ -1357,11 +1407,16 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
bool is_load_from_file_buf, char *error_buf,
uint32 error_buf_size)
{
const char *module_name, *field_name;
char *module_name, *field_name;
const uint8 *buf = *p_buf;
AOTImportFunc *import_funcs;
uint64 size;
uint32 i;
#if WASM_ENABLE_MULTI_MODULE != 0
AOTModule *sub_module = NULL;
AOTFunc *linked_func = NULL;
WASMType *declare_func_type = NULL;
#endif
/* Allocate memory */
size = sizeof(AOTImportFunc) * (uint64)module->import_func_count;
@ -1377,17 +1432,46 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
set_error_buf(error_buf, error_buf_size, "unknown type");
return false;
}
#if WASM_ENABLE_MULTI_MODULE != 0
declare_func_type = module->func_types[import_funcs[i].func_type_index];
read_string(buf, buf_end, module_name);
read_string(buf, buf_end, field_name);
import_funcs[i].module_name = module_name;
import_funcs[i].func_name = field_name;
linked_func = wasm_native_resolve_symbol(
module_name, field_name, declare_func_type,
&import_funcs[i].signature, &import_funcs[i].attachment,
&import_funcs[i].call_conv_raw);
if (!linked_func) {
if (!wasm_runtime_is_built_in_module(module_name)) {
sub_module = (AOTModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)module, module_name, error_buf,
error_buf_size);
if (!sub_module) {
return false;
}
}
linked_func = aot_loader_resolve_function(
module_name, field_name, declare_func_type, error_buf,
error_buf_size);
}
import_funcs[i].func_ptr_linked = linked_func;
import_funcs[i].func_type = declare_func_type;
#else
import_funcs[i].func_type =
module->func_types[import_funcs[i].func_type_index];
read_string(buf, buf_end, import_funcs[i].module_name);
read_string(buf, buf_end, import_funcs[i].func_name);
module_name = import_funcs[i].module_name;
field_name = import_funcs[i].func_name;
import_funcs[i].func_ptr_linked = wasm_native_resolve_symbol(
module_name, field_name, import_funcs[i].func_type,
&import_funcs[i].signature, &import_funcs[i].attachment,
&import_funcs[i].call_conv_raw);
#endif
#if WASM_ENABLE_LIBC_WASI != 0
if (!strcmp(import_funcs[i].module_name, "wasi_unstable")
@ -2871,6 +2955,7 @@ create_module(char *error_buf, uint32 error_buf_size)
{
AOTModule *module =
loader_malloc(sizeof(AOTModule), error_buf, error_buf_size);
bh_list_status ret;
if (!module) {
return NULL;
@ -2878,6 +2963,13 @@ create_module(char *error_buf, uint32 error_buf_size)
module->module_type = Wasm_Module_AoT;
#if WASM_ENABLE_MULTI_MODULE != 0
module->import_module_list = &module->import_module_list_head;
ret = bh_list_init(module->import_module_list);
bh_assert(ret == BH_LIST_SUCCESS);
#endif
(void)ret;
return module;
}
@ -3143,10 +3235,13 @@ aot_load_from_aot_file(const uint8 *buf, uint32 size, char *error_buf,
if (!module)
return NULL;
os_thread_jit_write_protect_np(false); /* Make memory writable */
if (!load(buf, size, module, error_buf, error_buf_size)) {
aot_unload(module);
return NULL;
}
os_thread_jit_write_protect_np(true); /* Make memory executable */
os_icache_flush(module->code, module->code_size);
LOG_VERBOSE("Load module success.\n");
return module;
@ -3201,6 +3296,19 @@ aot_unload(AOTModule *module)
if (module->const_str_set)
bh_hash_map_destroy(module->const_str_set);
#if WASM_ENABLE_MULTI_MODULE != 0
/* just release the sub module list */
if (module->import_module_list) {
WASMRegisteredModule *node =
bh_list_first_elem(module->import_module_list);
while (node) {
WASMRegisteredModule *next = bh_list_elem_next(node);
bh_list_remove(module->import_module_list, node);
wasm_runtime_free(node);
node = next;
}
}
#endif
if (module->code && !module->is_indirect_mode) {
/* The layout is: literal size + literal + code (with plt table) */

View File

@ -1091,6 +1091,9 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
uint8 *p;
uint32 i, extra_info_offset;
const bool is_sub_inst = parent != NULL;
#if WASM_ENABLE_MULTI_MODULE != 0
bool ret = false;
#endif
/* Check heap size */
heap_size = align_uint(heap_size, 8);
@ -1134,6 +1137,18 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
module_inst->e =
(WASMModuleInstanceExtra *)((uint8 *)module_inst + extra_info_offset);
#if WASM_ENABLE_MULTI_MODULE != 0
((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list =
&((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list_head;
ret = wasm_runtime_sub_module_instantiate(
(WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst,
stack_size, heap_size, error_buf, error_buf_size);
if (!ret) {
LOG_DEBUG("build a sub module list failed");
goto fail;
}
#endif
/* Initialize global info */
p = (uint8 *)module_inst + module_inst_struct_size
+ module_inst_mem_inst_size;
@ -1256,6 +1271,11 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
}
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
wasm_runtime_sub_module_deinstantiate(
(WASMModuleInstanceCommon *)module_inst);
#endif
if (module_inst->tables)
wasm_runtime_free(module_inst->tables);
@ -1276,12 +1296,10 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
->common.c_api_func_imports);
if (!is_sub_inst) {
#if WASM_ENABLE_LIBC_WASI != 0
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon *)module_inst);
#endif
#if WASM_ENABLE_WASI_NN != 0
wasi_nn_destroy(module_inst);
#endif
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
}
wasm_runtime_free(module_inst);
@ -1413,10 +1431,43 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
unsigned argc, uint32 argv[])
{
AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
AOTFuncType *func_type = function->u.func.func_type;
AOTFuncType *func_type = function->is_import_func
? function->u.func_import->func_type
: function->u.func.func_type;
uint32 result_count = func_type->result_count;
uint32 ext_ret_count = result_count > 1 ? result_count - 1 : 0;
bool ret;
void *func_ptr = function->is_import_func
? function->u.func_import->func_ptr_linked
: function->u.func.func_ptr;
#if WASM_ENABLE_MULTI_MODULE != 0
bh_list *sub_module_list_node = NULL;
const char *sub_inst_name = NULL;
const char *func_name = function->u.func_import->module_name;
if (function->is_import_func) {
sub_module_list_node =
((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list;
sub_module_list_node = bh_list_first_elem(sub_module_list_node);
while (sub_module_list_node) {
sub_inst_name =
((AOTSubModInstNode *)sub_module_list_node)->module_name;
if (strcmp(sub_inst_name, func_name) == 0) {
exec_env = wasm_runtime_get_exec_env_singleton(
(WASMModuleInstanceCommon *)((AOTSubModInstNode *)
sub_module_list_node)
->module_inst);
module_inst = (AOTModuleInstance *)exec_env->module_inst;
break;
}
sub_module_list_node = bh_list_elem_next(sub_module_list_node);
}
if (exec_env == NULL) {
wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst,
"create singleton exec_env failed");
return false;
}
}
#endif
if (argc < func_type->param_cell_num) {
char buf[108];
@ -1438,11 +1489,13 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
#endif
/* func pointer was looked up previously */
bh_assert(function->u.func.func_ptr != NULL);
bh_assert(func_ptr != NULL);
/* set thread handle and stack boundary */
wasm_exec_env_set_thread_info(exec_env);
/* set exec env so it can be later retrieved from instance */
((AOTModuleInstanceExtra *)module_inst->e)->common.cur_exec_env = exec_env;
if (ext_ret_count > 0) {
uint32 cell_num = 0, i;
uint8 *ext_ret_types = func_type->types + func_type->param_count + 1;
@ -1545,8 +1598,8 @@ aot_call_function(WASMExecEnv *exec_env, AOTFunctionInstance *function,
}
#endif
ret = invoke_native_internal(exec_env, function->u.func.func_ptr,
func_type, NULL, NULL, argv, argc, argv);
ret = invoke_native_internal(exec_env, func_ptr, func_type, NULL, NULL,
argv, argc, argv);
#if WASM_ENABLE_DUMP_CALL_STACK != 0
if (aot_copy_exception(module_inst, NULL)) {
@ -1938,7 +1991,10 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
void *attachment;
char buf[96];
bool ret = false;
#if WASM_ENABLE_MULTI_MODULE != 0
bh_list *sub_module_list_node = NULL;
const char *sub_inst_name = NULL;
#endif
bh_assert(func_idx < aot_module->import_func_count);
import_func = aot_module->import_funcs + func_idx;
@ -1962,6 +2018,28 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx, uint32 argc,
}
else if (!import_func->call_conv_raw) {
signature = import_func->signature;
#if WASM_ENABLE_MULTI_MODULE != 0
sub_module_list_node =
((AOTModuleInstanceExtra *)module_inst->e)->sub_module_inst_list;
sub_module_list_node = bh_list_first_elem(sub_module_list_node);
while (sub_module_list_node) {
sub_inst_name =
((AOTSubModInstNode *)sub_module_list_node)->module_name;
if (strcmp(sub_inst_name, import_func->module_name) == 0) {
exec_env = wasm_runtime_get_exec_env_singleton(
(WASMModuleInstanceCommon *)((AOTSubModInstNode *)
sub_module_list_node)
->module_inst);
break;
}
sub_module_list_node = bh_list_elem_next(sub_module_list_node);
}
if (exec_env == NULL) {
wasm_runtime_set_exception((WASMModuleInstanceCommon *)module_inst,
"create singleton exec_env failed");
goto fail;
}
#endif
ret =
wasm_runtime_invoke_native(exec_env, func_ptr, func_type, signature,
attachment, argv, argc, argv);
@ -2729,6 +2807,7 @@ aot_create_call_stack(struct WASMExecEnv *exec_env)
total_len += \
wasm_runtime_dump_line_buf_impl(line_buf, print, &buf, &len); \
if ((!print) && buf && (len == 0)) { \
exception_unlock(module_inst); \
return total_len; \
} \
} while (0)
@ -2751,6 +2830,7 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len)
return 0;
}
exception_lock(module_inst);
snprintf(line_buf, sizeof(line_buf), "\n");
PRINT_OR_DUMP();
@ -2759,6 +2839,7 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len)
uint32 line_length, i;
if (!bh_vector_get(module_inst->frames, n, &frame)) {
exception_unlock(module_inst);
return 0;
}
@ -2789,6 +2870,7 @@ aot_dump_call_stack(WASMExecEnv *exec_env, bool print, char *buf, uint32 len)
}
snprintf(line_buf, sizeof(line_buf), "\n");
PRINT_OR_DUMP();
exception_unlock(module_inst);
return total_len + 1;
}

View File

@ -90,6 +90,10 @@ typedef struct AOTFunctionInstance {
typedef struct AOTModuleInstanceExtra {
DefPointer(const uint32 *, stack_sizes);
WASMModuleInstanceExtraCommon common;
#if WASM_ENABLE_MULTI_MODULE != 0
bh_list sub_module_inst_list_head;
bh_list *sub_module_inst_list;
#endif
} AOTModuleInstanceExtra;
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
@ -229,6 +233,12 @@ typedef struct AOTModule {
WASIArguments wasi_args;
bool import_wasi_api;
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
/* TODO: add mutex for mutli-thread? */
bh_list import_module_list_head;
bh_list *import_module_list;
#endif
#if WASM_ENABLE_DEBUG_AOT != 0
void *elf_hdr;
uint32 elf_size;
@ -247,6 +257,10 @@ typedef struct AOTModule {
#define AOTTableInstance WASMTableInstance
#define AOTModuleInstance WASMModuleInstance
#if WASM_ENABLE_MULTI_MODULE != 0
#define AOTSubModInstNode WASMSubModInstNode
#endif
/* Target info, read from ELF header of object file */
typedef struct AOTTargetInfo {
/* Binary type, elf32l/elf32b/elf64l/elf64b */

View File

@ -53,7 +53,12 @@ get_target_symbol_map(uint32 *sym_num)
return target_sym_map;
}
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
#define BUILD_TARGET_AARCH64_DEFAULT "arm64"
#else
#define BUILD_TARGET_AARCH64_DEFAULT "aarch64v8"
#endif
void
get_current_target(char *target_buf, uint32 target_buf_size)
{

View File

@ -40,6 +40,7 @@ void __aeabi_ldivmod();
void __aeabi_memcpy();
void __aeabi_memmove();
void __aeabi_memset();
void __aeabi_memclr();
void __aeabi_uidiv();
void __aeabi_uidivmod();
void __aeabi_ul2d();
@ -126,6 +127,7 @@ static SymbolMap target_sym_map[] = {
REG_SYM(__aeabi_memcpy),
REG_SYM(__aeabi_memmove),
REG_SYM(__aeabi_memset),
REG_SYM(__aeabi_memclr),
REG_SYM(__aeabi_uidiv),
REG_SYM(__aeabi_uidivmod),
REG_SYM(__aeabi_ul2d),

View File

@ -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;
}

View 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 */

View File

@ -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)
{

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -363,6 +363,19 @@ check_type_compatible(uint8 src_type, uint8 dst_type)
} \
} while (0)
/* if val is a constant integer and its value is not undef or poison */
static inline bool
LLVMIsEfficientConstInt(LLVMValueRef val)
{
return LLVMIsConstant(val)
&& LLVMGetValueKind(val) == LLVMConstantIntValueKind
&& !LLVMIsUndef(val)
#if LLVM_VERSION_NUMBER >= 12
&& !LLVMIsPoison(addr)
#endif
;
}
bool
aot_compile_wasm(AOTCompContext *comp_ctx);

View File

@ -2703,6 +2703,7 @@ aot_resolve_stack_sizes(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
|| (obj_data->target_info.bin_type == AOT_COFF32_BIN_TYPE
&& !strncmp(name, "_", 1)
&& !strcmp(name + 1, aot_stack_sizes_alias_name)))) {
#if 0 /* cf. https://github.com/llvm/llvm-project/issues/67765 */
uint64 sz = LLVMGetSymbolSize(sym_itr);
if (sz != sizeof(uint32) * obj_data->func_count
/* sz of COFF64/COFF32 is 0, ignore the check */
@ -2711,6 +2712,7 @@ aot_resolve_stack_sizes(AOTCompContext *comp_ctx, AOTObjectData *obj_data)
aot_set_last_error("stack_sizes had unexpected size.");
goto fail;
}
#endif
uint64 addr = LLVMGetSymbolAddress(sym_itr);
if (!(sec_itr =
LLVMObjectFileCopySectionIterator(obj_data->binary))) {

View File

@ -4,6 +4,7 @@
*/
#include "aot_emit_control.h"
#include "aot_compiler.h"
#include "aot_emit_exception.h"
#include "../aot/aot_runtime.h"
#include "../interpreter/wasm_loader.h"
@ -234,13 +235,15 @@ handle_next_reachable_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
else {
/* Store extra return values to function parameters */
if (i != 0) {
LLVMValueRef res;
uint32 param_index = func_type->param_count + i;
if (!LLVMBuildStore(
comp_ctx->builder, block->result_phis[i],
LLVMGetParam(func_ctx->func, param_index))) {
if (!(res = LLVMBuildStore(
comp_ctx->builder, block->result_phis[i],
LLVMGetParam(func_ctx->func, param_index)))) {
aot_set_last_error("llvm build store failed.");
goto fail;
}
LLVMSetAlignment(res, 1);
}
}
}
@ -278,7 +281,7 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
AOTBlock *block)
{
uint32 i, param_index;
LLVMValueRef value;
LLVMValueRef value, br_inst;
uint64 size;
char name[32];
LLVMBasicBlockRef block_curr = CURR_BLOCK();
@ -326,7 +329,14 @@ push_aot_block_to_stack_and_pass_params(AOTCompContext *comp_ctx,
}
}
}
SET_BUILDER_POS(block_curr);
/* At this point, the branch instruction was already built to jump to
* the new BB, to avoid generating zext instruction from the popped
* operand that would come after branch instruction, we should position
* the builder before the last branch instruction */
br_inst = LLVMGetLastInstruction(block_curr);
bh_assert(LLVMGetInstructionOpcode(br_inst) == LLVMBr);
LLVMPositionBuilderBefore(comp_ctx->builder, br_inst);
/* Pop param values from current block's
* value stack and add to param phis.
@ -467,7 +477,7 @@ aot_compile_op_block(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
p_frame_ip);
}
if (!LLVMIsConstant(value)) {
if (!LLVMIsEfficientConstInt(value)) {
/* Compare value is not constant, create condition br IR */
/* Create entry block */
format_block_name(name, sizeof(name), block->block_index,
@ -833,7 +843,7 @@ aot_compile_op_br_if(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
}
if (!LLVMIsConstant(value_cmp)) {
if (!LLVMIsEfficientConstInt(value_cmp)) {
/* Compare value is not constant, create condition br IR */
if (!(block_dst = get_target_block(func_ctx, br_depth))) {
return false;
@ -970,7 +980,7 @@ aot_compile_op_br_table(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
}
if (!LLVMIsConstant(value_cmp)) {
if (!LLVMIsEfficientConstInt(value_cmp)) {
/* Compare value is not constant, create switch IR */
for (i = 0; i <= br_count; i++) {
target_block = get_target_block(func_ctx, br_depths[i]);
@ -1102,14 +1112,17 @@ aot_compile_op_return(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
if (block_func->result_count) {
/* Store extra result values to function parameters */
for (i = 0; i < block_func->result_count - 1; i++) {
LLVMValueRef res;
result_index = block_func->result_count - 1 - i;
POP(value, block_func->result_types[result_index]);
param_index = func_type->param_count + result_index;
if (!LLVMBuildStore(comp_ctx->builder, value,
LLVMGetParam(func_ctx->func, param_index))) {
if (!(res = LLVMBuildStore(
comp_ctx->builder, value,
LLVMGetParam(func_ctx->func, param_index)))) {
aot_set_last_error("llvm build store failed.");
goto fail;
}
LLVMSetAlignment(res, 1);
}
/* Return the first result value */
POP(value, block_func->result_types[0]);

View File

@ -4,6 +4,7 @@
*/
#include "aot_emit_memory.h"
#include "aot_compiler.h"
#include "aot_emit_exception.h"
#include "../aot/aot_runtime.h"
#include "aot_intrinsic.h"
@ -145,11 +146,7 @@ aot_check_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
* have been thrown when converting float to integer before
*/
/* return addres directly if constant offset and inside memory space */
if (LLVMIsConstant(addr) && !LLVMIsUndef(addr)
#if LLVM_VERSION_NUMBER >= 12
&& !LLVMIsPoison(addr)
#endif
) {
if (LLVMIsEfficientConstInt(addr)) {
uint64 mem_offset =
(uint64)LLVMConstIntGetZExtValue(addr) + (uint64)offset;
uint32 num_bytes_per_page =
@ -911,11 +908,7 @@ check_bulk_memory_overflow(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
* have been thrown when converting float to integer before
*/
/* return addres directly if constant offset and inside memory space */
if (!LLVMIsUndef(offset) && !LLVMIsUndef(bytes)
#if LLVM_VERSION_NUMBER >= 12
&& !LLVMIsPoison(offset) && !LLVMIsPoison(bytes)
#endif
&& LLVMIsConstant(offset) && LLVMIsConstant(bytes)) {
if (LLVMIsEfficientConstInt(offset) && LLVMIsEfficientConstInt(bytes)) {
uint64 mem_offset = (uint64)LLVMConstIntGetZExtValue(offset);
uint64 mem_len = (uint64)LLVMConstIntGetZExtValue(bytes);
uint32 num_bytes_per_page =

View File

@ -54,13 +54,13 @@
} while (0)
#if LLVM_VERSION_NUMBER >= 12
#define IS_CONST_ZERO(val) \
(!LLVMIsUndef(val) && !LLVMIsPoison(val) && LLVMIsConstant(val) \
&& ((is_i32 && (int32)LLVMConstIntGetZExtValue(val) == 0) \
#define IS_CONST_ZERO(val) \
(LLVMIsEfficientConstInt(val) \
&& ((is_i32 && (int32)LLVMConstIntGetZExtValue(val) == 0) \
|| (!is_i32 && (int64)LLVMConstIntGetSExtValue(val) == 0)))
#else
#define IS_CONST_ZERO(val) \
(!LLVMIsUndef(val) && LLVMIsConstant(val) \
(LLVMIsEfficientConstInt(val) \
&& ((is_i32 && (int32)LLVMConstIntGetZExtValue(val) == 0) \
|| (!is_i32 && (int64)LLVMConstIntGetSExtValue(val) == 0)))
#endif
@ -171,6 +171,15 @@
right = shift_count_mask; \
} while (0)
static bool
is_shift_count_mask_needed(AOTCompContext *comp_ctx, LLVMValueRef left,
LLVMValueRef right)
{
return (strcmp(comp_ctx->target_arch, "x86_64") != 0
&& strcmp(comp_ctx->target_arch, "i386") != 0)
|| (LLVMIsEfficientConstInt(left) && LLVMIsEfficientConstInt(right));
}
/* Call llvm constrained floating-point intrinsic */
static LLVMValueRef
call_llvm_float_experimental_constrained_intrinsic(AOTCompContext *comp_ctx,
@ -473,7 +482,7 @@ compile_int_div(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return aot_handle_next_reachable_block(comp_ctx, func_ctx, p_frame_ip);
}
if (LLVMIsConstant(right)) {
if (LLVMIsEfficientConstInt(right)) {
int64 right_val = (int64)LLVMConstIntGetSExtValue(right);
switch (right_val) {
case 0:
@ -728,8 +737,7 @@ compile_int_shl(AOTCompContext *comp_ctx, LLVMValueRef left, LLVMValueRef right,
{
LLVMValueRef res;
if (strcmp(comp_ctx->target_arch, "x86_64") != 0
&& strcmp(comp_ctx->target_arch, "i386") != 0)
if (is_shift_count_mask_needed(comp_ctx, left, right))
SHIFT_COUNT_MASK;
/* Build shl */
@ -744,8 +752,7 @@ compile_int_shr_s(AOTCompContext *comp_ctx, LLVMValueRef left,
{
LLVMValueRef res;
if (strcmp(comp_ctx->target_arch, "x86_64") != 0
&& strcmp(comp_ctx->target_arch, "i386") != 0)
if (is_shift_count_mask_needed(comp_ctx, left, right))
SHIFT_COUNT_MASK;
/* Build shl */
@ -760,8 +767,7 @@ compile_int_shr_u(AOTCompContext *comp_ctx, LLVMValueRef left,
{
LLVMValueRef res;
if (strcmp(comp_ctx->target_arch, "x86_64") != 0
&& strcmp(comp_ctx->target_arch, "i386") != 0)
if (is_shift_count_mask_needed(comp_ctx, left, right))
SHIFT_COUNT_MASK;
/* Build shl */

View File

@ -526,12 +526,18 @@ aot_add_precheck_function(AOTCompContext *comp_ctx, LLVMModuleRef module,
}
wasm_runtime_free(params);
params = NULL;
#if LLVM_VERSION_MAJOR < 17
if (aot_target_precheck_can_use_musttail(comp_ctx)) {
LLVMSetTailCallKind(retval, LLVMTailCallKindMustTail);
}
else {
LLVMSetTailCallKind(retval, LLVMTailCallKindTail);
}
#else
LLVMSetTailCall(retval, true);
#endif
if (ret_type == VOID_TYPE) {
if (!LLVMBuildRetVoid(b)) {
goto fail;
@ -2172,8 +2178,10 @@ bool
aot_compiler_init(void)
{
/* Initialize LLVM environment */
#if LLVM_VERSION_MAJOR < 17
LLVMInitializeCore(LLVMGetGlobalPassRegistry());
#endif
#if WASM_ENABLE_WAMR_COMPILER != 0
/* Init environment of all targets for AOT compiler */
LLVMInitializeAllTargetInfos();

View File

@ -15,15 +15,18 @@
#include "llvm-c/ExecutionEngine.h"
#include "llvm-c/Analysis.h"
#include "llvm-c/BitWriter.h"
#if LLVM_VERSION_MAJOR < 17
#include "llvm-c/Transforms/Utils.h"
#include "llvm-c/Transforms/Scalar.h"
#include "llvm-c/Transforms/Vectorize.h"
#include "llvm-c/Transforms/PassManagerBuilder.h"
#include "llvm-c/Initialization.h"
#endif
#include "llvm-c/Orc.h"
#include "llvm-c/Error.h"
#include "llvm-c/Support.h"
#include "llvm-c/Initialization.h"
#include "llvm-c/TargetMachine.h"
#include "llvm-c/LLJIT.h"
#if WASM_ENABLE_DEBUG_AOT != 0

View File

@ -5,11 +5,13 @@
#include <llvm/Passes/StandardInstrumentations.h>
#include <llvm/Support/Error.h>
#if LLVM_VERSION_MAJOR < 17
#include <llvm/ADT/None.h>
#include <llvm/ADT/Optional.h>
#include <llvm/ADT/Triple.h>
#endif
#include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/Twine.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Analysis/TargetTransformInfo.h>
#include <llvm/CodeGen/TargetPassConfig.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
@ -18,7 +20,9 @@
#include <llvm/Target/TargetMachine.h>
#include <llvm-c/Core.h>
#include <llvm-c/ExecutionEngine.h>
#if LLVM_VERSION_MAJOR < 17
#include <llvm-c/Initialization.h>
#endif
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/JITEventListener.h>
#include <llvm/ExecutionEngine/RTDyldMemoryManager.h>
@ -30,6 +34,9 @@
#include <llvm/IR/PassManager.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/ErrorHandling.h>
#if LLVM_VERSION_MAJOR >= 17
#include <llvm/Support/PGOOptions.h>
#endif
#include <llvm/Target/CodeGenCWrappers.h>
#include <llvm/Target/TargetMachine.h>
#include <llvm/Target/TargetOptions.h>
@ -55,6 +62,13 @@
using namespace llvm;
using namespace llvm::orc;
#if LLVM_VERSION_MAJOR >= 17
namespace llvm {
template<typename T>
using Optional = std::optional<T>;
}
#endif
LLVM_C_EXTERN_C_BEGIN
bool
@ -110,7 +124,14 @@ ExpandMemoryOpPass::run(Function &F, FunctionAnalysisManager &AM)
Memcpy->eraseFromParent();
}
else if (MemMoveInst *Memmove = dyn_cast<MemMoveInst>(MemCall)) {
#if LLVM_VERSION_MAJOR >= 17
Function *ParentFunc = Memmove->getParent()->getParent();
const TargetTransformInfo &TTI =
AM.getResult<TargetIRAnalysis>(*ParentFunc);
expandMemMoveAsLoop(Memmove, TTI);
#else
expandMemMoveAsLoop(Memmove);
#endif
Memmove->eraseFromParent();
}
else if (MemSetInst *Memset = dyn_cast<MemSetInst>(MemCall)) {
@ -181,6 +202,9 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
#else
Optional<PGOOptions> PGO = llvm::None;
#endif
// TODO
#if LLVM_VERSION_MAJOR < 17
if (comp_ctx->enable_llvm_pgo) {
/* Disable static counter allocation for value profiler,
it will be allocated by runtime */
@ -191,6 +215,7 @@ aot_apply_llvm_new_pass_manager(AOTCompContext *comp_ctx, LLVMModuleRef module)
else if (comp_ctx->use_prof_file) {
PGO = PGOOptions(comp_ctx->use_prof_file, "", "", PGOOptions::IRUse);
}
#endif
#ifdef DEBUG_PASS
PassInstrumentationCallbacks PIC;

View File

@ -4,8 +4,10 @@
*/
#include <llvm-c/TargetMachine.h>
#if LLVM_VERSION_MAJOR < 17
#include <llvm/ADT/None.h>
#include <llvm/ADT/Optional.h>
#endif
#include <llvm/IR/Instructions.h>
#if LLVM_VERSION_MAJOR >= 14
#include <llvm/MC/TargetRegistry.h>
@ -18,6 +20,13 @@
#include "aot_llvm_extra2.h"
#if LLVM_VERSION_MAJOR >= 17
namespace llvm {
template<typename T>
using Optional = std::optional<T>;
}
#endif
static llvm::Optional<llvm::Reloc::Model>
convert(LLVMRelocMode reloc_mode)
{

View File

@ -8,8 +8,10 @@
#include "llvm-c/OrcEE.h"
#include "llvm-c/TargetMachine.h"
#if LLVM_VERSION_MAJOR < 17
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#endif
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
@ -21,6 +23,13 @@
#include "aot_orc_extra.h"
#include "aot.h"
#if LLVM_VERSION_MAJOR >= 17
namespace llvm {
template<typename T>
using Optional = std::optional<T>;
}
#endif
using namespace llvm;
using namespace llvm::orc;
using GlobalValueSet = std::set<const GlobalValue *>;

View File

@ -217,10 +217,9 @@ aot_compile_simd_f64x2_nearest(AOTCompContext *comp_ctx,
static bool
simd_float_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
FloatArithmetic arith_op, LLVMTypeRef vector_type)
FloatArithmetic op, LLVMTypeRef vector_type)
{
LLVMValueRef lhs, rhs, result;
LLVMRealPredicate op = FLOAT_MIN == arith_op ? LLVMRealULT : LLVMRealUGT;
LLVMValueRef lhs, rhs, cmp, selected;
if (!(rhs =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs"))
@ -229,80 +228,240 @@ simd_float_cmp(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
return false;
}
if (!(result = LLVMBuildFCmp(comp_ctx->builder, op, lhs, rhs, "cmp"))) {
if (!(cmp = LLVMBuildFCmp(comp_ctx->builder,
op == FLOAT_MIN ? LLVMRealOLT : LLVMRealOGT, rhs,
lhs, "cmp"))) {
HANDLE_FAILURE("LLVMBuildFCmp");
return false;
}
if (!(result =
LLVMBuildSelect(comp_ctx->builder, result, lhs, rhs, "select"))) {
if (!(selected =
LLVMBuildSelect(comp_ctx->builder, cmp, rhs, lhs, "selected"))) {
HANDLE_FAILURE("LLVMBuildSelect");
return false;
}
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "result");
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, selected, "result");
}
static bool
simd_float_min(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef vector_type)
{
LLVMValueRef lhs, rhs, lhs_nan, rhs_nan, olt_ret, ogt_ret, or_ret, ret1,
ret2, ret3, ret4;
if (!(rhs =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs"))
|| !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type,
"lhs"))) {
return false;
}
if (!(lhs_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, lhs, lhs,
"lhs_nan"))) {
HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealUNO");
return false;
}
if (!(rhs_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, rhs, rhs,
"rhs_nan"))) {
HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealUNO");
return false;
}
if (!(olt_ret = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOLT, lhs, rhs,
"olt_ret"))) {
HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealOLT");
return false;
}
if (!(ogt_ret = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOGT, lhs, rhs,
"ogt_ret"))) {
HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealOGT");
return false;
}
/* lhs or rhs */
{
LLVMValueRef integer_l, integer_r, integer_or;
if (!(integer_l = LLVMBuildBitCast(comp_ctx->builder, lhs,
V128_i64x2_TYPE, "lhs_to_int"))) {
HANDLE_FAILURE("LLVMBuildBitCas");
return false;
}
if (!(integer_r = LLVMBuildBitCast(comp_ctx->builder, rhs,
V128_i64x2_TYPE, "rhs_to_int"))) {
HANDLE_FAILURE("LLVMBuildBitCas");
return false;
}
if (!(integer_or =
LLVMBuildOr(comp_ctx->builder, integer_l, integer_r, "or"))) {
HANDLE_FAILURE("LLVMBuildOr");
return false;
}
if (!(or_ret = LLVMBuildBitCast(comp_ctx->builder, integer_or,
vector_type, "holder"))) {
HANDLE_FAILURE("LLVMBuildBitCast");
return false;
}
}
if (!(ret1 = LLVMBuildSelect(comp_ctx->builder, olt_ret, lhs, or_ret,
"sel_olt"))) {
HANDLE_FAILURE("LLVMBuildSelect");
return false;
}
if (!(ret2 = LLVMBuildSelect(comp_ctx->builder, ogt_ret, rhs, ret1,
"sel_ogt"))) {
HANDLE_FAILURE("LLVMBuildSelect");
return false;
}
if (!(ret3 = LLVMBuildSelect(comp_ctx->builder, lhs_nan, lhs, ret2,
"sel_lhs_nan"))) {
HANDLE_FAILURE("LLVMBuildSelect");
return false;
}
if (!(ret4 = LLVMBuildSelect(comp_ctx->builder, rhs_nan, rhs, ret3,
"sel_rhs_nan"))) {
HANDLE_FAILURE("LLVMBuildSelect");
return false;
}
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, ret4, "result");
}
static bool
simd_float_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef vector_type)
{
LLVMValueRef lhs, rhs, lhs_nan, rhs_nan, olt_ret, ogt_ret, and_ret, ret1,
ret2, ret3, ret4;
if (!(rhs =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs"))
|| !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type,
"lhs"))) {
return false;
}
if (!(lhs_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, lhs, lhs,
"lhs_nan"))) {
HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealUNO");
return false;
}
if (!(rhs_nan = LLVMBuildFCmp(comp_ctx->builder, LLVMRealUNO, rhs, rhs,
"rhs_nan"))) {
HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealUNO");
return false;
}
if (!(olt_ret = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOLT, lhs, rhs,
"olt_ret"))) {
HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealOLT");
return false;
}
if (!(ogt_ret = LLVMBuildFCmp(comp_ctx->builder, LLVMRealOGT, lhs, rhs,
"ogt_ret"))) {
HANDLE_FAILURE("LLVMBuildFCmp + LLVMRealOGT");
return false;
}
/* lhs and rhs */
{
LLVMValueRef integer_l, integer_r, integer_and;
if (!(integer_l = LLVMBuildBitCast(comp_ctx->builder, lhs,
V128_i64x2_TYPE, "lhs_to_int"))) {
HANDLE_FAILURE("LLVMBuildBitCas");
return false;
}
if (!(integer_r = LLVMBuildBitCast(comp_ctx->builder, rhs,
V128_i64x2_TYPE, "rhs_to_int"))) {
HANDLE_FAILURE("LLVMBuildBitCas");
return false;
}
if (!(integer_and = LLVMBuildAnd(comp_ctx->builder, integer_l,
integer_r, "and"))) {
HANDLE_FAILURE("LLVMBuildOr");
return false;
}
if (!(and_ret = LLVMBuildBitCast(comp_ctx->builder, integer_and,
vector_type, "holder"))) {
HANDLE_FAILURE("LLVMBuildBitCast");
return false;
}
}
if (!(ret1 = LLVMBuildSelect(comp_ctx->builder, ogt_ret, lhs, and_ret,
"sel_ogt"))) {
HANDLE_FAILURE("LLVMBuildSelect");
return false;
}
if (!(ret2 = LLVMBuildSelect(comp_ctx->builder, olt_ret, rhs, ret1,
"sel_olt"))) {
HANDLE_FAILURE("LLVMBuildSelect");
return false;
}
if (!(ret3 = LLVMBuildSelect(comp_ctx->builder, lhs_nan, lhs, ret2,
"sel_lhs_nan"))) {
HANDLE_FAILURE("LLVMBuildSelect");
return false;
}
if (!(ret4 = LLVMBuildSelect(comp_ctx->builder, rhs_nan, rhs, ret3,
"sel_rhs_nan"))) {
HANDLE_FAILURE("LLVMBuildSelect");
return false;
}
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, ret4, "result");
}
/*TODO: sugggest non-IA platforms check with "llvm.minimum.*" and
* "llvm.maximum.*" firstly */
bool
aot_compile_simd_f32x4_min_max(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, bool run_min)
{
return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX,
V128_f32x4_TYPE);
return run_min ? simd_float_min(comp_ctx, func_ctx, V128_f32x4_TYPE)
: simd_float_max(comp_ctx, func_ctx, V128_f32x4_TYPE);
}
bool
aot_compile_simd_f64x2_min_max(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, bool run_min)
{
return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX,
V128_f64x2_TYPE);
}
static bool
simd_float_pmin_max(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
LLVMTypeRef vector_type, const char *intrinsic)
{
LLVMValueRef lhs, rhs, result;
LLVMTypeRef param_types[2];
param_types[0] = vector_type;
param_types[1] = vector_type;
if (!(rhs =
simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type, "rhs"))
|| !(lhs = simd_pop_v128_and_bitcast(comp_ctx, func_ctx, vector_type,
"lhs"))) {
return false;
}
if (!(result =
aot_call_llvm_intrinsic(comp_ctx, func_ctx, intrinsic,
vector_type, param_types, 2, lhs, rhs))) {
return false;
}
return simd_bitcast_and_push_v128(comp_ctx, func_ctx, result, "result");
return run_min ? simd_float_min(comp_ctx, func_ctx, V128_f64x2_TYPE)
: simd_float_max(comp_ctx, func_ctx, V128_f64x2_TYPE);
}
bool
aot_compile_simd_f32x4_pmin_pmax(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, bool run_min)
{
return simd_float_pmin_max(comp_ctx, func_ctx, V128_f32x4_TYPE,
run_min ? "llvm.minnum.v4f32"
: "llvm.maxnum.v4f32");
return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX,
V128_f32x4_TYPE);
}
bool
aot_compile_simd_f64x2_pmin_pmax(AOTCompContext *comp_ctx,
AOTFuncContext *func_ctx, bool run_min)
{
return simd_float_pmin_max(comp_ctx, func_ctx, V128_f64x2_TYPE,
run_min ? "llvm.minnum.v2f64"
: "llvm.maxnum.v2f64");
return simd_float_cmp(comp_ctx, func_ctx, run_min ? FLOAT_MIN : FLOAT_MAX,
V128_f64x2_TYPE);
}
bool

View File

@ -298,7 +298,15 @@ fail:
/* macros for integer binary operations (ibinop) */
#if defined(__GNUC__)
#define NO_SANITIZER_INTEGER \
__attribute__((no_sanitize("signed-integer-overflow")))
#else
#define NO_SANITIZER_INTEGER
#endif
#define __DEF_BI_INT_CONST_OPS(bits, opname, op) \
NO_SANITIZER_INTEGER \
static int##bits do_i##bits##_const_##opname(int##bits lhs, int##bits rhs) \
{ \
return lhs op rhs; \

View File

@ -311,7 +311,7 @@ wasm_runtime_is_xip_file(const uint8_t *buf, uint32_t size);
/**
* Callback to load a module file into a buffer in multi-module feature
*/
typedef bool (*module_reader)(const char *module_name,
typedef bool (*module_reader)(package_type_t module_type,const char *module_name,
uint8_t **p_buffer, uint32_t *p_size);
/**
@ -894,6 +894,27 @@ wasm_runtime_set_exception(wasm_module_inst_t module_inst,
WASM_RUNTIME_API_EXTERN void
wasm_runtime_clear_exception(wasm_module_inst_t module_inst);
/**
* Terminate the WASM module instance.
*
* This function causes the module instance fail as if it raised a trap.
*
* This is intended to be used in situations like:
*
* - A thread is executing the WASM module instance
* (eg. it's in the middle of `wasm_application_execute_main`)
*
* - Another thread has a copy of `wasm_module_inst_t` of
* the module instance and wants to terminate it asynchronously.
*
* This function is provided only when WAMR is built with threading enabled.
* (`WASM_ENABLE_THREAD_MGR=1`)
*
* @param module_inst the WASM module instance
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_terminate(wasm_module_inst_t module_inst);
/**
* Set custom data to WASM module instance.
* Note:
@ -1439,6 +1460,136 @@ WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_import_global_linked(const char *module_name,
const char *global_name);
typedef enum {
INTERNAL_ERROR,
MAX_SIZE_REACHED,
} enlarge_memory_error_reason_t;
typedef void (*enlarge_memory_error_callback_t)(
uint32_t inc_page_count, uint64_t current_memory_size,
uint32_t memory_index, enlarge_memory_error_reason_t failure_reason,
wasm_module_inst_t instance, wasm_exec_env_t exec_env,
void* user_data);
/**
* Setup callback invoked when memory.grow fails
*/
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_enlarge_mem_error_callback(
const enlarge_memory_error_callback_t callback, void *user_data);
/*
* module instance context APIs
* wasm_runtime_create_context_key
* wasm_runtime_destroy_context_key
* wasm_runtime_set_context
* wasm_runtime_set_context_spread
* wasm_runtime_get_context
*
* This set of APIs is intended to be used by an embedder which provides
* extra sets of native functions, which need per module instance state
* and are maintained outside of the WAMR tree.
*
* It's modelled after the pthread specific API.
*
* wasm_runtime_set_context_spread is similar to
* wasm_runtime_set_context, except that
* wasm_runtime_set_context_spread applies the change
* to all threads in the cluster.
* It's an undefined behavior if multiple threads in a cluster call
* wasm_runtime_set_context_spread on the same key
* simultaneously. It's a caller's resposibility to perform necessary
* serialization if necessary. For example:
*
* if (wasm_runtime_get_context(inst, key) == NULL) {
* newctx = alloc_and_init(...);
* lock(some_lock);
* if (wasm_runtime_get_context(inst, key) == NULL) {
* // this thread won the race
* wasm_runtime_set_context_spread(inst, key, newctx);
* newctx = NULL;
* }
* unlock(some_lock);
* if (newctx != NULL) {
* // this thread lost the race, free it
* cleanup_and_free(newctx);
* }
* }
*
* Note: dynamic key create/destroy while instances are live is not
* implemented as of writing this.
* it's caller's resposibility to ensure destorying all module instances
* before calling wasm_runtime_create_context_key or
* wasm_runtime_destroy_context_key.
* otherwise, it's an undefined behavior.
*
* Note about threads:
* - When spawning a thread, the contexts (the pointers given to
* wasm_runtime_set_context) are copied from the parent
* instance.
* - The destructor is called only on the main instance.
*/
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_create_context_key(
void (*dtor)(wasm_module_inst_t inst, void *ctx));
WASM_RUNTIME_API_EXTERN void
wasm_runtime_destroy_context_key(void *key);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_context(wasm_module_inst_t inst, void *key,
void *ctx);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_set_context_spread(wasm_module_inst_t inst, void *key,
void *ctx);
WASM_RUNTIME_API_EXTERN void *
wasm_runtime_get_context(wasm_module_inst_t inst, void *key);
/*
* wasm_runtime_begin_blocking_op/wasm_runtime_end_blocking_op
*
* These APIs are intended to be used by the implementations of
* host functions. It wraps an operation which possibly blocks for long
* to prepare for async termination.
*
* eg.
*
* if (!wasm_runtime_begin_blocking_op(exec_env)) {
* return EINTR;
* }
* ret = possibly_blocking_op();
* wasm_runtime_end_blocking_op(exec_env);
* return ret;
*
* If threading support (WASM_ENABLE_THREAD_MGR) is not enabled,
* these functions are no-op.
*
* If the underlying platform support (OS_ENABLE_WAKEUP_BLOCKING_OP) is
* not available, these functions are no-op. In that case, the runtime
* might not terminate a blocking thread in a timely manner.
*
* If the underlying platform support is available, it's used to wake up
* the thread for async termination. The expectation here is that a
* `os_wakeup_blocking_op` call makes the blocking operation
* (`possibly_blocking_op` in the above example) return in a timely manner.
*
* The actual wake up mechanism used by `os_wakeup_blocking_op` is
* platform-dependent. It might impose some platform-dependent restrictions
* on the implementation of the blocking opearation.
*
* For example, on POSIX-like platforms, a signal (by default SIGUSR1) is
* used. The signal delivery configurations (eg. signal handler, signal mask,
* etc) for the signal are set up by the runtime. You can change the signal
* to use for this purpose by calling os_set_signal_number_for_blocking_op
* before the runtime initialization.
*/
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_begin_blocking_op(wasm_exec_env_t exec_env);
WASM_RUNTIME_API_EXTERN void
wasm_runtime_end_blocking_op(wasm_exec_env_t exec_env);
/* clang-format on */
#ifdef __cplusplus

View File

@ -1418,6 +1418,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
while (node_cache) {
node_next = bh_list_elem_next(node_cache);
if (node_cache->br_table_op_addr == frame_ip - 1) {
if (lidx > node_cache->br_count)
lidx = node_cache->br_count;
depth = node_cache->br_depths[lidx];
goto label_pop_csp_n;
}
@ -4209,7 +4211,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);
unsigned i;
bool copy_argv_from_frame = true;
char exception[EXCEPTION_BUF_LEN];
if (argc < function->param_cell_num) {
char buf[128];
@ -4342,8 +4343,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
wasm_interp_dump_call_stack(exec_env, true, NULL, 0);
}
#endif
wasm_copy_exception(module_inst, exception);
LOG_DEBUG("meet an exception %s", exception);
}
wasm_exec_env_set_cur_frame(exec_env, prev_frame);

View File

@ -3945,7 +3945,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
/* This frame won't be used by JITed code, so only allocate interp
frame here. */
unsigned frame_size = wasm_interp_interp_frame_size(all_cell_num);
char exception[EXCEPTION_BUF_LEN];
if (argc < function->param_cell_num) {
char buf[128];
@ -4030,8 +4029,6 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
wasm_interp_dump_call_stack(exec_env, true, NULL, 0);
}
#endif
wasm_copy_exception(module_inst, exception);
LOG_DEBUG("meet an exception %s", exception);
}
wasm_exec_env_set_cur_frame(exec_env, prev_frame);

View File

@ -694,34 +694,10 @@ wasm_loader_find_export(const WASMModule *module, const char *module_name,
const char *field_name, uint8 export_kind,
char *error_buf, uint32 error_buf_size)
{
WASMExport *export;
uint32 i;
for (i = 0, export = module->exports; i < module->export_count;
++i, ++export) {
/**
* need to consider a scenario that different kinds of exports
* may have the same name, like
* (table (export "m1" "exported") 10 funcref)
* (memory (export "m1" "exported") 10)
**/
if (export->kind == export_kind && !strcmp(field_name, export->name)) {
break;
}
}
if (i == module->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");
return NULL;
}
(void)module_name;
/* since there is a validation in load_export_section(), it is for sure
* export->index is valid*/
WASMExport *export =
loader_find_export((WASMModuleCommon *)module, module_name, field_name,
export_kind, error_buf, error_buf_size);
;
return export;
}
#endif
@ -912,152 +888,6 @@ wasm_loader_resolve_global(const char *module_name, const char *global_name,
return global;
}
static WASMModule *
search_sub_module(const WASMModule *parent_module, const char *sub_module_name)
{
WASMRegisteredModule *node =
bh_list_first_elem(parent_module->import_module_list);
while (node && strcmp(sub_module_name, node->module_name)) {
node = bh_list_elem_next(node);
}
return node ? (WASMModule *)node->module : NULL;
}
static bool
register_sub_module(const WASMModule *parent_module,
const char *sub_module_name, WASMModule *sub_module)
{
/* register sub_module into its parent sub module list */
WASMRegisteredModule *node = NULL;
bh_list_status ret;
if (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 = (WASMModuleCommon *)sub_module;
ret = bh_list_insert(parent_module->import_module_list, node);
bh_assert(BH_LIST_SUCCESS == ret);
(void)ret;
return true;
}
static WASMModule *
load_depended_module(const WASMModule *parent_module,
const char *sub_module_name, char *error_buf,
uint32 error_buf_size)
{
WASMModule *sub_module = NULL;
bool ret = false;
uint8 *buffer = NULL;
uint32 buffer_size = 0;
const module_reader reader = wasm_runtime_get_module_reader();
const module_destroyer destroyer = wasm_runtime_get_module_destroyer();
/* check the registered module list of the parent */
sub_module = 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 =
(WASMModule *)wasm_runtime_find_module_registered(sub_module_name);
if (sub_module) {
LOG_DEBUG("%s has been loaded", sub_module_name);
goto register_sub_module;
}
LOG_VERBOSE("loading %s", sub_module_name);
if (!reader) {
set_error_buf_v(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(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(sub_module_name, &buffer, &buffer_size);
if (!ret) {
LOG_DEBUG("read the file of %s failed", sub_module_name);
set_error_buf_v(error_buf, error_buf_size, "unknown import",
sub_module_name);
goto delete_loading_module;
}
sub_module =
wasm_loader_load(buffer, buffer_size, false, error_buf, error_buf_size);
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 */
register_sub_module:
ret = register_sub_module(parent_module, sub_module_name, sub_module);
if (!ret) {
set_error_buf_v(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_loader_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;
}
#endif /* end of WASM_ENABLE_MULTI_MODULE */
static bool
@ -1104,8 +934,9 @@ load_function_import(const uint8 **p_buf, const uint8 *buf_end,
#if WASM_ENABLE_MULTI_MODULE != 0
else {
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
sub_module = load_depended_module(parent_module, sub_module_name,
error_buf, error_buf_size);
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
if (!sub_module) {
return false;
}
@ -1193,8 +1024,9 @@ load_table_import(const uint8 **p_buf, const uint8 *buf_end,
#if WASM_ENABLE_MULTI_MODULE != 0
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
sub_module = load_depended_module(parent_module, sub_module_name,
error_buf, error_buf_size);
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
if (!sub_module) {
return false;
}
@ -1327,8 +1159,9 @@ load_memory_import(const uint8 **p_buf, const uint8 *buf_end,
#if WASM_ENABLE_MULTI_MODULE != 0
if (!wasm_runtime_is_built_in_module(sub_module_name)) {
sub_module = load_depended_module(parent_module, sub_module_name,
error_buf, error_buf_size);
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
if (!sub_module) {
return false;
}
@ -1427,8 +1260,9 @@ load_global_import(const uint8 **p_buf, const uint8 *buf_end,
#if WASM_ENABLE_MULTI_MODULE != 0
if (!global->is_linked
&& !wasm_runtime_is_built_in_module(sub_module_name)) {
sub_module = load_depended_module(parent_module, sub_module_name,
error_buf, error_buf_size);
sub_module = (WASMModule *)wasm_runtime_load_depended_module(
(WASMModuleCommon *)parent_module, sub_module_name, error_buf,
error_buf_size);
if (!sub_module) {
return false;
}
@ -5476,6 +5310,7 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
return true;
}
#if WASM_ENABLE_FAST_INTERP == 0
static bool
wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt,
uint8 type_push, uint8 type_pop, char *error_buf,
@ -5490,6 +5325,7 @@ wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt,
return false;
return true;
}
#endif
static bool
wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type,
@ -6166,27 +6002,6 @@ wasm_loader_pop_frame_offset(WASMLoaderContext *ctx, uint8 type,
return true;
}
static bool
wasm_loader_push_pop_frame_offset(WASMLoaderContext *ctx, uint8 pop_cnt,
uint8 type_push, uint8 type_pop,
bool disable_emit, int16 operand_offset,
char *error_buf, uint32 error_buf_size)
{
uint8 i;
for (i = 0; i < pop_cnt; i++) {
if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf,
error_buf_size))
return false;
}
if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit,
operand_offset, error_buf,
error_buf_size))
return false;
return true;
}
static bool
wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type,
bool disable_emit, int16 operand_offset,
@ -6220,12 +6035,24 @@ wasm_loader_push_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 pop_cnt,
bool disable_emit, int16 operand_offset,
char *error_buf, uint32 error_buf_size)
{
if (!wasm_loader_push_pop_frame_offset(ctx, pop_cnt, type_push, type_pop,
disable_emit, operand_offset,
error_buf, error_buf_size))
uint8 i;
for (i = 0; i < pop_cnt; i++) {
if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf,
error_buf_size))
return false;
if (!wasm_loader_pop_frame_ref(ctx, type_pop, error_buf,
error_buf_size))
return false;
}
if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit,
operand_offset, error_buf,
error_buf_size))
return false;
if (!wasm_loader_push_pop_frame_ref(ctx, pop_cnt, type_push, type_pop,
error_buf, error_buf_size))
if (!wasm_loader_push_frame_ref(ctx, type_push, error_buf, error_buf_size))
return false;
return true;

View File

@ -3937,6 +3937,7 @@ wasm_loader_pop_frame_ref(WASMLoaderContext *ctx, uint8 type, char *error_buf,
return true;
}
#if WASM_ENABLE_FAST_INTERP == 0
static bool
wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt,
uint8 type_push, uint8 type_pop, char *error_buf,
@ -3951,6 +3952,7 @@ wasm_loader_push_pop_frame_ref(WASMLoaderContext *ctx, uint8 pop_cnt,
return false;
return true;
}
#endif
static bool
wasm_loader_push_frame_csp(WASMLoaderContext *ctx, uint8 label_type,
@ -4608,25 +4610,6 @@ wasm_loader_pop_frame_offset(WASMLoaderContext *ctx, uint8 type,
return true;
}
static bool
wasm_loader_push_pop_frame_offset(WASMLoaderContext *ctx, uint8 pop_cnt,
uint8 type_push, uint8 type_pop,
bool disable_emit, int16 operand_offset,
char *error_buf, uint32 error_buf_size)
{
for (int i = 0; i < pop_cnt; i++) {
if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf,
error_buf_size))
return false;
}
if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit,
operand_offset, error_buf,
error_buf_size))
return false;
return true;
}
static bool
wasm_loader_push_frame_ref_offset(WASMLoaderContext *ctx, uint8 type,
bool disable_emit, int16 operand_offset,
@ -4660,12 +4643,24 @@ wasm_loader_push_pop_frame_ref_offset(WASMLoaderContext *ctx, uint8 pop_cnt,
bool disable_emit, int16 operand_offset,
char *error_buf, uint32 error_buf_size)
{
if (!wasm_loader_push_pop_frame_offset(ctx, pop_cnt, type_push, type_pop,
disable_emit, operand_offset,
error_buf, error_buf_size))
uint8 i;
for (i = 0; i < pop_cnt; i++) {
if (!wasm_loader_pop_frame_offset(ctx, type_pop, error_buf,
error_buf_size))
return false;
if (!wasm_loader_pop_frame_ref(ctx, type_pop, error_buf,
error_buf_size))
return false;
}
if (!wasm_loader_push_frame_offset(ctx, type_push, disable_emit,
operand_offset, error_buf,
error_buf_size))
return false;
if (!wasm_loader_push_pop_frame_ref(ctx, pop_cnt, type_push, type_pop,
error_buf, error_buf_size))
if (!wasm_loader_push_frame_ref(ctx, type_push, error_buf, error_buf_size))
return false;
return true;

View File

@ -51,11 +51,15 @@ set_error_buf_v(char *error_buf, uint32 error_buf_size, const char *format, ...)
}
WASMModule *
wasm_load(uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size)
wasm_load(uint8 *buf, uint32 size,
#if WASM_ENABLE_MULTI_MODULE != 0
bool main_module,
#endif
char *error_buf, uint32 error_buf_size)
{
return wasm_loader_load(buf, size,
#if WASM_ENABLE_MULTI_MODULE != 0
true,
main_module,
#endif
error_buf, error_buf_size);
}
@ -1266,78 +1270,6 @@ execute_free_function(WASMModuleInstance *module_inst, WASMExecEnv *exec_env,
return ret;
}
#if WASM_ENABLE_MULTI_MODULE != 0
static bool
sub_module_instantiate(WASMModule *module, WASMModuleInstance *module_inst,
uint32 stack_size, uint32 heap_size, char *error_buf,
uint32 error_buf_size)
{
bh_list *sub_module_inst_list = module_inst->e->sub_module_inst_list;
WASMRegisteredModule *sub_module_list_node =
bh_list_first_elem(module->import_module_list);
while (sub_module_list_node) {
WASMSubModInstNode *sub_module_inst_list_node = NULL;
WASMModule *sub_module = (WASMModule *)sub_module_list_node->module;
WASMModuleInstance *sub_module_inst = NULL;
sub_module_inst =
wasm_instantiate(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);
goto failed;
}
sub_module_inst_list_node = runtime_malloc(sizeof(WASMSubModInstNode),
error_buf, error_buf_size);
if (!sub_module_inst_list_node) {
LOG_DEBUG("Malloc WASMSubModInstNode failed, SZ:%d",
sizeof(WASMSubModInstNode));
goto failed;
}
sub_module_inst_list_node->module_inst = 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);
continue;
failed:
if (sub_module_inst_list_node) {
bh_list_remove(sub_module_inst_list, sub_module_inst_list_node);
wasm_runtime_free(sub_module_inst_list_node);
}
if (sub_module_inst)
wasm_deinstantiate(sub_module_inst, false);
return false;
}
return true;
}
static void
sub_module_deinstantiate(WASMModuleInstance *module_inst)
{
bh_list *list = module_inst->e->sub_module_inst_list;
WASMSubModInstNode *node = bh_list_first_elem(list);
while (node) {
WASMSubModInstNode *next_node = bh_list_elem_next(node);
bh_list_remove(list, node);
wasm_deinstantiate(node->module_inst, false);
wasm_runtime_free(node);
node = next_node;
}
}
#endif
static bool
check_linked_symbol(WASMModuleInstance *module_inst, char *error_buf,
uint32 error_buf_size)
@ -1714,8 +1646,9 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
#if WASM_ENABLE_MULTI_MODULE != 0
module_inst->e->sub_module_inst_list =
&module_inst->e->sub_module_inst_list_head;
ret = sub_module_instantiate(module, module_inst, stack_size, heap_size,
error_buf, error_buf_size);
ret = wasm_runtime_sub_module_instantiate(
(WASMModuleCommon *)module, (WASMModuleInstanceCommon *)module_inst,
stack_size, heap_size, error_buf, error_buf_size);
if (!ret) {
LOG_DEBUG("build a sub module list failed");
goto fail;
@ -2198,7 +2131,8 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
#endif
#if WASM_ENABLE_MULTI_MODULE != 0
sub_module_deinstantiate(module_inst);
wasm_runtime_sub_module_deinstantiate(
(WASMModuleInstanceCommon *)module_inst);
#endif
if (module_inst->memory_count > 0)
@ -2234,12 +2168,10 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
wasm_runtime_free(module_inst->e->common.c_api_func_imports);
if (!is_sub_inst) {
#if WASM_ENABLE_LIBC_WASI != 0
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon *)module_inst);
#endif
#if WASM_ENABLE_WASI_NN != 0
wasi_nn_destroy(module_inst);
#endif
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
}
wasm_runtime_free(module_inst);
@ -2401,6 +2333,9 @@ wasm_call_function(WASMExecEnv *exec_env, WASMFunctionInstance *function,
/* set thread handle and stack boundary */
wasm_exec_env_set_thread_info(exec_env);
/* set exec env so it can be later retrieved from instance */
module_inst->e->common.cur_exec_env = exec_env;
interp_call_wasm(module_inst, exec_env, function, argc, argv);
return !wasm_copy_exception(module_inst, NULL);
}
@ -2981,6 +2916,7 @@ wasm_interp_create_call_stack(struct WASMExecEnv *exec_env)
total_len += \
wasm_runtime_dump_line_buf_impl(line_buf, print, &buf, &len); \
if ((!print) && buf && (len == 0)) { \
exception_unlock(module_inst); \
return total_len; \
} \
} while (0)
@ -3005,6 +2941,7 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf,
return 0;
}
exception_lock(module_inst);
snprintf(line_buf, sizeof(line_buf), "\n");
PRINT_OR_DUMP();
@ -3013,6 +2950,7 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf,
uint32 line_length, i;
if (!bh_vector_get(module_inst->frames, n, &frame)) {
exception_unlock(module_inst);
return 0;
}
@ -3043,6 +2981,7 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env, bool print, char *buf,
}
snprintf(line_buf, sizeof(line_buf), "\n");
PRINT_OR_DUMP();
exception_unlock(module_inst);
return total_len + 1;
}

View File

@ -212,7 +212,10 @@ typedef struct CApiFuncImport {
/* The common part of WASMModuleInstanceExtra and AOTModuleInstanceExtra */
typedef struct WASMModuleInstanceExtraCommon {
void *contexts[WASM_MAX_INSTANCE_CONTEXTS];
CApiFuncImport *c_api_func_imports;
/* pointer to the exec env currently used */
WASMExecEnv *cur_exec_env;
#if WASM_CONFIGUABLE_BOUNDS_CHECKS != 0
/* Disable bounds checks or not */
bool disable_bounds_checks;
@ -297,12 +300,8 @@ struct WASMModuleInstance {
it denotes `AOTModule *` */
DefPointer(WASMModule *, module);
#if WASM_ENABLE_LIBC_WASI
/* WASI context */
DefPointer(WASIContext *, wasi_ctx);
#else
DefPointer(void *, wasi_ctx);
#endif
DefPointer(void *, used_to_be_wasi_ctx); /* unused */
DefPointer(WASMExecEnv *, exec_env_singleton);
/* Array of function pointers to import functions,
not available in AOTModuleInstance */
@ -397,7 +396,11 @@ wasm_get_func_code_end(WASMFunctionInstance *func)
}
WASMModule *
wasm_load(uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size);
wasm_load(uint8 *buf, uint32 size,
#if WASM_ENABLE_MULTI_MODULE != 0
bool main_module,
#endif
char *error_buf, uint32 error_buf_size);
WASMModule *
wasm_load_from_sections(WASMSection *section_list, char *error_buf,
@ -668,6 +671,16 @@ void
wasm_propagate_wasi_args(WASMModule *module);
#endif
#if WASM_ENABLE_THREAD_MGR != 0
void
exception_lock(WASMModuleInstance *module_inst);
void
exception_unlock(WASMModuleInstance *module_inst);
#else
#define exception_lock(module_inst) (void)(module_inst)
#define exception_unlock(module_inst) (void)(module_inst)
#endif
#ifdef __cplusplus
}
#endif

View File

@ -559,9 +559,6 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
uint32 thread_handle;
uint32 stack_size = 8192;
int32 ret = -1;
#if WASM_ENABLE_LIBC_WASI != 0
WASIContext *wasi_ctx;
#endif
bh_assert(module);
bh_assert(module_inst);
@ -588,11 +585,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
wasm_runtime_set_custom_data_internal(
new_module_inst, wasm_runtime_get_custom_data(module_inst));
#if WASM_ENABLE_LIBC_WASI != 0
wasi_ctx = get_wasi_ctx(module_inst);
if (wasi_ctx)
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
#endif
wasm_native_inherit_contexts(new_module_inst, module_inst);
if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst)))
goto fail;

View File

@ -23,7 +23,7 @@ include(FetchContent)
set(RATS_BUILD_MODE "sgx"
CACHE INTERNAL "Select build mode for librats(host|occlum|sgxwasm)")
set(RATS_INSTALL_PATH "${CMAKE_BINARY_DIR}/librats" CACHE INTERNAL "")
set(BUILD_SAMPLES OFF)
set(BUILD_SAMPLES OFF CACHE BOOL "Disable de compilation of the librats samples" FORCE)
FetchContent_Declare(
librats

View File

@ -80,9 +80,6 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
int32 thread_id;
uint32 stack_size = 8192;
int32 ret = -1;
#if WASM_ENABLE_LIBC_WASI != 0
WASIContext *wasi_ctx;
#endif
bh_assert(module);
bh_assert(module_inst);
@ -99,11 +96,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst)))
goto thread_preparation_fail;
#if WASM_ENABLE_LIBC_WASI != 0
wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
if (wasi_ctx)
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
#endif
wasm_native_inherit_contexts(new_module_inst, module_inst);
start_func = wasm_runtime_lookup_function(new_module_inst,
THREAD_START_FUNCTION, NULL);

View File

@ -0,0 +1,66 @@
#!/bin/bash
#
# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
set -eo pipefail
CC=${CC:=/opt/wasi-sdk/bin/clang}
WAMR_DIR=../../../../..
show_usage() {
echo "Usage: $0 [--sysroot PATH_TO_SYSROOT]"
echo "--sysroot PATH_TO_SYSROOT specify to build with custom sysroot for wasi-libc"
}
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
--sysroot)
sysroot_path="$2"
shift
shift
;;
--help)
show_usage
exit
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
rm -rf *.wasm
rm -rf *.aot
for test_c in *.c; do
test_wasm="$(basename $test_c .c).wasm"
if [[ -n "$sysroot_path" ]]; then
if [ ! -d "$sysroot_path" ]; then
echo "Directory $sysroot_path doesn't exist. Aborting"
exit 1
fi
sysroot_command="--sysroot $sysroot_path"
fi
echo "Compiling $test_c to $test_wasm"
$CC \
-target wasm32-wasi-threads \
-O2 \
-Wall \
-pthread \
-z stack-size=32768 \
-Wl,--export=__heap_base \
-Wl,--export=__data_end \
-Wl,--shared-memory,--max-memory=1966080 \
-Wl,--export=wasi_thread_start \
-Wl,--export=malloc \
-Wl,--export=free \
-Wl,--export=test \
$sysroot_command \
$test_c -o $test_wasm
done

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <pthread.h>
#include <errno.h>
#include "mutex_common.h"
void
test()
{
pthread_mutex_t mutex;
// Set mutex type to errorcheck. This type provides some additional checks
// (for example returns EDEADLK instead of deadlocking in some cases)
pthread_mutexattr_t mutex_attr;
pthread_mutexattr_init(&mutex_attr);
pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&mutex, &mutex_attr);
pthread_mutexattr_destroy(&mutex_attr);
run_common_tests(&mutex);
fprintf(stderr, "Errorcheck mutex test is completed\n");
pthread_mutex_destroy(&mutex);
}
int
main()
{
test();
return 0;
}

View File

@ -0,0 +1,3 @@
{
"name": "lib-wasi-threads stress tests"
}

View File

@ -0,0 +1,229 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef MUTEX_COMMON_H
#define MUTEX_COMMON_H
#include <pthread.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <stdbool.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
enum Constants {
NUM_ITER = 250000,
NUM_THREADS = 12,
NUM_RETRY = 8,
RETRY_SLEEP_TIME_US = 1000,
};
// We're counting how many times each thread was called using this array
// Main thread is also counted here so we need to make arrays bigger
typedef struct {
int tids[NUM_THREADS + 1];
int calls[NUM_THREADS + 1];
} StatCollector;
typedef struct {
pthread_mutex_t *mutex;
StatCollector stat;
int counter;
bool is_sleeping;
} MutexCounter;
// This enum defines whether thread should sleep to increase contention
enum SleepState {
NON_SLEEP = 0,
SLEEP = 1,
};
void
mutex_counter_init(MutexCounter *mutex_counter, pthread_mutex_t *mutex,
enum SleepState is_sleeping)
{
memset(mutex_counter, 0, sizeof(*mutex_counter));
mutex_counter->mutex = mutex;
mutex_counter->is_sleeping = is_sleeping;
}
// This function spawns the thread using exponential retries if it receives
// EAGAIN
static inline void
spawn_thread(pthread_t *tid, void *func, void *arg)
{
int status_code = -1;
int timeout_us = RETRY_SLEEP_TIME_US;
for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) {
status_code = pthread_create(tid, NULL, (void *(*)(void *))func, arg);
assert(status_code == 0 || status_code == EAGAIN);
if (status_code == EAGAIN) {
usleep(timeout_us);
timeout_us *= 2;
}
}
assert(status_code == 0 && "Thread creation should succeed");
}
// This function adds tid to our stat
static inline void
add_to_stat(StatCollector *stat, int tid)
{
int tid_num = 0;
for (; tid_num < NUM_THREADS + 1 && stat->tids[tid_num] != 0; ++tid_num) {
if (stat->tids[tid_num] == tid) {
stat->calls[tid_num]++;
return;
}
}
assert(tid_num < NUM_THREADS + 1);
stat->tids[tid_num] = tid;
stat->calls[tid_num] = 1;
}
// This function prints number of calls by TID
static inline void
print_stat(StatCollector *stat)
{
fprintf(stderr, "Thread calls count by TID\n");
for (int i = 0; i < NUM_THREADS + 1; ++i) {
if (stat->tids[i] != 0) {
fprintf(stderr, "TID: %d; Calls: %d\n", stat->tids[i],
stat->calls[i]);
}
}
}
// This function is run by the threads, it increases counter in a loop and then
// sleeps after unlocking the mutex to provide better contention
static inline void *
inc_shared_variable(void *arg)
{
MutexCounter *mutex_counter = (MutexCounter *)(arg);
int sleep_us = 0;
while (!pthread_mutex_lock(mutex_counter->mutex)
&& mutex_counter->counter < NUM_ITER) {
mutex_counter->counter++;
add_to_stat(&mutex_counter->stat, (int)(pthread_self()));
if (mutex_counter->is_sleeping) {
sleep_us = rand() % 1000;
}
assert(pthread_mutex_unlock(mutex_counter->mutex) == 0
&& "Should be able to unlock a mutex");
if (mutex_counter->is_sleeping) {
usleep(sleep_us);
}
}
assert(mutex_counter->counter == NUM_ITER);
assert(pthread_mutex_unlock(mutex_counter->mutex) == 0
&& "Should be able to unlock the mutex after test execution");
return NULL;
}
// Locking and unlocking a mutex in a single thread.
static inline void *
same_thread_lock_unlock_test(void *mutex)
{
for (int i = 0; i < NUM_ITER; ++i) {
assert(pthread_mutex_lock(mutex) == 0
&& "Main thread should be able to lock a mutex");
assert(pthread_mutex_unlock(mutex) == 0
&& "Main thread should be able to unlock a mutex");
}
return NULL;
}
// This function spawns a thread that locks and unlocks a mutex `NUM_ITER` times
// in a row
static inline void
same_non_main_thread_lock_unlock_test(pthread_mutex_t *mutex)
{
pthread_t tid = 0;
spawn_thread(&tid, same_thread_lock_unlock_test, mutex);
assert(tid != 0 && "TID can't be 0 after successful thread creation");
assert(pthread_join(tid, NULL) == 0
&& "Thread should be joined successfully");
}
// This function checks basic contention between main and non-main thread
// increasing the shared variable
static inline void
two_threads_inc_test(pthread_mutex_t *mutex)
{
MutexCounter mutex_counter;
mutex_counter_init(&mutex_counter, mutex, false);
pthread_t tid = 0;
spawn_thread(&tid, inc_shared_variable, &mutex_counter);
assert(tid != 0 && "TID can't be 0 after successful thread creation");
inc_shared_variable(&mutex_counter);
assert(pthread_join(tid, NULL) == 0
&& "Thread should be joined without errors");
assert(mutex_counter.counter == NUM_ITER);
}
// This function creates number of threads specified by NUM_THREADS and run
// concurrent increasing of shared variable
static inline void
max_threads_inc_test(pthread_mutex_t *mutex, int threads_num,
enum SleepState is_sleeping)
{
MutexCounter mutex_counter;
mutex_counter_init(&mutex_counter, mutex, is_sleeping);
pthread_t tids[threads_num];
for (int i = 0; i < threads_num; ++i) {
spawn_thread(&tids[i], inc_shared_variable, &mutex_counter);
}
inc_shared_variable(&mutex_counter);
for (int i = 0; i < threads_num; ++i) {
assert(pthread_join(tids[i], NULL) == 0
&& "Thread should be joined without errors");
}
print_stat(&mutex_counter.stat);
}
// This function just runs all the tests described above
static inline void
run_common_tests(pthread_mutex_t *mutex)
{
srand(time(NULL));
fprintf(stderr, "Starting same_thread_lock_unlock_test test\n");
same_thread_lock_unlock_test(mutex);
fprintf(stderr, "Finished same_thread_lock_unlock_test test\n");
fprintf(stderr, "Starting same_non_main_thread_lock_unlock_test test\n");
same_non_main_thread_lock_unlock_test(mutex);
fprintf(stderr, "Finished same_non_main_thread_lock_unlock_test test\n");
fprintf(stderr, "Starting two_threads_inc_test test\n");
two_threads_inc_test(mutex);
fprintf(stderr, "Finished two_threads_inc_test test\n");
fprintf(stderr, "Starting max_threads_inc_test_sleep test\n");
max_threads_inc_test(mutex, NUM_THREADS, SLEEP);
fprintf(stderr, "Finished concurrent_inc sleep test\n");
fprintf(stderr, "Starting max_threads_inc_test_non_sleep test\n");
max_threads_inc_test(mutex, NUM_THREADS, NON_SLEEP);
fprintf(stderr, "Finished max_threads_inc_test test\n");
}
#endif // MUTEX_COMMON_H

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <pthread.h>
#include <errno.h>
#include "mutex_common.h"
void
test()
{
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);
run_common_tests(&mutex);
fprintf(stderr, "Normal mutex test is completed\n");
pthread_mutex_destroy(&mutex);
}
int
main()
{
test();
return 0;
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <pthread.h>
#include <errno.h>
#include "mutex_common.h"
void
multiple_same_thread_lock(void *mutex)
{
for (int i = 0; i < 100; ++i) {
assert(pthread_mutex_lock(mutex) == 0
&& "Recursive mutex should allow multiple locking");
}
for (int i = 0; i < 100; ++i) {
assert(pthread_mutex_unlock(mutex) == 0
&& "Recursive mutex should allow multiple unlocking");
}
}
void *
same_thread_multiple_rec_mutex_lock(void *mutex)
{
for (int i = 0; i < NUM_ITER; ++i) {
multiple_same_thread_lock(mutex);
}
return NULL;
}
void
test()
{
pthread_mutex_t mutex;
// Set mutex type to recursive. This type allows multiple locking and
// unlocking within the same thread
pthread_mutexattr_t mutex_attr;
pthread_mutexattr_init(&mutex_attr);
pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&mutex, &mutex_attr);
pthread_mutexattr_destroy(&mutex_attr);
run_common_tests(&mutex);
fprintf(stderr, "Starting same_thread_multiple_rec_mutex_lock test\n");
same_thread_multiple_rec_mutex_lock(&mutex);
fprintf(stderr, "Finished same_thread_multiple_rec_mutex_lock test\n");
fprintf(stderr, "Starting same_thread_multiple_rec_mutex_lock test in "
"non-main thread\n");
pthread_t tid;
spawn_thread(&tid, same_thread_multiple_rec_mutex_lock, &mutex);
assert(pthread_join(tid, NULL) == 0
&& "Non-main thread should be joined successfully");
fprintf(stderr, "Finished same_thread_multiple_rec_mutex_lock test in "
"non-main thread\n");
fprintf(stderr, "Recursive mutex test is completed\n");
pthread_mutex_destroy(&mutex);
}
int
main()
{
test();
return 0;
}

View File

@ -16,13 +16,6 @@
#include <stdlib.h>
#include <unistd.h>
enum CONSTANTS {
NUM_ITER = 100000,
NUM_RETRY = 8,
MAX_NUM_THREADS = 8,
RETRY_SLEEP_TIME_US = 2000,
};
unsigned prime_numbers_count = 0;
bool
@ -49,10 +42,10 @@ check_if_prime(void *value)
}
unsigned int
validate()
validate(int iter_num)
{
unsigned int counter = 0;
for (unsigned int i = 2; i <= NUM_ITER; ++i) {
for (unsigned int i = 2; i <= iter_num; ++i) {
counter += is_prime(i);
}
@ -60,11 +53,12 @@ validate()
}
void
spawn_thread(pthread_t *thread, unsigned int *arg)
spawn_thread(pthread_t *thread, int retry_time_us, int retry_num,
unsigned int *arg)
{
int status_code = -1;
int timeout_us = RETRY_SLEEP_TIME_US;
for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) {
int timeout_us = retry_time_us;
for (int tries = 0; status_code != 0 && tries < retry_num; ++tries) {
status_code = pthread_create(thread, NULL, &check_if_prime, arg);
assert(status_code == 0 || status_code == EAGAIN);
if (status_code == EAGAIN) {
@ -76,42 +70,56 @@ spawn_thread(pthread_t *thread, unsigned int *arg)
assert(status_code == 0 && "Thread creation should succeed");
}
int
main(int argc, char **argv)
void
test(int iter_num, int retry_num, int max_threads_num, int retry_time_us)
{
pthread_t threads[MAX_NUM_THREADS];
unsigned int args[MAX_NUM_THREADS];
pthread_t threads[max_threads_num];
unsigned int args[max_threads_num];
double percentage = 0.1;
for (unsigned int factorised_number = 2; factorised_number < NUM_ITER;
for (unsigned int factorised_number = 2; factorised_number < iter_num;
++factorised_number) {
if (factorised_number > NUM_ITER * percentage) {
if (factorised_number > iter_num * percentage) {
fprintf(stderr, "Stress test is %d%% finished\n",
(unsigned int)(percentage * 100));
percentage += 0.1;
}
unsigned int thread_num = factorised_number % MAX_NUM_THREADS;
unsigned int thread_num = factorised_number % max_threads_num;
if (threads[thread_num] != 0) {
assert(pthread_join(threads[thread_num], NULL) == 0);
}
args[thread_num] = factorised_number;
usleep(RETRY_SLEEP_TIME_US);
spawn_thread(&threads[thread_num], &args[thread_num]);
usleep(retry_time_us);
spawn_thread(&threads[thread_num], retry_time_us, retry_num,
&args[thread_num]);
assert(threads[thread_num] != 0);
}
for (int i = 0; i < MAX_NUM_THREADS; ++i) {
for (int i = 0; i < max_threads_num; ++i) {
assert(threads[i] == 0 || pthread_join(threads[i], NULL) == 0);
}
// Check the test results
assert(
prime_numbers_count == validate()
prime_numbers_count == validate(iter_num)
&& "Answer mismatch between tested code and reference implementation");
fprintf(stderr, "Stress test finished successfully\n");
}
enum DEFAULT_PARAMETERS {
ITER_NUM = 20000,
RETRY_NUM = 8,
MAX_THREADS_NUM = 12,
RETRY_SLEEP_TIME_US = 2000,
};
int
main(int argc, char **argv)
{
test(ITER_NUM, RETRY_NUM, MAX_THREADS_NUM, RETRY_SLEEP_TIME_US);
return 0;
}

View File

@ -9,14 +9,6 @@
#include <stdio.h>
#include <unistd.h>
enum CONSTANTS {
NUM_ITER = 200000,
NUM_RETRY = 8,
MAX_NUM_THREADS = 8,
RETRY_SLEEP_TIME_US = 4000,
SECOND = 1000 * 1000 * 1000
};
int threads_executed = 0;
unsigned int threads_creation_tried = 0;
unsigned int threads_in_use = 0;
@ -31,11 +23,11 @@ thread_func(void *arg)
}
void
spawn_thread(pthread_t *thread)
spawn_thread(pthread_t *thread, int retry_time, int iter_num)
{
int status_code = -1;
int timeout_us = RETRY_SLEEP_TIME_US;
for (int tries = 0; status_code != 0 && tries < NUM_RETRY; ++tries) {
int timeout_us = retry_time;
for (int tries = 0; status_code != 0 && tries < iter_num; ++tries) {
status_code = pthread_create(thread, NULL, &thread_func, NULL);
__atomic_fetch_add(&threads_creation_tried, 1, __ATOMIC_RELAXED);
@ -49,30 +41,33 @@ spawn_thread(pthread_t *thread)
assert(status_code == 0 && "Thread creation should succeed");
}
int
main(int argc, char **argv)
void
test(int iter_num, int max_threads_num, int retry_num, int retry_time_us)
{
double percentage = 0.1;
int second_us = 1000 * 1000 * 1000; // 1 second in us
for (int iter = 0; iter < NUM_ITER; ++iter) {
if (iter > NUM_ITER * percentage) {
for (int iter = 0; iter < iter_num; ++iter) {
if (iter > iter_num * percentage) {
fprintf(stderr, "Spawning stress test is %d%% finished\n",
(unsigned int)(percentage * 100));
percentage += 0.1;
}
while (__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST)
== MAX_NUM_THREADS) {
== max_threads_num) {
usleep(100);
}
__atomic_fetch_add(&threads_in_use, 1, __ATOMIC_SEQ_CST);
pthread_t tmp;
spawn_thread(&tmp);
spawn_thread(&tmp, retry_time_us, iter_num);
pthread_detach(tmp);
}
while ((__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) != 0)) {
__builtin_wasm_memory_atomic_wait32(&threads_in_use, 0, SECOND);
// Casting to int* to supress compiler warning
__builtin_wasm_memory_atomic_wait32((int *)(&threads_in_use), 0,
second_us);
}
assert(__atomic_load_n(&threads_in_use, __ATOMIC_SEQ_CST) == 0);
@ -89,5 +84,18 @@ main(int argc, char **argv)
"with retry ratio %f\n",
threads_creation_tried,
(1. * threads_creation_tried) / threads_executed);
}
enum DEFAULT_PARAMETERS {
ITER_NUM = 50000,
RETRY_NUM = 8,
MAX_NUM_THREADS = 12,
RETRY_SLEEP_TIME_US = 4000,
};
int
main(int argc, char **argv)
{
test(ITER_NUM, MAX_NUM_THREADS, RETRY_NUM, RETRY_SLEEP_TIME_US);
return 0;
}

View File

@ -34,7 +34,10 @@ while [[ $# -gt 0 ]]; do
done
# Stress tests names
thread_start_file_exclusions=("spawn_stress_test.wasm" "linear_memory_size_update.wasm" "stress_test_threads_creation.wasm")
thread_start_file_exclusions=("linear_memory_size_update.wasm")
rm -rf *.wasm
rm -rf *.aot
for test_c in *.c; do
test_wasm="$(basename $test_c .c).wasm"

View File

@ -65,7 +65,7 @@ main(int argc, char **argv)
assert(start_args_init(&data[i].base));
thread_ids[i] = __wasi_thread_spawn(&data[i]);
printf("Thread created with id=%d\n", thread_ids[i]);
assert(thread_ids[i] > 0 && "Thread creation failed");
ASSERT_VALID_TID(thread_ids[i]);
for (int j = 0; j < i; j++) {
assert(thread_ids[i] != thread_ids[j] && "Duplicated TIDs");

View File

@ -49,7 +49,7 @@ main(int argc, char **argv)
for (int i = 0; i < NUM_THREADS; i++) {
assert(start_args_init(&data[i].base));
thread_ids[i] = __wasi_thread_spawn(&data[i]);
assert(thread_ids[i] > 0 && "Thread creation failed");
ASSERT_VALID_TID(thread_ids[i]);
}
printf("Wait for threads to finish\n");

View File

@ -61,7 +61,7 @@ main(int argc, char **argv)
for (int i = 0; i < NUM_THREADS; i++) {
assert(start_args_init(&data[i].base));
thread_ids[i] = __wasi_thread_spawn(&data[i]);
assert(thread_ids[i] > 0 && "Thread creation failed");
ASSERT_VALID_TID(thread_ids[i]);
}
printf("Wait for threads to finish\n");

View File

@ -1,6 +0,0 @@
{
"lib-wasi-threads tests": {
"spawn_stress_test": "Stress tests are incompatible with the other part and executed differently",
"stress_test_threads_creation": "Stress tests are incompatible with the other part and executed differently"
}
}

View File

@ -38,7 +38,7 @@ main(int argc, char **argv)
assert(start_args_init(&data.base));
int thread_id = __wasi_thread_spawn(&data);
assert(thread_id > 0 && "Thread creation failed");
ASSERT_VALID_TID(thread_id);
return EXIT_SUCCESS;
}

View File

@ -69,7 +69,7 @@ main(int argc, char **argv)
data[i].iteration = i;
thread_ids[i] = __wasi_thread_spawn(&data[i]);
assert(thread_ids[i] > 0 && "Thread creation failed");
ASSERT_VALID_TID(thread_ids[i]);
}
printf("Wait for threads to finish\n");

View File

@ -8,8 +8,14 @@
#include "platform_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TID_ALLOCATOR_INIT_SIZE CLUSTER_MAX_THREAD_NUM
enum {
/* Keep it in sync with
https://github.com/WebAssembly/wasi-threads#design-choice-thread-ids */
TID_MIN = 1,
TID_MAX = 0x1FFFFFFF
}; // Reserved TIDs (WASI specification)
@ -33,4 +39,8 @@ tid_allocator_get_tid(TidAllocator *tid_allocator);
void
tid_allocator_release_tid(TidAllocator *tid_allocator, int32 thread_id);
#ifdef __cplusplus
}
#endif
#endif /* _TID_ALLOCATOR_H */

View File

@ -0,0 +1,6 @@
# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
create_wamr_unit_test(wasi_threads
${CMAKE_CURRENT_LIST_DIR}/test_tid_allocator.cpp
)

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <gtest/gtest.h>
#include "tid_allocator.h"
#include <stdint.h>
class TidAllocatorTest : public ::testing::Test
{
protected:
void SetUp() override { ASSERT_TRUE(tid_allocator_init(&_allocator)); }
void TearDown() override { tid_allocator_deinit(&_allocator); }
TidAllocator _allocator;
};
static bool
is_tid_valid(int32 tid)
{
/* See: https://github.com/WebAssembly/wasi-threads#design-choice-thread-ids
*/
return tid >= TID_MIN && tid <= TID_MAX;
}
TEST_F(TidAllocatorTest, BasicTest)
{
int32 tid = tid_allocator_get_tid(&_allocator);
ASSERT_TRUE(is_tid_valid(tid));
}
TEST_F(TidAllocatorTest, ShouldFailOnAllocatingMoreThanAllowedThreadIDs)
{
int32 last_tid = 0;
for (int32 i = 0; i < TID_MAX + 1; i++) {
last_tid = tid_allocator_get_tid(&_allocator);
if (last_tid < 0) {
break;
}
ASSERT_TRUE(is_tid_valid(last_tid));
}
ASSERT_LT(last_tid, 0);
}
TEST_F(TidAllocatorTest, ShouldAllocateMoreThanAllowedTIDsIfOldTIDsAreReleased)
{
int32 last_tid = 0;
for (int32 i = 0; i < TID_MAX + 1; i++) {
if (last_tid != 0) {
tid_allocator_release_tid(&_allocator, last_tid);
}
last_tid = tid_allocator_get_tid(&_allocator);
ASSERT_TRUE(is_tid_valid(last_tid));
}
}

View File

@ -335,7 +335,7 @@ wasi_fd_close(wasm_exec_env_t exec_env, wasi_fd_t fd)
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_close(curfds, prestats, fd);
return wasmtime_ssp_fd_close(exec_env, curfds, prestats, fd);
}
static wasi_errno_t
@ -348,7 +348,7 @@ wasi_fd_datasync(wasm_exec_env_t exec_env, wasi_fd_t fd)
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_datasync(curfds, fd);
return wasmtime_ssp_fd_datasync(exec_env, curfds, fd);
}
static wasi_errno_t
@ -389,8 +389,8 @@ wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
iovec->buf_len = iovec_app->buf_len;
}
err = wasmtime_ssp_fd_pread(curfds, fd, iovec_begin, iovs_len, offset,
&nread);
err = wasmtime_ssp_fd_pread(exec_env, curfds, fd, iovec_begin, iovs_len,
offset, &nread);
if (err)
goto fail;
@ -443,8 +443,8 @@ wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
ciovec->buf_len = iovec_app->buf_len;
}
err = wasmtime_ssp_fd_pwrite(curfds, fd, ciovec_begin, iovs_len, offset,
&nwritten);
err = wasmtime_ssp_fd_pwrite(exec_env, curfds, fd, ciovec_begin, iovs_len,
offset, &nwritten);
if (err)
goto fail;
@ -496,7 +496,8 @@ wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
iovec->buf_len = iovec_app->buf_len;
}
err = wasmtime_ssp_fd_read(curfds, fd, iovec_begin, iovs_len, &nread);
err = wasmtime_ssp_fd_read(exec_env, curfds, fd, iovec_begin, iovs_len,
&nread);
if (err)
goto fail;
@ -521,7 +522,7 @@ wasi_fd_renumber(wasm_exec_env_t exec_env, wasi_fd_t from, wasi_fd_t to)
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_renumber(curfds, prestats, from, to);
return wasmtime_ssp_fd_renumber(exec_env, curfds, prestats, from, to);
}
static wasi_errno_t
@ -538,7 +539,8 @@ wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset,
if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_seek(curfds, fd, offset, whence, newoffset);
return wasmtime_ssp_fd_seek(exec_env, curfds, fd, offset, whence,
newoffset);
}
static wasi_errno_t
@ -554,7 +556,7 @@ wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset)
if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_tell(curfds, fd, newoffset);
return wasmtime_ssp_fd_tell(exec_env, curfds, fd, newoffset);
}
static wasi_errno_t
@ -573,7 +575,7 @@ wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!validate_native_addr(fdstat_app, sizeof(wasi_fdstat_t)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_fdstat_get(curfds, fd, &fdstat);
err = wasmtime_ssp_fd_fdstat_get(exec_env, curfds, fd, &fdstat);
if (err)
return err;
@ -592,7 +594,7 @@ wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_fdstat_set_flags(curfds, fd, flags);
return wasmtime_ssp_fd_fdstat_set_flags(exec_env, curfds, fd, flags);
}
static wasi_errno_t
@ -607,8 +609,8 @@ wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_fdstat_set_rights(curfds, fd, fs_rights_base,
fs_rights_inheriting);
return wasmtime_ssp_fd_fdstat_set_rights(
exec_env, curfds, fd, fs_rights_base, fs_rights_inheriting);
}
static wasi_errno_t
@ -621,7 +623,7 @@ wasi_fd_sync(wasm_exec_env_t exec_env, wasi_fd_t fd)
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_sync(curfds, fd);
return wasmtime_ssp_fd_sync(exec_env, curfds, fd);
}
static wasi_errno_t
@ -663,7 +665,8 @@ wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
ciovec->buf_len = iovec_app->buf_len;
}
err = wasmtime_ssp_fd_write(curfds, fd, ciovec_begin, iovs_len, &nwritten);
err = wasmtime_ssp_fd_write(exec_env, curfds, fd, ciovec_begin, iovs_len,
&nwritten);
if (err)
goto fail;
@ -688,7 +691,7 @@ wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_advise(curfds, fd, offset, len, advice);
return wasmtime_ssp_fd_advise(exec_env, curfds, fd, offset, len, advice);
}
static wasi_errno_t
@ -702,7 +705,7 @@ wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_allocate(curfds, fd, offset, len);
return wasmtime_ssp_fd_allocate(exec_env, curfds, fd, offset, len);
}
static wasi_errno_t
@ -716,7 +719,8 @@ wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_create_directory(curfds, fd, path, path_len);
return wasmtime_ssp_path_create_directory(exec_env, curfds, fd, path,
path_len);
}
static wasi_errno_t
@ -733,8 +737,9 @@ wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_link(curfds, prestats, old_fd, old_flags, old_path,
old_path_len, new_fd, new_path, new_path_len);
return wasmtime_ssp_path_link(exec_env, curfds, prestats, old_fd, old_flags,
old_path, old_path_len, new_fd, new_path,
new_path_len);
}
static wasi_errno_t
@ -756,9 +761,9 @@ wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
if (!validate_native_addr(fd_app, sizeof(wasi_fd_t)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_path_open(curfds, dirfd, dirflags, path, path_len,
oflags, fs_rights_base, fs_rights_inheriting,
fs_flags, &fd);
err = wasmtime_ssp_path_open(exec_env, curfds, dirfd, dirflags, path,
path_len, oflags, fs_rights_base,
fs_rights_inheriting, fs_flags, &fd);
*fd_app = fd;
return err;
@ -780,7 +785,8 @@ wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_fd_readdir(curfds, fd, buf, buf_len, cookie, &bufused);
err = wasmtime_ssp_fd_readdir(exec_env, curfds, fd, buf, buf_len, cookie,
&bufused);
if (err)
return err;
@ -805,8 +811,8 @@ wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
if (!validate_native_addr(bufused_app, sizeof(uint32)))
return (wasi_errno_t)-1;
err = wasmtime_ssp_path_readlink(curfds, fd, path, path_len, buf, buf_len,
&bufused);
err = wasmtime_ssp_path_readlink(exec_env, curfds, fd, path, path_len, buf,
buf_len, &bufused);
if (err)
return err;
@ -826,8 +832,9 @@ wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_rename(curfds, old_fd, old_path, old_path_len,
new_fd, new_path, new_path_len);
return wasmtime_ssp_path_rename(exec_env, curfds, old_fd, old_path,
old_path_len, new_fd, new_path,
new_path_len);
}
static wasi_errno_t
@ -844,7 +851,7 @@ wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_filestat_get(curfds, fd, filestat);
return wasmtime_ssp_fd_filestat_get(exec_env, curfds, fd, filestat);
}
static wasi_errno_t
@ -859,8 +866,8 @@ wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_filestat_set_times(curfds, fd, st_atim, st_mtim,
fstflags);
return wasmtime_ssp_fd_filestat_set_times(exec_env, curfds, fd, st_atim,
st_mtim, fstflags);
}
static wasi_errno_t
@ -874,7 +881,7 @@ wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_fd_filestat_set_size(curfds, fd, st_size);
return wasmtime_ssp_fd_filestat_set_size(exec_env, curfds, fd, st_size);
}
static wasi_errno_t
@ -892,8 +899,8 @@ wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
return (wasi_errno_t)-1;
return wasmtime_ssp_path_filestat_get(curfds, fd, flags, path, path_len,
filestat);
return wasmtime_ssp_path_filestat_get(exec_env, curfds, fd, flags, path,
path_len, filestat);
}
static wasi_errno_t
@ -909,8 +916,9 @@ wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_filestat_set_times(
curfds, fd, flags, path, path_len, st_atim, st_mtim, fstflags);
return wasmtime_ssp_path_filestat_set_times(exec_env, curfds, fd, flags,
path, path_len, st_atim,
st_mtim, fstflags);
}
static wasi_errno_t
@ -926,8 +934,8 @@ wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_symlink(curfds, prestats, old_path, old_path_len,
fd, new_path, new_path_len);
return wasmtime_ssp_path_symlink(exec_env, curfds, prestats, old_path,
old_path_len, fd, new_path, new_path_len);
}
static wasi_errno_t
@ -941,7 +949,7 @@ wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_unlink_file(curfds, fd, path, path_len);
return wasmtime_ssp_path_unlink_file(exec_env, curfds, fd, path, path_len);
}
static wasi_errno_t
@ -955,7 +963,8 @@ wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
if (!wasi_ctx)
return (wasi_errno_t)-1;
return wasmtime_ssp_path_remove_directory(curfds, fd, path, path_len);
return wasmtime_ssp_path_remove_directory(exec_env, curfds, fd, path,
path_len);
}
#if WASM_ENABLE_THREAD_MGR != 0
@ -1026,8 +1035,8 @@ execute_interruptible_poll_oneoff(
/* update timeout for clock subscription events */
update_clock_subscription_data(
in_copy, nsubscriptions, min_uint64(time_quant, timeout - elapsed));
err = wasmtime_ssp_poll_oneoff(curfds, in_copy, out, nsubscriptions,
nevents);
err = wasmtime_ssp_poll_oneoff(exec_env, curfds, in_copy, out,
nsubscriptions, nevents);
elapsed += time_quant;
if (err) {
@ -1079,7 +1088,8 @@ wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
return (wasi_errno_t)-1;
#if WASM_ENABLE_THREAD_MGR == 0
err = wasmtime_ssp_poll_oneoff(curfds, in, out, nsubscriptions, &nevents);
err = wasmtime_ssp_poll_oneoff(exec_env, curfds, in, out, nsubscriptions,
&nevents);
#else
err = execute_interruptible_poll_oneoff(curfds, in, out, nsubscriptions,
&nevents, exec_env);
@ -1133,7 +1143,7 @@ wasi_sock_accept(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_fdflags_t flags,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_accept(curfds, fd, flags, fd_new);
return wasi_ssp_sock_accept(exec_env, curfds, fd, flags, fd_new);
}
static wasi_errno_t
@ -1152,7 +1162,7 @@ wasi_sock_addr_local(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_addr_local(curfds, fd, addr);
return wasi_ssp_sock_addr_local(exec_env, curfds, fd, addr);
}
static wasi_errno_t
@ -1171,7 +1181,7 @@ wasi_sock_addr_remote(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_addr_remote(curfds, fd, addr);
return wasi_ssp_sock_addr_remote(exec_env, curfds, fd, addr);
}
static wasi_errno_t
@ -1192,8 +1202,8 @@ wasi_sock_addr_resolve(wasm_exec_env_t exec_env, const char *host,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
ns_lookup_list = wasi_ctx_get_ns_lookup_list(wasi_ctx);
return wasi_ssp_sock_addr_resolve(curfds, ns_lookup_list, host, service,
hints, addr_info, addr_info_size,
return wasi_ssp_sock_addr_resolve(exec_env, curfds, ns_lookup_list, host,
service, hints, addr_info, addr_info_size,
max_info_size);
}
@ -1211,7 +1221,7 @@ wasi_sock_bind(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx);
return wasi_ssp_sock_bind(curfds, addr_pool, fd, addr);
return wasi_ssp_sock_bind(exec_env, curfds, addr_pool, fd, addr);
}
static wasi_errno_t
@ -1234,7 +1244,7 @@ wasi_sock_connect(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_addr_t *addr)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
addr_pool = wasi_ctx_get_addr_pool(module_inst, wasi_ctx);
return wasi_ssp_sock_connect(curfds, addr_pool, fd, addr);
return wasi_ssp_sock_connect(exec_env, curfds, addr_pool, fd, addr);
}
static wasi_errno_t
@ -1253,7 +1263,7 @@ wasi_sock_get_broadcast(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_broadcast(curfds, fd, is_enabled);
return wasmtime_ssp_sock_get_broadcast(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1272,7 +1282,7 @@ wasi_sock_get_keep_alive(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_keep_alive(curfds, fd, is_enabled);
return wasmtime_ssp_sock_get_keep_alive(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1292,7 +1302,8 @@ wasi_sock_get_linger(wasm_exec_env_t exec_env, wasi_fd_t fd, bool *is_enabled,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_linger(curfds, fd, is_enabled, linger_s);
return wasmtime_ssp_sock_get_linger(exec_env, curfds, fd, is_enabled,
linger_s);
}
static wasi_errno_t
@ -1311,7 +1322,7 @@ wasi_sock_get_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_recv_buf_size(curfds, fd, size);
return wasmtime_ssp_sock_get_recv_buf_size(exec_env, curfds, fd, size);
}
static wasi_errno_t
@ -1330,7 +1341,7 @@ wasi_sock_get_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_recv_timeout(curfds, fd, timeout_us);
return wasmtime_ssp_sock_get_recv_timeout(exec_env, curfds, fd, timeout_us);
}
static wasi_errno_t
@ -1349,7 +1360,7 @@ wasi_sock_get_reuse_addr(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_reuse_addr(curfds, fd, is_enabled);
return wasmtime_ssp_sock_get_reuse_addr(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1368,7 +1379,7 @@ wasi_sock_get_reuse_port(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_reuse_port(curfds, fd, is_enabled);
return wasmtime_ssp_sock_get_reuse_port(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1387,7 +1398,7 @@ wasi_sock_get_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_send_buf_size(curfds, fd, size);
return wasmtime_ssp_sock_get_send_buf_size(exec_env, curfds, fd, size);
}
static wasi_errno_t
@ -1406,7 +1417,7 @@ wasi_sock_get_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_send_timeout(curfds, fd, timeout_us);
return wasmtime_ssp_sock_get_send_timeout(exec_env, curfds, fd, timeout_us);
}
static wasi_errno_t
@ -1425,7 +1436,8 @@ wasi_sock_get_tcp_fastopen_connect(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_tcp_fastopen_connect(curfds, fd, is_enabled);
return wasmtime_ssp_sock_get_tcp_fastopen_connect(exec_env, curfds, fd,
is_enabled);
}
static wasi_errno_t
@ -1444,7 +1456,7 @@ wasi_sock_get_tcp_no_delay(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_tcp_no_delay(curfds, fd, is_enabled);
return wasmtime_ssp_sock_get_tcp_no_delay(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1463,7 +1475,8 @@ wasi_sock_get_tcp_quick_ack(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_tcp_quick_ack(curfds, fd, is_enabled);
return wasmtime_ssp_sock_get_tcp_quick_ack(exec_env, curfds, fd,
is_enabled);
}
static wasi_errno_t
@ -1482,7 +1495,7 @@ wasi_sock_get_tcp_keep_idle(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_tcp_keep_idle(curfds, fd, time_s);
return wasmtime_ssp_sock_get_tcp_keep_idle(exec_env, curfds, fd, time_s);
}
static wasi_errno_t
@ -1501,7 +1514,7 @@ wasi_sock_get_tcp_keep_intvl(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_tcp_keep_intvl(curfds, fd, time_s);
return wasmtime_ssp_sock_get_tcp_keep_intvl(exec_env, curfds, fd, time_s);
}
static wasi_errno_t
@ -1520,7 +1533,7 @@ wasi_sock_get_ip_multicast_loop(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_ip_multicast_loop(curfds, fd, ipv6,
return wasmtime_ssp_sock_get_ip_multicast_loop(exec_env, curfds, fd, ipv6,
is_enabled);
}
@ -1539,7 +1552,7 @@ wasi_sock_get_ip_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8_t *ttl_s)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_ip_ttl(curfds, fd, ttl_s);
return wasmtime_ssp_sock_get_ip_ttl(exec_env, curfds, fd, ttl_s);
}
static wasi_errno_t
@ -1558,7 +1571,7 @@ wasi_sock_get_ip_multicast_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_ip_multicast_ttl(curfds, fd, ttl_s);
return wasmtime_ssp_sock_get_ip_multicast_ttl(exec_env, curfds, fd, ttl_s);
}
static wasi_errno_t
@ -1577,7 +1590,7 @@ wasi_sock_get_ipv6_only(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_get_ipv6_only(curfds, fd, is_enabled);
return wasmtime_ssp_sock_get_ipv6_only(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1592,7 +1605,7 @@ wasi_sock_listen(wasm_exec_env_t exec_env, wasi_fd_t fd, uint32 backlog)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_listen(curfds, fd, backlog);
return wasi_ssp_sock_listen(exec_env, curfds, fd, backlog);
}
static wasi_errno_t
@ -1609,7 +1622,7 @@ wasi_sock_open(wasm_exec_env_t exec_env, wasi_fd_t poolfd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasi_ssp_sock_open(curfds, poolfd, af, socktype, sockfd);
return wasi_ssp_sock_open(exec_env, curfds, poolfd, af, socktype, sockfd);
}
static wasi_errno_t
@ -1624,7 +1637,7 @@ wasi_sock_set_broadcast(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_broadcast(curfds, fd, is_enabled);
return wasmtime_ssp_sock_set_broadcast(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1640,7 +1653,7 @@ wasi_sock_set_keep_alive(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_keep_alive(curfds, fd, is_enabled);
return wasmtime_ssp_sock_set_keep_alive(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1656,7 +1669,8 @@ wasi_sock_set_linger(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_linger(curfds, fd, is_enabled, linger_s);
return wasmtime_ssp_sock_set_linger(exec_env, curfds, fd, is_enabled,
linger_s);
}
static wasi_errno_t
@ -1671,7 +1685,7 @@ wasi_sock_set_recv_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd, size_t size)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_recv_buf_size(curfds, fd, size);
return wasmtime_ssp_sock_set_recv_buf_size(exec_env, curfds, fd, size);
}
static wasi_errno_t
@ -1687,7 +1701,7 @@ wasi_sock_set_recv_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_recv_timeout(curfds, fd, timeout_us);
return wasmtime_ssp_sock_set_recv_timeout(exec_env, curfds, fd, timeout_us);
}
static wasi_errno_t
@ -1703,7 +1717,7 @@ wasi_sock_set_reuse_addr(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_reuse_addr(curfds, fd, is_enabled);
return wasmtime_ssp_sock_set_reuse_addr(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1719,7 +1733,7 @@ wasi_sock_set_reuse_port(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_reuse_port(curfds, fd, is_enabled);
return wasmtime_ssp_sock_set_reuse_port(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1734,7 +1748,7 @@ wasi_sock_set_send_buf_size(wasm_exec_env_t exec_env, wasi_fd_t fd, size_t size)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_send_buf_size(curfds, fd, size);
return wasmtime_ssp_sock_set_send_buf_size(exec_env, curfds, fd, size);
}
static wasi_errno_t
@ -1750,7 +1764,7 @@ wasi_sock_set_send_timeout(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_send_timeout(curfds, fd, timeout_us);
return wasmtime_ssp_sock_set_send_timeout(exec_env, curfds, fd, timeout_us);
}
static wasi_errno_t
@ -1766,7 +1780,8 @@ wasi_sock_set_tcp_fastopen_connect(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_tcp_fastopen_connect(curfds, fd, is_enabled);
return wasmtime_ssp_sock_set_tcp_fastopen_connect(exec_env, curfds, fd,
is_enabled);
}
static wasi_errno_t
@ -1782,7 +1797,7 @@ wasi_sock_set_tcp_no_delay(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_tcp_no_delay(curfds, fd, is_enabled);
return wasmtime_ssp_sock_set_tcp_no_delay(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -1798,7 +1813,8 @@ wasi_sock_set_tcp_quick_ack(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_tcp_quick_ack(curfds, fd, is_enabled);
return wasmtime_ssp_sock_set_tcp_quick_ack(exec_env, curfds, fd,
is_enabled);
}
static wasi_errno_t
@ -1814,7 +1830,7 @@ wasi_sock_set_tcp_keep_idle(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_tcp_keep_idle(curfds, fd, time_s);
return wasmtime_ssp_sock_set_tcp_keep_idle(exec_env, curfds, fd, time_s);
}
static wasi_errno_t
@ -1830,7 +1846,7 @@ wasi_sock_set_tcp_keep_intvl(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_tcp_keep_intvl(curfds, fd, time_s);
return wasmtime_ssp_sock_set_tcp_keep_intvl(exec_env, curfds, fd, time_s);
}
static wasi_errno_t
@ -1846,7 +1862,7 @@ wasi_sock_set_ip_multicast_loop(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ip_multicast_loop(curfds, fd, ipv6,
return wasmtime_ssp_sock_set_ip_multicast_loop(exec_env, curfds, fd, ipv6,
is_enabled);
}
@ -1867,8 +1883,8 @@ wasi_sock_set_ip_add_membership(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ip_add_membership(curfds, fd, imr_multiaddr,
imr_interface);
return wasmtime_ssp_sock_set_ip_add_membership(
exec_env, curfds, fd, imr_multiaddr, imr_interface);
}
static wasi_errno_t
@ -1888,8 +1904,8 @@ wasi_sock_set_ip_drop_membership(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ip_drop_membership(curfds, fd, imr_multiaddr,
imr_interface);
return wasmtime_ssp_sock_set_ip_drop_membership(
exec_env, curfds, fd, imr_multiaddr, imr_interface);
}
static wasi_errno_t
@ -1904,7 +1920,7 @@ wasi_sock_set_ip_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd, uint8_t ttl_s)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ip_ttl(curfds, fd, ttl_s);
return wasmtime_ssp_sock_set_ip_ttl(exec_env, curfds, fd, ttl_s);
}
static wasi_errno_t
@ -1920,7 +1936,7 @@ wasi_sock_set_ip_multicast_ttl(wasm_exec_env_t exec_env, wasi_fd_t fd,
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ip_multicast_ttl(curfds, fd, ttl_s);
return wasmtime_ssp_sock_set_ip_multicast_ttl(exec_env, curfds, fd, ttl_s);
}
static wasi_errno_t
@ -1935,7 +1951,7 @@ wasi_sock_set_ipv6_only(wasm_exec_env_t exec_env, wasi_fd_t fd, bool is_enabled)
curfds = wasi_ctx_get_curfds(module_inst, wasi_ctx);
return wasmtime_ssp_sock_set_ipv6_only(curfds, fd, is_enabled);
return wasmtime_ssp_sock_set_ipv6_only(exec_env, curfds, fd, is_enabled);
}
static wasi_errno_t
@ -2053,8 +2069,9 @@ wasi_sock_recv_from(wasm_exec_env_t exec_env, wasi_fd_t sock,
memset(buf_begin, 0, total_size);
*ro_data_len = 0;
err = wasmtime_ssp_sock_recv_from(curfds, sock, buf_begin, total_size,
ri_flags, src_addr, &recv_bytes);
err = wasmtime_ssp_sock_recv_from(exec_env, curfds, sock, buf_begin,
total_size, ri_flags, src_addr,
&recv_bytes);
if (err != __WASI_ESUCCESS) {
goto fail;
}
@ -2153,7 +2170,8 @@ wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
return err;
*so_data_len = 0;
err = wasmtime_ssp_sock_send(curfds, sock, buf, buf_size, &send_bytes);
err = wasmtime_ssp_sock_send(exec_env, curfds, sock, buf, buf_size,
&send_bytes);
*so_data_len = (uint32)send_bytes;
wasm_runtime_free(buf);
@ -2193,8 +2211,8 @@ wasi_sock_send_to(wasm_exec_env_t exec_env, wasi_fd_t sock,
return err;
*so_data_len = 0;
err = wasmtime_ssp_sock_send_to(curfds, addr_pool, sock, buf, buf_size,
si_flags, dest_addr, &send_bytes);
err = wasmtime_ssp_sock_send_to(exec_env, curfds, addr_pool, sock, buf,
buf_size, si_flags, dest_addr, &send_bytes);
*so_data_len = (uint32)send_bytes;
wasm_runtime_free(buf);
@ -2212,7 +2230,7 @@ wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
if (!wasi_ctx)
return __WASI_EINVAL;
return wasmtime_ssp_sock_shutdown(curfds, sock);
return wasmtime_ssp_sock_shutdown(exec_env, curfds, sock);
}
static wasi_errno_t

View File

@ -22,6 +22,8 @@
#include <stddef.h>
#include <stdint.h>
#include "wasm_export.h"
/* clang-format off */
#ifdef __cplusplus
@ -274,37 +276,6 @@ typedef uint8_t __wasi_sdflags_t;
typedef uint16_t __wasi_siflags_t;
typedef uint8_t __wasi_signal_t;
// 0 is reserved; POSIX has special semantics for kill(pid, 0).
#define __WASI_SIGHUP (1)
#define __WASI_SIGINT (2)
#define __WASI_SIGQUIT (3)
#define __WASI_SIGILL (4)
#define __WASI_SIGTRAP (5)
#define __WASI_SIGABRT (6)
#define __WASI_SIGBUS (7)
#define __WASI_SIGFPE (8)
#define __WASI_SIGKILL (9)
#define __WASI_SIGUSR1 (10)
#define __WASI_SIGSEGV (11)
#define __WASI_SIGUSR2 (12)
#define __WASI_SIGPIPE (13)
#define __WASI_SIGALRM (14)
#define __WASI_SIGTERM (15)
#define __WASI_SIGCHLD (16)
#define __WASI_SIGCONT (17)
#define __WASI_SIGSTOP (18)
#define __WASI_SIGTSTP (19)
#define __WASI_SIGTTIN (20)
#define __WASI_SIGTTOU (21)
#define __WASI_SIGURG (22)
#define __WASI_SIGXCPU (23)
#define __WASI_SIGXFSZ (24)
#define __WASI_SIGVTALRM (25)
#define __WASI_SIGPROF (26)
#define __WASI_SIGWINCH (27)
#define __WASI_SIGPOLL (28)
#define __WASI_SIGPWR (29)
#define __WASI_SIGSYS (30)
typedef uint16_t __wasi_subclockflags_t;
#define __WASI_SUBSCRIPTION_CLOCK_ABSTIME (0x0001)
@ -639,17 +610,13 @@ typedef struct __wasi_addr_info_hints_t {
#endif
__wasi_errno_t wasmtime_ssp_args_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ,
#endif
char **argv,
char *argv_buf
) WASMTIME_SSP_SYSCALL_NAME(args_get) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_args_sizes_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ,
#endif
size_t *argc,
size_t *argv_buf_size
) WASMTIME_SSP_SYSCALL_NAME(args_sizes_get) WARN_UNUSED;
@ -666,57 +633,46 @@ __wasi_errno_t wasmtime_ssp_clock_time_get(
) WASMTIME_SSP_SYSCALL_NAME(clock_time_get) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_environ_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ,
#endif
char **environ,
char *environ_buf
) WASMTIME_SSP_SYSCALL_NAME(environ_get) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_environ_sizes_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct argv_environ_values *arg_environ,
#endif
size_t *environ_count,
size_t *environ_buf_size
) WASMTIME_SSP_SYSCALL_NAME(environ_sizes_get) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_prestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_prestats *prestats,
#endif
__wasi_fd_t fd,
__wasi_prestat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_get) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_prestat_dir_name(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
struct fd_prestats *prestats,
#endif
__wasi_fd_t fd,
char *path,
size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_dir_name) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_close(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
struct fd_prestats *prestats,
#endif
__wasi_fd_t fd
) WASMTIME_SSP_SYSCALL_NAME(fd_close) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_datasync(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd
) WASMTIME_SSP_SYSCALL_NAME(fd_datasync) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_pread(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const __wasi_iovec_t *iovs,
size_t iovs_len,
@ -725,9 +681,8 @@ __wasi_errno_t wasmtime_ssp_fd_pread(
) WASMTIME_SSP_SYSCALL_NAME(fd_pread) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_pwrite(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const __wasi_ciovec_t *iovs,
size_t iovs_len,
@ -736,9 +691,8 @@ __wasi_errno_t wasmtime_ssp_fd_pwrite(
) WASMTIME_SSP_SYSCALL_NAME(fd_pwrite) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_read(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const __wasi_iovec_t *iovs,
size_t iovs_len,
@ -746,18 +700,16 @@ __wasi_errno_t wasmtime_ssp_fd_read(
) WASMTIME_SSP_SYSCALL_NAME(fd_read) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_renumber(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
struct fd_prestats *prestats,
#endif
__wasi_fd_t from,
__wasi_fd_t to
) WASMTIME_SSP_SYSCALL_NAME(fd_renumber) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_seek(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filedelta_t offset,
__wasi_whence_t whence,
@ -765,49 +717,43 @@ __wasi_errno_t wasmtime_ssp_fd_seek(
) WASMTIME_SSP_SYSCALL_NAME(fd_seek) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_tell(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filesize_t *newoffset
) WASMTIME_SSP_SYSCALL_NAME(fd_tell) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_fdstat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_fdstat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_get) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_fdstat_set_flags(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_fdflags_t flags
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_flags) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_fdstat_set_rights(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_rights_t fs_rights_base,
__wasi_rights_t fs_rights_inheriting
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_rights) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_sync(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd
) WASMTIME_SSP_SYSCALL_NAME(fd_sync) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_write(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const __wasi_ciovec_t *iovs,
size_t iovs_len,
@ -815,9 +761,8 @@ __wasi_errno_t wasmtime_ssp_fd_write(
) WASMTIME_SSP_SYSCALL_NAME(fd_write) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_advise(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filesize_t offset,
__wasi_filesize_t len,
@ -825,28 +770,25 @@ __wasi_errno_t wasmtime_ssp_fd_advise(
) WASMTIME_SSP_SYSCALL_NAME(fd_advise) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_allocate(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filesize_t offset,
__wasi_filesize_t len
) WASMTIME_SSP_SYSCALL_NAME(fd_allocate) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_path_create_directory(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const char *path,
size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(path_create_directory) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_path_link(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
struct fd_prestats *prestats,
#endif
__wasi_fd_t old_fd,
__wasi_lookupflags_t old_flags,
const char *old_path,
@ -857,9 +799,8 @@ __wasi_errno_t wasmtime_ssp_path_link(
) WASMTIME_SSP_SYSCALL_NAME(path_link) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_path_open(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t dirfd,
__wasi_lookupflags_t dirflags,
const char *path,
@ -872,9 +813,8 @@ __wasi_errno_t wasmtime_ssp_path_open(
) WASMTIME_SSP_SYSCALL_NAME(path_open) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_readdir(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
void *buf,
size_t buf_len,
@ -883,9 +823,8 @@ __wasi_errno_t wasmtime_ssp_fd_readdir(
) WASMTIME_SSP_SYSCALL_NAME(fd_readdir) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_path_readlink(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const char *path,
size_t path_len,
@ -895,9 +834,8 @@ __wasi_errno_t wasmtime_ssp_path_readlink(
) WASMTIME_SSP_SYSCALL_NAME(path_readlink) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_path_rename(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t old_fd,
const char *old_path,
size_t old_path_len,
@ -907,17 +845,15 @@ __wasi_errno_t wasmtime_ssp_path_rename(
) WASMTIME_SSP_SYSCALL_NAME(path_rename) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_filestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filestat_t *buf
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_get) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_filestat_set_times(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_timestamp_t st_atim,
__wasi_timestamp_t st_mtim,
@ -925,17 +861,15 @@ __wasi_errno_t wasmtime_ssp_fd_filestat_set_times(
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_times) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_fd_filestat_set_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_filesize_t st_size
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_size) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_path_filestat_get(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_lookupflags_t flags,
const char *path,
@ -944,9 +878,8 @@ __wasi_errno_t wasmtime_ssp_path_filestat_get(
) WASMTIME_SSP_SYSCALL_NAME(path_filestat_get) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_path_filestat_set_times(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
__wasi_lookupflags_t flags,
const char *path,
@ -957,10 +890,9 @@ __wasi_errno_t wasmtime_ssp_path_filestat_set_times(
) WASMTIME_SSP_SYSCALL_NAME(path_filestat_set_times) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_path_symlink(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
struct fd_prestats *prestats,
#endif
const char *old_path,
size_t old_path_len,
__wasi_fd_t fd,
@ -969,47 +901,30 @@ __wasi_errno_t wasmtime_ssp_path_symlink(
) WASMTIME_SSP_SYSCALL_NAME(path_symlink) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_path_unlink_file(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const char *path,
size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(path_unlink_file) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_path_remove_directory(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd,
const char *path,
size_t path_len
) WASMTIME_SSP_SYSCALL_NAME(path_remove_directory) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_poll_oneoff(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
const __wasi_subscription_t *in,
__wasi_event_t *out,
size_t nsubscriptions,
size_t *nevents
) WASMTIME_SSP_SYSCALL_NAME(poll_oneoff) WARN_UNUSED;
#if 0
/**
* We throw exception in libc-wasi wrapper function wasi_proc_exit()
* but not call this function.
*/
_Noreturn void wasmtime_ssp_proc_exit(
__wasi_exitcode_t rval
) WASMTIME_SSP_SYSCALL_NAME(proc_exit);
#endif
__wasi_errno_t wasmtime_ssp_proc_raise(
__wasi_signal_t sig
) WASMTIME_SSP_SYSCALL_NAME(proc_raise) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_random_get(
void *buf,
size_t buf_len
@ -1017,50 +932,44 @@ __wasi_errno_t wasmtime_ssp_random_get(
__wasi_errno_t
wasi_ssp_sock_accept(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_fdflags_t flags, __wasi_fd_t *fd_new
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_addr_local(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_addr_remote(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_open(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t poolfd, __wasi_address_family_t af, __wasi_sock_type_t socktype,
__wasi_fd_t *sockfd
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_bind(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds, struct addr_pool *addr_pool,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_addr_resolve(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds, char **ns_lookup_list,
#endif
const char *host, const char* service,
__wasi_addr_info_hints_t *hints, __wasi_addr_info_t *addr_info,
__wasi_size_t addr_info_size, __wasi_size_t *max_info_size
@ -1068,88 +977,77 @@ wasi_ssp_sock_addr_resolve(
__wasi_errno_t
wasi_ssp_sock_connect(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds, struct addr_pool *addr_pool,
#endif
__wasi_fd_t fd, __wasi_addr_t *addr
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_get_recv_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t *size
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_get_reuse_addr(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, uint8_t *reuse
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_get_reuse_port(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, uint8_t *reuse
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_get_send_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t *size
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_set_recv_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t size
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_set_reuse_addr(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, uint8_t reuse
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_set_reuse_port(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, uint8_t reuse
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_set_send_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t size
) WARN_UNUSED;
__wasi_errno_t
wasi_ssp_sock_listen(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t fd, __wasi_size_t backlog
) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_recv(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
void *buf,
size_t buf_len,
@ -1157,9 +1055,8 @@ __wasi_errno_t wasmtime_ssp_sock_recv(
) WASMTIME_SSP_SYSCALL_NAME(sock_recv) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_recv_from(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
void *buf,
size_t buf_len,
@ -1169,9 +1066,8 @@ __wasi_errno_t wasmtime_ssp_sock_recv_from(
) WASMTIME_SSP_SYSCALL_NAME(sock_recv_from) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_send(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
const void *buf,
size_t buf_len,
@ -1179,9 +1075,8 @@ __wasi_errno_t wasmtime_ssp_sock_send(
) WASMTIME_SSP_SYSCALL_NAME(sock_send) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_send_to(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds, struct addr_pool *addr_pool,
#endif
__wasi_fd_t sock,
const void *buf,
size_t buf_len,
@ -1191,317 +1086,278 @@ __wasi_errno_t wasmtime_ssp_sock_send_to(
) WASMTIME_SSP_SYSCALL_NAME(sock_send_to) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_shutdown(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock
) WASMTIME_SSP_SYSCALL_NAME(sock_shutdown) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_recv_timeout(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint64_t timeout_us
) WASMTIME_SSP_SYSCALL_NAME(sock_set_recv_timeout) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_recv_timeout(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint64_t *timeout_us
) WASMTIME_SSP_SYSCALL_NAME(sock_get_recv_timeout) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_send_timeout(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint64_t timeout_us
) WASMTIME_SSP_SYSCALL_NAME(sock_set_send_timeout) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_send_timeout(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint64_t *timeout_us
) WASMTIME_SSP_SYSCALL_NAME(sock_get_send_timeout) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_send_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
size_t bufsiz
) WASMTIME_SSP_SYSCALL_NAME(sock_set_send_buf_size) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_send_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
size_t *bufsiz
) WASMTIME_SSP_SYSCALL_NAME(sock_get_send_buf_size) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_recv_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
size_t bufsiz
) WASMTIME_SSP_SYSCALL_NAME(sock_set_recv_buf_size) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_recv_buf_size(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
size_t *bufsiz
) WASMTIME_SSP_SYSCALL_NAME(sock_get_recv_buf_size) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_keep_alive(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_keep_alive) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_keep_alive(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_keep_alive) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_reuse_addr(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_reuse_addr) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_reuse_addr(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_reuse_addr) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_reuse_port(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_reuse_port) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_reuse_port(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_reuse_port) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_linger(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool is_enabled,
int linger_s
) WASMTIME_SSP_SYSCALL_NAME(sock_set_linger) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_linger(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock, bool *is_enabled, int *linger_s
) WASMTIME_SSP_SYSCALL_NAME(sock_get_linger) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_broadcast(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_broadcast) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_broadcast(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_broadcast) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_tcp_no_delay(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_no_delay) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_tcp_no_delay(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_no_delay) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_tcp_quick_ack(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_quick_ack) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_tcp_quick_ack(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_quick_ack) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_tcp_keep_idle(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint32_t time_s
) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_keep_idle) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_tcp_keep_idle(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint32_t *time_s
) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_keep_idle) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_tcp_keep_intvl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint32_t time_s
) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_keep_intvl) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_tcp_keep_intvl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint32_t *time_s
) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_keep_intvl) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_tcp_fastopen_connect(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_tcp_fastopen_connect) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_tcp_fastopen_connect(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_tcp_fastopen_connect) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_loop(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool ipv6,
bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_multicast_loop) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_loop(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool ipv6,
bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_multicast_loop) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_ip_add_membership(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
__wasi_addr_ip_t *imr_multiaddr,
uint32_t imr_interface
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_add_membership) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_ip_drop_membership(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
__wasi_addr_ip_t *imr_multiaddr,
uint32_t imr_interface
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_drop_membership) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_ip_ttl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint8_t ttl_s
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_ttl) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_ip_ttl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint8_t *ttl_s
) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_ttl) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_ip_multicast_ttl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint8_t ttl_s
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ip_multicast_ttl) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_ip_multicast_ttl(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
uint8_t *ttl_s
) WASMTIME_SSP_SYSCALL_NAME(sock_get_ip_multicast_ttl) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_set_ipv6_only(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_set_ipv6_only) WARN_UNUSED;
__wasi_errno_t wasmtime_ssp_sock_get_ipv6_only(
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
wasm_exec_env_t exec_env,
struct fd_table *curfds,
#endif
__wasi_fd_t sock,
bool *is_enabled
) WASMTIME_SSP_SYSCALL_NAME(sock_get_ipv6_only) WARN_UNUSED;

View File

@ -0,0 +1,226 @@
/*
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <errno.h>
#include "ssp_config.h"
#include "blocking_op.h"
int
blocking_op_close(wasm_exec_env_t exec_env, int fd)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = close(fd);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
ssize_t
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt)
{
#ifdef BH_PLATFORM_WINDOWS
errno = ENOTSUP;
return -1;
#else
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = readv(fd, iov, iovcnt);
wasm_runtime_end_blocking_op(exec_env);
return ret;
#endif
}
#if CONFIG_HAS_PREADV
ssize_t
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = preadv(fd, iov, iovcnt, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
#else /* CONFIG_HAS_PREADV */
ssize_t
blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb,
off_t offset)
{
#ifdef BH_PLATFORM_WINDOWS
errno = ENOTSUP;
return -1;
#else
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = pread(fd, p, nb, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
#endif
}
#endif /* CONFIG_HAS_PREADV */
ssize_t
blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt)
{
#ifdef BH_PLATFORM_WINDOWS
errno = ENOTSUP;
return -1;
#else
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = writev(fd, iov, iovcnt);
wasm_runtime_end_blocking_op(exec_env);
return ret;
#endif
}
#if CONFIG_HAS_PWRITEV
ssize_t
blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = pwritev(fd, iov, iovcnt, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
#else /* CONFIG_HAS_PWRITEV */
ssize_t
blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb,
off_t offset)
{
#ifdef BH_PLATFORM_WINDOWS
errno = ENOTSUP;
return -1;
#else
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
ssize_t ret = pwrite(fd, p, nb, offset);
wasm_runtime_end_blocking_op(exec_env);
return ret;
#endif
}
#endif /* CONFIG_HAS_PWRITEV */
int
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
bh_socket_t *sockp, void *addr,
unsigned int *addrlenp)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = os_socket_accept(server_sock, sockp, addr, addrlenp);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
int
blocking_op_socket_connect(wasm_exec_env_t exec_env, bh_socket_t sock,
const char *addr, int port)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = os_socket_connect(sock, addr, port);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
int
blocking_op_socket_recv_from(wasm_exec_env_t exec_env, bh_socket_t sock,
void *buf, unsigned int len, int flags,
bh_sockaddr_t *src_addr)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = os_socket_recv_from(sock, buf, len, flags, src_addr);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
int
blocking_op_socket_send_to(wasm_exec_env_t exec_env, bh_socket_t sock,
const void *buf, unsigned int len, int flags,
const bh_sockaddr_t *dest_addr)
{
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = os_socket_send_to(sock, buf, len, flags, dest_addr);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
int
blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host,
const char *service, uint8_t *hint_is_tcp,
uint8_t *hint_is_ipv4,
bh_addr_info_t *addr_info,
size_t addr_info_size, size_t *max_info_size)
{
/*
* Note: Unlike others, os_socket_addr_resolve() is not a simple system
* call. It's likely backed by a complex libc function, getaddrinfo().
* Depending on the implementation of getaddrinfo() and underlying
* DNS resolver, it might or might not be possible to make it return
* with os_wakeup_blocking_op().
*
* Unfortunately, many of ISC/bind based resolvers just keep going on
* interrupted system calls. It includes macOS and glibc.
*
* On the other hand, NuttX as of writing this returns EAI_AGAIN
* on EINTR.
*/
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = os_socket_addr_resolve(host, service, hint_is_tcp, hint_is_ipv4,
addr_info, addr_info_size, max_info_size);
wasm_runtime_end_blocking_op(exec_env);
return ret;
}
int
blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path,
int oflags, mode_t mode)
{
#ifdef BH_PLATFORM_WINDOWS
errno = ENOTSUP;
return -1;
#else
if (!wasm_runtime_begin_blocking_op(exec_env)) {
errno = EINTR;
return -1;
}
int ret = openat(fd, path, oflags, mode);
wasm_runtime_end_blocking_op(exec_env);
return ret;
#endif
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "bh_platform.h"
#include "wasm_export.h"
int
blocking_op_close(wasm_exec_env_t exec_env, int fd);
ssize_t
blocking_op_readv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt);
ssize_t
blocking_op_preadv(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset);
ssize_t
blocking_op_pread(wasm_exec_env_t exec_env, int fd, void *p, size_t nb,
off_t offset);
ssize_t
blocking_op_writev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt);
ssize_t
blocking_op_pwritev(wasm_exec_env_t exec_env, int fd, const struct iovec *iov,
int iovcnt, off_t offset);
ssize_t
blocking_op_pwrite(wasm_exec_env_t exec_env, int fd, const void *p, size_t nb,
off_t offset);
int
blocking_op_socket_accept(wasm_exec_env_t exec_env, bh_socket_t server_sock,
bh_socket_t *sockp, void *addr,
unsigned int *addrlenp);
int
blocking_op_socket_connect(wasm_exec_env_t exec_env, bh_socket_t sock,
const char *addr, int port);
int
blocking_op_socket_recv_from(wasm_exec_env_t exec_env, bh_socket_t sock,
void *buf, unsigned int len, int flags,
bh_sockaddr_t *src_addr);
int
blocking_op_socket_send_to(wasm_exec_env_t exec_env, bh_socket_t sock,
const void *buf, unsigned int len, int flags,
const bh_sockaddr_t *dest_addr);
int
blocking_op_socket_addr_resolve(wasm_exec_env_t exec_env, const char *host,
const char *service, uint8_t *hint_is_tcp,
uint8_t *hint_is_ipv4,
bh_addr_info_t *addr_info,
size_t addr_info_size, size_t *max_info_size);
#ifdef BH_PLATFORM_WINDOWS
/* TODO to be (re)moved as part of WASI on windows work */
typedef unsigned mode_t;
#endif
int
blocking_op_openat(wasm_exec_env_t exec_env, int fd, const char *path,
int oflags, mode_t mode);

View File

@ -14,8 +14,8 @@
#ifndef SSP_CONFIG_H
#define SSP_CONFIG_H
#include "bh_platform.h"
#include "gnuc.h"
#include <stdlib.h>
#if defined(__FreeBSD__) || defined(__APPLE__) \
|| (defined(ANDROID) && __ANDROID_API__ < 28)
@ -66,7 +66,8 @@
#endif
#endif
#if !defined(__APPLE__) && !defined(ESP_PLATFORM) && !defined(_WIN32)
#if !defined(__APPLE__) && !defined(ESP_PLATFORM) && !defined(_WIN32) \
&& !defined(__COSMOPOLITAN__)
#define CONFIG_HAS_POSIX_FALLOCATE 1
#else
#define CONFIG_HAS_POSIX_FALLOCATE 0
@ -84,7 +85,8 @@
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0
#endif
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) && !defined(_WIN32)
#if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) && !defined(_WIN32) \
&& !defined(__COSMOPOLITAN__)
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
#else
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0
@ -102,10 +104,18 @@
#define st_mtim st_mtimespec
#endif
#ifdef __APPLE__
#define CONFIG_TLS_USE_GSBASE 1
#else
#define CONFIG_TLS_USE_GSBASE 0
#if defined(O_DSYNC)
#define CONFIG_HAS_O_DSYNC
#endif
// POSIX requires O_RSYNC to be defined, but Linux explicitly doesn't support
// it.
#if defined(O_RSYNC) && !defined(__linux__)
#define CONFIG_HAS_O_RSYNC
#endif
#if defined(O_SYNC)
#define CONFIG_HAS_O_SYNC
#endif
#if !defined(BH_PLATFORM_LINUX_SGX)

View File

@ -16,10 +16,6 @@
#include "debug_engine.h"
#endif
#if WASM_ENABLE_SHARED_MEMORY != 0
#include "wasm_shared_memory.h"
#endif
typedef struct {
bh_list_link l;
void (*destroy_cb)(WASMCluster *);
@ -32,6 +28,8 @@ static bh_list cluster_list_head;
static bh_list *const cluster_list = &cluster_list_head;
static korp_mutex cluster_list_lock;
static korp_mutex _exception_lock;
typedef void (*list_visitor)(void *, void *);
static uint32 cluster_max_thread_num = CLUSTER_MAX_THREAD_NUM;
@ -52,6 +50,10 @@ thread_manager_init()
return false;
if (os_mutex_init(&cluster_list_lock) != 0)
return false;
if (os_mutex_init(&_exception_lock) != 0) {
os_mutex_destroy(&cluster_list_lock);
return false;
}
return true;
}
@ -66,6 +68,7 @@ thread_manager_destroy()
cluster = next;
}
wasm_cluster_cancel_all_callbacks();
os_mutex_destroy(&_exception_lock);
os_mutex_destroy(&cluster_list_lock);
}
@ -477,9 +480,6 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
wasm_module_inst_t module_inst = get_module_inst(exec_env);
wasm_module_t module;
wasm_module_inst_t new_module_inst;
#if WASM_ENABLE_LIBC_WASI != 0
WASIContext *wasi_ctx;
#endif
WASMExecEnv *new_exec_env;
uint32 aux_stack_start, aux_stack_size;
uint32 stack_size = 8192;
@ -517,10 +517,7 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
wasm_runtime_set_custom_data_internal(
new_module_inst, wasm_runtime_get_custom_data(module_inst));
#if WASM_ENABLE_LIBC_WASI != 0
wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
#endif
wasm_native_inherit_contexts(new_module_inst, module_inst);
new_exec_env = wasm_exec_env_create_internal(new_module_inst,
exec_env->wasm_stack_size);
@ -1062,6 +1059,19 @@ set_thread_cancel_flags(WASMExecEnv *exec_env)
WASM_SUSPEND_FLAG_TERMINATE);
os_mutex_unlock(&exec_env->wait_lock);
#ifdef OS_ENABLE_WAKEUP_BLOCKING_OP
wasm_runtime_interrupt_blocking_op(exec_env);
#endif
}
static void
clear_thread_cancel_flags(WASMExecEnv *exec_env)
{
os_mutex_lock(&exec_env->wait_lock);
WASM_SUSPEND_FLAGS_FETCH_AND(exec_env->suspend_flags,
~WASM_SUSPEND_FLAG_TERMINATE);
os_mutex_unlock(&exec_env->wait_lock);
}
int32
@ -1240,72 +1250,55 @@ wasm_cluster_resume_all(WASMCluster *cluster)
os_mutex_unlock(&cluster->lock);
}
struct spread_exception_data {
WASMExecEnv *skip;
const char *exception;
};
static void
set_exception_visitor(void *node, void *user_data)
{
WASMExecEnv *curr_exec_env = (WASMExecEnv *)node;
WASMExecEnv *exec_env = (WASMExecEnv *)user_data;
WASMModuleInstanceCommon *module_inst = get_module_inst(exec_env);
WASMModuleInstance *wasm_inst = (WASMModuleInstance *)module_inst;
const struct spread_exception_data *data = user_data;
WASMExecEnv *exec_env = (WASMExecEnv *)node;
if (curr_exec_env != exec_env) {
WASMModuleInstance *curr_wasm_inst =
(WASMModuleInstance *)get_module_inst(curr_exec_env);
if (exec_env != data->skip) {
WASMModuleInstance *wasm_inst =
(WASMModuleInstance *)get_module_inst(exec_env);
/* Only spread non "wasi proc exit" exception */
#if WASM_ENABLE_SHARED_MEMORY != 0
if (curr_wasm_inst->memory_count > 0)
shared_memory_lock(curr_wasm_inst->memories[0]);
#endif
if (!strstr(wasm_inst->cur_exception, "wasi proc exit")) {
bh_memcpy_s(curr_wasm_inst->cur_exception,
sizeof(curr_wasm_inst->cur_exception),
wasm_inst->cur_exception,
sizeof(wasm_inst->cur_exception));
exception_lock(wasm_inst);
if (data->exception != NULL) {
snprintf(wasm_inst->cur_exception, sizeof(wasm_inst->cur_exception),
"Exception: %s", data->exception);
}
#if WASM_ENABLE_SHARED_MEMORY != 0
if (curr_wasm_inst->memory_count > 0)
shared_memory_unlock(curr_wasm_inst->memories[0]);
#endif
else {
wasm_inst->cur_exception[0] = '\0';
}
exception_unlock(wasm_inst);
/* Terminate the thread so it can exit from dead loops */
set_thread_cancel_flags(curr_exec_env);
}
}
static void
clear_exception_visitor(void *node, void *user_data)
{
WASMExecEnv *exec_env = (WASMExecEnv *)user_data;
WASMExecEnv *curr_exec_env = (WASMExecEnv *)node;
if (curr_exec_env != exec_env) {
WASMModuleInstance *curr_wasm_inst =
(WASMModuleInstance *)get_module_inst(curr_exec_env);
#if WASM_ENABLE_SHARED_MEMORY != 0
if (curr_wasm_inst->memory_count > 0)
shared_memory_lock(curr_wasm_inst->memories[0]);
#endif
curr_wasm_inst->cur_exception[0] = '\0';
#if WASM_ENABLE_SHARED_MEMORY != 0
if (curr_wasm_inst->memory_count > 0)
shared_memory_unlock(curr_wasm_inst->memories[0]);
#endif
if (data->exception != NULL) {
set_thread_cancel_flags(exec_env);
}
else {
clear_thread_cancel_flags(exec_env);
}
}
}
void
wasm_cluster_spread_exception(WASMExecEnv *exec_env, bool clear)
wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception)
{
const bool has_exception = exception != NULL;
WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env);
bh_assert(cluster);
struct spread_exception_data data;
data.skip = NULL;
data.exception = exception;
os_mutex_lock(&cluster->lock);
cluster->has_exception = !clear;
traverse_list(&cluster->exec_env_list,
clear ? clear_exception_visitor : set_exception_visitor,
exec_env);
cluster->has_exception = has_exception;
traverse_list(&cluster->exec_env_list, set_exception_visitor, &data);
os_mutex_unlock(&cluster->lock);
}
@ -1341,6 +1334,48 @@ wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
}
}
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
struct inst_set_context_data {
void *key;
void *ctx;
};
static void
set_context_visitor(void *node, void *user_data)
{
WASMExecEnv *curr_exec_env = (WASMExecEnv *)node;
WASMModuleInstanceCommon *module_inst = get_module_inst(curr_exec_env);
const struct inst_set_context_data *data = user_data;
wasm_runtime_set_context(module_inst, data->key, data->ctx);
}
void
wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key,
void *ctx)
{
WASMExecEnv *exec_env = wasm_clusters_search_exec_env(module_inst);
if (exec_env == NULL) {
/* Maybe threads have not been started yet. */
wasm_runtime_set_context(module_inst, key, ctx);
}
else {
WASMCluster *cluster;
struct inst_set_context_data data;
data.key = key;
data.ctx = ctx;
cluster = wasm_exec_env_get_cluster(exec_env);
bh_assert(cluster);
os_mutex_lock(&cluster->lock);
traverse_list(&cluster->exec_env_list, set_context_visitor, &data);
os_mutex_unlock(&cluster->lock);
}
}
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */
bool
wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env)
{
@ -1353,3 +1388,21 @@ wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env)
return is_thread_terminated;
}
void
exception_lock(WASMModuleInstance *module_inst)
{
/*
* Note: this lock could be per module instance if desirable.
* We can revisit on AOT version bump.
* It probably doesn't matter though because the exception handling
* logic should not be executed too frequently anyway.
*/
os_mutex_lock(&_exception_lock);
}
void
exception_unlock(WASMModuleInstance *module_inst)
{
os_mutex_unlock(&_exception_lock);
}

View File

@ -139,7 +139,7 @@ WASMExecEnv *
wasm_clusters_search_exec_env(WASMModuleInstanceCommon *module_inst);
void
wasm_cluster_spread_exception(WASMExecEnv *exec_env, bool clear);
wasm_cluster_set_exception(WASMExecEnv *exec_env, const char *exception);
WASMExecEnv *
wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env);
@ -151,6 +151,10 @@ void
wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
void *custom_data);
void
wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key,
void *ctx);
bool
wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env);

View File

@ -163,6 +163,7 @@ void
wasi_nn_destroy(wasm_module_inst_t instance)
{
WASINNContext *wasi_nn_ctx = wasm_runtime_get_wasi_nn_ctx(instance);
bh_hash_map_remove(hashmap, (void *)instance, NULL, NULL);
wasi_nn_ctx_destroy(wasi_nn_ctx);
}

View File

@ -69,3 +69,7 @@ os_mprotect(void *addr, size_t size, int prot)
void
os_dcache_flush()
{}
void
os_icache_flush(void *start, size_t len)
{}

View File

@ -359,3 +359,7 @@ os_thread_get_stack_boundary()
/* TODO: get alios stack boundary */
return NULL;
}
void
os_thread_jit_write_protect_np(bool enabled)
{}

View File

@ -140,16 +140,12 @@ seekdir(DIR *__dir, long __location);
#endif
#if __ANDROID_API__ < 24
ssize_t
preadv(int __fd, const struct iovec *__iov, int __count, off_t __offset);
ssize_t
pwritev(int __fd, const struct iovec *__iov, int __count, off_t __offset);
#endif
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_extension.h"
#ifdef OS_ENABLE_WAKEUP_BLOCKING_OP
static bool g_blocking_op_inited = false;
static int g_blocking_op_signo = SIGUSR1;
static sigset_t g_blocking_op_sigmask;
static void
blocking_op_sighandler(int signo)
{
/* nothing */
}
void
os_set_signal_number_for_blocking_op(int signo)
{
g_blocking_op_signo = signo;
}
int
os_blocking_op_init()
{
if (g_blocking_op_inited) {
return BHT_OK;
}
sigemptyset(&g_blocking_op_sigmask);
sigaddset(&g_blocking_op_sigmask, g_blocking_op_signo);
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = blocking_op_sighandler;
if (sigaction(g_blocking_op_signo, &sa, NULL)) {
return BHT_ERROR;
}
g_blocking_op_inited = true;
return BHT_OK;
}
void
os_begin_blocking_op()
{
pthread_sigmask(SIG_UNBLOCK, &g_blocking_op_sigmask, NULL);
}
void
os_end_blocking_op()
{
pthread_sigmask(SIG_BLOCK, &g_blocking_op_sigmask, NULL);
}
int
os_wakeup_blocking_op(korp_tid tid)
{
int ret = pthread_kill(tid, g_blocking_op_signo);
if (ret != 0) {
return BHT_ERROR;
}
return BHT_OK;
}
#endif /* OS_ENABLE_WAKEUP_BLOCKING_OP */

View File

@ -5,6 +5,10 @@
#include "platform_api_vmcore.h"
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
#include <libkern/OSCacheControl.h>
#endif
#ifndef BH_ENABLE_TRACE_MMAP
#define BH_ENABLE_TRACE_MMAP 0
#endif
@ -36,7 +40,11 @@ void *
os_mmap(void *hint, size_t size, int prot, int flags)
{
int map_prot = PROT_NONE;
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_JIT;
#else
int map_flags = MAP_ANONYMOUS | MAP_PRIVATE;
#endif
uint64 request_size, page_size;
uint8 *addr = MAP_FAILED;
uint32 i;
@ -251,3 +259,11 @@ os_mprotect(void *addr, size_t size, int prot)
void
os_dcache_flush(void)
{}
void
os_icache_flush(void *start, size_t len)
{
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
sys_icache_invalidate(start, len);
#endif
}

View File

@ -0,0 +1,20 @@
/*
* Copyright (C) 2023 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <time.h>
#include "platform_api_extension.h"
int
os_usleep(uint32 usec)
{
struct timespec ts;
int ret;
ts.tv_sec = usec / 1000000;
ts.tv_nsec = (usec % 1000000) * 1000;
ret = nanosleep(&ts, NULL);
return ret == 0 ? 0 : -1;
}

View File

@ -53,7 +53,7 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr,
struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
bh_sockaddr->port = ntohs(addr->sin_port);
bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->addr_buffer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->is_ipv4 = true;
return BHT_OK;
}
@ -65,12 +65,12 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr,
bh_sockaddr->port = ntohs(addr->sin6_port);
for (i = 0; i < sizeof(bh_sockaddr->addr_bufer.ipv6)
/ sizeof(bh_sockaddr->addr_bufer.ipv6[0]);
for (i = 0; i < sizeof(bh_sockaddr->addr_buffer.ipv6)
/ sizeof(bh_sockaddr->addr_buffer.ipv6[0]);
i++) {
uint16 part_addr = addr->sin6_addr.s6_addr[i * 2]
| (addr->sin6_addr.s6_addr[i * 2 + 1] << 8);
bh_sockaddr->addr_bufer.ipv6[i] = ntohs(part_addr);
bh_sockaddr->addr_buffer.ipv6[i] = ntohs(part_addr);
}
bh_sockaddr->is_ipv4 = false;
@ -91,7 +91,7 @@ bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr,
struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
addr->sin_port = htons(bh_sockaddr->port);
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_bufer.ipv4);
addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_buffer.ipv4);
*socklen = sizeof(*addr);
}
#ifdef IPPROTO_IPV6
@ -101,10 +101,10 @@ bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr,
addr->sin6_port = htons(bh_sockaddr->port);
addr->sin6_family = AF_INET6;
for (i = 0; i < sizeof(bh_sockaddr->addr_bufer.ipv6)
/ sizeof(bh_sockaddr->addr_bufer.ipv6[0]);
for (i = 0; i < sizeof(bh_sockaddr->addr_buffer.ipv6)
/ sizeof(bh_sockaddr->addr_buffer.ipv6[0]);
i++) {
uint16 part_addr = htons(bh_sockaddr->addr_bufer.ipv6[i]);
uint16 part_addr = htons(bh_sockaddr->addr_buffer.ipv6[i]);
addr->sin6_addr.s6_addr[i * 2] = 0xff & part_addr;
addr->sin6_addr.s6_addr[i * 2 + 1] = (0xff00 & part_addr) >> 8;
}
@ -799,7 +799,7 @@ os_socket_set_ip_add_membership(bh_socket_t socket,
{
assert(imr_multiaddr);
if (is_ipv6) {
#ifdef IPPROTO_IPV6
#if defined(IPPROTO_IPV6) && !defined(BH_PLATFORM_COSMOPOLITAN)
struct ipv6_mreq mreq;
for (int i = 0; i < 8; i++) {
((uint16_t *)mreq.ipv6mr_multiaddr.s6_addr)[i] =
@ -837,7 +837,7 @@ os_socket_set_ip_drop_membership(bh_socket_t socket,
{
assert(imr_multiaddr);
if (is_ipv6) {
#ifdef IPPROTO_IPV6
#if defined(IPPROTO_IPV6) && !defined(BH_PLATFORM_COSMOPOLITAN)
struct ipv6_mreq mreq;
for (int i = 0; i < 8; i++) {
((uint16_t *)mreq.ipv6mr_multiaddr.s6_addr)[i] =

View File

@ -39,6 +39,9 @@ os_thread_wrapper(void *arg)
#ifdef OS_ENABLE_HW_BOUND_CHECK
if (os_thread_signal_init(handler) != 0)
return NULL;
#endif
#ifdef OS_ENABLE_WAKEUP_BLOCKING_OP
os_end_blocking_op();
#endif
start_func(thread_arg);
#ifdef OS_ENABLE_HW_BOUND_CHECK
@ -470,6 +473,14 @@ os_thread_get_stack_boundary()
return addr;
}
void
os_thread_jit_write_protect_np(bool enabled)
{
#if (defined(__APPLE__) || defined(__MACH__)) && defined(__arm64__)
pthread_jit_write_protect_np(enabled);
#endif
}
#ifdef OS_ENABLE_HW_BOUND_CHECK
#define SIG_ALT_STACK_SIZE (32 * 1024)
@ -564,8 +575,8 @@ mask_signals(int how)
pthread_sigmask(how, &set, NULL);
}
static os_thread_local_attribute struct sigaction prev_sig_act_SIGSEGV;
static os_thread_local_attribute struct sigaction prev_sig_act_SIGBUS;
static struct sigaction prev_sig_act_SIGSEGV;
static struct sigaction prev_sig_act_SIGBUS;
/* ASAN is not designed to work with custom stack unwind or other low-level \
things. > Ignore a function that does some low-level magic. (e.g. walking \
@ -596,9 +607,12 @@ signal_callback(int sig_num, siginfo_t *sig_info, void *sig_ucontext)
prev_sig_act->sa_sigaction(sig_num, sig_info, sig_ucontext);
}
else if (prev_sig_act
&& ((void *)prev_sig_act->sa_sigaction == SIG_DFL
|| (void *)prev_sig_act->sa_sigaction == SIG_IGN)) {
sigaction(sig_num, prev_sig_act, NULL);
&& prev_sig_act->sa_handler
/* Filter out SIG_DFL and SIG_IGN here, they will
run into the else branch below */
&& (void *)prev_sig_act->sa_handler != SIG_DFL
&& (void *)prev_sig_act->sa_handler != SIG_IGN) {
prev_sig_act->sa_handler(sig_num);
}
/* Output signal info and then crash if signal is unhandled */
else {

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "platform_api_vmcore.h"
int
bh_platform_init()
{
return 0;
}
void
bh_platform_destroy()
{}
int
os_printf(const char *format, ...)
{
int ret = 0;
va_list ap;
va_start(ap, format);
#ifndef BH_VPRINTF
ret += vprintf(format, ap);
#else
ret += BH_VPRINTF(format, ap);
#endif
va_end(ap);
return ret;
}
int
os_vprintf(const char *format, va_list ap)
{
#ifndef BH_VPRINTF
return vprintf(format, ap);
#else
return BH_VPRINTF(format, ap);
#endif
}

View File

@ -0,0 +1,122 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* Copyright (C) 2023 Dylibso. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#ifndef _PLATFORM_INTERNAL_H
#define _PLATFORM_INTERNAL_H
#include <inttypes.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <signal.h>
#include <semaphore.h>
#include <limits.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
#include <sched.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/resource.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BH_PLATFORM_COSMOPOLITAN
#define BH_PLATFORM_COSMOPOLITAN
#endif
/* Stack size of applet threads's native part. */
#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024)
/* Default thread priority */
#define BH_THREAD_DEFAULT_PRIORITY 0
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
typedef pthread_cond_t korp_cond;
typedef pthread_t korp_thread;
typedef sem_t korp_sem;
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#define os_thread_local_attribute __thread
#define bh_socket_t int
#if WASM_DISABLE_WRITE_GS_BASE == 0
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
#define os_writegsbase(base_addr) \
do { \
uint64 __gs_value = (uint64)(uintptr_t)base_addr; \
asm volatile("wrgsbase %0" ::"r"(__gs_value) : "memory"); \
} while (0)
#if 0
/* _writegsbase_u64 also works, but need to add -mfsgsbase flag for gcc */
#include <immintrin.h>
#define os_writegsbase(base_addr) \
_writegsbase_u64(((uint64)(uintptr_t)base_addr))
#endif
#endif
#endif
#if WASM_DISABLE_HW_BOUND_CHECK == 0
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
|| defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \
|| defined(BUILD_TARGET_RISCV64_LP64)
#include <setjmp.h>
#define OS_ENABLE_HW_BOUND_CHECK
typedef jmp_buf korp_jmpbuf;
#define os_setjmp setjmp
#define os_longjmp longjmp
#define os_alloca alloca
#define os_getpagesize getpagesize
typedef void (*os_signal_handler)(void *sig_addr);
int
os_thread_signal_init(os_signal_handler handler);
void
os_thread_signal_destroy();
bool
os_thread_signal_inited();
void
os_signal_unmask();
void
os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#ifdef __cplusplus
}
#endif
#endif /* end of _PLATFORM_INTERNAL_H */

View File

@ -0,0 +1,19 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# Copyright (C) 2023 Dylibso. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
add_definitions(-DBH_PLATFORM_COSMOPOLITAN)
include_directories(${PLATFORM_SHARED_DIR})
include_directories(${PLATFORM_SHARED_DIR}/../include)
include (${CMAKE_CURRENT_LIST_DIR}/../common/posix/platform_api_posix.cmake)
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_POSIX_SOURCE})
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})

View File

@ -103,6 +103,12 @@ os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
#define OS_ENABLE_WAKEUP_BLOCKING_OP
#endif
void
os_set_signal_number_for_blocking_op(int signo);
#ifdef __cplusplus
}
#endif

View File

@ -100,6 +100,10 @@ void
#endif
}
void
os_icache_flush(void *start, size_t len)
{}
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
void *
os_get_dbus_mirror(void *ibus)

View File

@ -53,6 +53,10 @@ os_thread_get_stack_boundary(void)
#endif
}
void
os_thread_jit_write_protect_np(bool enabled)
{}
int
os_usleep(uint32 usec)
{

View File

@ -30,7 +30,7 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, socklen_t socklen,
assert(socklen >= sizeof(struct sockaddr_in));
bh_sockaddr->port = ntohs(addr->sin_port);
bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->addr_buffer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->is_ipv4 = true;
return BHT_OK;
}

View File

@ -102,6 +102,12 @@ os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
#define OS_ENABLE_WAKEUP_BLOCKING_OP
#endif
void
os_set_signal_number_for_blocking_op(int signo);
#ifdef __cplusplus
}
#endif

View File

@ -373,6 +373,34 @@ os_sem_getvalue(korp_sem *sem, int *sval);
int
os_sem_unlink(const char *name);
/**
* Initialize process-global state for os_wakeup_blocking_op.
*/
int
os_blocking_op_init();
/**
* Start accepting os_wakeup_blocking_op requests for the calling thread.
*/
void
os_begin_blocking_op();
/**
* Stop accepting os_wakeup_blocking_op requests for the calling thread.
*/
void
os_end_blocking_op();
/**
* Wake up the specified thread.
*
* For example, on posix-like platforms, this can be implemented by
* sending a signal (w/o SA_RESTART) which interrupts a blocking
* system call.
*/
int
os_wakeup_blocking_op(korp_tid tid);
/****************************************************
* Section 2 *
* Socket support *
@ -392,7 +420,7 @@ typedef union {
} bh_ip_addr_buffer_t;
typedef struct {
bh_ip_addr_buffer_t addr_bufer;
bh_ip_addr_buffer_t addr_buffer;
uint16 port;
bool is_ipv4;
} bh_sockaddr_t;

View File

@ -81,6 +81,13 @@ os_self_thread(void);
uint8 *
os_thread_get_stack_boundary(void);
/**
* Set whether the MAP_JIT region write protection is enabled for this thread.
* Pass true to make the region executable, false to make it writable.
*/
void
os_thread_jit_write_protect_np(bool enabled);
/**
************** mutext APIs ***********
* vmcore: Not required until pthread is supported by runtime
@ -143,6 +150,12 @@ os_get_dbus_mirror(void *ibus);
void
os_dcache_flush(void);
/**
* Flush instruction cache.
*/
void
os_icache_flush(void *start, size_t len);
#ifdef __cplusplus
}
#endif

View File

@ -195,3 +195,7 @@ os_mprotect(void *addr, size_t size, int prot)
void
os_dcache_flush(void)
{}
void
os_icache_flush(void *start, size_t len)
{}

View File

@ -261,7 +261,7 @@ sockaddr_to_bh_sockaddr(const struct sockaddr *sockaddr, socklen_t socklen,
assert(socklen >= sizeof(struct sockaddr_in));
bh_sockaddr->port = ntohs(addr->sin_port);
bh_sockaddr->addr_bufer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->addr_buffer.ipv4 = ntohl(addr->sin_addr.s_addr);
bh_sockaddr->is_ipv4 = true;
return BHT_OK;
}
@ -279,7 +279,7 @@ bh_sockaddr_to_sockaddr(const bh_sockaddr_t *bh_sockaddr,
struct sockaddr_in *addr = (struct sockaddr_in *)sockaddr;
addr->sin_port = htons(bh_sockaddr->port);
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_bufer.ipv4);
addr->sin_addr.s_addr = htonl(bh_sockaddr->addr_buffer.ipv4);
*socklen = sizeof(*addr);
return BHT_OK;
}

View File

@ -211,6 +211,10 @@ os_thread_get_stack_boundary()
return NULL;
}
void
os_thread_jit_write_protect_np(bool enabled)
{}
int
os_rwlock_init(korp_rwlock *lock)
{

View File

@ -116,6 +116,12 @@ os_sigreturn();
#endif /* end of BUILD_TARGET_X86_64/AMD_64/AARCH64/RISCV64 */
#endif /* end of WASM_DISABLE_HW_BOUND_CHECK */
#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
#define OS_ENABLE_WAKEUP_BLOCKING_OP
#endif
void
os_set_signal_number_for_blocking_op(int signo);
#ifdef __cplusplus
}
#endif

View File

@ -144,6 +144,10 @@ os_dcache_flush()
bus_sync();
}
void
os_icache_flush(void *start, size_t len)
{}
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
void *
os_get_dbus_mirror(void *ibus)

View File

@ -124,6 +124,12 @@ utimensat(int fd, const char *path, const struct timespec ts[2], int flag);
DIR *
fdopendir(int fd);
#if WASM_DISABLE_WAKEUP_BLOCKING_OP == 0
#define OS_ENABLE_WAKEUP_BLOCKING_OP
#endif
void
os_set_signal_number_for_blocking_op(int signo);
#ifdef __cplusplus
}
#endif

View File

@ -79,3 +79,7 @@ os_dcache_flush(void)
irq_unlock(key);
#endif
}
void
os_icache_flush(void *start, size_t len)
{}

View File

@ -430,3 +430,7 @@ os_thread_get_stack_boundary()
return NULL;
#endif
}
void
os_thread_jit_write_protect_np(bool enabled)
{}

View File

@ -140,6 +140,10 @@ os_thread_get_stack_boundary(void)
return tid->stack_addr;
}
void
os_thread_jit_write_protect_np(bool enabled)
{}
int
os_mutex_init(korp_mutex *mutex)
{
@ -207,3 +211,7 @@ os_mprotect(void *addr, size_t size, int prot)
void
os_dcache_flush(void)
{}
void
os_icache_flush(void *start, size_t len)
{}

View File

@ -73,3 +73,7 @@ os_getpagesize()
void
os_dcache_flush(void)
{}
void
os_icache_flush(void *start, size_t len)
{}

Some files were not shown because too many files have changed in this diff Show More