From 2121535f27bfe1e4effaf51225a8adb3230368cb Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Thu, 29 May 2025 15:41:48 +0100 Subject: [PATCH 01/12] Draft function call context schemas --- schemas/program/context.schema.yaml | 12 + schemas/program/context/invoke.schema.yaml | 250 +++++++++++++++++++++ schemas/program/context/return.schema.yaml | 69 ++++++ schemas/program/context/revert.schema.yaml | 58 +++++ 4 files changed, 389 insertions(+) create mode 100644 schemas/program/context/invoke.schema.yaml create mode 100644 schemas/program/context/return.schema.yaml create mode 100644 schemas/program/context/revert.schema.yaml diff --git a/schemas/program/context.schema.yaml b/schemas/program/context.schema.yaml index 1a8238622..f4e04309b 100644 --- a/schemas/program/context.schema.yaml +++ b/schemas/program/context.schema.yaml @@ -64,6 +64,18 @@ allOf: intermediary representation) to associate a context with a particular compiler step. $ref: "schema:ethdebug/format/program/context/frame" + - if: + required: ["invoke"] + then: + $ref: "schema:ethdebug/format/program/context/invoke" + - if: + required: ["return"] + then: + $ref: "schema:ethdebug/format/program/context/return" + - if: + required: ["revert"] + then: + $ref: "schema:ethdebug/format/program/context/revert" unevaluatedProperties: false diff --git a/schemas/program/context/invoke.schema.yaml b/schemas/program/context/invoke.schema.yaml new file mode 100644 index 000000000..820c55f98 --- /dev/null +++ b/schemas/program/context/invoke.schema.yaml @@ -0,0 +1,250 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/program/context/invoke" + +title: ethdebug/format/program/context/invoke +description: | + Schema for representing function invocation context at a specific point in + program execution. + + This context captures information about function calls, including both + internal function calls (via JUMP) and external contract calls (via CALL, + DELEGATECALL, STATICCALL, etc.). The schema distinguishes between these + different invocation types through the use of `internal` and `external` + boolean properties. + +type: object +properties: + invoke: + type: object + title: Function invocation + description: | + Represents a function invocation, either internal (via JUMP) or external + (via CALL opcodes). The schema enforces that exactly one of `internal` + or `external` must be true. + + For internal calls, only `target` and `arguments` are valid. + For external calls, `gas`, `value`, `input`, `salt`, `delegate`, + `static`, `create`, and `create2` may be used as appropriate. + + properties: + target: + type: object + title: Invocation target + description: | + Pointer to the target of the invocation. For internal calls, this + typically points to a code location. For external calls, this points + to the address being called. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + additionalProperties: false + + internal: + type: boolean + description: | + Indicates this is an internal function call (JUMP/JUMPI). + + external: + type: boolean + description: | + Indicates this is an external contract call (CALL/DELEGATECALL/etc). + + arguments: + type: object + title: Function arguments + description: | + Pointer to the arguments for an internal function call. + Only valid for internal calls. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + additionalProperties: false + + gas: + type: object + title: Gas allocation + description: | + Pointer to the gas allocated for an external call. + Only valid for external calls. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + additionalProperties: false + + value: + type: object + title: ETH value + description: | + Pointer to the amount of ETH being sent with an external call. + Only valid for external calls. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + additionalProperties: false + + input: + type: object + title: Call input data + description: | + Pointer to the input data for an external call. + Only valid for external calls. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + additionalProperties: false + + salt: + type: object + title: CREATE2 salt + description: | + Pointer to the salt value for CREATE2. + Only valid when create2 is true. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + additionalProperties: false + + delegate: + type: boolean + description: | + Indicates this external call is a DELEGATECALL. + Only valid when external is true. + + static: + type: boolean + description: | + Indicates this external call is a STATICCALL. + Only valid when external is true. + + create: + type: boolean + description: | + Indicates this external call creates a new contract (CREATE). + Only valid when external is true. + + create2: + type: boolean + description: | + Indicates this external call creates a new contract (CREATE2). + Only valid when external is true. + + required: + - target + + oneOf: + - properties: + internal: + const: true + required: + - internal + - properties: + external: + const: true + required: + - external + +required: + - invoke + +additionalProperties: false + +examples: + - invoke: + target: + pointer: + location: code + offset: 291 + length: 2 + internal: true + arguments: + pointer: + location: stack + slot: 0 + length: 3 + + - invoke: + target: + pointer: + location: stack + slot: 0 + external: true + value: + pointer: + location: stack + slot: 1 + gas: + pointer: + location: stack + slot: 2 + input: + pointer: + location: memory + offset: 128 + length: 68 + + - invoke: + target: + pointer: + location: stack + slot: 0 + external: true + delegate: true + gas: + pointer: + location: stack + slot: 1 + input: + pointer: + location: calldata + offset: 4 + length: 68 + + - invoke: + target: + pointer: + location: stack + slot: 0 + external: true + create2: true + salt: + pointer: + location: stack + slot: 1 + value: + pointer: + location: stack + slot: 2 + input: + pointer: + location: memory + offset: 0 + length: 200 + + - invoke: + target: + pointer: + location: stack + slot: 0 + external: true + static: true + gas: + pointer: + location: stack + slot: 1 + input: + pointer: + location: calldata + offset: 4 + length: 36 diff --git a/schemas/program/context/return.schema.yaml b/schemas/program/context/return.schema.yaml new file mode 100644 index 000000000..091893132 --- /dev/null +++ b/schemas/program/context/return.schema.yaml @@ -0,0 +1,69 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/program/context/return" + +title: ethdebug/format/program/context/return +description: | + Schema for representing function return context at a specific point in + program execution. + + This context captures information about successful function returns, + including the return data and, for external calls, the success status. + +type: object +properties: + return: + type: object + properties: + data: + type: object + title: Return data + description: | + Pointer to the data being returned from the function. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + + success: + type: object + title: Call success status + description: | + Pointer to the success status of an external call. + Typically points to a boolean value on the stack. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + +required: + - return + +additionalProperties: false + +examples: + - return: + data: + pointer: + location: memory + offset: 0x40 + length: 0x20 + + - return: + data: + pointer: + location: memory + offset: 0x40 + length: 0x20 + success: + pointer: + location: stack + slot: 0 + + - return: + data: + pointer: + location: returndata + offset: 0 + length: 32 diff --git a/schemas/program/context/revert.schema.yaml b/schemas/program/context/revert.schema.yaml new file mode 100644 index 000000000..032b10c1c --- /dev/null +++ b/schemas/program/context/revert.schema.yaml @@ -0,0 +1,58 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/program/context/revert" + +title: ethdebug/format/program/context/revert +description: | + Schema for representing function revert context at a specific point in + program execution. + + This context captures information about function reverts, including + revert reason data or panic codes. + +type: object +properties: + revert: + type: object + properties: + reason: + type: object + title: Revert reason + description: | + Pointer to the revert reason data. This typically contains an + ABI-encoded error message or custom error data. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + + panic: + type: integer + title: Panic code + description: | + Numeric panic code for built-in assertion failures. + Languages may define their own panic code conventions + (e.g., Solidity uses codes like 0x11 for arithmetic overflow). + +required: + - revert + +additionalProperties: false + +examples: + - revert: + reason: + pointer: + location: memory + offset: 0x40 + length: 0x60 + + - revert: + panic: 0x11 + + - revert: + reason: + pointer: + location: returndata + offset: 0 + length: 100 From e66dc6e0ceeb4cf8ada00bd0245750a7017cb874 Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Sat, 31 May 2025 14:19:56 +0100 Subject: [PATCH 02/12] Organize schema a bit --- schemas/program/context/invoke.schema.yaml | 74 +++++++++++----------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/schemas/program/context/invoke.schema.yaml b/schemas/program/context/invoke.schema.yaml index 820c55f98..70c703d7c 100644 --- a/schemas/program/context/invoke.schema.yaml +++ b/schemas/program/context/invoke.schema.yaml @@ -33,7 +33,7 @@ properties: description: | Pointer to the target of the invocation. For internal calls, this typically points to a code location. For external calls, this points - to the address being called. + to the address and/or selector being called. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -41,15 +41,26 @@ properties: - pointer additionalProperties: false + oneOf: + - $ref: "#/$defs/InternalFunctionInvocation" + - $ref: "#/$defs/ExternalFunctionInvocation" + + required: + - target + +required: + - invoke + +additionalProperties: false + +$defs: + InternalFunctionInvocation: + type: object + properties: internal: - type: boolean description: | Indicates this is an internal function call (JUMP/JUMPI). - - external: - type: boolean - description: | - Indicates this is an external contract call (CALL/DELEGATECALL/etc). + const: true arguments: type: object @@ -63,13 +74,21 @@ properties: required: - pointer additionalProperties: false + required: [internal] + + ExternalFunctionInvocation: + type: object + properties: + external: + description: | + Indicates this is an external contract call (CALL/DELEGATECALL/etc). + const: true gas: type: object title: Gas allocation description: | - Pointer to the gas allocated for an external call. - Only valid for external calls. + Pointer to the gas allocated for an external call properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -82,7 +101,6 @@ properties: title: ETH value description: | Pointer to the amount of ETH being sent with an external call. - Only valid for external calls. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -90,12 +108,12 @@ properties: - pointer additionalProperties: false - input: + salt: type: object - title: Call input data + title: CREATE2 salt description: | - Pointer to the input data for an external call. - Only valid for external calls. + Pointer to the salt value for CREATE2. + Only valid when create2 is true. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -103,12 +121,12 @@ properties: - pointer additionalProperties: false - salt: + input: type: object - title: CREATE2 salt + title: Call input data description: | - Pointer to the salt value for CREATE2. - Only valid when create2 is true. + Pointer to the input data for an external call. + Only valid for external calls. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -140,25 +158,7 @@ properties: Indicates this external call creates a new contract (CREATE2). Only valid when external is true. - required: - - target - - oneOf: - - properties: - internal: - const: true - required: - - internal - - properties: - external: - const: true - required: - - external - -required: - - invoke - -additionalProperties: false + required: [external] examples: - invoke: From a136711d24649a67e1acb1c9312c0d31276ab1f3 Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Sat, 31 May 2025 15:00:35 +0100 Subject: [PATCH 03/12] Disable unevaluated properties --- schemas/program/context/invoke.schema.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/schemas/program/context/invoke.schema.yaml b/schemas/program/context/invoke.schema.yaml index 70c703d7c..31d8060c0 100644 --- a/schemas/program/context/invoke.schema.yaml +++ b/schemas/program/context/invoke.schema.yaml @@ -45,6 +45,8 @@ properties: - $ref: "#/$defs/InternalFunctionInvocation" - $ref: "#/$defs/ExternalFunctionInvocation" + unevaluatedProperties: false + required: - target From 915bf2da1b73b07c5ada2096f6a23e2dbe6633df Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Sat, 31 May 2025 15:00:58 +0100 Subject: [PATCH 04/12] Allow additionalProperties at top-level --- schemas/program/context/invoke.schema.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/schemas/program/context/invoke.schema.yaml b/schemas/program/context/invoke.schema.yaml index 31d8060c0..e0ca257c4 100644 --- a/schemas/program/context/invoke.schema.yaml +++ b/schemas/program/context/invoke.schema.yaml @@ -53,8 +53,6 @@ properties: required: - invoke -additionalProperties: false - $defs: InternalFunctionInvocation: type: object From 92babe1c6f9ce05db61f30a26f583a514426560b Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Tue, 3 Mar 2026 20:30:35 -0500 Subject: [PATCH 05/12] Add function identity fields to invoke/return/revert contexts Introduce a shared context/function schema defining identifier, declaration, and type properties (mirroring Variable's pattern) and compose it into invoke, return, and revert via allOf. Switch return and revert from additionalProperties to unevaluatedProperties to support allOf composition. --- packages/format/src/schemas/examples.test.ts | 1 + packages/web/spec/program/context/invoke.mdx | 38 ++++ packages/web/spec/program/context/return.mdx | 11 + packages/web/spec/program/context/revert.mdx | 11 + packages/web/src/schemas.ts | 24 +- .../components/UnnecessaryComposition.tsx | 1 + schemas/program/context.schema.yaml | 9 + schemas/program/context/function.schema.yaml | 29 +++ schemas/program/context/invoke.schema.yaml | 211 ++++++++++-------- schemas/program/context/return.schema.yaml | 31 ++- schemas/program/context/revert.schema.yaml | 15 +- 11 files changed, 272 insertions(+), 109 deletions(-) create mode 100644 packages/web/spec/program/context/invoke.mdx create mode 100644 packages/web/spec/program/context/return.mdx create mode 100644 packages/web/spec/program/context/revert.mdx create mode 100644 schemas/program/context/function.schema.yaml diff --git a/packages/format/src/schemas/examples.test.ts b/packages/format/src/schemas/examples.test.ts index 0b77fbd01..7f4da0d56 100644 --- a/packages/format/src/schemas/examples.test.ts +++ b/packages/format/src/schemas/examples.test.ts @@ -13,6 +13,7 @@ const idsOfSchemasAllowedToOmitExamples = new Set([ "schema:ethdebug/format/type/elementary", "schema:ethdebug/format/pointer/region", "schema:ethdebug/format/pointer/collection", + "schema:ethdebug/format/program/context/function", ]); describe("Examples", () => { diff --git a/packages/web/spec/program/context/invoke.mdx b/packages/web/spec/program/context/invoke.mdx new file mode 100644 index 000000000..f67e610fb --- /dev/null +++ b/packages/web/spec/program/context/invoke.mdx @@ -0,0 +1,38 @@ +--- +sidebar_position: 8 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Invocation contexts + + + +## Internal function invocation + +An internal function invocation represents a call within the same +contract via JUMP/JUMPI. The target points to a code location and +arguments are passed on the stack. + + + +## External function invocation + +An external function invocation represents a call to another contract +via CALL, DELEGATECALL, STATICCALL, CREATE, or CREATE2. The type of +call may be indicated by setting exactly one of `delegate`, `static`, +`create`, or `create2` to `true`. If none of these flags is present, +the invocation represents a regular CALL. + +For CREATE and CREATE2 operations, the `target` field is forbidden +since the creation bytecode is specified via `input` instead. + + diff --git a/packages/web/spec/program/context/return.mdx b/packages/web/spec/program/context/return.mdx new file mode 100644 index 000000000..80601939b --- /dev/null +++ b/packages/web/spec/program/context/return.mdx @@ -0,0 +1,11 @@ +--- +sidebar_position: 9 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Return contexts + + diff --git a/packages/web/spec/program/context/revert.mdx b/packages/web/spec/program/context/revert.mdx new file mode 100644 index 000000000..eb606b07c --- /dev/null +++ b/packages/web/spec/program/context/revert.mdx @@ -0,0 +1,11 @@ +--- +sidebar_position: 10 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Revert contexts + + diff --git a/packages/web/src/schemas.ts b/packages/web/src/schemas.ts index 194cdf034..73c8186d0 100644 --- a/packages/web/src/schemas.ts +++ b/packages/web/src/schemas.ts @@ -224,13 +224,35 @@ const programSchemaIndex: SchemaIndex = { href: "/spec/program/context", }, - ...["code", "variables", "remark", "pick", "gather", "frame"] + ...[ + "code", + "variables", + "remark", + "pick", + "gather", + "frame", + "invoke", + "return", + "revert", + ] .map((name) => ({ [`schema:ethdebug/format/program/context/${name}`]: { href: `/spec/program/context/${name}`, }, })) .reduce((a, b) => ({ ...a, ...b }), {}), + + "schema:ethdebug/format/program/context/invoke#/$defs/InternalFunctionInvocation": + { + title: "Internal function invocation schema", + href: "/spec/program/context/invoke#internal-function-invocation", + }, + + "schema:ethdebug/format/program/context/invoke#/$defs/ExternalFunctionInvocation": + { + title: "External function invocation schema", + href: "/spec/program/context/invoke#external-function-invocation", + }, }; const infoSchemaIndex: SchemaIndex = { diff --git a/packages/web/src/theme/JSONSchemaViewer/components/UnnecessaryComposition.tsx b/packages/web/src/theme/JSONSchemaViewer/components/UnnecessaryComposition.tsx index 8640d9a47..d468c6a15 100644 --- a/packages/web/src/theme/JSONSchemaViewer/components/UnnecessaryComposition.tsx +++ b/packages/web/src/theme/JSONSchemaViewer/components/UnnecessaryComposition.tsx @@ -2,6 +2,7 @@ import React from "react"; import Link from "@docusaurus/Link"; import CreateNodes from "@theme/JSONSchemaViewer/components/CreateNodes"; import { SchemaHierarchyComponent } from "@theme-original/JSONSchemaViewer/contexts"; +import { Collapsible } from "@theme/JSONSchemaViewer/components"; import { GenerateFriendlyName, QualifierMessages, diff --git a/schemas/program/context.schema.yaml b/schemas/program/context.schema.yaml index f4e04309b..5d826288f 100644 --- a/schemas/program/context.schema.yaml +++ b/schemas/program/context.schema.yaml @@ -67,14 +67,23 @@ allOf: - if: required: ["invoke"] then: + description: | + Function invocation context, representing an internal function call + (via JUMP) or an external contract call (via CALL opcodes). $ref: "schema:ethdebug/format/program/context/invoke" - if: required: ["return"] then: + description: | + Function return context, representing the data returned from a + function and, for external calls, the success status. $ref: "schema:ethdebug/format/program/context/return" - if: required: ["revert"] then: + description: | + Function revert context, representing revert reason data or a + panic code for built-in assertion failures. $ref: "schema:ethdebug/format/program/context/revert" unevaluatedProperties: false diff --git a/schemas/program/context/function.schema.yaml b/schemas/program/context/function.schema.yaml new file mode 100644 index 000000000..d28e2d6fa --- /dev/null +++ b/schemas/program/context/function.schema.yaml @@ -0,0 +1,29 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/program/context/function" + +title: ethdebug/format/program/context/function +description: | + Common properties for identifying the function associated with + an invoke, return, or revert context. These properties mirror + the Variable schema's identity fields (identifier, declaration, + type). + +type: object +properties: + identifier: + type: string + description: | + The function's name in the source language. + + declaration: + description: | + Source range where the function is declared. + $ref: "schema:ethdebug/format/materials/source-range" + + type: + description: | + The function's type, specified either as a full + ethdebug/format/type representation or a type reference. + oneOf: + - $ref: "schema:ethdebug/format/type" + - $ref: "schema:ethdebug/format/type/reference" diff --git a/schemas/program/context/invoke.schema.yaml b/schemas/program/context/invoke.schema.yaml index e0ca257c4..f61521594 100644 --- a/schemas/program/context/invoke.schema.yaml +++ b/schemas/program/context/invoke.schema.yaml @@ -3,14 +3,12 @@ $id: "schema:ethdebug/format/program/context/invoke" title: ethdebug/format/program/context/invoke description: | - Schema for representing function invocation context at a specific point in - program execution. + Schema for representing function invocation context at a specific + point in program execution. - This context captures information about function calls, including both - internal function calls (via JUMP) and external contract calls (via CALL, - DELEGATECALL, STATICCALL, etc.). The schema distinguishes between these - different invocation types through the use of `internal` and `external` - boolean properties. + This context captures information about function calls, including + both internal function calls (via JUMP) and external contract calls + (via CALL, DELEGATECALL, STATICCALL, etc.). type: object properties: @@ -18,22 +16,39 @@ properties: type: object title: Function invocation description: | - Represents a function invocation, either internal (via JUMP) or external - (via CALL opcodes). The schema enforces that exactly one of `internal` - or `external` must be true. + Represents a function invocation, either internal (via JUMP) or + external (via CALL opcodes). - For internal calls, only `target` and `arguments` are valid. - For external calls, `gas`, `value`, `input`, `salt`, `delegate`, - `static`, `create`, and `create2` may be used as appropriate. + allOf: + - $ref: "schema:ethdebug/format/program/context/function" + - oneOf: + - required: [internal] + - required: [external] + - if: + required: [internal] + then: + $ref: "#/$defs/InternalFunctionInvocation" + - if: + required: [external] + then: + $ref: "#/$defs/ExternalFunctionInvocation" + unevaluatedProperties: false + +required: + - invoke + +$defs: + InternalFunctionInvocation: + title: Internal function invocation + type: object properties: target: type: object title: Invocation target description: | - Pointer to the target of the invocation. For internal calls, this - typically points to a code location. For external calls, this points - to the address and/or selector being called. + Pointer to the target of the invocation. For internal + calls, this typically points to a code location. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -41,22 +56,6 @@ properties: - pointer additionalProperties: false - oneOf: - - $ref: "#/$defs/InternalFunctionInvocation" - - $ref: "#/$defs/ExternalFunctionInvocation" - - unevaluatedProperties: false - - required: - - target - -required: - - invoke - -$defs: - InternalFunctionInvocation: - type: object - properties: internal: description: | Indicates this is an internal function call (JUMP/JUMPI). @@ -67,28 +66,51 @@ $defs: title: Function arguments description: | Pointer to the arguments for an internal function call. - Only valid for internal calls. properties: pointer: $ref: "schema:ethdebug/format/pointer" required: - pointer additionalProperties: false - required: [internal] + required: [internal, target] ExternalFunctionInvocation: + title: External function invocation + description: | + Represents an external contract call. The type of call may be + indicated by setting exactly one of `delegate`, `static`, + `create`, or `create2` to `true`. If none of these flags is + present, the invocation represents a regular CALL. type: object properties: + target: + type: object + title: Invocation target + description: | + Pointer to the target of the invocation. For external + calls, this points to the address and/or selector + being called. + + Not used for contract creation operations + (CREATE/CREATE2), where the creation bytecode is + specified via input instead. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + additionalProperties: false + external: description: | - Indicates this is an external contract call (CALL/DELEGATECALL/etc). + Indicates this is an external contract call. const: true gas: type: object title: Gas allocation description: | - Pointer to the gas allocated for an external call + Pointer to the gas allocated for the external call. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -100,7 +122,7 @@ $defs: type: object title: ETH value description: | - Pointer to the amount of ETH being sent with an external call. + Pointer to the amount of ETH being sent with the call. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -113,7 +135,6 @@ $defs: title: CREATE2 salt description: | Pointer to the salt value for CREATE2. - Only valid when create2 is true. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -125,8 +146,7 @@ $defs: type: object title: Call input data description: | - Pointer to the input data for an external call. - Only valid for external calls. + Pointer to the input data for the external call. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -135,116 +155,123 @@ $defs: additionalProperties: false delegate: - type: boolean description: | Indicates this external call is a DELEGATECALL. - Only valid when external is true. + const: true static: - type: boolean description: | Indicates this external call is a STATICCALL. - Only valid when external is true. + const: true create: - type: boolean description: | - Indicates this external call creates a new contract (CREATE). - Only valid when external is true. + Indicates this external call creates a new contract + (CREATE). + const: true create2: - type: boolean description: | - Indicates this external call creates a new contract (CREATE2). - Only valid when external is true. + Indicates this external call creates a new contract + (CREATE2). + const: true + + allOf: + - if: + anyOf: + - required: [create] + - required: [create2] + then: + properties: + target: false + else: + required: [target] required: [external] examples: - invoke: + identifier: "transfer" + declaration: + source: + id: 1 + range: + offset: 256 + length: 80 + type: + id: 42 target: pointer: location: code - offset: 291 - length: 2 + offset: "0x100" + length: 1 internal: true arguments: pointer: - location: stack - slot: 0 - length: 3 + group: + - name: "arg0" + location: stack + slot: 0 + - name: "arg1" + location: stack + slot: 1 - invoke: target: pointer: location: stack - slot: 0 + slot: 1 external: true - value: + gas: pointer: location: stack - slot: 1 - gas: + slot: 0 + value: pointer: location: stack slot: 2 input: pointer: - location: memory - offset: 128 - length: 68 + group: + - name: "selector" + location: memory + offset: "0x80" + length: 4 + - name: "arguments" + location: memory + offset: "0x84" + length: "0x40" - invoke: target: pointer: location: stack - slot: 0 + slot: 1 external: true delegate: true gas: pointer: location: stack - slot: 1 + slot: 0 input: pointer: - location: calldata - offset: 4 - length: 68 + location: memory + offset: "0x80" + length: "0x24" - invoke: - target: - pointer: - location: stack - slot: 0 external: true create2: true - salt: - pointer: - location: stack - slot: 1 value: - pointer: - location: stack - slot: 2 - input: - pointer: - location: memory - offset: 0 - length: 200 - - - invoke: - target: pointer: location: stack slot: 0 - external: true - static: true - gas: + salt: pointer: location: stack slot: 1 input: pointer: - location: calldata - offset: 4 - length: 36 + location: memory + offset: "0x80" + length: "0x200" diff --git a/schemas/program/context/return.schema.yaml b/schemas/program/context/return.schema.yaml index 091893132..f373216e7 100644 --- a/schemas/program/context/return.schema.yaml +++ b/schemas/program/context/return.schema.yaml @@ -13,6 +13,8 @@ type: object properties: return: type: object + allOf: + - $ref: "schema:ethdebug/format/program/context/function" properties: data: type: object @@ -37,25 +39,35 @@ properties: required: - pointer + required: + - data + + unevaluatedProperties: false + required: - return -additionalProperties: false - examples: - return: + identifier: "transfer" + declaration: + source: + id: 1 + range: + offset: 256 + length: 80 data: pointer: location: memory - offset: 0x40 - length: 0x20 + offset: "0x80" + length: "0x20" - return: data: pointer: - location: memory - offset: 0x40 - length: 0x20 + location: returndata + offset: 0 + length: "0x20" success: pointer: location: stack @@ -64,6 +76,5 @@ examples: - return: data: pointer: - location: returndata - offset: 0 - length: 32 + location: stack + slot: 0 diff --git a/schemas/program/context/revert.schema.yaml b/schemas/program/context/revert.schema.yaml index 032b10c1c..b863b6c0e 100644 --- a/schemas/program/context/revert.schema.yaml +++ b/schemas/program/context/revert.schema.yaml @@ -13,6 +13,8 @@ type: object properties: revert: type: object + allOf: + - $ref: "schema:ethdebug/format/program/context/function" properties: reason: type: object @@ -34,25 +36,26 @@ properties: Languages may define their own panic code conventions (e.g., Solidity uses codes like 0x11 for arithmetic overflow). + unevaluatedProperties: false + required: - revert -additionalProperties: false - examples: - revert: + identifier: "transfer" reason: pointer: location: memory - offset: 0x40 - length: 0x60 + offset: "0x80" + length: "0x64" - revert: - panic: 0x11 + panic: 17 - revert: reason: pointer: location: returndata offset: 0 - length: 100 + length: "0x64" From 46f193bddd5838f47b1a32487669e4eaf9b76e6d Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Tue, 3 Mar 2026 20:54:52 -0500 Subject: [PATCH 06/12] Fix Playground crash on page refresh in dev server Wrap the Monaco-based Playground component in BrowserOnly with React.lazy so it only loads client-side, preventing SSR-related initialization errors that caused [object Object] crashes on refresh. --- packages/web/src/components/SchemaViewer.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/web/src/components/SchemaViewer.tsx b/packages/web/src/components/SchemaViewer.tsx index db803ddef..93dd9627b 100644 --- a/packages/web/src/components/SchemaViewer.tsx +++ b/packages/web/src/components/SchemaViewer.tsx @@ -1,16 +1,18 @@ -import React from "react"; +import React, { Suspense } from "react"; import type { URL } from "url"; import type { JSONSchema } from "json-schema-typed/draft-2020-12"; import JSONSchemaViewer from "@theme/JSONSchemaViewer"; import CodeBlock from "@theme/CodeBlock"; import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; +import BrowserOnly from "@docusaurus/BrowserOnly"; import { type DescribeSchemaOptions, describeSchema } from "@ethdebug/format"; import { schemaIndex } from "@site/src/schemas"; import { SchemaContext, internalIdKey } from "@site/src/contexts/SchemaContext"; import ReactMarkdown from "react-markdown"; import SchemaListing from "./SchemaListing"; -import Playground from "./Playground"; + +const Playground = React.lazy(() => import("./Playground")); export interface SchemaViewerProps extends DescribeSchemaOptions {} @@ -83,7 +85,13 @@ export default function SchemaViewer(props: SchemaViewerProps): JSX.Element { - + Loading playground...}> + {() => ( + Loading playground...}> + + + )} + ); From 89a97227e9e4903b5e954310855f47dbe667c415 Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Wed, 4 Mar 2026 00:23:02 -0500 Subject: [PATCH 07/12] Nest invoke/return/revert under function/ category Move function call lifecycle contexts (invoke, return, revert) into a function/ subcategory and extract shared identity fields (identifier, declaration, type) into a base function schema that each context extends via $ref. --- .../program/context/function/_category_.json | 4 + .../program/context/function/function.mdx | 14 ++ .../spec/program/context/function/invoke.mdx | 44 +++++ .../program/context/{ => function}/return.mdx | 4 +- .../program/context/{ => function}/revert.mdx | 4 +- packages/web/spec/program/context/invoke.mdx | 38 ---- packages/web/src/schemas.ts | 47 +++-- schemas/program/context.schema.yaml | 6 +- schemas/program/context/function.schema.yaml | 29 +++- .../context/{ => function}/invoke.schema.yaml | 162 ++++++++++-------- .../context/{ => function}/return.schema.yaml | 17 +- .../context/{ => function}/revert.schema.yaml | 24 +-- 12 files changed, 234 insertions(+), 159 deletions(-) create mode 100644 packages/web/spec/program/context/function/_category_.json create mode 100644 packages/web/spec/program/context/function/function.mdx create mode 100644 packages/web/spec/program/context/function/invoke.mdx rename packages/web/spec/program/context/{ => function}/return.mdx (52%) rename packages/web/spec/program/context/{ => function}/revert.mdx (52%) delete mode 100644 packages/web/spec/program/context/invoke.mdx rename schemas/program/context/{ => function}/invoke.schema.yaml (66%) rename schemas/program/context/{ => function}/return.schema.yaml (77%) rename schemas/program/context/{ => function}/revert.schema.yaml (65%) diff --git a/packages/web/spec/program/context/function/_category_.json b/packages/web/spec/program/context/function/_category_.json new file mode 100644 index 000000000..8c013b27b --- /dev/null +++ b/packages/web/spec/program/context/function/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Function contexts", + "link": null +} diff --git a/packages/web/spec/program/context/function/function.mdx b/packages/web/spec/program/context/function/function.mdx new file mode 100644 index 000000000..0b00b3a6d --- /dev/null +++ b/packages/web/spec/program/context/function/function.mdx @@ -0,0 +1,14 @@ +--- +sidebar_position: 0 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Function identity + +Function contexts (invoke, return, revert) share a common set of +identity fields for the function being called. + + diff --git a/packages/web/spec/program/context/function/invoke.mdx b/packages/web/spec/program/context/function/invoke.mdx new file mode 100644 index 000000000..553e88f03 --- /dev/null +++ b/packages/web/spec/program/context/function/invoke.mdx @@ -0,0 +1,44 @@ +--- +sidebar_position: 1 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Invocation contexts + + + +## Internal call + +An internal call represents a function call within the same contract +via JUMP/JUMPI. The target points to a code location and arguments +are passed on the stack. + + + +## External call + +An external call represents a call to another contract via CALL, +DELEGATECALL, or STATICCALL. The type of call may be indicated by +setting `delegate` or `static` to `true`. If neither flag is present, +the invocation represents a regular CALL. + + + +## Contract creation + +A contract creation represents a CREATE or CREATE2 operation. The +presence of `salt` implies CREATE2. + + diff --git a/packages/web/spec/program/context/return.mdx b/packages/web/spec/program/context/function/return.mdx similarity index 52% rename from packages/web/spec/program/context/return.mdx rename to packages/web/spec/program/context/function/return.mdx index 80601939b..44a0f1591 100644 --- a/packages/web/spec/program/context/return.mdx +++ b/packages/web/spec/program/context/function/return.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 9 +sidebar_position: 2 --- import SchemaViewer from "@site/src/components/SchemaViewer"; @@ -7,5 +7,5 @@ import SchemaViewer from "@site/src/components/SchemaViewer"; # Return contexts diff --git a/packages/web/spec/program/context/revert.mdx b/packages/web/spec/program/context/function/revert.mdx similarity index 52% rename from packages/web/spec/program/context/revert.mdx rename to packages/web/spec/program/context/function/revert.mdx index eb606b07c..4b18b518b 100644 --- a/packages/web/spec/program/context/revert.mdx +++ b/packages/web/spec/program/context/function/revert.mdx @@ -1,5 +1,5 @@ --- -sidebar_position: 10 +sidebar_position: 3 --- import SchemaViewer from "@site/src/components/SchemaViewer"; @@ -7,5 +7,5 @@ import SchemaViewer from "@site/src/components/SchemaViewer"; # Revert contexts diff --git a/packages/web/spec/program/context/invoke.mdx b/packages/web/spec/program/context/invoke.mdx deleted file mode 100644 index f67e610fb..000000000 --- a/packages/web/spec/program/context/invoke.mdx +++ /dev/null @@ -1,38 +0,0 @@ ---- -sidebar_position: 8 ---- - -import SchemaViewer from "@site/src/components/SchemaViewer"; - -# Invocation contexts - - - -## Internal function invocation - -An internal function invocation represents a call within the same -contract via JUMP/JUMPI. The target points to a code location and -arguments are passed on the stack. - - - -## External function invocation - -An external function invocation represents a call to another contract -via CALL, DELEGATECALL, STATICCALL, CREATE, or CREATE2. The type of -call may be indicated by setting exactly one of `delegate`, `static`, -`create`, or `create2` to `true`. If none of these flags is present, -the invocation represents a regular CALL. - -For CREATE and CREATE2 operations, the `target` field is forbidden -since the creation bytecode is specified via `input` instead. - - diff --git a/packages/web/src/schemas.ts b/packages/web/src/schemas.ts index 73c8186d0..56c6a144f 100644 --- a/packages/web/src/schemas.ts +++ b/packages/web/src/schemas.ts @@ -14,6 +14,10 @@ const typeSchemaIndex: SchemaIndex = { title: "Base type wrapper schema", href: "/spec/type/base#base-type-wrapper-schema", }, + "schema:ethdebug/format/type/specifier": { + title: "Type specifier schema", + href: "/spec/type/concepts#type-specifier-schema", + }, "schema:ethdebug/format/type/wrapper": { title: "Type wrapper schema", href: "/spec/type/concepts#type-wrapper-schema", @@ -224,17 +228,7 @@ const programSchemaIndex: SchemaIndex = { href: "/spec/program/context", }, - ...[ - "code", - "variables", - "remark", - "pick", - "gather", - "frame", - "invoke", - "return", - "revert", - ] + ...["code", "variables", "remark", "pick", "gather", "frame"] .map((name) => ({ [`schema:ethdebug/format/program/context/${name}`]: { href: `/spec/program/context/${name}`, @@ -242,16 +236,35 @@ const programSchemaIndex: SchemaIndex = { })) .reduce((a, b) => ({ ...a, ...b }), {}), - "schema:ethdebug/format/program/context/invoke#/$defs/InternalFunctionInvocation": + "schema:ethdebug/format/program/context/function": { + title: "Function identity schema", + href: "/spec/program/context/function", + }, + + ...["invoke", "return", "revert"] + .map((name) => ({ + [`schema:ethdebug/format/program/context/function/${name}`]: { + href: `/spec/program/context/function/${name}`, + }, + })) + .reduce((a, b) => ({ ...a, ...b }), {}), + + "schema:ethdebug/format/program/context/function/invoke#/$defs/InternalCall": + { + title: "Internal call schema", + href: "/spec/program/context/function/invoke#internal-call", + }, + + "schema:ethdebug/format/program/context/function/invoke#/$defs/ExternalCall": { - title: "Internal function invocation schema", - href: "/spec/program/context/invoke#internal-function-invocation", + title: "External call schema", + href: "/spec/program/context/function/invoke#external-call", }, - "schema:ethdebug/format/program/context/invoke#/$defs/ExternalFunctionInvocation": + "schema:ethdebug/format/program/context/function/invoke#/$defs/ContractCreation": { - title: "External function invocation schema", - href: "/spec/program/context/invoke#external-function-invocation", + title: "Contract creation schema", + href: "/spec/program/context/function/invoke#contract-creation", }, }; diff --git a/schemas/program/context.schema.yaml b/schemas/program/context.schema.yaml index 5d826288f..3ed6e89ce 100644 --- a/schemas/program/context.schema.yaml +++ b/schemas/program/context.schema.yaml @@ -70,21 +70,21 @@ allOf: description: | Function invocation context, representing an internal function call (via JUMP) or an external contract call (via CALL opcodes). - $ref: "schema:ethdebug/format/program/context/invoke" + $ref: "schema:ethdebug/format/program/context/function/invoke" - if: required: ["return"] then: description: | Function return context, representing the data returned from a function and, for external calls, the success status. - $ref: "schema:ethdebug/format/program/context/return" + $ref: "schema:ethdebug/format/program/context/function/return" - if: required: ["revert"] then: description: | Function revert context, representing revert reason data or a panic code for built-in assertion failures. - $ref: "schema:ethdebug/format/program/context/revert" + $ref: "schema:ethdebug/format/program/context/function/revert" unevaluatedProperties: false diff --git a/schemas/program/context/function.schema.yaml b/schemas/program/context/function.schema.yaml index d28e2d6fa..375cde728 100644 --- a/schemas/program/context/function.schema.yaml +++ b/schemas/program/context/function.schema.yaml @@ -3,15 +3,19 @@ $id: "schema:ethdebug/format/program/context/function" title: ethdebug/format/program/context/function description: | - Common properties for identifying the function associated with - an invoke, return, or revert context. These properties mirror - the Variable schema's identity fields (identifier, declaration, - type). + Properties for identifying a function in the source language. + Used by function context schemas (invoke, return, revert) to + associate a compile-time function identity with runtime + execution events. + + All properties are optional so that compilers may provide as + much or as little information as is available. type: object properties: identifier: type: string + minLength: 1 description: | The function's name in the source language. @@ -24,6 +28,17 @@ properties: description: | The function's type, specified either as a full ethdebug/format/type representation or a type reference. - oneOf: - - $ref: "schema:ethdebug/format/type" - - $ref: "schema:ethdebug/format/type/reference" + $ref: "schema:ethdebug/format/type/specifier" + +examples: + - identifier: "transfer" + declaration: + source: + id: 1 + range: + offset: 256 + length: 80 + type: + id: 42 + - identifier: "balanceOf" + - {} diff --git a/schemas/program/context/invoke.schema.yaml b/schemas/program/context/function/invoke.schema.yaml similarity index 66% rename from schemas/program/context/invoke.schema.yaml rename to schemas/program/context/function/invoke.schema.yaml index f61521594..d8e5cbeff 100644 --- a/schemas/program/context/invoke.schema.yaml +++ b/schemas/program/context/function/invoke.schema.yaml @@ -1,14 +1,14 @@ $schema: "https://json-schema.org/draft/2020-12/schema" -$id: "schema:ethdebug/format/program/context/invoke" +$id: "schema:ethdebug/format/program/context/function/invoke" -title: ethdebug/format/program/context/invoke +title: ethdebug/format/program/context/function/invoke description: | - Schema for representing function invocation context at a specific - point in program execution. + Context for a function being invoked. Covers internal calls + (JUMP), external contract calls (CALL, DELEGATECALL, STATICCALL), + and contract creation (CREATE, CREATE2). - This context captures information about function calls, including - both internal function calls (via JUMP) and external contract calls - (via CALL, DELEGATECALL, STATICCALL, etc.). + Extends the function identity schema with variant-specific + fields such as call targets, gas, value, and input data. type: object properties: @@ -16,22 +16,29 @@ properties: type: object title: Function invocation description: | - Represents a function invocation, either internal (via JUMP) or - external (via CALL opcodes). + Represents a function invocation: an internal call (via JUMP), + an external call (via CALL opcodes), or a contract creation + (via CREATE/CREATE2). + + $ref: "schema:ethdebug/format/program/context/function" allOf: - - $ref: "schema:ethdebug/format/program/context/function" - oneOf: - required: [internal] - - required: [external] + - required: [call] + - required: [create] - if: required: [internal] then: - $ref: "#/$defs/InternalFunctionInvocation" + $ref: "#/$defs/InternalCall" + - if: + required: [call] + then: + $ref: "#/$defs/ExternalCall" - if: - required: [external] + required: [create] then: - $ref: "#/$defs/ExternalFunctionInvocation" + $ref: "#/$defs/ContractCreation" unevaluatedProperties: false @@ -39,10 +46,18 @@ required: - invoke $defs: - InternalFunctionInvocation: - title: Internal function invocation + InternalCall: + title: Internal call + description: | + Represents an internal function call within the same contract + (via JUMP/JUMPI). type: object properties: + internal: + description: | + Indicates this is an internal function call (JUMP/JUMPI). + const: true + target: type: object title: Invocation target @@ -56,11 +71,6 @@ $defs: - pointer additionalProperties: false - internal: - description: | - Indicates this is an internal function call (JUMP/JUMPI). - const: true - arguments: type: object title: Function arguments @@ -72,17 +82,23 @@ $defs: required: - pointer additionalProperties: false + required: [internal, target] - ExternalFunctionInvocation: - title: External function invocation + ExternalCall: + title: External call description: | - Represents an external contract call. The type of call may be - indicated by setting exactly one of `delegate`, `static`, - `create`, or `create2` to `true`. If none of these flags is - present, the invocation represents a regular CALL. + Represents an external contract call via CALL, DELEGATECALL, + or STATICCALL. The type of call may be indicated by setting + `delegate` or `static` to `true`. If neither flag is present, + the invocation represents a regular CALL. type: object properties: + call: + description: | + Indicates this is an external contract call. + const: true + target: type: object title: Invocation target @@ -90,10 +106,6 @@ $defs: Pointer to the target of the invocation. For external calls, this points to the address and/or selector being called. - - Not used for contract creation operations - (CREATE/CREATE2), where the creation bytecode is - specified via input instead. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -101,11 +113,6 @@ $defs: - pointer additionalProperties: false - external: - description: | - Indicates this is an external contract call. - const: true - gas: type: object title: Gas allocation @@ -130,18 +137,6 @@ $defs: - pointer additionalProperties: false - salt: - type: object - title: CREATE2 salt - description: | - Pointer to the salt value for CREATE2. - properties: - pointer: - $ref: "schema:ethdebug/format/pointer" - required: - - pointer - additionalProperties: false - input: type: object title: Call input data @@ -164,30 +159,60 @@ $defs: Indicates this external call is a STATICCALL. const: true + required: [call, target] + + ContractCreation: + title: Contract creation + description: | + Represents a contract creation operation via CREATE or + CREATE2. The presence of `salt` implies CREATE2. + type: object + properties: create: description: | - Indicates this external call creates a new contract - (CREATE). + Indicates this is a contract creation operation + (CREATE or CREATE2). const: true - create2: + value: + type: object + title: ETH value description: | - Indicates this external call creates a new contract - (CREATE2). - const: true + Pointer to the amount of ETH being sent with the + creation. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + additionalProperties: false - allOf: - - if: - anyOf: - - required: [create] - - required: [create2] - then: - properties: - target: false - else: - required: [target] + salt: + type: object + title: CREATE2 salt + description: | + Pointer to the salt value for CREATE2. Its presence + implies this is a CREATE2 operation. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + additionalProperties: false + + input: + type: object + title: Creation bytecode + description: | + Pointer to the creation bytecode for the new contract. + properties: + pointer: + $ref: "schema:ethdebug/format/pointer" + required: + - pointer + additionalProperties: false - required: [external] + required: [create] examples: - invoke: @@ -221,7 +246,7 @@ examples: pointer: location: stack slot: 1 - external: true + call: true gas: pointer: location: stack @@ -247,7 +272,7 @@ examples: pointer: location: stack slot: 1 - external: true + call: true delegate: true gas: pointer: @@ -260,8 +285,7 @@ examples: length: "0x24" - invoke: - external: true - create2: true + create: true value: pointer: location: stack diff --git a/schemas/program/context/return.schema.yaml b/schemas/program/context/function/return.schema.yaml similarity index 77% rename from schemas/program/context/return.schema.yaml rename to schemas/program/context/function/return.schema.yaml index f373216e7..35cf256c6 100644 --- a/schemas/program/context/return.schema.yaml +++ b/schemas/program/context/function/return.schema.yaml @@ -1,20 +1,19 @@ $schema: "https://json-schema.org/draft/2020-12/schema" -$id: "schema:ethdebug/format/program/context/return" +$id: "schema:ethdebug/format/program/context/function/return" -title: ethdebug/format/program/context/return +title: ethdebug/format/program/context/function/return description: | - Schema for representing function return context at a specific point in - program execution. - - This context captures information about successful function returns, - including the return data and, for external calls, the success status. + Context for a function returning successfully. Extends the + function identity schema with the return data pointer and, + for external calls, the success status. type: object properties: return: type: object - allOf: - - $ref: "schema:ethdebug/format/program/context/function" + + $ref: "schema:ethdebug/format/program/context/function" + properties: data: type: object diff --git a/schemas/program/context/revert.schema.yaml b/schemas/program/context/function/revert.schema.yaml similarity index 65% rename from schemas/program/context/revert.schema.yaml rename to schemas/program/context/function/revert.schema.yaml index b863b6c0e..03a7afc6a 100644 --- a/schemas/program/context/revert.schema.yaml +++ b/schemas/program/context/function/revert.schema.yaml @@ -1,27 +1,26 @@ $schema: "https://json-schema.org/draft/2020-12/schema" -$id: "schema:ethdebug/format/program/context/revert" +$id: "schema:ethdebug/format/program/context/function/revert" -title: ethdebug/format/program/context/revert +title: ethdebug/format/program/context/function/revert description: | - Schema for representing function revert context at a specific point in - program execution. - - This context captures information about function reverts, including - revert reason data or panic codes. + Context for a function that reverts. Extends the function + identity schema with optional revert reason data and/or a + numeric panic code. type: object properties: revert: type: object - allOf: - - $ref: "schema:ethdebug/format/program/context/function" + + $ref: "schema:ethdebug/format/program/context/function" + properties: reason: type: object title: Revert reason description: | - Pointer to the revert reason data. This typically contains an - ABI-encoded error message or custom error data. + Pointer to the revert reason data. This typically contains + an ABI-encoded error message or custom error data. properties: pointer: $ref: "schema:ethdebug/format/pointer" @@ -34,7 +33,8 @@ properties: description: | Numeric panic code for built-in assertion failures. Languages may define their own panic code conventions - (e.g., Solidity uses codes like 0x11 for arithmetic overflow). + (e.g., Solidity uses codes like 0x11 for arithmetic + overflow). unevaluatedProperties: false From c36b8a67e0a698d79d792ca14d645afa55423cfb Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Wed, 4 Mar 2026 00:37:38 -0500 Subject: [PATCH 08/12] Rename invoke discriminant fields: internal->jump, call->message Reduces ambiguity: `call` could mean any function call, and `internal` vs `create` doesn't clearly convey the mechanism. The new names (jump/message/create) map directly to the three EVM invocation mechanisms. Also enforces mutual exclusivity of delegate/static on external calls via `not: required: [delegate, static]`. --- .../context/function/invoke.schema.yaml | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/schemas/program/context/function/invoke.schema.yaml b/schemas/program/context/function/invoke.schema.yaml index d8e5cbeff..8bab859d7 100644 --- a/schemas/program/context/function/invoke.schema.yaml +++ b/schemas/program/context/function/invoke.schema.yaml @@ -24,15 +24,15 @@ properties: allOf: - oneOf: - - required: [internal] - - required: [call] + - required: [jump] + - required: [message] - required: [create] - if: - required: [internal] + required: [jump] then: $ref: "#/$defs/InternalCall" - if: - required: [call] + required: [message] then: $ref: "#/$defs/ExternalCall" - if: @@ -53,7 +53,7 @@ $defs: (via JUMP/JUMPI). type: object properties: - internal: + jump: description: | Indicates this is an internal function call (JUMP/JUMPI). const: true @@ -83,7 +83,7 @@ $defs: - pointer additionalProperties: false - required: [internal, target] + required: [jump, target] ExternalCall: title: External call @@ -94,9 +94,10 @@ $defs: the invocation represents a regular CALL. type: object properties: - call: + message: description: | - Indicates this is an external contract call. + Indicates this is an external message call (CALL, + DELEGATECALL, or STATICCALL). const: true target: @@ -159,7 +160,11 @@ $defs: Indicates this external call is a STATICCALL. const: true - required: [call, target] + not: + description: Only one of `delegate` and `static` can be set at a time. + required: [delegate, static] + + required: [message, target] ContractCreation: title: Contract creation @@ -230,7 +235,7 @@ examples: location: code offset: "0x100" length: 1 - internal: true + jump: true arguments: pointer: group: @@ -246,7 +251,7 @@ examples: pointer: location: stack slot: 1 - call: true + message: true gas: pointer: location: stack @@ -272,7 +277,7 @@ examples: pointer: location: stack slot: 1 - call: true + message: true delegate: true gas: pointer: From c6f0c346c6e8fa20f6f67c6af605645ba2503042 Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Wed, 4 Mar 2026 00:40:52 -0500 Subject: [PATCH 09/12] Rewrite function context descriptions Frame descriptions from the perspective of contexts marking instructions rather than "representing" things. A context indicates association with a function lifecycle event; it does not represent the event itself. --- schemas/program/context.schema.yaml | 10 +++--- schemas/program/context/function.schema.yaml | 10 +++--- .../context/function/invoke.schema.yaml | 35 ++++++++++--------- .../context/function/return.schema.yaml | 7 ++-- .../context/function/revert.schema.yaml | 7 ++-- 5 files changed, 36 insertions(+), 33 deletions(-) diff --git a/schemas/program/context.schema.yaml b/schemas/program/context.schema.yaml index 3ed6e89ce..c2875811d 100644 --- a/schemas/program/context.schema.yaml +++ b/schemas/program/context.schema.yaml @@ -68,22 +68,20 @@ allOf: required: ["invoke"] then: description: | - Function invocation context, representing an internal function call - (via JUMP) or an external contract call (via CALL opcodes). + Indicates association with a function invocation (internal call, + external message call, or contract creation). $ref: "schema:ethdebug/format/program/context/function/invoke" - if: required: ["return"] then: description: | - Function return context, representing the data returned from a - function and, for external calls, the success status. + Indicates association with a successful function return. $ref: "schema:ethdebug/format/program/context/function/return" - if: required: ["revert"] then: description: | - Function revert context, representing revert reason data or a - panic code for built-in assertion failures. + Indicates association with a function revert. $ref: "schema:ethdebug/format/program/context/function/revert" unevaluatedProperties: false diff --git a/schemas/program/context/function.schema.yaml b/schemas/program/context/function.schema.yaml index 375cde728..f16d9b9aa 100644 --- a/schemas/program/context/function.schema.yaml +++ b/schemas/program/context/function.schema.yaml @@ -3,13 +3,13 @@ $id: "schema:ethdebug/format/program/context/function" title: ethdebug/format/program/context/function description: | - Properties for identifying a function in the source language. - Used by function context schemas (invoke, return, revert) to - associate a compile-time function identity with runtime - execution events. + Properties for identifying a source-language function. Function + context schemas (invoke, return, revert) extend this schema so + that each context can optionally indicate which function it + pertains to. All properties are optional so that compilers may provide as - much or as little information as is available. + much or as little detail as is available. type: object properties: diff --git a/schemas/program/context/function/invoke.schema.yaml b/schemas/program/context/function/invoke.schema.yaml index 8bab859d7..1bf401926 100644 --- a/schemas/program/context/function/invoke.schema.yaml +++ b/schemas/program/context/function/invoke.schema.yaml @@ -3,12 +3,14 @@ $id: "schema:ethdebug/format/program/context/function/invoke" title: ethdebug/format/program/context/function/invoke description: | - Context for a function being invoked. Covers internal calls - (JUMP), external contract calls (CALL, DELEGATECALL, STATICCALL), - and contract creation (CREATE, CREATE2). + This context indicates that the marked instruction is + associated with a function invocation. The invocation is one + of three kinds: an internal call via JUMP, an external message + call (CALL / DELEGATECALL / STATICCALL), or a contract + creation (CREATE / CREATE2). - Extends the function identity schema with variant-specific - fields such as call targets, gas, value, and input data. + Extends the function identity schema with kind-specific fields + such as call targets, gas, value, and input data. type: object properties: @@ -16,9 +18,10 @@ properties: type: object title: Function invocation description: | - Represents a function invocation: an internal call (via JUMP), - an external call (via CALL opcodes), or a contract creation - (via CREATE/CREATE2). + Describes the function invocation associated with this + context. Must indicate exactly one invocation kind: `jump` + for an internal call, `message` for an external call, or + `create` for a contract creation. $ref: "schema:ethdebug/format/program/context/function" @@ -49,8 +52,8 @@ $defs: InternalCall: title: Internal call description: | - Represents an internal function call within the same contract - (via JUMP/JUMPI). + An internal function call within the same contract, entered + via JUMP/JUMPI. type: object properties: jump: @@ -88,10 +91,10 @@ $defs: ExternalCall: title: External call description: | - Represents an external contract call via CALL, DELEGATECALL, - or STATICCALL. The type of call may be indicated by setting - `delegate` or `static` to `true`. If neither flag is present, - the invocation represents a regular CALL. + An external message call to another contract via CALL, + DELEGATECALL, or STATICCALL. Set `delegate` or `static` to + `true` to indicate the call variant; if neither is present + the call is a regular CALL. type: object properties: message: @@ -169,8 +172,8 @@ $defs: ContractCreation: title: Contract creation description: | - Represents a contract creation operation via CREATE or - CREATE2. The presence of `salt` implies CREATE2. + A contract creation via CREATE or CREATE2. The presence + of `salt` distinguishes CREATE2 from CREATE. type: object properties: create: diff --git a/schemas/program/context/function/return.schema.yaml b/schemas/program/context/function/return.schema.yaml index 35cf256c6..6885cb1f2 100644 --- a/schemas/program/context/function/return.schema.yaml +++ b/schemas/program/context/function/return.schema.yaml @@ -3,9 +3,10 @@ $id: "schema:ethdebug/format/program/context/function/return" title: ethdebug/format/program/context/function/return description: | - Context for a function returning successfully. Extends the - function identity schema with the return data pointer and, - for external calls, the success status. + This context indicates that the marked instruction is + associated with a successful function return. Extends the + function identity schema with a pointer to the return data + and, for external calls, the success status. type: object properties: diff --git a/schemas/program/context/function/revert.schema.yaml b/schemas/program/context/function/revert.schema.yaml index 03a7afc6a..483805f25 100644 --- a/schemas/program/context/function/revert.schema.yaml +++ b/schemas/program/context/function/revert.schema.yaml @@ -3,9 +3,10 @@ $id: "schema:ethdebug/format/program/context/function/revert" title: ethdebug/format/program/context/function/revert description: | - Context for a function that reverts. Extends the function - identity schema with optional revert reason data and/or a - numeric panic code. + This context indicates that the marked instruction is + associated with a function revert. Extends the function + identity schema with an optional pointer to revert reason + data and/or a numeric panic code. type: object properties: From f4fd83c3164d4d21e2c30a7a0ade6cb70f92be48 Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Wed, 4 Mar 2026 01:09:40 -0500 Subject: [PATCH 10/12] Rewrite function context examples with realistic scenarios Each example now describes a concrete EVM execution scenario: which instruction the context marks, what the stack and memory layout looks like, and why each pointer points where it does. --- schemas/program/context/function.schema.yaml | 16 +++- .../context/function/invoke.schema.yaml | 92 +++++++++++++++---- .../context/function/return.schema.yaml | 37 ++++++-- .../context/function/revert.schema.yaml | 24 +++++ 4 files changed, 142 insertions(+), 27 deletions(-) diff --git a/schemas/program/context/function.schema.yaml b/schemas/program/context/function.schema.yaml index f16d9b9aa..52da86c23 100644 --- a/schemas/program/context/function.schema.yaml +++ b/schemas/program/context/function.schema.yaml @@ -31,14 +31,22 @@ properties: $ref: "schema:ethdebug/format/type/specifier" examples: + # All three identity fields provided: the compiler knows the + # function name, where it was declared, and its type. - identifier: "transfer" declaration: source: - id: 1 + id: 0 range: - offset: 256 - length: 80 + offset: 128 + length: 95 type: - id: 42 + id: 7 + + # Only the function name is known. - identifier: "balanceOf" + + # No identity information. The compiler knows that a function + # context applies but cannot attribute it to a specific + # function (e.g., an indirect call through a function pointer). - {} diff --git a/schemas/program/context/function/invoke.schema.yaml b/schemas/program/context/function/invoke.schema.yaml index 1bf401926..e1779a733 100644 --- a/schemas/program/context/function/invoke.schema.yaml +++ b/schemas/program/context/function/invoke.schema.yaml @@ -223,38 +223,68 @@ $defs: required: [create] examples: + # ----------------------------------------------------------- + # Internal call: transfer(address, uint256) + # ----------------------------------------------------------- + # This context would mark the JUMP instruction that enters + # the function. Before the jump, the compiler has arranged + # the stack as follows (top first): + # + # slot 0: jump destination (entry PC of `transfer`) + # slot 1: return label + # slot 2: first argument (`to`) + # slot 3: second argument (`amount`) + # + # The `target` pointer reads the jump destination from the + # stack; `arguments` uses a group to name each argument's + # stack position. - invoke: identifier: "transfer" declaration: source: - id: 1 + id: 0 range: - offset: 256 - length: 80 + offset: 128 + length: 95 type: - id: 42 + id: 7 + jump: true target: pointer: - location: code - offset: "0x100" - length: 1 - jump: true + location: stack + slot: 0 arguments: pointer: group: - - name: "arg0" + - name: "to" location: stack - slot: 0 - - name: "arg1" + slot: 2 + - name: "amount" location: stack - slot: 1 + slot: 3 + # ----------------------------------------------------------- + # External CALL: token.balanceOf(account) + # ----------------------------------------------------------- + # This context would mark the CALL instruction. The EVM + # expects the stack to contain (top first): + # + # slot 0: gas to forward + # slot 1: target contract address + # slot 2: value (0 — balanceOf is non-payable) + # + # The ABI-encoded calldata has already been written to + # memory at 0x80: + # + # 0x80..0x83: function selector (4 bytes) + # 0x84..0xa3: abi-encoded `account` (32 bytes) - invoke: + identifier: "balanceOf" + message: true target: pointer: location: stack slot: 1 - message: true gas: pointer: location: stack @@ -273,15 +303,31 @@ examples: - name: "arguments" location: memory offset: "0x84" - length: "0x40" + length: "0x20" + # ----------------------------------------------------------- + # DELEGATECALL: proxy forwarding calldata + # ----------------------------------------------------------- + # This context would mark a DELEGATECALL instruction in a + # proxy contract. The call executes the implementation's + # code within the proxy's storage context. + # + # DELEGATECALL takes no value parameter. Stack layout + # (top first): + # + # slot 0: gas + # slot 1: implementation address + # + # The original calldata has been copied into memory: + # + # 0x80..0xe3: forwarded calldata (100 bytes) - invoke: + message: true + delegate: true target: pointer: location: stack slot: 1 - message: true - delegate: true gas: pointer: location: stack @@ -290,8 +336,20 @@ examples: pointer: location: memory offset: "0x80" - length: "0x24" + length: "0x64" + # ----------------------------------------------------------- + # CREATE2: deploying a child contract + # ----------------------------------------------------------- + # This context would mark the CREATE2 instruction. Stack + # layout (top first): + # + # slot 0: value (ETH to send to the new contract) + # slot 1: salt (for deterministic address derivation) + # + # The init code has been placed in memory: + # + # 0x80..0x027f: creation bytecode (512 bytes) - invoke: create: true value: diff --git a/schemas/program/context/function/return.schema.yaml b/schemas/program/context/function/return.schema.yaml index 6885cb1f2..dd274f67d 100644 --- a/schemas/program/context/function/return.schema.yaml +++ b/schemas/program/context/function/return.schema.yaml @@ -48,20 +48,37 @@ required: - return examples: + # ----------------------------------------------------------- + # Internal return: transfer(address, uint256) returns (bool) + # ----------------------------------------------------------- + # This context would mark the JUMP instruction that returns + # control to the caller. The function has left its return + # value on the stack: + # + # slot 0: return value (`bool success`) - return: identifier: "transfer" declaration: source: - id: 1 + id: 0 range: - offset: 256 - length: 80 + offset: 128 + length: 95 data: pointer: - location: memory - offset: "0x80" - length: "0x20" + location: stack + slot: 0 + # ----------------------------------------------------------- + # External call return: processing result of a CALL + # ----------------------------------------------------------- + # This context would mark an instruction after a CALL that + # completed successfully. The EVM places a success flag on + # the stack, and the callee's return data is accessible via + # the returndata buffer: + # + # stack slot 0: success flag (1 = success) + # returndata 0x00..0x1f: ABI-encoded return value (32 bytes) - return: data: pointer: @@ -73,6 +90,14 @@ examples: location: stack slot: 0 + # ----------------------------------------------------------- + # Minimal return: only the data pointer + # ----------------------------------------------------------- + # When the compiler cannot attribute the return to a named + # function, the context may contain only the return data. + # Here, a single stack value is being returned. + # + # slot 0: return value - return: data: pointer: diff --git a/schemas/program/context/function/revert.schema.yaml b/schemas/program/context/function/revert.schema.yaml index 483805f25..9aecc9026 100644 --- a/schemas/program/context/function/revert.schema.yaml +++ b/schemas/program/context/function/revert.schema.yaml @@ -43,6 +43,15 @@ required: - revert examples: + # ----------------------------------------------------------- + # Revert with reason: require() failure in transfer + # ----------------------------------------------------------- + # This context would mark the REVERT instruction after a + # failed require(). The compiler has written the ABI-encoded + # Error(string) revert reason into memory: + # + # 0x80..0xe3: ABI-encoded Error(string) (100 bytes) + # selector 0x08c379a0 + offset + length + data - revert: identifier: "transfer" reason: @@ -51,9 +60,24 @@ examples: offset: "0x80" length: "0x64" + # ----------------------------------------------------------- + # Panic: arithmetic overflow (code 0x11) + # ----------------------------------------------------------- + # A built-in safety check detected an arithmetic overflow. + # The panic code alone identifies the failure; no pointer to + # revert data is needed since the compiler inserts the check + # itself. - revert: panic: 17 + # ----------------------------------------------------------- + # External call revert: processing a failed CALL + # ----------------------------------------------------------- + # This context would mark an instruction after a CALL that + # reverted. The callee's revert reason is accessible via the + # returndata buffer: + # + # returndata 0x00..0x63: ABI-encoded revert reason - revert: reason: pointer: From 9359d81d928242e44e01e269cbfcbe50dea74ac7 Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Wed, 4 Mar 2026 01:10:14 -0500 Subject: [PATCH 11/12] Add type specifier schema and use it across the format Introduce schema:ethdebug/format/type/specifier to formalize the "type or type reference" pattern. Update type wrapper, variables, and doc pages to use the new schema instead of inline oneOf/if-then discrimination. Remove the now-unnecessary allow-list entry for the function context schema. --- packages/format/src/schemas/examples.test.ts | 1 - packages/web/spec/type/concepts.mdx | 41 ++++++++++++------- schemas/program/context/variables.schema.yaml | 10 ++--- schemas/type/specifier.schema.yaml | 20 +++++++++ schemas/type/wrapper.schema.yaml | 9 +--- 5 files changed, 51 insertions(+), 30 deletions(-) create mode 100644 schemas/type/specifier.schema.yaml diff --git a/packages/format/src/schemas/examples.test.ts b/packages/format/src/schemas/examples.test.ts index 7f4da0d56..0b77fbd01 100644 --- a/packages/format/src/schemas/examples.test.ts +++ b/packages/format/src/schemas/examples.test.ts @@ -13,7 +13,6 @@ const idsOfSchemasAllowedToOmitExamples = new Set([ "schema:ethdebug/format/type/elementary", "schema:ethdebug/format/pointer/region", "schema:ethdebug/format/pointer/collection", - "schema:ethdebug/format/program/context/function", ]); describe("Examples", () => { diff --git a/packages/web/spec/type/concepts.mdx b/packages/web/spec/type/concepts.mdx index e87a516f4..554baa560 100644 --- a/packages/web/spec/type/concepts.mdx +++ b/packages/web/spec/type/concepts.mdx @@ -158,18 +158,24 @@ possibly includes other fields alongside `"type"`. -## Type wrappers and type references +## Type specifiers, wrappers, and references -This schema defines the concept of a type wrapper and the related concept of a -type reference. +This schema defines three related concepts for working with types +indirectly: **type specifiers**, **type wrappers**, and +**type references**. -Type wrappers serve to encapsulate a type representation alongside other fields -in the same object, and to facilitate discriminating which polymorphic form is -used for a particular complex type. +A **type specifier** is either a complete type representation or a +reference to a known type by ID. Type specifiers appear wherever a +type or reference to a type is needed—as the value of a type +wrapper's `"type"` field, as properties on variable and function +context schemas, etc. -Type wrappers are any object of the form -`{ "type": , ...otherProperties }`, where `` is either a complete -type representation or a reference to another type by ID. +A **type wrapper** is any object of the form +`{ "type": , ...otherProperties }`, where `` +is a type specifier. Type wrappers serve to encapsulate a type +specifier alongside other fields in the same object, and to +facilitate discriminating which polymorphic form is used for a +particular complex type.
Example type wrapper with complete type representation @@ -198,9 +204,17 @@ type representation or a reference to another type by ID.
-Note that **ethdebug/format/type** places no restriction on IDs other than -that they must be either a number or a string. Other components of this format -at-large may impose restrictions, however. +A **type reference** is the simplest form of type specifier: an +object containing only an `"id"` field. Note that +**ethdebug/format/type** places no restriction on IDs other than +that they must be either a number or a string. Other components +of this format at-large may impose restrictions, however. + +### Type specifier schema + + ### Type wrapper schema @@ -208,9 +222,6 @@ at-large may impose restrictions, however. ### Type reference schema -A type reference is an object containing the single `"id"` field. This field -must be a string or a number. - ## Sometimes types are defined in code diff --git a/schemas/program/context/variables.schema.yaml b/schemas/program/context/variables.schema.yaml index a64b43725..9987a1856 100644 --- a/schemas/program/context/variables.schema.yaml +++ b/schemas/program/context/variables.schema.yaml @@ -58,12 +58,10 @@ $defs: type: description: | - The variable's static type, if it exists. This **must** be specified - either as a full **ethdebug/format/type** representation, or an - `{ "id": "..." }` type reference object. - oneOf: - - $ref: "schema:ethdebug/format/type" - - $ref: "schema:ethdebug/format/type/reference" + The variable's static type, if it exists. This **must** be + specified either as a full **ethdebug/format/type** + representation, or an `{ "id": "..." }` type reference. + $ref: "schema:ethdebug/format/type/specifier" pointer: description: | diff --git a/schemas/type/specifier.schema.yaml b/schemas/type/specifier.schema.yaml new file mode 100644 index 000000000..8781c890e --- /dev/null +++ b/schemas/type/specifier.schema.yaml @@ -0,0 +1,20 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/type/specifier" + +title: ethdebug/format/type/specifier +description: | + A type specifier: either a complete type representation or a + reference to a known type by ID. This schema discriminates + between the two forms based on the presence of an `id` field. + +if: + required: [id] +then: + $ref: "schema:ethdebug/format/type/reference" +else: + $ref: "schema:ethdebug/format/type" + +examples: + - kind: uint + bits: 256 + - id: 42 diff --git a/schemas/type/wrapper.schema.yaml b/schemas/type/wrapper.schema.yaml index eefca6a56..8e9a277f0 100644 --- a/schemas/type/wrapper.schema.yaml +++ b/schemas/type/wrapper.schema.yaml @@ -9,14 +9,7 @@ description: type: object properties: type: - # Discriminate between reference and type based on presence of `id` - if: - required: - - id - then: - $ref: "schema:ethdebug/format/type/reference" - else: - $ref: "schema:ethdebug/format/type" + $ref: "schema:ethdebug/format/type/specifier" required: - type From dddc5bfa14f5a0d531556e9418a9d5ea7bfe06cc Mon Sep 17 00:00:00 2001 From: "g. nicholas d'andrea" Date: Wed, 4 Mar 2026 01:15:39 -0500 Subject: [PATCH 12/12] Format --- packages/web/spec/type/concepts.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/web/spec/type/concepts.mdx b/packages/web/spec/type/concepts.mdx index 554baa560..e42bcbf7f 100644 --- a/packages/web/spec/type/concepts.mdx +++ b/packages/web/spec/type/concepts.mdx @@ -212,9 +212,7 @@ of this format at-large may impose restrictions, however. ### Type specifier schema - + ### Type wrapper schema