From 0d91608f39099e2d1de44041fd879fd57b3d0c44 Mon Sep 17 00:00:00 2001 From: rajames Date: Thu, 8 Oct 2026 11:46:05 -0400 Subject: [PATCH] fix(v4.0.0): EMIT ran past the output buffer; a message's first word was read before there was room for the rest The two root causes behind what the reviews of the wait found, both in the code as it stands. Each with a check that failed first. EMIT stored its character and only then looked whether the buffer was exactly full. A flush that ended in a fault -- the stack too deep to begin a message -- left the buffer full, and the fault's own message was then put past its end, with (OUT^) never again at the end to be flushed. The 28 cells after the buffer happen to be unused, so nothing showed; the wait had put the ports there, and the node blocked writing to one. EMIT now sends a buffer it finds full before it stores. AWAIT, and (GATE) when a neighbour is writing, read a message's first word and then used stack that was not known to be there. With 27 or 28 values on the stack, or 28 or 29 calls deep, a line typed during AWAIT was taken and never answered. (ROOM) tries six cells and four return entries first: if they are not there the text ends 'Stack overflow' with nothing read. (GATE) tries the three cells its writing needs before a first word goes; it was safe before only by the order things were done. v4/tools/depthsweep.py runs every message path of the hosted product at every depth of both stacks: each line typed must be answered and the node must come back. hosted-check runs it. make -C v4 test and sanitize at both widths, hosted-check. Co-Authored-By: Claude Opus 5.5 --- capsules/v4/nucleus-64.f18 | Bin 56608 -> 56808 bytes v4/Makefile | 1 + v4/capsule/core.v4 | 23 +++++++++- v4/capsule/quit.v4 | 3 +- v4/tests/test_host_quit.c | 20 +++++++++ v4/tools/depthsweep.py | 84 +++++++++++++++++++++++++++++++++++++ 6 files changed, 129 insertions(+), 2 deletions(-) create mode 100755 v4/tools/depthsweep.py diff --git a/capsules/v4/nucleus-64.f18 b/capsules/v4/nucleus-64.f18 index 6f8189113aac25137fb5b6eab2a7dfb10642796a..b108c931b23dda5bd5292c80c4cd7a2eb2b66551 100644 GIT binary patch literal 56808 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 U*@S%3Qy=Qbd_u1K^Lx|(4?iYb(*OVf literal 56608 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 diff --git a/v4/Makefile b/v4/Makefile index e8ae96ce..20fc19fd 100644 --- a/v4/Makefile +++ b/v4/Makefile @@ -206,6 +206,7 @@ hosted-check: $(foreach i,$(HOSTED_ISAS),$(BINDIR)/boot-$(i).txt) $(BINDIR)/star @grep -q '^ok> Stack overflow$$' $(BINDIR)/deep-amd64.txt && grep -q '^ok> 3 ok$$' $(BINDIR)/deep-amd64.txt || { echo "hosted-check: a line that left 29 values on the stack was not an error the node came back from"; tail -4 $(BINDIR)/deep-amd64.txt; exit 1; } @printf '1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26\nWORDS\nDEPTH .\n' | $(BINDIR)/starforth4-amd64 > $(BINDIR)/deepwords-amd64.txt 2>&1; true @grep -q 'DUP' $(BINDIR)/deepwords-amd64.txt && grep -q '^ok> 26 ok$$' $(BINDIR)/deepwords-amd64.txt || { echo "hosted-check: WORDS with 26 values on the stack did not print and come back"; tail -4 $(BINDIR)/deepwords-amd64.txt | cut -c1-200; exit 1; } + @python3 $(HERE)/tools/depthsweep.py $(BINDIR)/starforth4-amd64 $$(( $(HOST_DATA_RING) + 2 )) $$(( $(HOST_RET_RING) + 1 )) || { echo "hosted-check: at some depth of a stack a line was not answered, or the node did not come back"; exit 1; } @$(BINDIR)/starforth4-postfail < /dev/null > $(BINDIR)/postfail.txt; test $$? -ne 0 || { echo "hosted-check: a boot with a failing case did not fail"; exit 1; } @grep -q '^POST FAIL: fail.wrong out<5 5 $$' $(BINDIR)/postfail.txt || { echo "hosted-check: the failing case was not named"; cat $(BINDIR)/postfail.txt; exit 1; } @grep -q '^POST FAIL: fail.many out= V4_DATA_DEPTH, "the prompt and the interpreter take no more than four cells of the stack"); + /* A flush of the output buffer that ends in a fault leaves the buffer full: what is printed next -- the + * error's own message -- must not go past its end (MESH.md 7c.6). */ + { + unsigned over = 0, worst = 0, at; + for (k = most > 6 ? most - 6 : 0; k <= most + 3; k++) { + char line[4 * V4_DATA_DEPTH + 16]; + size_t n_at = 0; + unsigned m; + boot_bare(); + for (m = 0; m < 28; m++) n.mem[OUT_W + 256 + m] = 0; + for (m = 0; m < k; m++) n_at += (size_t)snprintf(line + n_at, sizeof line - n_at, "1 "); + snprintf(line + n_at, sizeof line - n_at, "\n"); + (void)say(line); + (void)say("WORDS\n"); + for (at = 0; at < 28; at++) if (n.mem[OUT_W + 256 + at] != 0) { over++; worst = k; break; } + if (n.mem[OUT_PTR] > OUT_W + 256) { over++; worst = k; } + CHECK(strcmp(say("1 2 + .\n"), "3 ok\nok> ") == 0, "WORDS with %u values on the stack: the node goes on", k); + } + CHECK(over == 0, "nothing was ever put past the end of the output buffer (it was, with %u values on the stack)", worst); + } } /* ---- how much of the data stack a line has ---- */ diff --git a/v4/tools/depthsweep.py b/v4/tools/depthsweep.py new file mode 100755 index 00000000..8cd1f278 --- /dev/null +++ b/v4/tools/depthsweep.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python3 +"""depthsweep.py -- the hosted product at every depth of both stacks. + + depthsweep.py + +Every path by which the node begins, writes or reads a message is run with +the data stack holding 0 .. depth+2 values, and from 1 .. depth+2 calls +deep. At each, every line typed must be answered -- " ok" or " ERROR" -- +and the node must come back: it may refuse with an error, but it may not +hang, and it may not swallow a line. Where the stack is shallow the +answers themselves are checked. + +Why: docs/v4.0.0/MESH.md 7c.6. A fault that came after a message's first +word had moved left it half done; and a fault inside a flush of the output +buffer let EMIT run past the buffer's end. Nothing ran these paths on a +deep stack. +""" +import subprocess, sys +from concurrent.futures import ThreadPoolExecutor + +binary, ddepth, rdepth = sys.argv[1], int(sys.argv[2]), int(sys.argv[3]) +cases = [] + +def run(lines): + text = '\n'.join(lines) + '\n' + try: + r = subprocess.run([binary], input=text.encode(), capture_output=True, timeout=30) + return r.stdout.decode('latin1'), False + except subprocess.TimeoutExpired as e: + return (e.stdout or b'').decode('latin1'), True + +def answers(out): + # what follows POST: one answer to a line typed + body = out.split('POST: PASSED', 1)[-1] + return body.count(' ok\n') + body.count(' ERROR\n') + +def check(name, k, lines, expect=None): + cases.append((name, k, lines, expect)) + +def judge(case): + name, k, lines, expect = case + out, hung = run(lines) + why = None + if 'POST: PASSED' not in out: why = 'POST did not pass' + elif hung: why = 'it hung' + elif answers(out) != len(lines): why = '%d lines typed, %d answered' % (len(lines), answers(out)) + elif expect is not None and expect not in out: why = 'no "%s"' % expect.strip() + if why is None: return None + tail = out.split('POST: PASSED', 1)[-1][-160:].replace('\n', '|') + return 'depthsweep: FAIL %s at %d: %s: ...%s' % (name, k, why, tail) + +def vals(k): return ' '.join(['1'] * k) + +# The stack shallow, and then every depth from well below where anything +# changes to past its end. An error empties the stack, and a wait that a +# typed line breaks ends in an error: so the line that broke it is always +# done, whatever the depth. +shallow = ddepth - 12 +for k in [0, 1, shallow] + list(range(ddepth - 10, ddepth + 3)): + v = [vals(k)] if k else [] + sh = k <= shallow + check('a number printed', k, v + ['7 .', '77 .'], '77 ok' if sh else None) + check('WORDS', k, v + ['WORDS', '77 .'], 'DUP' if sh else None) + check('a line typed during AWAIT', k, [': AW 5 AWAIT ;'] + v + ['AW', '77 .', '88 .'], '77 ok') + check('SEND with no way', k, [': SD S" 1 DROP" 5 SEND ;'] + v + ['SD', '77 .'], 'Argument out of range' if sh else None) + check('a write to an empty port', k, v + ['5 7 PORT!', '77 .'], 'No one on that port' if sh else None) + check('an unknown word', k, v + ['NOSUCHWORD', '77 .'], 'UNKNOWN WORD' if sh else None) + +def nest(n, inner): + return [': N1 %s ;' % inner] + [': N%d N%d ;' % (i, i - 1) for i in range(2, n + 1)] + ['N%d' % n] + +rshallow = rdepth - 14 +for n in [1, rshallow] + list(range(rdepth - 12, rdepth + 3)): + sh = n <= rshallow + check('a number printed, calls deep', n, nest(n, '7 .') + ['77 .'], '77 ok') + check('WORDS, calls deep', n, nest(n, 'WORDS') + ['77 .'], '77 ok') + check('a line typed during AWAIT, calls deep', n, nest(n, '5 AWAIT') + ['77 .', '88 .'], '77 ok') + check('SEND with no way, calls deep', n, nest(n, 'S" 1 DROP" 5 SEND') + ['77 .'], '77 ok') + +with ThreadPoolExecutor(max_workers=8) as pool: + found = [f for f in pool.map(judge, cases) if f] +for f in found: print(f) +print('depthsweep: %d runs, %d failures' % (len(cases), len(found))) +sys.exit(1 if found else 0)