From c90080d97f1f923973a38690c0674648b6cfc917 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Thu, 4 Jun 2026 02:30:22 +0900 Subject: [PATCH] selfhost/test: regen smoke.combined.ww for the lib append-workaround collapse (#34 review) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The follow-up collapse (70fa9e2) regenerated the 5 main.combined.ww but missed the tracked smoke amalgamation, which also embeds lib/shlex, lib/bytes and lib/strings — caught by the combined_ww_fresh gate. --- selfhost/test/smoke.combined.ww | 60 ++++++--------------------------- 1 file changed, 10 insertions(+), 50 deletions(-) diff --git a/selfhost/test/smoke.combined.ww b/selfhost/test/smoke.combined.ww index 56a51e00..02b7e464 100644 --- a/selfhost/test/smoke.combined.ww +++ b/selfhost/test/smoke.combined.ww @@ -2738,28 +2738,6 @@ export fn remaining_tokens(s: *tokenizer) []u8 = { return s.in; }; -// rt_ensure is the runtime slice-growth helper invoked by the -// `append(s, v)` builtin. We bind it directly because the builtin's -// expansion stores only 8 bytes of the new element (cgen emits a -// single MOVQ), losing the .len/.cap fields of a []u8 element (24B). -// Mirrors the same workaround in lib/shlex.shlex (appendstr, 16B) and -// lib/getopt.getopt (appendoption, 24B); collapses in one go when the -// append builtin learns to store the full element width. -@symbol("rt_ensure") fn rtensure(s: *void, membsz: u64) void; - -// appendslice — grow `*slice` by one and store `item` (24B). Mirror -// of [[shlex.appendstr]] / [[getopt.appendoption]]. Bypasses the -// `append` builtin's first-8B-only-store gap for a slice-element. -fn appendslice(slice: *[][]u8, item: []u8) void = { - let newlen: i32 = slice.len + 1; - slice.len = newlen; - rtensure(slice: *void, 24u64); - let dst: *[]u8 = &slice.ptr[newlen - 1]; - dst.ptr = item.ptr; - dst.len = item.len; - dst.cap = item.cap; -}; - // splitn — split `in` on any byte in `delim`, returning up to `n` // tokens via forward iteration. The trailing slot (when more than // `n - 1` tokens exist) holds the unconsumed remainder. @@ -2784,7 +2762,7 @@ export fn splitn(in: []u8, delim: []u8, n: i32) [][]u8 = { let i: i32 = 0; for (i < n - 1) { match (next_token(&tok)) { - case let s: []u8 => { appendslice(&toks, s); }; + case let s: []u8 => { append(toks, s); }; case done => { return toks; }; }; i += 1; @@ -2793,7 +2771,7 @@ export fn splitn(in: []u8, delim: []u8, n: i32) [][]u8 = { case done => void; case let pk: []u8 => { let r: []u8 = remaining_tokens(&tok); - appendslice(&toks, r); + append(toks, r); }; }; return toks; @@ -2822,7 +2800,7 @@ export fn rsplitn(in: []u8, delim: []u8, n: i32) [][]u8 = { let i: i32 = 0; for (i < n - 1) { match (next_token(&tok)) { - case let s: []u8 => { appendslice(&toks, s); }; + case let s: []u8 => { append(toks, s); }; case done => { return toks; }; }; i += 1; @@ -2831,7 +2809,7 @@ export fn rsplitn(in: []u8, delim: []u8, n: i32) [][]u8 = { case done => void; case let pk: []u8 => { let r: []u8 = remaining_tokens(&tok); - appendslice(&toks, r); + append(toks, r); }; }; @@ -3472,7 +3450,7 @@ export fn dup(s: str) str = { // so the only nomem propagation point is the initial slice alloc. // With no inner failure path, the rollback is structurally a no-op // and is omitted; it returns once dup graduates to `(str | nomem)` -// (#46). The pre-allocated slice has `cap == s.len`, so appendstr's +// (#46). The pre-allocated slice has `cap == s.len`, so append's // rt_ensure call never reaches the grow branch. // // Empty input bypasses the alloc: rt_malloc(0) is an mmap of 0 bytes @@ -3491,7 +3469,7 @@ export fn dupall(s: []str) ([]str | nomem) = { let newsl: []str = alloc([], s.len)?; let i: i32 = 0; for (i < s.len) { - appendstr(&newsl, dup(s[i])); + append(newsl, dup(s[i])); i += 1; }; return newsl; @@ -4117,24 +4095,6 @@ export fn rcut(in: str, delim: str) (str, str) = { return (frombytes(a), frombytes(b)); }; -// rt_ensure is the runtime slice-growth helper invoked by the -// `append(s, v)` builtin. Direct bind for the same reason as -// lib/shlex.shlex (appendstr, 16B): the builtin's expansion stores -// only 8B of the new element, losing the `.len` half of a `str`. -@symbol("rt_ensure") fn rtensure(s: *void, membsz: u64) void; - -// appendstr — grow `*slice` by one and store `item` (16B). Mirror of -// lib/shlex.shlex appendstr. Collapses when the append builtin learns -// to store the full element width. -fn appendstr(slice: *[]str, item: str) void = { - let newlen: i32 = slice.len + 1; - slice.len = newlen; - rtensure(slice: *void, size(str): u64); - let dst: *str = &slice.ptr[newlen - 1]; - dst.ptr = item.ptr; - dst.len = item.len; -}; - // splitn — split `in` on any byte in `delim`, returning up to `n` // tokens via forward iteration. The trailing slot (when more than // `n - 1` tokens exist) holds the unconsumed remainder. Strings @@ -4157,7 +4117,7 @@ export fn splitn(in: str, delim: str, n: i32) []str = { let i: i32 = 0; for (i < n - 1) { match (next_token(&tok)) { - case let s: str => { appendstr(&toks, s); }; + case let s: str => { append(toks, s); }; case bytes.done => { return toks; }; }; i += 1; @@ -4166,7 +4126,7 @@ export fn splitn(in: str, delim: str, n: i32) []str = { case bytes.done => void; case let pk: str => { let r: str = remaining_tokens(&tok); - appendstr(&toks, r); + append(toks, r); }; }; return toks; @@ -4191,7 +4151,7 @@ export fn rsplitn(in: str, delim: str, n: i32) []str = { let i: i32 = 0; for (i < n - 1) { match (next_token(&tok)) { - case let s: str => { appendstr(&toks, s); }; + case let s: str => { append(toks, s); }; case bytes.done => { return toks; }; }; i += 1; @@ -4200,7 +4160,7 @@ export fn rsplitn(in: str, delim: str, n: i32) []str = { case bytes.done => void; case let pk: str => { let r: str = remaining_tokens(&tok); - appendstr(&toks, r); + append(toks, r); }; };