From d585ddd811a119dd519f1ba8ed62a694469d5cca Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Thu, 2 Jul 2026 16:37:39 -0400 Subject: [PATCH 1/9] =?UTF-8?q?docs:=20Explore=20section=20content=20?= =?UTF-8?q?=E2=80=94=20playgrounds=20+=20reference=20trims?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Content for the docs reorg (#17), authored for integration into docs' Explore section (docs/explore/, per gnidan's Option A + build-fresh-and- trim). Authoring source for docs to integrate onto docs-explore-section. - explore/trace-playground.mdx: learn-by-doing (counter -> function call -> tail-call optimization). - explore/pointer-playground.mdx: curated cross-topic (memory region, storage slot, struct group, computed-slot expression). - explore/index.mdx: Explore hub linking the three playgrounds. - explore/bug-playground.mdx: moved from examples/. - core-schemas/programs/tracing.mdx: trimmed to reference; interactive examples moved to the Trace playground. - implementation-guides/building-a-trace-viewer.mdx: extracted how-to. - pointers/{regions,collections,expressions}.mdx: interactive examples removed, schema tables + prose kept, playground cross-links added. All internal links point at /docs/explore/*. --- .../core-schemas/pointers/collections.mdx | 247 +----------- .../core-schemas/pointers/expressions.mdx | 378 ++---------------- .../docs/core-schemas/pointers/regions.mdx | 179 ++------- .../docs/core-schemas/programs/tracing.mdx | 252 +++--------- packages/web/docs/examples/_category_.json | 4 - packages/web/docs/examples/index.mdx | 22 - .../{examples => explore}/bug-playground.mdx | 0 packages/web/docs/explore/index.mdx | 27 ++ .../web/docs/explore/pointer-playground.mdx | 102 +++++ .../web/docs/explore/trace-playground.mdx | 80 ++++ .../building-a-trace-viewer.mdx | 69 ++++ 11 files changed, 393 insertions(+), 967 deletions(-) delete mode 100644 packages/web/docs/examples/_category_.json delete mode 100644 packages/web/docs/examples/index.mdx rename packages/web/docs/{examples => explore}/bug-playground.mdx (100%) create mode 100644 packages/web/docs/explore/index.mdx create mode 100644 packages/web/docs/explore/pointer-playground.mdx create mode 100644 packages/web/docs/explore/trace-playground.mdx create mode 100644 packages/web/docs/implementation-guides/building-a-trace-viewer.mdx diff --git a/packages/web/docs/core-schemas/pointers/collections.mdx b/packages/web/docs/core-schemas/pointers/collections.mdx index dc46151d1..1dec6ed79 100644 --- a/packages/web/docs/core-schemas/pointers/collections.mdx +++ b/packages/web/docs/core-schemas/pointers/collections.mdx @@ -3,7 +3,6 @@ sidebar_position: 4 --- import SpecLink from "@site/src/components/SpecLink"; -import { PointerPlayground, PointerExample } from "@theme/PointersExample"; # Collections @@ -12,11 +11,13 @@ import { PointerPlayground, PointerExample } from "@theme/PointersExample"; href="/spec/pointer/collection" /> - +While [regions](./regions) describe single contiguous byte ranges, +**collections** aggregate multiple pointers together. Collections handle +cases where data structures span multiple locations or have dynamic +configurations. -While [regions](./regions) describe single contiguous byte ranges, **collections** -aggregate multiple pointers together. Collections handle cases where data -structures span multiple locations or have dynamic configurations. +To build and resolve collection pointers interactively, see the +[Pointer playground](/docs/explore/pointer-playground). ## Why collections? @@ -36,34 +37,12 @@ Collections provide six patterns for composing pointers: | `reference` | Invoke reusable pointer templates | | `templates` | Define inline templates for local reuse | -Click **"▶ Try it"** on any example to load it into the Pointer Playground -drawer at the bottom of the screen. - ## Group A **group** combines multiple pointers into a single composite pointer. Each -pointer in the group can have a name for identification. - - - -Groups are useful for structs and other compound data types where multiple -fields need to be accessed together. +pointer in the group can have a name for identification. Groups are useful for +structs and other compound data types where multiple fields need to be +accessed together. ## List @@ -77,68 +56,10 @@ identifiers with types and pointers). See the [glossary](/docs/reference/glossary) for complete definitions. ::: - - The list evaluates `count` to determine how many pointers to generate, then for each index (bound to the variable named by `each`), it evaluates the `is` -pointer template. - -### List with dynamic count - -When the count comes from storage: - - +pointer template. The `count` can itself come from storage, read via `$read`, +so the number of elements is determined at runtime. ### List properties @@ -153,31 +74,6 @@ When the count comes from storage: A **conditional** selects between pointers based on whether an expression evaluates to a non-zero value. - - ### Conditional properties | Property | Description | @@ -191,28 +87,6 @@ evaluates to a non-zero value. A **scope** defines variables that can be used in a nested pointer. Variables are evaluated in order, so later variables can reference earlier ones. - - Scopes help break complex pointer definitions into readable steps. For examples combining scopes with keccak256 for storage slot computation, see the [expressions documentation](./expressions#computing-storage-slots-with-keccak256). @@ -229,39 +103,6 @@ combining scopes with keccak256 for storage slot computation, see the A **reference** invokes a named pointer template, while **templates** defines them inline. These work together for reusable pointer patterns. - - ### Template definition Each template in the `templates` object has: @@ -284,80 +125,14 @@ Collections can be nested to build complex pointer structures. A group might contain lists, conditionals might wrap groups, and scopes can define variables used throughout nested collections. - - ## Named regions in collections Pointers within collections can include a `name` property. Named regions are tracked during resolution and can be referenced using the `.slot`, `.offset`, and `.length` syntax in expressions. - - ## Learn more - [Regions](./regions) for simple pointer definitions - [Expressions](./expressions) for dynamic value computation - [Pointer specification](/spec/pointer/collection) for formal definitions - - diff --git a/packages/web/docs/core-schemas/pointers/expressions.mdx b/packages/web/docs/core-schemas/pointers/expressions.mdx index ddca75b23..ed60fb787 100644 --- a/packages/web/docs/core-schemas/pointers/expressions.mdx +++ b/packages/web/docs/core-schemas/pointers/expressions.mdx @@ -4,7 +4,6 @@ sidebar_position: 3 import SpecLink from "@site/src/components/SpecLink"; import SchemaExample from "@site/src/components/SchemaExample"; -import { PointerPlayground, PointerExample } from "@theme/PointersExample"; # Expressions @@ -13,12 +12,13 @@ import { PointerPlayground, PointerExample } from "@theme/PointersExample"; href="/spec/pointer/expression" /> - - Static offsets work for simple variables, but most interesting data has locations that depend on runtime values. Expressions let pointers compute addresses dynamically. +To evaluate expressions against live EVM state interactively, see the +[Pointer playground](/docs/explore/pointer-playground). + ## Why expressions are needed Consider reading element `i` from a memory array. The element's location @@ -28,32 +28,9 @@ depends on: - Which element we want (the index `i`) - How big each element is (32 bytes for `uint256`) -A static pointer can't capture this. Expressions can: - - +A static pointer can't capture this, but an expression can — for example, +`array-start + index × 32` computes the element's offset from the array's +base and the index. ## Arithmetic expressions @@ -61,116 +38,31 @@ Basic math operations for computing addresses: ### `$sum` — Addition -Adds all values in an array: - - +Adds all values in an array. ### `$difference` — Subtraction -Subtracts the second value from the first (saturates at zero): - - +Subtracts the second value from the first (saturates at zero). ### `$product` — Multiplication -Multiplies all values in an array: - - +Multiplies all values in an array. ### `$quotient` — Division -Integer division of first value by second: - - +Integer division of the first value by the second. ### `$remainder` — Modulo -Remainder after division: - - +Remainder after division. ## Reading values ### `$read` — Read from a named region -Reads the bytes from a previously defined region: - - - -The `$read` expression retrieves the actual runtime value stored in the -`array-length-slot` region—the array's length. +Reads the bytes from a previously defined region. For example, a group can +name an `array-length-slot` region and then use `{ $read: "array-length-slot" }` +to retrieve the array's length at runtime and use it in a later computation. ## Region property lookups @@ -202,32 +94,9 @@ Returns the slot number for storage/stack/transient regions. ### Chaining lookups -Compute the next element's position from the previous one: - - +Property lookups can compute the next element's position from the previous +one. For example, `element-1`'s offset can be computed as the sum of +`element-0`'s `.offset` and its `.length`. ## Computing storage slots with `$keccak256` @@ -235,228 +104,43 @@ Solidity uses keccak256 hashing to compute storage locations for dynamic data. ### Array element slots -For a dynamic array at slot `n`, elements start at `keccak256(n)`: - - +For a dynamic array at slot `n`, elements start at `keccak256(n)`, so element +`i` lives at `keccak256(n) + i`. ### Mapping value slots -For a mapping at slot `n`, the value for key `k` is at `keccak256(k, n)`: - - +For a mapping at slot `n`, the value for key `k` is at `keccak256(k, n)`. ### Nested mappings -For `mapping(address => mapping(uint => uint))` at slot 2: - - - -This computes: `keccak256(inner_key, keccak256(outer_key, 2))` +For `mapping(address => mapping(uint => uint))` at slot 2, the value is at +`keccak256(inner_key, keccak256(outer_key, 2))`. ## Data manipulation ### `$concat` — Concatenate bytes -Joins byte sequences without padding: - - - -Useful for building hash inputs from multiple values. +Joins byte sequences without padding. Useful for building hash inputs from +multiple values. ### `$sized` — resize to N bytes -Truncates or pads to exactly N bytes: - - - -Pads with zeros on the left; truncates from the left if too long. +Truncates or pads to exactly N bytes. Pads with zeros on the left; truncates +from the left if too long. ### `$wordsized` — Resize to word size -Equivalent to `$sized32` on the EVM: - - +Equivalent to `$sized32` on the EVM (pads or truncates to 32 bytes). ## Variables in expressions Expressions can reference variables by name. These come from list pointer -contexts: - - - -The variable `"i"` takes values from 0 to count-1, computing each element's -slot. +contexts: within a `list`, the variable named by `each` takes values from 0 to +count-1, computing each element's slot. ## Complete example: dynamic array element -Reading element `i` from `uint256[] storage arr` at slot 5: - - - -The pointer: +To read element `i` from `uint256[] storage arr` at slot 5, a pointer: 1. Defines the array's base slot 2. Computes the element's slot: `keccak256(5) + element_index` @@ -469,5 +153,3 @@ The pointer: expression language - [Implementation guide](/docs/implementation-guides/pointers/evaluating-expressions) for building an expression evaluator - - diff --git a/packages/web/docs/core-schemas/pointers/regions.mdx b/packages/web/docs/core-schemas/pointers/regions.mdx index f03590976..1c9026671 100644 --- a/packages/web/docs/core-schemas/pointers/regions.mdx +++ b/packages/web/docs/core-schemas/pointers/regions.mdx @@ -3,18 +3,18 @@ sidebar_position: 2 --- import SpecLink from "@site/src/components/SpecLink"; -import { PointerPlayground, PointerExample } from "@theme/PointersExample"; # Regions - - A region represents a contiguous block of bytes in a specific EVM data location. Regions are the leaves of the pointer tree—the actual byte ranges that hold data. +To resolve regions against live EVM state interactively, see the +[Pointer playground](/docs/explore/pointer-playground). + ## Addressing schemes The EVM uses two different models for organizing bytes, and regions reflect @@ -25,192 +25,61 @@ this: **Memory**, **calldata**, **returndata**, and **code** are byte-addressable. Regions in these locations use `offset` and `length`: - - - `offset`: byte position from the start (required) - `length`: number of bytes (required) ### Slot-based locations **Storage**, **transient storage**, and **stack** are organized in 32-byte -slots. Regions use `slot`: - - +slots. Regions use `slot`. For storage and transient storage, values that don't fill a full slot can -specify sub-slot positioning: - - - -This addresses 20 bytes starting at byte 12 within slot 0—useful for packed -storage. +specify sub-slot positioning with `offset` and `length` within the slot — +useful for packed storage, such as a 20-byte address held at byte 12 of a +slot. ## Location-specific details ### Memory -Memory is a simple byte array that grows as needed: - - - -Memory addresses often come from the free memory pointer (stored at `0x40`). +Memory is a simple byte array that grows as needed. Memory addresses often +come from the free memory pointer (stored at `0x40`). ### Storage Storage persists between transactions. Slots are 32-byte words addressed by -256-bit keys: - - - -Slot addresses can be literal numbers, hex strings, or computed expressions. +256-bit keys. Slot addresses can be literal numbers, hex strings, or computed +expressions. ### Stack -The EVM stack holds up to 1024 words. Slot 0 is the top: - - - -Stack regions are typically read-only from a debugging perspective—you observe -values but don't address sub-ranges. +The EVM stack holds up to 1024 words; slot 0 is the top. Stack regions are +typically read-only from a debugging perspective—you observe values but don't +address sub-ranges. ### Calldata -Function arguments arrive in calldata, read-only and byte-addressable: - - - -The first 4 bytes are typically the function selector; arguments follow. +Function arguments arrive in calldata, read-only and byte-addressable. The +first 4 bytes are typically the function selector; arguments follow. ### Returndata -After a call, the returned data is accessible: - - +After a call, the data it returned is accessible as a byte-addressable +region. ### Code -Contract bytecode can be read as data: - - - -This is used for immutable variables and other data embedded in bytecode. +Contract bytecode can be read as data. This is used for immutable variables +and other data embedded in bytecode. ### Transient storage -Transient storage (EIP-1153) persists only within a transaction: - - - -Uses the same slot-based addressing as regular storage. +Transient storage (EIP-1153) persists only within a transaction and uses the +same slot-based addressing as regular storage. ## Naming regions -Any region can have a `name` that other parts of the pointer reference: - - - +Any region can have a `name` that other parts of the pointer reference. Names enable: - Reading the region's value with `{ "$read": "token-balance" }` @@ -230,5 +99,3 @@ reading, see [expressions](./expressions). For complete schemas for each location type, see the [pointer region specification](/spec/pointer/region). - - diff --git a/packages/web/docs/core-schemas/programs/tracing.mdx b/packages/web/docs/core-schemas/programs/tracing.mdx index d901224fb..67e2e234a 100644 --- a/packages/web/docs/core-schemas/programs/tracing.mdx +++ b/packages/web/docs/core-schemas/programs/tracing.mdx @@ -4,26 +4,16 @@ sidebar_position: 4 import SpecLink from "@site/src/components/SpecLink"; import SchemaExample from "@site/src/components/SchemaExample"; -import { TracePlayground, TraceExample } from "@theme/ProgramExample"; -import { - counterIncrement, - thresholdCheck, - multipleStorageSlots, - functionCallAndReturn, - mutualRecursion, - tailRecursiveSum, - tailRecursiveFactorial, -} from "./tracing-examples"; # Tracing execution - - -Tracing brings together programs, pointers, and types to show what's happening -at each step of EVM execution. Click **"Try it"** on any example to open the -Trace Playground, where you can compile and step through real BUG code. +Tracing brings together programs, pointers, and types to show what's +happening at each step of EVM execution. This page is the reference for how +trace data maps onto **ethdebug/format**. To compile and step through real +BUG programs interactively, see the +[Trace playground](/docs/explore/trace-playground). ## What tracing provides @@ -46,77 +36,17 @@ At each instruction in a transaction trace: current value 4. **Decode values**: Use the type information to interpret raw bytes -## Try it yourself - -Click **"Try it"** on any example below to load it into the Trace Playground. -The drawer will open at the bottom of the screen where you can compile the -code and step through the execution trace. - -### Simple counter increment - -This example shows a basic counter that increments a storage variable: - - - -### Storage with threshold check - -This example demonstrates conditional logic with storage variables: - - - -### Multiple storage slots - -This example shows working with multiple storage locations: +## Call contexts across function boundaries - +When execution crosses a function boundary, the JUMP instructions at the +boundary carry **invoke** and **return** contexts, so a debugger can follow +the call and maintain a call stack. -## Tracing through a function call +### Entering a function -The examples above trace simple straight-line code. Real programs -make function calls. **invoke** and **return** contexts let a -debugger follow execution across function boundaries. - -Click **"Try it"** on the example below, then step through the -trace. Watch for **invoke** contexts on the JUMP into `add` and -**return** contexts on the JUMP back to the caller: - - - -Mutual recursion produces alternating invoke/return pairs. In -this example, `isEven` and `isOdd` call each other, bouncing -back and forth until `n` reaches zero. Each call adds a frame -to the call stack: - - - -As you step through, three phases are visible: - -### Before the call — setting up arguments - -At the call site, the compiler pushes arguments onto the stack and -prepares the jump. The JUMP instruction carries an **invoke** -context identifying the function, its target, and the argument -locations: +At the call site, the compiler pushes arguments onto the stack and prepares +the jump. The JUMP instruction carries an **invoke** context identifying the +function, its target, and the argument locations: -The debugger now knows it's entering `add` with arguments at stack -slots 2 and 3. A trace viewer can show `add(3, 4)` in the call -stack. - -### Inside the function — normal tracing +The debugger now knows it's entering `add` with arguments at stack slots 2 +and 3, and can show `add(3, 4)` in the call stack. -Inside `add`, instructions carry their own `code` and `variables` -contexts as usual. The debugger shows the source range within the -function body, and parameters `a` and `b` appear as in-scope -variables. +Inside the function, instructions carry their own `code` and `variables` +contexts as usual — the debugger shows the source range within the function +body, and parameters appear as in-scope variables. -### Returning — the result +### Returning a result -When `add` finishes, the JUMP back to the caller carries a -**return** context with a pointer to the result: +When the function finishes, the JUMP back to the caller carries a **return** +context with a pointer to the result: -The debugger pops `add` from the call stack and can display the -return value (7). +The debugger pops `add` from the call stack and can display the return +value. ### External calls and reverts -The same pattern applies to external message calls, but with -additional fields. An external CALL instruction carries gas, value, -and input data pointers: +The same pattern applies to external message calls, but with additional +fields. An external CALL instruction carries gas, value, and input data +pointers: -For built-in assertion failures, the compiler can provide a panic -code instead of (or alongside) a reason pointer: +For built-in assertion failures, the compiler can provide a panic code +instead of (or alongside) a reason pointer: -## Tail-call optimization - -The recursion examples above push a new frame for every call — step -through them and watch the call stack grow. A compiler can often avoid -that. When a recursive call sits in **tail position** — its result is -returned directly, with no further work after it — the compiler can -reuse the current frame instead of pushing a new one. This is -**tail-call optimization** (TCO), and it turns recursion into a loop. - -The two programs below are written so bugc's optimizer folds them. Each -accumulates its result in an `acc` parameter and hands it to the next -call in tail position, so no work is left pending on the stack. - -Use the **Opt** selector in the trace drawer to set the optimization -level. Compile at **O0** (no optimization) and again at **O2** -(optimizations on, including TCO), then step through and compare the -call stack. TCO kicks in at **O2**. - - - - - -At **O0**, each `sum`/`fact` call is a real invoke/return pair and the -call stack grows one frame per iteration. At **O2**, the recursive -call becomes a **back-edge**: a single JUMP that ends one iteration and -begins the next without pushing a frame. The call stack stays flat. - -That one JUMP carries three facts at once, composed as sibling keys on a -single context — the flat form described on the -[transform context](/spec/program/context/transform) page: +## Optimized code: the tailcall transform + +When the compiler optimizes tail-recursive calls, it turns the recursion +into a loop: the recursive call becomes a **back-edge** — a single JUMP that +ends one iteration and begins the next without pushing a frame. That one +JUMP carries three facts at once, composed as sibling keys on a single +context (the flat form described on the +[transform context](/spec/program/context/transform) page): diff --git a/packages/web/docs/examples/_category_.json b/packages/web/docs/examples/_category_.json deleted file mode 100644 index 73d20c19a..000000000 --- a/packages/web/docs/examples/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "Examples", - "position": 6 -} diff --git a/packages/web/docs/examples/index.mdx b/packages/web/docs/examples/index.mdx deleted file mode 100644 index edd07f4ad..000000000 --- a/packages/web/docs/examples/index.mdx +++ /dev/null @@ -1,22 +0,0 @@ ---- -sidebar_position: 1 -pagination_prev: core-schemas/info/resources ---- - -# Examples - -Interactive examples demonstrating **ethdebug/format** concepts. - -## Available examples - -- [**BUG Playground**](/docs/examples/bug-playground) — Interactive - compiler playground for the BUG language, showing AST, IR, CFG, and - bytecode views. -- [**Pointer regions**](/docs/core-schemas/pointers/regions) — - Interactive pointer playground embedded in the regions reference - page. Visualize how regions resolve against EVM state for each - data location. -- [**Tracing execution**](/docs/core-schemas/programs/tracing) — - Interactive trace playground embedded in the tracing reference - page. Compile and step through BUG programs to see source mapping, - variables, and context in action. diff --git a/packages/web/docs/examples/bug-playground.mdx b/packages/web/docs/explore/bug-playground.mdx similarity index 100% rename from packages/web/docs/examples/bug-playground.mdx rename to packages/web/docs/explore/bug-playground.mdx diff --git a/packages/web/docs/explore/index.mdx b/packages/web/docs/explore/index.mdx new file mode 100644 index 000000000..69cdee90c --- /dev/null +++ b/packages/web/docs/explore/index.mdx @@ -0,0 +1,27 @@ +--- +sidebar_position: 1 +pagination_prev: core-schemas/info/resources +--- + +# Explore + +Learn **ethdebug/format** by doing. These interactive playgrounds let you +compile real code and watch the format describe it — where data lives, how +execution moves, and what the compiler did along the way. Each one runs in +your browser; no setup required. + +## Playgrounds + +- [**Pointer playground**](/docs/explore/pointer-playground) — Watch + pointers resolve against concrete EVM state. See how a memory range, a + storage slot, a struct, and a computed location each select their bytes. +- [**Trace playground**](/docs/explore/trace-playground) — Compile a BUG + program and step through its execution trace: source location, in-scope + variables, the call stack, and instruction context at every step — + including the optimizer's tail-call transform. +- [**BUG playground**](/docs/explore/bug-playground) — Compile the BUG + language end to end and inspect each stage: AST, IR, control-flow graph, + and bytecode. + +Looking for the schema details behind these? See the +[Core Schemas](/docs/core-schemas/pointers) reference. diff --git a/packages/web/docs/explore/pointer-playground.mdx b/packages/web/docs/explore/pointer-playground.mdx new file mode 100644 index 000000000..f2044efbd --- /dev/null +++ b/packages/web/docs/explore/pointer-playground.mdx @@ -0,0 +1,102 @@ +--- +sidebar_position: 4 +--- + +import { PointerPlayground, PointerExample } from "@theme/PointersExample"; + +# Pointer playground + +A **pointer** is a recipe for finding data in the EVM: it says where bytes +live and, when needed, how to compute that location from the current +machine state. The examples below let you watch pointers resolve against +concrete state — click **"Try it"** on any of them to open the playground +and see the bytes each one selects. + +These four cover the whole idea, from a fixed byte range to a computed +one. For the full reference, follow the links under each example. + + + +## A byte range in memory + +The simplest pointer names a location and a byte range. Memory, calldata, +returndata, and code are byte-addressable, so their regions use `offset` +and `length`. + + + +## A slot in storage + +Storage, transient storage, and the stack are organized in 32-byte slots, +so their regions use `slot` instead of a byte offset. + + + +See [Regions](/docs/core-schemas/pointers/regions) for every location and +addressing scheme. + +## Several fields at once + +A **collection** bundles regions together. A `group` names each member — +ideal for a struct whose fields you want to read as a unit. + + + +See [Collections](/docs/core-schemas/pointers/collections) for groups, +lists, conditionals, and scopes. + +## A location computed from state + +When a location depends on runtime values, an **expression** computes it. +Here `$sum` adds three numbers to derive a storage slot. + + + +See [Expressions](/docs/core-schemas/pointers/expressions) for arithmetic, +reads, and hashing. + + diff --git a/packages/web/docs/explore/trace-playground.mdx b/packages/web/docs/explore/trace-playground.mdx new file mode 100644 index 000000000..c339cfb0e --- /dev/null +++ b/packages/web/docs/explore/trace-playground.mdx @@ -0,0 +1,80 @@ +--- +sidebar_position: 3 +--- + +import { TracePlayground, TraceExample } from "@theme/ProgramExample"; +import { + counterIncrement, + functionCallAndReturn, + tailRecursiveSum, + tailRecursiveFactorial, +} from "../core-schemas/programs/tracing-examples"; + +# Trace playground + +See **ethdebug/format** in motion. Each example below compiles a small +BUG program and lets you step through its execution trace — watching the +source line, in-scope variables, call stack, and instruction context +light up at every step. + +Click **"Try it"** on an example to open the trace drawer, then use the +step controls to walk through execution. The examples build on each +other: start at the top and work down, picking up one idea at a time. + + + +## Start here: a storage write + +`Counter` increments a single storage slot. Step through it to get a feel +for the drawer — the highlighted source line, the value in storage, and +the context attached to each instruction. + + + +## Following a function call + +Real programs call functions, and the debugger follows them. Watch the +call stack push a frame on the JUMP into `add` (an **invoke** context) +and pop it on the JUMP back (a **return** context). + + + +For the exact shape of invoke, return, and revert contexts, see the +[function call spec](/spec/program/context/function/invoke) and the +[tracing reference](/docs/core-schemas/programs/tracing). + +## Watching the optimizer + +Compilers rewrite code as they optimize, and **transform** contexts +record what they did. Set the **Opt** selector to **O2** and step through +these tail-recursive programs: the recursive call folds into a loop, and +the back-edge JUMP carries `transform: ["tailcall"]` next to its invoke +and return. The call stack stays flat instead of growing one frame per +iteration. + + + + + +Flip the **Opt** selector between **O0** and **O2** to see the call stack +change. For how the `tailcall` transform composes with invoke/return, see +the [transform context spec](/spec/program/context/transform) and the +[tail-call optimization walkthrough](/docs/core-schemas/programs/tracing). + + diff --git a/packages/web/docs/implementation-guides/building-a-trace-viewer.mdx b/packages/web/docs/implementation-guides/building-a-trace-viewer.mdx new file mode 100644 index 000000000..c9ef15b7e --- /dev/null +++ b/packages/web/docs/implementation-guides/building-a-trace-viewer.mdx @@ -0,0 +1,69 @@ +--- +sidebar_position: 3 +--- + +# Building a trace viewer + +This guide walks through the pieces you need to turn **ethdebug/format** +data and an execution trace into a working trace viewer. For the conceptual +reference on how trace data maps to the format, see +[Tracing execution](/docs/core-schemas/programs/tracing); to see a finished +viewer in action, try the +[Trace playground](/docs/explore/trace-playground). + +The key components for trace integration: + +## 1. Trace source + +Get transaction traces from: + +- JSON-RPC `debug_traceTransaction` +- Local simulation (Ganache, Anvil, Hardhat) +- Historical archive nodes + +## 2. Program loader + +Load compiled program data containing: + +- Instruction list with contexts +- Source materials +- Type definitions + +## 3. Pointer resolver + +Use `@ethdebug/pointers` to resolve variable locations: + +```typescript +import { dereference } from "@ethdebug/pointers"; + +// For each variable in scope +const cursor = await dereference(variable.pointer, { state: machineState }); +const view = await cursor.view(machineState); +const value = await view.read(view.regions[0]); +``` + +## 4. Type decoder + +Interpret raw bytes according to type: + +```typescript +function decodeValue(bytes: Data, type: Type): string { + switch (type.kind) { + case "uint": + return bytes.asUint().toString(); + case "bool": + return bytes.asUint() !== 0n ? "true" : "false"; + case "address": + return "0x" + bytes.toHex().slice(-40); + // ... other types + } +} +``` + +## Learn more + +- [Tracing execution](/docs/core-schemas/programs/tracing) for how trace + data maps to the format +- [Pointers](/docs/core-schemas/pointers) for resolving variable locations +- [Trace playground](/docs/explore/trace-playground) for a working viewer + you can step through From 48bc7a92d20c53deba93d8e0918932aad95dc53f Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Thu, 2 Jul 2026 16:49:14 -0400 Subject: [PATCH 2/9] docs: wire Explore section structure (nav, sidebar, links) Structural wiring to complete the Explore section reorg: - add explore/_category_.json (label "Explore", sidebar position 2) - add navbar "Playground" item -> /docs/explore - renumber subsequent categories (Getting started 3, Concepts 4, Core schemas 5, Implementation guides 6; Reference 7) - order Explore pages: Pointer / Trace / BUG playground per plan - repoint former /docs/examples links (overview, getting-started, compiler guides) to /docs/explore and drop the stale resources pagination override Composes with the Explore content + reference trims. Part of #17. --- packages/web/docs/concepts/_category_.json | 2 +- packages/web/docs/core-schemas/_category_.json | 2 +- packages/web/docs/core-schemas/info/resources.mdx | 1 - packages/web/docs/explore/_category_.json | 4 ++++ packages/web/docs/explore/bug-playground.mdx | 2 +- packages/web/docs/explore/pointer-playground.mdx | 2 +- packages/web/docs/getting-started/_category_.json | 2 +- packages/web/docs/getting-started/for-compiler-authors.mdx | 2 +- packages/web/docs/getting-started/index.mdx | 2 +- packages/web/docs/implementation-guides/_category_.json | 2 +- .../docs/implementation-guides/compiler/case-study-bug.mdx | 4 ++-- packages/web/docs/implementation-guides/compiler/index.mdx | 2 +- packages/web/docs/overview.mdx | 2 +- packages/web/docusaurus.config.ts | 6 ++++++ 14 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 packages/web/docs/explore/_category_.json diff --git a/packages/web/docs/concepts/_category_.json b/packages/web/docs/concepts/_category_.json index 1d3167d49..d373a2925 100644 --- a/packages/web/docs/concepts/_category_.json +++ b/packages/web/docs/concepts/_category_.json @@ -1,4 +1,4 @@ { "label": "Concepts", - "position": 3 + "position": 4 } diff --git a/packages/web/docs/core-schemas/_category_.json b/packages/web/docs/core-schemas/_category_.json index 0fbf76d9e..85fb37536 100644 --- a/packages/web/docs/core-schemas/_category_.json +++ b/packages/web/docs/core-schemas/_category_.json @@ -1,4 +1,4 @@ { "label": "Core schemas", - "position": 4 + "position": 5 } diff --git a/packages/web/docs/core-schemas/info/resources.mdx b/packages/web/docs/core-schemas/info/resources.mdx index 5abb41766..44dce62e9 100644 --- a/packages/web/docs/core-schemas/info/resources.mdx +++ b/packages/web/docs/core-schemas/info/resources.mdx @@ -1,6 +1,5 @@ --- sidebar_position: 2 -pagination_next: examples/index --- import SpecLink from "@site/src/components/SpecLink"; diff --git a/packages/web/docs/explore/_category_.json b/packages/web/docs/explore/_category_.json new file mode 100644 index 000000000..955a30bc6 --- /dev/null +++ b/packages/web/docs/explore/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Explore", + "position": 2 +} diff --git a/packages/web/docs/explore/bug-playground.mdx b/packages/web/docs/explore/bug-playground.mdx index 9db8813b6..912112eb1 100644 --- a/packages/web/docs/explore/bug-playground.mdx +++ b/packages/web/docs/explore/bug-playground.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 2 +sidebar_position: 4 --- # BUG playground diff --git a/packages/web/docs/explore/pointer-playground.mdx b/packages/web/docs/explore/pointer-playground.mdx index f2044efbd..a7c7bd995 100644 --- a/packages/web/docs/explore/pointer-playground.mdx +++ b/packages/web/docs/explore/pointer-playground.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 4 +sidebar_position: 2 --- import { PointerPlayground, PointerExample } from "@theme/PointersExample"; diff --git a/packages/web/docs/getting-started/_category_.json b/packages/web/docs/getting-started/_category_.json index fd94d1fcf..eb95172a4 100644 --- a/packages/web/docs/getting-started/_category_.json +++ b/packages/web/docs/getting-started/_category_.json @@ -1,4 +1,4 @@ { "label": "Getting started", - "position": 2 + "position": 3 } diff --git a/packages/web/docs/getting-started/for-compiler-authors.mdx b/packages/web/docs/getting-started/for-compiler-authors.mdx index 4a97a6300..2d0cc83ae 100644 --- a/packages/web/docs/getting-started/for-compiler-authors.mdx +++ b/packages/web/docs/getting-started/for-compiler-authors.mdx @@ -158,5 +158,5 @@ Most compilers can add **ethdebug/format** support incrementally: - **[Pointers](/docs/core-schemas/pointers)** — Full documentation on pointer definitions - **[Programs](/docs/core-schemas/programs)** — Full documentation on program annotations - **[Info schema](/docs/core-schemas/info)** — Full documentation on bundling debug data -- **[BUG Playground](/docs/examples/bug-playground)** — See a working +- **[BUG Playground](/docs/explore/bug-playground)** — See a working compiler that emits **ethdebug/format** diff --git a/packages/web/docs/getting-started/index.mdx b/packages/web/docs/getting-started/index.mdx index 14ecd87e6..abafba550 100644 --- a/packages/web/docs/getting-started/index.mdx +++ b/packages/web/docs/getting-started/index.mdx @@ -67,6 +67,6 @@ started based on what you're building. - **[Concepts](/docs/concepts)** — Understand the mental models behind the format -- **[Examples](/docs/examples)** — See the format in action with interactive +- **[Explore](/docs/explore)** — See the format in action with interactive demos - **[Specification](/spec/overview)** — Read the formal schema definitions diff --git a/packages/web/docs/implementation-guides/_category_.json b/packages/web/docs/implementation-guides/_category_.json index d4987100c..72272d4a1 100644 --- a/packages/web/docs/implementation-guides/_category_.json +++ b/packages/web/docs/implementation-guides/_category_.json @@ -1,4 +1,4 @@ { "label": "Implementation guides", - "position": 5 + "position": 6 } diff --git a/packages/web/docs/implementation-guides/compiler/case-study-bug.mdx b/packages/web/docs/implementation-guides/compiler/case-study-bug.mdx index caa32751a..9082f31fa 100644 --- a/packages/web/docs/implementation-guides/compiler/case-study-bug.mdx +++ b/packages/web/docs/implementation-guides/compiler/case-study-bug.mdx @@ -12,7 +12,7 @@ integration. This case study explains how BUG implements debug information generation, providing a reference for other compiler authors. :::tip[Try it yourself] -See the [BUG Playground](/docs/examples/bug-playground) to experiment with +See the [BUG Playground](/docs/explore/bug-playground) to experiment with BUG and see its debug output. ::: @@ -366,6 +366,6 @@ Areas for improvement in BUG's debug support: ## Resources -- [BUG Playground](/docs/examples/bug-playground) — Interactive compiler demo +- [BUG Playground](/docs/explore/bug-playground) — Interactive compiler demo - [BUG Source Code](https://github.com/ethdebug/format/tree/main/packages/bugc) — Implementation reference - [ethdebug/format Specification](/spec/overview) — Format reference diff --git a/packages/web/docs/implementation-guides/compiler/index.mdx b/packages/web/docs/implementation-guides/compiler/index.mdx index 8c4e5d028..ce33ea5fb 100644 --- a/packages/web/docs/implementation-guides/compiler/index.mdx +++ b/packages/web/docs/implementation-guides/compiler/index.mdx @@ -54,5 +54,5 @@ demonstrates the full integration: - **[Case Study: BUG](./case-study-bug)** — Walkthrough of how the BUG compiler generates types, pointers, and program annotations -- **[BUG Playground](/docs/examples/bug-playground)** — Interactive +- **[BUG Playground](/docs/explore/bug-playground)** — Interactive demo where you can compile BUG code and inspect the debug output diff --git a/packages/web/docs/overview.mdx b/packages/web/docs/overview.mdx index 74058f0d9..374c71599 100644 --- a/packages/web/docs/overview.mdx +++ b/packages/web/docs/overview.mdx @@ -79,7 +79,7 @@ each compiler-debugger pair requires custom integration work. Or explore the [concepts](/docs/concepts) to understand the format's -design, browse [examples](/docs/examples) to see it in action, or +design, [explore](/docs/explore) interactive demos to see it in action, or dive into the [specification](/spec/overview) for formal definitions. To understand the motivation behind this project, see the diff --git a/packages/web/docusaurus.config.ts b/packages/web/docusaurus.config.ts index 7218db98c..045c22bc8 100644 --- a/packages/web/docusaurus.config.ts +++ b/packages/web/docusaurus.config.ts @@ -143,6 +143,12 @@ const config: Config = { position: "left", label: "Documentation", }, + { + to: "/docs/explore", + label: "Playground", + position: "left", + activeBaseRegex: `/docs/explore`, + }, { to: "/spec/overview", label: "Specification", From cd429a09fa62fb56f24917fc4eaeb1d422d6068c Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Thu, 2 Jul 2026 17:04:19 -0400 Subject: [PATCH 3/9] docs: drop navbar Playground item (keep Explore sidebar section) Per review: remove the top-nav Playground entry so the header reads Documentation | Specification. The Explore sidebar section (the core reorg) stays. Part of #17. --- packages/web/docusaurus.config.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/packages/web/docusaurus.config.ts b/packages/web/docusaurus.config.ts index 045c22bc8..7218db98c 100644 --- a/packages/web/docusaurus.config.ts +++ b/packages/web/docusaurus.config.ts @@ -143,12 +143,6 @@ const config: Config = { position: "left", label: "Documentation", }, - { - to: "/docs/explore", - label: "Playground", - position: "left", - activeBaseRegex: `/docs/explore`, - }, { to: "/spec/overview", label: "Specification", From 44ed60cf53657e6cccca863b76e6c809c09633ba Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Thu, 2 Jul 2026 17:05:44 -0400 Subject: [PATCH 4/9] docs: fix stale pagination_prev on Explore hub explore/index.mdx carried pagination_prev: core-schemas/info/resources from the old examples/ page (position 6). With Explore now at position 2, that pointed Previous forward into Core schemas; drop it so Previous auto-links to Project overview. Part of #17. --- packages/web/docs/explore/index.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web/docs/explore/index.mdx b/packages/web/docs/explore/index.mdx index 69cdee90c..5b4cfade8 100644 --- a/packages/web/docs/explore/index.mdx +++ b/packages/web/docs/explore/index.mdx @@ -1,6 +1,5 @@ --- sidebar_position: 1 -pagination_prev: core-schemas/info/resources --- # Explore From 00f2883e35784aa8d1a0ebc10f3443e2c0da6f8f Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Thu, 2 Jul 2026 19:03:50 -0400 Subject: [PATCH 5/9] docs: substantive Pointer Playground examples Per review, replace the toy pointer examples with real Solidity storage layouts: packed sub-slot address, dynamic array element (keccak256(5)+i), mapping value (keccak256(key,3)), and the flagship short/long storage string (one pointer resolved against both short and long state). Content authored by writer; keeps sidebar_position 2 (Pointer/Trace/BUG). #17. --- .../web/docs/explore/pointer-playground.mdx | 243 ++++++++++++++---- 1 file changed, 194 insertions(+), 49 deletions(-) diff --git a/packages/web/docs/explore/pointer-playground.mdx b/packages/web/docs/explore/pointer-playground.mdx index a7c7bd995..4d97f0470 100644 --- a/packages/web/docs/explore/pointer-playground.mdx +++ b/packages/web/docs/explore/pointer-playground.mdx @@ -4,99 +4,244 @@ sidebar_position: 2 import { PointerPlayground, PointerExample } from "@theme/PointersExample"; +export const solidityStringPointer = { + define: { slot: 0 }, + in: { + group: [ + { + name: "length-flag", + location: "storage", + slot: "slot", + offset: 31, + length: 1, + }, + { + if: { $remainder: [{ $sum: [{ $read: "length-flag" }, 1] }, 2] }, + then: { + define: { + "string-length": { $quotient: [{ $read: "length-flag" }, 2] }, + }, + in: { + name: "string", + location: "storage", + slot: "slot", + offset: 0, + length: "string-length", + }, + }, + else: { + group: [ + { + name: "long-string-length-data", + location: "storage", + slot: "slot", + offset: 0, + length: 32, + }, + { + define: { + "string-length": { + $quotient: [ + { $difference: [{ $read: "long-string-length-data" }, 1] }, + 2, + ], + }, + "start-slot": { $keccak256: [{ $wordsized: "slot" }] }, + "total-slots": { + $quotient: [ + { $sum: ["string-length", { $difference: [32, 1] }] }, + 32, + ], + }, + }, + in: { + list: { + count: "total-slots", + each: "i", + is: { + define: { + "current-slot": { $sum: ["start-slot", "i"] }, + "previous-length": { $product: ["i", 32] }, + }, + in: { + if: { + $difference: [ + "string-length", + { $sum: ["previous-length", 32] }, + ], + }, + then: { + name: "string", + location: "storage", + slot: "current-slot", + }, + else: { + name: "string", + location: "storage", + slot: "current-slot", + offset: 0, + length: { + $difference: ["string-length", "previous-length"], + }, + }, + }, + }, + }, + }, + }, + ], + }, + }, + ], + }, +}; + # Pointer playground -A **pointer** is a recipe for finding data in the EVM: it says where bytes -live and, when needed, how to compute that location from the current -machine state. The examples below let you watch pointers resolve against -concrete state — click **"Try it"** on any of them to open the playground -and see the bytes each one selects. +A **pointer** is a recipe for finding data in the EVM: where bytes live, +and how to compute that location from the current machine state. The +examples below resolve real Solidity storage layouts against concrete +state — click **"Try it"** to open the playground and watch each pointer +select its bytes. -These four cover the whole idea, from a fixed byte range to a computed -one. For the full reference, follow the links under each example. +They build up from a single packed variable to the full short/long string +layout, where the format really earns its keep. -## A byte range in memory +## A packed storage variable -The simplest pointer names a location and a byte range. Memory, calldata, -returndata, and code are byte-addressable, so their regions use `offset` -and `length`. +Solidity packs small values so several share a slot. This pointer reads a +20-byte `address` stored at byte 12 of slot 0 — a sub-slot region, offset +and length inside a single word. -## A slot in storage +## A dynamic array element -Storage, transient storage, and the stack are organized in 32-byte slots, -so their regions use `slot` instead of a byte offset. +A `uint256[]` at slot 5 stores its elements starting at `keccak256(5)`, so +element `i` lives at `keccak256(5) + i`. This pointer computes the slot for +element 2. -See [Regions](/docs/core-schemas/pointers/regions) for every location and -addressing scheme. - -## Several fields at once +## A mapping value -A **collection** bundles regions together. A `group` names each member — -ideal for a struct whose fields you want to read as a unit. +A `mapping(address => uint256)` at slot 3 stores each value at +`keccak256(key, 3)`. This pointer reads the key from the stack, hashes it +with the slot, and resolves the value's location. -See [Collections](/docs/core-schemas/pointers/collections) for groups, -lists, conditionals, and scopes. +## A Solidity storage string + +Strings are the real test. Solidity packs a **short** string (31 bytes or +fewer) directly into its slot, with `2 × length` in the slot's last byte. A +**long** string instead stores `2 × length + 1` in the slot and puts the +data at `keccak256(slot)`, spanning as many following slots as it needs. -## A location computed from state +One pointer handles both: it reads the last byte, and the parity of that +flag selects the short branch or the long branch. It's the same pointer in +both examples below — only the state changes. -When a location depends on runtime values, an **expression** computes it. -Here `$sum` adds three numbers to derive a storage slot. +### Short string + +Slot 0 packs the bytes of `"Hello"` with `0x0a` (that's `2 × 5`) in its +last byte. The flag is even, so the pointer reads the string straight out +of the slot. + +### Long string + +Here the flag is `0x51` (`2 × 40 + 1`), so the pointer takes the long +branch: it computes the length as `(0x51 − 1) / 2 = 40`, finds the data at +`keccak256(0)`, and reads 40 bytes across that slot and the next. + + -See [Expressions](/docs/core-schemas/pointers/expressions) for arithmetic, -reads, and hashing. +## Learn more + +- [Regions](/docs/core-schemas/pointers/regions) for locations and + addressing schemes +- [Collections](/docs/core-schemas/pointers/collections) for groups, + lists, and conditionals +- [Expressions](/docs/core-schemas/pointers/expressions) for arithmetic, + reads, and `$keccak256` From c9552b82a4e42414184a4047106015b88990b42e Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Thu, 2 Jul 2026 19:12:59 -0400 Subject: [PATCH 6/9] docs: prettier-format Pointer Playground page lint-staged's glob skips .mdx, so the rebuilt examples slipped past the local hook; apply prettier (quote-style only). #17 --- packages/web/docs/explore/pointer-playground.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/docs/explore/pointer-playground.mdx b/packages/web/docs/explore/pointer-playground.mdx index 4d97f0470..20fd13d44 100644 --- a/packages/web/docs/explore/pointer-playground.mdx +++ b/packages/web/docs/explore/pointer-playground.mdx @@ -231,7 +231,7 @@ branch: it computes the length as `(0x51 − 1) / 2 = 40`, finds the data at }, }} description={ - 'Resolves a 40-byte string across keccak256(0) and the following slot' + "Resolves a 40-byte string across keccak256(0) and the following slot" } /> From 80b2e1d2e0aaf0ae5422e3e36d47d45857468c2b Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Fri, 3 Jul 2026 16:59:25 -0400 Subject: [PATCH 7/9] docs: move Explore section to end of sidebar Per gnidan #227 review: Explore now sits after Reference (position 8) instead of position 2. --- packages/web/docs/explore/_category_.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/docs/explore/_category_.json b/packages/web/docs/explore/_category_.json index 955a30bc6..cc5d43602 100644 --- a/packages/web/docs/explore/_category_.json +++ b/packages/web/docs/explore/_category_.json @@ -1,4 +1,4 @@ { "label": "Explore", - "position": 2 + "position": 8 } From 16956865cc11471340e780d485dceeda2df06a6c Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Fri, 3 Jul 2026 17:06:13 -0400 Subject: [PATCH 8/9] docs: apply gnidan #227 prose notes (pointer/BUG intros, CTA labels) - pointer-playground: mark "pointer" as an ethdebug/format noun (bold+link to the pointers reference) - bug-playground: introduce BUG + bugc (optimizing reference compiler) and the self-referential validation angle - Explore CTA sidebar_labels (drop "Playground"): per-item call-to-action wording --- packages/web/docs/explore/bug-playground.mdx | 19 ++++++++++++++----- .../web/docs/explore/pointer-playground.mdx | 6 ++++-- .../web/docs/explore/trace-playground.mdx | 1 + 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/web/docs/explore/bug-playground.mdx b/packages/web/docs/explore/bug-playground.mdx index 912112eb1..08949a746 100644 --- a/packages/web/docs/explore/bug-playground.mdx +++ b/packages/web/docs/explore/bug-playground.mdx @@ -1,15 +1,24 @@ --- sidebar_position: 4 +sidebar_label: "compile a contract end to end" --- # BUG playground -BUG is a minimal smart contract language designed for demonstrating and testing -**ethdebug/format**. It compiles to EVM bytecode and produces rich debug -information. +**BUG** is a minimal smart contract language for exercising +**ethdebug/format**: small enough to read at a glance, expressive enough to +reach the cases a debug format has to handle. **bugc** is its reference +compiler — an _optimizing_ compiler from BUG to EVM bytecode that emits +**ethdebug/format** debug information alongside the code. -Use the interactive playground below to explore how BUG code compiles to -intermediate representations and EVM bytecode. +Why a reference compiler? Because a format is only as real as something +that produces it. **bugc** validates **ethdebug/format** by generating it +for every program it compiles — and you're looking at that validation +right now: the debug annotations in the **Bytecode** view below are +**bugc**'s output, the format describing real compiled code. + +Edit the source, switch views, and watch each stage update — from parse +tree to annotated bytecode. import { BugPlayground } from "@theme/BugcExample"; diff --git a/packages/web/docs/explore/pointer-playground.mdx b/packages/web/docs/explore/pointer-playground.mdx index 20fd13d44..4baa3bf4a 100644 --- a/packages/web/docs/explore/pointer-playground.mdx +++ b/packages/web/docs/explore/pointer-playground.mdx @@ -1,5 +1,6 @@ --- sidebar_position: 2 +sidebar_label: "explore high-level data with pointers" --- import { PointerPlayground, PointerExample } from "@theme/PointersExample"; @@ -98,8 +99,9 @@ export const solidityStringPointer = { # Pointer playground -A **pointer** is a recipe for finding data in the EVM: where bytes live, -and how to compute that location from the current machine state. The +A **[pointer](/docs/core-schemas/pointers)** in **ethdebug/format** is a +recipe for finding data in the EVM: where bytes live, and how to compute +that location from the current machine state. The examples below resolve real Solidity storage layouts against concrete state — click **"Try it"** to open the playground and watch each pointer select its bytes. diff --git a/packages/web/docs/explore/trace-playground.mdx b/packages/web/docs/explore/trace-playground.mdx index c339cfb0e..18567502e 100644 --- a/packages/web/docs/explore/trace-playground.mdx +++ b/packages/web/docs/explore/trace-playground.mdx @@ -1,5 +1,6 @@ --- sidebar_position: 3 +sidebar_label: "step through a live execution trace" --- import { TracePlayground, TraceExample } from "@theme/ProgramExample"; From 77347b6a3c890acdbf18c4a00446bd5297878767 Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Fri, 3 Jul 2026 17:22:30 -0400 Subject: [PATCH 9/9] docs: align pointers reference intro + refine trace CTA label - core-schemas/pointers/index.mdx: mark "pointer"/"ethdebug/format" as nouns on first use (harmonizes with the Explore pointer intro) - trace CTA sidebar_label: drop "live" --- packages/web/docs/core-schemas/pointers/index.mdx | 6 +++--- packages/web/docs/explore/trace-playground.mdx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/web/docs/core-schemas/pointers/index.mdx b/packages/web/docs/core-schemas/pointers/index.mdx index db33d46b7..9f9bd9f54 100644 --- a/packages/web/docs/core-schemas/pointers/index.mdx +++ b/packages/web/docs/core-schemas/pointers/index.mdx @@ -8,9 +8,9 @@ import SpecLink from "@site/src/components/SpecLink"; -Pointers describe where data lives in the EVM. They're recipes that tell -debuggers how to find bytes at runtime — recipes that can depend on the -current machine state. +A **pointer** in **ethdebug/format** describes where data lives in the +EVM: a recipe that tells a debugger how to find bytes at runtime — one +that can depend on the current machine state. For the mental model behind pointers (including EVM data locations), see [Concepts: Pointers](/docs/concepts/pointers). diff --git a/packages/web/docs/explore/trace-playground.mdx b/packages/web/docs/explore/trace-playground.mdx index 18567502e..01607bbd8 100644 --- a/packages/web/docs/explore/trace-playground.mdx +++ b/packages/web/docs/explore/trace-playground.mdx @@ -1,6 +1,6 @@ --- sidebar_position: 3 -sidebar_label: "step through a live execution trace" +sidebar_label: "step through an execution trace" --- import { TracePlayground, TraceExample } from "@theme/ProgramExample";