Browse Source

Fix issue of restoring wasm operand stack (#1721)

Xu Jun 3 years ago
parent
commit
ae580d481b

+ 0 - 12
core/iwasm/interpreter/wasm_interp.h

@@ -89,18 +89,6 @@ 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

+ 0 - 20
core/iwasm/interpreter/wasm_interp_classic.c

@@ -805,26 +805,6 @@ 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,

+ 0 - 20
core/iwasm/interpreter/wasm_interp_fast.c

@@ -869,26 +869,6 @@ 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,

+ 9 - 2
core/iwasm/interpreter/wasm_runtime.c

@@ -2027,6 +2027,8 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
     WASMJmpBuf jmpbuf_node = { 0 }, *jmpbuf_node_pop;
     uint32 page_size = os_getpagesize();
     uint32 guard_page_count = STACK_OVERFLOW_CHECK_GUARD_PAGE_COUNT;
+    WASMRuntimeFrame *prev_frame = wasm_exec_env_get_cur_frame(exec_env);
+    uint8 *prev_top = exec_env->wasm_stack.s.top;
 #ifdef BH_PLATFORM_WINDOWS
     const char *exce;
     int result;
@@ -2081,13 +2083,18 @@ call_wasm_with_hw_bound_check(WASMModuleInstance *module_inst,
         ret = false;
     }
 
-    if (wasm_get_exception(module_inst)) {
+    /* Note: can't check wasm_get_exception(module_inst) here, there may be
+     * exception which is not caught by hardware (e.g. uninitialized elements),
+     * then the stack-frame is already freed inside wasm_interp_call_wasm */
+    if (!ret) {
 #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);
+        /* Restore operand frames */
+        wasm_exec_env_set_cur_frame(exec_env, prev_frame);
+        exec_env->wasm_stack.s.top = prev_top;
     }
 
     jmpbuf_node_pop = wasm_exec_env_pop_jmpbuf(exec_env);