Skip to content

Commit 8908876

Browse files
committed
clean code
1 parent 121ce9e commit 8908876

File tree

1 file changed

+2
-345
lines changed

1 file changed

+2
-345
lines changed

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

Lines changed: 2 additions & 345 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
/// Control flow instructions
22
///
3-
/// These instructions handle function calls, returns, jumps, and coroutine operations.
3+
/// These instructions handle function calls, returns, and comparisons.
44
use crate::lua_value::LuaValueKind;
55
use crate::lua_vm::{LuaCallFrame, LuaError, LuaResult, LuaVM};
66
use crate::{FunctionId, LuaValue};
7-
use crate::{get_a, get_b, get_c, get_k, get_sb, get_sj};
7+
use crate::{get_a, get_b, get_c, get_k, get_sb};
88

99
/// RETURN A B C k
1010
/// return R[A], ... ,R[A+B-2]
@@ -135,47 +135,8 @@ pub fn exec_return(
135135
}
136136
}
137137

138-
// ============ Jump Instructions ============
139-
140-
/// JMP sJ
141-
/// pc += sJ
142-
#[allow(dead_code)]
143-
#[inline(always)]
144-
pub fn exec_jmp(instr: u32, pc: &mut usize) {
145-
let sj = get_sj!(instr);
146-
147-
// PC already incremented by dispatcher, so we add offset directly
148-
*pc = (*pc as i32 + sj) as usize;
149-
}
150-
151138
// ============ Test Instructions ============
152139

153-
/// TEST A k
154-
/// if (not R[A] == k) then pc++
155-
/// ULTRA-OPTIMIZED: Direct type tag check, single branch
156-
#[allow(dead_code)]
157-
#[inline(always)]
158-
pub fn exec_test(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) {
159-
let a = get_a!(instr);
160-
let k = get_k!(instr);
161-
162-
unsafe {
163-
// OPTIMIZATION: Direct unsafe access and type tag comparison
164-
let value = *vm.register_stack.as_ptr().add(base_ptr + a);
165-
166-
// OPTIMIZATION: Fast truthiness check using type tags
167-
// nil = TAG_NIL, false = VALUE_FALSE
168-
// Only nil and false are falsy
169-
use crate::lua_value::{TAG_NIL, VALUE_FALSE};
170-
let is_truthy = value.primary != TAG_NIL && value.primary != VALUE_FALSE;
171-
172-
// If (not value) == k, skip next instruction
173-
if !is_truthy == k {
174-
*pc += 1;
175-
}
176-
}
177-
}
178-
179140
/// TESTSET A B k
180141
/// if (not R[B] == k) then R[A] := R[B] else pc++
181142
/// ULTRA-OPTIMIZED: Direct type tag check, single branch
@@ -1230,193 +1191,6 @@ fn exec_call_lua_vararg(
12301191
Ok(())
12311192
}
12321193

