The reader is sub_8226E220, called by the per-frame drain sub_8226D740 as
(phase+272, six out-params). It pops one node and copies seven payload fields out.
Built-in 25, the appender, writes exactly those seven offsets:
+0 local[4] -- the unit +24 the constant 1
+4 local[12] +28 local[12] again
+8 computed +32 --
+16 a DOUBLE from local[16]
Neither side was derived from the other, so the agreement is the check. Container:
+16 head, +20 pending count -- which matches the count isl-builtins.md watched live at
phase+272+20 from a completely different direction -- and +24 a cursor.
WITHDRAWN, from the previous commit: "the drain spawns from [node+112]". r31 = r1 -
256, the stack frame, so +112 is an output slot and not a node field.
REFUTED, the follow-up hypothesis that the trigger carries the routine offset and so
names the code nothing else starts: payload+28 is local[12], and across all 25 call
sites disc-wide those values are the small integers 1 through 12 -- 1 of 25 (4.0%)
land on the instruction stream against a 16.0% control, and none are unreached
run-starts. Below chance. My first version of that test used n=2, Stage 02 only; it
happened to agree, but two samples could not have supported it either way.
One correction in the other direction, to the corpus: isl-builtins.md withdrew
sub_8226E458's link to the trigger queue on the grounds that "the argument is
lwz r4, 324(r29), the unit array, not the trigger container". That is the SECOND
argument; the first is r26 = phase + 272, set twelve instructions earlier. The drain
does operate on the container. What sub_8226E458 does to it remains unread, so only
the argument is corrected, not the conclusion.
All artefacts regenerate byte-identical; documentation only.
Still open: what local[12] indexes; what the drain actually spawns, since [stack+112]
is filled from payload+28 yet the spawner wants a code offset, so some step in that
chain is not what I read; and what starts the ~15% of unreached code.
61 lines
2.6 KiB
Markdown
61 lines
2.6 KiB
Markdown
# ✅ `sub_822737C8` is the coroutine spawner — and its seven callers name the whole start-up path
|
|
|
|
Asking *who calls the thing the timeline calls* turns out to enumerate every way
|
|
an ISL routine can begin.
|
|
|
|
`sub_822737C8(phase, base, offset)` — `add r9, r4, r28` computes `base + offset`
|
|
early on, so the third argument is a phase-relative code offset.
|
|
|
|
## The seven call sites
|
|
|
|
| site | in | what it starts |
|
|
|---|---|---|
|
|
| `0x82271030` | **`sub_82270DF8`** — the phase initialiser | the phase's **main entry** (the `0x1883` record's third word) |
|
|
| `0x822724D0` | the built-in stub region | `start_coroutine`'s target |
|
|
| `0x82274934` | **`sub_822748D0`** — the timeline walker | a scheduled routine |
|
|
| **`0x8226D8D0`** | **`sub_8226D740`** — the per-frame engine→script drain | an offset from **`[node+112]`** |
|
|
| **`0x8226DA10`** | the same drain, second path | the same `[node+112]` |
|
|
| `0x82273938` | `sub_82273910` | not read |
|
|
| `0x82264080` | `sub_82264058` | not read |
|
|
|
|
## ✅ The phase's main entry — a correction
|
|
|
|
`isl-stream-entry-points.md` called the record's third word a **size**. It is
|
|
not: the initialiser hands it to the spawner as an offset.
|
|
|
|
* **44 of 44 records land on the instruction stream — 100 %, against a 25.0 %
|
|
control.**
|
|
* All three of Stage 02's targets begin with the same prologue,
|
|
`special[0] = 0 ; local[0] = 0 ; call builtin116(0)`, which is a routine entry
|
|
and not a length.
|
|
|
|
So the record reads `0x1883, base, MAIN_ENTRY, 0, code_end, force_end_handler`.
|
|
|
|
🟡 Seeding it changes nothing measurable — every main entry was **already**
|
|
among the CFG's entry points by another route — so this corrects the *meaning*
|
|
of a field without moving any coverage number.
|
|
|
|
## 🔴 WITHDRAWN: "the drain spawns from `[node+112]`"
|
|
|
|
The two calls inside `sub_8226D740` both do
|
|
|
|
```
|
|
lwz r5, 112(r31) ; the routine offset, out of the node
|
|
lwz r4, 232(r29) ; the phase's code base
|
|
bl 0x822737C8
|
|
```
|
|
|
|
**`r31 = r1 - 256`** — it is the **stack frame**, so `+112` is an output slot,
|
|
not a node field. See [structures/isl-trigger-node](structures/isl-trigger-node.md),
|
|
which reads the node properly and also refutes the follow-up hypothesis that the
|
|
trigger carries a routine offset.
|
|
|
|
## 🟡 Not settled
|
|
|
|
* **`+112` is a field of *some* node** — this does not show the node comes from
|
|
the trigger queue at `phase+272`. That link is exactly the over-reach
|
|
`isl-builtins.md` already recorded and withdrew once; it is not asserted here.
|
|
* **Two callers unread**: `sub_82273910` and `sub_82264058`.
|
|
* **Whether the drain's nodes explain the unreached routines** is untested. It
|
|
is a lead, not a result.
|