interp: Restore context from prev_frame after tail calling a native function (#3283)
The current frame was freed before tail calling to an import or native function and the prev_frame was set as exec_env's cur_frame, so after the tail calling, we should recover context from prev_frame but not current frame. Found in https://github.com/bytecodealliance/wasm-micro-runtime/issues/3279.
This commit is contained in:
@ -1501,6 +1501,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
WASMStringviewIterObjectRef stringview_iter_obj;
|
||||
#endif
|
||||
#endif
|
||||
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||
bool is_return_call = false;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
#define HANDLE_OPCODE(op) &&HANDLE_##op
|
||||
@ -5618,6 +5621,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
{
|
||||
frame = prev_frame;
|
||||
frame_ip = frame->ip;
|
||||
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||
is_return_call = false;
|
||||
#endif
|
||||
goto call_func_from_entry;
|
||||
}
|
||||
|
||||
@ -5766,6 +5772,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
FREE_FRAME(exec_env, frame);
|
||||
frame_ip += cur_func->param_count * sizeof(int16);
|
||||
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame);
|
||||
is_return_call = true;
|
||||
goto call_func_from_entry;
|
||||
}
|
||||
#endif /* WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0 */
|
||||
@ -5838,6 +5845,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
}
|
||||
SYNC_ALL_TO_FRAME();
|
||||
prev_frame = frame;
|
||||
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||
is_return_call = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
call_func_from_entry:
|
||||
@ -5855,9 +5865,20 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
||||
prev_frame);
|
||||
}
|
||||
|
||||
prev_frame = frame->prev_frame;
|
||||
cur_func = frame->function;
|
||||
UPDATE_ALL_FROM_FRAME();
|
||||
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||
if (is_return_call) {
|
||||
/* the frame was freed before tail calling and
|
||||
the prev_frame was set as exec_env's cur_frame,
|
||||
so here we recover context from prev_frame */
|
||||
RECOVER_CONTEXT(prev_frame);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
prev_frame = frame->prev_frame;
|
||||
cur_func = frame->function;
|
||||
UPDATE_ALL_FROM_FRAME();
|
||||
}
|
||||
|
||||
/* update memory size, no need to update memory ptr as
|
||||
it isn't changed in wasm_enlarge_memory */
|
||||
|
||||
Reference in New Issue
Block a user