fix(v4): overlong lines are refused whole; a refused store moves neither A nor P
- hosted (v4/tools/hosted.c): a line longer than the buffer is read to its end and refused as too long. Before, fgets handed it over in 1025-byte pieces and the last piece ran as a line of its own. - bare metal (kernel/src/v4/sk_v4.c): the line editor takes 1024 characters, as the boot does, and a line typed past that is refused as too long instead of being cut at 255 and run. V4_BOOT_LINE_TOO_LONG is now reported at the prompt and while a line waits. - engine (v4/src/exec.c): a store the node itself refuses (to "any port", "which port", How or Have) left the opcode running on: !+ advanced A, against node.h's FAULTS, and !p advanced P past the handler, into the next fault kind's entry. A refused store now does nothing more; a store that raises an error (D-18) still counts as made, but P stays the handler's. - test_port.c: both cases; they fail on the old exec.c (A 1017, P 901). Engine-level tests (all v4/tests/test_*.c but test_host_*) pass at 32 and 64 bits; test_port also under ASan/UBSan. Not yet run: make -C v4 test, test-32, hosted-check, and the three QEMU acceptance boots. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GE3SDvQn5EoxdGufk84zz2
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
728b0a54eb
commit
fd2088255d
+17
-7
@@ -29,7 +29,7 @@
|
||||
#include "v4/boot.h"
|
||||
#include "block_subsystem.h"
|
||||
|
||||
#define SK_V4_LINE 255u /* what the line editor here takes */
|
||||
#define SK_V4_LINE 1024u /* what the line editor here takes: a line, as the boot takes one (v4/system/boot.c) */
|
||||
|
||||
/* v3's prompt (repl.c's SK_PROMPT_TEXT): "ok> " in bright cyan, after the
|
||||
* console's own "[zuse@Hera] " line prefix. */
|
||||
@@ -82,12 +82,15 @@ static void sk_v4_serve(v4_node *node, unsigned request)
|
||||
* Zuse's session has ended (her drive was pulled): the caller goes headless
|
||||
* (not in a build with EMERGENCY_CONSOLE_ENABLED, whose console needs no
|
||||
* login: v3's sk_console_readline() the same). While nothing is typed the
|
||||
* idle beat runs, as v3's. */
|
||||
* idle beat runs, as v3's. A line typed past SK_V4_LINE characters is not
|
||||
* cut short and run: what is typed after that is not kept, and
|
||||
* SK_V4_LINE + 1 is returned, which the boot refuses as too long
|
||||
* (V4_BOOT_LINE_TOO_LONG), running nothing. */
|
||||
#define SK_V4_CURSOR_BLINK 50u /* ticks between blinks, as v3's (500 ms at 100 Hz) */
|
||||
|
||||
static int sk_v4_readline(void)
|
||||
{
|
||||
int len = 0;
|
||||
int len = 0, over = 0;
|
||||
int cursor_on = 1;
|
||||
uint64_t blink = heartbeat_ticks();
|
||||
|
||||
@@ -113,11 +116,16 @@ static int sk_v4_readline(void)
|
||||
arch_relax();
|
||||
continue;
|
||||
}
|
||||
if (c == '\r' || c == '\n') { console_fb_erase_cursor(); console_putc('\n'); return len; }
|
||||
if (c == '\r' || c == '\n') {
|
||||
console_fb_erase_cursor(); console_putc('\n');
|
||||
return over ? (int)SK_V4_LINE + 1 : len;
|
||||
}
|
||||
if (c == 8 || c == 127) {
|
||||
if (len > 0) { len--; console_putc(8); console_putc(' '); console_putc(8); }
|
||||
} else if (c >= 32 && c < 127 && len < (int)SK_V4_LINE) {
|
||||
sk_v4_text[len++] = (char)c;
|
||||
if (over > 0) { over--; console_putc(8); console_putc(' '); console_putc(8); }
|
||||
else if (len > 0) { len--; console_putc(8); console_putc(' '); console_putc(8); }
|
||||
} else if (c >= 32 && c < 127) {
|
||||
if (len < (int)SK_V4_LINE) sk_v4_text[len++] = (char)c;
|
||||
else over++;
|
||||
console_putc((char)c);
|
||||
}
|
||||
cursor_on = 1; /* typing shows a solid cursor, as v3's */
|
||||
@@ -196,6 +204,7 @@ void sk_v4_run(void (*chain)(void), const BootDisk *boot_disk)
|
||||
break;
|
||||
}
|
||||
how = v4_boot_line(&boot, sk_v4_text, (unsigned)len);
|
||||
if (how == V4_BOOT_LINE_TOO_LONG) { console_puts("Line too long\n ERROR\n"); how = V4_BOOT_LINE_WAITING; continue; }
|
||||
if (how == V4_TEXT_ERROR) console_puts(" ERROR\n" SK_V4_PROMPT);
|
||||
else if (how == V4_TEXT_COMPLETED) console_puts(" ok\n" SK_V4_PROMPT);
|
||||
else break;
|
||||
@@ -204,6 +213,7 @@ void sk_v4_run(void (*chain)(void), const BootDisk *boot_disk)
|
||||
if (logged_out && (how == V4_TEXT_ERROR || how == V4_TEXT_COMPLETED)) continue;
|
||||
if (how == V4_TEXT_COMPLETED) console_puts(" ok\n");
|
||||
else if (how == V4_TEXT_ERROR) console_puts(" ERROR\n");
|
||||
else if (how == V4_BOOT_LINE_TOO_LONG) console_puts("Line too long\n ERROR\n");
|
||||
else if (how == V4_BOOT_LINE_REFUSED) console_puts("Message refused\n ERROR\n"); /* the node's wire is full: error 19's words */
|
||||
else if (how == V4_BOOT_LINE_STOPPED) {
|
||||
console_println("StarForth v4: the node stopped on a fault");
|
||||
|
||||
Reference in New Issue
Block a user