w6c: slice reassignment — full triple flow through N_IDENT/N_SLICE/N_ASSIGN
N_IDENT for a slice local now loads (AX=ptr, BX=len, CX=cap), matching the existing global-slice load. cgexpr learns N_SLICE: `base[lo:hi]` leaves the same triple in registers, so callers (return, arg push, reassignment) all share one shape. The let-init's pre-existing N_SLICE direct-store path stays as a specialisation; the new generic slice let-init catches fn-returning-slice and slice-ident initialisers. N_ASSIGN gains a TY_SLICE branch parallel to TY_STR: store all three halves to the local slot or, for globals, stash CX into DI before LEAQ-ing the address (CX is both the new cap and the address scratch).
This commit is contained in:
@@ -146,11 +146,10 @@ static const struct fixture fixtures[] = {
|
||||
},
|
||||
{
|
||||
"slice-cap-via-raw-pointer",
|
||||
/* Drive the slice header through a raw u64 pointer cast
|
||||
* — the language has no slice-reassignment expression
|
||||
* yet, so this is the only way to fill the header from
|
||||
* ww source today. .cap reads back as the value we
|
||||
* wrote. */
|
||||
/* Drive the slice header through a raw u64 pointer cast.
|
||||
* Pre-fix for slice reassignment this was the only way to
|
||||
* fill the header from ww source; kept because the path
|
||||
* still has to work. */
|
||||
"let buf: []u8;\n"
|
||||
"fn main() i32 = {\n"
|
||||
"\tlet p: *u64 = (&buf): *u64;\n"
|
||||
@@ -159,6 +158,52 @@ static const struct fixture fixtures[] = {
|
||||
"};\n",
|
||||
99,
|
||||
},
|
||||
{
|
||||
"slice-global-reassign-from-global",
|
||||
/* `dst = src` for slice globals — both halves of the
|
||||
* triple (ptr, len, cap) must propagate. */
|
||||
"let dst: []u8;\n"
|
||||
"let src: []u8;\n"
|
||||
"fn main() i32 = {\n"
|
||||
"\tlet p: *u64 = (&src): *u64;\n"
|
||||
"\tp[0] = 0x1000u64;\n"
|
||||
"\tp[1] = 7u64;\n"
|
||||
"\tp[2] = 99u64;\n"
|
||||
"\tdst = src;\n"
|
||||
"\treturn dst.len: i32 + dst.cap: i32;\n"
|
||||
"};\n",
|
||||
106,
|
||||
},
|
||||
{
|
||||
"slice-local-reassign-from-slice-expr",
|
||||
/* `s = arr[lo:hi]` reassigns the slice local; cgexpr now
|
||||
* emits N_SLICE as a triple. Previously the let-init
|
||||
* specific N_SLICE path worked but reassignment dropped
|
||||
* len/cap. */
|
||||
"fn main() i32 = {\n"
|
||||
"\tlet arr: [16]u8;\n"
|
||||
"\tlet i: i32 = 0;\n"
|
||||
"\tfor (i < 16) { arr[i] = i: u8; i += 1; };\n"
|
||||
"\tlet s: []u8 = arr[3:10];\n"
|
||||
"\ts = arr[1:5];\n"
|
||||
"\treturn s.len: i32;\n"
|
||||
"};\n",
|
||||
4,
|
||||
},
|
||||
{
|
||||
"slice-local-from-fn-return",
|
||||
/* fn returning []u8 leaves (AX,BX,CX) at return; the let-
|
||||
* init slice fallback stores the triple. */
|
||||
"fn mkslice() []u8 = {\n"
|
||||
"\tlet arr: [16]u8;\n"
|
||||
"\treturn arr[3:9];\n"
|
||||
"};\n"
|
||||
"fn main() i32 = {\n"
|
||||
"\tlet s: []u8 = mkslice();\n"
|
||||
"\treturn s.len: i32;\n"
|
||||
"};\n",
|
||||
6,
|
||||
},
|
||||
{
|
||||
"struct-field-readwrite",
|
||||
/* Top-level struct global. Field writes hit the global
|
||||
|
||||
Reference in New Issue
Block a user