docs(v4): heat.c's and the stacks' comments say what the code does (#181)
- heat.c call_index(): the comment read as an unfinished thought ("hash-mod or
just take low bits?", "ignore for now? Or clamp?"). It now states the rule
the code follows: indexed by the target, a target past the table not counted,
-1 telling the callers so; the table D-6's stand-in, which ENGINE step 4
Part A1 plans to remove.
- stack.h points 1 and 2 said there was no overflow detection "and there never
will be" and that a depth exceeded corrupted silently -- D-2, which D-16
revised. Now: guarded before every opcode, a mesh node 10 and 9, the host node
32 and 32 (D-17); C code that serves a node checks the depth itself.
- stack.c named an 8-ring and depths 10 and 9 only, and said D-2's rule still
held.
- DATASHEET-F18.md section 13 item 4 (this gap) struck, resolved in place.
Comments only: test_stack and test_heat unchanged at both widths (730,137 and
8,272 checks, 0 failures).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017RzZgrf7V7Zk2iczBXDRbm
This commit is contained in:
+8
-14
@@ -24,21 +24,15 @@ void v4_heat_on_retire(v4_heat *h, unsigned op, v4_uheat_t *anticlock)
|
||||
|
||||
static unsigned call_index(v4_cell target)
|
||||
{
|
||||
/* Index by target address. The table is a fixed-size cache for the model.
|
||||
* A real hardware table is deferred; here we hash-mod or just take low bits?
|
||||
* Or simply if in range use it. The spec says "per-call-target heat table"
|
||||
* indexed by target. For golden model, targets are small (node memory). */
|
||||
/* The per-call-target heat table is the golden model's stand-in until D-6 rules which
|
||||
* heat structures exist in hardware (DECOMPOSITION.md D-6). It is indexed by the call's
|
||||
* target address itself, V4_HEAT_MAX_CALL_TARGETS slots. A target at or past that has
|
||||
* no slot: it is not counted, and (unsigned)-1 tells the callers so -- they then record
|
||||
* nothing and read 0, rather than counting it in another target's slot. ENGINE.md step 4,
|
||||
* Part A1, plans to remove the table with v4_heat_on_call (corrected 2026-11-12, #181:
|
||||
* this comment read as an unfinished question). */
|
||||
unsigned idx = (unsigned)(v4_ucell)target;
|
||||
if (idx >= V4_HEAT_MAX_CALL_TARGETS) {
|
||||
/* Out of range: ignore for now? Or clamp? D-6 deferred; but heat must
|
||||
* be recorded for actual call targets exercised. Many tests will have
|
||||
* targets < 4096. This is a conservative model choice: if target is
|
||||
* outside the modeled table, we do not increment a modeled slot (and
|
||||
* we could log, but not specified). The boundary philosophy says detect
|
||||
* rather than corrupt: for the model, we just don't record in the fixed
|
||||
* table -- acceptable until D-4/D-6 pin sizes. */
|
||||
return (unsigned)-1; /* invalid */
|
||||
}
|
||||
if (idx >= V4_HEAT_MAX_CALL_TARGETS) return (unsigned)-1;
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
+12
-6
@@ -3,8 +3,11 @@
|
||||
*/
|
||||
/* stack.c -- F18 circular hardware stacks.
|
||||
*
|
||||
* The two decompositions (T/S + 8-ring, R + 8-ring) are exactly equivalent to
|
||||
* flat circular buffers of depth 10 and 9 respectively. The argument, since
|
||||
* The two decompositions (T/S + ring, R + ring) are exactly equivalent to flat
|
||||
* circular buffers of depth V4_DATA_RING + 2 and V4_RET_RING + 1 -- 10 and 9 on
|
||||
* a mesh node, as the F18, with an 8-cell ring; 32 and 32 on the host node
|
||||
* (D-17). The argument below is written for a mesh node's 8, "mod 8" meaning
|
||||
* mod the ring size (corrected 2026-11-12, #181: it named 8 only). The argument, since
|
||||
* the ISA is specified in terms of the decomposition and the differential
|
||||
* test in tests/test_stack.c is written against the flat form:
|
||||
*
|
||||
@@ -24,10 +27,13 @@
|
||||
* Return stack, 9 deep, same argument with one register instead of two: the
|
||||
* stack reads R, ring[(head-1) mod 8], ..., ring[head mod 8].
|
||||
*
|
||||
* "No overflow or underflow; pushing past the bottom silently overwrites the
|
||||
* oldest entry" (D-2) is not an extra rule here -- it is what a fixed-depth
|
||||
* circular buffer with no bounds check does on its own, once the pointer is
|
||||
* allowed to wrap. Nothing below tests head against anything.
|
||||
* Nothing below tests head against anything: a push past the bottom overwrites
|
||||
* the oldest entry, which is what a fixed-depth circular buffer does once the
|
||||
* pointer wraps -- D-2's rule. D-16 revised it: each stack also counts what it
|
||||
* holds (depth, kept here but never tested here), and the executor faults
|
||||
* before an opcode would push onto a full stack or pop an empty one (exec.c).
|
||||
* C code that pushes or pops for a node checks the depth itself (manage.c,
|
||||
* blocks.c). (Corrected 2026-11-12, #181: this said D-2's rule still held.)
|
||||
*/
|
||||
#include "v4/stack.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user