Stage D batch 4: mama_forth_words.c groups 1+2 -- capsule/lifecycle words + BIRTH/START/KILL (FABRIC-3.md §XXXII.6)
15 of mama_forth_words.c's 48 silent sites fixed, split by functional
grouping per direct instruction: CAPSULE@/CAPSULE-HASH@/CAPSULE-FLAGS@/
CAPSULE-LEN@/CAPSULE-BIRTH/CAPSULE-RUN/EXEC (9), and BIRTH/START/KILL
(6).
Refined the diagnostic-placement rule: match whichever convention that
same function's other already-correct guards use, rather than
defaulting uniformly. BIRTH/START/KILL/EXEC each already had a
console_println() sibling guard ("name too long or empty") -- their
newly-diagnosed guards now match that, same shape as USE's own fix.
The CAPSULE*@ words have no sibling guard to match, so they keep
log_message() (defer_words.c's gold-standard default).
Three-arch clean qemu acceptance passed; BIRTH itself is exercised by
every boot (Hermes/Artemis birth).
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
66c2f3e539
commit
b42c3b195c
+29
@@ -4605,3 +4605,32 @@ regression unaffected -- including the full POST word-test suite, which exercise
|
|||||||
`vm_compile_word`/`vm_compile_call`/`execute_colon_word` extensively via every colon-definition
|
`vm_compile_word`/`vm_compile_call`/`execute_colon_word` extensively via every colon-definition
|
||||||
test case, with zero regressions from either the diagnostics or the two NULL-guard fixes.
|
test case, with zero regressions from either the diagnostics or the two NULL-guard fixes.
|
||||||
|
|
||||||
|
**`mama_forth_words.c` (48 sites) -- per direct instruction, split by functional grouping
|
||||||
|
rather than mechanical file-order chunks or one single batch. Six groups identified from
|
||||||
|
§XXXII.3's own per-file site list:** capsule descriptor/lifecycle words + `EXEC` (9: `CAPSULE@`/
|
||||||
|
`CAPSULE-HASH@`/`CAPSULE-FLAGS@`/`CAPSULE-LEN@`/`CAPSULE-BIRTH`/`CAPSULE-RUN`/`EXEC`); VM
|
||||||
|
lifecycle words (6: `BIRTH`/`START`/`KILL`); cross-VM execution/dispatch (11: `VM-STEP`/
|
||||||
|
`VM-EXEC`/`VM-CALL`/`SWITCH-MARK-WORK`/`VM-HEAT`); identity/crypto (10: `MINT` + its
|
||||||
|
`mint_pop_string()` helper/`ZUSE-ELIGIBILITY-ADD`/`ZUSE-ELIGIBLE?`/`ELEVATE-PUBKEY-UNPACK`);
|
||||||
|
dictionary lookup + diagnostic/test words (6: `NAME>XT`/`RUNCAP-TEST`/`PAIR-TEST`); Stadium/
|
||||||
|
physics primitives (6: `STADIUM-ADMIT`/`STADIUM-EVICT`/`STADIUM-RES-PULL`/`STADIUM-RES-PUSH`/
|
||||||
|
`STADIUM-HEAT@`/`STADIUM-HEAT!`). Groups combined two-at-a-time per commit for acceptance-boot
|
||||||
|
economy (each full rebuild+3-arch cycle costs the same regardless of diff size within one file),
|
||||||
|
documented separately below per group.
|
||||||
|
|
||||||
|
**Batch 4 -- DONE, 2026-09-15: groups 1+2 (capsule descriptor/lifecycle words + EXEC, and VM
|
||||||
|
lifecycle words BIRTH/START/KILL) -- 15 sites.** Refined the diagnostic-placement rule while
|
||||||
|
doing this batch: rather than defaulting to `log_message()` everywhere (batches 1-3's own
|
||||||
|
default, absent any sibling to match), **match whichever convention that same function's other
|
||||||
|
already-correct guards already use.** `BIRTH`/`START`/`KILL`/`EXEC` each already had a sibling
|
||||||
|
guard using `console_println()` ("name too long or empty") -- their newly-diagnosed guards now
|
||||||
|
use `console_println()` too, for internal consistency within the same function, matching `USE`'s
|
||||||
|
own five-guard precedent exactly (these are all `S" name"`-taking, directly-interactive commands,
|
||||||
|
the same shape `USE` is). The four `CAPSULE*@` fetch words and `CAPSULE-BIRTH`/`CAPSULE-RUN` have
|
||||||
|
no such sibling (a single guard each) -- kept `log_message()`, matching `defer_words.c`'s
|
||||||
|
gold-standard default for a function with nothing else to match against.
|
||||||
|
|
||||||
|
**Verified:** three-architecture `clean qemu` acceptance (amd64/aarch64/riscv64) passed --
|
||||||
|
`BIRTH` itself is exercised heavily by every boot (Hermes/Artemis birth), a real regression check
|
||||||
|
beyond compile-cleanliness for this specific batch.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Capsule Block Manifest — Auto-generated
|
# Capsule Block Manifest — Auto-generated
|
||||||
<!-- Generated by mkcapsule --manifest 2026-09-15T21:25:23Z -->
|
<!-- Generated by mkcapsule --manifest 2026-09-15T22:41:56Z -->
|
||||||
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
||||||
<!-- Hand-written justifications and immutability notes live -->
|
<!-- Hand-written justifications and immutability notes live -->
|
||||||
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
||||||
|
|||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -93,6 +93,7 @@ void mama_word_capsule_count(VM *vm)
|
|||||||
void mama_word_capsule_fetch(VM *vm)
|
void mama_word_capsule_fetch(VM *vm)
|
||||||
{
|
{
|
||||||
if (vm->dsp < 0) {
|
if (vm->dsp < 0) {
|
||||||
|
log_message(LOG_ERROR, "CAPSULE@: stack underflow");
|
||||||
vm->error = 1;
|
vm->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -115,6 +116,7 @@ void mama_word_capsule_fetch(VM *vm)
|
|||||||
void mama_word_capsule_hash_fetch(VM *vm)
|
void mama_word_capsule_hash_fetch(VM *vm)
|
||||||
{
|
{
|
||||||
if (vm->dsp < 0) {
|
if (vm->dsp < 0) {
|
||||||
|
log_message(LOG_ERROR, "CAPSULE-HASH@: stack underflow");
|
||||||
vm->error = 1;
|
vm->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -137,6 +139,7 @@ void mama_word_capsule_hash_fetch(VM *vm)
|
|||||||
void mama_word_capsule_flags_fetch(VM *vm)
|
void mama_word_capsule_flags_fetch(VM *vm)
|
||||||
{
|
{
|
||||||
if (vm->dsp < 0) {
|
if (vm->dsp < 0) {
|
||||||
|
log_message(LOG_ERROR, "CAPSULE-FLAGS@: stack underflow");
|
||||||
vm->error = 1;
|
vm->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -159,6 +162,7 @@ void mama_word_capsule_flags_fetch(VM *vm)
|
|||||||
void mama_word_capsule_len_fetch(VM *vm)
|
void mama_word_capsule_len_fetch(VM *vm)
|
||||||
{
|
{
|
||||||
if (vm->dsp < 0) {
|
if (vm->dsp < 0) {
|
||||||
|
log_message(LOG_ERROR, "CAPSULE-LEN@: stack underflow");
|
||||||
vm->error = 1;
|
vm->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -240,6 +244,7 @@ void mama_word_birth(VM *vm)
|
|||||||
VMUuid new_vm_id;
|
VMUuid new_vm_id;
|
||||||
|
|
||||||
if (vm->dsp < 1) {
|
if (vm->dsp < 1) {
|
||||||
|
console_println("BIRTH: expects S\" name\" BIRTH -- nothing on the stack");
|
||||||
vm->error = 1;
|
vm->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -255,7 +260,11 @@ void mama_word_birth(VM *vm)
|
|||||||
/* caddr is a VM address; S" ( -- c-addr u ) stores chars directly at caddr */
|
/* caddr is a VM address; S" ( -- c-addr u ) stores chars directly at caddr */
|
||||||
{
|
{
|
||||||
const uint8_t *p = vm_ptr(vm, (vaddr_t)caddr);
|
const uint8_t *p = vm_ptr(vm, (vaddr_t)caddr);
|
||||||
if (!p) { vm->error = 1; return; }
|
if (!p) {
|
||||||
|
console_println("BIRTH: invalid address on the stack");
|
||||||
|
vm->error = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
src = (const char *)p;
|
src = (const char *)p;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (uint32_t)u; i++) name_buf[i] = src[i];
|
for (i = 0; i < (uint32_t)u; i++) name_buf[i] = src[i];
|
||||||
@@ -347,6 +356,7 @@ void mama_word_start(VM *vm)
|
|||||||
VM *target;
|
VM *target;
|
||||||
|
|
||||||
if (vm->dsp < 1) {
|
if (vm->dsp < 1) {
|
||||||
|
console_println("START: expects S\" name\" START -- nothing on the stack");
|
||||||
vm->error = 1;
|
vm->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -362,7 +372,11 @@ void mama_word_start(VM *vm)
|
|||||||
/* caddr is a VM address; S" ( -- c-addr u ) stores chars directly at caddr */
|
/* caddr is a VM address; S" ( -- c-addr u ) stores chars directly at caddr */
|
||||||
{
|
{
|
||||||
const uint8_t *p = vm_ptr(vm, (vaddr_t)caddr);
|
const uint8_t *p = vm_ptr(vm, (vaddr_t)caddr);
|
||||||
if (!p) { vm->error = 1; return; }
|
if (!p) {
|
||||||
|
console_println("START: invalid address on the stack");
|
||||||
|
vm->error = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
src = (const char *)p;
|
src = (const char *)p;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (uint32_t)u; i++) name_buf[i] = src[i];
|
for (i = 0; i < (uint32_t)u; i++) name_buf[i] = src[i];
|
||||||
@@ -558,6 +572,7 @@ void mama_word_kill(VM *vm)
|
|||||||
const char *src;
|
const char *src;
|
||||||
|
|
||||||
if (vm->dsp < 1) {
|
if (vm->dsp < 1) {
|
||||||
|
console_println("KILL: expects S\" name\" KILL -- nothing on the stack");
|
||||||
vm->error = 1;
|
vm->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -573,7 +588,11 @@ void mama_word_kill(VM *vm)
|
|||||||
/* caddr is a VM address; S" ( -- c-addr u ) stores chars directly at caddr */
|
/* caddr is a VM address; S" ( -- c-addr u ) stores chars directly at caddr */
|
||||||
{
|
{
|
||||||
const uint8_t *p = vm_ptr(vm, (vaddr_t)caddr);
|
const uint8_t *p = vm_ptr(vm, (vaddr_t)caddr);
|
||||||
if (!p) { vm->error = 1; return; }
|
if (!p) {
|
||||||
|
console_println("KILL: invalid address on the stack");
|
||||||
|
vm->error = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
src = (const char *)p;
|
src = (const char *)p;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (uint32_t)u; i++) name_buf[i] = src[i];
|
for (i = 0; i < (uint32_t)u; i++) name_buf[i] = src[i];
|
||||||
@@ -1319,6 +1338,7 @@ static void mama_word_pair_test(VM *vm)
|
|||||||
void mama_word_capsule_birth(VM *vm)
|
void mama_word_capsule_birth(VM *vm)
|
||||||
{
|
{
|
||||||
if (vm->dsp < 0) {
|
if (vm->dsp < 0) {
|
||||||
|
log_message(LOG_ERROR, "CAPSULE-BIRTH: stack underflow");
|
||||||
vm->error = 1;
|
vm->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1359,6 +1379,7 @@ void mama_word_capsule_birth(VM *vm)
|
|||||||
void mama_word_capsule_run(VM *vm)
|
void mama_word_capsule_run(VM *vm)
|
||||||
{
|
{
|
||||||
if (vm->dsp < 0) {
|
if (vm->dsp < 0) {
|
||||||
|
log_message(LOG_ERROR, "CAPSULE-RUN: stack underflow");
|
||||||
vm->error = 1;
|
vm->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1366,6 +1387,8 @@ void mama_word_capsule_run(VM *vm)
|
|||||||
cell_t capsule_idx = vm_pop(vm);
|
cell_t capsule_idx = vm_pop(vm);
|
||||||
|
|
||||||
if ((uint64_t)capsule_idx >= capsule_get_desc_count()) {
|
if ((uint64_t)capsule_idx >= capsule_get_desc_count()) {
|
||||||
|
log_message(LOG_ERROR, "CAPSULE-RUN: capsule index %lld out of range",
|
||||||
|
(long long)capsule_idx);
|
||||||
vm->error = 1;
|
vm->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1464,7 +1487,11 @@ void mama_word_exec(VM *vm)
|
|||||||
int saved_dsp;
|
int saved_dsp;
|
||||||
int saved_rsp;
|
int saved_rsp;
|
||||||
|
|
||||||
if (vm->dsp < 1) { vm->error = 1; return; }
|
if (vm->dsp < 1) {
|
||||||
|
console_println("EXEC: expects S\" name\" EXEC -- nothing on the stack");
|
||||||
|
vm->error = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
u = vm_pop(vm);
|
u = vm_pop(vm);
|
||||||
caddr = vm_pop(vm);
|
caddr = vm_pop(vm);
|
||||||
@@ -1476,7 +1503,11 @@ void mama_word_exec(VM *vm)
|
|||||||
|
|
||||||
{
|
{
|
||||||
const uint8_t *p = vm_ptr(vm, (vaddr_t)caddr);
|
const uint8_t *p = vm_ptr(vm, (vaddr_t)caddr);
|
||||||
if (!p) { vm->error = 1; return; }
|
if (!p) {
|
||||||
|
console_println("EXEC: invalid address on the stack");
|
||||||
|
vm->error = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
src = (const char *)p;
|
src = (const char *)p;
|
||||||
}
|
}
|
||||||
for (i = 0; i < (uint32_t)u; i++) name_buf[i] = src[i];
|
for (i = 0; i < (uint32_t)u; i++) name_buf[i] = src[i];
|
||||||
|
|||||||
Reference in New Issue
Block a user