// slice_global_arg_runonly_test — #148 (D2): a module-global slice passed BY // VALUE as a slice arg must arrive with a real header, not garbage. Migrated // from test/wcc/953_globalslice_arg_run.c. // // _runonly: CSTAGE-ONLY. wwstage's checker rejects a module-level `const []T` // global ("let: not assignable", filed task #28), so this file does not compile // under w6c_ww and is excluded from the T2 byte-id corpus. test-lang runs it // through the cstage `ww test` only. // // Pre-fix the slice-ident call-arg fast path emitted BP-relative pushes for a // global (localfind→0), reading saved-BP/RIP garbage instead of the global's // header at name(SB). The fix mirrors the N_SLICE arm's isglobal dispatch. The // callee reads .len AND a byte, so a wrong header is observable; u32_global // pins the path is element-width-agnostic; direct_read + local_arg lock the // in-place read and the off!=0 local arm against regression. package slice_global_arg_runonly_test; const dotdot: []u8 = ['.', '.']; const dot: []u8 = ['.']; const g: []u32 = [7u32, 8u32, 9u32]; const d: []u32 = [11u32, 22u32]; fn seen_u8(bs: []u8) i32 = { return bs.len: i32 * 1000 + bs[0]: i32; }; fn seen_u32(xs: []u32) i32 = { return xs.len: i32 * 100 + xs[0]: i32 + xs[2]: i32; }; @test fn u8_dotdot() void = { assert(seen_u8(dotdot) == 2046); }; @test fn u8_dot() void = { assert(seen_u8(dot) == 1046); }; @test fn u32_global() void = { assert(seen_u32(g) == 316); }; @test fn direct_read() void = { assert(d.len: i32 * 100 + d[0]: i32 + d[1]: i32 == 233); }; @test fn u8_local_arg() void = { let a: [2]u8 = ['.', '.']; let s: []u8 = a[0:2]; assert(seen_u8(s) == 2046); };