w6c+selfhost: str globals — 16B DATAW + (LEAQ, MOVQ, MOVQ) sequences
Extend top-level mutable `let` to cover str. The cgen now:
- emits a 16-byte zero DATAW for `let s: str;` (and the trivial
`nil` / `""` inits); a non-empty strlit init is skipped because
a compile-time .data → .text reloc isn't supported yet, so the
user gets a clean undefined-symbol error at link;
- loads `s` as `(LEAQ s(SB), CX; MOVQ (CX), AX; MOVQ 8(CX), BX)`
so the (AX=ptr, BX=len) pair convention is preserved;
- stores via the same `&s` indirection for `s = expr;` and routes
the `.ptr` / `.len` pseudo-field N_DOT branch through it; and
- tracks the declared type on each LetVar so cgident / cgdot /
cgassign pick the right load/store shape.
Selfhost cgen mirrors all four paths byte-for-byte; test 990
(cgen-match on err.ww) and tests 994/995 (self-rebuild) stay
green. 630_let_global gains two new fixtures (`let msg: str;` +
runtime assign, plus reassign from a helper).
Slice and struct globals still NYI — same scope deferred.
This commit is contained in:
@@ -91,6 +91,28 @@ static const struct fixture fixtures[] = {
|
||||
"fn main() i32 = { return val: i32; };\n",
|
||||
123,
|
||||
},
|
||||
{
|
||||
"str-zeroinit",
|
||||
/* `let msg: str;` zero-inits the {ptr,len} slot. Assigning
|
||||
* a strlit at runtime updates both halves; .len then reads
|
||||
* the stored length. */
|
||||
"let msg: str;\n"
|
||||
"fn main() i32 = {\n"
|
||||
"\tmsg = \"hello\";\n"
|
||||
"\treturn msg.len: i32;\n"
|
||||
"};\n",
|
||||
5,
|
||||
},
|
||||
{
|
||||
"str-reassign",
|
||||
"let msg: str;\n"
|
||||
"fn set(s: str) void = { msg = s; };\n"
|
||||
"fn main() i32 = {\n"
|
||||
"\tset(\"abcdefg\");\n"
|
||||
"\treturn msg.len: i32;\n"
|
||||
"};\n",
|
||||
7,
|
||||
},
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user