use aegis_vm_macro::vm_protect;
#[vm_protect(level = "debug")]
fn while_empty_body_never_runs(n: u64) -> u64 {
while n > 1000 {}
42
}
#[vm_protect(level = "debug")]
fn while_empty_body_runs_once() -> u64 {
let mut x = 1u64;
while x > 0 {
x = 0;
}
100
}
#[vm_protect(level = "debug")]
fn for_empty_body() -> u64 {
for _i in 0..5 {
}
200
}
#[vm_protect(level = "debug")]
fn loop_immediate_break_empty() -> u64 {
loop {
break;
}
300
}
#[vm_protect(level = "debug")]
fn while_only_let_stmt() -> u64 {
let mut count = 0u64;
let mut i = 0u64;
while i < 3 {
let _temp = i * 2; count += 1;
i += 1;
}
count
}
#[vm_protect(level = "debug")]
fn for_only_assignment() -> u64 {
let mut sum = 0u64;
for i in 0..5 {
sum += i; }
sum
}
#[vm_protect(level = "debug")]
fn nested_while_empty_inner() -> u64 {
let mut outer = 0u64;
let mut i = 0u64;
while i < 3 {
let mut j = 0u64;
while j < 2 {
j += 1;
}
outer += 1;
i += 1;
}
outer
}
#[vm_protect(level = "debug")]
fn nested_for_empty_both() -> u64 {
let mut count = 0u64;
for _i in 0..3 {
for _j in 0..2 {
}
count += 1;
}
count
}
#[vm_protect(level = "debug")]
fn break_first_thing() -> u64 {
let mut x = 0u64;
loop {
break;
#[allow(unreachable_code)]
{
x = 999; }
}
x
}
#[vm_protect(level = "debug")]
fn continue_skip_all() -> u64 {
let mut sum = 0u64;
let mut i = 0u64;
while i < 5 {
i += 1;
continue; #[allow(unreachable_code)]
{
sum += 100; }
}
sum
}
#[vm_protect(level = "debug")]
fn multiple_breaks(n: u64) -> u64 {
let mut i = 0u64;
loop {
if i >= n {
break;
}
if i >= 100 {
break;
}
i += 1;
}
i
}
#[vm_protect(level = "debug")]
fn early_return_nested() -> u64 {
for i in 0..10 {
for j in 0..10 {
if i * j == 15 {
return i * 100 + j; }
}
}
0
}
#[vm_protect(level = "debug")]
fn while_with_return(limit: u64) -> u64 {
let mut i = 0u64;
while i < 1000 {
if i >= limit {
return i;
}
i += 1;
}
i
}
#[test]
fn test_while_empty_body_never_runs() {
assert_eq!(while_empty_body_never_runs(0), 42);
assert_eq!(while_empty_body_never_runs(500), 42);
}
#[test]
fn test_while_empty_body_runs_once() {
assert_eq!(while_empty_body_runs_once(), 100);
}
#[test]
fn test_for_empty_body() {
assert_eq!(for_empty_body(), 200);
}
#[test]
fn test_loop_immediate_break_empty() {
assert_eq!(loop_immediate_break_empty(), 300);
}
#[test]
fn test_while_only_let_stmt() {
assert_eq!(while_only_let_stmt(), 3);
}
#[test]
fn test_for_only_assignment() {
assert_eq!(for_only_assignment(), 10);
}
#[test]
fn test_nested_while_empty_inner() {
assert_eq!(nested_while_empty_inner(), 3);
}
#[test]
fn test_nested_for_empty_both() {
assert_eq!(nested_for_empty_both(), 3);
}
#[test]
fn test_break_first_thing() {
assert_eq!(break_first_thing(), 0);
}
#[test]
fn test_continue_skip_all() {
assert_eq!(continue_skip_all(), 0);
}
#[test]
fn test_multiple_breaks() {
assert_eq!(multiple_breaks(5), 5);
assert_eq!(multiple_breaks(50), 50);
assert_eq!(multiple_breaks(200), 100); }
#[test]
fn test_early_return_nested() {
assert_eq!(early_return_nested(), 305);
}
#[test]
fn test_while_with_return() {
assert_eq!(while_with_return(5), 5);
assert_eq!(while_with_return(100), 100);
}
#[vm_protect(level = "debug")]
fn break_with_struct_cleanup() -> u64 {
struct Data { x: u64, y: u64 }
let mut result = 0;
for i in 0..10 {
let d = Data { x: i, y: i * 2 }; result = result + d.x;
if i == 5 {
break; }
}
result }
#[vm_protect(level = "debug")]
fn break_with_tuple_cleanup() -> u64 {
let mut sum = 0;
for i in 0..10 {
let t = (i, i + 1, i + 2); sum = sum + t.0 + t.1 + t.2;
if i == 3 {
break; }
}
sum }
#[vm_protect(level = "debug")]
fn continue_with_struct_cleanup() -> u64 {
struct Point { x: u64, y: u64 }
let mut sum = 0;
for i in 0..5 {
if i % 2 == 0 {
let p = Point { x: i, y: i }; sum = sum + p.x;
continue; }
sum = sum + 100; }
sum }
#[vm_protect(level = "debug")]
fn return_with_deep_cleanup() -> u64 {
struct Outer { a: u64 }
struct Inner { b: u64 }
let outer = Outer { a: 10 };
for i in 0..5 {
let inner = Inner { b: i };
if inner.b == 3 {
return outer.a + inner.b; }
}
outer.a }
#[vm_protect(level = "debug")]
fn nested_break_cleanup() -> u64 {
struct Counter { val: u64 }
let mut total = 0;
for i in 0..3 {
let outer_c = Counter { val: i * 100 };
for j in 0..5 {
let inner_c = Counter { val: j };
total = total + inner_c.val;
if j == 2 {
break; }
}
total = total + outer_c.val; }
total
}
#[vm_protect(level = "debug")]
fn nested_continue_cleanup() -> u64 {
struct Val { n: u64 }
let mut sum = 0;
for i in 0..3 {
let outer_v = Val { n: i };
for j in 0..4 {
if j % 2 == 1 {
continue; }
let inner_v = Val { n: j * 10 };
sum = sum + inner_v.n;
}
sum = sum + outer_v.n;
}
sum
}
#[test]
fn test_break_with_struct_cleanup() {
assert_eq!(break_with_struct_cleanup(), 15);
}
#[test]
fn test_break_with_tuple_cleanup() {
assert_eq!(break_with_tuple_cleanup(), 30);
}
#[test]
fn test_continue_with_struct_cleanup() {
assert_eq!(continue_with_struct_cleanup(), 206);
}
#[test]
fn test_return_with_deep_cleanup() {
assert_eq!(return_with_deep_cleanup(), 13);
}
#[test]
fn test_nested_break_cleanup() {
assert_eq!(nested_break_cleanup(), 309);
}
#[test]
fn test_nested_continue_cleanup() {
assert_eq!(nested_continue_cleanup(), 63);
}