diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a0621ab07..2f809e6b24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,21 @@ The sections do not signal obligations; the prefixes do. ### Changed +- Variables now have a stated sort. A list's `each` variable is an integer. + A `define` variable has the sort of its expression, so a bytes variable + keeps its width. A template's `expect`ed variable takes the sort of the + variable in scope at the reference ([#404]). + - Schemas: **ethdebug/format/pointer/expression**, + **ethdebug/format/pointer/collection/scope**, + **ethdebug/format/pointer/collection/list**, + **ethdebug/format/pointer/template** + - Producers: optional: a bytes variable may be an operand of `~concat` or + `~keccak256` without a resize. + - Consumers: required: a variable has the sort of its defining expression. + The previous text did not say so. A consumer that read every variable as + an integer must keep a bytes variable's width. One that already kept the + sort (as `@ethdebug/pointers` does) needs no change. + - The description of the resize forms (`~sized`, `~wordsized`) said that their left-side padding and truncation match how Solidity resizes both `bytesN` and `uintN`. That holds only for `uintN`. Solidity pads and @@ -732,3 +747,4 @@ First published version of the specification. [#323]: https://github.com/ethdebug/format/pull/323 [#325]: https://github.com/ethdebug/format/pull/325 [#402]: https://github.com/ethdebug/format/pull/402 +[#404]: https://github.com/ethdebug/format/pull/404 diff --git a/schemas/pointer/collection/list.schema.yaml b/schemas/pointer/collection/list.schema.yaml index dbbcef1380..1e42d289e7 100644 --- a/schemas/pointer/collection/list.schema.yaml +++ b/schemas/pointer/collection/list.schema.yaml @@ -16,7 +16,7 @@ properties: each: description: | An identifier name whose value as an expression resolves to the index - in the list + in the list. Its value is an integer. $ref: "schema:ethdebug/format/pointer/identifier" is: description: | diff --git a/schemas/pointer/collection/scope.schema.yaml b/schemas/pointer/collection/scope.schema.yaml index 8217653c3b..4fc1486d5f 100644 --- a/schemas/pointer/collection/scope.schema.yaml +++ b/schemas/pointer/collection/scope.schema.yaml @@ -10,6 +10,12 @@ description: | expression by identifier. Variables are specified **in order**, so that later appearing variables may reference earlier ones in the same object. + Each variable has the sort of the expression that defines it (see + **ethdebug/format/pointer/expression**). A variable defined by an integer + expression is an integer. A variable defined by a bytes expression is + bytes and keeps its width, so it may be used where bytes are required, + such as an operand of `~concat` or `~keccak256`. + The variables are visible only within `in`. Pointers outside this scope do not see them: later members of an enclosing group, for example, see only the variables of their own enclosing scopes. A variable defined here @@ -45,3 +51,17 @@ examples: location: memory offset: example-offset length: example-length + + - # example: a variable with a bytes value keeps its width, so it can be + # hashed directly. this is the storage slot of `m["abc"]` for a Solidity + # `mapping(string => uint256) m` at slot 0: the key's raw bytes followed + # by the word-sized slot. + define: + key: "0x616263" + in: + name: entry + location: storage + slot: + ~keccak256: + - key + - ~wordsized: 0 diff --git a/schemas/pointer/expression.schema.yaml b/schemas/pointer/expression.schema.yaml index d7b8318dca..35ab08bf9d 100644 --- a/schemas/pointer/expression.schema.yaml +++ b/schemas/pointer/expression.schema.yaml @@ -17,16 +17,18 @@ description: | The two sorts are produced by different forms: - **Integers** are produced by a JSON-number literal, the `~wordsize` - constant, a variable or lookup (`.offset` / `.length` / `.slot`) that - denotes an index or count, an arithmetic operation (`~sum`, - `~difference`, `~product`, `~quotient`, `~remainder`), and a - hexadecimal literal that has an **odd** number of digits (which has no - whole-byte width — see `Literal`). + constant, a lookup (`.offset` / `.length` / `.slot`), an arithmetic + operation (`~sum`, `~difference`, `~product`, `~quotient`, + `~remainder`), and a hexadecimal literal that has an **odd** number of + digits (which has no whole-byte width — see `Literal`). - **Bytes** are produced by a hexadecimal literal with an **even** number of digits (its width is the number of bytes written), `~read` (its width is the length of the region read), the resize forms `~sizedN` / `~wordsized` (whose width is `N` / the word size), `~keccak256` (width 32), and `~concat` (width the sum of its operands'). + - A **variable** has the sort of its value. A list's `each` variable is + an **integer** (the index). A variable from a scope's `define` has the + sort of the expression that defines it, and bytes keep their width. ## Coercion and the width-bearing requirement @@ -87,7 +89,9 @@ $defs: description: | A string that matches an identifier used in an earlier declaration of a scalar variable. This expression evaluates to the value of that - variable. + variable, with that value's sort: an integer for a list's `each` + index, and the sort of the defining expression for a variable from a + scope's `define`. $ref: "schema:ethdebug/format/pointer/identifier" Arithmetic: diff --git a/schemas/pointer/template.schema.yaml b/schemas/pointer/template.schema.yaml index 262adf74a4..d2bb1cad90 100644 --- a/schemas/pointer/template.schema.yaml +++ b/schemas/pointer/template.schema.yaml @@ -13,6 +13,10 @@ properties: description: | An array of variable identifiers used in the definition of the pointer template. + + A template does not give these variables values. Each one takes the + value, and so the sort, of the variable with that identifier in scope + where the template is referenced. type: array items: $ref: "schema:ethdebug/format/pointer/identifier"