test: migrate str/slice global family-1 batch to test/lang @test, retire C twins (fold-2)
Continue fold-2 (after 374e97b): migrate the remaining Family-1 str/slice
global + literal + index + call-arg group from bespoke build+run C twins to
test/lang @test, retiring each twin in the same commit. Runtime coverage MOVES
from $(TESTS) to test-lang (T1 runs+asserts via `ww test`) + test-lang-byteid
(T2 keeps cs==ww .s byte-id); coverage is preserved, the $(TESTS) headline
drops 9 (434->425). All asserts are primitive int/u8/bool comparisons (no
fmt/strconv in the assert path); the slice-store/index rows reset the global
each fn and sum ADJACENT elements so a dropped/mis-strided/over-wide word FAILS.
989_globslicefield_run.c -> glob_slice_field_test.ww (slice field of a global struct: g.f=<slice> stores full 24B header; len/cap/non-zero-offset + str/scalar controls)
989_globstrslice_run.c -> glob_str_slice_arg_test.ww (global str sliced with default hi passed as call arg loads its len word; explicit-hi control)
989_trystr_run.c -> try_str_unwrap_test.ww (`!` unwrap of str-success tagged union shuffles the str header for ident-source/error-first/success-first)
797_len_strglobal_run.c -> len_str_global_test.ww (len(str-global) loads .len via name(SB); local-str control)
801_litstr_pseudo_run.c -> lit_str_pseudo_test.ww (string-literal .len/.ptr pseudo-field; empty/multibyte + arg-passthrough)
803_globalidx_run.c -> global_index_test.ww (global str/slice index read/addr-of/store/compound, esz 1/4; local regression pins)
903_tuple_elem_slice_len.c -> tuple_elem_slice_len_test.ww (len(t.N) of a slice/str tuple element loads .len at +8; 2/3-slice, str-slice both orders)
927_composite_call_arg_run.c-> composite_call_arg_test.ww (slice-returning CALL passed inline as a composite arg; canonical/letslice/two-call/middle/nested/scalar/tagged)
952_slicecopy_assign_run.c -> slice_copy_assign_test.ww (bulk slice-copy-assign `arr[lo:hi]=bs`, esz 1/4, field/via-ptr/local bases; reslice-read companion)
rd_reslice asserts the TRUE value 360 (the .c twin's want=104 was 360 & 0xFF,
an exit-code truncation). 723_composite_call_arg.c's comment repointed to the
new test/lang location. 802_lenidx_run.c is DEFERRED (it carries //ww:error
reject rows — needs a value-rows-only split + a slim reject carrier, a fold-3
pass). Bump LANGBYTEID_EXPECTED_MIN 22->31 to ratchet the new corpus floor.
This commit is contained in:
122
test/lang/composite_call_arg_test.ww
Normal file
122
test/lang/composite_call_arg_test.ww
Normal file
@@ -0,0 +1,122 @@
|
||||
// composite_call_arg_test — a 3-reg composite (`[]u8` slice) CALL result passed
|
||||
// inline as a composite arg to another call, migrated from
|
||||
// test/wcc/927_composite_call_arg_run.c (#24, Class A wwstage cgen miscompile).
|
||||
// Pre-fix wwstage emitted a single `PUSHQ AX` for a slice-returning CALL arg
|
||||
// (losing .len/.cap) and under-popped the receiver's arg-regs by two words: the
|
||||
// arg-shift collision corrupts every subsequent arg (the receiver reads the
|
||||
// caller's spilled p.ptr as its own s.len). The fix gave `nodeisslice` an N_CALL
|
||||
// arm (mirroring nodeisstr): both the push side (3-PUSH CX,BX,AX) and the pop
|
||||
// side (extra=2) fire for slice-returning CALLs as args. Each @test KEEPS the
|
||||
// `check(view(s))` call-arg-composite shape under test and asserts the receiver
|
||||
// saw the right .len (a check fn returns 0 only when its internal .len checks
|
||||
// pass, so the asserted 0 IS the value contract).
|
||||
|
||||
package composite_call_arg_test;
|
||||
|
||||
fn view(s: str) []u8 = {
|
||||
let r: []u8;
|
||||
r.ptr = s.ptr;
|
||||
r.len = s.len;
|
||||
r.cap = s.len;
|
||||
return r;
|
||||
};
|
||||
|
||||
fn passthrough(a: []u8) []u8 = { return a; };
|
||||
|
||||
fn check_a(a: []u8) i32 = {
|
||||
if (a.len == 13) { return 0; };
|
||||
return 11;
|
||||
};
|
||||
|
||||
fn check2_b(a: []u8, b: []u8) i32 = {
|
||||
if (a.len != 13) { return 11; };
|
||||
if (b.len != 5) { return 12; };
|
||||
return 0;
|
||||
};
|
||||
|
||||
fn check2_c(a: []u8, b: []u8) i32 = {
|
||||
if (a.len != 3) { return 11; };
|
||||
if (b.len != 5) { return 12; };
|
||||
return 0;
|
||||
};
|
||||
|
||||
fn check3_d(k0: i32, a: []u8, k1: i32) i32 = {
|
||||
if (k0 != 7) { return 11; };
|
||||
if (a.len != 4) { return 12; };
|
||||
if (k1 != 9) { return 13; };
|
||||
return 0;
|
||||
};
|
||||
|
||||
fn check_e(a: []u8) i32 = {
|
||||
if (a.len == 6) { return 0; };
|
||||
return 11;
|
||||
};
|
||||
|
||||
fn use2_f(a: []u8, k: i32) i32 = {
|
||||
if (a.len != 13) { return 11; };
|
||||
if (k != 99) { return 12; };
|
||||
return 0;
|
||||
};
|
||||
|
||||
type oserror = !i32;
|
||||
|
||||
fn yield_ptr() (*u8 | oserror) = {
|
||||
let p: *u8 = nil;
|
||||
return p;
|
||||
};
|
||||
|
||||
fn dispatch(v: (*u8 | oserror)) i32 = {
|
||||
match (v) {
|
||||
case let p: *u8 => return 7;
|
||||
case let e: oserror => return e: i32;
|
||||
};
|
||||
return -99;
|
||||
};
|
||||
|
||||
@test fn canonical_slice_call() void = {
|
||||
// (a) canonical f(g()) with g returning []u8.
|
||||
let s: str = "hello, world!";
|
||||
assert(check_a(view(s)) == 0);
|
||||
};
|
||||
|
||||
@test fn slice_call_then_letslice() void = {
|
||||
// (b) f(g(), p) — strings.hasprefix shape: slice-CALL then a let-slice.
|
||||
let s: str = "hello, world!";
|
||||
let p: []u8;
|
||||
p.ptr = s.ptr;
|
||||
p.len = 5;
|
||||
p.cap = 5;
|
||||
assert(check2_b(view(s), p) == 0);
|
||||
};
|
||||
|
||||
@test fn two_composite_calls_args() void = {
|
||||
// (c) f(g(in1), g(in2)) — two composite CALLs; the stack must hold both
|
||||
// 3-word headers before the 6-POP drain.
|
||||
let s1: str = "foo";
|
||||
let s2: str = "hello";
|
||||
assert(check2_c(view(s1), view(s2)) == 0);
|
||||
};
|
||||
|
||||
@test fn slice_call_middle_arg() void = {
|
||||
// (d) f(k0, g(), k1) — slice-CALL in the middle of three args.
|
||||
let s: str = "abcd";
|
||||
assert(check3_d(7, view(s), 9) == 0);
|
||||
};
|
||||
|
||||
@test fn nested_composite_calls() void = {
|
||||
// (e) f(g(h(s))) — composite-in-composite nesting.
|
||||
let s: str = "abcdef";
|
||||
assert(check_e(passthrough(view(s))) == 0);
|
||||
};
|
||||
|
||||
@test fn slice_call_then_scalar() void = {
|
||||
// (f) f(g(), 99) — slice-CALL then a scalar (pop-count mix).
|
||||
let s: str = "hello, world!";
|
||||
assert(use2_f(view(s), 99) == 0);
|
||||
};
|
||||
|
||||
@test fn tagged_call_regression() void = {
|
||||
// (g) tagged-CALL alongside the slice path — confirms #21's natural-push
|
||||
// arm composes with #24's.
|
||||
assert(dispatch(yield_ptr()) == 7);
|
||||
};
|
||||
Reference in New Issue
Block a user