Skip to content

programs-react: resolve a local to its value region, not every region#268

Closed
gnidan wants to merge 4 commits into
compiler-locals-emissionfrom
ui-local-value-reduce
Closed

programs-react: resolve a local to its value region, not every region#268
gnidan wants to merge 4 commits into
compiler-locals-emissionfrom
ui-local-value-reduce

Conversation

@gnidan

@gnidan gnidan commented Jul 16, 2026

Copy link
Copy Markdown
Member

Stacked on #261 (base = compiler-locals-emission) so the deploy preview shows #261's local emission and this reduce together — the combined view to eyeball before merging #261.

Bug: resolveVariableValue (TraceContext.tsx) joined every region of a resolved pointer. A memory-homed local's pointer is a group carrying a frame scaffolding region plus the value region, so a scalar local rendered as two hex words (frame pointer + value) — the "weird memory values."

Fix (scalar-first reduce): select the value region by the variable's identifier via Cursor.Regions.lookup (last concrete region with that name) and read just that one. Falls back to the previous all-regions behavior when there's no identifier-named region, so nothing else regresses. Wired the identifier through the locals and call-argument call sites.

Verified against a real trace (add(a,b), O0): a's pointer is group:[{name:"frame"},{name:"a"}]; old code returned 0x…0100, 0x…aaaa (frame pointer + value), the fix returns 0x…aaaa = 43690 — one clean value. All 66 programs-react tests pass; web build green.

Coordinated the region API with debugger. This is the first slice of the value-reduce layer; it also sets up string/array locals later. Base can retarget to main (or fold into #261) once #261 lands.

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://ethdebug.github.io/format/pr-preview/pr-268/

Built to branch gh-pages at 2026-07-16 21:25 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@gnidan
gnidan force-pushed the ui-local-value-reduce branch 2 times, most recently from 72121c8 to 9745c9e Compare July 16, 2026 07:29
gnidan added 2 commits July 16, 2026 11:47
resolveVariableValue joined every region of a resolved pointer, so a
memory-homed local — whose pointer is a group carrying a frame
scaffolding region plus the value region — rendered as two hex words
(the frame pointer and the value) instead of one.

Select the value region by the variable's identifier via
Cursor.Regions.lookup (the last concrete region with that name) and read
just that region. Falls back to the previous all-regions behavior when
no identifier-named region exists, so nothing else regresses. This is
the scalar-first slice of the value-reduce layer; it also sets up
string/array locals later.

Verified against a real trace: a frame-relative local resolved to a
single clean value (0xaaaa) instead of frame-pointer + value.
The docs trace playground's drawer resolves variable/argument values
with its own resolvePointer, which had the same all-regions-join bug as
programs-react's resolveVariableValue — a memory-homed local rendered as
frame pointer + value. Apply the identical scalar-first reduce here:
select the value region by the variable/argument identifier via
Cursor.Regions.lookup, falling back to the all-regions read when there
is no identifier-named region. This is the surface the trace-playground
preview actually shows, so the combined preview now renders locals as a
single clean value.
@gnidan
gnidan force-pushed the ui-local-value-reduce branch from 262fd26 to b94b8ea Compare July 16, 2026 17:18
gnidan added 2 commits July 16, 2026 15:51
Adds decodeValue(data, type): a pure, framework-agnostic function that
turns a resolved value region's bytes + the variable's static type into a
readable string (uint256 -> "2", not 0x00..02) — the scalar-first slice of
the value-rendering reduce layer.

Handles uint (decimal), int (two's-complement over the region width), bool,
address (EIP-55 checksummed), and static bytesN (left-aligned). Dynamic
bytes/string, aggregates, fixed/ufixed, enum, unresolved {id} type refs, and
missing types fall back to raw hex so callers never break.
Wire debugger's decodeValue into both variable resolvers so a located
local renders as a readable value instead of raw hex: uint -> decimal,
int -> signed, bool -> true/false, address -> checksummed, static
bytesN -> hex; composite/unknown fall back to hex. The value region is
already narrowed by identifier (the reduce); this decodes that region's
bytes with the variable's static type.

- programs-react resolveVariableValue: thread the variable type, decode
  the selected/single region.
- TraceDrawer resolvePointer: same, keeping the raw type specifier on the
  extracted Variable; drop the render-side formatAsDecimal since
  decodeValue returns the final display string.

Verified on a real trace: uint locals a/b render as 43690/48059.
@gnidan
gnidan deleted the branch compiler-locals-emission July 16, 2026 21:25
@gnidan gnidan closed this Jul 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant