Skip to content

Commit a5e5087

Browse files
committed
update
1 parent 3b6d1fe commit a5e5087

File tree

3 files changed

+160
-192
lines changed

3 files changed

+160
-192
lines changed

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

Lines changed: 59 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ pub fn exec_shr(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) {
925925
}
926926

927927
/// BANDK: R[A] = R[B] & K[C]
928-
/// OPTIMIZED: Uses cached constants_ptr for direct constant access
928+
/// OPTIMIZED: Fast path for integer-integer
929929
#[inline(always)]
930930
pub fn exec_bandk(
931931
vm: &mut LuaVM,
@@ -940,38 +940,24 @@ pub fn exec_bandk(
940940

941941
unsafe {
942942
let left = *vm.register_stack.as_ptr().add(base_ptr + b);
943-
944-
// FAST PATH: Direct constant access via cached pointer
945943
let constant = *(*frame_ptr).constants_ptr.add(c);
946944

947-
let l_int = left.as_integer().or_else(|| {
948-
left.as_number().and_then(|f| {
949-
if f.fract() == 0.0 && f >= i64::MIN as f64 && f <= i64::MAX as f64 {
950-
Some(f as i64)
951-
} else {
952-
None
953-
}
954-
})
955-
});
956-
let r_int = constant.as_integer().or_else(|| {
957-
constant.as_number().and_then(|f| {
958-
if f.fract() == 0.0 && f >= i64::MIN as f64 && f <= i64::MAX as f64 {
959-
Some(f as i64)
960-
} else {
961-
None
962-
}
963-
})
964-
});
965-
966-
if let (Some(l), Some(r)) = (l_int, r_int) {
945+
// Fast path: both are integers (common case)
946+
if let (Some(l), Some(r)) = (left.as_integer_strict(), constant.as_integer_strict()) {
947+
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l & r);
948+
*pc += 1;
949+
return;
950+
}
951+
// Slow path: try float conversion
952+
if let (Some(l), Some(r)) = (left.as_integer(), constant.as_integer()) {
967953
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l & r);
968954
*pc += 1;
969955
}
970956
}
971957
}
972958

973959
/// BORK: R[A] = R[B] | K[C]
974-
/// OPTIMIZED: Uses cached constants_ptr for direct constant access
960+
/// OPTIMIZED: Fast path for integer-integer
975961
#[inline(always)]
976962
pub fn exec_bork(
977963
vm: &mut LuaVM,
@@ -986,38 +972,24 @@ pub fn exec_bork(
986972

987973
unsafe {
988974
let left = *vm.register_stack.as_ptr().add(base_ptr + b);
989-
990-
// FAST PATH: Direct constant access via cached pointer
991975
let constant = *(*frame_ptr).constants_ptr.add(c);
992976

993-
let l_int = left.as_integer().or_else(|| {
994-
left.as_number().and_then(|f| {
995-
if f.fract() == 0.0 && f >= i64::MIN as f64 && f <= i64::MAX as f64 {
996-
Some(f as i64)
997-
} else {
998-
None
999-
}
1000-
})
1001-
});
1002-
let r_int = constant.as_integer().or_else(|| {
1003-
constant.as_number().and_then(|f| {
1004-
if f.fract() == 0.0 && f >= i64::MIN as f64 && f <= i64::MAX as f64 {
1005-
Some(f as i64)
1006-
} else {
1007-
None
1008-
}
1009-
})
1010-
});
1011-
1012-
if let (Some(l), Some(r)) = (l_int, r_int) {
977+
// Fast path: both are integers
978+
if let (Some(l), Some(r)) = (left.as_integer_strict(), constant.as_integer_strict()) {
979+
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l | r);
980+
*pc += 1;
981+
return;
982+
}
983+
// Slow path
984+
if let (Some(l), Some(r)) = (left.as_integer(), constant.as_integer()) {
1013985
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l | r);
1014986
*pc += 1;
1015987
}
1016988
}
1017989
}
1018990

