Stage G: SEND, and two workers interleave; decision compares work heat (FABRIC-3.8 §3.8, §3.13.7)
SEND ( paddr plen name-c name-u -- ok? ): general kernel-Hermes send to a named VM, from = calling VM, one block max (refused, not truncated), every VM. New SK_HERMES_MSG_TYPE_SEND (30). Ruling C-4 (beta), Captain Bob: the switch decision compares work heat -- the heat each VM pulled in by its own per-beat charges -- not absolute heat, so Hera's structural endowment no longer makes her hottest. Before it, the two-worker test ran serial (AAAA...BBBB); after it, byte-identical on amd64/aarch64/riscv64: AAABBBBBBBBAAAAAAAABBBBBAAAAABBBBBAAAAABBBBBAAAAABBBBBAAAAABBBBBAAAAABBBBBAAAABB (40 A, 40 B, 16 runs; ordinary words only, nothing yields). Acceptance: relay 3, idle growth 0; dict_hash set changed by the new word (word_count 533) and identical across ISAs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c7185facf0
commit
81def7b4a5
+125
-2
@@ -666,6 +666,55 @@ without §3.7's idle point** (Stage F):
|
||||
the idle point she is eligible when input is pending (the REPL's own input poll), exactly as a
|
||||
worker is eligible when its kernel-Hermes queue is non-empty. **Ruling C-5**, below.
|
||||
|
||||
#### 3.13.7 Finding at Stage G: under C-4 (α), a sender can't dispatch a batch (2026-09-23)
|
||||
|
||||
`SEND` is built (§3.8). The naive interleave test, typed at `[zuse@Hera] ok>` with ordinary
|
||||
words only (`logs/20260923-201602/amd64/`):
|
||||
|
||||
```
|
||||
S" workload-1-lite.4th" S" wa" WORKER-BIRTH . → 1
|
||||
S" workload-1-lite.4th" S" wb" WORKER-BIRTH . → 1
|
||||
S" : LA 40 0 DO 65 EMIT 300 0 DO LOOP LOOP ; LA" S" wa" SEND . S" : LB 40 0 DO 66 EMIT 300 0 DO LOOP LOOP ; LB" S" wb" SEND .
|
||||
→ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1 BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB1 ok
|
||||
```
|
||||
|
||||
`SEND` works: each payload is delivered by a switch and runs on the worker's own stack. But the
|
||||
run is **serial**, and the mechanism is exactly C-4 (α):
|
||||
|
||||
- The first `SEND` makes `wa` eligible at heat 0.
|
||||
- Hera (heat ≈ `Q48_ONE`) is displaced at her next owned checkpoint, before she even prints that
|
||||
`SEND`'s `1`.
|
||||
- She is eligible only as "parked mid-task" and is the hottest VM, so she gets the CPU back only
|
||||
once `wa` has no work left. Then she sends to `wb`.
|
||||
|
||||
The rebuilt DoE driver (Stage H) would serialize the same way: it is Hera sending to N workers in
|
||||
a loop. So would the console under load (already recorded under C-b).
|
||||
|
||||
**Needs Captain Bob's ruling (C-4 reopened):**
|
||||
|
||||
- **(β) compare work heat, not absolute heat.** Work heat is each VM's cumulative heat pulled in
|
||||
by its own per-beat charges (Stage C-a). It is conserved-transfer bookkeeping already happening,
|
||||
so no new physics, but it is a different quantity than the one "coolest" has meant so far.
|
||||
Hera's structural endowment doesn't count.
|
||||
- Predicted: Hera keeps the CPU while she has work, because on a tie the incumbent stays and the
|
||||
workers' heat is still 0. She sends both messages, and the workers then alternate by work
|
||||
heat.
|
||||
- Hera with pending console input is cooler than busy workers, so the console gets turns under
|
||||
load.
|
||||
- **(δ) mail arrival stops triggering a decision for the running sender.** Decisions happen only
|
||||
at beats, the trampoline and idle points.
|
||||
- Batches sent within one beat all land before anyone runs.
|
||||
- Where the beat boundary falls decides whether a given batch lands intact. It's deterministic,
|
||||
not guaranteed.
|
||||
- It doesn't address the console starvation.
|
||||
- **(ε) keep (α)** and prove interleaving with a chain instead: worker A's payload `SEND`s B's.
|
||||
That satisfies Stage G's evidence, but leaves the DoE driver and the console serialized.
|
||||
|
||||
**RULED 2026-09-23, Captain Bob: (β) work heat.** The decision compares
|
||||
`vm_physics_work_heat_of()`, not `vm_physics_heat_of()`. Absolute heat still moves, is still
|
||||
conserved, and still appears in the DoE heat columns; it just no longer decides turns. The
|
||||
prediction held on all three ISAs: see the Stage G entry in §6.
|
||||
|
||||
#### 3.13.6 Stage C, split
|
||||
|
||||
This splits the single C row in §4 in two:
|
||||
@@ -715,7 +764,7 @@ QMP `send-key` computing a value, per `FABRIC-3.6.md` task 1.5).
|
||||
phase is the concurrent one). If the latter: new `-def` capsule variants, or strip the tail
|
||||
call from the existing `workload-N.4th` files (check their other users first, per `FABRIC-3.5.md`
|
||||
§XXII.2's three reachability routes)?
|
||||
3. **The send word's name** (§3.8): `SEND`, `HERMES-SEND`, `KH-SEND`, something else.
|
||||
3. **The send word's name** (§3.8) — **RULED 2026-09-23: `SEND`.**
|
||||
4. **The multiuser factor.** The DoE as built varies concurrency × workload mode and runs once
|
||||
per ISA. `FABRIC-3.md` §XXXIII.2 planned identity origin as a fixed arm, never built. Should
|
||||
identities (`UNATTENDED-BIRTH` capsule identities, or WIREBIND thumbdrives) become a crossed
|
||||
@@ -733,7 +782,8 @@ QMP `send-key` computing a value, per `FABRIC-3.6.md` task 1.5).
|
||||
8. **C-3 (§3.13.3):** ties. The incumbent stays on a tie with itself. Among several candidates:
|
||||
whether "waiting longest," by a single-writer arrival stamp, is acceptable under *"no scheduler
|
||||
allowed,"* or whether Bob wants something else. Slot, UUID and registry order are rejected.
|
||||
9. **C-4 (§3.13.2):** Hera's reservoir mass means the console gets no turn under worker load.
|
||||
9. **C-4 (§3.13.2) — RULED 2026-09-23: (β) work heat** (§3.13.7; first taken as (α) at C-b,
|
||||
reopened at Stage G). Hera's reservoir mass means the console gets no turn under worker load.
|
||||
Options are (α) accept it, (β) compare charged heat instead of absolute heat, or (γ) something
|
||||
else. No recommendation.
|
||||
10. **C-5 (§3.13.5):** fold the idle point (Stage F's §3.7) into C-b, since the relay can't be
|
||||
@@ -1103,3 +1153,76 @@ explicit instruction.
|
||||
**What this makes possible (not exercised yet):** every `WORKER-BIRTH`ed DoE worker is now
|
||||
a participant. Mail sent to a worker is delivered by a switch onto its own stack, and it
|
||||
competes by heat. Stage G's `SEND` word and interleave test are next.
|
||||
- [x] **Stage G — `SEND`, and two workers interleave (§3.8, §3.13.7).** 2026-09-23. Captain
|
||||
Bob: *"SEND, go ahead with stage G"*, then ruling C-4 (β), work heat, when the first run
|
||||
came out serial.
|
||||
|
||||
Changes:
|
||||
- `repl.c`: new `SEND ( paddr plen name-c name-u -- ok? )`, registered for every VM
|
||||
through the standard word set (`sk_repl_register_words`).
|
||||
- It resolves the target by registry name, copies the payload (at most 1023 chars plus
|
||||
the NUL; oversized payloads are **refused, not truncated**), and calls
|
||||
`sk_hermes_send_one()`. That stamps the message and sets decision-due (C-b).
|
||||
- `from` is the calling VM, derived in C, never taken from the stack.
|
||||
- It returns 1 if admitted, 0 if refused.
|
||||
- No C-side restriction; ACL is `ACL.4th`'s job.
|
||||
- `kernel_hermes.h`: new `SK_HERMES_MSG_TYPE_SEND` (30), clear of every older type space.
|
||||
- **C-4 (β):**
|
||||
- `capsule_vm_physics.c/.h`: a per-VM `work_heat_q48` accumulates what each of the VM's
|
||||
own per-beat charges actually moved in. Read with `vm_physics_work_heat_of()`.
|
||||
- `sk_vm_switch_decide()` compares work heat for candidates and for the incumbent.
|
||||
|
||||
**First run, before (β):** `logs/20260923-201602/amd64/`, the §3.13.7 finding. It came
|
||||
out `AAAA…A1 BBBB…B1`, serial.
|
||||
|
||||
**Evidence, as named in §4.** Only ordinary words, typed at `[zuse@Hera] ok>`, no probe:
|
||||
```
|
||||
S" workload-1-lite.4th" S" wa" WORKER-BIRTH .
|
||||
S" workload-1-lite.4th" S" wb" WORKER-BIRTH .
|
||||
S" : LA 40 0 DO 65 EMIT 300 0 DO LOOP LOOP ; LA" S" wa" SEND . S" : LB 40 0 DO 66 EMIT 300 0 DO LOOP LOOP ; LB" S" wb" SEND .
|
||||
```
|
||||
Result, **byte-identical on all three ISAs** (`logs/20260923-202403/amd64/`,
|
||||
`-204054/aarch64/`, `-205150/riscv64/`):
|
||||
```
|
||||
[zuse@Hera] 1 1 ok
|
||||
[zuse@Hera] ok> AAABBBBBBBBAAAAAAAABBBBBAAAAABBBBBAAAAABBBBBAAAAABBBBBAAAAABBBBBAAAAABBBBBAAAABB
|
||||
```
|
||||
- **A = 40, B = 40, in 16 alternating runs.**
|
||||
- Hera kept the CPU while she had work (work heat tied at ~0, so the incumbent stays), and
|
||||
both sends landed.
|
||||
- From her idle point, `wa` and `wb` took turns. Each switch came from the per-beat charge
|
||||
making the runner strictly hotter by work heat.
|
||||
- Nothing in either payload asks to yield.
|
||||
- The sequence is deterministic across ISAs, as the execution-paced beat implies.
|
||||
|
||||
**Acceptance,** in the same three boots, after the interleave test with both workers still
|
||||
alive:
|
||||
- All reach `[zuse@Hera] ok>` with zero `UNKNOWN WORD`, failures and faults.
|
||||
- Mint → WIREBIND → `USE` → `1 2 + .` → `3`, with `stadium_conserved(self)=true`.
|
||||
- Idle log growth: 0 bytes.
|
||||
- **The `dict_hash` set changes, as expected, because `SEND` is a new word in every VM's
|
||||
dictionary, and is identical across all three ISAs.**
|
||||
|
||||
| | New | Stages A–E |
|
||||
|---|---|---|
|
||||
| `word_count` | 533 | 532 |
|
||||
| M7.1a | `0x330b28ce0f4e1c75` | `0x3933d76939ef66c6` |
|
||||
| Hera | `0x0bf15066a73f6e32` | `0x27ba08011349842b` |
|
||||
| Hestia | `0x9116e19b34d2cb0b` | `0xdd1aa879b3a6c5df` |
|
||||
| Artemis | `0x165a9a66eafce131` | `0xe9d0408b1119d51f` |
|
||||
|
||||
- Clean build on all three plus hosted, no new warnings.
|
||||
|
||||
**Harness note (not a kernel change):** the first aarch64 attempt
|
||||
(`logs/20260923-203226/aarch64/`, kept) typed the next line while Hera was still birthing
|
||||
`wa`. Serial input received while Hera isn't polling is dropped, so the line arrived
|
||||
truncated (`S" workload-1-li…`) and gave `UNKNOWN WORD`. My test script now waits for each
|
||||
prompt before typing. Serial input is lost while the console isn't reading, which is the
|
||||
pre-existing behaviour.
|
||||
|
||||
**Consequences of (β) to know:**
|
||||
- Work heat only grows. A long-lived VM that has done a lot of work loses ties to newer
|
||||
ones until they catch up.
|
||||
- Hera's work heat grows only when other VMs hold absolute heat for her charges to pull
|
||||
from. She runs cheaply while they hold ~0.
|
||||
- Both are properties of the ruled quantity, recorded here, not changed.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Capsule Block Manifest — Auto-generated
|
||||
<!-- Generated by mkcapsule --manifest 2026-09-23T23:59:50Z -->
|
||||
<!-- Generated by mkcapsule --manifest 2026-09-24T00:51:15Z -->
|
||||
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
||||
<!-- Hand-written justifications and immutability notes live -->
|
||||
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
||||
|
||||
@@ -111,6 +111,18 @@ void vm_physics_touch(VMUuid vm_id);
|
||||
*/
|
||||
void vm_physics_charge(VMUuid vm_id);
|
||||
|
||||
/**
|
||||
* vm_physics_work_heat_of - Cumulative heat a VM has pulled in by working
|
||||
*
|
||||
* FABRIC-3.8.md §3.13.7, ruling C-4 (β), Captain Bob 2026-09-23: the sum of
|
||||
* every transfer vm_physics_charge() actually moved INTO this VM -- heat
|
||||
* earned by its own work, independent of any structural endowment (Hera's
|
||||
* initial Q48_ONE). This is the quantity the switch decision compares
|
||||
* ("coolest VM with work" = least work heat). Only grows; 0 for an unknown
|
||||
* or dead VM.
|
||||
*/
|
||||
uint64_t vm_physics_work_heat_of(VMUuid vm_id);
|
||||
|
||||
/**
|
||||
* vm_physics_tick - Heartbeat-gated inference pass
|
||||
*
|
||||
|
||||
@@ -138,7 +138,9 @@ int sk_vm_switch_signal_take_decision_due(void);
|
||||
* Among registered participants other than `self` that have work -- a
|
||||
* pending kernel-Hermes message, or parked on their own stack mid-task
|
||||
* (top frame not VM_FRAME_IDLE), or (Hera only) pending console input --
|
||||
* returns the one with the lowest VM-physics heat; among equally cool
|
||||
* returns the one with the lowest work heat (vm_physics_work_heat_of(): heat
|
||||
* earned by its own per-beat charges -- ruling C-4 (β), FABRIC-3.8.md
|
||||
* §3.13.7; Hera's structural endowment doesn't count); among equally cool
|
||||
* candidates, the one waiting longest (unique wait stamps). With
|
||||
* self_competes set (the caller still has work), returns a candidate only
|
||||
* if it is strictly cooler than `self`. Returns NULL when nobody should
|
||||
|
||||
@@ -752,6 +752,14 @@ int sk_hermes_reassemble(SkHermesMessage **chunks, int n_chunks,
|
||||
* Phase 4 entry. */
|
||||
#define SK_HERMES_MSG_TYPE_ELEVATE_REQUEST 8
|
||||
|
||||
/* SK_HERMES_MSG_TYPE_SEND (FABRIC-3.8.md §3.8, Stage G, 2026-09-23) --
|
||||
* a general message from the FORTH SEND word (repl.c): payload is FORTH
|
||||
* text the recipient interprets, like CONSOLE_CMD, but from any VM to any
|
||||
* VM. A fresh kernel-Hermes-space value, clear of messaging.4th's old type
|
||||
* space and the negotiation types (20-24) listed below -- no FORTH-side
|
||||
* type ever existed for it to reuse. */
|
||||
#define SK_HERMES_MSG_TYPE_SEND 30
|
||||
|
||||
/* The five negotiation types above (20-24) were chosen clear of
|
||||
* messaging.4th's own live/reserved type space (PAUSE-EVENT=2,
|
||||
* RESUME-EVENT=3, KILL-EVENT=4, CONSOLE-CMD-EVENT=7, ELEVATE-REQUEST=8,
|
||||
|
||||
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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -67,6 +67,16 @@ typedef struct {
|
||||
* FABRIC-3.8.md §3.13.2: kept, never truncated
|
||||
* away, so a one-beat charge (slope < 1 unit)
|
||||
* still moves heat once enough beats accrue */
|
||||
uint64_t work_heat_q48; /* FABRIC-3.8.md §3.13.7, ruling C-4 (β), Captain
|
||||
* Bob 2026-09-23: cumulative heat this VM has
|
||||
* pulled in through its OWN per-beat charges --
|
||||
* heat earned by working. The switch decision
|
||||
* compares this, not execution_heat_q48, so
|
||||
* Hera's structural endowment (all of Q48_ONE
|
||||
* at init) never counts against her. Only ever
|
||||
* grows; a record of transfers that already
|
||||
* happened, not heat of its own (fleet K is
|
||||
* unaffected). */
|
||||
} VMPhysics;
|
||||
|
||||
typedef struct vm_physics_node {
|
||||
@@ -208,6 +218,7 @@ void vm_physics_init(VMUuid vm_id)
|
||||
node->physics.touched = 0;
|
||||
node->physics.is_live = 1;
|
||||
node->physics.charge_carry = 0;
|
||||
node->physics.work_heat_q48 = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -220,6 +231,7 @@ void vm_physics_init(VMUuid vm_id)
|
||||
node->physics.touched = 0;
|
||||
node->physics.is_live = 1;
|
||||
node->physics.charge_carry = 0;
|
||||
node->physics.work_heat_q48 = 0;
|
||||
node->next = vm_physics_head;
|
||||
vm_physics_head = node;
|
||||
}
|
||||
@@ -407,6 +419,16 @@ void vm_physics_charge(VMUuid vm_id)
|
||||
* vanishing. Conservation is unaffected either way -- only what
|
||||
* vm_physics_transfer() actually moved ever changed any heat. */
|
||||
target->physics.charge_carry += (moved_total - moved) << 16;
|
||||
|
||||
/* §3.13.7 (β): what this VM's own work actually pulled in. */
|
||||
target->physics.work_heat_q48 += moved;
|
||||
}
|
||||
|
||||
uint64_t vm_physics_work_heat_of(VMUuid vm_id)
|
||||
{
|
||||
vm_physics_node_t *n = vm_physics_find(vm_id);
|
||||
if (!n || !n->physics.is_live) return 0;
|
||||
return n->physics.work_heat_q48;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "starkernel/kmalloc.h"
|
||||
#include "starkernel/console.h"
|
||||
#include "starkernel/capsule_birth.h" /* registry, capsule_vm_force_reap() */
|
||||
#include "starkernel/capsule_vm_physics.h" /* vm_physics_heat_of() -- the decision's heat */
|
||||
#include "starkernel/capsule_vm_physics.h" /* vm_physics_work_heat_of() -- the decision's heat (C-4 β) */
|
||||
#include "starkernel/vm/kernel_hermes.h" /* sk_hermes_pending_peek() -- eligibility is the queue */
|
||||
#include "starkernel/vm/vm_frame.h" /* top frame kind -- in progress vs parked idle */
|
||||
#include "starkernel/vm/bootstrap/sk_vm_bootstrap.h" /* sk_get_mama_vm() */
|
||||
@@ -222,7 +222,10 @@ static int candidate_standing(VM *v, VM *mama, uint64_t parked_stamp,
|
||||
}
|
||||
}
|
||||
if (!eligible) return 0;
|
||||
*heat_out = vm_physics_heat_of(v->stadium_vm_id);
|
||||
/* §3.13.7, ruling C-4 (β): work heat -- heat earned by this VM's own
|
||||
* work -- not absolute heat, so Hera's structural endowment never
|
||||
* makes her the "hottest" VM by construction. */
|
||||
*heat_out = vm_physics_work_heat_of(v->stadium_vm_id);
|
||||
*stamp_out = stamp;
|
||||
return 1;
|
||||
}
|
||||
@@ -260,7 +263,7 @@ VM *sk_vm_switch_decide(VM *self, int self_competes) {
|
||||
/* A running VM that still has work keeps the CPU unless the best
|
||||
* candidate is strictly cooler: a tie with the incumbent is "no reason
|
||||
* to move," not a coin toss (ruling C-3). */
|
||||
if (best && self_competes && !(best_heat < vm_physics_heat_of(self->stadium_vm_id))) {
|
||||
if (best && self_competes && !(best_heat < vm_physics_work_heat_of(self->stadium_vm_id))) {
|
||||
return (VM *)0;
|
||||
}
|
||||
return best;
|
||||
|
||||
@@ -489,10 +489,73 @@ static void sk_word_kh_elevate_send(VM *vm) {
|
||||
vm_push(vm, rc == 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
/* FABRIC-3.8.md §3.8 (Stage G, 2026-09-23; name ruled by Captain Bob:
|
||||
* "SEND"). SEND ( paddr plen name-c name-u -- ok? ): the general
|
||||
* FORTH-callable kernel-Hermes send. Delivers a copy of the payload text
|
||||
* to the VM named name-c/name-u, where it is interpreted -- on that VM's own
|
||||
* native stack, by a switch, once the compudynamic decision chooses it.
|
||||
* `from` is the calling VM, derived here, never taken from the stack (the
|
||||
* anti-spoof rule KH-ELEVATE-SEND established). Bounded to one block of
|
||||
* text (the payload is sent NUL-terminated, so at most
|
||||
* SK_HERMES_CHUNK_MAX_PAYLOAD - 1 characters); an oversized payload is
|
||||
* refused, not truncated -- truncated code would run as different code.
|
||||
* A plain, unconditional primitive: restricting who may SEND is ACL.4th's
|
||||
* job, never a C check. Returns 1 if admitted, 0 if refused (no such VM,
|
||||
* dead, oversized, bad address, or kernel-Hermes refused: queue full or the
|
||||
* sender's reservoir can't fund it). */
|
||||
static char g_send_buf[SK_HERMES_CHUNK_MAX_PAYLOAD];
|
||||
|
||||
static void sk_word_send(VM *vm) {
|
||||
cell_t name_u, name_c, plen, paddr;
|
||||
char name[VM_NAME_MAX];
|
||||
VMRegistryEntry target;
|
||||
const char *src;
|
||||
int i, rc;
|
||||
|
||||
if (vm->dsp < 3) {
|
||||
console_println("SEND: expects paddr plen S\" name\" SEND");
|
||||
vm->error = 1;
|
||||
return;
|
||||
}
|
||||
name_u = vm_pop(vm);
|
||||
name_c = vm_pop(vm);
|
||||
plen = vm_pop(vm);
|
||||
paddr = vm_pop(vm);
|
||||
|
||||
if (name_u <= 0 || (uint32_t)name_u >= VM_NAME_MAX ||
|
||||
plen < 0 || plen > SK_HERMES_CHUNK_MAX_PAYLOAD - 1) {
|
||||
vm_push(vm, 0);
|
||||
return;
|
||||
}
|
||||
src = (const char *)vm_ptr(vm, (vaddr_t)name_c);
|
||||
if (!src) { vm_push(vm, 0); return; }
|
||||
for (i = 0; i < (int)name_u; i++) name[i] = src[i];
|
||||
name[name_u] = '\0';
|
||||
|
||||
if (capsule_vm_find_by_name_nocase(name, &target) != 0 || !target.vm_ptr ||
|
||||
target.state == VM_STATE_DEAD || target.state == VM_STATE_STILLBORN) {
|
||||
vm_push(vm, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (plen > 0) {
|
||||
src = (const char *)vm_ptr(vm, (vaddr_t)paddr);
|
||||
if (!src) { vm_push(vm, 0); return; }
|
||||
for (i = 0; i < (int)plen; i++) g_send_buf[i] = src[i];
|
||||
}
|
||||
g_send_buf[plen] = '\0';
|
||||
|
||||
rc = sk_hermes_send_one(vm->stadium_vm_id, target.vm_id,
|
||||
SK_HERMES_MSG_TYPE_SEND, 0,
|
||||
g_send_buf, (uint32_t)(plen + 1));
|
||||
vm_push(vm, rc == 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
void sk_repl_register_words(VM *vm) {
|
||||
register_word(vm, "BLK-ATTACH-ACK", sk_word_blk_attach_ack);
|
||||
register_word(vm, "KH-BLK-ATTACH-SEND", sk_word_kh_blk_attach_send);
|
||||
register_word(vm, "KH-ELEVATE-SEND", sk_word_kh_elevate_send);
|
||||
register_word(vm, "SEND", sk_word_send); /* FABRIC-3.8.md §3.8 */
|
||||
}
|
||||
|
||||
/*===========================================================================
|
||||
|
||||
Reference in New Issue
Block a user