diff --git a/packages/web/spec/info/_category_.json b/packages/web/spec/info/_category_.json new file mode 100644 index 00000000..c5a4b4a8 --- /dev/null +++ b/packages/web/spec/info/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "ethdebug/format/info", + "position": 7, + "link": null +} diff --git a/packages/web/spec/info/info.mdx b/packages/web/spec/info/info.mdx new file mode 100644 index 00000000..3eb4eb99 --- /dev/null +++ b/packages/web/spec/info/info.mdx @@ -0,0 +1,11 @@ +--- +sidebar_position: 2 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Schema + + diff --git a/packages/web/spec/info/overview.mdx b/packages/web/spec/info/overview.mdx new file mode 100644 index 00000000..d044ee03 --- /dev/null +++ b/packages/web/spec/info/overview.mdx @@ -0,0 +1,52 @@ +--- +sidebar_position: 1 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Overview + +:::tip[Summary] + +Objects in the **ethdebug/format/info** schema organize debugging data +associated with a particular compilation. This includes lookup tables of +types and pointers by their unique name identifiers, as well as optionally may +include additional information such as complete program listings and compiled +source contents. + +::: + +This schema serves as a root schema, in that it (a) aggregates +all other schemas in this format (either directly or indirectly), and (b) in +that no other schema aggregates it. + +This schema serves as a suitable target for +[JSON Schema bundling](https://json-schema.org/understanding-json-schema/structuring#bundling), +e.g., for implementations that want to reduce complexity around validating +**ethdebug/format** records and don't want to handle reference resolution +across schema YAML files. + +:::warning + +**Note**, however, that "root schema" does not imply "objects in the schema +always contain all relevant debugging data". Due to widespread practice among +EVM language compilers to produce their own structured JSON output, objects in +this schema are not necessarily complete records of debug information. + +Compilers may choose to divide **distinct portions of debugging data** into +**distinct sections of compiler JSON output**. For instance, it likely makes +sense for a compiler to produce debugging data about a particular contract's +bytecode alongside that contract bytecode's other output information. + +At least until tooling accommodates this concern, debugging implementers +**must** be aware that they will likely need to aggregate debugging data from +multiple sections of each supported compiler's own output format. + +::: + +**However**, this schema _is suitable_ for representing a complete and +standalone debugging data record for a particular compilation, but +note the optionality of fields such as `compilation` and `programs`. +Implementations looking to produce such self-contained debugging data objects +should study the structure of these (and any other optional fields) and ensure +that such fields are fully populated. diff --git a/packages/web/spec/program/_category_.json b/packages/web/spec/program/_category_.json new file mode 100644 index 00000000..aeaea680 --- /dev/null +++ b/packages/web/spec/program/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "ethdebug/format/program", + "position": 5, + "link": null +} diff --git a/packages/web/spec/program/context/_category_.json b/packages/web/spec/program/context/_category_.json new file mode 100644 index 00000000..4f0c10a2 --- /dev/null +++ b/packages/web/spec/program/context/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Program contexts", + "position": 6, + "link": null +} diff --git a/packages/web/spec/program/context/code.mdx b/packages/web/spec/program/context/code.mdx new file mode 100644 index 00000000..8231b5a4 --- /dev/null +++ b/packages/web/spec/program/context/code.mdx @@ -0,0 +1,11 @@ +--- +sidebar_position: 4 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Code contexts + + diff --git a/packages/web/spec/program/context/context.mdx b/packages/web/spec/program/context/context.mdx new file mode 100644 index 00000000..05ee98d7 --- /dev/null +++ b/packages/web/spec/program/context/context.mdx @@ -0,0 +1,11 @@ +--- +sidebar_position: 3 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Schema + + diff --git a/packages/web/spec/program/context/variables.mdx b/packages/web/spec/program/context/variables.mdx new file mode 100644 index 00000000..88e2b552 --- /dev/null +++ b/packages/web/spec/program/context/variables.mdx @@ -0,0 +1,11 @@ +--- +sidebar_position: 5 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Variables contexts + + diff --git a/packages/web/spec/program/instruction.mdx b/packages/web/spec/program/instruction.mdx new file mode 100644 index 00000000..375e11e7 --- /dev/null +++ b/packages/web/spec/program/instruction.mdx @@ -0,0 +1,11 @@ +--- +sidebar_position: 4 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Instruction schema + + diff --git a/packages/web/spec/program/program.mdx b/packages/web/spec/program/program.mdx new file mode 100644 index 00000000..c6d59716 --- /dev/null +++ b/packages/web/spec/program/program.mdx @@ -0,0 +1,11 @@ +--- +sidebar_position: 3 +--- + +import SchemaViewer from "@site/src/components/SchemaViewer"; + +# Schema + + diff --git a/packages/web/src/css/custom.css b/packages/web/src/css/custom.css index ed7727ac..d345640e 100644 --- a/packages/web/src/css/custom.css +++ b/packages/web/src/css/custom.css @@ -59,3 +59,22 @@ text-decoration: underline !important; background-color: inherit !important; } + +.theme-doc-sidebar-item-category.root-schema > * > a::after { + margin-left: 0.5em; + content: "Root schema"; + width: min-content; + font-size: 66%; + font-weight: var(--ifm-font-weight-bold); + line-height: 1; + text-transform: uppercase; + background-color: var(--ifm-badge-background-color); + border: var(--ifm-badge-border-width) solid var(--ifm-badge-border-color); + border-radius: var(--ifm-badge-border-radius); + color: var(--ifm-color-primary-darkest); + padding: var(--ifm-badge-padding-vertical) var(--ifrm-badge-padding-horizontal); + transform: none; + + + +} diff --git a/packages/web/src/schemas.ts b/packages/web/src/schemas.ts index 65a2a87b..5732b45f 100644 --- a/packages/web/src/schemas.ts +++ b/packages/web/src/schemas.ts @@ -168,6 +168,33 @@ export const schemaIndex: SchemaIndex = { })).reduce((a, b) => ({ ...a, ...b }), {}) ), + "schema:ethdebug/format/program/context": { + title: "ethdebug/format/program/context schema", + href: "/spec/context" + }, + + ...([ + "code", + "variables" + ].map(name => ({ + [`schema:ethdebug/format/program/context/${name}`]: { + href: `/spec/context/${name}` + }, + })).reduce((a, b) => ({ ...a, ...b }), {})), + + "schema:ethdebug/format/program": { + title: "ethdebug/format/program schema", + href: "/spec/program" + }, + + ...([ + "instruction" + ].map(name => ({ + [`schema:ethdebug/format/program/${name}`]: { + href: `/spec/program/${name}` + }, + })).reduce((a, b) => ({ ...a, ...b }), {})), + "schema:ethdebug/format/materials/id": { title: "Identifier schema", href: "/spec/materials/id#identifier-schema" @@ -187,4 +214,9 @@ export const schemaIndex: SchemaIndex = { title: "Source schema", href: "/spec/materials/source" }, + + "schema:ethdebug/format/materials/source-range": { + title: "Source range schema", + href: "/spec/materials/source-range" + }, }; diff --git a/schemas/info.schema.yaml b/schemas/info.schema.yaml new file mode 100644 index 00000000..2cbccb60 --- /dev/null +++ b/schemas/info.schema.yaml @@ -0,0 +1,45 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/info" + +title: ethdebug/format/info +description: | + Objects in this schema organize debugging data relating to a particular + compilation, including **ethdebug/format/type** and + **ethdebug/format/pointer** records by name identifiers. + + Objects in this schema **may** contain debugging information about individual + sources, contracts, and compiled bytecodes, to accommodate use cases that + benefit from debugging data being collected together in a single JSON object. +type: object +properties: + types: + title: Types by name + description: | + A collection of types by name identifier. + type: object + additionalProperties: + $ref: "schema:ethdebug/format/type" + + pointers: + title: Pointer templates by name + description: | + A collection of pointer templates by name identifier. + type: object + additionalProperties: + $ref: "schema:ethdebug/format/pointer/template" + + compilation: + $ref: "schema:ethdebug/format/materials/compilation" + + programs: + type: array + items: + $ref: "schema:ethdebug/format/program" + +required: + - types + - pointers + +examples: + - types: {} + pointers: {} diff --git a/schemas/program.schema.yaml b/schemas/program.schema.yaml new file mode 100644 index 00000000..013d9a6f --- /dev/null +++ b/schemas/program.schema.yaml @@ -0,0 +1,141 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/program" + +title: ethdebug/format/program +description: | + Debugging information about a particular bytecode in a compilation. + +type: object + +properties: + compilation: + title: Compilation reference by ID + $ref: "schema:ethdebug/format/materials/reference" + + contract: + type: object + properties: + name: + type: string + + definition: + $ref: "schema:ethdebug/format/materials/source-range" + + environment: + title: Bytecode execution environment + description: | + Whether this bytecode is for contract creation or runtime calls. + type: string + enum: + - call + - create + + context: + description: | + The context known to exist prior to the execution of the first + instruction in the bytecode. + $ref: "schema:ethdebug/format/program/context" + + instructions: + type: array + description: | + The full array of instructions for the bytecode. + items: + $ref: "schema:ethdebug/format/program/instruction" + additionalItems: false + +required: + - contract + - environment + - instructions + +examples: + - # Incrementing a storage counter + # + # This example represents the call bytecode for the following pseudo-code: + # ``` + # contract Incrementer; + # + # storage { + # [0] storedValue: uint256; + # }; + # + # code { + # let localValue = storedValue; + # storedValue += 1; + # value = tmp; + # }; + # ``` + contract: + name: "Incrementer" + definition: + source: + id: 0 + environment: call + context: + variables: + - &stored-value + identifier: storedValue + type: + kind: uint + bits: 256 + pointer: + location: storage + slot: 0 + instructions: + - offset: 0 + operation: + mnemonic: PUSH0 + context: + variables: + - *stored-value + - offset: 1 + operation: + mnemonic: SLOAD + context: + variables: + - *stored-value + - &local-value + identifier: localValue + type: + kind: uint + bits: 256 + pointer: + location: stack + slot: 0 + - offset: 2 + operation: + mnemonic: PUSH1 + arguments: ["0x01"] + context: + variables: + - *stored-value + - <<: *local-value + pointer: + location: stack + slot: 1 + + - offset: 4 + operation: + mnemonic: ADD + context: + variables: + - *stored-value + - *local-value + - offset: 5 + operation: + mnemonic: PUSH0 + context: + variables: + - *stored-value + - <<: *local-value + pointer: + location: stack + slot: 1 + + - offset: 6 + operation: + mnemonic: SSTORE + context: + variables: + - *stored-value diff --git a/schemas/program/context.schema.yaml b/schemas/program/context.schema.yaml new file mode 100644 index 00000000..5995bb43 --- /dev/null +++ b/schemas/program/context.schema.yaml @@ -0,0 +1,37 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/program/context" + +title: ethdebug/format/program/context +description: | + A schema for representing the information known at compile-time about the + high-level language concerns at a particular point in code execution. + +type: object + +anyOf: + - $ref: "schema:ethdebug/format/program/context/code" + - $ref: "schema:ethdebug/format/program/context/variables" + +minProperties: 1 +unevaluatedProperties: false + +examples: + - variables: + - identifier: x + declaration: + source: + id: 5 + range: + offset: 10 + length: 56 + type: + kind: string + pointer: + location: storage + slot: 0 + code: + source: + id: 5 + range: + offset: 68 + length: 16 diff --git a/schemas/program/context/code.schema.yaml b/schemas/program/context/code.schema.yaml new file mode 100644 index 00000000..003e8d2c --- /dev/null +++ b/schemas/program/context/code.schema.yaml @@ -0,0 +1,22 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/program/context/code" + +title: ethdebug/format/program/context/code +description: | + Information about the source code range corresponding to this point in + machine execution. + +type: object +properties: + code: + $ref: "schema:ethdebug/format/materials/source-range" +required: + - code + +examples: + - code: + source: + id: 5 + range: + offset: 68 + length: 16 diff --git a/schemas/program/context/name.schema.yaml b/schemas/program/context/name.schema.yaml new file mode 100644 index 00000000..57d0ce77 --- /dev/null +++ b/schemas/program/context/name.schema.yaml @@ -0,0 +1,18 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/program/context/name" + +title: ethdebug/format/program/context/name +description: | + The name of the context, for use in disambiguating future instruction + annotations that specify one of several possible contexts based on + information only available at runtime. + +type: object +properties: + name: + type: string +required: + - name + +examples: + - name: "Array" diff --git a/schemas/program/context/variables.schema.yaml b/schemas/program/context/variables.schema.yaml new file mode 100644 index 00000000..32cf2585 --- /dev/null +++ b/schemas/program/context/variables.schema.yaml @@ -0,0 +1,80 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/program/context/variables" + +title: ethdebug/format/program/context/variables +description: | + Information about known variables at this context's point in code + execution, specified as an array whose items each correspond to a unique + variable. + + Items in this array **should not** have duplicate non-empty `identifier` + values except where high-level language semantics require it. Where + possible, use other mechanisms provided by this format to indicate that + an identifier's corresponding variable is ambiguous. + +type: object +properties: + variables: + type: array + items: + $ref: "#/$defs/Variable" + minItems: 1 + additionalItems: false +required: + - variables + +examples: + - variables: + - identifier: x + declaration: + source: + id: 5 + range: + offset: 10 + length: 56 + type: + kind: string + pointer: + location: storage + slot: 0 + +$defs: + Variable: + title: Variable + description: | + The information known about a variable at a particular point in the code + execution. + + type: object + properties: + identifier: + type: string + minLength: 1 + + declaration: + description: | + Source range corresponding to where the variable was declared. + $ref: "schema:ethdebug/format/materials/source-range" + + 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" + + pointer: + description: | + Allocation information for the variable, if it exists. + $ref: "schema:ethdebug/format/pointer" + + examples: + - identifier: x + declaration: + source: + id: 5 + range: + offset: 10 + length: 56 diff --git a/schemas/program/instruction.schema.yaml b/schemas/program/instruction.schema.yaml new file mode 100644 index 00000000..2472201c --- /dev/null +++ b/schemas/program/instruction.schema.yaml @@ -0,0 +1,65 @@ +$schema: "https://json-schema.org/draft/2020-12/schema" +$id: "schema:ethdebug/format/program/instruction" + +title: ethdebug/format/program/instruction +description: | + A schema for representing the information pertaining to a particular + instruction in machine code. + +type: object + +properties: + offset: + title: Instruction byte offset + description: | + The byte offset where the instruction begins within the bytecode. + + For legacy contract bytecode (non-EOF), this value is equivalent to the + instruction's program counter. For EOF bytecode, this value **must** be + the offset from the start of the container, not the start of a particular + code section within that container. + oneOf: + - $ref: "schema:ethdebug/format/data/unsigned" + - $ref: "schema:ethdebug/format/data/hex" + + operation: + title: Machine operation information + type: object + properties: + mnemonic: + description: The mnemonic operation code (PUSH1, e.g.) + type: string + + arguments: + description: The immediate arguments to the operation, if relevant. + type: array + minItems: 1 + items: + description: | + An immediate value, specified as a `0x`-prefixed hexadecimal string. + type: string + pattern: "^0x[0-9a-fA-F]{1,}$" + required: + - mnemonic + + context: + description: | + The context known to exist following the execution of this instruction. + $ref: "schema:ethdebug/format/program/context" + +required: + - offset + - context + +examples: + - offset: 0 + operation: + mnemonic: "PUSH1" + arguments: ["0x60"] + context: + code: + source: + id: 5 + range: + offset: 10 + length: 30