interp: Don't restore data from frame after tail call native func

This commit is contained in:
Wenyong Huang 2024-04-06 19:59:35 +08:00
parent 202abc1937
commit 0efdd1fea3
2 changed files with 44 additions and 6 deletions

View File

@ -1509,6 +1509,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMStringviewIterObjectRef stringview_iter_obj; WASMStringviewIterObjectRef stringview_iter_obj;
#endif #endif
#endif #endif
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
bool is_return_call = false;
#endif
#if WASM_ENABLE_MEMORY64 != 0 #if WASM_ENABLE_MEMORY64 != 0
/* TODO: multi-memories for now assuming the memory idx type is consistent /* TODO: multi-memories for now assuming the memory idx type is consistent
* across multi-memories */ * across multi-memories */
@ -6227,6 +6230,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
frame_ip = frame->ip; frame_ip = frame->ip;
frame_sp = frame->sp; frame_sp = frame->sp;
frame_csp = frame->csp; frame_csp = frame->csp;
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
is_return_call = false;
#endif
goto call_func_from_entry; goto call_func_from_entry;
} }
@ -6320,6 +6326,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
FREE_FRAME(exec_env, frame); FREE_FRAME(exec_env, frame);
wasm_exec_env_set_cur_frame(exec_env, prev_frame); wasm_exec_env_set_cur_frame(exec_env, prev_frame);
is_return_call = true;
goto call_func_from_entry; goto call_func_from_entry;
} }
#endif #endif
@ -6333,6 +6340,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
} }
SYNC_ALL_TO_FRAME(); SYNC_ALL_TO_FRAME();
prev_frame = frame; prev_frame = frame;
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
is_return_call = false;
#endif
} }
call_func_from_entry: call_func_from_entry:
@ -6394,9 +6404,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
prev_frame); prev_frame);
} }
prev_frame = frame->prev_frame; #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
cur_func = frame->function; /* Don't restore some variables from frame for tail call, since
UPDATE_ALL_FROM_FRAME(); they weren't committed into the frame previously and are
available now. Instead, the frame was freed, allocated and
set again, restoring from it may cause unexped behavior. */
if (!is_return_call)
#endif
{
prev_frame = frame->prev_frame;
cur_func = frame->function;
UPDATE_ALL_FROM_FRAME();
}
/* update memory size, no need to update memory ptr as /* update memory size, no need to update memory ptr as
it isn't changed in wasm_enlarge_memory */ it isn't changed in wasm_enlarge_memory */

View File

@ -1501,6 +1501,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
WASMStringviewIterObjectRef stringview_iter_obj; WASMStringviewIterObjectRef stringview_iter_obj;
#endif #endif
#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 #if WASM_ENABLE_LABELS_AS_VALUES != 0
#define HANDLE_OPCODE(op) &&HANDLE_##op #define HANDLE_OPCODE(op) &&HANDLE_##op
@ -5618,6 +5621,9 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
{ {
frame = prev_frame; frame = prev_frame;
frame_ip = frame->ip; frame_ip = frame->ip;
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
is_return_call = false;
#endif
goto call_func_from_entry; goto call_func_from_entry;
} }
@ -5766,6 +5772,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
FREE_FRAME(exec_env, frame); FREE_FRAME(exec_env, frame);
frame_ip += cur_func->param_count * sizeof(int16); frame_ip += cur_func->param_count * sizeof(int16);
wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame); wasm_exec_env_set_cur_frame(exec_env, (WASMRuntimeFrame *)prev_frame);
is_return_call = true;
goto call_func_from_entry; goto call_func_from_entry;
} }
#endif /* WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0 */ #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(); SYNC_ALL_TO_FRAME();
prev_frame = frame; prev_frame = frame;
#if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
is_return_call = false;
#endif
} }
call_func_from_entry: call_func_from_entry:
@ -5855,9 +5865,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
prev_frame); prev_frame);
} }
prev_frame = frame->prev_frame; #if WASM_ENABLE_TAIL_CALL != 0 || WASM_ENABLE_GC != 0
cur_func = frame->function; /* Don't restore some variables from frame for tail call, since
UPDATE_ALL_FROM_FRAME(); they weren't committed into the frame previously and are
available now. Instead, the frame was freed, allocated and
set again, restoring from it may cause unexped behavior. */
if (!is_return_call)
#endif
{
prev_frame = frame->prev_frame;
cur_func = frame->function;
UPDATE_ALL_FROM_FRAME();
}
/* update memory size, no need to update memory ptr as /* update memory size, no need to update memory ptr as
it isn't changed in wasm_enlarge_memory */ it isn't changed in wasm_enlarge_memory */