#![cfg(feature = "jit")]
use fusevm::{ChunkBuilder, JitCompiler, Op};
#[test]
fn block_jit_sum_loop() {
let mut b = ChunkBuilder::new();
b.emit(Op::PushFrame, 1);
b.emit(Op::LoadInt(0), 1);
b.emit(Op::SetSlot(0), 1); b.emit(Op::LoadInt(0), 1);
b.emit(Op::SetSlot(1), 1); b.emit(Op::GetSlot(0), 1);
b.emit(Op::GetSlot(1), 1);
b.emit(Op::Add, 1);
b.emit(Op::SetSlot(0), 1); b.emit(Op::PreIncSlotVoid(1), 1); b.emit(Op::SlotLtIntJumpIfFalse(1, 100, 12), 1);
b.emit(Op::Jump(5), 1);
b.emit(Op::GetSlot(0), 1);
let chunk = b.build();
let jit = JitCompiler::new();
assert!(jit.is_block_eligible(&chunk));
let mut slots = vec![0i64; 4];
let result = jit.try_run_block(&chunk, &mut slots).unwrap();
assert_eq!(result, 4950);
}
#[test]
fn block_jit_accum_sum_loop() {
let mut b = ChunkBuilder::new();
b.emit(Op::PushFrame, 1);
b.emit(Op::LoadInt(0), 1);
b.emit(Op::SetSlot(0), 1);
b.emit(Op::LoadInt(0), 1);
b.emit(Op::SetSlot(1), 1);
b.emit(Op::AccumSumLoop(0, 1, 1000), 1);
b.emit(Op::GetSlot(0), 1);
let chunk = b.build();
let jit = JitCompiler::new();
assert!(jit.is_block_eligible(&chunk));
let mut slots = vec![0i64; 4];
let result = jit.try_run_block(&chunk, &mut slots).unwrap();
assert_eq!(result, 499500);
}
#[test]
fn block_jit_conditional() {
let mut b = ChunkBuilder::new();
b.emit(Op::PushFrame, 1);
b.emit(Op::LoadInt(1), 1); b.emit(Op::JumpIfFalse(6), 1); b.emit(Op::LoadInt(42), 1);
b.emit(Op::SetSlot(0), 1);
b.emit(Op::Jump(8), 1); b.emit(Op::LoadInt(99), 1);
b.emit(Op::SetSlot(0), 1);
b.emit(Op::GetSlot(0), 1);
let chunk = b.build();
let jit = JitCompiler::new();
assert!(jit.is_block_eligible(&chunk));
let mut slots = vec![0i64; 4];
let result = jit.try_run_block(&chunk, &mut slots).unwrap();
assert_eq!(result, 42);
}
#[test]
fn block_jit_conditional_false() {
let mut b = ChunkBuilder::new();
b.emit(Op::PushFrame, 1);
b.emit(Op::LoadInt(0), 1); b.emit(Op::JumpIfFalse(6), 1);
b.emit(Op::LoadInt(42), 1);
b.emit(Op::SetSlot(0), 1);
b.emit(Op::Jump(8), 1);
b.emit(Op::LoadInt(99), 1);
b.emit(Op::SetSlot(0), 1);
b.emit(Op::GetSlot(0), 1);
let chunk = b.build();
let jit = JitCompiler::new();
let mut slots = vec![0i64; 4];
let result = jit.try_run_block(&chunk, &mut slots).unwrap();
assert_eq!(result, 99);
}
#[test]
fn block_jit_fused_backedge() {
let mut b = ChunkBuilder::new();
b.emit(Op::PushFrame, 1);
b.emit(Op::LoadInt(0), 1);
b.emit(Op::SetSlot(0), 1); b.emit(Op::LoadInt(0), 1);
b.emit(Op::SetSlot(1), 1); b.emit(Op::AddAssignSlotVoid(0, 1), 1); b.emit(Op::SlotIncLtIntJumpBack(1, 50, 5), 1); b.emit(Op::GetSlot(0), 1);
let chunk = b.build();
let jit = JitCompiler::new();
assert!(jit.is_block_eligible(&chunk));
let mut slots = vec![0i64; 4];
let result = jit.try_run_block(&chunk, &mut slots).unwrap();
assert_eq!(result, 1225);
}
#[test]
fn block_jit_ineligible_with_print() {
let mut b = ChunkBuilder::new();
b.emit(Op::LoadInt(42), 1);
b.emit(Op::Print(1), 1); let chunk = b.build();
let jit = JitCompiler::new();
assert!(!jit.is_block_eligible(&chunk));
}
#[test]
fn block_jit_slots_written_back() {
let mut b = ChunkBuilder::new();
b.emit(Op::PushFrame, 1);
b.emit(Op::LoadInt(0), 1);
b.emit(Op::SetSlot(0), 1);
b.emit(Op::LoadInt(0), 1);
b.emit(Op::SetSlot(1), 1);
b.emit(Op::AccumSumLoop(0, 1, 10), 1);
b.emit(Op::GetSlot(0), 1);
let chunk = b.build();
let jit = JitCompiler::new();
let mut slots = vec![0i64; 4];
let _ = jit.try_run_block(&chunk, &mut slots);
assert_eq!(slots[0], 45); assert_eq!(slots[1], 10); }