Skip to content

Instantly share code, notes, and snippets.

@ekpyron
Created April 13, 2021 09:24
Show Gist options
  • Save ekpyron/4722673da507e38cb0065310d3af7879 to your computer and use it in GitHub Desktop.
Save ekpyron/4722673da507e38cb0065310d3af7879 to your computer and use it in GitHub Desktop.
Change in test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol
Optimized IR:
/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object "c_145" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("c_145_deployed")
codecopy(0, dataoffset("c_145_deployed"), _1)
return(0, _1)
}
}
object "c_145_deployed" {
code {
{
let _1 := 64
mstore(_1, 128)
if iszero(lt(calldatasize(), 4))
{
let _2 := 0
switch shr(224, calldataload(_2))
case 0x0178fe3f {
if callvalue() { revert(_2, _2) }
let ret, ret_1 := fun_getData(abi_decode_uint256(calldatasize()))
let memPos := mload(_1)
return(memPos, sub(abi_encode_uint256_uint256(memPos, ret, ret_1), memPos))
}
case 0x0d18e43c {
if callvalue() { revert(_2, _2) }
let ret_2 := fun_getID(abi_decode_uint256(calldatasize()))
let memPos_1 := mload(_1)
return(memPos_1, sub(abi_encode_uint256(memPos_1, ret_2), memPos_1))
}
case 0x23fef0c0 {
if callvalue() { revert(_2, _2) }
let param, param_1 := abi_decode_uint256t_uint256(calldatasize())
fun_setLengths(param, param_1)
return(mload(_1), _2)
}
case 0x2909f638 {
if callvalue() { revert(_2, _2) }
let param_2, param_3, param_4 := abi_decode_uint256t_uint256t_uint256(calldatasize())
fun_setData(param_2, param_3, param_4)
return(mload(_1), _2)
}
case 0x800bd5c8 {
if callvalue() { revert(_2, _2) }
abi_decode(calldatasize())
let ret_3, ret_4 := fun_getLengths()
let memPos_2 := mload(_1)
return(memPos_2, sub(abi_encode_uint256_uint256(memPos_2, ret_3, ret_4), memPos_2))
}
case 0xb55e49c0 {
if callvalue() { revert(_2, _2) }
fun_setIDStatic(abi_decode_uint256(calldatasize()))
return(mload(_1), _2)
}
case 0xcc959c73 {
if callvalue() { revert(_2, _2) }
let param_5, param_6 := abi_decode_uint256t_uint256(calldatasize())
fun_setID(param_5, param_6)
return(mload(_1), _2)
}
}
revert(0, 0)
}
function abi_decode(dataEnd)
{
if slt(add(dataEnd, not(3)), 0) { revert(0, 0) }
}
function abi_decode_uint256(dataEnd) -> value0
{
if slt(add(dataEnd, not(3)), 32) { revert(0, 0) }
value0 := calldataload(4)
}
function abi_decode_uint256t_uint256(dataEnd) -> value0, value1
{
if slt(add(dataEnd, not(3)), 64) { revert(0, 0) }
value0 := calldataload(4)
value1 := calldataload(36)
}
function abi_decode_uint256t_uint256t_uint256(dataEnd) -> value0, value1, value2
{
if slt(add(dataEnd, not(3)), 96) { revert(0, 0) }
value0 := calldataload(4)
value1 := calldataload(36)
value2 := calldataload(68)
}
function abi_encode_uint256(headStart, value0) -> tail
{
tail := add(headStart, 32)
mstore(headStart, value0)
}
function abi_encode_uint256_uint256(headStart, value0, value1) -> tail
{
tail := add(headStart, 64)
mstore(headStart, value0)
mstore(add(headStart, 32), value1)
}
function fun_getData(var_index) -> var_x, var_y
{
let _1, _2 := storage_array_index_access_struct_Data__dyn(var_index)
var_x := sload(_1)
let _3, _4 := storage_array_index_access_struct_Data__dyn(var_index)
var_y := sload(add(_3, 1))
}
function fun_getID(var_index) -> var
{
let _1, _2 := storage_array_index_access_uint256_dyn(var_index)
var := shr(shl(3, _2), sload(_1))
}
function fun_getLengths() -> var_l1, var_l2
{
var_l1 := sload(0x00)
var_l2 := sload(0x01)
}
function fun_setData(var_index, var_x, var_y)
{
let _1, _2 := storage_array_index_access_struct_Data__dyn(var_index)
sstore(_1, var_x)
let _3, _4 := storage_array_index_access_struct_Data__dyn(var_index)
sstore(add(_3, 1), var_y)
}
function fun_setIDStatic(var_id)
{
if iszero(lt(0x02, sload(0x01))) { panic_error_0x32() }
mstore(0, 0x01)
sstore(add(keccak256(0, 0x20), 0x02), var_id)
}
function fun_setID(var_index, var_id)
{
let _1, _2 := storage_array_index_access_uint256_dyn(var_index)
let _3 := sload(_1)
let shiftBits := shl(3, _2)
let mask := shl(shiftBits, not(0))
sstore(_1, or(and(_3, not(mask)), and(shl(shiftBits, var_id), mask)))
}
function fun_setLengths(var_l1, var_l2)
{
for { } 1 { }
{
let _1 := 0x00
let expr := sload(_1)
if iszero(lt(expr, var_l1)) { break }
if iszero(lt(expr, 18446744073709551616)) { panic_error_0x41() }
sstore(_1, add(expr, 1))
let slot, offset := storage_array_index_access_struct_Data__dyn(expr)
}
for { } 1 { }
{
let _2 := 1
let expr_1 := sload(_2)
if iszero(lt(expr_1, var_l2)) { break }
if iszero(lt(expr_1, 18446744073709551616)) { panic_error_0x41() }
sstore(_2, add(expr_1, _2))
let slot_1, offset_1 := storage_array_index_access_uint256_dyn(expr_1)
}
}
function panic_error_0x32()
{
mstore(0, shl(224, 0x4e487b71))
mstore(4, 0x32)
revert(0, 0x24)
}
function panic_error_0x41()
{
mstore(0, shl(224, 0x4e487b71))
mstore(4, 0x41)
revert(0, 0x24)
}
function storage_array_index_access_struct_Data__dyn(index) -> slot, offset
{
if iszero(lt(index, sload(0x00))) { panic_error_0x32() }
mstore(0x00, 0x00)
let data := keccak256(0x00, 0x20)
slot := add(data, shl(1, index))
offset := 0x00
}
function storage_array_index_access_uint256_dyn(index) -> slot, offset
{
if iszero(lt(index, sload(0x01))) { panic_error_0x32() }
mstore(0, 0x01)
slot := add(keccak256(0, 0x20), index)
offset := 0
}
}
}
}
Optimized IR:
/*******************************************************
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*******************************************************/
object "c_145" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("c_145_deployed")
codecopy(0, dataoffset("c_145_deployed"), _1)
return(0, _1)
}
}
object "c_145_deployed" {
code {
{
let _1 := 64
mstore(_1, 128)
if iszero(lt(calldatasize(), 4))
{
let _2 := 0
switch shr(224, calldataload(_2))
case 0x0178fe3f {
if callvalue() { revert(_2, _2) }
let ret, ret_1 := fun_getData(abi_decode_uint256(calldatasize()))
let memPos := mload(_1)
return(memPos, sub(abi_encode_uint256_uint256(memPos, ret, ret_1), memPos))
}
case 0x0d18e43c {
if callvalue() { revert(_2, _2) }
let ret_2 := fun_getID(abi_decode_uint256(calldatasize()))
let memPos_1 := mload(_1)
return(memPos_1, sub(abi_encode_uint256(memPos_1, ret_2), memPos_1))
}
case 0x23fef0c0 {
if callvalue() { revert(_2, _2) }
let param, param_1 := abi_decode_uint256t_uint256(calldatasize())
fun_setLengths(param, param_1)
return(mload(_1), _2)
}
case 0x2909f638 {
if callvalue() { revert(_2, _2) }
let param_2, param_3, param_4 := abi_decode_uint256t_uint256t_uint256(calldatasize())
fun_setData(param_2, param_3, param_4)
return(mload(_1), _2)
}
case 0x800bd5c8 {
if callvalue() { revert(_2, _2) }
abi_decode(calldatasize())
let ret_3, ret_4 := fun_getLengths()
let memPos_2 := mload(_1)
return(memPos_2, sub(abi_encode_uint256_uint256(memPos_2, ret_3, ret_4), memPos_2))
}
case 0xb55e49c0 {
if callvalue() { revert(_2, _2) }
fun_setIDStatic(abi_decode_uint256(calldatasize()))
return(mload(_1), _2)
}
case 0xcc959c73 {
if callvalue() { revert(_2, _2) }
let param_5, param_6 := abi_decode_uint256t_uint256(calldatasize())
fun_setID(param_5, param_6)
return(mload(_1), _2)
}
}
revert(0, 0)
}
function abi_decode(dataEnd)
{
if slt(add(dataEnd, not(3)), 0) { revert(0, 0) }
}
function abi_decode_uint256(dataEnd) -> value0
{
if slt(add(dataEnd, not(3)), 32) { revert(value0, value0) }
value0 := calldataload(4)
}
function abi_decode_uint256t_uint256(dataEnd) -> value0, value1
{
if slt(add(dataEnd, not(3)), 64) { revert(value1, value1) }
value0 := calldataload(4)
value1 := calldataload(36)
}
function abi_decode_uint256t_uint256t_uint256(dataEnd) -> value0, value1, value2
{
if slt(add(dataEnd, not(3)), 96) { revert(value2, value2) }
value0 := calldataload(4)
value1 := calldataload(36)
value2 := calldataload(68)
}
function abi_encode_uint256(headStart, value0) -> tail
{
tail := add(headStart, 32)
mstore(headStart, value0)
}
function abi_encode_uint256_uint256(headStart, value0, value1) -> tail
{
tail := add(headStart, 64)
mstore(headStart, value0)
mstore(add(headStart, 32), value1)
}
function fun_getData(var_index) -> var_x, var_y
{
let _1, _2 := storage_array_index_access_struct_Data__dyn(var_index)
var_x := sload(_1)
let _3, _4 := storage_array_index_access_struct_Data__dyn(var_index)
var_y := sload(add(_3, 1))
}
function fun_getID(var_index) -> var
{
if iszero(lt(var_index, sload(0x01))) { panic_error_0x32() }
mstore(var, 0x01)
var := shr(shl(3, var), sload(add(keccak256(var, 0x20), var_index)))
}
function fun_getLengths() -> var_l1, var_l2
{
var_l1 := sload(var_l1)
var_l2 := sload(0x01)
}
function fun_setData(var_index, var_x, var_y)
{
let _1, _2 := storage_array_index_access_struct_Data__dyn(var_index)
sstore(_1, var_x)
let _3, _4 := storage_array_index_access_struct_Data__dyn(var_index)
sstore(add(_3, 1), var_y)
}
function fun_setIDStatic(var_id)
{
if iszero(lt(0x02, sload(0x01))) { panic_error_0x32() }
mstore(0, 0x01)
sstore(add(keccak256(0, 0x20), 0x02), var_id)
}
function fun_setID(var_index, var_id)
{
if iszero(lt(var_index, sload(0x01))) { panic_error_0x32() }
mstore(0, 0x01)
sstore(add(keccak256(0, 0x20), var_index), var_id)
}
function fun_setLengths(var_l1, var_l2)
{
for { } 1 { }
{
let _1 := 0x00
let expr := sload(_1)
if iszero(lt(expr, var_l1)) { break }
if iszero(lt(expr, 18446744073709551616)) { panic_error_0x41() }
sstore(_1, add(expr, 1))
let slot, offset := storage_array_index_access_struct_Data__dyn(expr)
}
for { } 1 { }
{
let _2 := 1
let expr_1 := sload(_2)
if iszero(lt(expr_1, var_l2)) { break }
if iszero(lt(expr_1, 18446744073709551616)) { panic_error_0x41() }
let _3 := add(expr_1, _2)
sstore(_2, _3)
if iszero(lt(expr_1, _3)) { panic_error_0x32() }
mstore(0x00, _2)
}
}
function panic_error_0x32()
{
mstore(0, shl(224, 0x4e487b71))
mstore(4, 0x32)
revert(0, 0x24)
}
function panic_error_0x41()
{
mstore(0, shl(224, 0x4e487b71))
mstore(4, 0x41)
revert(0, 0x24)
}
function storage_array_index_access_struct_Data__dyn(index) -> slot, offset
{
if iszero(lt(index, sload(slot))) { panic_error_0x32() }
mstore(slot, slot)
let data := keccak256(slot, 0x20)
slot := add(data, shl(1, index))
offset := offset
}
}
}
}
--- /tmp/old.yul 2021-04-13 11:20:26.371508531 +0200
+++ /tmp/new.yul 2021-04-13 11:19:43.075243419 +0200
@@ -76,18 +76,18 @@
}
function abi_decode_uint256(dataEnd) -> value0
{
- if slt(add(dataEnd, not(3)), 32) { revert(value0, value0) }
+ if slt(add(dataEnd, not(3)), 32) { revert(0, 0) }
value0 := calldataload(4)
}
function abi_decode_uint256t_uint256(dataEnd) -> value0, value1
{
- if slt(add(dataEnd, not(3)), 64) { revert(value1, value1) }
+ if slt(add(dataEnd, not(3)), 64) { revert(0, 0) }
value0 := calldataload(4)
value1 := calldataload(36)
}
function abi_decode_uint256t_uint256t_uint256(dataEnd) -> value0, value1, value2
{
- if slt(add(dataEnd, not(3)), 96) { revert(value2, value2) }
+ if slt(add(dataEnd, not(3)), 96) { revert(0, 0) }
value0 := calldataload(4)
value1 := calldataload(36)
value2 := calldataload(68)
@@ -112,13 +112,12 @@
}
function fun_getID(var_index) -> var
{
- if iszero(lt(var_index, sload(0x01))) { panic_error_0x32() }
- mstore(var, 0x01)
- var := shr(shl(3, var), sload(add(keccak256(var, 0x20), var_index)))
+ let _1, _2 := storage_array_index_access_uint256_dyn(var_index)
+ var := shr(shl(3, _2), sload(_1))
}
function fun_getLengths() -> var_l1, var_l2
{
- var_l1 := sload(var_l1)
+ var_l1 := sload(0x00)
var_l2 := sload(0x01)
}
function fun_setData(var_index, var_x, var_y)
@@ -136,9 +135,11 @@
}
function fun_setID(var_index, var_id)
{
- if iszero(lt(var_index, sload(0x01))) { panic_error_0x32() }
- mstore(0, 0x01)
- sstore(add(keccak256(0, 0x20), var_index), var_id)
+ let _1, _2 := storage_array_index_access_uint256_dyn(var_index)
+ let _3 := sload(_1)
+ let shiftBits := shl(3, _2)
+ let mask := shl(shiftBits, not(0))
+ sstore(_1, or(and(_3, not(mask)), and(shl(shiftBits, var_id), mask)))
}
function fun_setLengths(var_l1, var_l2)
{
@@ -157,10 +158,8 @@
let expr_1 := sload(_2)
if iszero(lt(expr_1, var_l2)) { break }
if iszero(lt(expr_1, 18446744073709551616)) { panic_error_0x41() }
- let _3 := add(expr_1, _2)
- sstore(_2, _3)
- if iszero(lt(expr_1, _3)) { panic_error_0x32() }
- mstore(0x00, _2)
+ sstore(_2, add(expr_1, _2))
+ let slot_1, offset_1 := storage_array_index_access_uint256_dyn(expr_1)
}
}
function panic_error_0x32()
@@ -177,11 +176,18 @@
}
function storage_array_index_access_struct_Data__dyn(index) -> slot, offset
{
- if iszero(lt(index, sload(slot))) { panic_error_0x32() }
- mstore(slot, slot)
- let data := keccak256(slot, 0x20)
+ if iszero(lt(index, sload(0x00))) { panic_error_0x32() }
+ mstore(0x00, 0x00)
+ let data := keccak256(0x00, 0x20)
slot := add(data, shl(1, index))
- offset := offset
+ offset := 0x00
+ }
+ function storage_array_index_access_uint256_dyn(index) -> slot, offset
+ {
+ if iszero(lt(index, sload(0x01))) { panic_error_0x32() }
+ mstore(0, 0x01)
+ slot := add(keccak256(0, 0x20), index)
+ offset := 0
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment