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 00000000..8c013b27
--- /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 00000000..0b00b3a6
--- /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 00000000..553e88f0
--- /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/function/return.mdx b/packages/web/spec/program/context/function/return.mdx
new file mode 100644
index 00000000..44a0f159
--- /dev/null
+++ b/packages/web/spec/program/context/function/return.mdx
@@ -0,0 +1,11 @@
+---
+sidebar_position: 2
+---
+
+import SchemaViewer from "@site/src/components/SchemaViewer";
+
+# Return contexts
+
+
diff --git a/packages/web/spec/program/context/function/revert.mdx b/packages/web/spec/program/context/function/revert.mdx
new file mode 100644
index 00000000..4b18b518
--- /dev/null
+++ b/packages/web/spec/program/context/function/revert.mdx
@@ -0,0 +1,11 @@
+---
+sidebar_position: 3
+---
+
+import SchemaViewer from "@site/src/components/SchemaViewer";
+
+# Revert contexts
+
+
diff --git a/packages/web/spec/type/concepts.mdx b/packages/web/spec/type/concepts.mdx
index e87a516f..e42bcbf7 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,15 @@ 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 +220,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/packages/web/src/components/SchemaViewer.tsx b/packages/web/src/components/SchemaViewer.tsx
index db803dde..93dd9627 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...}>
+
+
+ )}
+
);
diff --git a/packages/web/src/schemas.ts b/packages/web/src/schemas.ts
index 194cdf03..56c6a144 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",
@@ -231,6 +235,37 @@ const programSchemaIndex: SchemaIndex = {
},
}))
.reduce((a, b) => ({ ...a, ...b }), {}),
+
+ "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: "External call schema",
+ href: "/spec/program/context/function/invoke#external-call",
+ },
+
+ "schema:ethdebug/format/program/context/function/invoke#/$defs/ContractCreation":
+ {
+ title: "Contract creation schema",
+ href: "/spec/program/context/function/invoke#contract-creation",
+ },
};
const infoSchemaIndex: SchemaIndex = {
diff --git a/packages/web/src/theme/JSONSchemaViewer/components/UnnecessaryComposition.tsx b/packages/web/src/theme/JSONSchemaViewer/components/UnnecessaryComposition.tsx
index 8640d9a4..d468c6a1 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 1a823862..c2875811 100644
--- a/schemas/program/context.schema.yaml
+++ b/schemas/program/context.schema.yaml
@@ -64,6 +64,25 @@ allOf:
intermediary representation) to associate a
context with a particular compiler step.
$ref: "schema:ethdebug/format/program/context/frame"
+ - if:
+ required: ["invoke"]
+ then:
+ description: |
+ 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: |
+ Indicates association with a successful function return.
+ $ref: "schema:ethdebug/format/program/context/function/return"
+ - if:
+ required: ["revert"]
+ then:
+ description: |
+ 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
new file mode 100644
index 00000000..52da86c2
--- /dev/null
+++ b/schemas/program/context/function.schema.yaml
@@ -0,0 +1,52 @@
+$schema: "https://json-schema.org/draft/2020-12/schema"
+$id: "schema:ethdebug/format/program/context/function"
+
+title: ethdebug/format/program/context/function
+description: |
+ 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 detail as is available.
+
+type: object
+properties:
+ identifier:
+ type: string
+ minLength: 1
+ 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.
+ $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: 0
+ range:
+ offset: 128
+ length: 95
+ type:
+ 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
new file mode 100644
index 00000000..e1779a73
--- /dev/null
+++ b/schemas/program/context/function/invoke.schema.yaml
@@ -0,0 +1,367 @@
+$schema: "https://json-schema.org/draft/2020-12/schema"
+$id: "schema:ethdebug/format/program/context/function/invoke"
+
+title: ethdebug/format/program/context/function/invoke
+description: |
+ 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 kind-specific fields
+ such as call targets, gas, value, and input data.
+
+type: object
+properties:
+ invoke:
+ type: object
+ title: Function invocation
+ description: |
+ 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"
+
+ allOf:
+ - oneOf:
+ - required: [jump]
+ - required: [message]
+ - required: [create]
+ - if:
+ required: [jump]
+ then:
+ $ref: "#/$defs/InternalCall"
+ - if:
+ required: [message]
+ then:
+ $ref: "#/$defs/ExternalCall"
+ - if:
+ required: [create]
+ then:
+ $ref: "#/$defs/ContractCreation"
+
+ unevaluatedProperties: false
+
+required:
+ - invoke
+
+$defs:
+ InternalCall:
+ title: Internal call
+ description: |
+ An internal function call within the same contract, entered
+ via JUMP/JUMPI.
+ type: object
+ properties:
+ jump:
+ description: |
+ Indicates this is an internal function call (JUMP/JUMPI).
+ const: true
+
+ target:
+ type: object
+ title: Invocation target
+ description: |
+ Pointer to the target of the invocation. For internal
+ calls, this typically points to a code location.
+ properties:
+ pointer:
+ $ref: "schema:ethdebug/format/pointer"
+ required:
+ - pointer
+ additionalProperties: false
+
+ arguments:
+ type: object
+ title: Function arguments
+ description: |
+ Pointer to the arguments for an internal function call.
+ properties:
+ pointer:
+ $ref: "schema:ethdebug/format/pointer"
+ required:
+ - pointer
+ additionalProperties: false
+
+ required: [jump, target]
+
+ ExternalCall:
+ title: External call
+ description: |
+ 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:
+ description: |
+ Indicates this is an external message call (CALL,
+ DELEGATECALL, or STATICCALL).
+ const: true
+
+ 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.
+ properties:
+ pointer:
+ $ref: "schema:ethdebug/format/pointer"
+ required:
+ - pointer
+ additionalProperties: false
+
+ gas:
+ type: object
+ title: Gas allocation
+ description: |
+ Pointer to the gas allocated for the external call.
+ 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 the call.
+ 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 the external call.
+ properties:
+ pointer:
+ $ref: "schema:ethdebug/format/pointer"
+ required:
+ - pointer
+ additionalProperties: false
+
+ delegate:
+ description: |
+ Indicates this external call is a DELEGATECALL.
+ const: true
+
+ static:
+ description: |
+ Indicates this external call is a STATICCALL.
+ const: true
+
+ not:
+ description: Only one of `delegate` and `static` can be set at a time.
+ required: [delegate, static]
+
+ required: [message, target]
+
+ ContractCreation:
+ title: Contract creation
+ description: |
+ A contract creation via CREATE or CREATE2. The presence
+ of `salt` distinguishes CREATE2 from CREATE.
+ type: object
+ properties:
+ create:
+ description: |
+ Indicates this is a contract creation operation
+ (CREATE or CREATE2).
+ const: true
+
+ value:
+ type: object
+ title: ETH value
+ description: |
+ Pointer to the amount of ETH being sent with the
+ creation.
+ 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. 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: [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: 0
+ range:
+ offset: 128
+ length: 95
+ type:
+ id: 7
+ jump: true
+ target:
+ pointer:
+ location: stack
+ slot: 0
+ arguments:
+ pointer:
+ group:
+ - name: "to"
+ location: stack
+ slot: 2
+ - name: "amount"
+ location: stack
+ 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
+ gas:
+ pointer:
+ location: stack
+ slot: 0
+ value:
+ pointer:
+ location: stack
+ slot: 2
+ input:
+ pointer:
+ group:
+ - name: "selector"
+ location: memory
+ offset: "0x80"
+ length: 4
+ - name: "arguments"
+ location: memory
+ offset: "0x84"
+ 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
+ gas:
+ pointer:
+ location: stack
+ slot: 0
+ input:
+ pointer:
+ location: memory
+ offset: "0x80"
+ 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:
+ pointer:
+ location: stack
+ slot: 0
+ salt:
+ pointer:
+ location: stack
+ slot: 1
+ input:
+ pointer:
+ location: memory
+ offset: "0x80"
+ length: "0x200"
diff --git a/schemas/program/context/function/return.schema.yaml b/schemas/program/context/function/return.schema.yaml
new file mode 100644
index 00000000..dd274f67
--- /dev/null
+++ b/schemas/program/context/function/return.schema.yaml
@@ -0,0 +1,105 @@
+$schema: "https://json-schema.org/draft/2020-12/schema"
+$id: "schema:ethdebug/format/program/context/function/return"
+
+title: ethdebug/format/program/context/function/return
+description: |
+ 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:
+ return:
+ type: object
+
+ $ref: "schema:ethdebug/format/program/context/function"
+
+ 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:
+ - data
+
+ unevaluatedProperties: false
+
+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: 0
+ range:
+ offset: 128
+ length: 95
+ data:
+ pointer:
+ 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:
+ location: returndata
+ offset: 0
+ length: "0x20"
+ success:
+ pointer:
+ 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:
+ location: stack
+ slot: 0
diff --git a/schemas/program/context/function/revert.schema.yaml b/schemas/program/context/function/revert.schema.yaml
new file mode 100644
index 00000000..9aecc902
--- /dev/null
+++ b/schemas/program/context/function/revert.schema.yaml
@@ -0,0 +1,86 @@
+$schema: "https://json-schema.org/draft/2020-12/schema"
+$id: "schema:ethdebug/format/program/context/function/revert"
+
+title: ethdebug/format/program/context/function/revert
+description: |
+ 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:
+ revert:
+ type: object
+
+ $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.
+ 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).
+
+ unevaluatedProperties: false
+
+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:
+ pointer:
+ location: memory
+ 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:
+ location: returndata
+ offset: 0
+ length: "0x64"
diff --git a/schemas/program/context/variables.schema.yaml b/schemas/program/context/variables.schema.yaml
index a64b4372..9987a185 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 00000000..8781c890
--- /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 eefca6a5..8e9a277f 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