blob: d1c44c98dceda0095ee52795374f46252b1f254b [file] [edit]
diff --git a/core/iwasm/aot/aot_runtime.h b/core/iwasm/aot/aot_runtime.h
index d06cd10..c9bf9ed 100644
--- a/core/iwasm/aot/aot_runtime.h
+++ b/core/iwasm/aot/aot_runtime.h
@@ -349,6 +349,13 @@ typedef struct AOTModule {
/* Whether the underlying wasm binary buffer can be freed */
bool is_binary_freeable;
+ /* rive patch: artifact compiled without sw bounds checks, so exceptions
+ unwind through the exce_check guard page; sw artifacts unwind by
+ checked returns and must never take that longjmp. Set by the embedder
+ via wasm_runtime_set_module_hw_bounds; the file format records
+ nothing. */
+ bool rive_hw_bounds;
+
/* `.data` sections merged into one mmaped to reduce the tlb cache miss */
uint8 *merged_data_sections;
uint32 merged_data_sections_size;
diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c
index 5853813..a5a2e24 100644
--- a/core/iwasm/common/wasm_runtime_common.c
+++ b/core/iwasm/common/wasm_runtime_common.c
@@ -2331,10 +2331,27 @@ wasm_runtime_set_native_stack_boundary(WASMExecEnv *exec_env,
}
#ifdef OS_ENABLE_HW_BOUND_CHECK
+/* rive patch: only hw-bounds AOT artifacts unwind through the guard page;
+ sw artifacts emit checked returns after every call and a longjmp here
+ would skip native frames between nested wasm entries (the sjlj glue). */
+static bool
+module_inst_uses_hw_unwind(WASMModuleInstanceCommon *module_inst)
+{
+#if WASM_ENABLE_AOT != 0
+ if (module_inst && module_inst->module_type == Wasm_Module_AoT) {
+ AOTModule *module =
+ (AOTModule *)((AOTModuleInstance *)module_inst)->module;
+ return module && module->rive_hw_bounds;
+ }
+#endif
+ return false;
+}
+
void
wasm_runtime_access_exce_check_guard_page()
{
- if (exec_env_tls && exec_env_tls->handle == os_self_thread()) {
+ if (exec_env_tls && exec_env_tls->handle == os_self_thread()
+ && module_inst_uses_hw_unwind(exec_env_tls->module_inst)) {
uint32 page_size = os_getpagesize();
memset(exec_env_tls->exce_check_guard_page, 0, page_size);
}
@@ -2350,6 +2367,19 @@ wasm_runtime_set_instruction_count_limit(WASMExecEnv *exec_env,
}
#endif
+void
+wasm_runtime_set_module_hw_bounds(WASMModuleCommon *module, bool hw_bounds)
+{
+#if WASM_ENABLE_AOT != 0
+ if (module && module->module_type == Wasm_Module_AoT) {
+ ((AOTModule *)module)->rive_hw_bounds = hw_bounds;
+ }
+#else
+ (void)module;
+#endif
+ (void)hw_bounds;
+}
+
WASMFuncType *
wasm_runtime_get_function_type(const WASMFunctionInstanceCommon *function,
uint32 module_type)
diff --git a/core/iwasm/include/wasm_export.h b/core/iwasm/include/wasm_export.h
index 81efb8f..a510f3c 100644
--- a/core/iwasm/include/wasm_export.h
+++ b/core/iwasm/include/wasm_export.h
@@ -2287,6 +2287,13 @@ wasm_runtime_set_module_name(wasm_module_t module, const char *name,
WASM_RUNTIME_API_EXTERN const char *
wasm_runtime_get_module_name(wasm_module_t module);
+/* rive patch: mark an AOT module as compiled without sw bounds checks
+ (wamrc --bounds-checks=0) so runtime exceptions unwind through the hw
+ trap guard page. Default false: sw artifacts unwind by checked returns.
+ The AOT file format records nothing, so the embedder must know. */
+WASM_RUNTIME_API_EXTERN void
+wasm_runtime_set_module_hw_bounds(wasm_module_t module, bool hw_bounds);
+
/*
* wasm_runtime_detect_native_stack_overflow
*