diff --git a/docs/v4.0.0/ENGINE.md b/docs/v4.0.0/ENGINE.md index ce7cd517..cf4e9917 100644 --- a/docs/v4.0.0/ENGINE.md +++ b/docs/v4.0.0/ENGINE.md @@ -133,6 +133,67 @@ engine's. *v3:* `vm_dict_hash_fn`, a hook the birth protocol calls. *v4:* the same hook, answered from the node's dictionary. +## 3b. A word's two halves (ruled 2026-10-05: "A is good") + +`V3-PARITY.md` section 1j. A word on a node is its name and its code, in +the node's memory, with its word ID in its header. Its accounts are v3's +own `DictEntry` record, kept by the kernel: `execution_heat`, `physics`, +the four ACL fields, the transition metrics, the word ID. The two are +joined by the word ID. + +- The node tells the kernel when a word is defined and when words are + forgotten, by a request through its port. The kernel makes or drops the + record. +- At each `call` the kernel does on the record what v3's inner loop does + (3.5). +- v3's physics, heartbeat, ACL words, Stadium word layer and parity run on + the records, unchanged. The ACL fields v4 keeps in an entry's flags cell + (`v4/capsule/acl.v4`) go: v3's C ACL words serve a node as they are. + +## 3c. What exactly is swapped, in v3's own files + +Measured 2026-10-05. Each build already has one file that is the +interpreter, and the rest of v3 calls into it: + +| Build | The interpreter file | The stacks | +|---|---|---| +| Hosted | `v3/src/vm.c` | `v3/src/stack_management.c` | +| Kernel | `kernel/src/vm/vm_core.c` (the kernel build leaves `v3/src/vm.c` out) | the same | + +The functions in it that execute FORTH, and so are the node's to answer: +`vm_interpret`, `vm_interpret_word`, `execute_colon_word`, `acl_recheck`, +`vm_parse_word`, `vm_parse_number`, `vm_enter_compile_mode`, +`vm_exit_compile_mode`, `vm_compile_word`, `vm_compile_literal`, +`vm_compile_call`, `vm_compile_exit`, `vm_make_immediate`; the memory +accessors `vm_addr_ok`, `vm_ptr`, `vm_load_u8`, `vm_store_u8`, +`vm_load_cell`, `vm_store_cell`; and the stacks, `vm_push`, `vm_pop`, +`vm_rpush`, `vm_rpop`. The rest of those files — host services, the time +base, `vm_cleanup` — is not the engine and stays. + +So the swap is a third interpreter file, for both builds: the same +functions, answered by a node. Everything else of v3 is compiled as it is. + +**This changes what the hosted v4 product is.** It is not a separate +program (`v4/tools/hosted.c`, `v4/system/boot.c`). It is v3's hosted +program — its `main`, its REPL, its physics, its POST — built with the +node as its interpreter, exactly as the kernel product is v3's kernel +built the same way. `hosted.c` and `boot.c` are the lone node's and go +when that build reaches its prompt. + +**Two things in v3's C words do not carry over as they are**, and must be +dealt with word by word: + +- A C word that takes an address from the stack and reads memory through + `vm_ptr` gets a pointer into v3's flat bytes. A node's bytes are four to + a cell (D-1), so they are not a flat run of C bytes. Such a word needs + the text copied out of the node. `mama_forth_words.c` has 40 such uses. +- A C word that reaches into `vm->data_stack` or `vm->dsp` directly must + go through `vm_push`, `vm_pop` or a depth accessor. `mama_forth_words.c` + has 45. + +Both are changes to files v3 also builds, so each must leave v3 as it is +and be accepted by v3's own three-ISA boot. + ## 3a. Many VMs at once (Captain Bob, 2026-10-05) > Do not forget that this is multiuser, multitasking, and a hybrid of @@ -166,19 +227,19 @@ It is step 6's, and section 6 lists it as open. **The loop that runs one node until its line ends** (`v4_boot_line`, `v4/system/boot.c`) is the lone node's and the hosted program's, where there is one node and nothing to share the processor with. It is not how -the kernel will run a fleet, and goes with the lone node at step 4. +the kernel will run a fleet, and goes with the lone node at step 5. ## 4. What was built on the detour | Built 2026-10-05 | What becomes of it | |---|---| -| `kernel_main.c` calling `sk_v4_run()` before the fleet tables | Goes at step 4. Until then it is how the bare-metal build is kept booting while the interface is built. | -| `v4/system/boot.c`: its own capsule loader and `PARITY:V4_*` lines | Goes at step 4, when v3's birth protocol loads the capsules and prints v3's parity lines. | +| `kernel_main.c` calling `sk_v4_run()` before the fleet tables | Goes at step 5. Until then it is how the bare-metal build is kept booting while the interface is built. | +| `v4/system/boot.c`: its own capsule loader and `PARITY:V4_*` lines | Goes at step 5, when v3's birth protocol loads the capsules and prints v3's parity lines. | | The node's prompt loop, and the code that strips ` ok` from its output | Goes at step 1. | | `capsules/v4/forth79.4th`, `post79.4th`, `mkpost.py`, the rules | Stay. POST is the gate for every word moved out of the nucleus. | | `(CATCH)`, `(EMIT-HOOK)`, `NODE-ERROR` by name | Stay; POST uses them. | | The per-call-target count (`v4/src/heat.c`, `call[]`) | Goes at step 3, when the node does at `call` what v3 does. | -| The hosted Linux product | Stays, on the same interface. Hosted v3 has no fleet and neither has hosted v4. | +| The hosted Linux product, as `v4/tools/hosted.c` | Goes at step 4: the hosted product is v3's hosted program with the node as its interpreter (3c). | ## 5. Steps @@ -214,14 +275,18 @@ its logs. 3. **A word is being executed (3.5).** The hook at `call`; the ACL's countdown and recheck; the word's count; `stadium_word_dispatch`. In-line words become calls. The per-call-target count goes. -4. **In place.** Under `STARFORTH_V4` the kernel's own boot brings the - node up where it brings a v3 VM up, after the fleet tables; the - kernel's REPL drives it; blocks come from the block subsystem. - `sk_v4_run()` and `boot.c` go. -5. **Hera as v3 has her.** `init.4th` runs on the node; v3's whole POST; - v3's parity lines. -6. **The fleet.** Hestia and Artemis; message delivery; the switcher. -7. **Identity and the prompt.** Zuse; `[zuse@Hera] ok>`. +4. **The node as v3's interpreter, hosted.** The third interpreter file + (3c). v3's hosted program built with it: `vm_interpret` hands the node + the line; `register_word` makes a kernel word and its record; the + node's own words get records. It reaches v3's prompt. v3's POST runs + through it and its failures are the list of what is not yet there. +5. **The same, in the kernel.** Under `STARFORTH_V4` the kernel's boot + brings the node up where it brings a v3 VM up. `sk_v4_run()`, + `boot.c` and `hosted.c` go. +6. **Hera as v3 has her.** `init.4th` runs on the node; v3's whole POST + passes; v3's parity lines. +7. **The fleet.** Hestia and Artemis; message delivery; who runs next. +8. **Identity and the prompt.** Zuse; `[zuse@Hera] ok>`. Moving words from the assembled nucleus to `forth79.4th` goes on beside these, a group at a time, with POST after each. @@ -233,7 +298,7 @@ these, a group at a time, with POST after each. | How the node tells a dictionary entry from a bare address at `call` | Step 3 | | `EXECUTE`, which enters a word by a return | Step 3 | | `>R R> R@ I J LEAVE`, which cannot be called | Step 3 | -| Who decides which node runs next, and when: Hera, by compudynamics; preemptive and cooperative | Step 6 | -| The node's safe moment for message delivery and switching | Step 6 | -| `PAD 42 OVER !`, a byte address given to `!` (D-1) | Step 5 | +| Who decides which node runs next, and when: Hera, by compudynamics; preemptive and cooperative | Step 7 | +| The node's safe moment for message delivery and switching | Step 7 | +| `PAD 42 OVER !`, a byte address given to `!` (D-1) | Step 6 | | Which word patrons' accounts the hosted product keeps, having no Stadium | Step 3 |