lib/memio: wire seeker (io.seek dispatch landed; #5-era deferral stale)

io.error grows errors.invalid (ref/hare/io/types.ha:11 spreads
...errors::error, which includes it; Hare's memio seek returns it on
out-of-bounds, stream.ha:134-136) — appended last so existing member
tags stay put; no exhaustive io.error matches exist in lib.

seekfn mirrors ref/hare/memio/stream.ha:122-140 over the flat header,
shared by fixed/dynamic/dynamicfrom (Hare wires the same seek into
both vtables). The io.off-vs-i64 arithmetic runs on an i64 copy:
cstage binop typing is nominal on aliases, wwstage accepts (filed,
ww-core #54).

791's stream_seek_unsupported row re-pins st_seek's void-arm on a
hand-built seekerless vtable: its old premise (memio wires no seeker)
is retired by this commit; memio seek success is pinned by memiotest.

w6c/wwdump main.combined.ww regen'd: they embed lib/io + lib/memio
(the freshness gates are blind to this — embedded-source discipline);
w6a/w6l/ww don't embed io, verified untouched.
This commit is contained in:
2026-06-04 15:49:25 +09:00
parent bc048ebe65
commit 532b0a88ae
6 changed files with 365 additions and 31 deletions

View File

@@ -24,9 +24,13 @@
* | the backing buffer, then read them back
* | through io.read on a fresh fixed stream.
* | exit 43.
* stream_seek_unsupported | memio wires no seeker slot; io.seek
* | takes st_seek's void-arm and returns an
* | io.error (not an off). exit 44.
* stream_seek_unsupported | hand-built vtable with the seeker slot
* | left void; io.seek takes st_seek's
* | void-arm and returns an io.error (not
* | an off). exit 44. (Was memio.fixed:
* | memio wires a seeker now, so its seek
* | succeeds — pinned by memiotest; this
* | row keeps the void-arm dispatch pin.)
* stream_seeker_tell | hand-built vtable WITH a seeker fn:
* | io.seek returns the seeker's off, and
* | io.tell == seek(s, 0, CUR). exit 45.
@@ -142,11 +146,9 @@ static const struct row rows[] = {
{ "stream_seek_unsupported",
"package main;\n"
"import io;\n"
"import memio;\n"
"export fn main() i32 = {\n"
" let buf: [4]u8;\n"
" let st: memio.stream = memio.fixed(buf[0:4]);\n"
" let s: io.stream = &st.vt;\n"
" let vt: io.vtable;\n"
" let s: io.stream = &vt;\n"
" match (io.seek(s, 0: io.off, io.whence.SET)) {\n"
" case let o: io.off => return 61;\n"
" case let e: io.error => return 44;\n"