Stage D batch 5: mama_forth_words.c group 3 -- cross-VM execution/dispatch, both flagged special cases resolved (FABRIC-3.md §XXXII.6)
VM-STEP/VM-EXEC/VM-CALL (5 sites) gained console_println() diagnostics
matching their own existing sibling guards.
SWITCH-MARK-WORK and VM-HEAT (3 sites) resolved per §XXXII.3's own
recommendation: dropped vm->error entirely rather than diagnosing it,
matching each function's own doc comment ("must never error or spam
the console" / "does not print/error"). SWITCH-MARK-WORK is the same
function §XXVIII.3 already fixed once for an off-by-one that fired
silently on every MSG-SEND in the system -- the guard now genuinely
cannot repeat that by contract, not just by the threshold being right.
VM-HEAT's guards now push 0 and return, matching its own
always-returns-a-value stack effect.
Three-arch clean qemu acceptance passed. Zuse's own WIREBIND attach
(every boot) drives MSG-SEND -> SWITCH-MARK-WORK, so this batch's most
safety-critical fix is exercised by standard acceptance, not just
compiled.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BWpNjdwPtFLuVLaAq44L9K
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b42c3b195c
commit
8b5300fc4f
@@ -680,7 +680,11 @@ static void mama_word_vm_step(VM *vm)
|
||||
VM *target;
|
||||
char saved_name[VM_NAME_MAX];
|
||||
|
||||
if (vm->dsp < 1) { vm->error = 1; return; }
|
||||
if (vm->dsp < 1) {
|
||||
console_println("VM-STEP: expects S\" name\" VM-STEP -- nothing on the stack");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
u = vm_pop(vm);
|
||||
caddr = vm_pop(vm);
|
||||
@@ -692,7 +696,11 @@ static void mama_word_vm_step(VM *vm)
|
||||
|
||||
{
|
||||
const uint8_t *p = vm_ptr(vm, (vaddr_t)caddr);
|
||||
if (!p) { vm->error = 1; return; }
|
||||
if (!p) {
|
||||
console_println("VM-STEP: invalid address on the stack");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
src = (const char *)p;
|
||||
}
|
||||
for (i = 0; i < (uint32_t)u; i++) name_buf[i] = src[i];
|
||||
@@ -741,7 +749,11 @@ static void mama_word_vm_exec(VM *vm)
|
||||
VM *target;
|
||||
char saved_name[VM_NAME_MAX];
|
||||
|
||||
if (vm->dsp < 3) { vm->error = 1; return; }
|
||||
if (vm->dsp < 3) {
|
||||
console_println("VM-EXEC: expects S\" cmd\" S\" name\" VM-EXEC -- too few items on the stack");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* TOS: vm-name-u, vm-name-caddr, cmd-u, cmd-caddr */
|
||||
vm_u = vm_pop(vm);
|
||||
@@ -760,7 +772,11 @@ static void mama_word_vm_exec(VM *vm)
|
||||
|
||||
{
|
||||
const uint8_t *p = vm_ptr(vm, (vaddr_t)vm_caddr);
|
||||
if (!p) { vm->error = 1; return; }
|
||||
if (!p) {
|
||||
console_println("VM-EXEC: invalid VM-name address on the stack");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
src = (const char *)p;
|
||||
}
|
||||
for (i = 0; i < (uint32_t)vm_u; i++) vm_name[i] = src[i];
|
||||
@@ -768,7 +784,11 @@ static void mama_word_vm_exec(VM *vm)
|
||||
|
||||
{
|
||||
const uint8_t *p = vm_ptr(vm, (vaddr_t)cmd_caddr);
|
||||
if (!p) { vm->error = 1; return; }
|
||||
if (!p) {
|
||||
console_println("VM-EXEC: invalid command address on the stack");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
src = (const char *)p;
|
||||
}
|
||||
for (i = 0; i < (uint32_t)cmd_u; i++) cmd_buf[i] = src[i];
|
||||
@@ -823,7 +843,12 @@ static void mama_word_switch_mark_work(VM *vm)
|
||||
uint32_t i;
|
||||
VMRegistryEntry entry;
|
||||
|
||||
if (vm->dsp < 1) { vm->error = 1; return; }
|
||||
/* FABRIC-3.md §XXXII.6, 2026-09-15: this guard used to set vm->error on
|
||||
* underflow, contradicting this function's own doc comment above ("must
|
||||
* never error or spam the console") -- flagged as a special case in
|
||||
* §XXXII.3's triage, not just a missing diagnostic. Silently ignored,
|
||||
* matching every other malformed-input case in this same function. */
|
||||
if (vm->dsp < 1) return;
|
||||
|
||||
u = vm_pop(vm);
|
||||
caddr = vm_pop(vm);
|
||||
@@ -860,7 +885,11 @@ static void mama_word_vm_call(VM *vm)
|
||||
VM *target;
|
||||
char saved_name[VM_NAME_MAX];
|
||||
|
||||
if (vm->dsp < 3) { vm->error = 1; return; }
|
||||
if (vm->dsp < 3) {
|
||||
console_println("VM-CALL: expects S\" cmd\" S\" name\" VM-CALL -- too few items on the stack");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
vm_u = vm_pop(vm);
|
||||
vm_caddr = vm_pop(vm);
|
||||
@@ -878,7 +907,11 @@ static void mama_word_vm_call(VM *vm)
|
||||
|
||||
{
|
||||
const uint8_t *p = vm_ptr(vm, (vaddr_t)vm_caddr);
|
||||
if (!p) { vm->error = 1; return; }
|
||||
if (!p) {
|
||||
console_println("VM-CALL: invalid VM-name address on the stack");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
src = (const char *)p;
|
||||
}
|
||||
for (i = 0; i < (uint32_t)vm_u; i++) vm_name[i] = src[i];
|
||||
@@ -886,7 +919,11 @@ static void mama_word_vm_call(VM *vm)
|
||||
|
||||
{
|
||||
const uint8_t *p = vm_ptr(vm, (vaddr_t)cmd_caddr);
|
||||
if (!p) { vm->error = 1; return; }
|
||||
if (!p) {
|
||||
console_println("VM-CALL: invalid command address on the stack");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
src = (const char *)p;
|
||||
}
|
||||
for (i = 0; i < (uint32_t)cmd_u; i++) cmd_buf[i] = src[i];
|
||||
@@ -952,7 +989,13 @@ static void mama_word_vm_heat(VM *vm)
|
||||
const char *src;
|
||||
VMRegistryEntry entry;
|
||||
|
||||
if (vm->dsp < 1) { vm->error = 1; return; }
|
||||
/* FABRIC-3.md §XXXII.6, 2026-09-15: both guards below used to set
|
||||
* vm->error, contradicting this function's own doc comment above
|
||||
* ("does not print/error") -- flagged as a special case in §XXXII.3's
|
||||
* triage. Push the same 0 the "unknown name" case already returns,
|
||||
* matching this word's own always-returns-a-value contract, instead
|
||||
* of erroring. */
|
||||
if (vm->dsp < 1) { vm_push(vm, 0); return; }
|
||||
|
||||
vm_u = vm_pop(vm);
|
||||
vm_caddr = vm_pop(vm);
|
||||
@@ -964,7 +1007,7 @@ static void mama_word_vm_heat(VM *vm)
|
||||
|
||||
{
|
||||
const uint8_t *p = vm_ptr(vm, (vaddr_t)vm_caddr);
|
||||
if (!p) { vm->error = 1; return; }
|
||||
if (!p) { vm_push(vm, 0); return; }
|
||||
src = (const char *)p;
|
||||
}
|
||||
for (i = 0; i < (uint32_t)vm_u; i++) vm_name[i] = src[i];
|
||||
|
||||
Reference in New Issue
Block a user