re: close the ISL operand chain -- built-in result is special[0], via a vtable
Answers what the previous commit left open: naming the branches did not give a clear condition, because that needs the operand chain feeding each compare. First, a correction to my own work. isl-bytecode.md -- which OWNS the opcode table -- already named ops 21-24 push.i/push.f/pop.i/pop.f. isl-branches.md, which I wrote last iteration, said op21 and op23 were unread. The stale file was mine. Verified from the thunks rather than accepted: 21 pushes [phase+168] onto the deque at phase+44, 22 pushes [phase+184] onto phase+64, and the 23/24 handlers touch only r3+168 and r3+184. So pop.i lands in special[1]. New: the 147-entry built-in table is a thin DISPATCH LAYER, not implementations. Each stub resolves the local[] argument base and tail-calls a fixed ScriptPhase vtable slot. 112 of 147 dispatch that way; 17 write [phase+164] inline; 0 write +184. Every named predicate is in the vtable group -- unit_state 184, unit_alive 188, hp_pct_test 64, dist_lt 56, is_engaged 252, timer_elapsed 372 -- which is the control that the split separates engine queries from script bookkeeping. The vtable is 0x820A84BC, derived from a known implementation rather than a stride: MARK_LAST_PHASE is documented as [phase+300]=2; the function 0x8226B498 is exactly that stub; it appears as a data word at exactly one address, 0x820A8570; built-in 39 uses slot 180. The check NOT used in the derivation: built-in 40 mark_not_last uses slot 176, and slot 176 holds the [phase+300]=1 stub. Predicted and confirmed. The db's own vptr_writes independently lists 0x820A84BC, written at 0x82261B80. unit_state = slot 184 = 0x8226ADF0, which indexes [phase+324] by local[4] and writes its answer to [phase+164] = special[0] at both exits. The phase-3 poll loop now reads end to end: unit_state(ADT308) -> special[0]; pop.i -> special[1]; cmp.i; beq. isl.py names ops 21-24; the calls artefact regenerates with NO diff. Left open and said so: the other 111 vtable slots, which comparand each site pushes, the 35 non-vtable built-ins, and the vtable's length.
This commit is contained in:
@@ -1396,11 +1396,25 @@ premise was wrong.**
|
||||
`beq/bne/blt/ble/bgt/bge` on those bits, targeting `[phase+232] + word@+4`
|
||||
exactly like `op12`. All six relations present, each once — the completeness is
|
||||
the check. Handler addresses come from the `bl` inside each dispatcher thunk;
|
||||
guessing them at a fixed stride lands mid-function. ▶️ **Still open:** `op23`
|
||||
guessing them at a fixed stride lands mid-function. ~~▶️ **Still open:** `op23`
|
||||
(`0x82271C30`, takes a built-in's result to `phase+168`) and `op21`
|
||||
(`0x82175C20`) are characterised but NOT named, and naming the branch does not
|
||||
yet give each stage's clear condition — that needs the operand chain feeding
|
||||
each compare. The condition lives in the `op10`/`op13` poll loop upstream of
|
||||
each compare.~~ ✅ **(2026-08-27) THE OPERAND CHAIN IS CLOSED —
|
||||
[structures/isl-builtin-dispatch](structures/isl-builtin-dispatch.md).**
|
||||
⚠️ op21/op23 were already named in `isl-bytecode.md` (the owning file) as
|
||||
`push.i`/`pop.i`; my `isl-branches.md` was the stale one. Verified and
|
||||
reconciled. NEW: the 147-entry built-in table is a **thin dispatch layer** —
|
||||
**112 of 147** stubs tail-call a fixed slot of the `ScriptPhase` vtable, and
|
||||
every named predicate is in that group. The vtable is **`0x820A84BC`**,
|
||||
derived from `MARK_LAST_PHASE`'s known `[phase+300]=2` stub and confirmed by
|
||||
an unused-in-the-derivation prediction (slot 176 = the `=1` stub) plus the
|
||||
db's own `vptr_writes`. `unit_state` = slot 184 = `0x8226ADF0`, which indexes
|
||||
`[phase+324]` by `local[4]` and writes its answer to **`[phase+164]` =
|
||||
`special[0]`**. So: **result → `special[0]`, comparand popped → `special[1]`,
|
||||
then `cmp.i` + branch.** ▶️ **Still open:** the other 111 vtable slots are a
|
||||
lookup but unread; which comparand each site pushes (needs `push.i` tracked
|
||||
through the decode); the 35 non-vtable built-ins; the vtable's length. The condition lives in the `op10`/`op13` poll loop upstream of
|
||||
the outro — e.g. phase 3 polls `unit_state(ADT308)` and branches back to
|
||||
`0xFEB4` until it passes. Artefact: `data/isl-stage02-phase-ends.txt`.
|
||||
* 🐛 **(2026-08-25) The nav fix is NOT fully reliable.** `dialog_up.py` works on
|
||||
|
||||
Reference in New Issue
Block a user