mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 06:55:07 +00:00
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:
parent
b11dbcba0a
commit
ef3babc658
|
@ -1509,6 +1509,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_MEMORY64 != 0
|
||||
/* TODO: multi-memories for now assuming the memory idx type is consistent
|
||||
* across multi-memories */
|
||||
|
@ -6227,6 +6230,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
frame_ip = frame->ip;
|
||||
frame_sp = frame->sp;
|
||||
frame_csp = frame->csp;
|
||||
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
|
||||
is_return_call = false;
|
||||
#endif
|
||||
goto call_func_from_entry;
|
||||
}
|
||||
|
||||
|
@ -6320,6 +6326,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
}
|
||||
FREE_FRAME(exec_env, frame);
|
||||
wasm_exec_env_set_cur_frame(exec_env, prev_frame);
|
||||
is_return_call = true;
|
||||
goto call_func_from_entry;
|
||||
}
|
||||
#endif
|
||||
|
@ -6333,6 +6340,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:
|
||||
|
@ -6342,15 +6352,27 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
if (cur_func->import_func_inst) {
|
||||
wasm_interp_call_func_import(module, exec_env, cur_func,
|
||||
prev_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();
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_EXCE_HANDLING != 0
|
||||
char uncaught_exception[128] = { 0 };
|
||||
bool has_exception =
|
||||
wasm_copy_exception(module, uncaught_exception);
|
||||
if (has_exception
|
||||
&& strstr(uncaught_exception, "uncaught wasm exception")) {
|
||||
/* fix framesp */
|
||||
UPDATE_ALL_FROM_FRAME();
|
||||
|
||||
uint32 import_exception;
|
||||
/* initialize imported exception index to be invalid */
|
||||
SET_INVALID_TAGINDEX(import_exception);
|
||||
|
@ -6392,12 +6414,22 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
|
|||
{
|
||||
wasm_interp_call_func_native(module, exec_env, cur_func,
|
||||
prev_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();
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue
Block a user