wcc: tuple slice-element read loads the full 24B header, both stages
Reading a slice-typed tuple element (t.0) loaded only the pointer word; len and cap took whatever was left in BX/CX — silent garbage in BOTH stages once anything clobbered the registers between build and read. Load all three header words at the tuple-element arm. Review item #28. Both stages move in one commit: one emission contract; splitting would leave the byte-id gates red between the halves.
This commit is contained in:
@@ -100,6 +100,45 @@ static const struct row rows[] = {
|
||||
" let v: []u8 = s: []u8;\n"
|
||||
" return v.cap: i32;\n"
|
||||
"};\n", 4, K_RUN, NULL },
|
||||
/* #28 (#263 both-stages): tuple slice-element read `t.0` over a
|
||||
* ([]u8, i64). A clobber() call between the tuple build and the
|
||||
* read leaves junk in BX/CX; pre-fix the str-only arm fell to the
|
||||
* scalar tail (ptr word only), so ys.len read stale BX. Reads len
|
||||
* == 5 (distinct from any stale value) → 0. */
|
||||
{ "tuple_slice_elem",
|
||||
"package main;\n"
|
||||
"fn clobber() i64 = {\n"
|
||||
" let a: i64 = 111;\n"
|
||||
" let b: i64 = 222;\n"
|
||||
" return a + b;\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let xs: []u8 = [1u8, 2u8, 3u8, 4u8, 5u8];\n"
|
||||
" let t: ([]u8, i64) = (xs, 7);\n"
|
||||
" let junk: i64 = clobber();\n"
|
||||
" let ys: []u8 = t.0;\n"
|
||||
" if (ys.len == 5) { return 0; };\n"
|
||||
" return 1;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
/* #28 sibling: the slice element sits at tuple position 1 (foff != 0:
|
||||
* an i64 occupies slot 0, the []u8 header starts at +8). Exercises the
|
||||
* widened arm's offset arithmetic, which the position-0 row leaves
|
||||
* untested. Same clobber()-between-build-and-read trigger; len == 6. */
|
||||
{ "tuple_slice_elem_pos1",
|
||||
"package main;\n"
|
||||
"fn clobber() i64 = {\n"
|
||||
" let a: i64 = 111;\n"
|
||||
" let b: i64 = 222;\n"
|
||||
" return a + b;\n"
|
||||
"};\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let xs: []u8 = [1u8, 2u8, 3u8, 4u8, 5u8, 6u8];\n"
|
||||
" let t: (i64, []u8) = (9, xs);\n"
|
||||
" let junk: i64 = clobber();\n"
|
||||
" let ys: []u8 = t.1;\n"
|
||||
" if (ys.len == 6) { return 0; };\n"
|
||||
" return 1;\n"
|
||||
"};\n", 0, K_RUN, NULL },
|
||||
};
|
||||
|
||||
static int
|
||||
|
||||
Reference in New Issue
Block a user