diff --git a/core/iwasm/interpreter/wasm_interp.h b/core/iwasm/interpreter/wasm_interp.h index d3692ff2..9010c942 100644 --- a/core/iwasm/interpreter/wasm_interp.h +++ b/core/iwasm/interpreter/wasm_interp.h @@ -89,6 +89,18 @@ wasm_interp_call_wasm(struct WASMModuleInstance *module_inst, struct WASMFunctionInstance *function, uint32 argc, uint32 argv[]); +/** + * @brief Restore the wasm stack frame to the last native frame or the begging + * of the whole stack + * @note e.g. for stack "begin --> interp --> interp", it will back to the + * "begin", for stack "begin --> interp --> native --> interp", it will become + * "begin --> interp --> native" + * + * @param exec_env the execution environment + */ +void +wasm_interp_restore_wasm_frame(struct WASMExecEnv *exec_env); + #ifdef __cplusplus } #endif diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index ab66bd09..24071cf1 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -781,6 +781,26 @@ FREE_FRAME(WASMExecEnv *exec_env, WASMInterpFrame *frame) wasm_exec_env_free_wasm_frame(exec_env, frame); } +void +wasm_interp_restore_wasm_frame(WASMExecEnv *exec_env) +{ + WASMInterpFrame *cur_frame, *prev_frame; + + cur_frame = wasm_exec_env_get_cur_frame(exec_env); + while (cur_frame) { + prev_frame = cur_frame->prev_frame; + if (cur_frame->ip) { + /* FREE_FRAME just set the wasm_stack.s.top pointer, we only need to + * call it once */ + FREE_FRAME(exec_env, cur_frame); + break; + } + cur_frame = prev_frame; + } + + wasm_exec_env_set_cur_frame(exec_env, cur_frame); +} + static void wasm_interp_call_func_native(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 184b0dc9..49cbce5c 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -845,6 +845,26 @@ FREE_FRAME(WASMExecEnv *exec_env, WASMInterpFrame *frame) wasm_exec_env_free_wasm_frame(exec_env, frame); } +void +wasm_interp_restore_wasm_frame(WASMExecEnv *exec_env) +{ + WASMInterpFrame *cur_frame, *prev_frame; + + cur_frame = wasm_exec_env_get_cur_frame(exec_env); + while (cur_frame) { + prev_frame = cur_frame->prev_frame; + if (cur_frame->ip) { + /* FREE_FRAME just set the wasm_stack.s.top pointer, we only need to + * call it once */ + FREE_FRAME(exec_env, cur_frame); + break; + } + cur_frame = prev_frame; + } + + wasm_exec_env_set_cur_frame(exec_env, cur_frame); +} + static void wasm_interp_call_func_native(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, @@ -3925,6 +3945,7 @@ wasm_interp_call_wasm(WASMModuleInstance *module_inst, WASMExecEnv *exec_env, wasm_interp_dump_call_stack(exec_env, true, NULL, 0); } #endif + LOG_DEBUG("meet an exception %s", wasm_get_exception(module_inst)); } wasm_exec_env_set_cur_frame(exec_env, prev_frame); diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index 6009b749..1d590bd6 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1986,6 +1986,15 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst, ret = false; } + if (wasm_get_exception(module_inst)) { +#if WASM_ENABLE_DUMP_CALL_STACK != 0 + if (wasm_interp_create_call_stack(exec_env)) { + wasm_interp_dump_call_stack(exec_env, true, NULL, 0); + } +#endif + wasm_interp_restore_wasm_frame(exec_env); + } + jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env); bh_assert(&jmpbuf_node == jmpbuf_node_pop); if (!exec_env->jmpbuf_stack_top) {