Ruled 2026-10-08. The engine, the nucleus and their tests are as they
were at dfabfa46, before step 6d; the code of the wait and its tests are
in history at 075385ab..2cf37aab. The limit of MESH.md 7b.7 stands: a
node that is stuck can hold up its neighbours until Hera kills it.
MESH.md 7c is kept as the record of the design as approved, and 7c.6 says
what was built, what the two reviews found, the cause the findings share
-- a node's message machinery runs on the stacks its text is using, and a
fault abandons whatever was in progress -- and what a second attempt
must settle before anything is built.
Kept from it, in hosted-check: a line that leaves 29 values on the stack,
and WORDS with 26 values on it. Both hung the products at some commit of
the wait.
make -C v4 test and sanitize at both widths, hosted-check, lint; three
bare-metal boots typing both. POST 538 of 538, word_count=317,
dict_hash=0xc0769523a47b7dc3 on all six: the hash of step 6c's code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
99 lines
4.2 KiB
C
99 lines
4.2 KiB
C
/* image.h -- the StarForth nucleus, as its host knows it: where things are
|
|
* in a node that has taken it in, and how a line is handed to that node.
|
|
*
|
|
* The nucleus is text (capsule/ *.v4). tools/mkimage.c assembles it on the
|
|
* build machine and writes two things:
|
|
*
|
|
* - the nucleus as a capsule of F18 code (capsule.h), which is put into
|
|
* an empty node through its port. It is a capsule like any other: in
|
|
* the capsule directory, with a name, a hash and a signature
|
|
* (capsules/v4/nucleus-<width>.f18). docs/v4.0.0/MESH.md section 5.
|
|
* - this description of it, a C file: the addresses a host needs.
|
|
*
|
|
* A node that has taken the nucleus in is sent text as messages and sends
|
|
* back what it prints (v4/include/v4/message.h); nothing here hands it a
|
|
* line.
|
|
*
|
|
* A description is for one cell width, one node size and one pair of stack
|
|
* sizes; v4_image_born refuses one the engine was not built for.
|
|
*/
|
|
#ifndef V4_IMAGE_H
|
|
#define V4_IMAGE_H
|
|
|
|
#include "v4/exec.h"
|
|
|
|
typedef struct {
|
|
/* what the image was built for */
|
|
unsigned cell_bits, node_words, data_ring, ret_ring;
|
|
|
|
/* Where the nucleus waits for a message (v4/capsule/quit.v4, (IDLE)):
|
|
* the node's P is there, blocked reading its ports, when it has nothing
|
|
* to do. */
|
|
v4_cell idle;
|
|
v4_cell fault_table; /* (FAULTS): where a fault goes */
|
|
v4_cell port; /* word address of the node's port (node.h) */
|
|
|
|
/* KEY's code: a node whose P is in key_start .. key_end - 1 with no
|
|
* character pending is waiting for one */
|
|
v4_cell key_start, key_end;
|
|
|
|
/* the memory-mapped registers (DECOMPOSITION.md section 7; D-4 leaves
|
|
* the map to the loader, and this is the map the image was built with) */
|
|
v4_cell console_tx, console_rx, console_status;
|
|
v4_cell dstack_reg, rstack_reg;
|
|
v4_cell node_error;
|
|
|
|
/* the dictionary's two variables: DP holds HERE, a byte address, and
|
|
* LATEST the newest word of FORTH. What lies below HERE, and LATEST,
|
|
* is what the dictionary hash covers (v4/include/v4/boot.h). */
|
|
v4_cell dp, latest;
|
|
|
|
/* What COLD returns the system to and FORGET will not go below: two
|
|
* cells, DP and LATEST as they were when the system was complete, and
|
|
* the variable FENCE. The image has them as the nucleus alone; a system
|
|
* that loads capsules when it boots sets them again when it has
|
|
* (v4_image_seal). */
|
|
v4_cell boot_cells, fence;
|
|
|
|
/* the block window: the word address of the slots the kernel copies
|
|
* blocks into (v4/blocks.h) */
|
|
v4_cell block_window;
|
|
} v4_image;
|
|
|
|
/* The nucleus's error for a node blocked at a port with no one on it
|
|
* (v4/capsule/core.v4's list; node.h, v4_node_port_gone): "No one on that
|
|
* port". */
|
|
#define V4_ERROR_NO_ONE 18
|
|
|
|
/* The nucleus's error for a node let go of a message it was blocked on the
|
|
* first word of, because its console has a line for it (fabric.h,
|
|
* v4_fabric_interrupt_error): "Interrupted". */
|
|
#define V4_ERROR_INTERRUPTED 21
|
|
|
|
/* The description of the nucleus built from v4/capsule (the generated file
|
|
* defines it). */
|
|
extern const v4_image v4_capsule_image;
|
|
|
|
/* The system is complete: what is in the dictionary now is what COLD comes
|
|
* back to, and FORGET will not go below it. */
|
|
void v4_image_seal(v4_node *n, const v4_image *im);
|
|
|
|
/* The dictionary hash of a node started from `im`: FNV-1a over its memory
|
|
* below HERE, a cell at a time, low byte first, and then LATEST. It does
|
|
* not depend on the machine: every build of one commit, with one cell
|
|
* width, gives the same hash for the same dictionary. */
|
|
uint64_t v4_image_dict_hash(const v4_node *n, const v4_image *im);
|
|
|
|
/* A node newly born (node.h), with the registers the nucleus expects of the
|
|
* node it runs on. Its memory is empty and it is blocked
|
|
* reading its ports: the nucleus is yet to be sent to it. Returns 1, or 0
|
|
* if the description is not for this build of the engine (nothing is then
|
|
* done). */
|
|
int v4_image_born(v4_node *n, v4_exec_state *es, v4_heat *h, const v4_image *im);
|
|
|
|
/* 1 if the node is waiting for a character: it is inside KEY and none is
|
|
* pending. */
|
|
int v4_image_waiting(const v4_node *n, const v4_image *im);
|
|
|
|
#endif /* V4_IMAGE_H */
|