diff --git a/core/iwasm/common/wasm_exec_env.h b/core/iwasm/common/wasm_exec_env.h index 5d80312fb..6083280b4 100644 --- a/core/iwasm/common/wasm_exec_env.h +++ b/core/iwasm/common/wasm_exec_env.h @@ -30,6 +30,10 @@ typedef struct WASMCurrentEnvStatus WASMCurrentEnvStatus; typedef struct WASMJmpBuf { struct WASMJmpBuf *prev; korp_jmpbuf jmpbuf; +#if WASM_ENABLE_MULTI_MODULE != 0 + /* The owner module instance associated with the current jmpbuf. Used in multi-module to propagate the exception */ + struct WASMModuleInstanceCommon *module_inst; +#endif } WASMJmpBuf; #endif diff --git a/core/iwasm/common/wasm_runtime_common.c b/core/iwasm/common/wasm_runtime_common.c index 259816e0b..7a5ded2cf 100644 --- a/core/iwasm/common/wasm_runtime_common.c +++ b/core/iwasm/common/wasm_runtime_common.c @@ -248,6 +248,15 @@ runtime_signal_handler(void *sig_addr) if (is_sig_addr_in_guard_pages(sig_addr, module_inst)) { wasm_set_exception(module_inst, "out of bounds memory access"); +#if WASM_ENABLE_MULTI_MODULE != 0 + if (jmpbuf_node->module_inst + && jmpbuf_node->module_inst + != (WASMModuleInstanceCommon *)module_inst) { + wasm_runtime_propagate_exception_from_import( + (WASMModuleInstance *)jmpbuf_node->module_inst, + module_inst); + } +#endif os_longjmp(jmpbuf_node->jmpbuf, 1); } #if WASM_DISABLE_STACK_HW_BOUND_CHECK == 0 @@ -375,6 +384,15 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info) the wasm func returns, the caller will check whether the exception is thrown and return to runtime. */ wasm_set_exception(module_inst, "out of bounds memory access"); +#if WASM_ENABLE_MULTI_MODULE != 0 + if (jmpbuf_node->module_inst + && jmpbuf_node->module_inst + != (WASMModuleInstanceCommon *)module_inst) { + wasm_runtime_propagate_exception_from_import( + (WASMModuleInstance *)jmpbuf_node->module_inst, + module_inst); + } +#endif ret = next_action(module_inst, exce_info); if (ret == EXCEPTION_CONTINUE_SEARCH || ret == EXCEPTION_CONTINUE_EXECUTION) diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index a59bc9257..f07950630 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -103,6 +103,29 @@ wasm_resolve_symbols(WASMModule *module) return ret; } +#if WASM_ENABLE_MULTI_MODULE != 0 +void +wasm_runtime_propagate_exception_from_import(WASMModuleInstance *parent, + WASMModuleInstance *sub_module) +{ + static const char exception_prefix[] = "Exception: "; + const char *message = NULL; + + if (!parent || !sub_module) + return; + + message = wasm_get_exception(sub_module); + if (message && message[0] != '\0') { + if (!strncmp(message, exception_prefix, sizeof(exception_prefix) - 1)) { + message += sizeof(exception_prefix) - 1; + } + + wasm_set_exception(parent, message); + wasm_set_exception(sub_module, NULL); + } +} +#endif + #if WASM_ENABLE_MULTI_MODULE != 0 static WASMFunction * wasm_resolve_function(const char *module_name, const char *function_name, @@ -3621,6 +3644,10 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst, return; } +#if WASM_ENABLE_MULTI_MODULE != 0 + jmpbuf_node.module_inst = (WASMModuleInstanceCommon *)module_inst; +#endif + wasm_exec_env_push_jmpbuf(exec_env, &jmpbuf_node); if (os_setjmp(jmpbuf_node.jmpbuf) == 0) { diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 0ba2049af..fef6eda43 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -593,6 +593,10 @@ wasm_lookup_tag(const WASMModuleInstance *module_inst, const char *name, const char *signature); #endif +void +wasm_runtime_propagate_exception_from_import(WASMModuleInstance *parent, + WASMModuleInstance *sub_module); + #endif bool