From 4638734d3e33ba0638f916329c886b592b84b2b1 Mon Sep 17 00:00:00 2001 From: CppCXY <812125110@qq.com> Date: Tue, 2 Dec 2025 01:52:37 +0800 Subject: [PATCH 1/7] refactor match --- crates/luars/src/lua_vm/execute/mod.rs | 321 +++++++++++++++++++++---- 1 file changed, 279 insertions(+), 42 deletions(-) diff --git a/crates/luars/src/lua_vm/execute/mod.rs b/crates/luars/src/lua_vm/execute/mod.rs index 6a809bc5..73c2f8e1 100644 --- a/crates/luars/src/lua_vm/execute/mod.rs +++ b/crates/luars/src/lua_vm/execute/mod.rs @@ -18,13 +18,14 @@ pub use upvalue_instructions::*; use super::{Instruction, LuaError, LuaResult, LuaVM, OpCode}; use crate::LuaValue; +use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; /// Ultra-optimized main execution loop /// -/// Key optimizations: -/// 1. Instructions that never fail don't return Result - just continue -/// 2. frame_ptr is passed by mutable reference so CALL/RETURN can update it -/// 3. Minimal branching on the fast path +/// Key optimizations (like Lua C): +/// 1. Local variables: pc, code_ptr, base_ptr cached locally (like Lua C's luaV_execute) +/// 2. Hot path instructions inlined directly in match +/// 3. State reload only when frame changes (CALL/RETURN) /// /// Returns: Ok(LuaValue) on success, Err on runtime error #[inline(never)] // Don't inline this - it's the main loop, let it stay in cache @@ -36,165 +37,268 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // Initialize frame pointer - Box ensures pointer stability across Vec reallocs let mut frame_ptr = vm.current_frame_ptr(); + + // Like Lua C: cache hot variables as locals (register allocated) + // This avoids dereferencing frame_ptr on each instruction + let mut pc: usize; + let mut code_ptr: *const u32; + let mut base_ptr: usize; + + // Initial load from frame + unsafe { + pc = (*frame_ptr).pc; + code_ptr = (*frame_ptr).code_ptr; + base_ptr = (*frame_ptr).base_ptr; + } 'mainloop: loop { - // Fetch and decode instruction - let instr = unsafe { (*frame_ptr).code_ptr.add((*frame_ptr).pc).read() }; - unsafe { - (*frame_ptr).pc += 1; - } + // Fetch instruction using local pc (like Lua C's vmfetch) + let instr = unsafe { *code_ptr.add(pc) }; + pc += 1; let opcode = Instruction::get_opcode(instr); match opcode { - // ============ Load Instructions (never fail) ============ + // ============ HOT PATH: Inline for maximum speed ============ + + // MOVE - directly inline with cached base_ptr OpCode::Move => { - exec_move(vm, instr, frame_ptr); + let a = Instruction::get_a(instr) as usize; + let b = Instruction::get_b(instr) as usize; + unsafe { + let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); + *reg_base.add(a) = *reg_base.add(b); + } continue 'mainloop; } + + // LOADI - directly inline with cached base_ptr OpCode::LoadI => { - exec_loadi(vm, instr, frame_ptr); + let a = Instruction::get_a(instr) as usize; + let sbx = Instruction::get_sbx(instr); + unsafe { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(sbx as i64); + } continue 'mainloop; } + + // ============ Other Load Instructions ============ OpCode::LoadNil => { + unsafe { (*frame_ptr).pc = pc; } exec_loadnil(vm, instr, frame_ptr); continue 'mainloop; } OpCode::LoadFalse => { + unsafe { (*frame_ptr).pc = pc; } exec_loadfalse(vm, instr, frame_ptr); continue 'mainloop; } OpCode::LoadTrue => { + unsafe { (*frame_ptr).pc = pc; } exec_loadtrue(vm, instr, frame_ptr); continue 'mainloop; } OpCode::LFalseSkip => { + unsafe { (*frame_ptr).pc = pc; } exec_lfalseskip(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::LoadF => { + unsafe { (*frame_ptr).pc = pc; } exec_loadf(vm, instr, frame_ptr); continue 'mainloop; } OpCode::LoadK => { + unsafe { (*frame_ptr).pc = pc; } exec_loadk(vm, instr, frame_ptr); continue 'mainloop; } OpCode::LoadKX => { + unsafe { (*frame_ptr).pc = pc; } exec_loadkx(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::VarargPrep => { + unsafe { (*frame_ptr).pc = pc; } exec_varargprep(vm, instr, frame_ptr); continue 'mainloop; } - // ============ Arithmetic (integer fast path never fails) ============ + // ============ Arithmetic (hot path inline) ============ OpCode::Add => { + let a = Instruction::get_a(instr) as usize; + let b = Instruction::get_b(instr) as usize; + let c = Instruction::get_c(instr) as usize; + unsafe { + let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); + let left = *reg_base.add(b); + let right = *reg_base.add(c); + let combined_tags = (left.primary | right.primary) & TYPE_MASK; + if combined_tags == TAG_INTEGER { + let result = (left.secondary as i64).wrapping_add(right.secondary as i64); + *reg_base.add(a) = LuaValue { primary: TAG_INTEGER, secondary: result as u64 }; + pc += 1; // Skip MMBIN + continue 'mainloop; + } + } + // Slow path: floats or metamethods + unsafe { (*frame_ptr).pc = pc; } exec_add(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Sub => { + unsafe { (*frame_ptr).pc = pc; } exec_sub(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Mul => { + unsafe { (*frame_ptr).pc = pc; } exec_mul(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::AddI => { + unsafe { (*frame_ptr).pc = pc; } exec_addi(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Div => { + unsafe { (*frame_ptr).pc = pc; } exec_div(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::IDiv => { + unsafe { (*frame_ptr).pc = pc; } exec_idiv(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Mod => { + unsafe { (*frame_ptr).pc = pc; } exec_mod(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Pow => { + unsafe { (*frame_ptr).pc = pc; } exec_pow(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } // Arithmetic with constants OpCode::AddK => { + unsafe { (*frame_ptr).pc = pc; } exec_addk(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::SubK => { + unsafe { (*frame_ptr).pc = pc; } exec_subk(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::MulK => { + unsafe { (*frame_ptr).pc = pc; } exec_mulk(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::ModK => { + unsafe { (*frame_ptr).pc = pc; } exec_modk(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::PowK => { + unsafe { (*frame_ptr).pc = pc; } exec_powk(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::DivK => { + unsafe { (*frame_ptr).pc = pc; } exec_divk(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::IDivK => { + unsafe { (*frame_ptr).pc = pc; } exec_idivk(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } // ============ Bitwise (never fail for integers) ============ OpCode::BAnd => { + unsafe { (*frame_ptr).pc = pc; } exec_band(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::BOr => { + unsafe { (*frame_ptr).pc = pc; } exec_bor(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::BXor => { + unsafe { (*frame_ptr).pc = pc; } exec_bxor(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Shl => { + unsafe { (*frame_ptr).pc = pc; } exec_shl(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Shr => { + unsafe { (*frame_ptr).pc = pc; } exec_shr(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::BAndK => { + unsafe { (*frame_ptr).pc = pc; } exec_bandk(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::BOrK => { + unsafe { (*frame_ptr).pc = pc; } exec_bork(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::BXorK => { + unsafe { (*frame_ptr).pc = pc; } exec_bxork(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::ShrI => { + unsafe { (*frame_ptr).pc = pc; } exec_shri(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::ShlI => { + unsafe { (*frame_ptr).pc = pc; } exec_shli(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::BNot => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_bnot(vm, instr, frame_ptr) { return Err(e); } @@ -203,108 +307,166 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Unary operations ============ OpCode::Not => { + unsafe { (*frame_ptr).pc = pc; } exec_not(vm, instr, frame_ptr); continue 'mainloop; } // ============ Metamethod stubs (skip, handled by previous instruction) ============ OpCode::MmBin => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_mmbin(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::MmBinI => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_mmbini(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::MmBinK => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_mmbink(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } - // ============ Comparisons (never fail for basic types) ============ + // ============ Comparisons (may skip next instruction) ============ OpCode::LtI => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_lti(vm, instr, frame_ptr) { return Err(e); } + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::LeI => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_lei(vm, instr, frame_ptr) { return Err(e); } + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::GtI => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_gti(vm, instr, frame_ptr) { return Err(e); } + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::GeI => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_gei(vm, instr, frame_ptr) { return Err(e); } + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::EqI => { + unsafe { (*frame_ptr).pc = pc; } exec_eqi(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::EqK => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_eqk(vm, instr, frame_ptr) { return Err(e); } + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } - // ============ Control Flow (never fail) ============ + // ============ Control Flow (inline for speed) ============ OpCode::Jmp => { - exec_jmp(instr, frame_ptr); + let sj = Instruction::get_sj(instr); + pc = (pc as i32 + sj) as usize; continue 'mainloop; } OpCode::Test => { - exec_test(vm, instr, frame_ptr); + let a = Instruction::get_a(instr) as usize; + let k = Instruction::get_k(instr); + unsafe { + let val = *vm.register_stack.as_ptr().add(base_ptr + a); + let is_truthy = val.is_truthy(); + // If (not value) == k, skip next instruction + if !is_truthy == k { + pc += 1; // Skip next instruction + } + } continue 'mainloop; } OpCode::TestSet => { + unsafe { (*frame_ptr).pc = pc; } exec_testset(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } - // ============ Loop Instructions (never fail for integer loops) ============ + // ============ Loop Instructions (hot path inline) ============ OpCode::ForPrep => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_forprep(vm, instr, frame_ptr) { return Err(e); } + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::ForLoop => { - if let Err(e) = exec_forloop(vm, instr, frame_ptr) { - return Err(e); + let a = Instruction::get_a(instr) as usize; + let bx = Instruction::get_bx(instr) as usize; + unsafe { + let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr + a); + let step = *reg_base.add(2); + + // Integer loop (vast majority of cases) + if step.primary == TAG_INTEGER { + let count = (*reg_base.add(1)).secondary; + if count > 0 { + let idx = (*reg_base).secondary as i64; + let step_i = step.secondary as i64; + let new_idx = idx.wrapping_add(step_i); + (*reg_base.add(1)).secondary = count - 1; + (*reg_base).secondary = new_idx as u64; + (*reg_base.add(3)).secondary = new_idx as u64; + pc -= bx; + } + continue 'mainloop; + } + // Float loop - use existing function + (*frame_ptr).pc = pc; + let _ = exec_forloop(vm, instr, frame_ptr); + pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::TForPrep => { + unsafe { (*frame_ptr).pc = pc; } exec_tforprep(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::TForLoop => { + unsafe { (*frame_ptr).pc = pc; } exec_tforloop(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } // ============ Upvalue operations ============ OpCode::GetUpval => { + unsafe { (*frame_ptr).pc = pc; } exec_getupval(vm, instr, frame_ptr); continue 'mainloop; } OpCode::SetUpval => { + unsafe { (*frame_ptr).pc = pc; } exec_setupval(vm, instr, frame_ptr); continue 'mainloop; } @@ -314,90 +476,149 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } - // ============ Return Instructions (special handling - can Exit) ============ - OpCode::Return0 => match exec_return0(vm, instr, &mut frame_ptr) { - Ok(()) => continue 'mainloop, - Err(LuaError::Exit) => return Err(LuaError::Exit), - Err(e) => return Err(e), - }, - OpCode::Return1 => match exec_return1(vm, instr, &mut frame_ptr) { - Ok(()) => continue 'mainloop, - Err(LuaError::Exit) => return Err(LuaError::Exit), - Err(e) => return Err(e), - }, - OpCode::Return => match exec_return(vm, instr, &mut frame_ptr) { - Ok(()) => continue 'mainloop, - Err(LuaError::Exit) => return Err(LuaError::Exit), - Err(e) => return Err(e), - }, + // ============ Return Instructions (reload state after frame change) ============ + OpCode::Return0 => { + unsafe { (*frame_ptr).pc = pc; } + match exec_return0(vm, instr, &mut frame_ptr) { + Ok(()) => { + // Reload state from new frame + unsafe { + pc = (*frame_ptr).pc; + code_ptr = (*frame_ptr).code_ptr; + base_ptr = (*frame_ptr).base_ptr; + } + continue 'mainloop; + } + Err(LuaError::Exit) => return Err(LuaError::Exit), + Err(e) => return Err(e), + } + } + OpCode::Return1 => { + unsafe { (*frame_ptr).pc = pc; } + match exec_return1(vm, instr, &mut frame_ptr) { + Ok(()) => { + unsafe { + pc = (*frame_ptr).pc; + code_ptr = (*frame_ptr).code_ptr; + base_ptr = (*frame_ptr).base_ptr; + } + continue 'mainloop; + } + Err(LuaError::Exit) => return Err(LuaError::Exit), + Err(e) => return Err(e), + } + } + OpCode::Return => { + unsafe { (*frame_ptr).pc = pc; } + match exec_return(vm, instr, &mut frame_ptr) { + Ok(()) => { + unsafe { + pc = (*frame_ptr).pc; + code_ptr = (*frame_ptr).code_ptr; + base_ptr = (*frame_ptr).base_ptr; + } + continue 'mainloop; + } + Err(LuaError::Exit) => return Err(LuaError::Exit), + Err(e) => return Err(e), + } + } - // ============ Function calls (update frame_ptr) ============ + // ============ Function calls (reload state after frame change) ============ OpCode::Call => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_call(vm, instr, &mut frame_ptr) { return Err(e); } + // Reload state from new frame + unsafe { + pc = (*frame_ptr).pc; + code_ptr = (*frame_ptr).code_ptr; + base_ptr = (*frame_ptr).base_ptr; + } continue 'mainloop; } - OpCode::TailCall => match exec_tailcall(vm, instr, &mut frame_ptr) { - Ok(()) => continue 'mainloop, - Err(LuaError::Exit) => return Err(LuaError::Exit), - Err(e) => return Err(e), - }, + OpCode::TailCall => { + unsafe { (*frame_ptr).pc = pc; } + match exec_tailcall(vm, instr, &mut frame_ptr) { + Ok(()) => { + unsafe { + pc = (*frame_ptr).pc; + code_ptr = (*frame_ptr).code_ptr; + base_ptr = (*frame_ptr).base_ptr; + } + continue 'mainloop; + } + Err(LuaError::Exit) => return Err(LuaError::Exit), + Err(e) => return Err(e), + } + } // ============ Table operations (can trigger metamethods) ============ OpCode::NewTable => { + unsafe { (*frame_ptr).pc = pc; } exec_newtable(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::GetTable => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_gettable(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetTable => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_settable(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetI => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_geti(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetI => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_seti(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetField => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_getfield(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetField => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_setfield(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetTabUp => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_gettabup(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetTabUp => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_settabup(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::Self_ => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_self(vm, instr, frame_ptr) { return Err(e); } @@ -406,44 +627,54 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Operations that can trigger metamethods ============ OpCode::Unm => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_unm(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::Len => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_len(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::Concat => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_concat(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::Eq => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_eq(vm, instr, frame_ptr) { return Err(e); } + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Lt => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_lt(vm, instr, frame_ptr) { return Err(e); } + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Le => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_le(vm, instr, frame_ptr) { return Err(e); } + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } // ============ TForCall ============ OpCode::TForCall => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_tforcall(vm, instr, frame_ptr) { return Err(e); } @@ -452,26 +683,32 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Closure and special ============ OpCode::Closure => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_closure(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::Vararg => { + unsafe { (*frame_ptr).pc = pc; } if let Err(e) = exec_vararg(vm, instr, frame_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetList => { + unsafe { (*frame_ptr).pc = pc; } exec_setlist(vm, instr, frame_ptr); + unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Close => { + unsafe { (*frame_ptr).pc = pc; } exec_close(vm, instr, frame_ptr); continue 'mainloop; } OpCode::Tbc => { + unsafe { (*frame_ptr).pc = pc; } exec_tbc(vm, instr, frame_ptr); continue 'mainloop; } From 88411f1a452a5998ceebc8d2a9eb221043b2a705 Mon Sep 17 00:00:00 2001 From: CppCXY <812125110@qq.com> Date: Tue, 2 Dec 2025 10:31:03 +0800 Subject: [PATCH 2/7] update --- .../src/lua_vm/execute/load_instructions.rs | 27 +- crates/luars/src/lua_vm/execute/mod.rs | 437 ++++++++---------- 2 files changed, 206 insertions(+), 258 deletions(-) diff --git a/crates/luars/src/lua_vm/execute/load_instructions.rs b/crates/luars/src/lua_vm/execute/load_instructions.rs index 94ef7b13..39bab6b6 100644 --- a/crates/luars/src/lua_vm/execute/load_instructions.rs +++ b/crates/luars/src/lua_vm/execute/load_instructions.rs @@ -10,11 +10,11 @@ use crate::lua_vm::{Instruction, LuaCallFrame, LuaVM}; /// /// This instruction moves vararg arguments to a safe location after max_stack_size, /// so they won't be overwritten by local variable operations. -pub fn exec_varargprep(vm: &mut LuaVM, instr: u32, _frame_ptr: *mut LuaCallFrame) { +pub fn exec_varargprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; // number of fixed params let frame = vm.current_frame(); - let base_ptr = frame.base_ptr; + let frame_base = frame.base_ptr; let top = frame.top; // Get max_stack_size from the function using new ObjectPool API @@ -26,24 +26,24 @@ pub fn exec_varargprep(vm: &mut LuaVM, instr: u32, _frame_ptr: *mut LuaCallFrame }; let max_stack_size = func_ref.chunk.max_stack_size; - // Arguments were placed starting at base_ptr by CALL instruction - // Fixed parameters are at base_ptr + 0 to base_ptr + a - 1 - // Extra arguments (varargs) are at base_ptr + a to base_ptr + top - 1 - // We need to move the varargs to base_ptr + max_stack_size to protect them + // Arguments were placed starting at frame_base by CALL instruction + // Fixed parameters are at frame_base + 0 to frame_base + a - 1 + // Extra arguments (varargs) are at frame_base + a to frame_base + top - 1 + // We need to move the varargs to frame_base + max_stack_size to protect them // from being overwritten by local variable operations if top > a { let vararg_count = top - a; - let vararg_dest = base_ptr + max_stack_size; + let vararg_dest = frame_base + max_stack_size; // Ensure we have enough space for the varargs let required_size = vararg_dest + vararg_count; vm.ensure_stack_capacity(required_size); - // Move varargs from base_ptr + a to base_ptr + max_stack_size + // Move varargs from frame_base + a to frame_base + max_stack_size // Copy in reverse order in case source and destination overlap for i in (0..vararg_count).rev() { - vm.register_stack[vararg_dest + i] = vm.register_stack[base_ptr + a + i]; + vm.register_stack[vararg_dest + i] = vm.register_stack[frame_base + a + i]; } // Set vararg info in frame @@ -51,16 +51,19 @@ pub fn exec_varargprep(vm: &mut LuaVM, instr: u32, _frame_ptr: *mut LuaCallFrame } else { // No varargs passed vm.current_frame_mut() - .set_vararg(base_ptr + max_stack_size, 0); + .set_vararg(frame_base + max_stack_size, 0); } // Initialize local variables (registers from 0 to max_stack_size) with nil // But preserve fixed parameters (0..a) for i in a..max_stack_size { - if base_ptr + i < vm.register_stack.len() { - vm.register_stack[base_ptr + i] = LuaValue::nil(); + if frame_base + i < vm.register_stack.len() { + vm.register_stack[frame_base + i] = LuaValue::nil(); } } + + // updatebase - frame operations may change base_ptr + unsafe { *base_ptr = (*frame_ptr).base_ptr; } } /// LOADNIL A B diff --git a/crates/luars/src/lua_vm/execute/mod.rs b/crates/luars/src/lua_vm/execute/mod.rs index 73c2f8e1..dbf516fe 100644 --- a/crates/luars/src/lua_vm/execute/mod.rs +++ b/crates/luars/src/lua_vm/execute/mod.rs @@ -18,7 +18,28 @@ pub use upvalue_instructions::*; use super::{Instruction, LuaError, LuaResult, LuaVM, OpCode}; use crate::LuaValue; -use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; +use crate::lua_value::{TAG_INTEGER, TAG_FLOAT, TYPE_MASK}; + +/// Update base_ptr from frame (like Lua C's updatebase macro) +/// Called after operations that may change the call stack +#[inline(always)] +unsafe fn updatebase(frame_ptr: *mut crate::lua_vm::LuaCallFrame, base_ptr: &mut usize) { + *base_ptr = (*frame_ptr).base_ptr; +} + +/// Update both pc and base_ptr from frame +/// Used after CALL/RETURN instructions +#[inline(always)] +unsafe fn updatestate( + frame_ptr: *mut crate::lua_vm::LuaCallFrame, + pc: &mut usize, + code_ptr: &mut *const u32, + base_ptr: &mut usize +) { + *pc = (*frame_ptr).pc; + *code_ptr = (*frame_ptr).code_ptr; + *base_ptr = (*frame_ptr).base_ptr; +} /// Ultra-optimized main execution loop /// @@ -26,6 +47,7 @@ use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; /// 1. Local variables: pc, code_ptr, base_ptr cached locally (like Lua C's luaV_execute) /// 2. Hot path instructions inlined directly in match /// 3. State reload only when frame changes (CALL/RETURN) +/// 4. Pass mutable references to avoid frequent frame_ptr writes /// /// Returns: Ok(LuaValue) on success, Err on runtime error #[inline(never)] // Don't inline this - it's the main loop, let it stay in cache @@ -59,9 +81,9 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { let opcode = Instruction::get_opcode(instr); match opcode { - // ============ HOT PATH: Inline for maximum speed ============ + // ============ HOT PATH: Inline simple instructions (< 10 lines) ============ - // MOVE - directly inline with cached base_ptr + // MOVE - R[A] := R[B] OpCode::Move => { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -72,7 +94,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } - // LOADI - directly inline with cached base_ptr + // LOADI - R[A] := sBx OpCode::LoadI => { let a = Instruction::get_a(instr) as usize; let sbx = Instruction::get_sbx(instr); @@ -82,51 +104,89 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } - // ============ Other Load Instructions ============ - OpCode::LoadNil => { - unsafe { (*frame_ptr).pc = pc; } - exec_loadnil(vm, instr, frame_ptr); + // LOADF - R[A] := (float)sBx + OpCode::LoadF => { + let a = Instruction::get_a(instr) as usize; + let sbx = Instruction::get_sbx(instr); + unsafe { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(sbx as f64); + } continue 'mainloop; } - OpCode::LoadFalse => { - unsafe { (*frame_ptr).pc = pc; } - exec_loadfalse(vm, instr, frame_ptr); + + // LOADTRUE - R[A] := true + OpCode::LoadTrue => { + let a = Instruction::get_a(instr) as usize; + unsafe { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(true); + } continue 'mainloop; } - OpCode::LoadTrue => { - unsafe { (*frame_ptr).pc = pc; } - exec_loadtrue(vm, instr, frame_ptr); + + // LOADFALSE - R[A] := false + OpCode::LoadFalse => { + let a = Instruction::get_a(instr) as usize; + unsafe { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(false); + } continue 'mainloop; } + + // LFALSESKIP - R[A] := false; pc++ OpCode::LFalseSkip => { - unsafe { (*frame_ptr).pc = pc; } - exec_lfalseskip(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + let a = Instruction::get_a(instr) as usize; + unsafe { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(false); + } + pc += 1; continue 'mainloop; } - OpCode::LoadF => { - unsafe { (*frame_ptr).pc = pc; } - exec_loadf(vm, instr, frame_ptr); + + // LOADNIL - R[A], ..., R[A+B] := nil + OpCode::LoadNil => { + let a = Instruction::get_a(instr) as usize; + let b = Instruction::get_b(instr) as usize; + unsafe { + let nil_val = LuaValue::nil(); + let reg_ptr = vm.register_stack.as_mut_ptr().add(base_ptr); + for i in 0..=b { + *reg_ptr.add(a + i) = nil_val; + } + } continue 'mainloop; } + + // LOADK - R[A] := K[Bx] OpCode::LoadK => { - unsafe { (*frame_ptr).pc = pc; } - exec_loadk(vm, instr, frame_ptr); + let a = Instruction::get_a(instr) as usize; + let bx = Instruction::get_bx(instr) as usize; + unsafe { + let constant = *(*frame_ptr).constants_ptr.add(bx); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = constant; + } continue 'mainloop; } + + // LOADKX - R[A] := K[extra arg]; pc++ OpCode::LoadKX => { - unsafe { (*frame_ptr).pc = pc; } - exec_loadkx(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + let a = Instruction::get_a(instr) as usize; + unsafe { + let extra_instr = *code_ptr.add(pc); + pc += 1; + let bx = Instruction::get_ax(extra_instr) as usize; + let constant = *(*frame_ptr).constants_ptr.add(bx); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = constant; + } continue 'mainloop; } + + // VARARGPREP - complex, call function OpCode::VarargPrep => { - unsafe { (*frame_ptr).pc = pc; } - exec_varargprep(vm, instr, frame_ptr); + exec_varargprep(vm, instr, frame_ptr, &mut base_ptr); continue 'mainloop; } - // ============ Arithmetic (hot path inline) ============ + // ============ Arithmetic (inline integer fast path) ============ OpCode::Add => { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -142,248 +202,196 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { pc += 1; // Skip MMBIN continue 'mainloop; } + // Float fast path + if combined_tags == TAG_FLOAT { + let result = f64::from_bits(left.secondary) + f64::from_bits(right.secondary); + *reg_base.add(a) = LuaValue { primary: TAG_FLOAT, secondary: result.to_bits() }; + pc += 1; // Skip MMBIN + continue 'mainloop; + } } - // Slow path: floats or metamethods - unsafe { (*frame_ptr).pc = pc; } - exec_add(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + // Slow path: mixed types or metamethods + exec_add(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } + + // Other arithmetic - call functions OpCode::Sub => { - unsafe { (*frame_ptr).pc = pc; } - exec_sub(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_sub(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::Mul => { - unsafe { (*frame_ptr).pc = pc; } - exec_mul(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_mul(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::AddI => { - unsafe { (*frame_ptr).pc = pc; } - exec_addi(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_addi(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::Div => { - unsafe { (*frame_ptr).pc = pc; } - exec_div(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_div(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::IDiv => { - unsafe { (*frame_ptr).pc = pc; } - exec_idiv(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_idiv(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::Mod => { - unsafe { (*frame_ptr).pc = pc; } - exec_mod(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_mod(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::Pow => { - unsafe { (*frame_ptr).pc = pc; } - exec_pow(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_pow(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } // Arithmetic with constants OpCode::AddK => { - unsafe { (*frame_ptr).pc = pc; } - exec_addk(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_addk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::SubK => { - unsafe { (*frame_ptr).pc = pc; } - exec_subk(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_subk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::MulK => { - unsafe { (*frame_ptr).pc = pc; } - exec_mulk(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_mulk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::ModK => { - unsafe { (*frame_ptr).pc = pc; } - exec_modk(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_modk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::PowK => { - unsafe { (*frame_ptr).pc = pc; } - exec_powk(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_powk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::DivK => { - unsafe { (*frame_ptr).pc = pc; } - exec_divk(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_divk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::IDivK => { - unsafe { (*frame_ptr).pc = pc; } - exec_idivk(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_idivk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } - // ============ Bitwise (never fail for integers) ============ + // ============ Bitwise (inline simple ones) ============ OpCode::BAnd => { - unsafe { (*frame_ptr).pc = pc; } - exec_band(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_band(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::BOr => { - unsafe { (*frame_ptr).pc = pc; } - exec_bor(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_bor(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::BXor => { - unsafe { (*frame_ptr).pc = pc; } - exec_bxor(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_bxor(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::Shl => { - unsafe { (*frame_ptr).pc = pc; } - exec_shl(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_shl(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::Shr => { - unsafe { (*frame_ptr).pc = pc; } - exec_shr(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_shr(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::BAndK => { - unsafe { (*frame_ptr).pc = pc; } - exec_bandk(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_bandk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::BOrK => { - unsafe { (*frame_ptr).pc = pc; } - exec_bork(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_bork(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::BXorK => { - unsafe { (*frame_ptr).pc = pc; } - exec_bxork(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_bxork(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::ShrI => { - unsafe { (*frame_ptr).pc = pc; } - exec_shri(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_shri(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::ShlI => { - unsafe { (*frame_ptr).pc = pc; } - exec_shli(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_shli(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::BNot => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_bnot(vm, instr, frame_ptr) { + if let Err(e) = exec_bnot(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } - // ============ Unary operations ============ + // ============ Unary operations (inline NOT) ============ OpCode::Not => { - unsafe { (*frame_ptr).pc = pc; } - exec_not(vm, instr, frame_ptr); + let a = Instruction::get_a(instr) as usize; + let b = Instruction::get_b(instr) as usize; + unsafe { + let value = *vm.register_stack.as_ptr().add(base_ptr + b); + let is_falsy = !value.is_truthy(); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(is_falsy); + } continue 'mainloop; } - // ============ Metamethod stubs (skip, handled by previous instruction) ============ + // ============ Metamethod stubs ============ OpCode::MmBin => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_mmbin(vm, instr, frame_ptr) { + if let Err(e) = exec_mmbin(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::MmBinI => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_mmbini(vm, instr, frame_ptr) { + if let Err(e) = exec_mmbini(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::MmBinK => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_mmbink(vm, instr, frame_ptr) { + if let Err(e) = exec_mmbink(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } - // ============ Comparisons (may skip next instruction) ============ + // ============ Comparisons (inline simple ones) ============ OpCode::LtI => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_lti(vm, instr, frame_ptr) { + if let Err(e) = exec_lti(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } - unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::LeI => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_lei(vm, instr, frame_ptr) { + if let Err(e) = exec_lei(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } - unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::GtI => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_gti(vm, instr, frame_ptr) { + if let Err(e) = exec_gti(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } - unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::GeI => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_gei(vm, instr, frame_ptr) { + if let Err(e) = exec_gei(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } - unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::EqI => { - unsafe { (*frame_ptr).pc = pc; } - exec_eqi(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_eqi(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::EqK => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_eqk(vm, instr, frame_ptr) { + if let Err(e) = exec_eqk(vm, instr, frame_ptr, &mut pc) { return Err(e); } - unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } - // ============ Control Flow (inline for speed) ============ + // ============ Control Flow (inline JMP and TEST) ============ OpCode::Jmp => { let sj = Instruction::get_sj(instr); pc = (pc as i32 + sj) as usize; @@ -395,27 +403,22 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { unsafe { let val = *vm.register_stack.as_ptr().add(base_ptr + a); let is_truthy = val.is_truthy(); - // If (not value) == k, skip next instruction if !is_truthy == k { - pc += 1; // Skip next instruction + pc += 1; } } continue 'mainloop; } OpCode::TestSet => { - unsafe { (*frame_ptr).pc = pc; } - exec_testset(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_testset(vm, instr, &mut pc, base_ptr); continue 'mainloop; } - // ============ Loop Instructions (hot path inline) ============ + // ============ Loop Instructions (inline FORLOOP) ============ OpCode::ForPrep => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_forprep(vm, instr, frame_ptr) { + if let Err(e) = exec_forprep(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } - unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::ForLoop => { @@ -425,7 +428,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr + a); let step = *reg_base.add(2); - // Integer loop (vast majority of cases) + // Integer loop (like Lua C) if step.primary == TAG_INTEGER { let count = (*reg_base.add(1)).secondary; if count > 0 { @@ -439,35 +442,29 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } continue 'mainloop; } - // Float loop - use existing function - (*frame_ptr).pc = pc; - let _ = exec_forloop(vm, instr, frame_ptr); - pc = (*frame_ptr).pc; + // Float loop + if let Err(e) = exec_forloop(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + return Err(e); + } } continue 'mainloop; } OpCode::TForPrep => { - unsafe { (*frame_ptr).pc = pc; } - exec_tforprep(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_tforprep(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::TForLoop => { - unsafe { (*frame_ptr).pc = pc; } - exec_tforloop(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_tforloop(vm, instr, &mut pc, base_ptr); continue 'mainloop; } - // ============ Upvalue operations ============ + // ============ Upvalue operations (inline simple ones) ============ OpCode::GetUpval => { - unsafe { (*frame_ptr).pc = pc; } - exec_getupval(vm, instr, frame_ptr); + exec_getupval(vm, instr, frame_ptr, base_ptr); continue 'mainloop; } OpCode::SetUpval => { - unsafe { (*frame_ptr).pc = pc; } - exec_setupval(vm, instr, frame_ptr); + exec_setupval(vm, instr, frame_ptr, base_ptr); continue 'mainloop; } @@ -476,17 +473,12 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } - // ============ Return Instructions (reload state after frame change) ============ + // ============ Return Instructions (update state after frame change) ============ OpCode::Return0 => { - unsafe { (*frame_ptr).pc = pc; } match exec_return0(vm, instr, &mut frame_ptr) { Ok(()) => { - // Reload state from new frame - unsafe { - pc = (*frame_ptr).pc; - code_ptr = (*frame_ptr).code_ptr; - base_ptr = (*frame_ptr).base_ptr; - } + // Reload state from new frame (like Lua C) + unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } continue 'mainloop; } Err(LuaError::Exit) => return Err(LuaError::Exit), @@ -494,14 +486,9 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } } OpCode::Return1 => { - unsafe { (*frame_ptr).pc = pc; } match exec_return1(vm, instr, &mut frame_ptr) { Ok(()) => { - unsafe { - pc = (*frame_ptr).pc; - code_ptr = (*frame_ptr).code_ptr; - base_ptr = (*frame_ptr).base_ptr; - } + unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } continue 'mainloop; } Err(LuaError::Exit) => return Err(LuaError::Exit), @@ -509,14 +496,9 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } } OpCode::Return => { - unsafe { (*frame_ptr).pc = pc; } match exec_return(vm, instr, &mut frame_ptr) { Ok(()) => { - unsafe { - pc = (*frame_ptr).pc; - code_ptr = (*frame_ptr).code_ptr; - base_ptr = (*frame_ptr).base_ptr; - } + unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } continue 'mainloop; } Err(LuaError::Exit) => return Err(LuaError::Exit), @@ -524,29 +506,19 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } } - // ============ Function calls (reload state after frame change) ============ + // ============ Function calls (update state after frame change) ============ OpCode::Call => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_call(vm, instr, &mut frame_ptr) { + if let Err(e) = exec_call(vm, instr, base_ptr, &mut frame_ptr) { return Err(e); } // Reload state from new frame - unsafe { - pc = (*frame_ptr).pc; - code_ptr = (*frame_ptr).code_ptr; - base_ptr = (*frame_ptr).base_ptr; - } + unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } continue 'mainloop; } OpCode::TailCall => { - unsafe { (*frame_ptr).pc = pc; } match exec_tailcall(vm, instr, &mut frame_ptr) { Ok(()) => { - unsafe { - pc = (*frame_ptr).pc; - code_ptr = (*frame_ptr).code_ptr; - base_ptr = (*frame_ptr).base_ptr; - } + unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } continue 'mainloop; } Err(LuaError::Exit) => return Err(LuaError::Exit), @@ -554,72 +526,61 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } } - // ============ Table operations (can trigger metamethods) ============ + // ============ Table operations ============ OpCode::NewTable => { - unsafe { (*frame_ptr).pc = pc; } - exec_newtable(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_newtable(vm, instr, frame_ptr, &mut pc); continue 'mainloop; } OpCode::GetTable => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_gettable(vm, instr, frame_ptr) { + if let Err(e) = exec_gettable(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetTable => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_settable(vm, instr, frame_ptr) { + if let Err(e) = exec_settable(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetI => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_geti(vm, instr, frame_ptr) { + if let Err(e) = exec_geti(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetI => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_seti(vm, instr, frame_ptr) { + if let Err(e) = exec_seti(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetField => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_getfield(vm, instr, frame_ptr) { + if let Err(e) = exec_getfield(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetField => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_setfield(vm, instr, frame_ptr) { + if let Err(e) = exec_setfield(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetTabUp => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_gettabup(vm, instr, frame_ptr) { + if let Err(e) = exec_gettabup(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetTabUp => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_settabup(vm, instr, frame_ptr) { + if let Err(e) = exec_settabup(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Self_ => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_self(vm, instr, frame_ptr) { + if let Err(e) = exec_self(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; @@ -627,55 +588,45 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Operations that can trigger metamethods ============ OpCode::Unm => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_unm(vm, instr, frame_ptr) { + if let Err(e) = exec_unm(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Len => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_len(vm, instr, frame_ptr) { + if let Err(e) = exec_len(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Concat => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_concat(vm, instr, frame_ptr) { + if let Err(e) = exec_concat(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Eq => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_eq(vm, instr, frame_ptr) { + if let Err(e) = exec_eq(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } - unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Lt => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_lt(vm, instr, frame_ptr) { + if let Err(e) = exec_lt(vm, instr, frame_ptr, &mut pc, base_ptr) { return Err(e); } - unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } OpCode::Le => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_le(vm, instr, frame_ptr) { + if let Err(e) = exec_le(vm, instr, frame_ptr, &mut pc, base_ptr) { return Err(e); } - unsafe { pc = (*frame_ptr).pc; } continue 'mainloop; } // ============ TForCall ============ OpCode::TForCall => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_tforcall(vm, instr, frame_ptr) { + if let Err(e) = exec_tforcall(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; @@ -683,33 +634,27 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Closure and special ============ OpCode::Closure => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_closure(vm, instr, frame_ptr) { + if let Err(e) = exec_closure(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Vararg => { - unsafe { (*frame_ptr).pc = pc; } - if let Err(e) = exec_vararg(vm, instr, frame_ptr) { + if let Err(e) = exec_vararg(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetList => { - unsafe { (*frame_ptr).pc = pc; } - exec_setlist(vm, instr, frame_ptr); - unsafe { pc = (*frame_ptr).pc; } + exec_setlist(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::Close => { - unsafe { (*frame_ptr).pc = pc; } - exec_close(vm, instr, frame_ptr); + exec_close(vm, instr, base_ptr); continue 'mainloop; } OpCode::Tbc => { - unsafe { (*frame_ptr).pc = pc; } - exec_tbc(vm, instr, frame_ptr); + exec_tbc(vm, instr, base_ptr); continue 'mainloop; } } From 13177515f120040fece9cffdb32295deb289b456 Mon Sep 17 00:00:00 2001 From: CppCXY <812125110@qq.com> Date: Tue, 2 Dec 2025 11:15:07 +0800 Subject: [PATCH 3/7] update --- .../lua_vm/execute/arithmetic_instructions.rs | 303 ++++++++---------- .../lua_vm/execute/control_instructions.rs | 88 +++-- .../src/lua_vm/execute/load_instructions.rs | 53 ++- .../src/lua_vm/execute/loop_instructions.rs | 26 +- crates/luars/src/lua_vm/execute/mod.rs | 130 ++++---- .../src/lua_vm/execute/table_instructions.rs | 39 ++- .../lua_vm/execute/upvalue_instructions.rs | 16 +- 7 files changed, 294 insertions(+), 361 deletions(-) diff --git a/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs b/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs index 028cd681..a6f5d2bc 100644 --- a/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs +++ b/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs @@ -39,14 +39,13 @@ fn exec_add_slow( /// ADD: R[A] = R[B] + R[C] /// OPTIMIZED: Matches Lua C's setivalue behavior - always write both fields #[inline(always)] -pub fn exec_add(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_add(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); + let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -60,7 +59,7 @@ pub fn exec_add(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { primary: TAG_INTEGER, secondary: result as u64, }; - (*frame_ptr).pc += 1; // Skip MMBIN + *pc += 1; // Skip MMBIN return; } @@ -101,14 +100,13 @@ fn exec_sub_slow( /// SUB: R[A] = R[B] - R[C] /// OPTIMIZED: Matches Lua C's setivalue behavior #[inline(always)] -pub fn exec_sub(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_sub(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); + let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -120,7 +118,7 @@ pub fn exec_sub(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { primary: TAG_INTEGER, secondary: result as u64, }; - (*frame_ptr).pc += 1; + *pc += 1; return; } @@ -160,14 +158,13 @@ fn exec_mul_slow( /// MUL: R[A] = R[B] * R[C] /// OPTIMIZED: Matches Lua C's setivalue behavior #[inline(always)] -pub fn exec_mul(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_mul(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); + let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -179,7 +176,7 @@ pub fn exec_mul(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { primary: TAG_INTEGER, secondary: result as u64, }; - (*frame_ptr).pc += 1; + *pc += 1; return; } @@ -189,14 +186,13 @@ pub fn exec_mul(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// DIV: R[A] = R[B] / R[C] /// Division always returns float in Lua -pub fn exec_div(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_div(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_base = vm.register_stack.as_ptr().add(base_ptr); + let reg_base = vm.register_stack.as_ptr().add(*base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -219,20 +215,19 @@ pub fn exec_div(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { return; }; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l_float / r_float); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l_float / r_float); + *pc += 1; } } /// IDIV: R[A] = R[B] // R[C] (floor division) -pub fn exec_idiv(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_idiv(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_base = vm.register_stack.as_ptr().add(base_ptr); + let reg_base = vm.register_stack.as_ptr().add(*base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -268,20 +263,19 @@ pub fn exec_idiv(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { LuaValue::number((l_float / r_float).floor()) }; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *pc += 1; } } /// MOD: R[A] = R[B] % R[C] -pub fn exec_mod(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_mod(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_base = vm.register_stack.as_ptr().add(base_ptr); + let reg_base = vm.register_stack.as_ptr().add(*base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -318,21 +312,20 @@ pub fn exec_mod(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { LuaValue::number(result) }; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *pc += 1; } } /// POW: R[A] = R[B] ^ R[C] -pub fn exec_pow(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_pow(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); - let right = *vm.register_stack.as_ptr().add(base_ptr + c); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let right = *vm.register_stack.as_ptr().add(*base_ptr + c); let l_float = match left.as_number() { Some(n) => n, @@ -343,13 +336,13 @@ pub fn exec_pow(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { None => return, }; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l_float.powf(r_float)); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l_float.powf(r_float)); + *pc += 1; } } /// UNM: R[A] = -R[B] (unary minus) -pub fn exec_unm(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_unm(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -393,14 +386,13 @@ pub fn exec_unm(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua /// ADDI: R[A] = R[B] + sC /// OPTIMIZED: Minimal branches, inline integer path #[inline(always)] -pub fn exec_addi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_addi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let sc = Instruction::get_sc(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); + let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr); let left = *reg_base.add(b); if left.primary == TAG_INTEGER { @@ -409,14 +401,14 @@ pub fn exec_addi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { let dest = reg_base.add(a); (*dest).primary = TAG_INTEGER; (*dest).secondary = result as u64; - (*frame_ptr).pc += 1; // Skip MMBINI + *pc += 1; // Skip MMBINI return; } if left.primary == TAG_FLOAT { let l = f64::from_bits(left.secondary); *reg_base.add(a) = LuaValue::float(l + sc as f64); - (*frame_ptr).pc += 1; + *pc += 1; return; } } @@ -425,14 +417,13 @@ pub fn exec_addi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// ADDK: R[A] = R[B] + K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_addk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_addk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -440,29 +431,29 @@ pub fn exec_addk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { // Integer + Integer fast path if left.primary == TAG_INTEGER && constant.primary == TAG_INTEGER { let result = (left.secondary as i64).wrapping_add(constant.secondary as i64); - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { primary: TAG_INTEGER, secondary: result as u64, }; - (*frame_ptr).pc += 1; + *pc += 1; return; } // Float + Float fast path if left.primary == TAG_FLOAT && constant.primary == TAG_FLOAT { let result = f64::from_bits(left.secondary) + f64::from_bits(constant.secondary); - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { primary: TAG_FLOAT, secondary: result.to_bits(), }; - (*frame_ptr).pc += 1; + *pc += 1; return; } // Mixed types if let (Some(l), Some(r)) = (left.as_number(), constant.as_number()) { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l + r); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l + r); + *pc += 1; } } } @@ -470,14 +461,13 @@ pub fn exec_addk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// SUBK: R[A] = R[B] - K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_subk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_subk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -485,29 +475,29 @@ pub fn exec_subk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { // Integer - Integer fast path if left.primary == TAG_INTEGER && constant.primary == TAG_INTEGER { let result = (left.secondary as i64).wrapping_sub(constant.secondary as i64); - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { primary: TAG_INTEGER, secondary: result as u64, }; - (*frame_ptr).pc += 1; + *pc += 1; return; } // Float - Float fast path if left.primary == TAG_FLOAT && constant.primary == TAG_FLOAT { let result = f64::from_bits(left.secondary) - f64::from_bits(constant.secondary); - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { primary: TAG_FLOAT, secondary: result.to_bits(), }; - (*frame_ptr).pc += 1; + *pc += 1; return; } // Mixed types if let (Some(l), Some(r)) = (left.as_number(), constant.as_number()) { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l - r); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l - r); + *pc += 1; } } } @@ -515,14 +505,13 @@ pub fn exec_subk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// MULK: R[A] = R[B] * K[C] /// OPTIMIZED: Direct field writes, minimal branching #[inline(always)] -pub fn exec_mulk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_mulk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -530,35 +519,35 @@ pub fn exec_mulk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { // Integer * Integer fast path FIRST (most common in benchmarks with integer loops) if left.primary == TAG_INTEGER && constant.primary == TAG_INTEGER { let result = (left.secondary as i64).wrapping_mul(constant.secondary as i64); - let dest = vm.register_stack.as_mut_ptr().add(base_ptr + a); + let dest = vm.register_stack.as_mut_ptr().add(*base_ptr + a); (*dest).primary = TAG_INTEGER; (*dest).secondary = result as u64; - (*frame_ptr).pc += 1; + *pc += 1; return; } // Float * Float fast path if left.primary == TAG_FLOAT && constant.primary == TAG_FLOAT { let result = f64::from_bits(left.secondary) * f64::from_bits(constant.secondary); - let dest = vm.register_stack.as_mut_ptr().add(base_ptr + a); + let dest = vm.register_stack.as_mut_ptr().add(*base_ptr + a); (*dest).primary = TAG_FLOAT; (*dest).secondary = result.to_bits(); - (*frame_ptr).pc += 1; + *pc += 1; return; } // Mixed types: Integer * Float or Float * Integer if left.primary == TAG_INTEGER && constant.primary == TAG_FLOAT { let result = (left.secondary as i64) as f64 * f64::from_bits(constant.secondary); - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::float(result); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::float(result); + *pc += 1; return; } if left.primary == TAG_FLOAT && constant.primary == TAG_INTEGER { let result = f64::from_bits(left.secondary) * (constant.secondary as i64) as f64; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::float(result); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::float(result); + *pc += 1; } } } @@ -566,14 +555,13 @@ pub fn exec_mulk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// MODK: R[A] = R[B] % K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_modk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_modk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -585,19 +573,19 @@ pub fn exec_modk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { return; } let l = left.secondary as i64; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { primary: TAG_INTEGER, secondary: l.rem_euclid(r) as u64, }; - (*frame_ptr).pc += 1; + *pc += 1; return; } // Float % Float if let (Some(l), Some(r)) = (left.as_number(), constant.as_number()) { let result = l - (l / r).floor() * r; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(result); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(result); + *pc += 1; } } } @@ -605,14 +593,13 @@ pub fn exec_modk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// POWK: R[A] = R[B] ^ K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_powk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_powk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -626,22 +613,21 @@ pub fn exec_powk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { None => return, }; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l_float.powf(r_float)); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l_float.powf(r_float)); + *pc += 1; } } /// DIVK: R[A] = R[B] / K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_divk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_divk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -655,22 +641,21 @@ pub fn exec_divk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { None => return, }; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l_float / r_float); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l_float / r_float); + *pc += 1; } } /// IDIVK: R[A] = R[B] // K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_idivk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_idivk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -682,18 +667,18 @@ pub fn exec_idivk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { return; } let l = left.secondary as i64; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { primary: TAG_INTEGER, secondary: l.div_euclid(r) as u64, }; - (*frame_ptr).pc += 1; + *pc += 1; return; } // Float // Float if let (Some(l), Some(r)) = (left.as_number(), constant.as_number()) { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number((l / r).floor()); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number((l / r).floor()); + *pc += 1; } } } @@ -702,72 +687,68 @@ pub fn exec_idivk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// BAND: R[A] = R[B] & R[C] #[inline(always)] -pub fn exec_band(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_band(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); - let right = *vm.register_stack.as_ptr().add(base_ptr + c); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let right = *vm.register_stack.as_ptr().add(*base_ptr + c); if let (Some(l), Some(r)) = (left.as_integer(), right.as_integer()) { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l & r); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l & r); + *pc += 1; } } } /// BOR: R[A] = R[B] | R[C] #[inline(always)] -pub fn exec_bor(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_bor(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); - let right = *vm.register_stack.as_ptr().add(base_ptr + c); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let right = *vm.register_stack.as_ptr().add(*base_ptr + c); if let (Some(l), Some(r)) = (left.as_integer(), right.as_integer()) { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l | r); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l | r); + *pc += 1; } } } /// BXOR: R[A] = R[B] ~ R[C] #[inline(always)] -pub fn exec_bxor(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_bxor(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); - let right = *vm.register_stack.as_ptr().add(base_ptr + c); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let right = *vm.register_stack.as_ptr().add(*base_ptr + c); if let (Some(l), Some(r)) = (left.as_integer(), right.as_integer()) { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l ^ r); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l ^ r); + *pc += 1; } } } /// SHL: R[A] = R[B] << R[C] #[inline(always)] -pub fn exec_shl(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_shl(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); - let right = *vm.register_stack.as_ptr().add(base_ptr + c); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let right = *vm.register_stack.as_ptr().add(*base_ptr + c); if let (Some(l), Some(r)) = (left.as_integer(), right.as_integer()) { let result = if r >= 0 { @@ -775,23 +756,22 @@ pub fn exec_shl(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { } else { LuaValue::integer(l >> ((-r) & 63)) }; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *pc += 1; } } } /// SHR: R[A] = R[B] >> R[C] #[inline(always)] -pub fn exec_shr(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_shr(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); - let right = *vm.register_stack.as_ptr().add(base_ptr + c); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let right = *vm.register_stack.as_ptr().add(*base_ptr + c); if let (Some(l), Some(r)) = (left.as_integer(), right.as_integer()) { let result = if r >= 0 { @@ -799,8 +779,8 @@ pub fn exec_shr(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { } else { LuaValue::integer(l << ((-r) & 63)) }; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *pc += 1; } } } @@ -808,14 +788,13 @@ pub fn exec_shr(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// BANDK: R[A] = R[B] & K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_bandk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_bandk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -840,8 +819,8 @@ pub fn exec_bandk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { }); if let (Some(l), Some(r)) = (l_int, r_int) { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l & r); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l & r); + *pc += 1; } } } @@ -849,14 +828,13 @@ pub fn exec_bandk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// BORK: R[A] = R[B] | K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_bork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_bork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -881,8 +859,8 @@ pub fn exec_bork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { }); if let (Some(l), Some(r)) = (l_int, r_int) { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l | r); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l | r); + *pc += 1; } } } @@ -890,14 +868,13 @@ pub fn exec_bork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// BXORK: R[A] = R[B] ~ K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_bxork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_bxork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -922,22 +899,21 @@ pub fn exec_bxork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { }); if let (Some(l), Some(r)) = (l_int, r_int) { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l ^ r); - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l ^ r); + *pc += 1; } } } /// SHRI: R[A] = R[B] >> sC #[inline(always)] -pub fn exec_shri(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_shri(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let sc = Instruction::get_sc(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let left = *vm.register_stack.as_ptr().add(*base_ptr + b); if let Some(l) = left.as_integer() { let result = if sc >= 0 { @@ -945,22 +921,21 @@ pub fn exec_shri(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { } else { LuaValue::integer(l << ((-sc) & 63)) }; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *pc += 1; } } } /// SHLI: R[A] = sC << R[B] #[inline(always)] -pub fn exec_shli(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_shli(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let sc = Instruction::get_sc(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let right = *vm.register_stack.as_ptr().add(base_ptr + b); + let right = *vm.register_stack.as_ptr().add(*base_ptr + b); if let Some(r) = right.as_integer() { let result = if r >= 0 { @@ -968,15 +943,15 @@ pub fn exec_shli(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { } else { LuaValue::integer((sc as i64) >> ((-r) & 63)) }; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; - (*frame_ptr).pc += 1; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *pc += 1; } } } /// BNOT: R[A] = ~R[B] #[inline(always)] -pub fn exec_bnot(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_bnot(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -1010,24 +985,23 @@ pub fn exec_bnot(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lu /// NOT: R[A] = not R[B] #[inline(always)] -pub fn exec_not(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_not(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let value = *vm.register_stack.as_ptr().add(base_ptr + b); + let value = *vm.register_stack.as_ptr().add(*base_ptr + b); // In Lua, only nil and false are falsy use crate::lua_value::{TAG_NIL, VALUE_FALSE}; let is_falsy = value.primary == TAG_NIL || value.primary == VALUE_FALSE; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(is_falsy); + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::boolean(is_falsy); } } /// LEN: R[A] = #R[B] #[inline(always)] -pub fn exec_len(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_len(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -1075,13 +1049,12 @@ pub fn exec_len(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua /// MmBin: Metamethod binary operation (register, register) #[inline(always)] -pub fn exec_mmbin(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_mmbin(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; let prev_pc = (*frame_ptr).pc - 1; if prev_pc == 0 { @@ -1092,8 +1065,8 @@ pub fn exec_mmbin(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> L let prev_instr = (*frame_ptr).code_ptr.add(prev_pc - 1).read(); let dest_reg = Instruction::get_a(prev_instr) as usize; - let ra = *vm.register_stack.as_ptr().add(base_ptr + a); - let rb = *vm.register_stack.as_ptr().add(base_ptr + b); + let ra = *vm.register_stack.as_ptr().add(*base_ptr + a); + let rb = *vm.register_stack.as_ptr().add(*base_ptr + b); // Use pre-cached metamethod StringId let mm_key = LuaValue::string(vm.object_pool.get_binop_tm(c as u8)); @@ -1110,7 +1083,7 @@ pub fn exec_mmbin(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> L if !metamethod.is_nil() { if let Some(result) = vm.call_metamethod(&metamethod, &[ra, rb])? { - *vm.register_stack.as_mut_ptr().add(base_ptr + dest_reg) = result; + *vm.register_stack.as_mut_ptr().add(*base_ptr + dest_reg) = result; } } // If no metamethod, leave the instruction result as-is (error will be caught elsewhere) @@ -1120,14 +1093,13 @@ pub fn exec_mmbin(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> L /// MmBinI: Metamethod binary operation (register, immediate) #[inline(always)] -pub fn exec_mmbini(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_mmbini(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let c = Instruction::get_c(instr); let k = Instruction::get_k(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; let prev_pc = (*frame_ptr).pc - 1; if prev_pc == 0 { @@ -1137,7 +1109,7 @@ pub fn exec_mmbini(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> let prev_instr = (*frame_ptr).code_ptr.add(prev_pc - 1).read(); let dest_reg = Instruction::get_a(prev_instr) as usize; - let rb = *vm.register_stack.as_ptr().add(base_ptr + a); + let rb = *vm.register_stack.as_ptr().add(*base_ptr + a); let rc = LuaValue::integer(sb as i64); // Use pre-cached metamethod StringId @@ -1153,7 +1125,7 @@ pub fn exec_mmbini(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> if !metamethod.is_nil() { let args = if k { vec![rc, rb] } else { vec![rb, rc] }; if let Some(result) = vm.call_metamethod(&metamethod, &args)? { - *vm.register_stack.as_mut_ptr().add(base_ptr + dest_reg) = result; + *vm.register_stack.as_mut_ptr().add(*base_ptr + dest_reg) = result; } } } @@ -1162,14 +1134,13 @@ pub fn exec_mmbini(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> /// MmBinK: Metamethod binary operation (register, constant) #[inline(always)] -pub fn exec_mmbink(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_mmbink(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; let k = Instruction::get_k(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; let prev_pc = (*frame_ptr).pc - 1; if prev_pc == 0 { @@ -1179,7 +1150,7 @@ pub fn exec_mmbink(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> let prev_instr = (*frame_ptr).code_ptr.add(prev_pc - 1).read(); let dest_reg = Instruction::get_a(prev_instr) as usize; - let ra = *vm.register_stack.as_ptr().add(base_ptr + a); + let ra = *vm.register_stack.as_ptr().add(*base_ptr + a); // Get constant let kb = if let Some(func_id) = (*frame_ptr).function_value.as_function_id() { @@ -1213,7 +1184,7 @@ pub fn exec_mmbink(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> if !metamethod.is_nil() { if let Some(result) = vm.call_metamethod(&metamethod, &[left, right])? { - *vm.register_stack.as_mut_ptr().add(base_ptr + dest_reg) = result; + *vm.register_stack.as_mut_ptr().add(*base_ptr + dest_reg) = result; } } } diff --git a/crates/luars/src/lua_vm/execute/control_instructions.rs b/crates/luars/src/lua_vm/execute/control_instructions.rs index 202e3bf3..5dfb4d7d 100644 --- a/crates/luars/src/lua_vm/execute/control_instructions.rs +++ b/crates/luars/src/lua_vm/execute/control_instructions.rs @@ -139,12 +139,12 @@ pub fn exec_return( /// JMP sJ /// pc += sJ #[inline(always)] -pub fn exec_jmp(instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_jmp(instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let sj = Instruction::get_sj(instr); unsafe { // PC already incremented by dispatcher, so we add offset directly - (*frame_ptr).pc = ((*frame_ptr).pc as i32 + sj) as usize; + *pc = ((*frame_ptr).pc as i32 + sj) as usize; } } @@ -154,15 +154,14 @@ pub fn exec_jmp(instr: u32, frame_ptr: *mut LuaCallFrame) { /// if (not R[A] == k) then pc++ /// ULTRA-OPTIMIZED: Direct type tag check, single branch #[inline(always)] -pub fn exec_test(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_test(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let k = Instruction::get_k(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; // OPTIMIZATION: Direct unsafe access and type tag comparison - let value = *vm.register_stack.as_ptr().add(base_ptr + a); + let value = *vm.register_stack.as_ptr().add(*base_ptr + a); // OPTIMIZATION: Fast truthiness check using type tags // nil = TAG_NIL, false = VALUE_FALSE @@ -172,7 +171,7 @@ pub fn exec_test(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { // If (not value) == k, skip next instruction if !is_truthy == k { - (*frame_ptr).pc += 1; + *pc += 1; } } } @@ -181,16 +180,15 @@ pub fn exec_test(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// if (not R[B] == k) then R[A] := R[B] else pc++ /// ULTRA-OPTIMIZED: Direct type tag check, single branch #[inline(always)] -pub fn exec_testset(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_testset(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; // OPTIMIZATION: Direct unsafe access - let reg_ptr = vm.register_stack.as_ptr().add(base_ptr); + let reg_ptr = vm.register_stack.as_ptr().add(*base_ptr); let value = *reg_ptr.add(b); // OPTIMIZATION: Fast truthiness check @@ -199,9 +197,9 @@ pub fn exec_testset(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { // If (is_truthy == k), assign R[A] = R[B], otherwise skip next instruction if is_truthy == k { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = value; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = value; } else { - (*frame_ptr).pc += 1; + *pc += 1; } } } @@ -212,7 +210,7 @@ pub fn exec_testset(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// if ((R[A] == R[B]) ~= k) then pc++ /// ULTRA-OPTIMIZED: Fast path for common types (integers, floats, strings) #[inline(always)] -pub fn exec_eq(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_eq(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); @@ -280,7 +278,7 @@ pub fn exec_eq(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR // If (left == right) != k, skip next instruction if is_equal != k { unsafe { - (*frame_ptr).pc += 1; + *pc += 1; } } @@ -291,14 +289,13 @@ pub fn exec_eq(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR /// if ((R[A] < R[B]) ~= k) then pc++ /// ULTRA-OPTIMIZED: Direct integer fast path like Lua C #[inline(always)] -pub fn exec_lt(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_lt(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_base = vm.register_stack.as_ptr().add(base_ptr); + let reg_base = vm.register_stack.as_ptr().add(*base_ptr); let left = *reg_base.add(a); let right = *reg_base.add(b); @@ -310,7 +307,7 @@ pub fn exec_lt(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR if left_tag == TAG_INTEGER && right_tag == TAG_INTEGER { let is_less = (left.secondary as i64) < (right.secondary as i64); if is_less != k { - (*frame_ptr).pc += 1; + *pc += 1; } return Ok(()); } @@ -319,7 +316,7 @@ pub fn exec_lt(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR if left_tag == TAG_FLOAT && right_tag == TAG_FLOAT { let is_less = f64::from_bits(left.secondary) < f64::from_bits(right.secondary); if is_less != k { - (*frame_ptr).pc += 1; + *pc += 1; } return Ok(()); } @@ -340,7 +337,7 @@ pub fn exec_lt(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR }; let is_less = left_f < right_f; if is_less != k { - (*frame_ptr).pc += 1; + *pc += 1; } return Ok(()); } @@ -350,7 +347,7 @@ pub fn exec_lt(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR if left_tag == TAG_STRING && right_tag == TAG_STRING { let is_less = left < right; if is_less != k { - (*frame_ptr).pc += 1; + *pc += 1; } return Ok(()); } @@ -424,7 +421,7 @@ fn exec_lt_metamethod( /// if ((R[A] <= R[B]) ~= k) then pc++ /// ULTRA-OPTIMIZED: Use combined_tags for fast path like LT #[inline(always)] -pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); @@ -482,7 +479,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR let is_le_result = !result.is_nil() && result.as_bool().unwrap_or(true); if is_le_result != k { unsafe { - (*frame_ptr).pc += 1; + *pc += 1; } } return Ok(()); @@ -500,7 +497,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR let is_le_result = !result.is_nil() && result.as_bool().unwrap_or(true); if is_le_result != k { unsafe { - (*frame_ptr).pc += 1; + *pc += 1; } } return Ok(()); @@ -524,7 +521,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR let is_le_result = !is_gt_result; // a <= b is !(b < a) if is_le_result != k { unsafe { - (*frame_ptr).pc += 1; + *pc += 1; } } return Ok(()); @@ -544,7 +541,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR let is_le_result = !is_gt_result; if is_le_result != k { unsafe { - (*frame_ptr).pc += 1; + *pc += 1; } } return Ok(()); @@ -568,7 +565,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR if is_less_or_equal != k { unsafe { - (*frame_ptr).pc += 1; + *pc += 1; } } @@ -578,7 +575,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaR /// EQK A B k /// if ((R[A] == K[B]) ~= k) then pc++ #[inline(always)] -pub fn exec_eqk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_eqk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); @@ -602,7 +599,7 @@ pub fn exec_eqk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua if is_equal != k { unsafe { - (*frame_ptr).pc += 1; + *pc += 1; } } @@ -612,14 +609,13 @@ pub fn exec_eqk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua /// EQI A sB k /// if ((R[A] == sB) ~= k) then pc++ #[inline(always)] -pub fn exec_eqi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_eqi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let k = Instruction::get_k(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + a); + let left = *vm.register_stack.as_ptr().add(*base_ptr + a); use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; let is_equal = if (left.primary & TYPE_MASK) == TAG_INTEGER { @@ -631,7 +627,7 @@ pub fn exec_eqi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { }; if is_equal != k { - (*frame_ptr).pc += 1; + *pc += 1; } } } @@ -639,14 +635,13 @@ pub fn exec_eqi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// LTI A sB k /// if ((R[A] < sB) ~= k) then pc++ #[inline(always)] -pub fn exec_lti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_lti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let k = Instruction::get_k(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + a); + let left = *vm.register_stack.as_ptr().add(*base_ptr + a); // OPTIMIZATION: Direct type tag comparison use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; @@ -663,7 +658,7 @@ pub fn exec_lti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua }; if is_less != k { - (*frame_ptr).pc += 1; + *pc += 1; } } @@ -673,14 +668,13 @@ pub fn exec_lti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua /// LEI A sB k /// if ((R[A] <= sB) ~= k) then pc++ #[inline(always)] -pub fn exec_lei(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_lei(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let k = Instruction::get_k(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + a); + let left = *vm.register_stack.as_ptr().add(*base_ptr + a); use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; let is_less_equal = if (left.primary & TYPE_MASK) == TAG_INTEGER { @@ -695,7 +689,7 @@ pub fn exec_lei(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua }; if is_less_equal != k { - (*frame_ptr).pc += 1; + *pc += 1; } } @@ -705,14 +699,13 @@ pub fn exec_lei(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua /// GTI A sB k /// if ((R[A] > sB) ~= k) then pc++ #[inline(always)] -pub fn exec_gti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_gti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let k = Instruction::get_k(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + a); + let left = *vm.register_stack.as_ptr().add(*base_ptr + a); use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; let is_greater = if (left.primary & TYPE_MASK) == TAG_INTEGER { @@ -727,7 +720,7 @@ pub fn exec_gti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua }; if is_greater != k { - (*frame_ptr).pc += 1; + *pc += 1; } } @@ -737,14 +730,13 @@ pub fn exec_gti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua /// GEI A sB k /// if ((R[A] >= sB) ~= k) then pc++ #[inline(always)] -pub fn exec_gei(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_gei(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let k = Instruction::get_k(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let left = *vm.register_stack.as_ptr().add(base_ptr + a); + let left = *vm.register_stack.as_ptr().add(*base_ptr + a); use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; let is_greater_equal = if (left.primary & TYPE_MASK) == TAG_INTEGER { @@ -759,7 +751,7 @@ pub fn exec_gei(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lua }; if is_greater_equal != k { - (*frame_ptr).pc += 1; + *pc += 1; } } diff --git a/crates/luars/src/lua_vm/execute/load_instructions.rs b/crates/luars/src/lua_vm/execute/load_instructions.rs index 39bab6b6..4bb78e2f 100644 --- a/crates/luars/src/lua_vm/execute/load_instructions.rs +++ b/crates/luars/src/lua_vm/execute/load_instructions.rs @@ -69,14 +69,13 @@ pub fn exec_varargprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, /// LOADNIL A B /// R[A], R[A+1], ..., R[A+B] := nil #[inline(always)] -pub fn exec_loadnil(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_loadnil(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; let nil_val = LuaValue::nil(); - let reg_ptr = vm.register_stack.as_mut_ptr().add(base_ptr); + let reg_ptr = vm.register_stack.as_mut_ptr().add(*base_ptr); for i in 0..=b { *reg_ptr.add(a + i) = nil_val; } @@ -86,64 +85,59 @@ pub fn exec_loadnil(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// LOADFALSE A /// R[A] := false #[inline(always)] -pub fn exec_loadfalse(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_loadfalse(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(false); + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::boolean(false); } } /// LFALSESKIP A /// R[A] := false; pc++ #[inline(always)] -pub fn exec_lfalseskip(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_lfalseskip(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(false); + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::boolean(false); // Skip next instruction - (*frame_ptr).pc += 1; + *pc += 1; } } /// LOADTRUE A /// R[A] := true #[inline(always)] -pub fn exec_loadtrue(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_loadtrue(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(true); + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::boolean(true); } } /// LOADI A sBx /// R[A] := sBx (signed integer) #[inline(always)] -pub fn exec_loadi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_loadi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let sbx = Instruction::get_sbx(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(sbx as i64); + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(sbx as i64); } } /// LOADF A sBx /// R[A] := (lua_Number)sBx #[inline(always)] -pub fn exec_loadf(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_loadf(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let sbx = Instruction::get_sbx(instr); unsafe { - let base_ptr = (*frame_ptr).base_ptr; - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(sbx as f64); + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(sbx as f64); } } @@ -151,36 +145,34 @@ pub fn exec_loadf(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// R[A] := K[Bx] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_loadk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_loadk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(bx); - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = constant; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = constant; } } /// LOADKX A /// R[A] := K[extra arg] #[inline(always)] -pub fn exec_loadkx(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_loadkx(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; unsafe { - let pc = (*frame_ptr).pc; - (*frame_ptr).pc += 1; // Skip the extra arg instruction - let base_ptr = (*frame_ptr).base_ptr; + let pc_val = (*frame_ptr).pc; + (*frame_ptr).pc = pc_val + 1; // Skip the extra arg instruction let func_id = (*frame_ptr).function_value.as_function_id(); if let Some(fid) = func_id { if let Some(func_ref) = vm.object_pool.get_function(fid) { - if let Some(&extra_instr) = func_ref.chunk.code.get(pc) { + if let Some(&extra_instr) = func_ref.chunk.code.get(pc_val) { let bx = Instruction::get_ax(extra_instr) as usize; if let Some(&constant) = func_ref.chunk.constants.get(bx) { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = constant; + *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = constant; } } } @@ -191,13 +183,12 @@ pub fn exec_loadkx(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// MOVE A B /// R[A] := R[B] #[inline(always)] -pub fn exec_move(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_move(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_ptr = vm.register_stack.as_mut_ptr().add(base_ptr); + let reg_ptr = vm.register_stack.as_mut_ptr().add(*base_ptr); *reg_ptr.add(a) = *reg_ptr.add(b); } } diff --git a/crates/luars/src/lua_vm/execute/loop_instructions.rs b/crates/luars/src/lua_vm/execute/loop_instructions.rs index 39512ae0..74059fea 100644 --- a/crates/luars/src/lua_vm/execute/loop_instructions.rs +++ b/crates/luars/src/lua_vm/execute/loop_instructions.rs @@ -13,13 +13,12 @@ use crate::{ /// Prepare numeric for loop: R[A]-=R[A+2]; R[A+3]=R[A]; if (skip) pc+=Bx+1 /// OPTIMIZED: Uses frame_ptr directly, no i128, unsafe register access #[inline(always)] -pub fn exec_forprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_forprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr + a); + let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr + a); let init = *reg_base; let limit = *reg_base.add(1); @@ -133,13 +132,12 @@ pub fn exec_forprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> /// /// ULTRA-OPTIMIZED: Only check step type (like Lua C), use chgivalue pattern #[inline(always)] -pub fn exec_forloop(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_forloop(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr + a); + let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr + a); // Only check step type - like Lua C's ttisinteger(s2v(ra + 2)) let step = *reg_base.add(2); @@ -232,17 +230,16 @@ fn exec_forloop_float( /// create upvalue for R[A + 3]; pc+=Bx /// In Lua 5.4, this creates a to-be-closed variable for the state #[inline(always)] -pub fn exec_tforprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_tforprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; // In Lua 5.4, R[A+3] is the to-be-closed variable for the state // For now, we just copy the state value to ensure it's preserved - let state = vm.register_stack[base_ptr + a + 1]; - vm.register_stack[base_ptr + a + 3] = state; + let state = vm.register_stack[*base_ptr + a + 1]; + vm.register_stack[*base_ptr + a + 3] = state; // Jump to loop start (*frame_ptr).pc += bx; @@ -252,7 +249,7 @@ pub fn exec_tforprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// TFORCALL A C /// R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); #[inline(always)] -pub fn exec_tforcall(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_tforcall(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -361,17 +358,16 @@ pub fn exec_tforcall(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - /// TFORLOOP A Bx /// if R[A+1] ~= nil then { R[A]=R[A+1]; pc -= Bx } #[inline(always)] -pub fn exec_tforloop(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_tforloop(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let value = vm.register_stack[base_ptr + a + 1]; + let value = vm.register_stack[*base_ptr + a + 1]; if !value.is_nil() { // Continue loop - vm.register_stack[base_ptr + a] = value; + vm.register_stack[*base_ptr + a] = value; (*frame_ptr).pc -= bx; } } diff --git a/crates/luars/src/lua_vm/execute/mod.rs b/crates/luars/src/lua_vm/execute/mod.rs index dbf516fe..887559b5 100644 --- a/crates/luars/src/lua_vm/execute/mod.rs +++ b/crates/luars/src/lua_vm/execute/mod.rs @@ -17,28 +17,32 @@ pub use table_instructions::*; pub use upvalue_instructions::*; use super::{Instruction, LuaError, LuaResult, LuaVM, OpCode}; +use crate::lua_vm::LuaCallFrame; use crate::LuaValue; -use crate::lua_value::{TAG_INTEGER, TAG_FLOAT, TYPE_MASK}; +use crate::lua_value::TAG_INTEGER; -/// Update base_ptr from frame (like Lua C's updatebase macro) -/// Called after operations that may change the call stack -#[inline(always)] -unsafe fn updatebase(frame_ptr: *mut crate::lua_vm::LuaCallFrame, base_ptr: &mut usize) { - *base_ptr = (*frame_ptr).base_ptr; +/// Save current pc to frame (like Lua C's savepc macro) +/// Called before operations that may call Lua functions (CALL, metamethods, etc.) +macro_rules! savepc { + ($frame_ptr:expr, $pc:expr) => { + unsafe { (*$frame_ptr).pc = $pc; } + }; } -/// Update both pc and base_ptr from frame -/// Used after CALL/RETURN instructions +/// Update pc, code_ptr and base_ptr from frame (like Lua C's updatestate) +/// Used after CALL/RETURN instructions when frame changes #[inline(always)] unsafe fn updatestate( - frame_ptr: *mut crate::lua_vm::LuaCallFrame, + frame_ptr: *mut LuaCallFrame, pc: &mut usize, code_ptr: &mut *const u32, base_ptr: &mut usize ) { - *pc = (*frame_ptr).pc; - *code_ptr = (*frame_ptr).code_ptr; - *base_ptr = (*frame_ptr).base_ptr; + unsafe { + *pc = (*frame_ptr).pc; + *code_ptr = (*frame_ptr).code_ptr; + *base_ptr = (*frame_ptr).base_ptr; + } } /// Ultra-optimized main execution loop @@ -186,36 +190,11 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } - // ============ Arithmetic (inline integer fast path) ============ + // ============ Arithmetic operations ============ OpCode::Add => { - let a = Instruction::get_a(instr) as usize; - let b = Instruction::get_b(instr) as usize; - let c = Instruction::get_c(instr) as usize; - unsafe { - let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); - let left = *reg_base.add(b); - let right = *reg_base.add(c); - let combined_tags = (left.primary | right.primary) & TYPE_MASK; - if combined_tags == TAG_INTEGER { - let result = (left.secondary as i64).wrapping_add(right.secondary as i64); - *reg_base.add(a) = LuaValue { primary: TAG_INTEGER, secondary: result as u64 }; - pc += 1; // Skip MMBIN - continue 'mainloop; - } - // Float fast path - if combined_tags == TAG_FLOAT { - let result = f64::from_bits(left.secondary) + f64::from_bits(right.secondary); - *reg_base.add(a) = LuaValue { primary: TAG_FLOAT, secondary: result.to_bits() }; - pc += 1; // Skip MMBIN - continue 'mainloop; - } - } - // Slow path: mixed types or metamethods exec_add(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } - - // Other arithmetic - call functions OpCode::Sub => { exec_sub(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; @@ -317,7 +296,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::BNot => { - if let Err(e) = exec_bnot(vm, instr, frame_ptr, &mut base_ptr) { + if let Err(e) = exec_bnot(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; @@ -335,21 +314,24 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } - // ============ Metamethod stubs ============ + // ============ Metamethod stubs (save pc before calling) ============ OpCode::MmBin => { - if let Err(e) = exec_mmbin(vm, instr, frame_ptr, &mut base_ptr) { + savepc!(frame_ptr, pc); + if let Err(e) = exec_mmbin(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::MmBinI => { - if let Err(e) = exec_mmbini(vm, instr, frame_ptr, &mut base_ptr) { + savepc!(frame_ptr, pc); + if let Err(e) = exec_mmbini(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::MmBinK => { - if let Err(e) = exec_mmbink(vm, instr, frame_ptr, &mut base_ptr) { + savepc!(frame_ptr, pc); + if let Err(e) = exec_mmbink(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; @@ -381,11 +363,11 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::EqI => { - exec_eqi(vm, instr, &mut pc, base_ptr); + exec_eqi(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::EqK => { - if let Err(e) = exec_eqk(vm, instr, frame_ptr, &mut pc) { + if let Err(e) = exec_eqk(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; @@ -410,7 +392,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::TestSet => { - exec_testset(vm, instr, &mut pc, base_ptr); + exec_testset(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } @@ -450,21 +432,21 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::TForPrep => { - exec_tforprep(vm, instr, &mut pc, base_ptr); + exec_tforprep(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::TForLoop => { - exec_tforloop(vm, instr, &mut pc, base_ptr); + exec_tforloop(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } // ============ Upvalue operations (inline simple ones) ============ OpCode::GetUpval => { - exec_getupval(vm, instr, frame_ptr, base_ptr); + exec_getupval(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::SetUpval => { - exec_setupval(vm, instr, frame_ptr, base_ptr); + exec_setupval(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } @@ -508,7 +490,9 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Function calls (update state after frame change) ============ OpCode::Call => { - if let Err(e) = exec_call(vm, instr, base_ptr, &mut frame_ptr) { + // Save current pc to frame before call (so return knows where to resume) + savepc!(frame_ptr, pc); + if let Err(e) = exec_call(vm, instr, &mut frame_ptr) { return Err(e); } // Reload state from new frame @@ -516,6 +500,8 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::TailCall => { + // Save current pc before tail call + savepc!(frame_ptr, pc); match exec_tailcall(vm, instr, &mut frame_ptr) { Ok(()) => { unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } @@ -528,59 +514,59 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Table operations ============ OpCode::NewTable => { - exec_newtable(vm, instr, frame_ptr, &mut pc); + exec_newtable(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::GetTable => { - if let Err(e) = exec_gettable(vm, instr, frame_ptr, &mut base_ptr) { + if let Err(e) = exec_gettable(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetTable => { - if let Err(e) = exec_settable(vm, instr, frame_ptr, &mut base_ptr) { + if let Err(e) = exec_settable(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetI => { - if let Err(e) = exec_geti(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_geti(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetI => { - if let Err(e) = exec_seti(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_seti(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetField => { - if let Err(e) = exec_getfield(vm, instr, frame_ptr, &mut base_ptr) { + if let Err(e) = exec_getfield(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetField => { - if let Err(e) = exec_setfield(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_setfield(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetTabUp => { - if let Err(e) = exec_gettabup(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_gettabup(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetTabUp => { - if let Err(e) = exec_settabup(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_settabup(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Self_ => { - if let Err(e) = exec_self(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_self(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; @@ -588,19 +574,19 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Operations that can trigger metamethods ============ OpCode::Unm => { - if let Err(e) = exec_unm(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_unm(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Len => { - if let Err(e) = exec_len(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_len(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Concat => { - if let Err(e) = exec_concat(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_concat(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; @@ -612,13 +598,13 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::Lt => { - if let Err(e) = exec_lt(vm, instr, frame_ptr, &mut pc, base_ptr) { + if let Err(e) = exec_lt(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Le => { - if let Err(e) = exec_le(vm, instr, frame_ptr, &mut pc, base_ptr) { + if let Err(e) = exec_le(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; @@ -626,7 +612,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ TForCall ============ OpCode::TForCall => { - if let Err(e) = exec_tforcall(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_tforcall(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; @@ -634,27 +620,27 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Closure and special ============ OpCode::Closure => { - if let Err(e) = exec_closure(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_closure(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Vararg => { - if let Err(e) = exec_vararg(vm, instr, frame_ptr, base_ptr) { + if let Err(e) = exec_vararg(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetList => { - exec_setlist(vm, instr, frame_ptr, &mut pc, base_ptr); + exec_setlist(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::Close => { - exec_close(vm, instr, base_ptr); + exec_close(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } OpCode::Tbc => { - exec_tbc(vm, instr, base_ptr); + exec_tbc(vm, instr, frame_ptr, &mut pc, &mut base_ptr); continue 'mainloop; } } diff --git a/crates/luars/src/lua_vm/execute/table_instructions.rs b/crates/luars/src/lua_vm/execute/table_instructions.rs index 7717fc89..e471cabb 100644 --- a/crates/luars/src/lua_vm/execute/table_instructions.rs +++ b/crates/luars/src/lua_vm/execute/table_instructions.rs @@ -11,7 +11,7 @@ use crate::lua_vm::{Instruction, LuaCallFrame, LuaResult, LuaVM}; /// k = 1 means EXTRAARG follows with array_size / 256 /// OPTIMIZED: Fast path for common empty/small table case #[inline(always)] -pub fn exec_newtable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_newtable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr); // log2(hash_size) + 1 let c = Instruction::get_c(instr); // array_size % 256 @@ -21,7 +21,7 @@ pub fn exec_newtable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { let hash_size = if b > 0 { 1usize << (b - 1) } else { 0 }; let (base_ptr, func_value) = unsafe { - (*frame_ptr).pc += 1; // Skip EXTRAARG + *pc += 1; // Skip EXTRAARG ((*frame_ptr).base_ptr, (*frame_ptr).function_value) }; @@ -63,7 +63,7 @@ pub fn exec_newtable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// R[A] := R[B][R[C]] /// OPTIMIZED: Fast path for integer keys and tables without metatable #[inline(always)] -pub fn exec_gettable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_gettable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -120,7 +120,7 @@ pub fn exec_gettable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - /// R[A][R[B]] := RK(C) /// OPTIMIZED: Fast path for integer keys and tables without metatable #[inline(always)] -pub fn exec_settable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_settable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -128,16 +128,15 @@ pub fn exec_settable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - // Read all values using unchecked access let (table_value, key_value, set_value) = unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let table = *vm.register_stack.get_unchecked(base_ptr + a); - let key = *vm.register_stack.get_unchecked(base_ptr + b); + let table = *vm.register_stack.get_unchecked(*base_ptr + a); + let key = *vm.register_stack.get_unchecked(*base_ptr + b); let value = if k { // Get constant via cached pointer *(*frame_ptr).constants_ptr.add(c) } else { - *vm.register_stack.get_unchecked(base_ptr + c) + *vm.register_stack.get_unchecked(*base_ptr + c) }; (table, key, value) @@ -174,7 +173,7 @@ pub fn exec_settable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - /// R[A] := R[B][C:integer] /// OPTIMIZED: Direct integer access using get_int_full() without creating LuaValue key #[inline(always)] -pub fn exec_geti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_geti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as i64; // C is unsigned integer index @@ -215,7 +214,7 @@ pub fn exec_geti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lu /// R[A][B] := RK(C) /// OPTIMIZED: Direct integer key access using set_int() #[inline(always)] -pub fn exec_seti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_seti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as i64; // B is unsigned integer key let c = Instruction::get_c(instr) as usize; @@ -223,15 +222,14 @@ pub fn exec_seti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lu // CRITICAL: Read all values BEFORE any metamethod calls let (table_value, set_value) = unsafe { - let base_ptr = (*frame_ptr).base_ptr; - let table = *vm.register_stack.get_unchecked(base_ptr + a); + let table = *vm.register_stack.get_unchecked(*base_ptr + a); let value = if k { // Get constant via cached pointer for speed *(*frame_ptr).constants_ptr.add(c) } else { - *vm.register_stack.get_unchecked(base_ptr + c) + *vm.register_stack.get_unchecked(*base_ptr + c) }; (table, value) @@ -264,7 +262,7 @@ pub fn exec_seti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> Lu /// GETFIELD A B C /// R[A] := R[B][K[C]:string] #[inline(always)] -pub fn exec_getfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_getfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -318,7 +316,7 @@ pub fn exec_getfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - /// SETFIELD A B C k /// R[A][K[B]:string] := RK(C) #[inline(always)] -pub fn exec_setfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_setfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -327,7 +325,6 @@ pub fn exec_setfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - // CRITICAL: Read all values BEFORE any metamethod calls // because metamethods can modify the register stack let (table_value, key_value, set_value) = unsafe { - let base_ptr = (*frame_ptr).base_ptr; let func_value = (*frame_ptr).function_value; // Get key constant using new API @@ -341,7 +338,7 @@ pub fn exec_setfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - return Err(vm.error(format!("Invalid constant index: {}", b))); }; - let table = vm.register_stack[base_ptr + a]; + let table = vm.register_stack[*base_ptr + a]; let value = if k { let Some(constant) = func_ref.chunk.constants.get(c).copied() else { @@ -349,7 +346,7 @@ pub fn exec_setfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - }; constant } else { - vm.register_stack[base_ptr + c] + vm.register_stack[*base_ptr + c] }; (table, key, value) @@ -379,7 +376,7 @@ pub fn exec_setfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - /// R[A] := UpValue[B][K[C]:string] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_gettabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_gettabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -437,7 +434,7 @@ pub fn exec_gettabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - /// UpValue[A][K[B]:string] := RK(C) /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_settabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_settabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -493,7 +490,7 @@ pub fn exec_settabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) - /// SELF A B C /// R[A+1] := R[B]; R[A] := R[B][RK(C):string] #[inline(always)] -pub fn exec_self(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_self(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; diff --git a/crates/luars/src/lua_vm/execute/upvalue_instructions.rs b/crates/luars/src/lua_vm/execute/upvalue_instructions.rs index 5eabb352..dcf32298 100644 --- a/crates/luars/src/lua_vm/execute/upvalue_instructions.rs +++ b/crates/luars/src/lua_vm/execute/upvalue_instructions.rs @@ -9,7 +9,7 @@ use crate::{ /// GETUPVAL A B /// R[A] := UpValue[B] #[inline(always)] -pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -31,7 +31,7 @@ pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// SETUPVAL A B /// UpValue[B] := R[A] #[inline(always)] -pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -51,7 +51,7 @@ pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// CLOSE A /// close all upvalues >= R[A] #[inline(always)] -pub fn exec_close(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_close(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let base_ptr = unsafe { (*frame_ptr).base_ptr }; let close_from = base_ptr + a; @@ -63,7 +63,7 @@ pub fn exec_close(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// R[A] := closure(KPROTO[Bx]) /// OPTIMIZED: Fast path for closures without upvalues #[inline(always)] -pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { use crate::gc::UpvalueId; let a = Instruction::get_a(instr) as usize; @@ -157,7 +157,7 @@ pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> /// Vararg arguments are stored at frame.vararg_start (set by VARARGPREP). /// This instruction copies them to the target registers. #[inline(always)] -pub fn exec_vararg(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_vararg(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -207,7 +207,7 @@ pub fn exec_vararg(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> /// R[A] := R[A].. ... ..R[A+B] /// OPTIMIZED: Pre-allocation for string/number combinations #[inline(always)] -pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> LuaResult<()> { +pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -356,7 +356,7 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) -> /// SETLIST A B C k /// R[A][C+i] := R[A+i], 1 <= i <= B #[inline(always)] -pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -400,7 +400,7 @@ pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { /// mark variable A as to-be-closed /// This marks a variable to have its __close metamethod called when it goes out of scope #[inline(always)] -pub fn exec_tbc(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame) { +pub fn exec_tbc(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; let base_ptr = unsafe { (*frame_ptr).base_ptr }; let reg_idx = base_ptr + a; From 58b9701f3a384b1125482a60e70632b8f7f3142b Mon Sep 17 00:00:00 2001 From: CppCXY <812125110@qq.com> Date: Tue, 2 Dec 2025 11:29:09 +0800 Subject: [PATCH 4/7] update --- .../lua_vm/execute/arithmetic_instructions.rs | 37 +++++----- .../lua_vm/execute/control_instructions.rs | 9 +-- .../src/lua_vm/execute/loop_instructions.rs | 15 ++-- .../src/lua_vm/execute/table_instructions.rs | 72 +++++++++---------- .../lua_vm/execute/upvalue_instructions.rs | 46 ++++++------ 5 files changed, 86 insertions(+), 93 deletions(-) diff --git a/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs b/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs index a6f5d2bc..9e71d4ac 100644 --- a/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs +++ b/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs @@ -32,7 +32,7 @@ fn exec_add_slow( }; *reg_base.add(a) = result; - (*frame_ptr).pc += 1; + // pc increment handled by caller } } @@ -76,7 +76,7 @@ fn exec_sub_slow( a: usize, left: LuaValue, right: LuaValue, - frame_ptr: *mut LuaCallFrame, + pc: &mut usize, ) { unsafe { let left_tag = left.primary & TYPE_MASK; @@ -93,7 +93,7 @@ fn exec_sub_slow( }; *reg_base.add(a) = result; - (*frame_ptr).pc += 1; + *pc += 1; } } @@ -122,7 +122,7 @@ pub fn exec_sub(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m return; } - exec_sub_slow(reg_base, a, left, right, frame_ptr); + exec_sub_slow(reg_base, a, left, right, pc); } } @@ -151,7 +151,7 @@ fn exec_mul_slow( }; *reg_base.add(a) = result; - (*frame_ptr).pc += 1; + // pc skip handled by caller } } @@ -346,8 +346,7 @@ pub fn exec_unm(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; - let base_ptr = unsafe { (*frame_ptr).base_ptr }; - let value = vm.register_stack[base_ptr + b]; + let value = vm.register_stack[*base_ptr + b]; let result = if let Some(i) = value.as_integer() { if let Some(neg) = i.checked_neg() { @@ -366,7 +365,7 @@ pub fn exec_unm(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m let result = vm .call_metamethod(&metamethod, &[value])? .unwrap_or(LuaValue::nil()); - vm.register_stack[base_ptr + a] = result; + vm.register_stack[*base_ptr + a] = result; return Ok(()); } } @@ -377,7 +376,7 @@ pub fn exec_unm(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m ))); }; - vm.register_stack[base_ptr + a] = result; + vm.register_stack[*base_ptr + a] = result; Ok(()) } @@ -955,11 +954,10 @@ pub fn exec_bnot(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; - let base_ptr = unsafe { (*frame_ptr).base_ptr }; - let value = vm.register_stack[base_ptr + b]; + let value = vm.register_stack[*base_ptr + b]; if let Some(int_val) = value.as_integer() { - vm.register_stack[base_ptr + a] = LuaValue::integer(!int_val); + vm.register_stack[*base_ptr + a] = LuaValue::integer(!int_val); return Ok(()); } @@ -971,7 +969,7 @@ pub fn exec_bnot(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & let result = vm .call_metamethod(&metamethod, &[value])? .unwrap_or(LuaValue::nil()); - vm.register_stack[base_ptr + a] = result; + vm.register_stack[*base_ptr + a] = result; return Ok(()); } } @@ -1005,8 +1003,7 @@ pub fn exec_len(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; - let base_ptr = unsafe { (*frame_ptr).base_ptr }; - let value = vm.register_stack[base_ptr + b]; + let value = vm.register_stack[*base_ptr + b]; // Check for __len metamethod first (for tables) if value.is_table() { @@ -1018,7 +1015,7 @@ pub fn exec_len(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m let result = vm .call_metamethod(&metamethod, &[value])? .unwrap_or(LuaValue::nil()); - vm.register_stack[base_ptr + a] = result; + vm.register_stack[*base_ptr + a] = result; return Ok(()); } } @@ -1043,7 +1040,7 @@ pub fn exec_len(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m }; let result = LuaValue::integer(len); - vm.register_stack[base_ptr + a] = result; + vm.register_stack[*base_ptr + a] = result; Ok(()) } @@ -1055,7 +1052,7 @@ pub fn exec_mmbin(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: let c = Instruction::get_c(instr) as usize; unsafe { - let prev_pc = (*frame_ptr).pc - 1; + let prev_pc = *pc - 1; if prev_pc == 0 { return Ok(()); @@ -1100,7 +1097,7 @@ pub fn exec_mmbini(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: let k = Instruction::get_k(instr); unsafe { - let prev_pc = (*frame_ptr).pc - 1; + let prev_pc = *pc - 1; if prev_pc == 0 { return Ok(()); @@ -1141,7 +1138,7 @@ pub fn exec_mmbink(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: let k = Instruction::get_k(instr); unsafe { - let prev_pc = (*frame_ptr).pc - 1; + let prev_pc = *pc - 1; if prev_pc == 0 { return Ok(()); diff --git a/crates/luars/src/lua_vm/execute/control_instructions.rs b/crates/luars/src/lua_vm/execute/control_instructions.rs index 5dfb4d7d..58157f46 100644 --- a/crates/luars/src/lua_vm/execute/control_instructions.rs +++ b/crates/luars/src/lua_vm/execute/control_instructions.rs @@ -144,7 +144,7 @@ pub fn exec_jmp(instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_p unsafe { // PC already incremented by dispatcher, so we add offset directly - *pc = ((*frame_ptr).pc as i32 + sj) as usize; + *pc = (*pc as i32 + sj) as usize; } } @@ -353,7 +353,7 @@ pub fn exec_lt(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mu } // Slow path: metamethod - exec_lt_metamethod(vm, left, right, k, frame_ptr) + exec_lt_metamethod(vm, left, right, k, frame_ptr, pc) } } @@ -366,6 +366,7 @@ fn exec_lt_metamethod( right: crate::LuaValue, k: bool, frame_ptr: *mut LuaCallFrame, + pc: &mut usize, ) -> LuaResult<()> { // Use pre-cached __lt StringId let mm_key = LuaValue::string(vm.object_pool.tm_lt); @@ -378,7 +379,7 @@ fn exec_lt_metamethod( let is_less_result = !result.is_nil() && result.as_bool().unwrap_or(true); if is_less_result != k { unsafe { - (*frame_ptr).pc += 1; + *pc += 1; } } return Ok(()); @@ -396,7 +397,7 @@ fn exec_lt_metamethod( let is_less_result = !result.is_nil() && result.as_bool().unwrap_or(true); if is_less_result != k { unsafe { - (*frame_ptr).pc += 1; + *pc += 1; } } return Ok(()); diff --git a/crates/luars/src/lua_vm/execute/loop_instructions.rs b/crates/luars/src/lua_vm/execute/loop_instructions.rs index 74059fea..845a1c7c 100644 --- a/crates/luars/src/lua_vm/execute/loop_instructions.rs +++ b/crates/luars/src/lua_vm/execute/loop_instructions.rs @@ -66,7 +66,7 @@ pub fn exec_forprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc if count == 0 { // Skip the entire loop body and FORLOOP - (*frame_ptr).pc += bx; + *pc += bx; } else { // Store count-1 in R[A+1] (we'll execute count times, counter starts at count-1) // because we already set R[A+3] = init for the first iteration @@ -115,7 +115,7 @@ pub fn exec_forprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc }; if should_skip { - (*frame_ptr).pc += bx; + *pc += bx; } else { // Prepare internal index *reg_base = LuaValue::number(init_f - step_f); @@ -156,14 +156,14 @@ pub fn exec_forloop(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc (*reg_base).secondary = new_idx as u64; // idx += step (*reg_base.add(3)).secondary = new_idx as u64; // control = idx - (*frame_ptr).pc -= bx; + *pc -= bx; } // count == 0: loop ended, fall through return Ok(()); } // Float loop - slower path - exec_forloop_float(vm, reg_base, bx, frame_ptr) + exec_forloop_float(vm, reg_base, bx, frame_ptr, pc) } } @@ -175,6 +175,7 @@ fn exec_forloop_float( reg_base: *mut LuaValue, bx: usize, frame_ptr: *mut LuaCallFrame, + pc: &mut usize, ) -> LuaResult<()> { unsafe { let idx = *reg_base; @@ -219,7 +220,7 @@ fn exec_forloop_float( if should_continue { *reg_base = LuaValue::number(new_idx_f); *reg_base.add(3) = LuaValue::number(new_idx_f); - (*frame_ptr).pc -= bx; + *pc -= bx; } } @@ -242,7 +243,7 @@ pub fn exec_tforprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p vm.register_stack[*base_ptr + a + 3] = state; // Jump to loop start - (*frame_ptr).pc += bx; + *pc += bx; } } @@ -368,7 +369,7 @@ pub fn exec_tforloop(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p if !value.is_nil() { // Continue loop vm.register_stack[*base_ptr + a] = value; - (*frame_ptr).pc -= bx; + *pc -= bx; } } } diff --git a/crates/luars/src/lua_vm/execute/table_instructions.rs b/crates/luars/src/lua_vm/execute/table_instructions.rs index e471cabb..76c8886c 100644 --- a/crates/luars/src/lua_vm/execute/table_instructions.rs +++ b/crates/luars/src/lua_vm/execute/table_instructions.rs @@ -20,20 +20,20 @@ pub fn exec_newtable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p // Decode hash size: if b > 0, hash_size = 2^(b-1) let hash_size = if b > 0 { 1usize << (b - 1) } else { 0 }; - let (base_ptr, func_value) = unsafe { + let func_value = unsafe { *pc += 1; // Skip EXTRAARG - ((*frame_ptr).base_ptr, (*frame_ptr).function_value) + (*frame_ptr).function_value }; // Calculate array size - C is low bits, EXTRAARG has high bits when k=1 let array_size = if k { // Need to read EXTRAARG for large arrays - let pc = unsafe { (*frame_ptr).pc - 1 }; // We already incremented pc + let prev_pc = *pc - 1; // We already incremented pc // Use new ID-based API to get function and read EXTRAARG if let Some(func_id) = func_value.as_function_id() { if let Some(func_ref) = vm.object_pool.get_function(func_id) { - if pc < func_ref.chunk.code.len() { - let extra = Instruction::get_ax(func_ref.chunk.code[pc]) as usize; + if prev_pc < func_ref.chunk.code.len() { + let extra = Instruction::get_ax(func_ref.chunk.code[prev_pc]) as usize; extra * 256 + c as usize // MAXARG_C + 1 = 256 } else { c as usize @@ -53,7 +53,7 @@ pub fn exec_newtable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p // Store in register - use unchecked for speed unsafe { - *vm.register_stack.get_unchecked_mut(base_ptr + a) = table; + *vm.register_stack.get_unchecked_mut(*base_ptr + a) = table; } // GC checkpoint disabled for testing @@ -69,11 +69,10 @@ pub fn exec_gettable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p let c = Instruction::get_c(instr) as usize; // Read values using unchecked access - let (table_value, key_value, base_ptr) = unsafe { - let bp = (*frame_ptr).base_ptr; - let table = *vm.register_stack.get_unchecked(bp + b); - let key = *vm.register_stack.get_unchecked(bp + c); - (table, key, bp) + let (table_value, key_value) = unsafe { + let table = *vm.register_stack.get_unchecked(*base_ptr + b); + let key = *vm.register_stack.get_unchecked(*base_ptr + c); + (table, key) }; // FAST PATH: Direct table access for common case (integer key, no metatable) @@ -84,7 +83,7 @@ pub fn exec_gettable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p // Try integer key fast path first if let Some(i) = key_value.as_integer() { if let Some(val) = lua_table.get_int(i) { - unsafe { *vm.register_stack.get_unchecked_mut(base_ptr + a) = val }; + unsafe { *vm.register_stack.get_unchecked_mut(*base_ptr + a) = val }; return Ok(()); } } @@ -92,14 +91,14 @@ pub fn exec_gettable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p // Try hash lookup if let Some(val) = lua_table.get_from_hash(&key_value) { if !val.is_nil() { - unsafe { *vm.register_stack.get_unchecked_mut(base_ptr + a) = val }; + unsafe { *vm.register_stack.get_unchecked_mut(*base_ptr + a) = val }; return Ok(()); } } // Key not found - check if no metatable to skip metamethod handling if lua_table.get_metatable().is_none() { - unsafe { *vm.register_stack.get_unchecked_mut(base_ptr + a) = LuaValue::nil() }; + unsafe { *vm.register_stack.get_unchecked_mut(*base_ptr + a) = LuaValue::nil() }; return Ok(()); } } @@ -110,8 +109,8 @@ pub fn exec_gettable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p .unwrap_or(LuaValue::nil()); // Re-read base_ptr after metamethod call - let new_base_ptr = unsafe { (*frame_ptr).base_ptr }; - vm.register_stack[new_base_ptr + a] = value; + *base_ptr = unsafe { (*frame_ptr).base_ptr }; + vm.register_stack[*base_ptr + a] = value; Ok(()) } @@ -178,8 +177,7 @@ pub fn exec_geti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as i64; // C is unsigned integer index - let base_ptr = unsafe { (*frame_ptr).base_ptr }; - let table = unsafe { *vm.register_stack.get_unchecked(base_ptr + b) }; + let table = unsafe { *vm.register_stack.get_unchecked(*base_ptr + b) }; // FAST PATH: Direct integer access for tables using unchecked access if let Some(table_id) = table.as_table_id() { @@ -189,13 +187,13 @@ pub fn exec_geti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Use get_int_full to check both array and hash parts // This is necessary because integer keys may be stored in hash if array wasn't pre-allocated if let Some(val) = lua_table.get_int_full(c) { - unsafe { *vm.register_stack.get_unchecked_mut(base_ptr + a) = val }; + unsafe { *vm.register_stack.get_unchecked_mut(*base_ptr + a) = val }; return Ok(()); } // Key not found - check if no metatable to skip metamethod handling if lua_table.get_metatable().is_none() { - unsafe { *vm.register_stack.get_unchecked_mut(base_ptr + a) = LuaValue::nil() }; + unsafe { *vm.register_stack.get_unchecked_mut(*base_ptr + a) = LuaValue::nil() }; return Ok(()); } } @@ -205,7 +203,7 @@ pub fn exec_geti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & let value = vm .table_get_with_meta(&table, &key) .unwrap_or(LuaValue::nil()); - vm.register_stack[base_ptr + a] = value; + vm.register_stack[*base_ptr + a] = value; Ok(()) } @@ -267,7 +265,7 @@ pub fn exec_getfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; - let (base_ptr, func_value) = unsafe { ((*frame_ptr).base_ptr, (*frame_ptr).function_value) }; + let func_value = unsafe { (*frame_ptr).function_value }; // Get key constant using new API let Some(func_id) = func_value.as_function_id() else { @@ -280,7 +278,7 @@ pub fn exec_getfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p return Err(vm.error(format!("Invalid constant index: {}", c))); }; - let table_value = vm.register_stack[base_ptr + b]; + let table_value = vm.register_stack[*base_ptr + b]; // FAST PATH: Direct hash access for tables without metatable if let Some(table_id) = table_value.as_table_id() { @@ -288,14 +286,14 @@ pub fn exec_getfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p // Use optimized hash-only lookup (GETFIELD always uses string keys, never integers) if let Some(val) = table_ref.get_from_hash(&key_value) { if !val.is_nil() { - vm.register_stack[base_ptr + a] = val; + vm.register_stack[*base_ptr + a] = val; return Ok(()); } } // Check if no metatable - can return nil directly if table_ref.get_metatable().is_none() { - vm.register_stack[base_ptr + a] = LuaValue::nil(); + vm.register_stack[*base_ptr + a] = LuaValue::nil(); return Ok(()); } } @@ -307,8 +305,8 @@ pub fn exec_getfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p .unwrap_or(LuaValue::nil()); // IMPORTANT: Re-read base_ptr after metamethod call in case frames changed - let new_base_ptr = unsafe { (*frame_ptr).base_ptr }; - vm.register_stack[new_base_ptr + a] = value; + *base_ptr = unsafe { (*frame_ptr).base_ptr }; + vm.register_stack[*base_ptr + a] = value; Ok(()) } @@ -381,7 +379,7 @@ pub fn exec_gettabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; - let (base_ptr, func_value) = unsafe { ((*frame_ptr).base_ptr, (*frame_ptr).function_value) }; + let func_value = unsafe { (*frame_ptr).function_value }; // FAST PATH: Direct constant access via cached pointer let key_value = unsafe { *(*frame_ptr).constants_ptr.add(c) }; @@ -407,14 +405,14 @@ pub fn exec_gettabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p // Try direct access if let Some(val) = table_ref.raw_get(&key_value) { if !val.is_nil() { - vm.register_stack[base_ptr + a] = val; + vm.register_stack[*base_ptr + a] = val; return Ok(()); } } // Check if no metatable - can return nil directly if table_ref.get_metatable().is_none() { - vm.register_stack[base_ptr + a] = LuaValue::nil(); + vm.register_stack[*base_ptr + a] = LuaValue::nil(); return Ok(()); } } @@ -425,7 +423,7 @@ pub fn exec_gettabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p .table_get_with_meta(&table_value, &key_value) .unwrap_or(LuaValue::nil()); - vm.register_stack[base_ptr + a] = value; + vm.register_stack[*base_ptr + a] = value; Ok(()) } @@ -440,7 +438,7 @@ pub fn exec_settabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p let c = Instruction::get_c(instr) as usize; let k = Instruction::get_k(instr); - let (base_ptr, func_value) = unsafe { ((*frame_ptr).base_ptr, (*frame_ptr).function_value) }; + let func_value = unsafe { (*frame_ptr).function_value }; // FAST PATH: Direct constant access via cached pointer let key_value = unsafe { *(*frame_ptr).constants_ptr.add(b) }; @@ -449,7 +447,7 @@ pub fn exec_settabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p let set_value = if k { unsafe { *(*frame_ptr).constants_ptr.add(c) } } else { - vm.register_stack[base_ptr + c] + vm.register_stack[*base_ptr + c] }; // Get function for upvalues access (still needed) @@ -495,8 +493,8 @@ pub fn exec_self(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; - let (base_ptr, func_value) = unsafe { ((*frame_ptr).base_ptr, (*frame_ptr).function_value) }; - let table = vm.register_stack[base_ptr + b]; + let func_value = unsafe { (*frame_ptr).function_value }; + let table = vm.register_stack[*base_ptr + b]; // Get method key from constant using new API let Some(func_id) = func_value.as_function_id() else { @@ -510,7 +508,7 @@ pub fn exec_self(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & }; // R[A+1] := R[B] (self parameter) - vm.register_stack[base_ptr + a + 1] = table; + vm.register_stack[*base_ptr + a + 1] = table; // R[A] := R[B][K[C]] (method) // Support both tables and userdata @@ -521,7 +519,7 @@ pub fn exec_self(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & vm.table_get_with_meta(&table, &key) .unwrap_or(crate::LuaValue::nil()) }; - vm.register_stack[base_ptr + a] = method; + vm.register_stack[*base_ptr + a] = method; Ok(()) } diff --git a/crates/luars/src/lua_vm/execute/upvalue_instructions.rs b/crates/luars/src/lua_vm/execute/upvalue_instructions.rs index dcf32298..bc49de34 100644 --- a/crates/luars/src/lua_vm/execute/upvalue_instructions.rs +++ b/crates/luars/src/lua_vm/execute/upvalue_instructions.rs @@ -13,7 +13,7 @@ pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; - let (base_ptr, func_value) = unsafe { ((*frame_ptr).base_ptr, (*frame_ptr).function_value) }; + let func_value = unsafe { (*frame_ptr).function_value }; // OPTIMIZED: Use unchecked access since we know the function is valid let func_id = unsafe { func_value.as_function_id().unwrap_unchecked() }; @@ -24,7 +24,7 @@ pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p // SAFETY: upvalue_id is from a valid function closure let value = unsafe { vm.read_upvalue_unchecked(upvalue_id) }; unsafe { - *vm.register_stack.get_unchecked_mut(base_ptr + a) = value; + *vm.register_stack.get_unchecked_mut(*base_ptr + a) = value; } } @@ -35,14 +35,14 @@ pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; - let (base_ptr, func_value) = unsafe { ((*frame_ptr).base_ptr, (*frame_ptr).function_value) }; + let func_value = unsafe { (*frame_ptr).function_value }; // OPTIMIZED: Use unchecked access since we know the function is valid let func_id = unsafe { func_value.as_function_id().unwrap_unchecked() }; let func_ref = unsafe { vm.object_pool.get_function_unchecked(func_id) }; let upvalue_id = unsafe { *func_ref.upvalues.get_unchecked(b) }; - let value = unsafe { *vm.register_stack.get_unchecked(base_ptr + a) }; + let value = unsafe { *vm.register_stack.get_unchecked(*base_ptr + a) }; // Set upvalue value using the helper method vm.write_upvalue(upvalue_id, value); @@ -53,8 +53,7 @@ pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p #[inline(always)] pub fn exec_close(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; - let base_ptr = unsafe { (*frame_ptr).base_ptr }; - let close_from = base_ptr + a; + let close_from = *base_ptr + a; vm.close_upvalues_from(close_from); } @@ -66,11 +65,11 @@ pub fn exec_close(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { use crate::gc::UpvalueId; + let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; - let (base_ptr, func_value) = unsafe { ((*frame_ptr).base_ptr, (*frame_ptr).function_value) }; - + let func_value = unsafe { (*frame_ptr).function_value }; // Get current function using ID-based lookup let func_id = func_value .as_function_id() @@ -92,7 +91,7 @@ pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc if proto.upvalue_descs.is_empty() { let closure = vm.create_function(proto, Vec::new()); unsafe { - *vm.register_stack.get_unchecked_mut(base_ptr + a) = closure; + *vm.register_stack.get_unchecked_mut(*base_ptr + a) = closure; } vm.check_gc(); return Ok(()); @@ -109,7 +108,7 @@ pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc if desc.is_local { // Upvalue refers to a register in current function // Calculate absolute stack index for this upvalue - let stack_index = base_ptr + desc.index as usize; + let stack_index = *base_ptr + desc.index as usize; // Check if this upvalue is already open let existing = vm.open_upvalues.iter().find(|uv_id| { @@ -142,7 +141,7 @@ pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc let closure = vm.create_function(proto, upvalue_ids); unsafe { - *vm.register_stack.get_unchecked_mut(base_ptr + a) = closure; + *vm.register_stack.get_unchecked_mut(*base_ptr + a) = closure; } // GC checkpoint: closure now safely stored in register @@ -211,8 +210,6 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; - let base_ptr = unsafe { (*frame_ptr).base_ptr }; - // ULTRA-OPTIMIZED: Build result string directly without intermediate allocations // Estimate total capacity and format numbers inline with itoa let mut total_capacity = 0usize; @@ -220,7 +217,7 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: // First pass: check types and estimate capacity for i in 0..=b { - let value = vm.register_stack[base_ptr + a + i]; + let value = vm.register_stack[*base_ptr + a + i]; if let Some(str_id) = value.as_string_id() { if let Some(s) = vm.object_pool.get_string(str_id) { @@ -243,7 +240,7 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: let mut float_buffer = ryu::Buffer::new(); for i in 0..=b { - let value = vm.register_stack[base_ptr + a + i]; + let value = vm.register_stack[*base_ptr + a + i]; if let Some(str_id) = value.as_string_id() { if let Some(s) = vm.object_pool.get_string(str_id) { @@ -260,7 +257,7 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: // OPTIMIZED: Use create_string_owned to avoid extra clone let result_value = vm.create_string_owned(result); - vm.register_stack[base_ptr + a] = result_value; + vm.register_stack[*base_ptr + a] = result_value; // No GC check for fast path - rely on debt mechanism // Only large allocations trigger automatic GC @@ -268,10 +265,10 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: } // Slow path: need to handle metamethods - let mut result_value = vm.register_stack[base_ptr + a]; + let mut result_value = vm.register_stack[*base_ptr + a]; for i in 1..=b { - let next_value = vm.register_stack[base_ptr + a + i]; + let next_value = vm.register_stack[*base_ptr + a + i]; // Try direct concatenation first let left_str = if let Some(str_id) = result_value.as_string_id() { @@ -347,7 +344,7 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: } } - vm.register_stack[base_ptr + a] = result_value; + vm.register_stack[*base_ptr + a] = result_value; // No GC check - rely on debt mechanism Ok(()) @@ -361,8 +358,8 @@ pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; - let (base_ptr, top) = unsafe { ((*frame_ptr).base_ptr, (*frame_ptr).top) }; - let table = vm.register_stack[base_ptr + a]; + let top = unsafe { (*frame_ptr).top }; + let table = vm.register_stack[*base_ptr + a]; let start_idx = c * 50; // 0-based for array indexing let count = if b == 0 { top - a - 1 } else { b }; @@ -382,7 +379,7 @@ pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc for i in 0..count { unsafe { *t.array.get_unchecked_mut(start_idx + i) = - *vm.register_stack.get_unchecked(base_ptr + a + 1 + i); + *vm.register_stack.get_unchecked(*base_ptr + a + 1 + i); } } return; @@ -391,7 +388,7 @@ pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc // Slow path with metamethods for i in 0..count { let key = LuaValue::integer((start_idx + i + 1) as i64); - let value = vm.register_stack[base_ptr + a + i + 1]; + let value = vm.register_stack[*base_ptr + a + i + 1]; let _ = vm.table_set_with_meta(table, key, value); } } @@ -402,8 +399,7 @@ pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc #[inline(always)] pub fn exec_tbc(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { let a = Instruction::get_a(instr) as usize; - let base_ptr = unsafe { (*frame_ptr).base_ptr }; - let reg_idx = base_ptr + a; + let reg_idx = *base_ptr + a; // Get the value to be marked as to-be-closed let value = vm.register_stack[reg_idx]; From 3dcf680c31a955fc749d0514833bdcc4a32a7e8b Mon Sep 17 00:00:00 2001 From: CppCXY <812125110@qq.com> Date: Tue, 2 Dec 2025 13:39:42 +0800 Subject: [PATCH 5/7] Fix --- .../lua_vm/execute/arithmetic_instructions.rs | 392 ++++++++++-------- crates/luars/src/lua_vm/execute/mod.rs | 152 +++---- 2 files changed, 294 insertions(+), 250 deletions(-) diff --git a/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs b/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs index 9e71d4ac..80f8224d 100644 --- a/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs +++ b/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs @@ -7,45 +7,16 @@ use crate::{ lua_vm::{Instruction, LuaCallFrame, LuaResult, LuaVM}, }; -/// Slow path for ADD - separate function to hint branch predictor -#[cold] -#[inline(never)] -fn exec_add_slow( - reg_base: *mut LuaValue, - a: usize, - left: LuaValue, - right: LuaValue, - frame_ptr: *mut LuaCallFrame, -) { - unsafe { - let left_tag = left.primary & TYPE_MASK; - let right_tag = right.primary & TYPE_MASK; - - let result = if left_tag == TAG_FLOAT && right_tag == TAG_FLOAT { - LuaValue::number(f64::from_bits(left.secondary) + f64::from_bits(right.secondary)) - } else if left_tag == TAG_INTEGER && right_tag == TAG_FLOAT { - LuaValue::number((left.secondary as i64) as f64 + f64::from_bits(right.secondary)) - } else if left_tag == TAG_FLOAT && right_tag == TAG_INTEGER { - LuaValue::number(f64::from_bits(left.secondary) + (right.secondary as i64) as f64) - } else { - return; - }; - - *reg_base.add(a) = result; - // pc increment handled by caller - } -} - /// ADD: R[A] = R[B] + R[C] /// OPTIMIZED: Matches Lua C's setivalue behavior - always write both fields #[inline(always)] -pub fn exec_add(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_add(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr); + let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -63,31 +34,15 @@ pub fn exec_add(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m return; } - // Slow path: Float operations - in separate cold function - exec_add_slow(reg_base, a, left, right, frame_ptr); - } -} - -/// Slow path for SUB -#[cold] -#[inline(never)] -fn exec_sub_slow( - reg_base: *mut LuaValue, - a: usize, - left: LuaValue, - right: LuaValue, - pc: &mut usize, -) { - unsafe { let left_tag = left.primary & TYPE_MASK; let right_tag = right.primary & TYPE_MASK; let result = if left_tag == TAG_FLOAT && right_tag == TAG_FLOAT { - LuaValue::number(f64::from_bits(left.secondary) - f64::from_bits(right.secondary)) + LuaValue::number(f64::from_bits(left.secondary) + f64::from_bits(right.secondary)) } else if left_tag == TAG_INTEGER && right_tag == TAG_FLOAT { - LuaValue::number((left.secondary as i64) as f64 - f64::from_bits(right.secondary)) + LuaValue::number((left.secondary as i64) as f64 + f64::from_bits(right.secondary)) } else if left_tag == TAG_FLOAT && right_tag == TAG_INTEGER { - LuaValue::number(f64::from_bits(left.secondary) - (right.secondary as i64) as f64) + LuaValue::number(f64::from_bits(left.secondary) + (right.secondary as i64) as f64) } else { return; }; @@ -100,13 +55,13 @@ fn exec_sub_slow( /// SUB: R[A] = R[B] - R[C] /// OPTIMIZED: Matches Lua C's setivalue behavior #[inline(always)] -pub fn exec_sub(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_sub(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr); + let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -122,49 +77,35 @@ pub fn exec_sub(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m return; } - exec_sub_slow(reg_base, a, left, right, pc); - } -} - -/// Slow path for MUL -#[cold] -#[inline(never)] -fn exec_mul_slow( - reg_base: *mut LuaValue, - a: usize, - left: LuaValue, - right: LuaValue, - frame_ptr: *mut LuaCallFrame, -) { - unsafe { + // Slow path: mixed or float types let left_tag = left.primary & TYPE_MASK; let right_tag = right.primary & TYPE_MASK; let result = if left_tag == TAG_FLOAT && right_tag == TAG_FLOAT { - LuaValue::number(f64::from_bits(left.secondary) * f64::from_bits(right.secondary)) + LuaValue::number(f64::from_bits(left.secondary) - f64::from_bits(right.secondary)) } else if left_tag == TAG_INTEGER && right_tag == TAG_FLOAT { - LuaValue::number((left.secondary as i64) as f64 * f64::from_bits(right.secondary)) + LuaValue::number((left.secondary as i64) as f64 - f64::from_bits(right.secondary)) } else if left_tag == TAG_FLOAT && right_tag == TAG_INTEGER { - LuaValue::number(f64::from_bits(left.secondary) * (right.secondary as i64) as f64) + LuaValue::number(f64::from_bits(left.secondary) - (right.secondary as i64) as f64) } else { return; }; *reg_base.add(a) = result; - // pc skip handled by caller + *pc += 1; } } /// MUL: R[A] = R[B] * R[C] /// OPTIMIZED: Matches Lua C's setivalue behavior #[inline(always)] -pub fn exec_mul(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_mul(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr); + let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -180,19 +121,33 @@ pub fn exec_mul(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m return; } - exec_mul_slow(reg_base, a, left, right, frame_ptr); + let left_tag = left.primary & TYPE_MASK; + let right_tag = right.primary & TYPE_MASK; + + let result = if left_tag == TAG_FLOAT && right_tag == TAG_FLOAT { + LuaValue::number(f64::from_bits(left.secondary) * f64::from_bits(right.secondary)) + } else if left_tag == TAG_INTEGER && right_tag == TAG_FLOAT { + LuaValue::number((left.secondary as i64) as f64 * f64::from_bits(right.secondary)) + } else if left_tag == TAG_FLOAT && right_tag == TAG_INTEGER { + LuaValue::number(f64::from_bits(left.secondary) * (right.secondary as i64) as f64) + } else { + return; + }; + + *reg_base.add(a) = result; + *pc += 1; } } /// DIV: R[A] = R[B] / R[C] /// Division always returns float in Lua -pub fn exec_div(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_div(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let reg_base = vm.register_stack.as_ptr().add(*base_ptr); + let reg_base = vm.register_stack.as_ptr().add(base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -215,19 +170,19 @@ pub fn exec_div(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m return; }; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l_float / r_float); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l_float / r_float); *pc += 1; } } /// IDIV: R[A] = R[B] // R[C] (floor division) -pub fn exec_idiv(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_idiv(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let reg_base = vm.register_stack.as_ptr().add(*base_ptr); + let reg_base = vm.register_stack.as_ptr().add(base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -263,19 +218,19 @@ pub fn exec_idiv(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & LuaValue::number((l_float / r_float).floor()) }; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; *pc += 1; } } /// MOD: R[A] = R[B] % R[C] -pub fn exec_mod(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_mod(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let reg_base = vm.register_stack.as_ptr().add(*base_ptr); + let reg_base = vm.register_stack.as_ptr().add(base_ptr); let left = *reg_base.add(b); let right = *reg_base.add(c); @@ -312,20 +267,20 @@ pub fn exec_mod(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m LuaValue::number(result) }; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; *pc += 1; } } /// POW: R[A] = R[B] ^ R[C] -pub fn exec_pow(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_pow(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); - let right = *vm.register_stack.as_ptr().add(*base_ptr + c); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let right = *vm.register_stack.as_ptr().add(base_ptr + c); let l_float = match left.as_number() { Some(n) => n, @@ -336,17 +291,17 @@ pub fn exec_pow(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m None => return, }; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l_float.powf(r_float)); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l_float.powf(r_float)); *pc += 1; } } /// UNM: R[A] = -R[B] (unary minus) -pub fn exec_unm(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_unm(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; - let value = vm.register_stack[*base_ptr + b]; + let value = vm.register_stack[base_ptr + b]; let result = if let Some(i) = value.as_integer() { if let Some(neg) = i.checked_neg() { @@ -365,7 +320,7 @@ pub fn exec_unm(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m let result = vm .call_metamethod(&metamethod, &[value])? .unwrap_or(LuaValue::nil()); - vm.register_stack[*base_ptr + a] = result; + vm.register_stack[base_ptr + a] = result; return Ok(()); } } @@ -376,7 +331,7 @@ pub fn exec_unm(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m ))); }; - vm.register_stack[*base_ptr + a] = result; + vm.register_stack[base_ptr + a] = result; Ok(()) } @@ -385,13 +340,13 @@ pub fn exec_unm(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m /// ADDI: R[A] = R[B] + sC /// OPTIMIZED: Minimal branches, inline integer path #[inline(always)] -pub fn exec_addi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_addi(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let sc = Instruction::get_sc(instr); unsafe { - let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr); + let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr); let left = *reg_base.add(b); if left.primary == TAG_INTEGER { @@ -416,13 +371,19 @@ pub fn exec_addi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// ADDK: R[A] = R[B] + K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_addk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_addk( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -430,7 +391,7 @@ pub fn exec_addk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Integer + Integer fast path if left.primary == TAG_INTEGER && constant.primary == TAG_INTEGER { let result = (left.secondary as i64).wrapping_add(constant.secondary as i64); - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { primary: TAG_INTEGER, secondary: result as u64, }; @@ -441,7 +402,7 @@ pub fn exec_addk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Float + Float fast path if left.primary == TAG_FLOAT && constant.primary == TAG_FLOAT { let result = f64::from_bits(left.secondary) + f64::from_bits(constant.secondary); - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { primary: TAG_FLOAT, secondary: result.to_bits(), }; @@ -451,7 +412,7 @@ pub fn exec_addk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Mixed types if let (Some(l), Some(r)) = (left.as_number(), constant.as_number()) { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l + r); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l + r); *pc += 1; } } @@ -460,13 +421,19 @@ pub fn exec_addk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// SUBK: R[A] = R[B] - K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_subk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_subk( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -474,7 +441,7 @@ pub fn exec_subk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Integer - Integer fast path if left.primary == TAG_INTEGER && constant.primary == TAG_INTEGER { let result = (left.secondary as i64).wrapping_sub(constant.secondary as i64); - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { primary: TAG_INTEGER, secondary: result as u64, }; @@ -485,7 +452,7 @@ pub fn exec_subk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Float - Float fast path if left.primary == TAG_FLOAT && constant.primary == TAG_FLOAT { let result = f64::from_bits(left.secondary) - f64::from_bits(constant.secondary); - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { primary: TAG_FLOAT, secondary: result.to_bits(), }; @@ -495,7 +462,7 @@ pub fn exec_subk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Mixed types if let (Some(l), Some(r)) = (left.as_number(), constant.as_number()) { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l - r); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l - r); *pc += 1; } } @@ -504,13 +471,19 @@ pub fn exec_subk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// MULK: R[A] = R[B] * K[C] /// OPTIMIZED: Direct field writes, minimal branching #[inline(always)] -pub fn exec_mulk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_mulk( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -518,7 +491,7 @@ pub fn exec_mulk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Integer * Integer fast path FIRST (most common in benchmarks with integer loops) if left.primary == TAG_INTEGER && constant.primary == TAG_INTEGER { let result = (left.secondary as i64).wrapping_mul(constant.secondary as i64); - let dest = vm.register_stack.as_mut_ptr().add(*base_ptr + a); + let dest = vm.register_stack.as_mut_ptr().add(base_ptr + a); (*dest).primary = TAG_INTEGER; (*dest).secondary = result as u64; *pc += 1; @@ -528,7 +501,7 @@ pub fn exec_mulk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Float * Float fast path if left.primary == TAG_FLOAT && constant.primary == TAG_FLOAT { let result = f64::from_bits(left.secondary) * f64::from_bits(constant.secondary); - let dest = vm.register_stack.as_mut_ptr().add(*base_ptr + a); + let dest = vm.register_stack.as_mut_ptr().add(base_ptr + a); (*dest).primary = TAG_FLOAT; (*dest).secondary = result.to_bits(); *pc += 1; @@ -538,14 +511,14 @@ pub fn exec_mulk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Mixed types: Integer * Float or Float * Integer if left.primary == TAG_INTEGER && constant.primary == TAG_FLOAT { let result = (left.secondary as i64) as f64 * f64::from_bits(constant.secondary); - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::float(result); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::float(result); *pc += 1; return; } if left.primary == TAG_FLOAT && constant.primary == TAG_INTEGER { let result = f64::from_bits(left.secondary) * (constant.secondary as i64) as f64; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::float(result); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::float(result); *pc += 1; } } @@ -554,13 +527,19 @@ pub fn exec_mulk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// MODK: R[A] = R[B] % K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_modk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_modk( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -572,7 +551,7 @@ pub fn exec_modk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & return; } let l = left.secondary as i64; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { primary: TAG_INTEGER, secondary: l.rem_euclid(r) as u64, }; @@ -583,7 +562,7 @@ pub fn exec_modk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Float % Float if let (Some(l), Some(r)) = (left.as_number(), constant.as_number()) { let result = l - (l / r).floor() * r; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(result); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(result); *pc += 1; } } @@ -592,13 +571,19 @@ pub fn exec_modk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// POWK: R[A] = R[B] ^ K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_powk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_powk( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -612,7 +597,7 @@ pub fn exec_powk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & None => return, }; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l_float.powf(r_float)); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l_float.powf(r_float)); *pc += 1; } } @@ -620,13 +605,19 @@ pub fn exec_powk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// DIVK: R[A] = R[B] / K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_divk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_divk( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -640,7 +631,7 @@ pub fn exec_divk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & None => return, }; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(l_float / r_float); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(l_float / r_float); *pc += 1; } } @@ -648,13 +639,19 @@ pub fn exec_divk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// IDIVK: R[A] = R[B] // K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_idivk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_idivk( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -666,7 +663,7 @@ pub fn exec_idivk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: return; } let l = left.secondary as i64; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue { + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue { primary: TAG_INTEGER, secondary: l.div_euclid(r) as u64, }; @@ -676,7 +673,7 @@ pub fn exec_idivk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: // Float // Float if let (Some(l), Some(r)) = (left.as_number(), constant.as_number()) { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number((l / r).floor()); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number((l / r).floor()); *pc += 1; } } @@ -686,17 +683,17 @@ pub fn exec_idivk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: /// BAND: R[A] = R[B] & R[C] #[inline(always)] -pub fn exec_band(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_band(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); - let right = *vm.register_stack.as_ptr().add(*base_ptr + c); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let right = *vm.register_stack.as_ptr().add(base_ptr + c); if let (Some(l), Some(r)) = (left.as_integer(), right.as_integer()) { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l & r); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l & r); *pc += 1; } } @@ -704,17 +701,17 @@ pub fn exec_band(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// BOR: R[A] = R[B] | R[C] #[inline(always)] -pub fn exec_bor(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_bor(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); - let right = *vm.register_stack.as_ptr().add(*base_ptr + c); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let right = *vm.register_stack.as_ptr().add(base_ptr + c); if let (Some(l), Some(r)) = (left.as_integer(), right.as_integer()) { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l | r); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l | r); *pc += 1; } } @@ -722,17 +719,17 @@ pub fn exec_bor(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m /// BXOR: R[A] = R[B] ~ R[C] #[inline(always)] -pub fn exec_bxor(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_bxor(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); - let right = *vm.register_stack.as_ptr().add(*base_ptr + c); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let right = *vm.register_stack.as_ptr().add(base_ptr + c); if let (Some(l), Some(r)) = (left.as_integer(), right.as_integer()) { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l ^ r); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l ^ r); *pc += 1; } } @@ -740,14 +737,14 @@ pub fn exec_bxor(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// SHL: R[A] = R[B] << R[C] #[inline(always)] -pub fn exec_shl(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_shl(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); - let right = *vm.register_stack.as_ptr().add(*base_ptr + c); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let right = *vm.register_stack.as_ptr().add(base_ptr + c); if let (Some(l), Some(r)) = (left.as_integer(), right.as_integer()) { let result = if r >= 0 { @@ -755,7 +752,7 @@ pub fn exec_shl(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m } else { LuaValue::integer(l >> ((-r) & 63)) }; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; *pc += 1; } } @@ -763,14 +760,14 @@ pub fn exec_shl(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m /// SHR: R[A] = R[B] >> R[C] #[inline(always)] -pub fn exec_shr(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_shr(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); - let right = *vm.register_stack.as_ptr().add(*base_ptr + c); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); + let right = *vm.register_stack.as_ptr().add(base_ptr + c); if let (Some(l), Some(r)) = (left.as_integer(), right.as_integer()) { let result = if r >= 0 { @@ -778,7 +775,7 @@ pub fn exec_shr(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m } else { LuaValue::integer(l << ((-r) & 63)) }; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; *pc += 1; } } @@ -787,13 +784,19 @@ pub fn exec_shr(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m /// BANDK: R[A] = R[B] & K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_bandk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_bandk( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -818,7 +821,7 @@ pub fn exec_bandk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: }); if let (Some(l), Some(r)) = (l_int, r_int) { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l & r); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l & r); *pc += 1; } } @@ -827,13 +830,19 @@ pub fn exec_bandk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: /// BORK: R[A] = R[B] | K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_bork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_bork( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -858,7 +867,7 @@ pub fn exec_bork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & }); if let (Some(l), Some(r)) = (l_int, r_int) { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l | r); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l | r); *pc += 1; } } @@ -867,13 +876,19 @@ pub fn exec_bork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// BXORK: R[A] = R[B] ~ K[C] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_bxork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_bxork( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(c); @@ -898,7 +913,7 @@ pub fn exec_bxork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: }); if let (Some(l), Some(r)) = (l_int, r_int) { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(l ^ r); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l ^ r); *pc += 1; } } @@ -906,13 +921,13 @@ pub fn exec_bxork(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: /// SHRI: R[A] = R[B] >> sC #[inline(always)] -pub fn exec_shri(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_shri(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let sc = Instruction::get_sc(instr); unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + b); + let left = *vm.register_stack.as_ptr().add(base_ptr + b); if let Some(l) = left.as_integer() { let result = if sc >= 0 { @@ -920,7 +935,7 @@ pub fn exec_shri(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & } else { LuaValue::integer(l << ((-sc) & 63)) }; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; *pc += 1; } } @@ -928,13 +943,13 @@ pub fn exec_shri(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// SHLI: R[A] = sC << R[B] #[inline(always)] -pub fn exec_shli(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_shli(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let sc = Instruction::get_sc(instr); unsafe { - let right = *vm.register_stack.as_ptr().add(*base_ptr + b); + let right = *vm.register_stack.as_ptr().add(base_ptr + b); if let Some(r) = right.as_integer() { let result = if r >= 0 { @@ -942,7 +957,7 @@ pub fn exec_shli(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & } else { LuaValue::integer((sc as i64) >> ((-r) & 63)) }; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = result; + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = result; *pc += 1; } } @@ -950,14 +965,14 @@ pub fn exec_shli(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// BNOT: R[A] = ~R[B] #[inline(always)] -pub fn exec_bnot(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_bnot(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; - let value = vm.register_stack[*base_ptr + b]; + let value = vm.register_stack[base_ptr + b]; if let Some(int_val) = value.as_integer() { - vm.register_stack[*base_ptr + a] = LuaValue::integer(!int_val); + vm.register_stack[base_ptr + a] = LuaValue::integer(!int_val); return Ok(()); } @@ -969,7 +984,7 @@ pub fn exec_bnot(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & let result = vm .call_metamethod(&metamethod, &[value])? .unwrap_or(LuaValue::nil()); - vm.register_stack[*base_ptr + a] = result; + vm.register_stack[base_ptr + a] = result; return Ok(()); } } @@ -981,29 +996,30 @@ pub fn exec_bnot(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & ))) } +#[allow(dead_code)] /// NOT: R[A] = not R[B] #[inline(always)] -pub fn exec_not(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_not(vm: &mut LuaVM, instr: u32, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; unsafe { - let value = *vm.register_stack.as_ptr().add(*base_ptr + b); + let value = *vm.register_stack.as_ptr().add(base_ptr + b); // In Lua, only nil and false are falsy use crate::lua_value::{TAG_NIL, VALUE_FALSE}; let is_falsy = value.primary == TAG_NIL || value.primary == VALUE_FALSE; - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::boolean(is_falsy); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(is_falsy); } } /// LEN: R[A] = #R[B] #[inline(always)] -pub fn exec_len(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_len(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; - let value = vm.register_stack[*base_ptr + b]; + let value = vm.register_stack[base_ptr + b]; // Check for __len metamethod first (for tables) if value.is_table() { @@ -1015,7 +1031,7 @@ pub fn exec_len(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m let result = vm .call_metamethod(&metamethod, &[value])? .unwrap_or(LuaValue::nil()); - vm.register_stack[*base_ptr + a] = result; + vm.register_stack[base_ptr + a] = result; return Ok(()); } } @@ -1040,13 +1056,19 @@ pub fn exec_len(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m }; let result = LuaValue::integer(len); - vm.register_stack[*base_ptr + a] = result; + vm.register_stack[base_ptr + a] = result; Ok(()) } /// MmBin: Metamethod binary operation (register, register) #[inline(always)] -pub fn exec_mmbin(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_mmbin( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -1062,8 +1084,8 @@ pub fn exec_mmbin(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: let prev_instr = (*frame_ptr).code_ptr.add(prev_pc - 1).read(); let dest_reg = Instruction::get_a(prev_instr) as usize; - let ra = *vm.register_stack.as_ptr().add(*base_ptr + a); - let rb = *vm.register_stack.as_ptr().add(*base_ptr + b); + let ra = *vm.register_stack.as_ptr().add(base_ptr + a); + let rb = *vm.register_stack.as_ptr().add(base_ptr + b); // Use pre-cached metamethod StringId let mm_key = LuaValue::string(vm.object_pool.get_binop_tm(c as u8)); @@ -1080,7 +1102,7 @@ pub fn exec_mmbin(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: if !metamethod.is_nil() { if let Some(result) = vm.call_metamethod(&metamethod, &[ra, rb])? { - *vm.register_stack.as_mut_ptr().add(*base_ptr + dest_reg) = result; + *vm.register_stack.as_mut_ptr().add(base_ptr + dest_reg) = result; } } // If no metamethod, leave the instruction result as-is (error will be caught elsewhere) @@ -1090,7 +1112,13 @@ pub fn exec_mmbin(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: /// MmBinI: Metamethod binary operation (register, immediate) #[inline(always)] -pub fn exec_mmbini(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_mmbini( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let c = Instruction::get_c(instr); @@ -1106,7 +1134,7 @@ pub fn exec_mmbini(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: let prev_instr = (*frame_ptr).code_ptr.add(prev_pc - 1).read(); let dest_reg = Instruction::get_a(prev_instr) as usize; - let rb = *vm.register_stack.as_ptr().add(*base_ptr + a); + let rb = *vm.register_stack.as_ptr().add(base_ptr + a); let rc = LuaValue::integer(sb as i64); // Use pre-cached metamethod StringId @@ -1122,7 +1150,7 @@ pub fn exec_mmbini(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: if !metamethod.is_nil() { let args = if k { vec![rc, rb] } else { vec![rb, rc] }; if let Some(result) = vm.call_metamethod(&metamethod, &args)? { - *vm.register_stack.as_mut_ptr().add(*base_ptr + dest_reg) = result; + *vm.register_stack.as_mut_ptr().add(base_ptr + dest_reg) = result; } } } @@ -1131,7 +1159,13 @@ pub fn exec_mmbini(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: /// MmBinK: Metamethod binary operation (register, constant) #[inline(always)] -pub fn exec_mmbink(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_mmbink( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -1147,7 +1181,7 @@ pub fn exec_mmbink(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: let prev_instr = (*frame_ptr).code_ptr.add(prev_pc - 1).read(); let dest_reg = Instruction::get_a(prev_instr) as usize; - let ra = *vm.register_stack.as_ptr().add(*base_ptr + a); + let ra = *vm.register_stack.as_ptr().add(base_ptr + a); // Get constant let kb = if let Some(func_id) = (*frame_ptr).function_value.as_function_id() { @@ -1181,7 +1215,7 @@ pub fn exec_mmbink(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: if !metamethod.is_nil() { if let Some(result) = vm.call_metamethod(&metamethod, &[left, right])? { - *vm.register_stack.as_mut_ptr().add(*base_ptr + dest_reg) = result; + *vm.register_stack.as_mut_ptr().add(base_ptr + dest_reg) = result; } } } diff --git a/crates/luars/src/lua_vm/execute/mod.rs b/crates/luars/src/lua_vm/execute/mod.rs index 887559b5..96c1ad4b 100644 --- a/crates/luars/src/lua_vm/execute/mod.rs +++ b/crates/luars/src/lua_vm/execute/mod.rs @@ -17,15 +17,17 @@ pub use table_instructions::*; pub use upvalue_instructions::*; use super::{Instruction, LuaError, LuaResult, LuaVM, OpCode}; -use crate::lua_vm::LuaCallFrame; use crate::LuaValue; use crate::lua_value::TAG_INTEGER; +use crate::lua_vm::LuaCallFrame; /// Save current pc to frame (like Lua C's savepc macro) /// Called before operations that may call Lua functions (CALL, metamethods, etc.) macro_rules! savepc { ($frame_ptr:expr, $pc:expr) => { - unsafe { (*$frame_ptr).pc = $pc; } + unsafe { + (*$frame_ptr).pc = $pc; + } }; } @@ -33,10 +35,10 @@ macro_rules! savepc { /// Used after CALL/RETURN instructions when frame changes #[inline(always)] unsafe fn updatestate( - frame_ptr: *mut LuaCallFrame, - pc: &mut usize, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, code_ptr: &mut *const u32, - base_ptr: &mut usize + base_ptr: &mut usize, ) { unsafe { *pc = (*frame_ptr).pc; @@ -63,13 +65,13 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // Initialize frame pointer - Box ensures pointer stability across Vec reallocs let mut frame_ptr = vm.current_frame_ptr(); - + // Like Lua C: cache hot variables as locals (register allocated) // This avoids dereferencing frame_ptr on each instruction let mut pc: usize; let mut code_ptr: *const u32; let mut base_ptr: usize; - + // Initial load from frame unsafe { pc = (*frame_ptr).pc; @@ -86,7 +88,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { match opcode { // ============ HOT PATH: Inline simple instructions (< 10 lines) ============ - + // MOVE - R[A] := R[B] OpCode::Move => { let a = Instruction::get_a(instr) as usize; @@ -97,27 +99,29 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } continue 'mainloop; } - + // LOADI - R[A] := sBx OpCode::LoadI => { let a = Instruction::get_a(instr) as usize; let sbx = Instruction::get_sbx(instr); unsafe { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(sbx as i64); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = + LuaValue::integer(sbx as i64); } continue 'mainloop; } - + // LOADF - R[A] := (float)sBx OpCode::LoadF => { let a = Instruction::get_a(instr) as usize; let sbx = Instruction::get_sbx(instr); unsafe { - *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(sbx as f64); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = + LuaValue::number(sbx as f64); } continue 'mainloop; } - + // LOADTRUE - R[A] := true OpCode::LoadTrue => { let a = Instruction::get_a(instr) as usize; @@ -126,7 +130,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } continue 'mainloop; } - + // LOADFALSE - R[A] := false OpCode::LoadFalse => { let a = Instruction::get_a(instr) as usize; @@ -135,7 +139,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } continue 'mainloop; } - + // LFALSESKIP - R[A] := false; pc++ OpCode::LFalseSkip => { let a = Instruction::get_a(instr) as usize; @@ -145,7 +149,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { pc += 1; continue 'mainloop; } - + // LOADNIL - R[A], ..., R[A+B] := nil OpCode::LoadNil => { let a = Instruction::get_a(instr) as usize; @@ -159,7 +163,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } continue 'mainloop; } - + // LOADK - R[A] := K[Bx] OpCode::LoadK => { let a = Instruction::get_a(instr) as usize; @@ -170,7 +174,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } continue 'mainloop; } - + // LOADKX - R[A] := K[extra arg]; pc++ OpCode::LoadKX => { let a = Instruction::get_a(instr) as usize; @@ -183,7 +187,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { } continue 'mainloop; } - + // VARARGPREP - complex, call function OpCode::VarargPrep => { exec_varargprep(vm, instr, frame_ptr, &mut base_ptr); @@ -192,111 +196,111 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Arithmetic operations ============ OpCode::Add => { - exec_add(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_add(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::Sub => { - exec_sub(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_sub(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::Mul => { - exec_mul(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_mul(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::AddI => { - exec_addi(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_addi(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::Div => { - exec_div(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_div(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::IDiv => { - exec_idiv(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_idiv(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::Mod => { - exec_mod(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_mod(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::Pow => { - exec_pow(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_pow(vm, instr, &mut pc, base_ptr); continue 'mainloop; } // Arithmetic with constants OpCode::AddK => { - exec_addk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_addk(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::SubK => { - exec_subk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_subk(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::MulK => { - exec_mulk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_mulk(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::ModK => { - exec_modk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_modk(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::PowK => { - exec_powk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_powk(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::DivK => { - exec_divk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_divk(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::IDivK => { - exec_idivk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_idivk(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } // ============ Bitwise (inline simple ones) ============ OpCode::BAnd => { - exec_band(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_band(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::BOr => { - exec_bor(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_bor(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::BXor => { - exec_bxor(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_bxor(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::Shl => { - exec_shl(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_shl(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::Shr => { - exec_shr(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_shr(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::BAndK => { - exec_bandk(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_bandk(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::BOrK => { - exec_bork(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_bork(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::BXorK => { - exec_bxork(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_bxork(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::ShrI => { - exec_shri(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_shri(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::ShlI => { - exec_shli(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_shli(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::BNot => { - if let Err(e) = exec_bnot(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_bnot(vm, instr, base_ptr) { return Err(e); } continue 'mainloop; @@ -317,21 +321,21 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Metamethod stubs (save pc before calling) ============ OpCode::MmBin => { savepc!(frame_ptr, pc); - if let Err(e) = exec_mmbin(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_mmbin(vm, instr, frame_ptr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::MmBinI => { savepc!(frame_ptr, pc); - if let Err(e) = exec_mmbini(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_mmbini(vm, instr, frame_ptr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::MmBinK => { savepc!(frame_ptr, pc); - if let Err(e) = exec_mmbink(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_mmbink(vm, instr, frame_ptr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; @@ -409,7 +413,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { unsafe { let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr + a); let step = *reg_base.add(2); - + // Integer loop (like Lua C) if step.primary == TAG_INTEGER { let count = (*reg_base.add(1)).secondary; @@ -460,33 +464,35 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { match exec_return0(vm, instr, &mut frame_ptr) { Ok(()) => { // Reload state from new frame (like Lua C) - unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } + unsafe { + updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); + } continue 'mainloop; } Err(LuaError::Exit) => return Err(LuaError::Exit), Err(e) => return Err(e), } } - OpCode::Return1 => { - match exec_return1(vm, instr, &mut frame_ptr) { - Ok(()) => { - unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } - continue 'mainloop; + OpCode::Return1 => match exec_return1(vm, instr, &mut frame_ptr) { + Ok(()) => { + unsafe { + updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } - Err(LuaError::Exit) => return Err(LuaError::Exit), - Err(e) => return Err(e), - } - } - OpCode::Return => { - match exec_return(vm, instr, &mut frame_ptr) { - Ok(()) => { - unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } - continue 'mainloop; + continue 'mainloop; + } + Err(LuaError::Exit) => return Err(LuaError::Exit), + Err(e) => return Err(e), + }, + OpCode::Return => match exec_return(vm, instr, &mut frame_ptr) { + Ok(()) => { + unsafe { + updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } - Err(LuaError::Exit) => return Err(LuaError::Exit), - Err(e) => return Err(e), + continue 'mainloop; } - } + Err(LuaError::Exit) => return Err(LuaError::Exit), + Err(e) => return Err(e), + }, // ============ Function calls (update state after frame change) ============ OpCode::Call => { @@ -496,7 +502,9 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { return Err(e); } // Reload state from new frame - unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } + unsafe { + updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); + } continue 'mainloop; } OpCode::TailCall => { @@ -504,7 +512,9 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { savepc!(frame_ptr, pc); match exec_tailcall(vm, instr, &mut frame_ptr) { Ok(()) => { - unsafe { updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); } + unsafe { + updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); + } continue 'mainloop; } Err(LuaError::Exit) => return Err(LuaError::Exit), @@ -574,13 +584,13 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Operations that can trigger metamethods ============ OpCode::Unm => { - if let Err(e) = exec_unm(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_unm(vm, instr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Len => { - if let Err(e) = exec_len(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_len(vm, instr, base_ptr) { return Err(e); } continue 'mainloop; From 80f2a795d58e060455f5c7b1c197074656777078 Mon Sep 17 00:00:00 2001 From: CppCXY <812125110@qq.com> Date: Tue, 2 Dec 2025 14:27:57 +0800 Subject: [PATCH 6/7] clean --- .../lua_vm/execute/control_instructions.rs | 107 +++++++++--------- .../src/lua_vm/execute/load_instructions.rs | 46 +++++--- .../src/lua_vm/execute/loop_instructions.rs | 55 ++++----- crates/luars/src/lua_vm/execute/mod.rs | 50 ++++---- .../src/lua_vm/execute/table_instructions.rs | 14 +-- .../lua_vm/execute/upvalue_instructions.rs | 51 ++++----- 6 files changed, 157 insertions(+), 166 deletions(-) diff --git a/crates/luars/src/lua_vm/execute/control_instructions.rs b/crates/luars/src/lua_vm/execute/control_instructions.rs index 58157f46..fb245eca 100644 --- a/crates/luars/src/lua_vm/execute/control_instructions.rs +++ b/crates/luars/src/lua_vm/execute/control_instructions.rs @@ -138,14 +138,13 @@ pub fn exec_return( /// JMP sJ /// pc += sJ +#[allow(dead_code)] #[inline(always)] -pub fn exec_jmp(instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_jmp(instr: u32, pc: &mut usize) { let sj = Instruction::get_sj(instr); - unsafe { - // PC already incremented by dispatcher, so we add offset directly - *pc = (*pc as i32 + sj) as usize; - } + // PC already incremented by dispatcher, so we add offset directly + *pc = (*pc as i32 + sj) as usize; } // ============ Test Instructions ============ @@ -153,15 +152,15 @@ pub fn exec_jmp(instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_p /// TEST A k /// if (not R[A] == k) then pc++ /// ULTRA-OPTIMIZED: Direct type tag check, single branch +#[allow(dead_code)] #[inline(always)] -pub fn exec_test(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_test(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let k = Instruction::get_k(instr); unsafe { - // OPTIMIZATION: Direct unsafe access and type tag comparison - let value = *vm.register_stack.as_ptr().add(*base_ptr + a); + let value = *vm.register_stack.as_ptr().add(base_ptr + a); // OPTIMIZATION: Fast truthiness check using type tags // nil = TAG_NIL, false = VALUE_FALSE @@ -180,15 +179,14 @@ pub fn exec_test(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// if (not R[B] == k) then R[A] := R[B] else pc++ /// ULTRA-OPTIMIZED: Direct type tag check, single branch #[inline(always)] -pub fn exec_testset(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_testset(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); unsafe { - // OPTIMIZATION: Direct unsafe access - let reg_ptr = vm.register_stack.as_ptr().add(*base_ptr); + let reg_ptr = vm.register_stack.as_ptr().add(base_ptr); let value = *reg_ptr.add(b); // OPTIMIZATION: Fast truthiness check @@ -197,7 +195,7 @@ pub fn exec_testset(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc // If (is_truthy == k), assign R[A] = R[B], otherwise skip next instruction if is_truthy == k { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = value; + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = value; } else { *pc += 1; } @@ -210,7 +208,12 @@ pub fn exec_testset(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc /// if ((R[A] == R[B]) ~= k) then pc++ /// ULTRA-OPTIMIZED: Fast path for common types (integers, floats, strings) #[inline(always)] -pub fn exec_eq(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_eq( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, +) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); @@ -277,9 +280,7 @@ pub fn exec_eq(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mu // If (left == right) != k, skip next instruction if is_equal != k { - unsafe { - *pc += 1; - } + *pc += 1; } Ok(()) @@ -289,7 +290,7 @@ pub fn exec_eq(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mu /// if ((R[A] < R[B]) ~= k) then pc++ /// ULTRA-OPTIMIZED: Direct integer fast path like Lua C #[inline(always)] -pub fn exec_lt(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_lt(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); @@ -353,7 +354,7 @@ pub fn exec_lt(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mu } // Slow path: metamethod - exec_lt_metamethod(vm, left, right, k, frame_ptr, pc) + exec_lt_metamethod(vm, left, right, k, pc) } } @@ -365,7 +366,6 @@ fn exec_lt_metamethod( left: crate::LuaValue, right: crate::LuaValue, k: bool, - frame_ptr: *mut LuaCallFrame, pc: &mut usize, ) -> LuaResult<()> { // Use pre-cached __lt StringId @@ -378,9 +378,7 @@ fn exec_lt_metamethod( if let Some(result) = vm.call_metamethod(&metamethod, &[left, right])? { let is_less_result = !result.is_nil() && result.as_bool().unwrap_or(true); if is_less_result != k { - unsafe { - *pc += 1; - } + *pc += 1; } return Ok(()); } @@ -396,9 +394,7 @@ fn exec_lt_metamethod( if let Some(result) = vm.call_metamethod(&metamethod, &[left, right])? { let is_less_result = !result.is_nil() && result.as_bool().unwrap_or(true); if is_less_result != k { - unsafe { - *pc += 1; - } + *pc += 1; } return Ok(()); } @@ -422,7 +418,12 @@ fn exec_lt_metamethod( /// if ((R[A] <= R[B]) ~= k) then pc++ /// ULTRA-OPTIMIZED: Use combined_tags for fast path like LT #[inline(always)] -pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_le( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, +) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); @@ -479,9 +480,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mu if let Some(result) = vm.call_metamethod(&metamethod, &[left, right])? { let is_le_result = !result.is_nil() && result.as_bool().unwrap_or(true); if is_le_result != k { - unsafe { - *pc += 1; - } + *pc += 1; } return Ok(()); } @@ -497,9 +496,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mu if let Some(result) = vm.call_metamethod(&metamethod, &[left, right])? { let is_le_result = !result.is_nil() && result.as_bool().unwrap_or(true); if is_le_result != k { - unsafe { - *pc += 1; - } + *pc += 1; } return Ok(()); } @@ -521,9 +518,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mu let is_gt_result = !result.is_nil() && result.as_bool().unwrap_or(true); let is_le_result = !is_gt_result; // a <= b is !(b < a) if is_le_result != k { - unsafe { - *pc += 1; - } + *pc += 1; } return Ok(()); } @@ -541,9 +536,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mu !result.is_nil() && result.as_bool().unwrap_or(true); let is_le_result = !is_gt_result; if is_le_result != k { - unsafe { - *pc += 1; - } + *pc += 1; } return Ok(()); } @@ -565,9 +558,7 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mu }; if is_less_or_equal != k { - unsafe { - *pc += 1; - } + *pc += 1; } Ok(()) @@ -576,12 +567,18 @@ pub fn exec_le(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mu /// EQK A B k /// if ((R[A] == K[B]) ~= k) then pc++ #[inline(always)] -pub fn exec_eqk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_eqk( + vm: &mut LuaVM, + instr: u32, + frame_ptr: *mut LuaCallFrame, + pc: &mut usize, + base_ptr: usize, +) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); - let (base_ptr, func_value) = unsafe { ((*frame_ptr).base_ptr, (*frame_ptr).function_value) }; + let func_value = unsafe { (*frame_ptr).function_value }; // Get function using new ID-based API let Some(func_id) = func_value.as_function_id() else { @@ -599,9 +596,7 @@ pub fn exec_eqk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m let is_equal = left == constant; if is_equal != k { - unsafe { - *pc += 1; - } + *pc += 1; } Ok(()) @@ -610,13 +605,13 @@ pub fn exec_eqk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m /// EQI A sB k /// if ((R[A] == sB) ~= k) then pc++ #[inline(always)] -pub fn exec_eqi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_eqi(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let k = Instruction::get_k(instr); unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + a); + let left = *vm.register_stack.as_ptr().add(base_ptr + a); use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; let is_equal = if (left.primary & TYPE_MASK) == TAG_INTEGER { @@ -636,13 +631,13 @@ pub fn exec_eqi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m /// LTI A sB k /// if ((R[A] < sB) ~= k) then pc++ #[inline(always)] -pub fn exec_lti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_lti(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let k = Instruction::get_k(instr); unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + a); + let left = *vm.register_stack.as_ptr().add(base_ptr + a); // OPTIMIZATION: Direct type tag comparison use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; @@ -669,13 +664,13 @@ pub fn exec_lti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m /// LEI A sB k /// if ((R[A] <= sB) ~= k) then pc++ #[inline(always)] -pub fn exec_lei(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_lei(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let k = Instruction::get_k(instr); unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + a); + let left = *vm.register_stack.as_ptr().add(base_ptr + a); use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; let is_less_equal = if (left.primary & TYPE_MASK) == TAG_INTEGER { @@ -700,13 +695,13 @@ pub fn exec_lei(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m /// GTI A sB k /// if ((R[A] > sB) ~= k) then pc++ #[inline(always)] -pub fn exec_gti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_gti(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let k = Instruction::get_k(instr); unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + a); + let left = *vm.register_stack.as_ptr().add(base_ptr + a); use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; let is_greater = if (left.primary & TYPE_MASK) == TAG_INTEGER { @@ -731,13 +726,13 @@ pub fn exec_gti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &m /// GEI A sB k /// if ((R[A] >= sB) ~= k) then pc++ #[inline(always)] -pub fn exec_gei(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_gei(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let sb = Instruction::get_sb(instr); let k = Instruction::get_k(instr); unsafe { - let left = *vm.register_stack.as_ptr().add(*base_ptr + a); + let left = *vm.register_stack.as_ptr().add(base_ptr + a); use crate::lua_value::{TAG_INTEGER, TYPE_MASK}; let is_greater_equal = if (left.primary & TYPE_MASK) == TAG_INTEGER { diff --git a/crates/luars/src/lua_vm/execute/load_instructions.rs b/crates/luars/src/lua_vm/execute/load_instructions.rs index 4bb78e2f..821b8c79 100644 --- a/crates/luars/src/lua_vm/execute/load_instructions.rs +++ b/crates/luars/src/lua_vm/execute/load_instructions.rs @@ -69,13 +69,14 @@ pub fn exec_varargprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, /// LOADNIL A B /// R[A], R[A+1], ..., R[A+B] := nil #[inline(always)] -pub fn exec_loadnil(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +#[allow(dead_code)] +pub fn exec_loadnil(vm: &mut LuaVM, instr: u32, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; unsafe { let nil_val = LuaValue::nil(); - let reg_ptr = vm.register_stack.as_mut_ptr().add(*base_ptr); + let reg_ptr = vm.register_stack.as_mut_ptr().add(base_ptr); for i in 0..=b { *reg_ptr.add(a + i) = nil_val; } @@ -85,22 +86,24 @@ pub fn exec_loadnil(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc /// LOADFALSE A /// R[A] := false #[inline(always)] -pub fn exec_loadfalse(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +#[allow(dead_code)] +pub fn exec_loadfalse(vm: &mut LuaVM, instr: u32, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; unsafe { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::boolean(false); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(false); } } /// LFALSESKIP A /// R[A] := false; pc++ #[inline(always)] -pub fn exec_lfalseskip(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +#[allow(dead_code)] +pub fn exec_lfalseskip(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; unsafe { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::boolean(false); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(false); // Skip next instruction *pc += 1; } @@ -109,35 +112,39 @@ pub fn exec_lfalseskip(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, /// LOADTRUE A /// R[A] := true #[inline(always)] -pub fn exec_loadtrue(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +#[allow(dead_code)] +pub fn exec_loadtrue(vm: &mut LuaVM, instr: u32, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; unsafe { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::boolean(true); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::boolean(true); } } /// LOADI A sBx /// R[A] := sBx (signed integer) #[inline(always)] -pub fn exec_loadi(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +#[allow(dead_code)] +#[allow(dead_code)] +pub fn exec_loadi(vm: &mut LuaVM, instr: u32, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let sbx = Instruction::get_sbx(instr); unsafe { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::integer(sbx as i64); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(sbx as i64); } } /// LOADF A sBx /// R[A] := (lua_Number)sBx #[inline(always)] -pub fn exec_loadf(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +#[allow(dead_code)] +pub fn exec_loadf(vm: &mut LuaVM, instr: u32, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let sbx = Instruction::get_sbx(instr); unsafe { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = LuaValue::number(sbx as f64); + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::number(sbx as f64); } } @@ -145,21 +152,23 @@ pub fn exec_loadf(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: /// R[A] := K[Bx] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_loadk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +#[allow(dead_code)] +pub fn exec_loadk(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; unsafe { // FAST PATH: Direct constant access via cached pointer let constant = *(*frame_ptr).constants_ptr.add(bx); - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = constant; + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = constant; } } /// LOADKX A /// R[A] := K[extra arg] #[inline(always)] -pub fn exec_loadkx(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +#[allow(dead_code)] +pub fn exec_loadkx(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; unsafe { @@ -172,7 +181,7 @@ pub fn exec_loadkx(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: if let Some(&extra_instr) = func_ref.chunk.code.get(pc_val) { let bx = Instruction::get_ax(extra_instr) as usize; if let Some(&constant) = func_ref.chunk.constants.get(bx) { - *vm.register_stack.as_mut_ptr().add(*base_ptr + a) = constant; + *vm.register_stack.as_mut_ptr().add(base_ptr + a) = constant; } } } @@ -183,12 +192,13 @@ pub fn exec_loadkx(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: /// MOVE A B /// R[A] := R[B] #[inline(always)] -pub fn exec_move(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +#[allow(dead_code)] +pub fn exec_move(vm: &mut LuaVM, instr: u32, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; unsafe { - let reg_ptr = vm.register_stack.as_mut_ptr().add(*base_ptr); + let reg_ptr = vm.register_stack.as_mut_ptr().add(base_ptr); *reg_ptr.add(a) = *reg_ptr.add(b); } } diff --git a/crates/luars/src/lua_vm/execute/loop_instructions.rs b/crates/luars/src/lua_vm/execute/loop_instructions.rs index 845a1c7c..d6db7d6d 100644 --- a/crates/luars/src/lua_vm/execute/loop_instructions.rs +++ b/crates/luars/src/lua_vm/execute/loop_instructions.rs @@ -13,12 +13,12 @@ use crate::{ /// Prepare numeric for loop: R[A]-=R[A+2]; R[A+3]=R[A]; if (skip) pc+=Bx+1 /// OPTIMIZED: Uses frame_ptr directly, no i128, unsafe register access #[inline(always)] -pub fn exec_forprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_forprep(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; unsafe { - let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr + a); + let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr + a); let init = *reg_base; let limit = *reg_base.add(1); @@ -132,12 +132,13 @@ pub fn exec_forprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc /// /// ULTRA-OPTIMIZED: Only check step type (like Lua C), use chgivalue pattern #[inline(always)] -pub fn exec_forloop(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +#[allow(dead_code)] +pub fn exec_forloop(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; unsafe { - let reg_base = vm.register_stack.as_mut_ptr().add(*base_ptr + a); + let reg_base = vm.register_stack.as_mut_ptr().add(base_ptr + a); // Only check step type - like Lua C's ttisinteger(s2v(ra + 2)) let step = *reg_base.add(2); @@ -163,18 +164,17 @@ pub fn exec_forloop(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc } // Float loop - slower path - exec_forloop_float(vm, reg_base, bx, frame_ptr, pc) + exec_forloop_float(vm, reg_base, bx, pc) } } /// Float loop - separate cold function #[cold] #[inline(never)] -fn exec_forloop_float( +pub fn exec_forloop_float( vm: &mut LuaVM, reg_base: *mut LuaValue, bx: usize, - frame_ptr: *mut LuaCallFrame, pc: &mut usize, ) -> LuaResult<()> { unsafe { @@ -231,37 +231,26 @@ fn exec_forloop_float( /// create upvalue for R[A + 3]; pc+=Bx /// In Lua 5.4, this creates a to-be-closed variable for the state #[inline(always)] -pub fn exec_tforprep(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_tforprep(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; - unsafe { - - // In Lua 5.4, R[A+3] is the to-be-closed variable for the state - // For now, we just copy the state value to ensure it's preserved - let state = vm.register_stack[*base_ptr + a + 1]; - vm.register_stack[*base_ptr + a + 3] = state; + // In Lua 5.4, R[A+3] is the to-be-closed variable for the state + // For now, we just copy the state value to ensure it's preserved + let state = vm.register_stack[base_ptr + a + 1]; + vm.register_stack[base_ptr + a + 3] = state; - // Jump to loop start - *pc += bx; - } + // Jump to loop start + *pc += bx; } /// TFORCALL A C /// R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); #[inline(always)] -pub fn exec_tforcall(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_tforcall(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let c = Instruction::get_c(instr) as usize; - let (base_ptr, _func_value, _current_pc) = unsafe { - ( - (*frame_ptr).base_ptr, - (*frame_ptr).function_value, - (*frame_ptr).pc, - ) - }; - // Get iterator function and state let func = vm.register_stack[base_ptr + a]; let state = vm.register_stack[base_ptr + a + 1]; @@ -359,17 +348,15 @@ pub fn exec_tforcall(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// TFORLOOP A Bx /// if R[A+1] ~= nil then { R[A]=R[A+1]; pc -= Bx } #[inline(always)] -pub fn exec_tforloop(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_tforloop(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let bx = Instruction::get_bx(instr) as usize; - unsafe { - let value = vm.register_stack[*base_ptr + a + 1]; + let value = vm.register_stack[base_ptr + a + 1]; - if !value.is_nil() { - // Continue loop - vm.register_stack[*base_ptr + a] = value; - *pc -= bx; - } + if !value.is_nil() { + // Continue loop + vm.register_stack[base_ptr + a] = value; + *pc -= bx; } } diff --git a/crates/luars/src/lua_vm/execute/mod.rs b/crates/luars/src/lua_vm/execute/mod.rs index 96c1ad4b..79e13303 100644 --- a/crates/luars/src/lua_vm/execute/mod.rs +++ b/crates/luars/src/lua_vm/execute/mod.rs @@ -343,35 +343,35 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Comparisons (inline simple ones) ============ OpCode::LtI => { - if let Err(e) = exec_lti(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_lti(vm, instr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::LeI => { - if let Err(e) = exec_lei(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_lei(vm, instr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GtI => { - if let Err(e) = exec_gti(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_gti(vm, instr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GeI => { - if let Err(e) = exec_gei(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_gei(vm, instr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::EqI => { - exec_eqi(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_eqi(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::EqK => { - if let Err(e) = exec_eqk(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_eqk(vm, instr, frame_ptr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; @@ -396,13 +396,13 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::TestSet => { - exec_testset(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_testset(vm, instr, &mut pc, base_ptr); continue 'mainloop; } // ============ Loop Instructions (inline FORLOOP) ============ OpCode::ForPrep => { - if let Err(e) = exec_forprep(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_forprep(vm, instr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; @@ -429,28 +429,28 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } // Float loop - if let Err(e) = exec_forloop(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_forloop_float(vm, reg_base, bx, &mut pc) { return Err(e); } } continue 'mainloop; } OpCode::TForPrep => { - exec_tforprep(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_tforprep(vm, instr, &mut pc, base_ptr); continue 'mainloop; } OpCode::TForLoop => { - exec_tforloop(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_tforloop(vm, instr, &mut pc, base_ptr); continue 'mainloop; } // ============ Upvalue operations (inline simple ones) ============ OpCode::GetUpval => { - exec_getupval(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_getupval(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::SetUpval => { - exec_setupval(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_setupval(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } @@ -524,7 +524,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Table operations ============ OpCode::NewTable => { - exec_newtable(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_newtable(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::GetTable => { @@ -540,7 +540,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::GetI => { - if let Err(e) = exec_geti(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_geti(vm, instr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; @@ -596,25 +596,25 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::Concat => { - if let Err(e) = exec_concat(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_concat(vm, instr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Eq => { - if let Err(e) = exec_eq(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_eq(vm, instr, frame_ptr, &mut pc) { return Err(e); } continue 'mainloop; } OpCode::Lt => { - if let Err(e) = exec_lt(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_lt(vm, instr, &mut pc, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Le => { - if let Err(e) = exec_le(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_le(vm, instr, frame_ptr, &mut pc) { return Err(e); } continue 'mainloop; @@ -622,7 +622,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ TForCall ============ OpCode::TForCall => { - if let Err(e) = exec_tforcall(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_tforcall(vm, instr, base_ptr) { return Err(e); } continue 'mainloop; @@ -630,27 +630,27 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Closure and special ============ OpCode::Closure => { - if let Err(e) = exec_closure(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_closure(vm, instr, frame_ptr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Vararg => { - if let Err(e) = exec_vararg(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_vararg(vm, instr, frame_ptr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetList => { - exec_setlist(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_setlist(vm, instr, frame_ptr, &mut pc, base_ptr); continue 'mainloop; } OpCode::Close => { - exec_close(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_close(vm, instr, base_ptr); continue 'mainloop; } OpCode::Tbc => { - exec_tbc(vm, instr, frame_ptr, &mut pc, &mut base_ptr); + exec_tbc(vm, instr, base_ptr); continue 'mainloop; } } diff --git a/crates/luars/src/lua_vm/execute/table_instructions.rs b/crates/luars/src/lua_vm/execute/table_instructions.rs index 76c8886c..1cfc56a7 100644 --- a/crates/luars/src/lua_vm/execute/table_instructions.rs +++ b/crates/luars/src/lua_vm/execute/table_instructions.rs @@ -11,7 +11,7 @@ use crate::lua_vm::{Instruction, LuaCallFrame, LuaResult, LuaVM}; /// k = 1 means EXTRAARG follows with array_size / 256 /// OPTIMIZED: Fast path for common empty/small table case #[inline(always)] -pub fn exec_newtable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_newtable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr); // log2(hash_size) + 1 let c = Instruction::get_c(instr); // array_size % 256 @@ -53,7 +53,7 @@ pub fn exec_newtable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p // Store in register - use unchecked for speed unsafe { - *vm.register_stack.get_unchecked_mut(*base_ptr + a) = table; + *vm.register_stack.get_unchecked_mut(base_ptr + a) = table; } // GC checkpoint disabled for testing @@ -172,12 +172,12 @@ pub fn exec_settable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// R[A] := R[B][C:integer] /// OPTIMIZED: Direct integer access using get_int_full() without creating LuaValue key #[inline(always)] -pub fn exec_geti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_geti(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as i64; // C is unsigned integer index - let table = unsafe { *vm.register_stack.get_unchecked(*base_ptr + b) }; + let table = unsafe { *vm.register_stack.get_unchecked(base_ptr + b) }; // FAST PATH: Direct integer access for tables using unchecked access if let Some(table_id) = table.as_table_id() { @@ -187,13 +187,13 @@ pub fn exec_geti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & // Use get_int_full to check both array and hash parts // This is necessary because integer keys may be stored in hash if array wasn't pre-allocated if let Some(val) = lua_table.get_int_full(c) { - unsafe { *vm.register_stack.get_unchecked_mut(*base_ptr + a) = val }; + unsafe { *vm.register_stack.get_unchecked_mut(base_ptr + a) = val }; return Ok(()); } // Key not found - check if no metatable to skip metamethod handling if lua_table.get_metatable().is_none() { - unsafe { *vm.register_stack.get_unchecked_mut(*base_ptr + a) = LuaValue::nil() }; + unsafe { *vm.register_stack.get_unchecked_mut(base_ptr + a) = LuaValue::nil() }; return Ok(()); } } @@ -203,7 +203,7 @@ pub fn exec_geti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & let value = vm .table_get_with_meta(&table, &key) .unwrap_or(LuaValue::nil()); - vm.register_stack[*base_ptr + a] = value; + vm.register_stack[base_ptr + a] = value; Ok(()) } diff --git a/crates/luars/src/lua_vm/execute/upvalue_instructions.rs b/crates/luars/src/lua_vm/execute/upvalue_instructions.rs index bc49de34..1fe31f42 100644 --- a/crates/luars/src/lua_vm/execute/upvalue_instructions.rs +++ b/crates/luars/src/lua_vm/execute/upvalue_instructions.rs @@ -9,7 +9,7 @@ use crate::{ /// GETUPVAL A B /// R[A] := UpValue[B] #[inline(always)] -pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -24,14 +24,14 @@ pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p // SAFETY: upvalue_id is from a valid function closure let value = unsafe { vm.read_upvalue_unchecked(upvalue_id) }; unsafe { - *vm.register_stack.get_unchecked_mut(*base_ptr + a) = value; + *vm.register_stack.get_unchecked_mut(base_ptr + a) = value; } } /// SETUPVAL A B /// UpValue[B] := R[A] #[inline(always)] -pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -42,7 +42,7 @@ pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p let func_ref = unsafe { vm.object_pool.get_function_unchecked(func_id) }; let upvalue_id = unsafe { *func_ref.upvalues.get_unchecked(b) }; - let value = unsafe { *vm.register_stack.get_unchecked(*base_ptr + a) }; + let value = unsafe { *vm.register_stack.get_unchecked(base_ptr + a) }; // Set upvalue value using the helper method vm.write_upvalue(upvalue_id, value); @@ -51,9 +51,9 @@ pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// CLOSE A /// close all upvalues >= R[A] #[inline(always)] -pub fn exec_close(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_close(vm: &mut LuaVM, instr: u32, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; - let close_from = *base_ptr + a; + let close_from = base_ptr + a; vm.close_upvalues_from(close_from); } @@ -62,7 +62,7 @@ pub fn exec_close(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: /// R[A] := closure(KPROTO[Bx]) /// OPTIMIZED: Fast path for closures without upvalues #[inline(always)] -pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { use crate::gc::UpvalueId; @@ -91,7 +91,7 @@ pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc if proto.upvalue_descs.is_empty() { let closure = vm.create_function(proto, Vec::new()); unsafe { - *vm.register_stack.get_unchecked_mut(*base_ptr + a) = closure; + *vm.register_stack.get_unchecked_mut(base_ptr + a) = closure; } vm.check_gc(); return Ok(()); @@ -108,7 +108,7 @@ pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc if desc.is_local { // Upvalue refers to a register in current function // Calculate absolute stack index for this upvalue - let stack_index = *base_ptr + desc.index as usize; + let stack_index = base_ptr + desc.index as usize; // Check if this upvalue is already open let existing = vm.open_upvalues.iter().find(|uv_id| { @@ -141,7 +141,7 @@ pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc let closure = vm.create_function(proto, upvalue_ids); unsafe { - *vm.register_stack.get_unchecked_mut(*base_ptr + a) = closure; + *vm.register_stack.get_unchecked_mut(base_ptr + a) = closure; } // GC checkpoint: closure now safely stored in register @@ -156,14 +156,13 @@ pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc /// Vararg arguments are stored at frame.vararg_start (set by VARARGPREP). /// This instruction copies them to the target registers. #[inline(always)] -pub fn exec_vararg(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_vararg(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let c = Instruction::get_c(instr) as usize; - let (base_ptr, vararg_start, vararg_count, top) = unsafe { + let (vararg_start, vararg_count, top) = unsafe { let frame = &*frame_ptr; ( - frame.base_ptr, frame.get_vararg_start(), frame.get_vararg_count(), frame.top, @@ -206,7 +205,7 @@ pub fn exec_vararg(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: /// R[A] := R[A].. ... ..R[A+B] /// OPTIMIZED: Pre-allocation for string/number combinations #[inline(always)] -pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_concat(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -217,7 +216,7 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: // First pass: check types and estimate capacity for i in 0..=b { - let value = vm.register_stack[*base_ptr + a + i]; + let value = vm.register_stack[base_ptr + a + i]; if let Some(str_id) = value.as_string_id() { if let Some(s) = vm.object_pool.get_string(str_id) { @@ -240,7 +239,7 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: let mut float_buffer = ryu::Buffer::new(); for i in 0..=b { - let value = vm.register_stack[*base_ptr + a + i]; + let value = vm.register_stack[base_ptr + a + i]; if let Some(str_id) = value.as_string_id() { if let Some(s) = vm.object_pool.get_string(str_id) { @@ -257,7 +256,7 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: // OPTIMIZED: Use create_string_owned to avoid extra clone let result_value = vm.create_string_owned(result); - vm.register_stack[*base_ptr + a] = result_value; + vm.register_stack[base_ptr + a] = result_value; // No GC check for fast path - rely on debt mechanism // Only large allocations trigger automatic GC @@ -265,10 +264,10 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: } // Slow path: need to handle metamethods - let mut result_value = vm.register_stack[*base_ptr + a]; + let mut result_value = vm.register_stack[base_ptr + a]; for i in 1..=b { - let next_value = vm.register_stack[*base_ptr + a + i]; + let next_value = vm.register_stack[base_ptr + a + i]; // Try direct concatenation first let left_str = if let Some(str_id) = result_value.as_string_id() { @@ -344,7 +343,7 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: } } - vm.register_stack[*base_ptr + a] = result_value; + vm.register_stack[base_ptr + a] = result_value; // No GC check - rely on debt mechanism Ok(()) @@ -353,13 +352,13 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: /// SETLIST A B C k /// R[A][C+i] := R[A+i], 1 <= i <= B #[inline(always)] -pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; let top = unsafe { (*frame_ptr).top }; - let table = vm.register_stack[*base_ptr + a]; + let table = vm.register_stack[base_ptr + a]; let start_idx = c * 50; // 0-based for array indexing let count = if b == 0 { top - a - 1 } else { b }; @@ -379,7 +378,7 @@ pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc for i in 0..count { unsafe { *t.array.get_unchecked_mut(start_idx + i) = - *vm.register_stack.get_unchecked(*base_ptr + a + 1 + i); + *vm.register_stack.get_unchecked(base_ptr + a + 1 + i); } } return; @@ -388,7 +387,7 @@ pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc // Slow path with metamethods for i in 0..count { let key = LuaValue::integer((start_idx + i + 1) as i64); - let value = vm.register_stack[*base_ptr + a + i + 1]; + let value = vm.register_stack[base_ptr + a + i + 1]; let _ = vm.table_set_with_meta(table, key, value); } } @@ -397,9 +396,9 @@ pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc /// mark variable A as to-be-closed /// This marks a variable to have its __close metamethod called when it goes out of scope #[inline(always)] -pub fn exec_tbc(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) { +pub fn exec_tbc(vm: &mut LuaVM, instr: u32, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; - let reg_idx = *base_ptr + a; + let reg_idx = base_ptr + a; // Get the value to be marked as to-be-closed let value = vm.register_stack[reg_idx]; From 3b6ab877218db822198c811f775c1b9d77226cb4 Mon Sep 17 00:00:00 2001 From: CppCXY <812125110@qq.com> Date: Tue, 2 Dec 2025 15:02:00 +0800 Subject: [PATCH 7/7] update --- .../lua_vm/execute/arithmetic_instructions.rs | 32 +++++------ .../lua_vm/execute/control_instructions.rs | 8 +-- .../src/lua_vm/execute/loop_instructions.rs | 12 +++-- crates/luars/src/lua_vm/execute/mod.rs | 53 +++++++++++-------- .../src/lua_vm/execute/table_instructions.rs | 20 +++---- .../lua_vm/execute/upvalue_instructions.rs | 10 ++-- 6 files changed, 68 insertions(+), 67 deletions(-) diff --git a/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs b/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs index 80f8224d..135e102f 100644 --- a/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs +++ b/crates/luars/src/lua_vm/execute/arithmetic_instructions.rs @@ -1061,11 +1061,12 @@ pub fn exec_len(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<()> { } /// MmBin: Metamethod binary operation (register, register) +/// OPTIMIZED: Uses passed code_ptr instead of dereferencing frame_ptr #[inline(always)] pub fn exec_mmbin( vm: &mut LuaVM, instr: u32, - frame_ptr: *mut LuaCallFrame, + code_ptr: *const u32, pc: &mut usize, base_ptr: usize, ) -> LuaResult<()> { @@ -1081,7 +1082,7 @@ pub fn exec_mmbin( } // Get previous instruction to find destination register - let prev_instr = (*frame_ptr).code_ptr.add(prev_pc - 1).read(); + let prev_instr = code_ptr.add(prev_pc - 1).read(); let dest_reg = Instruction::get_a(prev_instr) as usize; let ra = *vm.register_stack.as_ptr().add(base_ptr + a); @@ -1111,11 +1112,12 @@ pub fn exec_mmbin( } /// MmBinI: Metamethod binary operation (register, immediate) +/// OPTIMIZED: Uses passed code_ptr instead of dereferencing frame_ptr #[inline(always)] pub fn exec_mmbini( vm: &mut LuaVM, instr: u32, - frame_ptr: *mut LuaCallFrame, + code_ptr: *const u32, pc: &mut usize, base_ptr: usize, ) -> LuaResult<()> { @@ -1131,7 +1133,7 @@ pub fn exec_mmbini( return Ok(()); } - let prev_instr = (*frame_ptr).code_ptr.add(prev_pc - 1).read(); + let prev_instr = code_ptr.add(prev_pc - 1).read(); let dest_reg = Instruction::get_a(prev_instr) as usize; let rb = *vm.register_stack.as_ptr().add(base_ptr + a); @@ -1158,11 +1160,13 @@ pub fn exec_mmbini( } /// MmBinK: Metamethod binary operation (register, constant) +/// OPTIMIZED: Uses passed code_ptr and constants_ptr instead of dereferencing frame_ptr #[inline(always)] pub fn exec_mmbink( vm: &mut LuaVM, instr: u32, - frame_ptr: *mut LuaCallFrame, + code_ptr: *const u32, + constants_ptr: *const LuaValue, pc: &mut usize, base_ptr: usize, ) -> LuaResult<()> { @@ -1178,25 +1182,13 @@ pub fn exec_mmbink( return Ok(()); } - let prev_instr = (*frame_ptr).code_ptr.add(prev_pc - 1).read(); + let prev_instr = code_ptr.add(prev_pc - 1).read(); let dest_reg = Instruction::get_a(prev_instr) as usize; let ra = *vm.register_stack.as_ptr().add(base_ptr + a); - // Get constant - let kb = if let Some(func_id) = (*frame_ptr).function_value.as_function_id() { - if let Some(func_ref) = vm.object_pool.get_function(func_id) { - if let Some(&val) = func_ref.chunk.constants.get(b) { - val - } else { - return Ok(()); - } - } else { - return Ok(()); - } - } else { - return Ok(()); - }; + // Get constant via passed constants_ptr + let kb = *constants_ptr.add(b); // Use pre-cached metamethod StringId let mm_key = LuaValue::string(vm.object_pool.get_binop_tm(c as u8)); diff --git a/crates/luars/src/lua_vm/execute/control_instructions.rs b/crates/luars/src/lua_vm/execute/control_instructions.rs index fb245eca..d74fe679 100644 --- a/crates/luars/src/lua_vm/execute/control_instructions.rs +++ b/crates/luars/src/lua_vm/execute/control_instructions.rs @@ -211,15 +211,13 @@ pub fn exec_testset(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) pub fn exec_eq( vm: &mut LuaVM, instr: u32, - frame_ptr: *mut LuaCallFrame, pc: &mut usize, + base_ptr: usize, ) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); - let base_ptr = unsafe { (*frame_ptr).base_ptr }; - // OPTIMIZATION: Use unsafe for unchecked register access let (left, right) = unsafe { let reg_base = vm.register_stack.as_ptr().add(base_ptr); @@ -421,15 +419,13 @@ fn exec_lt_metamethod( pub fn exec_le( vm: &mut LuaVM, instr: u32, - frame_ptr: *mut LuaCallFrame, pc: &mut usize, + base_ptr: usize, ) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let k = Instruction::get_k(instr); - let base_ptr = unsafe { (*frame_ptr).base_ptr }; - // OPTIMIZATION: Use unsafe for unchecked register access let (left, right) = unsafe { let reg_base = vm.register_stack.as_ptr().add(base_ptr); diff --git a/crates/luars/src/lua_vm/execute/loop_instructions.rs b/crates/luars/src/lua_vm/execute/loop_instructions.rs index d6db7d6d..82da7d81 100644 --- a/crates/luars/src/lua_vm/execute/loop_instructions.rs +++ b/crates/luars/src/lua_vm/execute/loop_instructions.rs @@ -246,8 +246,9 @@ pub fn exec_tforprep(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize /// TFORCALL A C /// R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); +/// Returns true if a Lua function was called and frame changed (needs updatestate) #[inline(always)] -pub fn exec_tforcall(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<()> { +pub fn exec_tforcall(vm: &mut LuaVM, instr: u32, frame_ptr: &mut *mut LuaCallFrame, base_ptr: usize) -> LuaResult { let a = Instruction::get_a(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -288,6 +289,7 @@ pub fn exec_tforcall(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<( for i in values.len()..=c { vm.register_stack[base_ptr + a + 3 + i] = LuaValue::nil(); } + Ok(false) // No frame change for C functions } LuaValueKind::Function => { // For Lua functions, we need to use CALL instruction logic @@ -335,14 +337,14 @@ pub fn exec_tforcall(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<( ); vm.push_frame(new_frame); - // Execution will continue in the new frame + // Update frame_ptr to point to new frame + *frame_ptr = vm.current_frame_ptr(); + Ok(true) // Frame changed, need updatestate } _ => { - return Err(vm.error("attempt to call a non-function value in for loop".to_string())); + Err(vm.error("attempt to call a non-function value in for loop".to_string())) } } - - Ok(()) } /// TFORLOOP A Bx diff --git a/crates/luars/src/lua_vm/execute/mod.rs b/crates/luars/src/lua_vm/execute/mod.rs index 79e13303..fd3bcdd6 100644 --- a/crates/luars/src/lua_vm/execute/mod.rs +++ b/crates/luars/src/lua_vm/execute/mod.rs @@ -321,21 +321,22 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Metamethod stubs (save pc before calling) ============ OpCode::MmBin => { savepc!(frame_ptr, pc); - if let Err(e) = exec_mmbin(vm, instr, frame_ptr, &mut pc, base_ptr) { + if let Err(e) = exec_mmbin(vm, instr, code_ptr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::MmBinI => { savepc!(frame_ptr, pc); - if let Err(e) = exec_mmbini(vm, instr, frame_ptr, &mut pc, base_ptr) { + if let Err(e) = exec_mmbini(vm, instr, code_ptr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::MmBinK => { savepc!(frame_ptr, pc); - if let Err(e) = exec_mmbink(vm, instr, frame_ptr, &mut pc, base_ptr) { + let constants_ptr = unsafe { (*frame_ptr).constants_ptr }; + if let Err(e) = exec_mmbink(vm, instr, code_ptr, constants_ptr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; @@ -446,11 +447,11 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ Upvalue operations (inline simple ones) ============ OpCode::GetUpval => { - exec_getupval(vm, instr, frame_ptr, &mut pc, base_ptr); + exec_getupval(vm, instr, frame_ptr, base_ptr); continue 'mainloop; } OpCode::SetUpval => { - exec_setupval(vm, instr, frame_ptr, &mut pc, base_ptr); + exec_setupval(vm, instr, frame_ptr, base_ptr); continue 'mainloop; } @@ -528,55 +529,55 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::GetTable => { - if let Err(e) = exec_gettable(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_gettable(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetTable => { - if let Err(e) = exec_settable(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_settable(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetI => { - if let Err(e) = exec_geti(vm, instr, &mut pc, base_ptr) { + if let Err(e) = exec_geti(vm, instr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetI => { - if let Err(e) = exec_seti(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_seti(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetField => { - if let Err(e) = exec_getfield(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_getfield(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetField => { - if let Err(e) = exec_setfield(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_setfield(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::GetTabUp => { - if let Err(e) = exec_gettabup(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_gettabup(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetTabUp => { - if let Err(e) = exec_settabup(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_settabup(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Self_ => { - if let Err(e) = exec_self(vm, instr, frame_ptr, &mut pc, &mut base_ptr) { + if let Err(e) = exec_self(vm, instr, frame_ptr, &mut base_ptr) { return Err(e); } continue 'mainloop; @@ -602,7 +603,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::Eq => { - if let Err(e) = exec_eq(vm, instr, frame_ptr, &mut pc) { + if let Err(e) = exec_eq(vm, instr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; @@ -614,7 +615,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { continue 'mainloop; } OpCode::Le => { - if let Err(e) = exec_le(vm, instr, frame_ptr, &mut pc) { + if let Err(e) = exec_le(vm, instr, &mut pc, base_ptr) { return Err(e); } continue 'mainloop; @@ -622,27 +623,37 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult { // ============ TForCall ============ OpCode::TForCall => { - if let Err(e) = exec_tforcall(vm, instr, base_ptr) { - return Err(e); + savepc!(frame_ptr, pc); + match exec_tforcall(vm, instr, &mut frame_ptr, base_ptr) { + Ok(true) => { + // Lua function called, need to update state + unsafe { + updatestate(frame_ptr, &mut pc, &mut code_ptr, &mut base_ptr); + } + } + Ok(false) => { + // C function called, no state change needed + } + Err(e) => return Err(e), } continue 'mainloop; } // ============ Closure and special ============ OpCode::Closure => { - if let Err(e) = exec_closure(vm, instr, frame_ptr, &mut pc, base_ptr) { + if let Err(e) = exec_closure(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::Vararg => { - if let Err(e) = exec_vararg(vm, instr, frame_ptr, &mut pc, base_ptr) { + if let Err(e) = exec_vararg(vm, instr, frame_ptr, base_ptr) { return Err(e); } continue 'mainloop; } OpCode::SetList => { - exec_setlist(vm, instr, frame_ptr, &mut pc, base_ptr); + exec_setlist(vm, instr, frame_ptr, base_ptr); continue 'mainloop; } OpCode::Close => { diff --git a/crates/luars/src/lua_vm/execute/table_instructions.rs b/crates/luars/src/lua_vm/execute/table_instructions.rs index 1cfc56a7..68146eb1 100644 --- a/crates/luars/src/lua_vm/execute/table_instructions.rs +++ b/crates/luars/src/lua_vm/execute/table_instructions.rs @@ -63,7 +63,7 @@ pub fn exec_newtable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// R[A] := R[B][R[C]] /// OPTIMIZED: Fast path for integer keys and tables without metatable #[inline(always)] -pub fn exec_gettable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_gettable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -119,7 +119,7 @@ pub fn exec_gettable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// R[A][R[B]] := RK(C) /// OPTIMIZED: Fast path for integer keys and tables without metatable #[inline(always)] -pub fn exec_settable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_settable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -172,7 +172,7 @@ pub fn exec_settable(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// R[A] := R[B][C:integer] /// OPTIMIZED: Direct integer access using get_int_full() without creating LuaValue key #[inline(always)] -pub fn exec_geti(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { +pub fn exec_geti(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as i64; // C is unsigned integer index @@ -208,11 +208,11 @@ pub fn exec_geti(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) -> Ok(()) } -/// SETI A B C k +/// SETI A B C /// R[A][B] := RK(C) /// OPTIMIZED: Direct integer key access using set_int() #[inline(always)] -pub fn exec_seti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_seti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as i64; // B is unsigned integer key let c = Instruction::get_c(instr) as usize; @@ -260,7 +260,7 @@ pub fn exec_seti(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: & /// GETFIELD A B C /// R[A] := R[B][K[C]:string] #[inline(always)] -pub fn exec_getfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_getfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -314,7 +314,7 @@ pub fn exec_getfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// SETFIELD A B C k /// R[A][K[B]:string] := RK(C) #[inline(always)] -pub fn exec_setfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_setfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -374,7 +374,7 @@ pub fn exec_setfield(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// R[A] := UpValue[B][K[C]:string] /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_gettabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_gettabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -432,7 +432,7 @@ pub fn exec_gettabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// UpValue[A][K[B]:string] := RK(C) /// OPTIMIZED: Uses cached constants_ptr for direct constant access #[inline(always)] -pub fn exec_settabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_settabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -488,7 +488,7 @@ pub fn exec_settabup(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// SELF A B C /// R[A+1] := R[B]; R[A] := R[B][RK(C):string] #[inline(always)] -pub fn exec_self(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: &mut usize) -> LuaResult<()> { +pub fn exec_self(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: &mut usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize; diff --git a/crates/luars/src/lua_vm/execute/upvalue_instructions.rs b/crates/luars/src/lua_vm/execute/upvalue_instructions.rs index 1fe31f42..9c90d95f 100644 --- a/crates/luars/src/lua_vm/execute/upvalue_instructions.rs +++ b/crates/luars/src/lua_vm/execute/upvalue_instructions.rs @@ -9,7 +9,7 @@ use crate::{ /// GETUPVAL A B /// R[A] := UpValue[B] #[inline(always)] -pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) { +pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -31,7 +31,7 @@ pub fn exec_getupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, p /// SETUPVAL A B /// UpValue[B] := R[A] #[inline(always)] -pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) { +pub fn exec_setupval(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; @@ -62,7 +62,7 @@ pub fn exec_close(vm: &mut LuaVM, instr: u32, base_ptr: usize) { /// R[A] := closure(KPROTO[Bx]) /// OPTIMIZED: Fast path for closures without upvalues #[inline(always)] -pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { +pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: usize) -> LuaResult<()> { use crate::gc::UpvalueId; @@ -156,7 +156,7 @@ pub fn exec_closure(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc /// Vararg arguments are stored at frame.vararg_start (set by VARARGPREP). /// This instruction copies them to the target registers. #[inline(always)] -pub fn exec_vararg(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) -> LuaResult<()> { +pub fn exec_vararg(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: usize) -> LuaResult<()> { let a = Instruction::get_a(instr) as usize; let c = Instruction::get_c(instr) as usize; @@ -352,7 +352,7 @@ pub fn exec_concat(vm: &mut LuaVM, instr: u32, base_ptr: usize) -> LuaResult<()> /// SETLIST A B C k /// R[A][C+i] := R[A+i], 1 <= i <= B #[inline(always)] -pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, pc: &mut usize, base_ptr: usize) { +pub fn exec_setlist(vm: &mut LuaVM, instr: u32, frame_ptr: *mut LuaCallFrame, base_ptr: usize) { let a = Instruction::get_a(instr) as usize; let b = Instruction::get_b(instr) as usize; let c = Instruction::get_c(instr) as usize;