1233-
/// Slow path for Lua function calls with metamethod
1234-
/// OPTIMIZED: Minimize branches and memory operations for common case
1235-
#[inline(always)]
1236-
fn exec_call_lua_function(
1237-
vm: &mut LuaVM,
1238-
func: LuaValue,
1239-
a: usize,
1240-
b: usize,
1241-
c: usize,
1242-
caller_base: usize,
1243-
use_call_metamethod: bool,
1244-
call_metamethod_self: LuaValue,
1245-
frame_ptr_ptr: &mut *mut LuaCallFrame, // Use passed frame_ptr!
1246-
) -> LuaResult<()> {
1247-
// Get function ID - FAST PATH: assume valid function
1248-
let func_id = unsafe { func.as_function_id().unwrap_unchecked() };
1249-
1250-
// Extract chunk info from ObjectPool - use unchecked for hot path
1251-
let func_ref = unsafe { vm.object_pool.get_function_unchecked(func_id) };
1252-
let chunk = func_ref.lua_chunk();
1253-
1254-
let (max_stack_size, num_params, is_vararg, code_ptr, constants_ptr, upvalues_ptr) = (
1255-
chunk.max_stack_size,
1256-
chunk.param_count,
1257-
chunk.is_vararg,
1258-
chunk.code.as_ptr(),
1259-
chunk.constants.as_ptr(),
1260-
func_ref.upvalues.as_ptr(),
1261-
);
1262-
1263-
// Calculate argument count - use frame_ptr directly!
1264-
let arg_count = if b == 0 {
1265-
unsafe { (**frame_ptr_ptr).top.saturating_sub((a + 1) as u32) as usize }
1266-
} else {
1267-
unsafe {
1268-
(**frame_ptr_ptr).top = (a + b) as u32;
1269-
}
1270-
b - 1
1271-
};
1272-
1273-
let return_count = if c == 0 { usize::MAX } else { c - 1 };
1274-
1275-
// Zero-copy: new frame base = R[A+1]
1276-
let new_base = caller_base + a + 1;
1277-
1278-
// Check if this call would overwrite parent frame's vararg
1279-
// If the parent frame has vararg at vararg_start..vararg_start+vararg_count,
1280-
// and new_base + max_stack_size > vararg_start, we need to relocate vararg
1281-
let parent_frame = unsafe { &mut **frame_ptr_ptr };
1282-
let parent_vararg_start = parent_frame.get_vararg_start();
1283-
let parent_vararg_count = parent_frame.get_vararg_count();
1284-
1285-
if parent_vararg_count > 0 {
1286-
let new_frame_end = new_base + max_stack_size;
1287-
if new_frame_end > parent_vararg_start {
1288-
// Vararg would be overwritten! Relocate it to after new frame's stack
1289-
let new_vararg_start = new_frame_end;
1290-
let required_capacity = new_vararg_start + parent_vararg_count;
1291-
vm.ensure_stack_capacity(required_capacity);
1292-
if vm.register_stack.len() < required_capacity {
1293-
vm.register_stack.resize(required_capacity, LuaValue::nil());
1294-
}
1295-
1296-
// Copy vararg values to new location (copy forward, no overlap issue since new > old)
1297-
for i in 0..parent_vararg_count {
1298-
vm.register_stack[new_vararg_start + i] =
1299-
vm.register_stack[parent_vararg_start + i];
1300-
}
1301-
1302-
// Update parent frame's vararg position
1303-
// Need to get mutable reference again after potential reallocation
1304-
let parent_frame = unsafe { &mut **frame_ptr_ptr };
1305-
parent_frame.set_vararg(new_vararg_start, parent_vararg_count);
1306-
}
1307-
}
1308-
1309-
// FAST PATH: No metamethod, no vararg (most common case)
1310-
if !use_call_metamethod && !is_vararg {
1311-
// Simple case: just ensure capacity and push frame
1312-
let required_capacity = new_base + max_stack_size;
1313-
1314-
// Ensure capacity - single branch
1315-
if vm.register_stack.len() < required_capacity {
1316-
vm.register_stack.resize(required_capacity, LuaValue::nil());
1317-
}
1318-
1319-
// LIKE LUA C: Only fill missing arguments (arg_count < num_params)
1320-
// NOT all stack slots! This is the key optimization.
1321-
// For add(a,b) called with add(1,5): arg_count=2, num_params=2 → no fill!
1322-
if arg_count < num_params {
1323-
unsafe {
1324-
let reg_ptr = vm.register_stack.as_mut_ptr().add(new_base);
1325-
let nil_val = LuaValue::nil();
1326-
for i in arg_count..num_params {
1327-
*reg_ptr.add(i) = nil_val;
1328-
}
1329-
}
1330-
}
1331-
1332-
// Create and push new frame - inline nresults calculation
1333-
let nresults = if c == 0 { -1i16 } else { (c - 1) as i16 };
1334-
let new_frame = LuaCallFrame::new_lua_function(
1335-
func_id,
1336-
code_ptr,
1337-
constants_ptr,
1338-
upvalues_ptr,
1339-
new_base,
1340-
arg_count, // top = number of arguments
1341-
a, // result_reg
1342-
nresults,
1343-
max_stack_size,
1344-
);
1345-
1346-
*frame_ptr_ptr = vm.push_frame(new_frame);
1347-
return Ok(());
1348-
}
1349-
1350-
// SLOW PATH: Handle metamethod or vararg
1351-
let actual_arg_count = if use_call_metamethod {
1352-
arg_count + 1
1353-
} else {
1354-
arg_count
1355-
};
1356-
let actual_stack_size = max_stack_size.max(actual_arg_count);
1357-
let total_stack_size = if is_vararg && actual_arg_count > 0 {
1358-
actual_stack_size + actual_arg_count
1359-
} else {
1360-
actual_stack_size
1361-
};
1362-
1363-
// Ensure stack capacity
1364-
let required_capacity = new_base + total_stack_size;
1365-
if vm.register_stack.len() < required_capacity {
1366-
vm.ensure_stack_capacity(required_capacity);
1367-
vm.register_stack.resize(required_capacity, LuaValue::nil());
1368-
}
1369-
1370-
// Initialize registers
1371-
unsafe {
1372-
let reg_ptr = vm.register_stack.as_mut_ptr();
1373-
let nil_val = LuaValue::nil();
1374-
1375-
// Initialize local variable slots beyond arguments
1376-
for i in actual_arg_count..actual_stack_size {
1377-
*reg_ptr.add(new_base + i) = nil_val;
1378-
}
1379-
1380-
// Vararg extra space
1381-
if is_vararg && actual_arg_count > 0 {
1382-
for i in actual_stack_size..total_stack_size {
1383-
*reg_ptr.add(new_base + i) = nil_val;
1384-
}
1385-
}
1386-
1387-
// __call metamethod: shift arguments and insert self
1388-
if use_call_metamethod && arg_count > 0 {
1389-
for i in (0..arg_count).rev() {
1390-
*reg_ptr.add(new_base + 1 + i) = *reg_ptr.add(new_base + i);
1391-
}
1392-
*reg_ptr.add(new_base) = call_metamethod_self;
1393-
} else if use_call_metamethod {
1394-
*reg_ptr.add(new_base) = call_metamethod_self;
1395-
}
1396-
}
1397-
1398-
// Create and push new frame
1399-
let nresults = if return_count == usize::MAX {
1400-
-1i16
1401-
} else {
1402-
return_count as i16
1403-
};
1404-
let new_frame = LuaCallFrame::new_lua_function(
1405-
func_id,
1406-
code_ptr,
1407-
constants_ptr,
1408-
upvalues_ptr,
1409-
new_base,
1410-
actual_arg_count, // top = number of arguments
1411-
a, // result_reg
1412-
nresults,
1413-
max_stack_size,
1414-
);
1415-
1416-
*frame_ptr_ptr = vm.push_frame(new_frame);
1417-
Ok(())
1418-
}
1419-
14201194
/// Execute a C closure call (native function with upvalues)
14211195
#[inline(always)]
14221196
fn exec_call_c_closure(
@@ -2109,120 +1883,3 @@ pub fn exec_tailcall(
21091883
_ => Err(vm.error(format!("attempt to call a {} value", func.type_name()))),
21101884
}
21111885
}
2112-
2113-
/// RETURN0
2114-
/// return (no values)
2115-
/// ULTRA-OPTIMIZED: Minimal work for the common case (Lua->Lua call with no upvalues)
2116-
/// NOTE: Currently inlined in main loop for performance, but kept for potential future use
2117-
#[inline(always)]
2118-
#[allow(dead_code)]
2119-
pub fn exec_return0(
2120-
vm: &mut LuaVM,
2121-
_instr: u32,
2122-
frame_ptr_ptr: &mut *mut LuaCallFrame,
2123-
) -> LuaResult<()> {
2124-
// Like Lua C: check if we have a Lua caller (most common case)
2125-
if vm.frame_count > 1 {
2126-
// FAST PATH: Calculate caller frame pointer BEFORE pop
2127-
let caller_ptr = unsafe { vm.frames.as_mut_ptr().add(vm.frame_count - 2) };
2128-
2129-
// Pop frame - just decrement counter (like Lua C: L->ci = ci->previous)
2130-
vm.frame_count -= 1;
2131-
2132-
// Check if caller is Lua function
2133-
if unsafe { (*caller_ptr).is_lua() } {
2134-
// Get info we need
2135-
let (result_reg, num_results) = unsafe {
2136-
(
2137-
(**frame_ptr_ptr).get_result_reg(),
2138-
(**frame_ptr_ptr).get_num_results(),
2139-
)
2140-
};
2141-
2142-
// Update frame_ptr to caller
2143-
*frame_ptr_ptr = caller_ptr;
2144-
2145-
// Only fill nil if caller expects results
2146-
// Like Lua C: for (nres = ci->nresults; l_unlikely(nres > 0); nres--)
2147-
if num_results > 0 && num_results != usize::MAX {
2148-
let caller_base = unsafe { (*caller_ptr).base_ptr } as usize;
2149-
let dest_base = caller_base + result_reg;
2150-
unsafe {
2151-
let reg_ptr = vm.register_stack.as_mut_ptr();
2152-
let nil_val = LuaValue::nil();
2153-
for i in 0..num_results {
2154-
*reg_ptr.add(dest_base + i) = nil_val;
2155-
}
2156-
}
2157-
}
2158-
2159-
return Ok(());
2160-
} else {
2161-
// C function caller
2162-
*frame_ptr_ptr = caller_ptr;
2163-
vm.return_values.clear();
2164-
return Err(LuaError::Exit);
2165-
}
2166-
}
2167-
2168-
// No caller - exit VM
2169-
vm.frame_count -= 1;
2170-
vm.return_values.clear();
2171-
Err(LuaError::Exit)
2172-
}
2173-
2174-
/// RETURN1 A
2175-
/// return R[A]
2176-
/// ULTRA-OPTIMIZED: Minimal work for single-value return (most common case)
2177-
/// NOTE: Currently inlined in main loop for performance, but kept for potential future use
2178-
#[inline(always)]
2179-
#[allow(dead_code)]
2180-
pub fn exec_return1(
2181-
vm: &mut LuaVM,
2182-
instr: u32,
2183-
frame_ptr_ptr: &mut *mut LuaCallFrame,
2184-
) -> LuaResult<()> {
2185-
let a = get_a!(instr);
2186-
2187-
// Get base_ptr and return value FIRST
2188-
let base_ptr = unsafe { (**frame_ptr_ptr).base_ptr } as usize;
2189-
let return_value = unsafe { *vm.register_stack.get_unchecked(base_ptr + a) };
2190-
2191-
// Like Lua C: check if we have a Lua caller (most common case)
2192-
if vm.frame_count > 1 {
2193-
// FAST PATH: Calculate caller frame pointer BEFORE pop
2194-
let caller_ptr = unsafe { vm.frames.as_mut_ptr().add(vm.frame_count - 2) };
2195-
2196-
// Pop frame - just decrement counter
2197-
vm.frame_count -= 1;
2198-
2199-
// Check if caller is Lua function
2200-
if unsafe { (*caller_ptr).is_lua() } {
2201-
let result_reg = unsafe { (**frame_ptr_ptr).get_result_reg() };
2202-
2203-
// Update frame_ptr to caller
2204-
*frame_ptr_ptr = caller_ptr;
2205-
2206-
// Write return value directly to caller's register
2207-
let caller_base = unsafe { (*caller_ptr).base_ptr } as usize;
2208-
unsafe {
2209-
*vm.register_stack
2210-
.get_unchecked_mut(caller_base + result_reg) = return_value;
2211-
}
2212-
2213-
return Ok(());
2214-
} else {
2215-
// C function caller
2216-
*frame_ptr_ptr = caller_ptr;
2217-
vm.return_values.clear();
2218-
vm.return_values.push(return_value);
2219-
return Err(LuaError::Exit);
2220-
}
2221-
}
2222-
2223-
// No caller - exit VM
2224-
vm.frame_count -= 1;
2225-
vm.return_values.clear();
2226-
vm.return_values.push(return_value);
2227-
Err(LuaError::Exit)
2228-
}

0 commit comments

Comments
 (0)