@@ -9,6 +9,21 @@ support. Changes to the specification itself are tracked in the root
99
1010### Added
1111
12+ - ` block.prevrandao ` , the previous block's RANDAO value (EIP-4399), as a
13+ ` uint256 ` . It compiles to the EVM's ` PREVRANDAO ` (` 0x44 ` ) ([ #363 ] ).
14+ - ` keccak256 ` over value types: ` keccak256(a, b, ...) ` hashes the 32-byte
15+ words of one or more integers, ` address ` , ` bool ` or ` bytesN ` values, in
16+ order. For integers, ` address ` and ` bool ` this equals Solidity's
17+ ` keccak256(abi.encode(a, b, ...)) ` . A ` bytesN ` narrower than 32 bytes
18+ hashes its word with its bytes at the right end, unlike ` abi.encode ` ;
19+ cast it to ` bytes32 ` to match Solidity. A single dynamic ` bytes ` or
20+ ` string ` argument still hashes its data, and must be the only argument.
21+ The optimizer folds a hash of constant words at levels 1 to 3 ([ #365 ] ).
22+ - ` push ` on a dynamic array in storage, as in Solidity: ` a.push(v) `
23+ writes ` v ` at index ` a.length ` and adds one to the length, and
24+ ` a.push() ` adds a zero element, as for an array of arrays. ` a ` may be
25+ in a mapping or a struct. A push has no value. On an array in memory
26+ or a fixed-size array, it is a type error ([ #366 ] ).
1227- The ` % ` operator, with the precedence of ` * ` and ` / ` . It compiles to
1328 the EVM's ` MOD ` (` SMOD ` for signed operands), so ` x % 0 ` is ` 0 ` , as
1429 ` x / 0 ` is ([ #321 ] ).
@@ -28,6 +43,24 @@ support. Changes to the specification itself are tracked in the root
2843
2944### Changed
3045
46+ - The IR ` hash ` instruction now has ` values ` , a list, in place of
47+ ` value ` and ` valueDebug ` ([ #365 ] ).
48+ - An index into a dynamic array in storage now reverts with Solidity's
49+ ` Panic(0x32) ` unless it is less than the array's length, for reads and
50+ writes, as an index into an array in memory does. Before, a write past
51+ the end wrote there and left the length as it was, so the array's
52+ pointer did not show the element ([ #366 ] ).
53+ - Storage arrays now have Solidity's layout. A fixed-size array is
54+ inline: its elements start at its own slot, so `[ 0] a: array<uint256,
55+ 3>` takes slots 0 to 2, and a struct member that is a fixed-size array
56+ takes all its slots. A dynamic array still keeps its length in its
57+ slot and its elements from ` keccak256(slot) ` . In either, elements
58+ narrower than 16 bytes now share a slot, as many as fit, from its
59+ low-order end: an ` array<uint8, 40> ` takes two slots. Each storage
60+ variable's pointer describes the same layout. Before, every array's
61+ elements started at ` keccak256(slot) ` , one element to a slot, while
62+ the pointer of a fixed-size array described it inline, and the pointer
63+ of an array of narrow elements described them packed ([ #364 ] ).
3164- An integer literal operand of an arithmetic or comparison operator now
3265 takes the type of the other operand when its value fits, so with
3366 ` x: int8 ` , ` x < 0 ` , ` x == 1 ` and ` -1 < x ` compare as ` int8 ` . A literal
@@ -79,6 +112,8 @@ support. Changes to the specification itself are tracked in the root
79112
80113### Fixed
81114
115+ - ` a.length ` on a dynamic array in storage now reads the length in the
116+ array's slot. Before, it did not read that slot ([ #366 ] ).
82117- At optimization levels 2 and 3, an inlined body's control flow now has
83118 a ` transform: ["inline"] ` context: the branch of an ` if ` , the jumps
84119 between the body's blocks, each block's ` JUMPDEST ` , and the jump that
@@ -89,6 +124,61 @@ support. Changes to the specification itself are tracked in the root
89124 has the branch's context: its source range, its variables (the storage
90125 variables too) and its transforms. Before, it had no context, so a
91126 debugger listed no variables while it ran ([ #356 ] ).
127+ - ` ! ` is now a logical not: ` !true ` is ` false ` . Before, at every
128+ optimization level, it compiled to the EVM's bitwise ` NOT ` , so ` !x ` was
129+ a non-zero word, and so ` true ` , for every ` x ` ([ #353 ] ).
130+ - A source range now ends at its node's last token. Before, a node
131+ followed by whitespace or a comment included them, so most ` code `
132+ ranges had trailing whitespace: ` block.number ` in ` block.number + 1 ` ,
133+ the target ` x ` in ` x = 1 ` , a statement up to the next statement, and
134+ the ` create ` and ` code ` blocks up to the next block ([ #362 ] ).
135+ - A slice of a fixed-size ` bytesN ` value, as in
136+ ` keccak256("transfer(address,uint256)")[0:4] ` , now gives those bytes as
137+ dynamic ` bytes ` . Before, at every optimization level, the compiler read
138+ the value as the memory address of dynamic ` bytes ` , so the slice
139+ reverted with ` Panic(0x32) ` or held other memory ([ #357 ] ).
140+ - ` keccak256 ` of dynamic ` bytes ` or a ` string ` now hashes its data, and
141+ ` keccak256(msg.data) ` hashes the calldata. Before, code generation
142+ hashed the word that refers to the data (its memory address, or 0 for
143+ ` msg.data ` ). So at optimization level 0, ` keccak256("transfer()") ` was
144+ wrong, while levels 1 to 3 folded it to the right constant; at every
145+ level, the hash of a slice or of ` msg.data ` was wrong ([ #360 ] ).
146+ - The ` invoke ` context on a caller's ` JUMP ` into a function now has the
147+ call's ` arguments ` , as the callee's entry ` JUMPDEST ` does: the ` JUMP `
148+ leaves them on the stack, and the ` JUMPDEST ` does not change it.
149+ Before, only the ` JUMPDEST ` 's ` invoke ` had them, so a debugger that
150+ opens the frame on the step after the ` JUMP ` showed it for one step
151+ without its arguments ([ #354 ] ).
152+ - The instructions that run before a function's first statement now have
153+ a ` variables ` context: the memory setup at the start of the code (and
154+ ` create ` ) blocks, and a function's entry ` JUMPDEST ` and prologue. They
155+ list the storage variables and the locals in scope, a local without a
156+ pointer: a parameter is not yet in its home there, and the ` invoke ` 's
157+ ` arguments ` point at it on the stack. Before, they listed no variables,
158+ so a debugger showed none for those steps ([ #358 ] ).
159+ - Assigning a memory ` string ` or ` bytes ` to storage, as in ` s = m; ` , now
160+ stores its bytes as Solidity does: up to 31 bytes in the slot, with
161+ twice the length in the low byte; else twice the length plus one in the
162+ slot, and the data from ` keccak256(slot) ` . A slice's bytes past its
163+ length are stored as zero. Before, the slot held the value's memory
164+ address ([ #355 ] ).
165+ - A slice now copies all its bytes, as in ` msg.data[4:] ` or ` m[1:40] ` .
166+ The IR has a ` copy ` instruction, which compiles to ` CALLDATACOPY ` from
167+ calldata and ` MCOPY ` from memory. Before, a slice copied one word, so a
168+ slice longer than 32 bytes held zeros after its first 32 ([ #359 ] ).
169+ - A struct read from storage into a local, as in
170+ ` let p = players[who]; ` or ` let s = stored; ` , is now a copy in memory,
171+ as the examples' README describes: reading ` p.score ` reads the copy,
172+ and a write to ` p.score ` changes the copy, not storage. A field that is
173+ a struct is copied too; a struct with an array, mapping, ` string ` or
174+ dynamic ` bytes ` field is an error. Before, at every optimization level,
175+ the local held the struct's first storage word as if it were a memory
176+ address, and a write to one of its fields failed code generation
177+ ([ #361 ] ).
178+ - A value whose only later uses are as the address, slot or value of a
179+ read or write, or as the base of an offset, now gets a home in memory
180+ when code generation cannot keep it on the stack. Before, such a value
181+ could fail code generation with "Cannot load value" ([ #361 ] ).
92182- A call to a function with no return type now compiles as a statement,
93183 as in ` bump(); ` , at every optimization level. The function's ` return `
94184 context has no ` data ` . Before, IR generation failed with "Cannot convert
@@ -300,4 +390,17 @@ First publication.
300390[ #349 ] : https://github.com/ethdebug/format/pull/349
301391[ #351 ] : https://github.com/ethdebug/format/pull/351
302392[ #352 ] : https://github.com/ethdebug/format/pull/352
393+ [ #353 ] : https://github.com/ethdebug/format/pull/353
394+ [ #354 ] : https://github.com/ethdebug/format/pull/354
395+ [ #355 ] : https://github.com/ethdebug/format/pull/355
303396[ #356 ] : https://github.com/ethdebug/format/pull/356
397+ [ #357 ] : https://github.com/ethdebug/format/pull/357
398+ [ #358 ] : https://github.com/ethdebug/format/pull/358
399+ [ #359 ] : https://github.com/ethdebug/format/pull/359
400+ [ #360 ] : https://github.com/ethdebug/format/pull/360
401+ [ #361 ] : https://github.com/ethdebug/format/pull/361
402+ [ #362 ] : https://github.com/ethdebug/format/pull/362
403+ [ #363 ] : https://github.com/ethdebug/format/pull/363
404+ [ #364 ] : https://github.com/ethdebug/format/pull/364
405+ [ #365 ] : https://github.com/ethdebug/format/pull/365
406+ [ #366 ] : https://github.com/ethdebug/format/pull/366
0 commit comments