use aegis_vm::execute;
use aegis_vm::build_config::opcodes::{stack, arithmetic, control, exec};
#[test]
fn test_vm_add_through_execute() {
let code = vec![
stack::PUSH_IMM8, 10,
stack::PUSH_IMM8, 20,
arithmetic::ADD,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 30);
}
#[test]
fn test_vm_sub_through_execute() {
let code = vec![
stack::PUSH_IMM8, 50,
stack::PUSH_IMM8, 20,
arithmetic::SUB,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 30);
}
#[test]
fn test_vm_mul_through_execute() {
let code = vec![
stack::PUSH_IMM8, 6,
stack::PUSH_IMM8, 7,
arithmetic::MUL,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 42);
}
#[test]
fn test_vm_xor_through_execute() {
let code = vec![
stack::PUSH_IMM8, 0b1100,
stack::PUSH_IMM8, 0b1010,
arithmetic::XOR,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 0b0110);
}
#[test]
fn test_vm_and_through_execute() {
let code = vec![
stack::PUSH_IMM8, 0b1100,
stack::PUSH_IMM8, 0b1010,
arithmetic::AND,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 0b1000);
}
#[test]
fn test_vm_or_through_execute() {
let code = vec![
stack::PUSH_IMM8, 0b1100,
stack::PUSH_IMM8, 0b1010,
arithmetic::OR,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 0b1110);
}
#[test]
fn test_vm_not_through_execute() {
let code = vec![
stack::PUSH_IMM8, 0,
arithmetic::NOT,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), u64::MAX);
}
#[test]
fn test_vm_inc_through_execute() {
let code = vec![
stack::PUSH_IMM8, 41,
arithmetic::INC,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 42);
}
#[test]
fn test_vm_dec_through_execute() {
let code = vec![
stack::PUSH_IMM8, 43,
arithmetic::DEC,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 42);
}
#[test]
fn test_vm_complex_arithmetic_expression() {
let code = vec![
stack::PUSH_IMM8, 10,
stack::PUSH_IMM8, 5,
arithmetic::ADD, stack::PUSH_IMM8, 3,
arithmetic::MUL, stack::PUSH_IMM8, 15,
arithmetic::SUB, exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 30);
}
#[test]
fn test_vm_bitwise_chain() {
let code = vec![
stack::PUSH_IMM8, 0xFF,
stack::PUSH_IMM8, 0x0F,
arithmetic::AND, stack::PUSH_IMM8, 0x05,
arithmetic::XOR, exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 0x0A);
}
#[test]
fn test_vm_inc_dec_chain() {
let code = vec![
stack::PUSH_IMM8, 10,
arithmetic::INC,
arithmetic::INC,
arithmetic::DEC,
arithmetic::INC,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 12);
}
#[test]
fn test_vm_not_double_inversion() {
let code = vec![
stack::PUSH_IMM8, 42,
arithmetic::NOT,
arithmetic::NOT,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 42);
}
#[test]
fn test_vm_add_overflow() {
let code = vec![
stack::PUSH_IMM,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, stack::PUSH_IMM8, 1,
arithmetic::ADD,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 0);
}
#[test]
fn test_vm_sub_underflow() {
let code = vec![
stack::PUSH_IMM8, 0,
stack::PUSH_IMM8, 1,
arithmetic::SUB,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), u64::MAX);
}
#[test]
fn test_vm_xor_self_zero() {
let code = vec![
stack::PUSH_IMM8, 123,
stack::DUP,
arithmetic::XOR,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 0);
}
#[test]
fn test_vm_and_with_zero() {
let code = vec![
stack::PUSH_IMM8, 255,
stack::PUSH_IMM8, 0,
arithmetic::AND,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 0);
}
#[test]
fn test_vm_or_with_zero() {
let code = vec![
stack::PUSH_IMM8, 42,
stack::PUSH_IMM8, 0,
arithmetic::OR,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 42);
}
#[test]
fn test_vm_sum_loop_with_mutated_add() {
let code = vec![
stack::PUSH_IMM8, 1,
stack::POP_REG, 0, stack::PUSH_IMM8, 0,
stack::POP_REG, 1,
stack::PUSH_REG, 1, stack::PUSH_REG, 0, arithmetic::ADD, stack::POP_REG, 1,
stack::PUSH_REG, 0,
arithmetic::INC, stack::POP_REG, 0,
stack::PUSH_REG, 0,
stack::PUSH_IMM8, 6,
control::CMP,
control::JLT,
(-20i16 as u16) as u8, ((-20i16 as u16) >> 8) as u8,
stack::PUSH_REG, 1,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 15);
}
#[test]
fn test_vm_factorial_with_mutated_mul() {
let code = vec![
stack::PUSH_IMM8, 5,
stack::POP_REG, 0, stack::PUSH_IMM8, 1,
stack::POP_REG, 1,
stack::PUSH_REG, 1, stack::PUSH_REG, 0, arithmetic::MUL, stack::POP_REG, 1,
stack::PUSH_REG, 0,
arithmetic::DEC, stack::POP_REG, 0,
stack::PUSH_REG, 0,
stack::PUSH_IMM8, 0,
control::CMP,
control::JGT,
(-20i16 as u16) as u8, ((-20i16 as u16) >> 8) as u8,
stack::PUSH_REG, 1,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 120);
}
#[test]
fn test_vm_fibonacci_with_mutated_handlers() {
let code = vec![
stack::PUSH_IMM8, 10,
stack::POP_REG, 0,
stack::PUSH_IMM8, 1,
stack::POP_REG, 1,
stack::PUSH_IMM8, 0,
stack::POP_REG, 2,
stack::PUSH_IMM8, 2,
stack::POP_REG, 3,
stack::PUSH_REG, 1,
stack::PUSH_REG, 2,
arithmetic::ADD,
stack::PUSH_REG, 1,
stack::POP_REG, 2,
stack::POP_REG, 1,
stack::PUSH_REG, 3,
arithmetic::INC, stack::POP_REG, 3,
stack::PUSH_REG, 3,
stack::PUSH_REG, 0,
control::CMP,
control::JLE,
(-24i16 as u16) as u8, ((-24i16 as u16) >> 8) as u8,
stack::PUSH_REG, 1,
exec::HALT,
];
assert_eq!(execute(&code, &[]).unwrap(), 55);
}