diff --git a/core/iwasm/common/wasm_exec_env.c b/core/iwasm/common/wasm_exec_env.c index 7128b4c63..48465fc94 100644 --- a/core/iwasm/common/wasm_exec_env.c +++ b/core/iwasm/common/wasm_exec_env.c @@ -282,8 +282,13 @@ wasm_exec_env_set_thread_info(WASMExecEnv *exec_env) os_mutex_lock(&exec_env->wait_lock); #endif exec_env->handle = os_self_thread(); - exec_env->native_stack_boundary = - stack_boundary ? stack_boundary + WASM_STACK_GUARD_SIZE : NULL; + if (exec_env->user_native_stack_boundary) + /* WASM_STACK_GUARD_SIZE isn't added for flexibility to developer, + he must ensure that enough guard bytes are kept. */ + exec_env->native_stack_boundary = exec_env->user_native_stack_boundary; + else + exec_env->native_stack_boundary = + stack_boundary ? stack_boundary + WASM_STACK_GUARD_SIZE : NULL; exec_env->native_stack_top_min = (void *)UINTPTR_MAX; #if WASM_ENABLE_THREAD_MGR != 0 os_mutex_unlock(&exec_env->wait_lock); diff --git a/core/iwasm/common/wasm_exec_env.h b/core/iwasm/common/wasm_exec_env.h index 53d248755..ce0c1fa7f 100644 --- a/core/iwasm/common/wasm_exec_env.h +++ b/core/iwasm/common/wasm_exec_env.h @@ -136,6 +136,10 @@ typedef struct WASMExecEnv { void *user_data; + /* The boundary of native stack set by host embedder. It is used + if it is not NULL when calling wasm functions. */ + uint8 *user_native_stack_boundary; + /* The native thread handle of current thread */ korp_tid handle; diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index cc3b4bb95..1c77b2e4d 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -2225,6 +2225,13 @@ wasm_runtime_get_user_data(WASMExecEnv *exec_env) return exec_env->user_data; } +void +wasm_runtime_set_native_stack_boundary(WASMExecEnv *exec_env, + uint8 *native_stack_boundary) +{ + exec_env->user_native_stack_boundary = native_stack_boundary; +} + #ifdef OS_ENABLE_HW_BOUND_CHECK void wasm_runtime_access_exce_check_guard_page() diff --git a/core/iwasm/common/wasm_runtime_common.h b/core/iwasm/common/wasm_runtime_common.h index fb2c79408..4c7dfed4f 100644 --- a/core/iwasm/common/wasm_runtime_common.h +++ b/core/iwasm/common/wasm_runtime_common.h @@ -673,6 +673,11 @@ wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data); WASM_RUNTIME_API_EXTERN void * wasm_runtime_get_user_data(WASMExecEnv *exec_env); +/* See wasm_export.h for description */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_native_stack_boundary(WASMExecEnv *exec_env, + uint8 *native_stack_boundary); + #if WASM_CONFIGURABLE_BOUNDS_CHECKS != 0 /* See wasm_export.h for description */ WASM_RUNTIME_API_EXTERN void diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h index dfb6b8023..aa6cfaae7 100644 --- a/core/iwasm/include/wasm_export.h +++ b/core/iwasm/include/wasm_export.h @@ -1755,6 +1755,26 @@ wasm_runtime_set_user_data(wasm_exec_env_t exec_env, void *user_data); WASM_RUNTIME_API_EXTERN void * wasm_runtime_get_user_data(wasm_exec_env_t exec_env); +/** + * Set native stack boundary to execution environment, if it is set, + * it will be used instead of getting the boundary with the platform + * layer API when calling wasm functions. This is useful for some + * fiber cases. + * + * Note: unlike setting the boundary by runtime, this API doesn't add + * the WASM_STACK_GUARD_SIZE(see comments in core/config.h) to the + * exec_env's native_stack_boundary to reserve bytes to the native + * thread stack boundary, which is used to throw native stack overflow + * exception if the guard boundary is reached. Developer should ensure + * that enough guard bytes are kept. + * + * @param exec_env the execution environment + * @param native_stack_boundary the user data to be set + */ +WASM_RUNTIME_API_EXTERN void +wasm_runtime_set_native_stack_boundary(wasm_exec_env_t exec_env, + uint8_t *native_stack_boundary); + /** * Dump runtime memory consumption, including: * Exec env memory consumption