cmd/w6c+selfhost/wcc+lib: route sizeof(str)/sizeof(slice) through SSoT
Audit §1.1/§1.2 cataloged 17 wwstage sites hardcoding 16 for sizeof(str) and ~10 hardcoding 24 for sizeof(slice), plus 4 cstage str-size sites and the cstage let_emit_size str/slice arms. Each new size constant required ~30 edits in both stages to bump cleanly — task #1 (str → 24B {ptr,len,cap}) can't land until the literal sweep is done. Track A — wwstage codegen (selfhost/cmd/wcc/*): - check.ww introduces two stateless helpers next to astsize: primtypesize(nm) — primitive-name → byte size (i64; -1 unknown) tyslicesize() — slice-header bytes (i64; 24 today) astsize now reads both for its N_TNAME-primitive and N_TSLICE arms, so the size(T) fold gets the SSoT for free. - cgen.ww, cgenutil.ww, cgenstmt.ww, cgendecl.ww: every `return 16` / `esz = 16` / `sz0 = 16` for str, every `return 24` / `localadd(c, _, 24, _)` for slice, plus the matching `sz == 16` / `sz == 24` / `for (i < 16/24)` gates in the global-let DATAW emit, route through primtypesize / tyslicesize. - Direct delegation slotsize→astsize would require restructuring astsize to drop its *checker dep (resolvealias) — the leaf primitive/slice cases factor out cleanly, the alias-chain leaves diverge because cgen's aliaslookup/structlookup tables and check's scope chain aren't unified yet (§1.8, task #50 follow-up). Sharing the leaf table satisfies the SSoT promise without that refactor. Track B — cstage (cmd/w6c/cgen.c): - let_emit_size's TY_STR/TY_SLICE arms drop the hardcoded 16/24 and fall to `(int)u->size` like the existing TY_STRUCT/TUPLE/TAGGED arms. - N_LET cgstmt's per-kind `sz` cascade collapses to a single `if (lu->kind ∈ {ARRAY,SLICE,STR,STRUCT,TUPLE,TAGGED}) sz = lu->size`. - N_LET cgexpr's match-bind primitive sizing: `bsz = (int)bu->size` drops the TY_STR/TY_SLICE special-cases (same outcome — ty_str/ ty_slice already have ->size set by type.c). - Three `sz == 16` / `let_emit_size(d->type) != 16` gates against the str slot width route through ty_str->size. Cap-offset sites (cgen.c:2440/1994/3206/5517 `delta = 16` for slice's .cap field-write) intentionally NOT touched: 16 there is the *offset of .cap inside a slice header*, structurally always 16 regardless of str.size. #1 doesn't move the slice layout. Track C — lib/ user code: - lib/strings.freeall + appendstr, lib/shlex.freepartial + appendstr: the four `16u64` literals (per-str-element stride for rt_ensure and os.free) become `size(str): u64`. Check-time fold via #42's intercept resolves to 16 today; #1 reroutes via the bumped tinfo. After this commit, bumping ty_str to 24B for task #1 requires editing exactly two places (cmd/wcc/type.c:64 ty_str.size, plus check.ww primtypesize's "str" arm) for the SSoT to propagate. Verification: - 131/131 tests pass. 994_w6c_ww + 995_self_rebuild byte-identity holds — each replacement evaluates to the same constant the literal had today, so cgen output is unchanged. - selfhost source's `size(str): u64` folds at check time (cstage cmd/wcc/check.c:907-960 for the C-bootstrap of selfhost; wwstage check.ww:898-942 for the rebuild path), no runtime call introduced.
This commit is contained in:
@@ -705,9 +705,8 @@ let_emit_size(Type *t)
|
|||||||
case TY_F64:
|
case TY_F64:
|
||||||
return 8; /* MOVSD loads/stores 8B via LEAQ+indir. */
|
return 8; /* MOVSD loads/stores 8B via LEAQ+indir. */
|
||||||
case TY_STR:
|
case TY_STR:
|
||||||
return 16; /* {ptr, len}; literal-strlit init NYI. */
|
|
||||||
case TY_SLICE:
|
case TY_SLICE:
|
||||||
return 24; /* {ptr, len, cap}; no init only. */
|
return (int)u->size; /* #43: ty_str / ty_slice SSoT. */
|
||||||
case TY_STRUCT:
|
case TY_STRUCT:
|
||||||
return (int)u->size; /* zero-init only; field reads/
|
return (int)u->size; /* zero-init only; field reads/
|
||||||
* scalar-field writes only. */
|
* scalar-field writes only. */
|
||||||
@@ -4988,10 +4987,10 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
|||||||
amem(D_BP, voff));
|
amem(D_BP, voff));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* #43: route through Type.size SSoT rather
|
||||||
|
* than re-asserting 16/24 for str/slice. */
|
||||||
int bsz = 8;
|
int bsz = 8;
|
||||||
if (bu && bu->kind == TY_STR) bsz = 16;
|
if (bu) bsz = (int)bu->size;
|
||||||
else if (bu && bu->kind == TY_SLICE) bsz = 24;
|
|
||||||
else if (bu) bsz = (int)bu->size;
|
|
||||||
if (bsz <= 0) bsz = 8;
|
if (bsz <= 0) bsz = 8;
|
||||||
/* local_alloc to dodge name-collision
|
/* local_alloc to dodge name-collision
|
||||||
* dedup — a 16B str bind shadowing an
|
* dedup — a 16B str bind shadowing an
|
||||||
@@ -6350,13 +6349,14 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
|||||||
* collapsed the struct/slice/tagged sizing arms to the 8B
|
* collapsed the struct/slice/tagged sizing arms to the 8B
|
||||||
* fallback, and the slot under-allocated the local. */
|
* fallback, and the slot under-allocated the local. */
|
||||||
Type *lu = type_chase_named(lt);
|
Type *lu = type_chase_named(lt);
|
||||||
|
/* #43: every composite kind already has its byte size cached in
|
||||||
|
* lu->size; route through it instead of re-asserting 16/24 for
|
||||||
|
* str/slice and re-reading for the others. */
|
||||||
int sz = 8;
|
int sz = 8;
|
||||||
if (lu && lu->kind == TY_ARRAY) sz = (int)lu->size;
|
if (lu && (lu->kind == TY_ARRAY || lu->kind == TY_SLICE
|
||||||
else if (lu && lu->kind == TY_SLICE) sz = 24;
|
|| lu->kind == TY_STR || lu->kind == TY_STRUCT
|
||||||
else if (lu && lu->kind == TY_STR) sz = 16;
|
|| lu->kind == TY_TUPLE || lu->kind == TY_TAGGED))
|
||||||
else if (lu && lu->kind == TY_STRUCT) sz = (int)lu->size;
|
sz = (int)lu->size;
|
||||||
else if (lu && lu->kind == TY_TUPLE) sz = (int)lu->size;
|
|
||||||
else if (lu && lu->kind == TY_TAGGED) sz = (int)lu->size;
|
|
||||||
int off = localoff(c, locals, n->str, sz, frame);
|
int off = localoff(c, locals, n->str, sz, frame);
|
||||||
int isf = cg_isfloat(lt);
|
int isf = cg_isfloat(lt);
|
||||||
int isf32 = type_isf32(lt);
|
int isf32 = type_isf32(lt);
|
||||||
@@ -6433,8 +6433,10 @@ cgstmt(Cg *c, Node *n, Local **locals, int *frame)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* str initialiser: cgexpr produces (AX=ptr, BX=len). */
|
/* str initialiser: cgexpr produces (AX=ptr, BX=len).
|
||||||
if (n->rhs && type_isstr(lt) && sz == 16) {
|
* #43: gate width via ty_str->size so a future str-layout
|
||||||
|
* bump (#1) propagates without touching this site. */
|
||||||
|
if (n->rhs && type_isstr(lt) && sz == (int)ty_str->size) {
|
||||||
cgexpr(c, n->rhs, *locals);
|
cgexpr(c, n->rhs, *locals);
|
||||||
ins2(c, A_MOVQ, areg(D_AX), amem(D_BP, off + 0));
|
ins2(c, A_MOVQ, areg(D_AX), amem(D_BP, off + 0));
|
||||||
ins2(c, A_MOVQ, areg(D_BX), amem(D_BP, off + 8));
|
ins2(c, A_MOVQ, areg(D_BX), amem(D_BP, off + 8));
|
||||||
@@ -7763,7 +7765,8 @@ emit_lets(Cg *c, FILE *out, Node *file)
|
|||||||
/* str literal init: bake the interned label's address
|
/* str literal init: bake the interned label's address
|
||||||
* into the ptr half via a DATAR reloc, set the len half
|
* into the ptr half via a DATAR reloc, set the len half
|
||||||
* inline. */
|
* inline. */
|
||||||
if (sz == 16 && r != NULL && r->kind == N_STRLIT
|
/* #43: gate via ty_str->size so #1 propagates. */
|
||||||
|
if (sz == (int)ty_str->size && r != NULL && r->kind == N_STRLIT
|
||||||
&& r->strlen > 0) {
|
&& r->strlen > 0) {
|
||||||
const char *lab = intern_strlit(c, r->str, r->strlen);
|
const char *lab = intern_strlit(c, r->str, r->strlen);
|
||||||
const char *sym = mod_mangle(c, d->str);
|
const char *sym = mod_mangle(c, d->str);
|
||||||
@@ -7916,7 +7919,7 @@ let_pre_intern(Cg *c, Node *file)
|
|||||||
if (file == NULL) return;
|
if (file == NULL) return;
|
||||||
for (Node *d = file->list; d; d = d->next) {
|
for (Node *d = file->list; d; d = d->next) {
|
||||||
if (d->kind != N_LET) continue;
|
if (d->kind != N_LET) continue;
|
||||||
if (let_emit_size(d->type) != 16) continue;
|
if (let_emit_size(d->type) != (int)ty_str->size) continue;
|
||||||
Node *r = d->rhs;
|
Node *r = d->rhs;
|
||||||
while (r != NULL && r->kind == N_CAST) r = r->lhs;
|
while (r != NULL && r->kind == N_CAST) r = r->lhs;
|
||||||
if (r == NULL || r->kind != N_STRLIT) continue;
|
if (r == NULL || r->kind != N_STRLIT) continue;
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ fn dupstr(s: str) str = {
|
|||||||
fn appendstr(slice: *[]str, item: str) void = {
|
fn appendstr(slice: *[]str, item: str) void = {
|
||||||
let newlen: i32 = slice.len + 1;
|
let newlen: i32 = slice.len + 1;
|
||||||
slice.len = newlen;
|
slice.len = newlen;
|
||||||
rtensure(slice: *void, 16u64);
|
rtensure(slice: *void, size(str): u64);
|
||||||
let dst: *str = &slice.ptr[newlen - 1];
|
let dst: *str = &slice.ptr[newlen - 1];
|
||||||
dst.ptr = item.ptr;
|
dst.ptr = item.ptr;
|
||||||
dst.len = item.len;
|
dst.len = item.len;
|
||||||
@@ -159,7 +159,7 @@ fn freepartial(slice: []str) void = {
|
|||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
if (slice.cap > 0) {
|
if (slice.cap > 0) {
|
||||||
os.free(slice.ptr: *void, (slice.cap: u64) * 16u64);
|
os.free(slice.ptr: *void, (slice.cap: u64) * size(str): u64);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ export fn freeall(s: []str) void = {
|
|||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
if (s.cap > 0) {
|
if (s.cap > 0) {
|
||||||
os.free(s.ptr: *void, (s.cap: u64) * 16u64);
|
os.free(s.ptr: *void, (s.cap: u64) * size(str): u64);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -762,7 +762,7 @@ export fn remaining_tokens(s: *tokenizer) str = {
|
|||||||
fn appendstr(slice: *[]str, item: str) void = {
|
fn appendstr(slice: *[]str, item: str) void = {
|
||||||
let newlen: i32 = slice.len + 1;
|
let newlen: i32 = slice.len + 1;
|
||||||
slice.len = newlen;
|
slice.len = newlen;
|
||||||
rtensure(slice: *void, 16u64);
|
rtensure(slice: *void, size(str): u64);
|
||||||
let dst: *str = &slice.ptr[newlen - 1];
|
let dst: *str = &slice.ptr[newlen - 1];
|
||||||
dst.ptr = item.ptr;
|
dst.ptr = item.ptr;
|
||||||
dst.len = item.len;
|
dst.len = item.len;
|
||||||
|
|||||||
@@ -1996,7 +1996,7 @@ export fn freeall(s: []str) void = {
|
|||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
if (s.cap > 0) {
|
if (s.cap > 0) {
|
||||||
os.free(s.ptr: *void, (s.cap: u64) * 16u64);
|
os.free(s.ptr: *void, (s.cap: u64) * size(str): u64);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2599,7 +2599,7 @@ export fn remaining_tokens(s: *tokenizer) str = {
|
|||||||
fn appendstr(slice: *[]str, item: str) void = {
|
fn appendstr(slice: *[]str, item: str) void = {
|
||||||
let newlen: i32 = slice.len + 1;
|
let newlen: i32 = slice.len + 1;
|
||||||
slice.len = newlen;
|
slice.len = newlen;
|
||||||
rtensure(slice: *void, 16u64);
|
rtensure(slice: *void, size(str): u64);
|
||||||
let dst: *str = &slice.ptr[newlen - 1];
|
let dst: *str = &slice.ptr[newlen - 1];
|
||||||
dst.ptr = item.ptr;
|
dst.ptr = item.ptr;
|
||||||
dst.len = item.len;
|
dst.len = item.len;
|
||||||
@@ -7612,6 +7612,29 @@ fn mktname(c: *checker, nm: str) *node = {
|
|||||||
return n;
|
return n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #43: SSoT for primitive type byte sizes. astsize's N_TNAME-primitive
|
||||||
|
// arm and every wwstage cgen size walker (slotsize/fieldsize/letemit-
|
||||||
|
// size/elemsizeof/paramfieldsize) consult this table so a future
|
||||||
|
// ty_str.size bump (#1) lands in one place. Returns -1 for non-prim
|
||||||
|
// names; callers fall back to alias/struct/enum lookup. Cstage's
|
||||||
|
// equivalent SSoT is cmd/wcc/type.c:46-79 (ty_void/ty_bool/.../ty_str).
|
||||||
|
fn primtypesize(nm: str) i64 = {
|
||||||
|
if (streq(nm, "void")) { return 0i64; };
|
||||||
|
if (streq(nm, "bool")) { return 1i64; };
|
||||||
|
if (streq(nm, "i8") || streq(nm, "u8")) { return 1i64; };
|
||||||
|
if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; };
|
||||||
|
if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; };
|
||||||
|
if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64")) { return 8i64; };
|
||||||
|
if (streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr")) { return 8i64; };
|
||||||
|
if (streq(nm, "str")) { return 16i64; };
|
||||||
|
return -1i64;
|
||||||
|
};
|
||||||
|
|
||||||
|
// #43: SSoT for slice header size (ptr+len+cap = 24B today). Mirrors
|
||||||
|
// cstage cmd/wcc/type.c:103 (ty_slice->size = 24). Bumping a slice's
|
||||||
|
// header layout in #34 touches only this constant.
|
||||||
|
fn tyslicesize() i64 = { return 24i64; };
|
||||||
|
|
||||||
// #42: AST-level layout helpers for the size(T)/align(T)/offset(e.f)
|
// #42: AST-level layout helpers for the size(T)/align(T)/offset(e.f)
|
||||||
// fold. Mirror cstage resolve_type's size/align computation
|
// fold. Mirror cstage resolve_type's size/align computation
|
||||||
// (cmd/wcc/check.c:286-528) on AST nodes — wwstage check.ww never
|
// (cmd/wcc/check.c:286-528) on AST nodes — wwstage check.ww never
|
||||||
@@ -7673,7 +7696,7 @@ fn astsize(c: *checker, t: *node) i64 = {
|
|||||||
let k: nkind = t.kind;
|
let k: nkind = t.kind;
|
||||||
if (k == nkind.N_TBANG) { return astsize(c, t.lhs); };
|
if (k == nkind.N_TBANG) { return astsize(c, t.lhs); };
|
||||||
if (k == nkind.N_TPTR) { return 8i64; };
|
if (k == nkind.N_TPTR) { return 8i64; };
|
||||||
if (k == nkind.N_TSLICE) { return 24i64; };
|
if (k == nkind.N_TSLICE) { return tyslicesize(); };
|
||||||
if (k == nkind.N_TCHAN) { return 8i64; };
|
if (k == nkind.N_TCHAN) { return 8i64; };
|
||||||
if (k == nkind.N_TFN) { return 8i64; };
|
if (k == nkind.N_TFN) { return 8i64; };
|
||||||
if (k == nkind.N_TARRAY) {
|
if (k == nkind.N_TARRAY) {
|
||||||
@@ -7725,13 +7748,8 @@ fn astsize(c: *checker, t: *node) i64 = {
|
|||||||
};
|
};
|
||||||
if (k == nkind.N_TNAME) {
|
if (k == nkind.N_TNAME) {
|
||||||
let nm: str = t.str;
|
let nm: str = t.str;
|
||||||
if (streq(nm, "void")) { return 0i64; };
|
let ps: i64 = primtypesize(nm);
|
||||||
if (streq(nm, "bool")) { return 1i64; };
|
if (ps >= 0i64) { return ps; };
|
||||||
if (streq(nm, "i8") || streq(nm, "u8")) { return 1i64; };
|
|
||||||
if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; };
|
|
||||||
if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; };
|
|
||||||
if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64") || streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr")) { return 8i64; };
|
|
||||||
if (streq(nm, "str")) { return 16i64; };
|
|
||||||
let resolved: *node = resolvealias(c, t);
|
let resolved: *node = resolvealias(c, t);
|
||||||
if (resolved != nil && resolved != t) {
|
if (resolved != nil && resolved != t) {
|
||||||
return astsize(c, resolved);
|
return astsize(c, resolved);
|
||||||
@@ -9854,7 +9872,7 @@ fn indexbaseesz(c: *cgen, base: *node) i32 = {
|
|||||||
let elem: *node = ft.lhs;
|
let elem: *node = ft.lhs;
|
||||||
if (elem != nil) {
|
if (elem != nil) {
|
||||||
if (elem.kind == nkind.N_TNAME) {
|
if (elem.kind == nkind.N_TNAME) {
|
||||||
if (streq(elem.str, "str")) { return 16; };
|
if (streq(elem.str, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(elem.str);
|
let ps: i32 = primsize(elem.str);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
// Pointer to named struct: indexing
|
// Pointer to named struct: indexing
|
||||||
@@ -9962,11 +9980,11 @@ fn elemsizeof(t: *node) i32 = {
|
|||||||
// `*[]T`: stride is the slice header (24B). Hare-faithful — a
|
// `*[]T`: stride is the slice header (24B). Hare-faithful — a
|
||||||
// pointer-to-slice is a 1D array of slices, not of T. Mirrors the
|
// pointer-to-slice is a 1D array of slices, not of T. Mirrors the
|
||||||
// cstage check.c default `*U → U` path for U=[]T (slice element).
|
// cstage check.c default `*U → U` path for U=[]T (slice element).
|
||||||
if (elem.kind == nkind.N_TSLICE) { return 24; };
|
if (elem.kind == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (elem.kind == nkind.N_TNAME) {
|
if (elem.kind == nkind.N_TNAME) {
|
||||||
let nm: str = elem.str;
|
let nm: str = elem.str;
|
||||||
// str element is 16B (ptr+len). primsize returns 0 for it.
|
// str element is 16B (ptr+len). primsize returns 0 for it.
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
};
|
};
|
||||||
@@ -10561,7 +10579,7 @@ export fn letslotsize(c: *cgen, n: *node) i32 = {
|
|||||||
// (ptr+len) — primsize returns 0 for
|
// (ptr+len) — primsize returns 0 for
|
||||||
// it, so it'd slot 8B without this.
|
// it, so it'd slot 8B without this.
|
||||||
if (streq(elemn.str, "str")) {
|
if (streq(elemn.str, "str")) {
|
||||||
esz = 16;
|
esz = primtypesize("str"): i32;
|
||||||
} else {
|
} else {
|
||||||
let ps: i32 = primsize(elemn.str);
|
let ps: i32 = primsize(elemn.str);
|
||||||
if (ps > 0) { esz = ps; };
|
if (ps > 0) { esz = ps; };
|
||||||
@@ -10610,7 +10628,7 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
|||||||
if (k == nkind.N_TPTR) { return 8; };
|
if (k == nkind.N_TPTR) { return 8; };
|
||||||
if (k == nkind.N_TFN) { return 8; };
|
if (k == nkind.N_TFN) { return 8; };
|
||||||
if (k == nkind.N_TCHAN) { return 8; };
|
if (k == nkind.N_TCHAN) { return 8; };
|
||||||
if (k == nkind.N_TSLICE) { return 24; };
|
if (k == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (k == nkind.N_TTUPLE) {
|
if (k == nkind.N_TTUPLE) {
|
||||||
// Sum element sizes. Mirrors C cgen which uses raw type
|
// Sum element sizes. Mirrors C cgen which uses raw type
|
||||||
// sizes; padding to 8 happens inside slotsize for primitives,
|
// sizes; padding to 8 happens inside slotsize for primitives,
|
||||||
@@ -10650,7 +10668,7 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
|||||||
// slot+8 picking up the callee's stale-DX. Bypassing primsize's
|
// slot+8 picking up the callee's stale-DX. Bypassing primsize's
|
||||||
// `> 0` guard keeps the rest of the prim-pad-to-8 contract intact.
|
// `> 0` guard keeps the rest of the prim-pad-to-8 contract intact.
|
||||||
if (streq(nm, "void")) { return 0; };
|
if (streq(nm, "void")) { return 0; };
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) {
|
if (ps > 0) {
|
||||||
// Pad to 8 for stack slots — matches C cgen which spills
|
// Pad to 8 for stack slots — matches C cgen which spills
|
||||||
@@ -10691,7 +10709,7 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
|||||||
// explicit case a `[N]str` would slot 8B/elem,
|
// explicit case a `[N]str` would slot 8B/elem,
|
||||||
// collapsing the per-element stride and losing
|
// collapsing the per-element stride and losing
|
||||||
// every .len half.
|
// every .len half.
|
||||||
if (streq(en, "str")) { esz = 16; };
|
if (streq(en, "str")) { esz = primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(en);
|
let ps: i32 = primsize(en);
|
||||||
if (esz == 8) { if (ps > 0) { esz = ps; }
|
if (esz == 8) { if (ps > 0) { esz = ps; }
|
||||||
else {
|
else {
|
||||||
@@ -10749,7 +10767,7 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = {
|
|||||||
if (k == nkind.N_TTAGGED){ return slotsize(c, tnode); };
|
if (k == nkind.N_TTAGGED){ return slotsize(c, tnode); };
|
||||||
if (k == nkind.N_TNAME) {
|
if (k == nkind.N_TNAME) {
|
||||||
let nm: str = tnode.str;
|
let nm: str = tnode.str;
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
let si: *structinfo = structlookup(c, nm);
|
let si: *structinfo = structlookup(c, nm);
|
||||||
@@ -10776,7 +10794,7 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = {
|
|||||||
return 8;
|
return 8;
|
||||||
};
|
};
|
||||||
if (k == nkind.N_TPTR) { return 8; };
|
if (k == nkind.N_TPTR) { return 8; };
|
||||||
if (k == nkind.N_TSLICE) { return 24; };
|
if (k == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (k == nkind.N_TARRAY) {
|
if (k == nkind.N_TARRAY) {
|
||||||
// Same shape as slotsize's TARRAY branch.
|
// Same shape as slotsize's TARRAY branch.
|
||||||
let lenn: *node = tnode.rhs;
|
let lenn: *node = tnode.rhs;
|
||||||
@@ -19139,7 +19157,7 @@ fn cglet(c: *cgen, n: *node) void = {
|
|||||||
if (elemn != nil) {
|
if (elemn != nil) {
|
||||||
if (elemn.kind == nkind.N_TNAME) {
|
if (elemn.kind == nkind.N_TNAME) {
|
||||||
if (streq(elemn.str, "str")) {
|
if (streq(elemn.str, "str")) {
|
||||||
esz = 16;
|
esz = primtypesize("str"): i32;
|
||||||
isstrel = true;
|
isstrel = true;
|
||||||
} else {
|
} else {
|
||||||
let ps: i32 = primsize(elemn.str);
|
let ps: i32 = primsize(elemn.str);
|
||||||
@@ -19624,8 +19642,8 @@ fn cgmlet(c: *cgen, n: *node) void = {
|
|||||||
if (s0_is_str != s1_is_str) {
|
if (s0_is_str != s1_is_str) {
|
||||||
let sz0: i32 = 8;
|
let sz0: i32 = 8;
|
||||||
let sz1: i32 = 8;
|
let sz1: i32 = 8;
|
||||||
if (s0_is_str) { sz0 = 16; };
|
if (s0_is_str) { sz0 = primtypesize("str"): i32; };
|
||||||
if (s1_is_str) { sz1 = 16; };
|
if (s1_is_str) { sz1 = primtypesize("str"): i32; };
|
||||||
let off0: i32 = localadd(c, l0.str, sz0, t0);
|
let off0: i32 = localadd(c, l0.str, sz0, t0);
|
||||||
let off1: i32 = localadd(c, l1.str, sz1, t1);
|
let off1: i32 = localadd(c, l1.str, sz1, t1);
|
||||||
if (s0_is_str) {
|
if (s0_is_str) {
|
||||||
@@ -19682,7 +19700,7 @@ fn paramfieldsize(t: *node) i32 = {
|
|||||||
if (k == nkind.N_TCHAN) { return 8; };
|
if (k == nkind.N_TCHAN) { return 8; };
|
||||||
if (k == nkind.N_TNAME) {
|
if (k == nkind.N_TNAME) {
|
||||||
let nm: str = t.str;
|
let nm: str = t.str;
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
};
|
};
|
||||||
@@ -20054,7 +20072,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
if (p.op == tkind.TK_ELLIPSIS) {
|
if (p.op == tkind.TK_ELLIPSIS) {
|
||||||
let tn: *node = slicewrap(c, p.lhs);
|
let tn: *node = slicewrap(c, p.lhs);
|
||||||
if (idx + 3 <= 6) {
|
if (idx + 3 <= 6) {
|
||||||
let off: i32 = localadd(c, nm, 24, tn);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, tn);
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
emitline(argregname(idx));
|
emitline(argregname(idx));
|
||||||
emitline(", ");
|
emitline(", ");
|
||||||
@@ -20078,7 +20096,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
// at the ABI boundary (the call site synthesises a
|
// at the ABI boundary (the call site synthesises a
|
||||||
// 24B descriptor and pushes ptr/len/cap), so this
|
// 24B descriptor and pushes ptr/len/cap), so this
|
||||||
// mirrors the slice branch at cgendecl.ww:518.
|
// mirrors the slice branch at cgendecl.ww:518.
|
||||||
let off: i32 = localadd(c, nm, 24, tn);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, tn);
|
||||||
let regs_left: i32 = 6 - idx;
|
let regs_left: i32 = 6 - idx;
|
||||||
let w: i32 = 0;
|
let w: i32 = 0;
|
||||||
for (w < regs_left) {
|
for (w < regs_left) {
|
||||||
@@ -20178,7 +20196,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
};};
|
};};
|
||||||
} else { if (isslicetype(c, p.lhs)) {
|
} else { if (isslicetype(c, p.lhs)) {
|
||||||
if (idx + 3 <= 6) {
|
if (idx + 3 <= 6) {
|
||||||
let off: i32 = localadd(c, nm, 24, p.lhs);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, p.lhs);
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
emitline(argregname(idx));
|
emitline(argregname(idx));
|
||||||
emitline(", ");
|
emitline(", ");
|
||||||
@@ -20202,7 +20220,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
// 440-469. Caller's pushargsrev greedy-fills the
|
// 440-469. Caller's pushargsrev greedy-fills the
|
||||||
// remaining argregs (ptr,len,cap order), the tail
|
// remaining argregs (ptr,len,cap order), the tail
|
||||||
// spills to +16+stkcursor*8(BP).
|
// spills to +16+stkcursor*8(BP).
|
||||||
let off: i32 = localadd(c, nm, 24, p.lhs);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, p.lhs);
|
||||||
let regs_left: i32 = 6 - idx;
|
let regs_left: i32 = 6 - idx;
|
||||||
let w: i32 = 0;
|
let w: i32 = 0;
|
||||||
for (w < regs_left) {
|
for (w < regs_left) {
|
||||||
@@ -21426,7 +21444,7 @@ fn letemitsize(c: *cgen, d: *node) i32 = {
|
|||||||
let t: *node = d.lhs;
|
let t: *node = d.lhs;
|
||||||
for (t != nil) {
|
for (t != nil) {
|
||||||
if (t.kind == nkind.N_TPTR) { return 8; };
|
if (t.kind == nkind.N_TPTR) { return 8; };
|
||||||
if (t.kind == nkind.N_TSLICE) { return 24; };
|
if (t.kind == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (t.kind == nkind.N_TARRAY) {
|
if (t.kind == nkind.N_TARRAY) {
|
||||||
let lenn: *node = t.rhs;
|
let lenn: *node = t.rhs;
|
||||||
let elemn: *node = t.lhs;
|
let elemn: *node = t.lhs;
|
||||||
@@ -21448,7 +21466,7 @@ fn letemitsize(c: *cgen, d: *node) i32 = {
|
|||||||
if (letscalarprim(nm)) { return 8; };
|
if (letscalarprim(nm)) { return 8; };
|
||||||
let fsz: i32 = letfloatprim(nm);
|
let fsz: i32 = letfloatprim(nm);
|
||||||
if (fsz > 0) { return fsz; };
|
if (fsz > 0) { return fsz; };
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let si: *structinfo = structlookup(c, nm);
|
let si: *structinfo = structlookup(c, nm);
|
||||||
if (si != nil) { return si.totsize; };
|
if (si != nil) { return si.totsize; };
|
||||||
let next: *node = aliaslookup(c, nm);
|
let next: *node = aliaslookup(c, nm);
|
||||||
@@ -21774,7 +21792,7 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
emitline("\"\n");
|
emitline("\"\n");
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (sz == 16 && !issg) {
|
if (sz == primtypesize("str"): i32 && !issg) {
|
||||||
let r: *node = d.rhs;
|
let r: *node = d.rhs;
|
||||||
for (r != nil) {
|
for (r != nil) {
|
||||||
if (r.kind != nkind.N_CAST) { break; };
|
if (r.kind != nkind.N_CAST) { break; };
|
||||||
@@ -21830,7 +21848,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
emitsymname(c, nm);
|
emitsymname(c, nm);
|
||||||
emitline("(SB),\"");
|
emitline("(SB),\"");
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < 16) {
|
let szstr: i32 = primtypesize("str"): i32;
|
||||||
|
for (i < szstr) {
|
||||||
emitdatawbyte(0u8);
|
emitdatawbyte(0u8);
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
@@ -21838,7 +21857,7 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (sz == 24 && !issg) {
|
if (sz == tyslicesize(): i32 && !issg) {
|
||||||
// Slice: zero-init only (no slice-literal
|
// Slice: zero-init only (no slice-literal
|
||||||
// syntax to honour). Any rhs other than
|
// syntax to honour). Any rhs other than
|
||||||
// `nil` is skipped → undefined symbol at
|
// `nil` is skipped → undefined symbol at
|
||||||
@@ -21860,7 +21879,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
emitsymname(c, nm);
|
emitsymname(c, nm);
|
||||||
emitline("(SB),\"");
|
emitline("(SB),\"");
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < 24) {
|
let szsl: i32 = tyslicesize(): i32;
|
||||||
|
for (i < szsl) {
|
||||||
emitdatawbyte(0u8);
|
emitdatawbyte(0u8);
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -965,7 +965,7 @@ fn letemitsize(c: *cgen, d: *node) i32 = {
|
|||||||
let t: *node = d.lhs;
|
let t: *node = d.lhs;
|
||||||
for (t != nil) {
|
for (t != nil) {
|
||||||
if (t.kind == nkind.N_TPTR) { return 8; };
|
if (t.kind == nkind.N_TPTR) { return 8; };
|
||||||
if (t.kind == nkind.N_TSLICE) { return 24; };
|
if (t.kind == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (t.kind == nkind.N_TARRAY) {
|
if (t.kind == nkind.N_TARRAY) {
|
||||||
let lenn: *node = t.rhs;
|
let lenn: *node = t.rhs;
|
||||||
let elemn: *node = t.lhs;
|
let elemn: *node = t.lhs;
|
||||||
@@ -987,7 +987,7 @@ fn letemitsize(c: *cgen, d: *node) i32 = {
|
|||||||
if (letscalarprim(nm)) { return 8; };
|
if (letscalarprim(nm)) { return 8; };
|
||||||
let fsz: i32 = letfloatprim(nm);
|
let fsz: i32 = letfloatprim(nm);
|
||||||
if (fsz > 0) { return fsz; };
|
if (fsz > 0) { return fsz; };
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let si: *structinfo = structlookup(c, nm);
|
let si: *structinfo = structlookup(c, nm);
|
||||||
if (si != nil) { return si.totsize; };
|
if (si != nil) { return si.totsize; };
|
||||||
let next: *node = aliaslookup(c, nm);
|
let next: *node = aliaslookup(c, nm);
|
||||||
@@ -1313,7 +1313,7 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
emitline("\"\n");
|
emitline("\"\n");
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (sz == 16 && !issg) {
|
if (sz == primtypesize("str"): i32 && !issg) {
|
||||||
let r: *node = d.rhs;
|
let r: *node = d.rhs;
|
||||||
for (r != nil) {
|
for (r != nil) {
|
||||||
if (r.kind != nkind.N_CAST) { break; };
|
if (r.kind != nkind.N_CAST) { break; };
|
||||||
@@ -1369,7 +1369,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
emitsymname(c, nm);
|
emitsymname(c, nm);
|
||||||
emitline("(SB),\"");
|
emitline("(SB),\"");
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < 16) {
|
let szstr: i32 = primtypesize("str"): i32;
|
||||||
|
for (i < szstr) {
|
||||||
emitdatawbyte(0u8);
|
emitdatawbyte(0u8);
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
@@ -1377,7 +1378,7 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (sz == 24 && !issg) {
|
if (sz == tyslicesize(): i32 && !issg) {
|
||||||
// Slice: zero-init only (no slice-literal
|
// Slice: zero-init only (no slice-literal
|
||||||
// syntax to honour). Any rhs other than
|
// syntax to honour). Any rhs other than
|
||||||
// `nil` is skipped → undefined symbol at
|
// `nil` is skipped → undefined symbol at
|
||||||
@@ -1399,7 +1400,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
emitsymname(c, nm);
|
emitsymname(c, nm);
|
||||||
emitline("(SB),\"");
|
emitline("(SB),\"");
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < 24) {
|
let szsl: i32 = tyslicesize(): i32;
|
||||||
|
for (i < szsl) {
|
||||||
emitdatawbyte(0u8);
|
emitdatawbyte(0u8);
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
if (p.op == tkind.TK_ELLIPSIS) {
|
if (p.op == tkind.TK_ELLIPSIS) {
|
||||||
let tn: *node = slicewrap(c, p.lhs);
|
let tn: *node = slicewrap(c, p.lhs);
|
||||||
if (idx + 3 <= 6) {
|
if (idx + 3 <= 6) {
|
||||||
let off: i32 = localadd(c, nm, 24, tn);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, tn);
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
emitline(argregname(idx));
|
emitline(argregname(idx));
|
||||||
emitline(", ");
|
emitline(", ");
|
||||||
@@ -70,7 +70,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
// at the ABI boundary (the call site synthesises a
|
// at the ABI boundary (the call site synthesises a
|
||||||
// 24B descriptor and pushes ptr/len/cap), so this
|
// 24B descriptor and pushes ptr/len/cap), so this
|
||||||
// mirrors the slice branch at cgendecl.ww:518.
|
// mirrors the slice branch at cgendecl.ww:518.
|
||||||
let off: i32 = localadd(c, nm, 24, tn);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, tn);
|
||||||
let regs_left: i32 = 6 - idx;
|
let regs_left: i32 = 6 - idx;
|
||||||
let w: i32 = 0;
|
let w: i32 = 0;
|
||||||
for (w < regs_left) {
|
for (w < regs_left) {
|
||||||
@@ -170,7 +170,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
};};
|
};};
|
||||||
} else { if (isslicetype(c, p.lhs)) {
|
} else { if (isslicetype(c, p.lhs)) {
|
||||||
if (idx + 3 <= 6) {
|
if (idx + 3 <= 6) {
|
||||||
let off: i32 = localadd(c, nm, 24, p.lhs);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, p.lhs);
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
emitline(argregname(idx));
|
emitline(argregname(idx));
|
||||||
emitline(", ");
|
emitline(", ");
|
||||||
@@ -194,7 +194,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
// 440-469. Caller's pushargsrev greedy-fills the
|
// 440-469. Caller's pushargsrev greedy-fills the
|
||||||
// remaining argregs (ptr,len,cap order), the tail
|
// remaining argregs (ptr,len,cap order), the tail
|
||||||
// spills to +16+stkcursor*8(BP).
|
// spills to +16+stkcursor*8(BP).
|
||||||
let off: i32 = localadd(c, nm, 24, p.lhs);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, p.lhs);
|
||||||
let regs_left: i32 = 6 - idx;
|
let regs_left: i32 = 6 - idx;
|
||||||
let w: i32 = 0;
|
let w: i32 = 0;
|
||||||
for (w < regs_left) {
|
for (w < regs_left) {
|
||||||
|
|||||||
@@ -759,7 +759,7 @@ fn cglet(c: *cgen, n: *node) void = {
|
|||||||
if (elemn != nil) {
|
if (elemn != nil) {
|
||||||
if (elemn.kind == nkind.N_TNAME) {
|
if (elemn.kind == nkind.N_TNAME) {
|
||||||
if (streq(elemn.str, "str")) {
|
if (streq(elemn.str, "str")) {
|
||||||
esz = 16;
|
esz = primtypesize("str"): i32;
|
||||||
isstrel = true;
|
isstrel = true;
|
||||||
} else {
|
} else {
|
||||||
let ps: i32 = primsize(elemn.str);
|
let ps: i32 = primsize(elemn.str);
|
||||||
@@ -1244,8 +1244,8 @@ fn cgmlet(c: *cgen, n: *node) void = {
|
|||||||
if (s0_is_str != s1_is_str) {
|
if (s0_is_str != s1_is_str) {
|
||||||
let sz0: i32 = 8;
|
let sz0: i32 = 8;
|
||||||
let sz1: i32 = 8;
|
let sz1: i32 = 8;
|
||||||
if (s0_is_str) { sz0 = 16; };
|
if (s0_is_str) { sz0 = primtypesize("str"): i32; };
|
||||||
if (s1_is_str) { sz1 = 16; };
|
if (s1_is_str) { sz1 = primtypesize("str"): i32; };
|
||||||
let off0: i32 = localadd(c, l0.str, sz0, t0);
|
let off0: i32 = localadd(c, l0.str, sz0, t0);
|
||||||
let off1: i32 = localadd(c, l1.str, sz1, t1);
|
let off1: i32 = localadd(c, l1.str, sz1, t1);
|
||||||
if (s0_is_str) {
|
if (s0_is_str) {
|
||||||
@@ -1302,7 +1302,7 @@ fn paramfieldsize(t: *node) i32 = {
|
|||||||
if (k == nkind.N_TCHAN) { return 8; };
|
if (k == nkind.N_TCHAN) { return 8; };
|
||||||
if (k == nkind.N_TNAME) {
|
if (k == nkind.N_TNAME) {
|
||||||
let nm: str = t.str;
|
let nm: str = t.str;
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1196,7 +1196,7 @@ fn indexbaseesz(c: *cgen, base: *node) i32 = {
|
|||||||
let elem: *node = ft.lhs;
|
let elem: *node = ft.lhs;
|
||||||
if (elem != nil) {
|
if (elem != nil) {
|
||||||
if (elem.kind == nkind.N_TNAME) {
|
if (elem.kind == nkind.N_TNAME) {
|
||||||
if (streq(elem.str, "str")) { return 16; };
|
if (streq(elem.str, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(elem.str);
|
let ps: i32 = primsize(elem.str);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
// Pointer to named struct: indexing
|
// Pointer to named struct: indexing
|
||||||
@@ -1304,11 +1304,11 @@ fn elemsizeof(t: *node) i32 = {
|
|||||||
// `*[]T`: stride is the slice header (24B). Hare-faithful — a
|
// `*[]T`: stride is the slice header (24B). Hare-faithful — a
|
||||||
// pointer-to-slice is a 1D array of slices, not of T. Mirrors the
|
// pointer-to-slice is a 1D array of slices, not of T. Mirrors the
|
||||||
// cstage check.c default `*U → U` path for U=[]T (slice element).
|
// cstage check.c default `*U → U` path for U=[]T (slice element).
|
||||||
if (elem.kind == nkind.N_TSLICE) { return 24; };
|
if (elem.kind == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (elem.kind == nkind.N_TNAME) {
|
if (elem.kind == nkind.N_TNAME) {
|
||||||
let nm: str = elem.str;
|
let nm: str = elem.str;
|
||||||
// str element is 16B (ptr+len). primsize returns 0 for it.
|
// str element is 16B (ptr+len). primsize returns 0 for it.
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
};
|
};
|
||||||
@@ -1903,7 +1903,7 @@ export fn letslotsize(c: *cgen, n: *node) i32 = {
|
|||||||
// (ptr+len) — primsize returns 0 for
|
// (ptr+len) — primsize returns 0 for
|
||||||
// it, so it'd slot 8B without this.
|
// it, so it'd slot 8B without this.
|
||||||
if (streq(elemn.str, "str")) {
|
if (streq(elemn.str, "str")) {
|
||||||
esz = 16;
|
esz = primtypesize("str"): i32;
|
||||||
} else {
|
} else {
|
||||||
let ps: i32 = primsize(elemn.str);
|
let ps: i32 = primsize(elemn.str);
|
||||||
if (ps > 0) { esz = ps; };
|
if (ps > 0) { esz = ps; };
|
||||||
@@ -1952,7 +1952,7 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
|||||||
if (k == nkind.N_TPTR) { return 8; };
|
if (k == nkind.N_TPTR) { return 8; };
|
||||||
if (k == nkind.N_TFN) { return 8; };
|
if (k == nkind.N_TFN) { return 8; };
|
||||||
if (k == nkind.N_TCHAN) { return 8; };
|
if (k == nkind.N_TCHAN) { return 8; };
|
||||||
if (k == nkind.N_TSLICE) { return 24; };
|
if (k == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (k == nkind.N_TTUPLE) {
|
if (k == nkind.N_TTUPLE) {
|
||||||
// Sum element sizes. Mirrors C cgen which uses raw type
|
// Sum element sizes. Mirrors C cgen which uses raw type
|
||||||
// sizes; padding to 8 happens inside slotsize for primitives,
|
// sizes; padding to 8 happens inside slotsize for primitives,
|
||||||
@@ -1992,7 +1992,7 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
|||||||
// slot+8 picking up the callee's stale-DX. Bypassing primsize's
|
// slot+8 picking up the callee's stale-DX. Bypassing primsize's
|
||||||
// `> 0` guard keeps the rest of the prim-pad-to-8 contract intact.
|
// `> 0` guard keeps the rest of the prim-pad-to-8 contract intact.
|
||||||
if (streq(nm, "void")) { return 0; };
|
if (streq(nm, "void")) { return 0; };
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) {
|
if (ps > 0) {
|
||||||
// Pad to 8 for stack slots — matches C cgen which spills
|
// Pad to 8 for stack slots — matches C cgen which spills
|
||||||
@@ -2033,7 +2033,7 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
|||||||
// explicit case a `[N]str` would slot 8B/elem,
|
// explicit case a `[N]str` would slot 8B/elem,
|
||||||
// collapsing the per-element stride and losing
|
// collapsing the per-element stride and losing
|
||||||
// every .len half.
|
// every .len half.
|
||||||
if (streq(en, "str")) { esz = 16; };
|
if (streq(en, "str")) { esz = primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(en);
|
let ps: i32 = primsize(en);
|
||||||
if (esz == 8) { if (ps > 0) { esz = ps; }
|
if (esz == 8) { if (ps > 0) { esz = ps; }
|
||||||
else {
|
else {
|
||||||
@@ -2091,7 +2091,7 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = {
|
|||||||
if (k == nkind.N_TTAGGED){ return slotsize(c, tnode); };
|
if (k == nkind.N_TTAGGED){ return slotsize(c, tnode); };
|
||||||
if (k == nkind.N_TNAME) {
|
if (k == nkind.N_TNAME) {
|
||||||
let nm: str = tnode.str;
|
let nm: str = tnode.str;
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
let si: *structinfo = structlookup(c, nm);
|
let si: *structinfo = structlookup(c, nm);
|
||||||
@@ -2118,7 +2118,7 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = {
|
|||||||
return 8;
|
return 8;
|
||||||
};
|
};
|
||||||
if (k == nkind.N_TPTR) { return 8; };
|
if (k == nkind.N_TPTR) { return 8; };
|
||||||
if (k == nkind.N_TSLICE) { return 24; };
|
if (k == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (k == nkind.N_TARRAY) {
|
if (k == nkind.N_TARRAY) {
|
||||||
// Same shape as slotsize's TARRAY branch.
|
// Same shape as slotsize's TARRAY branch.
|
||||||
let lenn: *node = tnode.rhs;
|
let lenn: *node = tnode.rhs;
|
||||||
|
|||||||
@@ -618,6 +618,29 @@ fn mktname(c: *checker, nm: str) *node = {
|
|||||||
return n;
|
return n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #43: SSoT for primitive type byte sizes. astsize's N_TNAME-primitive
|
||||||
|
// arm and every wwstage cgen size walker (slotsize/fieldsize/letemit-
|
||||||
|
// size/elemsizeof/paramfieldsize) consult this table so a future
|
||||||
|
// ty_str.size bump (#1) lands in one place. Returns -1 for non-prim
|
||||||
|
// names; callers fall back to alias/struct/enum lookup. Cstage's
|
||||||
|
// equivalent SSoT is cmd/wcc/type.c:46-79 (ty_void/ty_bool/.../ty_str).
|
||||||
|
fn primtypesize(nm: str) i64 = {
|
||||||
|
if (streq(nm, "void")) { return 0i64; };
|
||||||
|
if (streq(nm, "bool")) { return 1i64; };
|
||||||
|
if (streq(nm, "i8") || streq(nm, "u8")) { return 1i64; };
|
||||||
|
if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; };
|
||||||
|
if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; };
|
||||||
|
if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64")) { return 8i64; };
|
||||||
|
if (streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr")) { return 8i64; };
|
||||||
|
if (streq(nm, "str")) { return 16i64; };
|
||||||
|
return -1i64;
|
||||||
|
};
|
||||||
|
|
||||||
|
// #43: SSoT for slice header size (ptr+len+cap = 24B today). Mirrors
|
||||||
|
// cstage cmd/wcc/type.c:103 (ty_slice->size = 24). Bumping a slice's
|
||||||
|
// header layout in #34 touches only this constant.
|
||||||
|
fn tyslicesize() i64 = { return 24i64; };
|
||||||
|
|
||||||
// #42: AST-level layout helpers for the size(T)/align(T)/offset(e.f)
|
// #42: AST-level layout helpers for the size(T)/align(T)/offset(e.f)
|
||||||
// fold. Mirror cstage resolve_type's size/align computation
|
// fold. Mirror cstage resolve_type's size/align computation
|
||||||
// (cmd/wcc/check.c:286-528) on AST nodes — wwstage check.ww never
|
// (cmd/wcc/check.c:286-528) on AST nodes — wwstage check.ww never
|
||||||
@@ -679,7 +702,7 @@ fn astsize(c: *checker, t: *node) i64 = {
|
|||||||
let k: nkind = t.kind;
|
let k: nkind = t.kind;
|
||||||
if (k == nkind.N_TBANG) { return astsize(c, t.lhs); };
|
if (k == nkind.N_TBANG) { return astsize(c, t.lhs); };
|
||||||
if (k == nkind.N_TPTR) { return 8i64; };
|
if (k == nkind.N_TPTR) { return 8i64; };
|
||||||
if (k == nkind.N_TSLICE) { return 24i64; };
|
if (k == nkind.N_TSLICE) { return tyslicesize(); };
|
||||||
if (k == nkind.N_TCHAN) { return 8i64; };
|
if (k == nkind.N_TCHAN) { return 8i64; };
|
||||||
if (k == nkind.N_TFN) { return 8i64; };
|
if (k == nkind.N_TFN) { return 8i64; };
|
||||||
if (k == nkind.N_TARRAY) {
|
if (k == nkind.N_TARRAY) {
|
||||||
@@ -731,13 +754,8 @@ fn astsize(c: *checker, t: *node) i64 = {
|
|||||||
};
|
};
|
||||||
if (k == nkind.N_TNAME) {
|
if (k == nkind.N_TNAME) {
|
||||||
let nm: str = t.str;
|
let nm: str = t.str;
|
||||||
if (streq(nm, "void")) { return 0i64; };
|
let ps: i64 = primtypesize(nm);
|
||||||
if (streq(nm, "bool")) { return 1i64; };
|
if (ps >= 0i64) { return ps; };
|
||||||
if (streq(nm, "i8") || streq(nm, "u8")) { return 1i64; };
|
|
||||||
if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; };
|
|
||||||
if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; };
|
|
||||||
if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64") || streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr")) { return 8i64; };
|
|
||||||
if (streq(nm, "str")) { return 16i64; };
|
|
||||||
let resolved: *node = resolvealias(c, t);
|
let resolved: *node = resolvealias(c, t);
|
||||||
if (resolved != nil && resolved != t) {
|
if (resolved != nil && resolved != t) {
|
||||||
return astsize(c, resolved);
|
return astsize(c, resolved);
|
||||||
|
|||||||
@@ -1996,7 +1996,7 @@ export fn freeall(s: []str) void = {
|
|||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
if (s.cap > 0) {
|
if (s.cap > 0) {
|
||||||
os.free(s.ptr: *void, (s.cap: u64) * 16u64);
|
os.free(s.ptr: *void, (s.cap: u64) * size(str): u64);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2599,7 +2599,7 @@ export fn remaining_tokens(s: *tokenizer) str = {
|
|||||||
fn appendstr(slice: *[]str, item: str) void = {
|
fn appendstr(slice: *[]str, item: str) void = {
|
||||||
let newlen: i32 = slice.len + 1;
|
let newlen: i32 = slice.len + 1;
|
||||||
slice.len = newlen;
|
slice.len = newlen;
|
||||||
rtensure(slice: *void, 16u64);
|
rtensure(slice: *void, size(str): u64);
|
||||||
let dst: *str = &slice.ptr[newlen - 1];
|
let dst: *str = &slice.ptr[newlen - 1];
|
||||||
dst.ptr = item.ptr;
|
dst.ptr = item.ptr;
|
||||||
dst.len = item.len;
|
dst.len = item.len;
|
||||||
@@ -7612,6 +7612,29 @@ fn mktname(c: *checker, nm: str) *node = {
|
|||||||
return n;
|
return n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #43: SSoT for primitive type byte sizes. astsize's N_TNAME-primitive
|
||||||
|
// arm and every wwstage cgen size walker (slotsize/fieldsize/letemit-
|
||||||
|
// size/elemsizeof/paramfieldsize) consult this table so a future
|
||||||
|
// ty_str.size bump (#1) lands in one place. Returns -1 for non-prim
|
||||||
|
// names; callers fall back to alias/struct/enum lookup. Cstage's
|
||||||
|
// equivalent SSoT is cmd/wcc/type.c:46-79 (ty_void/ty_bool/.../ty_str).
|
||||||
|
fn primtypesize(nm: str) i64 = {
|
||||||
|
if (streq(nm, "void")) { return 0i64; };
|
||||||
|
if (streq(nm, "bool")) { return 1i64; };
|
||||||
|
if (streq(nm, "i8") || streq(nm, "u8")) { return 1i64; };
|
||||||
|
if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; };
|
||||||
|
if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; };
|
||||||
|
if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64")) { return 8i64; };
|
||||||
|
if (streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr")) { return 8i64; };
|
||||||
|
if (streq(nm, "str")) { return 16i64; };
|
||||||
|
return -1i64;
|
||||||
|
};
|
||||||
|
|
||||||
|
// #43: SSoT for slice header size (ptr+len+cap = 24B today). Mirrors
|
||||||
|
// cstage cmd/wcc/type.c:103 (ty_slice->size = 24). Bumping a slice's
|
||||||
|
// header layout in #34 touches only this constant.
|
||||||
|
fn tyslicesize() i64 = { return 24i64; };
|
||||||
|
|
||||||
// #42: AST-level layout helpers for the size(T)/align(T)/offset(e.f)
|
// #42: AST-level layout helpers for the size(T)/align(T)/offset(e.f)
|
||||||
// fold. Mirror cstage resolve_type's size/align computation
|
// fold. Mirror cstage resolve_type's size/align computation
|
||||||
// (cmd/wcc/check.c:286-528) on AST nodes — wwstage check.ww never
|
// (cmd/wcc/check.c:286-528) on AST nodes — wwstage check.ww never
|
||||||
@@ -7673,7 +7696,7 @@ fn astsize(c: *checker, t: *node) i64 = {
|
|||||||
let k: nkind = t.kind;
|
let k: nkind = t.kind;
|
||||||
if (k == nkind.N_TBANG) { return astsize(c, t.lhs); };
|
if (k == nkind.N_TBANG) { return astsize(c, t.lhs); };
|
||||||
if (k == nkind.N_TPTR) { return 8i64; };
|
if (k == nkind.N_TPTR) { return 8i64; };
|
||||||
if (k == nkind.N_TSLICE) { return 24i64; };
|
if (k == nkind.N_TSLICE) { return tyslicesize(); };
|
||||||
if (k == nkind.N_TCHAN) { return 8i64; };
|
if (k == nkind.N_TCHAN) { return 8i64; };
|
||||||
if (k == nkind.N_TFN) { return 8i64; };
|
if (k == nkind.N_TFN) { return 8i64; };
|
||||||
if (k == nkind.N_TARRAY) {
|
if (k == nkind.N_TARRAY) {
|
||||||
@@ -7725,13 +7748,8 @@ fn astsize(c: *checker, t: *node) i64 = {
|
|||||||
};
|
};
|
||||||
if (k == nkind.N_TNAME) {
|
if (k == nkind.N_TNAME) {
|
||||||
let nm: str = t.str;
|
let nm: str = t.str;
|
||||||
if (streq(nm, "void")) { return 0i64; };
|
let ps: i64 = primtypesize(nm);
|
||||||
if (streq(nm, "bool")) { return 1i64; };
|
if (ps >= 0i64) { return ps; };
|
||||||
if (streq(nm, "i8") || streq(nm, "u8")) { return 1i64; };
|
|
||||||
if (streq(nm, "i16") || streq(nm, "u16")) { return 2i64; };
|
|
||||||
if (streq(nm, "i32") || streq(nm, "u32") || streq(nm, "f32") || streq(nm, "rune")) { return 4i64; };
|
|
||||||
if (streq(nm, "i64") || streq(nm, "u64") || streq(nm, "f64") || streq(nm, "int") || streq(nm, "uint") || streq(nm, "uintptr")) { return 8i64; };
|
|
||||||
if (streq(nm, "str")) { return 16i64; };
|
|
||||||
let resolved: *node = resolvealias(c, t);
|
let resolved: *node = resolvealias(c, t);
|
||||||
if (resolved != nil && resolved != t) {
|
if (resolved != nil && resolved != t) {
|
||||||
return astsize(c, resolved);
|
return astsize(c, resolved);
|
||||||
@@ -9854,7 +9872,7 @@ fn indexbaseesz(c: *cgen, base: *node) i32 = {
|
|||||||
let elem: *node = ft.lhs;
|
let elem: *node = ft.lhs;
|
||||||
if (elem != nil) {
|
if (elem != nil) {
|
||||||
if (elem.kind == nkind.N_TNAME) {
|
if (elem.kind == nkind.N_TNAME) {
|
||||||
if (streq(elem.str, "str")) { return 16; };
|
if (streq(elem.str, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(elem.str);
|
let ps: i32 = primsize(elem.str);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
// Pointer to named struct: indexing
|
// Pointer to named struct: indexing
|
||||||
@@ -9962,11 +9980,11 @@ fn elemsizeof(t: *node) i32 = {
|
|||||||
// `*[]T`: stride is the slice header (24B). Hare-faithful — a
|
// `*[]T`: stride is the slice header (24B). Hare-faithful — a
|
||||||
// pointer-to-slice is a 1D array of slices, not of T. Mirrors the
|
// pointer-to-slice is a 1D array of slices, not of T. Mirrors the
|
||||||
// cstage check.c default `*U → U` path for U=[]T (slice element).
|
// cstage check.c default `*U → U` path for U=[]T (slice element).
|
||||||
if (elem.kind == nkind.N_TSLICE) { return 24; };
|
if (elem.kind == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (elem.kind == nkind.N_TNAME) {
|
if (elem.kind == nkind.N_TNAME) {
|
||||||
let nm: str = elem.str;
|
let nm: str = elem.str;
|
||||||
// str element is 16B (ptr+len). primsize returns 0 for it.
|
// str element is 16B (ptr+len). primsize returns 0 for it.
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
};
|
};
|
||||||
@@ -10561,7 +10579,7 @@ export fn letslotsize(c: *cgen, n: *node) i32 = {
|
|||||||
// (ptr+len) — primsize returns 0 for
|
// (ptr+len) — primsize returns 0 for
|
||||||
// it, so it'd slot 8B without this.
|
// it, so it'd slot 8B without this.
|
||||||
if (streq(elemn.str, "str")) {
|
if (streq(elemn.str, "str")) {
|
||||||
esz = 16;
|
esz = primtypesize("str"): i32;
|
||||||
} else {
|
} else {
|
||||||
let ps: i32 = primsize(elemn.str);
|
let ps: i32 = primsize(elemn.str);
|
||||||
if (ps > 0) { esz = ps; };
|
if (ps > 0) { esz = ps; };
|
||||||
@@ -10610,7 +10628,7 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
|||||||
if (k == nkind.N_TPTR) { return 8; };
|
if (k == nkind.N_TPTR) { return 8; };
|
||||||
if (k == nkind.N_TFN) { return 8; };
|
if (k == nkind.N_TFN) { return 8; };
|
||||||
if (k == nkind.N_TCHAN) { return 8; };
|
if (k == nkind.N_TCHAN) { return 8; };
|
||||||
if (k == nkind.N_TSLICE) { return 24; };
|
if (k == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (k == nkind.N_TTUPLE) {
|
if (k == nkind.N_TTUPLE) {
|
||||||
// Sum element sizes. Mirrors C cgen which uses raw type
|
// Sum element sizes. Mirrors C cgen which uses raw type
|
||||||
// sizes; padding to 8 happens inside slotsize for primitives,
|
// sizes; padding to 8 happens inside slotsize for primitives,
|
||||||
@@ -10650,7 +10668,7 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
|||||||
// slot+8 picking up the callee's stale-DX. Bypassing primsize's
|
// slot+8 picking up the callee's stale-DX. Bypassing primsize's
|
||||||
// `> 0` guard keeps the rest of the prim-pad-to-8 contract intact.
|
// `> 0` guard keeps the rest of the prim-pad-to-8 contract intact.
|
||||||
if (streq(nm, "void")) { return 0; };
|
if (streq(nm, "void")) { return 0; };
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) {
|
if (ps > 0) {
|
||||||
// Pad to 8 for stack slots — matches C cgen which spills
|
// Pad to 8 for stack slots — matches C cgen which spills
|
||||||
@@ -10691,7 +10709,7 @@ fn slotsize(c: *cgen, typn: *node) i32 = {
|
|||||||
// explicit case a `[N]str` would slot 8B/elem,
|
// explicit case a `[N]str` would slot 8B/elem,
|
||||||
// collapsing the per-element stride and losing
|
// collapsing the per-element stride and losing
|
||||||
// every .len half.
|
// every .len half.
|
||||||
if (streq(en, "str")) { esz = 16; };
|
if (streq(en, "str")) { esz = primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(en);
|
let ps: i32 = primsize(en);
|
||||||
if (esz == 8) { if (ps > 0) { esz = ps; }
|
if (esz == 8) { if (ps > 0) { esz = ps; }
|
||||||
else {
|
else {
|
||||||
@@ -10749,7 +10767,7 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = {
|
|||||||
if (k == nkind.N_TTAGGED){ return slotsize(c, tnode); };
|
if (k == nkind.N_TTAGGED){ return slotsize(c, tnode); };
|
||||||
if (k == nkind.N_TNAME) {
|
if (k == nkind.N_TNAME) {
|
||||||
let nm: str = tnode.str;
|
let nm: str = tnode.str;
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
let si: *structinfo = structlookup(c, nm);
|
let si: *structinfo = structlookup(c, nm);
|
||||||
@@ -10776,7 +10794,7 @@ fn fieldsize(c: *cgen, tnode: *node) i32 = {
|
|||||||
return 8;
|
return 8;
|
||||||
};
|
};
|
||||||
if (k == nkind.N_TPTR) { return 8; };
|
if (k == nkind.N_TPTR) { return 8; };
|
||||||
if (k == nkind.N_TSLICE) { return 24; };
|
if (k == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (k == nkind.N_TARRAY) {
|
if (k == nkind.N_TARRAY) {
|
||||||
// Same shape as slotsize's TARRAY branch.
|
// Same shape as slotsize's TARRAY branch.
|
||||||
let lenn: *node = tnode.rhs;
|
let lenn: *node = tnode.rhs;
|
||||||
@@ -19139,7 +19157,7 @@ fn cglet(c: *cgen, n: *node) void = {
|
|||||||
if (elemn != nil) {
|
if (elemn != nil) {
|
||||||
if (elemn.kind == nkind.N_TNAME) {
|
if (elemn.kind == nkind.N_TNAME) {
|
||||||
if (streq(elemn.str, "str")) {
|
if (streq(elemn.str, "str")) {
|
||||||
esz = 16;
|
esz = primtypesize("str"): i32;
|
||||||
isstrel = true;
|
isstrel = true;
|
||||||
} else {
|
} else {
|
||||||
let ps: i32 = primsize(elemn.str);
|
let ps: i32 = primsize(elemn.str);
|
||||||
@@ -19624,8 +19642,8 @@ fn cgmlet(c: *cgen, n: *node) void = {
|
|||||||
if (s0_is_str != s1_is_str) {
|
if (s0_is_str != s1_is_str) {
|
||||||
let sz0: i32 = 8;
|
let sz0: i32 = 8;
|
||||||
let sz1: i32 = 8;
|
let sz1: i32 = 8;
|
||||||
if (s0_is_str) { sz0 = 16; };
|
if (s0_is_str) { sz0 = primtypesize("str"): i32; };
|
||||||
if (s1_is_str) { sz1 = 16; };
|
if (s1_is_str) { sz1 = primtypesize("str"): i32; };
|
||||||
let off0: i32 = localadd(c, l0.str, sz0, t0);
|
let off0: i32 = localadd(c, l0.str, sz0, t0);
|
||||||
let off1: i32 = localadd(c, l1.str, sz1, t1);
|
let off1: i32 = localadd(c, l1.str, sz1, t1);
|
||||||
if (s0_is_str) {
|
if (s0_is_str) {
|
||||||
@@ -19682,7 +19700,7 @@ fn paramfieldsize(t: *node) i32 = {
|
|||||||
if (k == nkind.N_TCHAN) { return 8; };
|
if (k == nkind.N_TCHAN) { return 8; };
|
||||||
if (k == nkind.N_TNAME) {
|
if (k == nkind.N_TNAME) {
|
||||||
let nm: str = t.str;
|
let nm: str = t.str;
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let ps: i32 = primsize(nm);
|
let ps: i32 = primsize(nm);
|
||||||
if (ps > 0) { return ps; };
|
if (ps > 0) { return ps; };
|
||||||
};
|
};
|
||||||
@@ -20054,7 +20072,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
if (p.op == tkind.TK_ELLIPSIS) {
|
if (p.op == tkind.TK_ELLIPSIS) {
|
||||||
let tn: *node = slicewrap(c, p.lhs);
|
let tn: *node = slicewrap(c, p.lhs);
|
||||||
if (idx + 3 <= 6) {
|
if (idx + 3 <= 6) {
|
||||||
let off: i32 = localadd(c, nm, 24, tn);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, tn);
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
emitline(argregname(idx));
|
emitline(argregname(idx));
|
||||||
emitline(", ");
|
emitline(", ");
|
||||||
@@ -20078,7 +20096,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
// at the ABI boundary (the call site synthesises a
|
// at the ABI boundary (the call site synthesises a
|
||||||
// 24B descriptor and pushes ptr/len/cap), so this
|
// 24B descriptor and pushes ptr/len/cap), so this
|
||||||
// mirrors the slice branch at cgendecl.ww:518.
|
// mirrors the slice branch at cgendecl.ww:518.
|
||||||
let off: i32 = localadd(c, nm, 24, tn);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, tn);
|
||||||
let regs_left: i32 = 6 - idx;
|
let regs_left: i32 = 6 - idx;
|
||||||
let w: i32 = 0;
|
let w: i32 = 0;
|
||||||
for (w < regs_left) {
|
for (w < regs_left) {
|
||||||
@@ -20178,7 +20196,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
};};
|
};};
|
||||||
} else { if (isslicetype(c, p.lhs)) {
|
} else { if (isslicetype(c, p.lhs)) {
|
||||||
if (idx + 3 <= 6) {
|
if (idx + 3 <= 6) {
|
||||||
let off: i32 = localadd(c, nm, 24, p.lhs);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, p.lhs);
|
||||||
emitline("\tMOVQ\t");
|
emitline("\tMOVQ\t");
|
||||||
emitline(argregname(idx));
|
emitline(argregname(idx));
|
||||||
emitline(", ");
|
emitline(", ");
|
||||||
@@ -20202,7 +20220,7 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
|||||||
// 440-469. Caller's pushargsrev greedy-fills the
|
// 440-469. Caller's pushargsrev greedy-fills the
|
||||||
// remaining argregs (ptr,len,cap order), the tail
|
// remaining argregs (ptr,len,cap order), the tail
|
||||||
// spills to +16+stkcursor*8(BP).
|
// spills to +16+stkcursor*8(BP).
|
||||||
let off: i32 = localadd(c, nm, 24, p.lhs);
|
let off: i32 = localadd(c, nm, tyslicesize(): i32, p.lhs);
|
||||||
let regs_left: i32 = 6 - idx;
|
let regs_left: i32 = 6 - idx;
|
||||||
let w: i32 = 0;
|
let w: i32 = 0;
|
||||||
for (w < regs_left) {
|
for (w < regs_left) {
|
||||||
@@ -21426,7 +21444,7 @@ fn letemitsize(c: *cgen, d: *node) i32 = {
|
|||||||
let t: *node = d.lhs;
|
let t: *node = d.lhs;
|
||||||
for (t != nil) {
|
for (t != nil) {
|
||||||
if (t.kind == nkind.N_TPTR) { return 8; };
|
if (t.kind == nkind.N_TPTR) { return 8; };
|
||||||
if (t.kind == nkind.N_TSLICE) { return 24; };
|
if (t.kind == nkind.N_TSLICE) { return tyslicesize(): i32; };
|
||||||
if (t.kind == nkind.N_TARRAY) {
|
if (t.kind == nkind.N_TARRAY) {
|
||||||
let lenn: *node = t.rhs;
|
let lenn: *node = t.rhs;
|
||||||
let elemn: *node = t.lhs;
|
let elemn: *node = t.lhs;
|
||||||
@@ -21448,7 +21466,7 @@ fn letemitsize(c: *cgen, d: *node) i32 = {
|
|||||||
if (letscalarprim(nm)) { return 8; };
|
if (letscalarprim(nm)) { return 8; };
|
||||||
let fsz: i32 = letfloatprim(nm);
|
let fsz: i32 = letfloatprim(nm);
|
||||||
if (fsz > 0) { return fsz; };
|
if (fsz > 0) { return fsz; };
|
||||||
if (streq(nm, "str")) { return 16; };
|
if (streq(nm, "str")) { return primtypesize("str"): i32; };
|
||||||
let si: *structinfo = structlookup(c, nm);
|
let si: *structinfo = structlookup(c, nm);
|
||||||
if (si != nil) { return si.totsize; };
|
if (si != nil) { return si.totsize; };
|
||||||
let next: *node = aliaslookup(c, nm);
|
let next: *node = aliaslookup(c, nm);
|
||||||
@@ -21774,7 +21792,7 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
emitline("\"\n");
|
emitline("\"\n");
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (sz == 16 && !issg) {
|
if (sz == primtypesize("str"): i32 && !issg) {
|
||||||
let r: *node = d.rhs;
|
let r: *node = d.rhs;
|
||||||
for (r != nil) {
|
for (r != nil) {
|
||||||
if (r.kind != nkind.N_CAST) { break; };
|
if (r.kind != nkind.N_CAST) { break; };
|
||||||
@@ -21830,7 +21848,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
emitsymname(c, nm);
|
emitsymname(c, nm);
|
||||||
emitline("(SB),\"");
|
emitline("(SB),\"");
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < 16) {
|
let szstr: i32 = primtypesize("str"): i32;
|
||||||
|
for (i < szstr) {
|
||||||
emitdatawbyte(0u8);
|
emitdatawbyte(0u8);
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
@@ -21838,7 +21857,7 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
if (sz == 24 && !issg) {
|
if (sz == tyslicesize(): i32 && !issg) {
|
||||||
// Slice: zero-init only (no slice-literal
|
// Slice: zero-init only (no slice-literal
|
||||||
// syntax to honour). Any rhs other than
|
// syntax to honour). Any rhs other than
|
||||||
// `nil` is skipped → undefined symbol at
|
// `nil` is skipped → undefined symbol at
|
||||||
@@ -21860,7 +21879,8 @@ fn emitletdataw(c: *cgen, file: *node) void = {
|
|||||||
emitsymname(c, nm);
|
emitsymname(c, nm);
|
||||||
emitline("(SB),\"");
|
emitline("(SB),\"");
|
||||||
let i: i32 = 0;
|
let i: i32 = 0;
|
||||||
for (i < 24) {
|
let szsl: i32 = tyslicesize(): i32;
|
||||||
|
for (i < szsl) {
|
||||||
emitdatawbyte(0u8);
|
emitdatawbyte(0u8);
|
||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1887,7 +1887,7 @@ export fn freeall(s: []str) void = {
|
|||||||
i += 1;
|
i += 1;
|
||||||
};
|
};
|
||||||
if (s.cap > 0) {
|
if (s.cap > 0) {
|
||||||
os.free(s.ptr: *void, (s.cap: u64) * 16u64);
|
os.free(s.ptr: *void, (s.cap: u64) * size(str): u64);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2490,7 +2490,7 @@ export fn remaining_tokens(s: *tokenizer) str = {
|
|||||||
fn appendstr(slice: *[]str, item: str) void = {
|
fn appendstr(slice: *[]str, item: str) void = {
|
||||||
let newlen: i32 = slice.len + 1;
|
let newlen: i32 = slice.len + 1;
|
||||||
slice.len = newlen;
|
slice.len = newlen;
|
||||||
rtensure(slice: *void, 16u64);
|
rtensure(slice: *void, size(str): u64);
|
||||||
let dst: *str = &slice.ptr[newlen - 1];
|
let dst: *str = &slice.ptr[newlen - 1];
|
||||||
dst.ptr = item.ptr;
|
dst.ptr = item.ptr;
|
||||||
dst.len = item.len;
|
dst.len = item.len;
|
||||||
|
|||||||
Reference in New Issue
Block a user