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
@@ -107,6 +107,11 @@ void v4_exec_op(v4_node *n, v4_exec_state *es, v4_heat *h,
|
||||
v4_dstack *ds = &n->ds;
|
||||
v4_rstack *rs = &n->rs;
|
||||
v4_cell x;
|
||||
/* A store can be refused by the node itself -- to "any port", "which
|
||||
* port", How or Have (node.c) -- or raise an error (D-18). Refused, the
|
||||
* opcode did nothing more (node.h, FAULTS); raised, the store was made,
|
||||
* but P is the handler's. */
|
||||
unsigned faults = n->faults;
|
||||
|
||||
if (op <= V4_OP_BANG_A && stack_faulted(n, op)) return;
|
||||
|
||||
@@ -180,20 +185,27 @@ void v4_exec_op(v4_node *n, v4_exec_state *es, v4_heat *h,
|
||||
case V4_OP_STORE_P:
|
||||
if (faulted(n, n->p)) return;
|
||||
v4_node_store(n, n->p, v4_dstack_pop(ds));
|
||||
if (n->faults != faults) { /* P is the handler now: it is not advanced */
|
||||
if (n->fault_kind != V4_FAULT_RAISED) return;
|
||||
break;
|
||||
}
|
||||
n->p = add_wrap(n->p, 1);
|
||||
break;
|
||||
case V4_OP_STORE_INC:
|
||||
if (faulted(n, n->a)) return;
|
||||
v4_node_store(n, n->a, v4_dstack_pop(ds));
|
||||
if (n->faults != faults && n->fault_kind != V4_FAULT_RAISED) return; /* refused: A is untouched */
|
||||
n->a = add_wrap(n->a, 1);
|
||||
break;
|
||||
case V4_OP_STORE_B:
|
||||
if (faulted(n, n->b)) return;
|
||||
v4_node_store(n, n->b, v4_dstack_pop(ds));
|
||||
if (n->faults != faults && n->fault_kind != V4_FAULT_RAISED) return;
|
||||
break;
|
||||
case V4_OP_STORE_A:
|
||||
if (faulted(n, n->a)) return;
|
||||
v4_node_store(n, n->a, v4_dstack_pop(ds));
|
||||
if (n->faults != faults && n->fault_kind != V4_FAULT_RAISED) return;
|
||||
break;
|
||||
|
||||
case V4_OP_MUL_STEP:
|
||||
|
||||
Reference in New Issue
Block a user