1019991
/// BXORK: R[A] = R[B] ~ K[C]
1020-
/// OPTIMIZED: Uses cached constants_ptr for direct constant access
992+
/// OPTIMIZED: Fast path for integer-integer
1021993
#[inline(always)]
1022994
pub fn exec_bxork(
1023995
vm: &mut LuaVM,
@@ -1032,37 +1004,24 @@ pub fn exec_bxork(
10321004

10331005
unsafe {
10341006
let left = *vm.register_stack.as_ptr().add(base_ptr + b);
1035-
1036-
// FAST PATH: Direct constant access via cached pointer
10371007
let constant = *(*frame_ptr).constants_ptr.add(c);
10381008

1039-
let l_int = left.as_integer().or_else(|| {
1040-
left.as_number().and_then(|f| {
1041-
if f.fract() == 0.0 && f >= i64::MIN as f64 && f <= i64::MAX as f64 {
1042-
Some(f as i64)
1043-
} else {
1044-
None
1045-
}
1046-
})
1047-
});
1048-
let r_int = constant.as_integer().or_else(|| {
1049-
constant.as_number().and_then(|f| {
1050-
if f.fract() == 0.0 && f >= i64::MIN as f64 && f <= i64::MAX as f64 {
1051-
Some(f as i64)
1052-
} else {
1053-
None
1054-
}
1055-
})
1056-
});
1057-
1058-
if let (Some(l), Some(r)) = (l_int, r_int) {
1009+
// Fast path: both are integers
1010+
if let (Some(l), Some(r)) = (left.as_integer_strict(), constant.as_integer_strict()) {
1011+
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l ^ r);
1012+
*pc += 1;
1013+
return;
1014+
}
1015+
// Slow path
1016+
if let (Some(l), Some(r)) = (left.as_integer(), constant.as_integer()) {
10591017
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(l ^ r);
10601018
*pc += 1;
10611019
}
10621020
}
10631021
}
10641022

10651023
/// SHRI: R[A] = R[B] >> sC
1024+
/// OPTIMIZED: Fast path + wrapping operations
10661025
#[inline(always)]
10671026
pub fn exec_shri(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) {
10681027
let a = get_a!(instr);
@@ -1072,19 +1031,32 @@ pub fn exec_shri(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) {
10721031
unsafe {
10731032
let left = *vm.register_stack.as_ptr().add(base_ptr + b);
10741033

1034+
// Fast path
1035+
if let Some(l) = left.as_integer_strict() {
1036+
let result = if sc >= 0 {
1037+
(l as u64).wrapping_shr((sc & 63) as u32) as i64
1038+
} else {
1039+
l.wrapping_shl(((-sc) & 63) as u32)
1040+
};
1041+
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(result);
1042+
*pc += 1;
1043+
return;
1044+
}
1045+
// Slow path
10751046
if let Some(l) = left.as_integer() {
10761047
let result = if sc >= 0 {
1077-
LuaValue::integer(l >> (sc & 63))
1048+
(l as u64).wrapping_shr((sc & 63) as u32) as i64
10781049
} else {
1079-
LuaValue::integer(l << ((-sc) & 63))
1050+
l.wrapping_shl(((-sc) & 63) as u32)
10801051
};
1081-
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = result;
1052+
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(result);
10821053
*pc += 1;
10831054
}
10841055
}
10851056
}
10861057

10871058
/// SHLI: R[A] = sC << R[B]
1059+
/// OPTIMIZED: Fast path + wrapping operations
10881060
#[inline(always)]
10891061
pub fn exec_shli(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) {
10901062
let a = get_a!(instr);
@@ -1094,13 +1066,25 @@ pub fn exec_shli(vm: &mut LuaVM, instr: u32, pc: &mut usize, base_ptr: usize) {
10941066
unsafe {
10951067
let right = *vm.register_stack.as_ptr().add(base_ptr + b);
10961068

1069+
// Fast path
1070+
if let Some(r) = right.as_integer_strict() {
1071+
let result = if r >= 0 {
1072+
(sc as i64).wrapping_shl((r & 63) as u32)
1073+
} else {
1074+
((sc as i64) as u64).wrapping_shr(((-r) & 63) as u32) as i64
1075+
};
1076+
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(result);
1077+
*pc += 1;
1078+
return;
1079+
}
1080+
// Slow path
10971081
if let Some(r) = right.as_integer() {
10981082
let result = if r >= 0 {
1099-
LuaValue::integer((sc as i64) << (r & 63))
1083+
(sc as i64).wrapping_shl((r & 63) as u32)
11001084
} else {
1101-
LuaValue::integer((sc as i64) >> ((-r) & 63))
1085+
((sc as i64) as u64).wrapping_shr(((-r) & 63) as u32) as i64
11021086
};
1103-
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = result;
1087+
*vm.register_stack.as_mut_ptr().add(base_ptr + a) = LuaValue::integer(result);
11041088
*pc += 1;
11051089
}
11061090
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub use upvalue_instructions::*;
1919
use super::{LuaError, LuaResult, LuaVM, OpCode};
2020
use crate::lua_value::{TAG_FALSE, TAG_FLOAT, TAG_INTEGER, TAG_NIL, TAG_TRUE, TYPE_MASK};
2121
use crate::lua_vm::LuaCallFrame;
22-
use crate::{LuaValue, get_a, get_ax, get_b, get_bx, get_k, get_op, get_sbx, get_sj};
22+
use crate::{LuaValue, get_a, get_ax, get_b, get_bx, get_c, get_k, get_op, get_sbx, get_sc, get_sj};
2323

2424
/// Save current pc to frame (like Lua C's savepc macro)
2525
/// Called before operations that may call Lua functions (CALL, metamethods, etc.)
@@ -262,7 +262,7 @@ pub fn luavm_execute(vm: &mut LuaVM) -> LuaResult<LuaValue> {
262262
continue 'mainloop;
263263
}
264264

265-
// ============ Bitwise (inline simple ones) ============
265+
// ============ Bitwise operations ============
266266
OpCode::BAnd => {
267267
exec_band(vm, instr, &mut pc, base_ptr);
268268
continue 'mainloop;

0 commit comments

Comments
 (0)