The #94 Option-C vstream surface was left incomplete and structurally
divergent from Hare: constructors heap-allocated and returned (X | nomem)
or used out-params instead of Hare's by-value stack ownership; memio lacked
reset/buffer/borrowedread; bufio's scanner was never ported to the vtable.
This is the additive half of the eFinal collapse — OLD surface stays fully
live; the destructive FLIP (delete OLD + drop _v + repoint) is the next
commit.
Reshape all constructors to VALUE-RETURN (field-by-field sret; the heap +
nomem was an unnecessary crutch — wide slice-bearing struct return-by-value
is byte-id-proven, cf 925_sret_struct_return_run). memio fixed/dynamic/
dynamicfrom, bufio init, log new now return the struct by value; the nomem
is gone with the alloc that forced it.
memio: unify the per-flavour ctx structs onto one `stream` (vt at offset 0);
collapse fixed_string + dynamic_string into a single string() over the common
header (bare-str return is the ratified rule-9 frombytes carve-out, cited at
the site per ref/hare/memio/stream.ha:81); port reset/buffer/borrowedread as
single fns over the header.
bufio: collapse the EXISTING scanner subset (newscannerbuf/scanbyte/scanbytes/
scanline/finish + setflush/flush/unread/isbuffered) onto the vtable, with src
now io.vstream so reads go through io.st_read. The Hare scanner functions ww
never implemented (scanrune/scanstring-arbitrary-delim/readtok/readline/
auto-grow newscanner) are out of scope and deferred to #217 — eFinal is a
collapse, not a feature expansion.
Keep the explicit (&fn): *io.T casts on vtable-slot stores (cgen-neutral;
avoids the #214 (X|void) over-acceptance surface; dropping the casts is a
deferred #206 payoff gated on #214).
Self-gate: 776 (memio) 18/18 and 778 (bufio) 27/27, every row carrying a
cs.s == ww.s byte-id check — bufio/fmt/log are not compiler-embedded, so
these rows are their only byte-id coverage. 779/781 stay STAGE_CS-only
pending #209. Regen w6c+wwdump combined.ww (io+memio are the embedded
modules).
Last per-caller migration before fold-eFinal (#50). Adds the 10 _v
variants of OLD log.ww's surface (new_v / lprintln_v / println_v /
lprintfln_v / printfln_v / lfatal_v / fatal_v / lfatalf_v / fatalf_v /
setlogger_v) alongside a vlogger vtable + vstdlogger over io.vstream.
Default sink is a module-static stderrsink_ctx_g with vt FIRST field for
the intrusive vstream cast and fd=2 — only scalars/ptrs beyond vt per
ken's mandate, no nested aggregates that would bite #18, no f32 per
#165b. Zero-init at link time per #129 A.2/A.3 SSoT; ensureinit_v wires
vt.reader / vt.writer / fd lazily on first dispatch (mirror of OLD
ensureinit at log.ww:122 + lib/temp's rnginit pattern).
OLD lib/log/log.ww UNCHANGED. fold-eFinal (#50) atomically retires the
OLD logger / stdlogger / globals + the pre-vtable stderrsink and drops
the `_v` suffix wholesale to match Hare's bare names.
Two `export` bumps on lib/fmt/vstream.ww (vfprint, vfprintf) so log's
stdprintln_v / stdprintfln_v dispatch through the existing vstream-side
formatters; additive exposure, eFinal collapses fprint over the unified
surface.
Bootstrap-embed check: log is NOT in any selfhost/cmd/*/main.combined.ww
(grep `package log\|import log` returns empty pre-impl). The fmt
vstream.ww changes are also non-embedded. 990-997 byte-id gates stay
green by virtue of log being test-only and the touched fmt symbols not
being embedded.
Probe wcc/779_log_vstream_run pins the additive surface across 4 rows
(println_v_default_stderr / printfln_v_default_stderr /
lprintln_v_custom_sink / branched_lprintln_v) cstage-only per #209
(wwstage formattable match-arm bail; bites OLD log.println identically).
Byte-id graduates when #209 lands.
Cite refs: ref/hare/log/{logger,funcs,global,silent}.ha; drew acks on
module-static stderrsink_ctx + intrusive vt + 10-fn _v parity; ken
mandates on bootstrap byte-id mechanical + simple-ctx + #129 static-init.
Sibling tasks parked (filed, NOT fixed): eFinal #50; #206 (2 cast sites
at ensureinit_v); #173 (stderrwrite_v constructs nomem + widens to
io.error); #209 (cstage-only).