Repository navigation
ruff_r2il: emit the 6502 partition as an MGRA v3 graph - #109
Merged
Merged
Conversation
The reachability probe measures a partition and prints a table. The partition is a graph, and the tier that draws this exact wire already ships: medcare-rs emits MGRA v3 from graph_abi.rs and a2ui-graph renders it over wgpu with a WebGL2 fallback. What was missing was the emitter, so that is what this adds — no new renderer, no new format. src/mgra.rs is the encoder: a pure writer plus a GraphBuilder that holds the address-to-index mapping the renderer needs, since the wire carries node ordinals and a walk produces addresses. It refuses three things the wire cannot express — an endpoint past the node lane, a label over its u16 prefix, a count over the header u32. The consumer is not defenceless (its edge_pairs() drops ghost ordinals so they cannot index a GPU buffer) but a dropped edge is silent data loss: the field renders slightly wrong and nothing says so. The round-trip test decodes with a2ui-graph's own parser rather than a second reader written here, added as a dev-dependency with default-features = false. Zero wgpu crates enter the lock; 30 transitive ones do. An encoder checked against your own re-read of your own encoder proves only that you were consistent. Two mistakes the tests and the run caught, both recorded where they happened: - edge()'s third element is the predicate at @11; the line style is a separate byte at @8 behind edge_kind(). The first version wrote the relation into @8 alone. A call and a data reference differ both in meaning and in how they should be drawn, so both fields carry it. - The first walk observed a node per decoded instruction, which made nodes == instrs exactly (1349/1349, 7347/7347) — an instruction dump, not a call graph. And one measurement that changed the design. The data arm fired zero times, so rather than assume why, the address operands were counted by space: of 1777, 1257 land in Unique, 354 in Register, 166 in Const — and not one Const operand is inside the image. 6502 absolute addressing lifts its address into a computed temp, so recovering an in-image data address needs constant propagation through the p-code temps, which this walk does not do and does not fake. What Const does catch is the out-of-image absolute, and the emitted addresses are exactly what that predicts: $0007, $0057, $0059, $005b — zero page. A guard now warns when either arm reports zero, because that column read 0 and looked like a measurement. This also means reachability_probe's own data_refs set is structurally empty on these images for the same reason. Its unreached+ref column is not measuring what its name says. Not touched here: its numbers are pinned in a merged PR, and quietly rewriting a measured result is how one moves. Measured: LOCODE 79 entries / 4 referenced / 40 calls, HICODE 199 / 10 / 526. Artifacts are gitignored on the same footing as the ore — a build product from a commercial game's image. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DCfrD5y19cvFc4AoyydXYv
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_7b48e6ec-208d-4346-ae54-5aeb19f8d835) |
AdaWorldAPI
marked this pull request as ready for review
August 26, 2026 07:25
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The reachability probe measures a partition and prints a table. That partition is a graph — addresses are nodes, calls and references are edges — and the tier that draws this exact wire already ships:
medcare-rsemits MGRA v3 fromgraph_abi.rs,a2ui-graphrenders it over wgpu with a WebGL2 fallback. What was missing was the emitter. No new renderer, no new format.What landed
src/mgra.rs— the encoder. A pure writer, plus aGraphBuilderholding the address→index mapping the renderer needs (the wire carries node ordinals; a walk produces addresses). It refuses three things the wire cannot express: an endpoint past the node lane, a label over itsu16prefix, a count over the headeru32.The consumer is not defenceless — its
edge_pairs()drops ghost ordinals so they cannot index a GPU buffer out of bounds — but a dropped edge is silent data loss: the field renders slightly wrong and nothing says so. Refusing the stream names the offending edge instead.examples/mgra_emit.rs— the walk. Same recursive descent as the probe, with one extra piece of state: every queue entry carries the entry its descent started from, so a call becomes an edge rather than just a target. Kept separate from the probe's walk deliberately — the probe's numbers are pinned in a merged PR, and rewriting its walk to serve a second consumer is how a measured result quietly moves.The falsifier
The round-trip test decodes with
a2ui-graph's own parser, added as a dev-dependency withdefault-features = false. Zero wgpu crates enter the lock; 30 transitive ones do (ndarray, the wasm-bindgen/web-sys family). An encoder checked against your own re-read of your own encoder proves only that you were consistent.It earned its keep immediately — it caught the first of the two mistakes below.
Three things that went wrong, and what they taught
edge()'s third element is thepredicate@11; the line style is a separate byte @8 behindedge_kind(). The first version wrote the relation into @8 alone. A call and a data reference differ both in meaning and in how they should be drawn, so both fields carry it.The first walk observed a node per decoded instruction —
nodes == instrsexactly (1349/1349, 7347/7347). That is an instruction dump, not a call graph.The data arm fired zero times, and rather than assume why, the address operands were counted by space:
UniqueRegisterConst6502 absolute addressing lifts its address into a computed temp, so recovering an in-image data address needs constant propagation through the p-code temps — which this walk does not do and does not fake. What
Constdoes catch is the out-of-image absolute, and the emitted addresses are exactly what that predicts:$0007,$0057,$0059,$005b— zero page.(
in_imageis deliberately not applied to aUniqueoperand: its offset is a temp slot number, not an address. 92 of them compare "inside the image" by coincidence of numbering.)A guard now warns when either arm reports zero — that column read
0and looked like a measurement.A finding this surfaced elsewhere, not fixed here
reachability_probe's owndata_refsset is structurally empty on these images, for exactly the same reason. Itsunreached+refcolumn is not measuring what its name says.Left alone on purpose: its numbers are pinned in a merged PR and in
CLAUDE.md, and quietly rewriting a measured result is how one moves. It wants its own change with the re-run as the evidence.Measured
LOCODE.unprot.binHICODE.unprot.binArtifacts are gitignored on the same footing as the ore — a build product derived from a commercial game's image.
Gates
cargo clippy --features lift --all-targets -- -D warningsclean ·cargo fmt --checkclean ·cargo test -p ruff_r2il --lib46/46 ·prekon every changed file, all hooks pass · both probes re-run end to end.Generated by Claude Code