Skip to content

Commit 40dacec

Browse files
committed
update
1 parent bc5864a commit 40dacec

File tree

3 files changed

+123
-62
lines changed

3 files changed

+123
-62
lines changed

crates/luars/src/lua_vm/dispatcher/control_instructions.rs

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub fn exec_return(vm: &mut LuaVM, instr: u32) -> LuaResult<()> {
1818
let base_ptr = vm.current_frame().base_ptr;
1919
vm.close_upvalues_from(base_ptr);
2020

21-
let Some(frame) = vm.frames.pop() else {
21+
let Some(frame) = vm.pop_frame() else {
2222
return Err(vm.error("RETURN with no frame on stack".to_string()));
2323
};
2424

@@ -36,7 +36,7 @@ pub fn exec_return(vm: &mut LuaVM, instr: u32) -> LuaResult<()> {
3636
// === 零拷贝返回值优化 ===
3737
// 关键:返回值需要写回 caller 的 R[result_reg]
3838
// 而不是写到 caller 的栈顶
39-
if !vm.frames.is_empty() {
39+
if !vm.frames_is_empty() {
4040
let caller_frame = vm.current_frame();
4141
let caller_base = caller_frame.base_ptr;
4242

@@ -127,7 +127,7 @@ pub fn exec_return(vm: &mut LuaVM, instr: u32) -> LuaResult<()> {
127127

128128
// CRITICAL: If frames are now empty, we're done - return control to caller
129129
// This prevents run() loop from trying to access empty frame
130-
if vm.frames.is_empty() {
130+
if vm.frames_is_empty() {
131131
// Save return values before exiting
132132
vm.return_values.clear();
133133
for i in 0..return_count {
@@ -840,20 +840,17 @@ fn exec_call_lua_function(
840840
}
841841
}
842842

843-
// Create and push new frame - inline to avoid call overhead
844-
let frame_id = vm.next_frame_id;
845-
vm.next_frame_id += 1;
846-
843+
// Create and push new frame - use frames.len() as frame_id to avoid counter
847844
let new_frame = LuaCallFrame::new_lua_function(
848-
frame_id,
845+
vm.frames.len(), // Use len as frame_id
849846
func,
850847
code_ptr,
851848
new_base,
852849
arg_count,
853850
a,
854851
return_count,
855852
);
856-
vm.frames.push(new_frame);
853+
vm.push_frame(new_frame);
857854
return Ok(());
858855
}
859856

@@ -919,7 +916,7 @@ fn exec_call_lua_function(
919916
return_count,
920917
);
921918

922-
vm.frames.push(new_frame);
919+
vm.push_frame(new_frame);
923920
Ok(())
924921
}
925922

@@ -987,21 +984,21 @@ fn exec_call_cfunction(
987984
actual_arg_count + 1,
988985
);
989986

990-
vm.frames.push(temp_frame);
987+
vm.push_frame(temp_frame);
991988

992989
// Call C function
993990
let result = match cfunc(vm) {
994991
Ok(r) => r,
995992
Err(LuaError::Yield) => {
996-
vm.frames.pop();
993+
vm.pop_frame_discard();
997994
return Err(LuaError::Yield);
998995
}
999996
Err(e) => {
1000-
vm.frames.pop();
997+
vm.pop_frame_discard();
1001998
return Err(e);
1002999
}
10031000
};
1004-
vm.frames.pop();
1001+
vm.pop_frame_discard();
10051002

10061003
// Copy return values
10071004
let values = result.all_values();
@@ -1097,7 +1094,7 @@ pub fn exec_tailcall(vm: &mut LuaVM, instr: u32) -> LuaResult<()> {
10971094
// Pop current frame (tail call optimization)
10981095
let old_base = base; // Already extracted
10991096
// return_count already extracted
1100-
vm.frames.pop();
1097+
vm.pop_frame_discard();
11011098

11021099
// Create new frame at same location
11031100
let frame_id = vm.next_frame_id;
@@ -1119,7 +1116,7 @@ pub fn exec_tailcall(vm: &mut LuaVM, instr: u32) -> LuaResult<()> {
11191116
result_reg, // result_reg from the CALLER (not 0!)
11201117
return_count,
11211118
);
1122-
vm.frames.push(new_frame);
1119+
vm.push_frame(new_frame);
11231120

11241121
Ok(())
11251122
}
@@ -1157,16 +1154,16 @@ pub fn exec_tailcall(vm: &mut LuaVM, instr: u32) -> LuaResult<()> {
11571154
LuaCallFrame::new_c_function(frame_id, function_value, pc, call_base, args_len + 1);
11581155

11591156
// Push temp frame and call C function
1160-
vm.frames.push(temp_frame);
1157+
vm.push_frame(temp_frame);
11611158
let result = c_func(vm)?;
1162-
vm.frames.pop(); // Pop temp frame
1159+
vm.pop_frame_discard(); // Pop temp frame
11631160

11641161
// NOW pop the tail-calling function's frame
1165-
vm.frames.pop();
1162+
vm.pop_frame_discard();
11661163

11671164
// Write return values to PARENT frame
11681165
// CRITICAL: result_reg is relative to PARENT's base_ptr!
1169-
if !vm.frames.is_empty() {
1166+
if !vm.frames_is_empty() {
11701167
let parent_base = vm.current_frame().base_ptr;
11711168
let vals = result.all_values();
11721169
let count = if return_count == usize::MAX {
@@ -1203,26 +1200,32 @@ pub fn exec_tailcall(vm: &mut LuaVM, instr: u32) -> LuaResult<()> {
12031200
/// OPTIMIZED: Use frame_ptr directly
12041201
#[inline(always)]
12051202
pub fn exec_return0(vm: &mut LuaVM, _instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> {
1206-
// FAST PATH: Use passed frame_ptr directly
1207-
let base_ptr = unsafe { (*frame_ptr).base_ptr };
1203+
// FAST PATH: Use passed frame_ptr directly - get all info BEFORE popping
1204+
let (base_ptr, result_reg, num_results) = unsafe {
1205+
(
1206+
(*frame_ptr).base_ptr,
1207+
(*frame_ptr).get_result_reg(),
1208+
(*frame_ptr).get_num_results(),
1209+
)
1210+
};
12081211

12091212
// Only close upvalues if there are any
12101213
if !vm.open_upvalues.is_empty() {
12111214
vm.close_upvalues_from(base_ptr);
12121215
}
12131216

1214-
let frame = unsafe { vm.frames.pop().unwrap_unchecked() };
1217+
vm.pop_frame_discard();
12151218

12161219
vm.return_values.clear();
12171220

12181221
// FAST PATH: Check if we have a caller frame
1219-
if let Some(caller_frame) = vm.frames.last_mut() {
1220-
let result_reg = frame.get_result_reg();
1221-
let num_results = frame.get_num_results();
1222+
if !vm.frames_is_empty() {
1223+
// Get caller's base_ptr first without holding borrow
1224+
let caller_base = vm.current_frame().base_ptr;
12221225

12231226
// Fill expected return values with nil
12241227
if num_results != usize::MAX && num_results > 0 {
1225-
let dest_base = caller_frame.base_ptr + result_reg;
1228+
let dest_base = caller_base + result_reg;
12261229
unsafe {
12271230
let reg_ptr = vm.register_stack.as_mut_ptr();
12281231
let nil_val = LuaValue::nil();
@@ -1233,7 +1236,7 @@ pub fn exec_return0(vm: &mut LuaVM, _instr: u32, frame_ptr: *mut LuaCallFrame) -
12331236
}
12341237

12351238
// Update caller's top
1236-
caller_frame.top = result_reg;
1239+
vm.current_frame_mut().top = result_reg;
12371240
Ok(())
12381241
} else {
12391242
Err(LuaError::Exit)
@@ -1263,22 +1266,25 @@ pub fn exec_return1(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) ->
12631266
};
12641267

12651268
// Pop frame - we already have all info we need from frame_ptr
1266-
unsafe { vm.frames.pop().unwrap_unchecked() };
1269+
vm.pop_frame_discard();
12671270

12681271
// CRITICAL: Always set return_values for call_function_internal compatibility
12691272
vm.return_values.clear();
12701273
vm.return_values.push(return_value);
12711274

12721275
// Check if there's a caller frame
1273-
if let Some(caller_frame) = vm.frames.last_mut() {
1276+
if !vm.frames_is_empty() {
1277+
// Get caller's base_ptr first without holding mutable borrow
1278+
let caller_base = vm.current_frame().base_ptr;
1279+
let dest_pos = caller_base + result_reg;
1280+
12741281
// Write to caller's result register
1275-
let dest_pos = caller_frame.base_ptr + result_reg;
12761282
if dest_pos < vm.register_stack.len() {
12771283
vm.register_stack[dest_pos] = return_value;
12781284
}
12791285

12801286
// Update top
1281-
caller_frame.top = result_reg + 1;
1287+
vm.current_frame_mut().top = result_reg + 1;
12821288

12831289
Ok(())
12841290
} else {

crates/luars/src/lua_vm/dispatcher/loop_instructions.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,9 @@ pub fn exec_tforcall(vm: &mut LuaVM, instr: u32) -> LuaResult<()> {
244244
3, // func + 2 args
245245
);
246246

247-
vm.frames.push(temp_frame);
247+
vm.push_frame(temp_frame);
248248
let result = cfunc(vm)?;
249-
vm.frames.pop();
249+
vm.pop_frame_discard();
250250

251251
// Store results starting at R[A+3]
252252
let values = result.all_values();
@@ -301,7 +301,7 @@ pub fn exec_tforcall(vm: &mut LuaVM, instr: u32) -> LuaResult<()> {
301301
c + 1, // expecting c+1 results
302302
);
303303

304-
vm.frames.push(new_frame);
304+
vm.push_frame(new_frame);
305305
// Execution will continue in the new frame
306306
}
307307
_ => {

0 commit comments

Comments
 (0)