// local_zeroinit_test preserves the retired C wrappers' dirty-frame runtime // seam. Each @test child // dirties a callee frame and immediately calls a sibling probe whose bare local // is its first slot. Keeping the calls in one @test matters: the native runner // forks once per test, so separate dirty and probe tests could receive clean // pages and mask a missing zero-fill. package local_zeroinit_test; type tiny3 = struct { a: u8, b: u8, c: u8 }; // Preserve the two original poison frames. Besides their distinct byte values, // the 512-byte int frame exercises the larger array cases while the 64-byte u8 // frame is the historical sub-8 aggregate reproducer. fn dirty_int_frame() int = { let j: [64]int; for (let i: int = 0; i < 64; i += 1) { j[i] = 165; }; return j[0]; }; fn dirty_byte_frame() void = { let big: [64]u8; let i: i32 = 0; for (i < 64) { big[i] = 222u8; i += 1; }; }; fn probe_int3() i32 = { let a: [3]int; return (a[0] + a[1] + a[2]): i32; }; fn probe_u32x4() i32 = { let a: [4]u32; return (a[0] + a[1] + a[2] + a[3]): i32; }; fn probe_u8x20_int_frame() i32 = { let b: [20]u8; let s: i32 = 0; for (let i: int = 0; i < 20; i += 1) { s += b[i]: i32; }; return s; }; fn probe_int2x2() i32 = { let m: [2][2]int; return (m[0][0] + m[0][1] + m[1][0] + m[1][1]): i32; }; fn probe_initialized_int3() i32 = { let c: [3]int = [7, 8, 9]; return (c[0] + c[1] + c[2]): i32; }; @test fn array_int3_zero() void = { dirty_int_frame(); assert(probe_int3() == 0); }; @test fn array_u32x4_zero() void = { dirty_int_frame(); assert(probe_u32x4() == 0); }; @test fn array_u8x20_zero() void = { dirty_int_frame(); assert(probe_u8x20_int_frame() == 0); }; @test fn nested_array_int2x2_zero() void = { dirty_int_frame(); assert(probe_int2x2() == 0); }; @test fn initialized_array_control() void = { dirty_int_frame(); assert(probe_initialized_int3() == 24); }; fn probe_u8x3() i32 = { let c: [3]u8; return (c[0]: i32) + (c[1]: i32) + (c[2]: i32); }; fn probe_u8x5() i32 = { let c: [5]u8; let acc: i32 = 0; let j: i32 = 0; for (j < 5) { acc += c[j]: i32; j += 1; }; return acc; }; fn probe_u8x7() i32 = { let c: [7]u8; let acc: i32 = 0; let j: i32 = 0; for (j < 7) { acc += c[j]: i32; j += 1; }; return acc; }; fn probe_tiny3() i32 = { let s: tiny3; return (s.a: i32) + (s.b: i32) + (s.c: i32); }; fn probe_scalar_i32() i32 = { let x: i32; return x; }; fn probe_u8x20_byte_frame() i32 = { let c: [20]u8; let acc: i32 = 0; let j: i32 = 0; for (j < 20) { acc += c[j]: i32; j += 1; }; return acc; }; fn probe_str_len() i32 = { let empty: str; return empty.len; }; fn probe_slice_len() i32 = { let xs: []i32; return xs.len; }; @test fn sub8_array_u8x3_zero() void = { dirty_byte_frame(); assert(probe_u8x3() == 0); }; @test fn sub8_array_u8x5_zero() void = { dirty_byte_frame(); assert(probe_u8x5() == 0); }; @test fn sub8_array_u8x7_zero() void = { dirty_byte_frame(); assert(probe_u8x7() == 0); }; @test fn sub8_struct_u8x3_zero() void = { dirty_byte_frame(); assert(probe_tiny3() == 0); }; @test fn scalar_i32_control() void = { dirty_byte_frame(); assert(probe_scalar_i32() == 0); }; @test fn array_u8x20_control() void = { dirty_byte_frame(); assert(probe_u8x20_byte_frame() == 0); }; @test fn str_header_control() void = { dirty_byte_frame(); assert(probe_str_len() == 0); }; @test fn slice_header_control() void = { dirty_byte_frame(); assert(probe_slice_len() == 0); };