mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-31 13:17:31 +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
	 Wenyong Huang
						Wenyong Huang