Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/web/spec/program/context/function/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"label": "Function contexts",
"link": null
}
14 changes: 14 additions & 0 deletions packages/web/spec/program/context/function/function.mdx
Original file line number Diff line number Diff line change
@@ -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.

<SchemaViewer
schema={{ id: "schema:ethdebug/format/program/context/function" }}
/>
44 changes: 44 additions & 0 deletions packages/web/spec/program/context/function/invoke.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
sidebar_position: 1
---

import SchemaViewer from "@site/src/components/SchemaViewer";

# Invocation contexts

<SchemaViewer
schema={{ id: "schema:ethdebug/format/program/context/function/invoke" }}
/>

## 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.

<SchemaViewer
schema={{ id: "schema:ethdebug/format/program/context/function/invoke" }}
pointer="#/$defs/InternalCall"
/>

## 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.

<SchemaViewer
schema={{ id: "schema:ethdebug/format/program/context/function/invoke" }}
pointer="#/$defs/ExternalCall"
/>

## Contract creation

A contract creation represents a CREATE or CREATE2 operation. The
presence of `salt` implies CREATE2.

<SchemaViewer
schema={{ id: "schema:ethdebug/format/program/context/function/invoke" }}
pointer="#/$defs/ContractCreation"
/>
11 changes: 11 additions & 0 deletions packages/web/spec/program/context/function/return.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
sidebar_position: 2
---

import SchemaViewer from "@site/src/components/SchemaViewer";

# Return contexts

<SchemaViewer
schema={{ id: "schema:ethdebug/format/program/context/function/return" }}
/>
11 changes: 11 additions & 0 deletions packages/web/spec/program/context/function/revert.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
sidebar_position: 3
---

import SchemaViewer from "@site/src/components/SchemaViewer";

# Revert contexts

<SchemaViewer
schema={{ id: "schema:ethdebug/format/program/context/function/revert" }}
/>
39 changes: 24 additions & 15 deletions packages/web/spec/type/concepts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,24 @@ possibly includes other fields alongside `"type"`.
</Tabs>
</details>

## 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&mdash;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": <type>, ...otherProperties }`, where `<type>` is either a complete
type representation or a reference to another type by ID.
A **type wrapper** is any object of the form
`{ "type": <specifier>, ...otherProperties }`, where `<specifier>`
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.

<details>
<summary>Example type wrapper with complete type representation</summary>
Expand Down Expand Up @@ -198,19 +204,22 @@ type representation or a reference to another type by ID.

</details>

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

<SchemaViewer schema={{ id: "schema:ethdebug/format/type/specifier" }} />

### Type wrapper schema

<SchemaViewer schema={{ id: "schema:ethdebug/format/type/wrapper" }} />

### Type reference schema

A type reference is an object containing the single `"id"` field. This field
must be a string or a number.

<SchemaViewer schema={{ id: "schema:ethdebug/format/type/reference" }} />

## Sometimes types are defined in code
Expand Down
14 changes: 11 additions & 3 deletions packages/web/src/components/SchemaViewer.tsx
Original file line number Diff line number Diff line change
@@ -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 {}

Expand Down Expand Up @@ -83,7 +85,13 @@ export default function SchemaViewer(props: SchemaViewerProps): JSX.Element {
<SchemaListing schema={props.schema} pointer={props.pointer} />
</TabItem>
<TabItem value="playground" label="Playground">
<Playground schema={props.schema} pointer={props.pointer} />
<BrowserOnly fallback={<div>Loading playground...</div>}>
{() => (
<Suspense fallback={<div>Loading playground...</div>}>
<Playground schema={props.schema} pointer={props.pointer} />
</Suspense>
)}
</BrowserOnly>
</TabItem>
</Tabs>
);
Expand Down
35 changes: 35 additions & 0 deletions packages/web/src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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 = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
19 changes: 19 additions & 0 deletions schemas/program/context.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
52 changes: 52 additions & 0 deletions schemas/program/context/function.schema.yaml
Original file line number Diff line number Diff line change
@@ -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).
- {}
Loading
Loading