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 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
6015c87157
commit
0d91608f39
@@ -1133,6 +1133,26 @@ int main(void)
|
||||
}
|
||||
printf(" %u values may wait on the stack while the next line is typed and interpreted\n", most);
|
||||
CHECK(most + 4u >= 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 ---- */
|
||||
|
||||
Reference in New Issue
Block a user