Skip to content

Commit

Permalink
Merge pull request #91 from ethdebug/pointer-scopes
Browse files Browse the repository at this point in the history
Add scope collection to pointer schema and fix storage string pointer example
  • Loading branch information
gnidan committed Jun 17, 2024
2 parents 9896b3f + 90a5961 commit 60d7296
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 46 deletions.
11 changes: 11 additions & 0 deletions packages/web/spec/pointer/collection/scope.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
sidebar_position: 5
---

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

# Scope

<SchemaViewer
schema={{ id: "schema:ethdebug/format/pointer/collection/scope" }}
/>
2 changes: 1 addition & 1 deletion packages/web/src/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export const schemaIndex: SchemaIndex = {

...(
[
"group", "list", "conditional"
"group", "list", "conditional", "scope"
].map(collection => ({
[`schema:ethdebug/format/pointer/collection/${collection}`]: {
href: `/spec/pointer/collection/${collection}`
Expand Down
130 changes: 85 additions & 45 deletions schemas/pointer.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -142,53 +142,93 @@ examples:
length: $wordsize

- # example `string storage` allocation
group:
# for short strings, the length is stored as 2n in the last byte of slot
- name: "length-flag"
location: storage
slot: 0
offset:
$difference:
- $wordsize
- 1
length: 1

# long strings may use full word to describe length as 2n+1
- name: "long-length-data"
location: storage
slot:
.slot: "length-flag"
offset: 0
length: $wordsize
define:
"contract-variable-slot": 0
in:
group:
# for short strings, the length is stored as 2n in the last byte of slot
- name: "length-flag"
location: storage
slot: contract-variable-slot
offset:
$difference: [$wordsize, 1]
length: 1

# define the region representing the string data itself conditionally
# based on odd or even length data
- if:
$remainder:
- $read: "length-flag"
- 2
then:
name: "string"
# long strings may use full word to describe length as 2n+1
- name: "long-string-length-data"
location: storage
slot:
$keccak256:
- .slot: "length-flag"
slot: contract-variable-slot
offset: 0
length:
# length n is encoded as 2n+1
$quotient:
- $difference:
- $read: "long-length-data"
length: $wordsize

# define the region representing the string data itself conditionally
# based on odd or even length data
- if:
$remainder:
- $sum:
- $read: "length-flag"
- 1
- 2
else:
name: "string"
location: storage
slot:
.slot: "length-flag"
offset: 0
length:
# length n is encoded as 2n
$quotient:
- $read: "length-flag"
- 2

# short string case (flag is even)
then:
define:
"string-length":
$quotient: [{ $read: "length-flag" }, 2]
in:
name: "string"
location: storage
slot: "contract-variable-slot"
offset: 0
length: "string-length"

# long string case (flag is odd)
else:
define:
"string-length":
$quotient:
- $difference:
- $read: "long-string-length-data"
- 1
- 2

"start-slot":
$keccak256: ["contract-variable-slot"]

"total-slots":
# account for both zero and nonzero slot remainders by adding
# $wordsize-1 to the length before dividing
$quotient:
- $sum: ["string-length", { $difference: [$wordsize, 1] }]
- $wordsize
in:
list:
count: "total-slots"
each: "i"
is:
define:
"current-slot":
$sum: ["start-slot", "i"]
"previous-length":
$product: ["i", $wordsize]
in:
# conditional based on whether this is the last slot:
# is the string length longer than the previous length
# plus this whole slot?
if:
$difference:
- "string-length"
- $sum: ["previous-length", "$wordsize"]
then:
# include the whole slot
name: "string"
location: storage
slot: "current-slot"
else:
# include only what's left in the string
name: "string"
location: storage
slot: "current-slot"
offset: 0
length:
$difference: ["string-length", "previous-length"]
8 changes: 8 additions & 0 deletions schemas/pointer/collection.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ allOf:
- list
- required:
- if
- required:
- define
- if:
required:
- group
Expand All @@ -31,3 +33,9 @@ allOf:
- if
then:
$ref: "schema:ethdebug/format/pointer/collection/conditional"

- if:
required:
- define
then:
$ref: "schema:ethdebug/format/pointer/collection/scope"
42 changes: 42 additions & 0 deletions schemas/pointer/collection/scope.schema.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "schema:ethdebug/format/pointer/collection/scope"

title: ethdebug/format/pointer/collection/scope
description: |
A pointer defined with the aid of additional variables with values specified
as expressions.
Variables are specified by the `define` field as an object mapping of
expression by identifier. Variables are specified **in order**, so that
later appearing variables may reference earlier ones in the same object.
type: object

properties:
define:
title: Mapping of variables to expression value
type: object
patternProperties:
"^[a-zA-Z_\\-]+[a-zA-Z0-9$_\\-]*$":
$ref: "schema:ethdebug/format/pointer/expression"
additionalProperties: false
in:
$ref: "schema:ethdebug/format/pointer"

required:
- define
- in

additionalProperties: false

examples:
- define:
example-offset:
$sum: [1, 2]
example-length:
$product: [2, $wordsize]
in:
name: example
location: memory
offset: example-offset
length: example-length
3 changes: 3 additions & 0 deletions schemas/pointer/expression.schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ $defs:
A tuple of two expressions where the second is to be subtracted from
the first.
If the second operand is larger than the first, the result of this
arithmetic operation is defined to equal zero (`0`).
(i.e., `{ "$difference": [a, b] }` equals `a` minus `b`.)
$ref: "#/$defs/Operands"
minItems: 2
Expand Down

0 comments on commit 60d7296

Please sign in to comment.