Skip to content

Instantly share code, notes, and snippets.

@chriseth
Created May 29, 2019 21:23
Show Gist options
  • Save chriseth/c95c20393e0dd1063d4366983b4bc4c9 to your computer and use it in GitHub Desktop.
Save chriseth/c95c20393e0dd1063d4366983b4bc4c9 to your computer and use it in GitHub Desktop.
Solidity to EWasm code generation
Solidity code:
contract c {
function f(uint x) internal returns (uint) {
while (x > 0)
return 2 * f(x - 1);
}
}
Yul IR:
{
{
mstore(64, 128)
let _1 := datasize("c_21_deployed")
codecopy(0, dataoffset("c_21_deployed"), _1)
return(0, _1)
}
function fun_f_20(vloc_x) -> vloc
{
let return_flag := 1
for { } return_flag { }
{
for { } return_flag { }
{
if iszero(vloc_x) { break }
if lt(vloc_x, 1) { revert(0x0, 0x0) }
let _1 := fun_f_20(add(vloc_x, not(0)))
if and(1, lt(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, _1)) { revert(0, 0) }
vloc := mul(0x2, _1)
return_flag := 0
break
}
if iszero(return_flag) { break }
break
}
}
}
EWasm dialect of Yul:
{
{ }
function main()
{
let _1, _2, _3, _4 := datasize("c_21_deployed")
let _5, _6, _7, _8 := dataoffset("c_21_deployed")
datacopy(0, 0, 0, 0, _5, _6, _7, _8, _1, _2, _3, _4)
}
function fun_f_20(vloc_x, vloc_x_1, vloc_x_2, vloc_x_3) -> vloc, vloc_1, vloc_2, vloc_3
{
let return_flag := 0
let return_flag_1 := return_flag
let return_flag_2 := return_flag
let return_flag_3 := return_flag
let return_flag_4 := 1
for { }
or_bool(return_flag, return_flag_2, return_flag_3, return_flag_4)
{ }
{
for { }
or_bool(return_flag, return_flag_2, return_flag_3, return_flag_4)
{ }
{
let r1 := 0
if i64.ne(r1, i64.or(i64.or(r1, r1), i64.or(r1, i64.eqz(i64.or(i64.or(vloc_x, vloc_x_1), i64.or(vloc_x_2, vloc_x_3)))))) { break }
drop(i64.ne(r1, i64.or(i64.or(r1, r1), i64.or(r1, r1))))
let mask := 0xffffffffffffffff
let r1_1 := i64.xor(return_flag_1, mask)
let r2 := i64.xor(return_flag_1, mask)
let r3 := i64.xor(return_flag_1, mask)
let _1, _2, _3, _4 := add(vloc_x, vloc_x_1, vloc_x_2, vloc_x_3, r1_1, r2, r3, i64.xor(return_flag_1, mask))
let _5, _6, _7, _8 := fun_f_20(_1, _2, _3, _4)
let _9, _10, _11, _12 := and(return_flag_1, return_flag_1, return_flag_1, 1, r1, r1, r1, r1)
drop(or_bool(_9, _10, _11, _12))
vloc := r1
vloc_1 := r1
vloc_2 := r1
vloc_3 := r1
return_flag := return_flag_1
return_flag_2 := return_flag_1
return_flag_3 := return_flag_1
return_flag_4 := return_flag_1
break
}
let _13, _14, _15, _16 := iszero(return_flag, return_flag_2, return_flag_3, return_flag_4)
if or_bool(_13, _14, _15, _16) { break }
break
}
}
function or_bool(a, b, c, d) -> r
{
r := i64.ne(0, i64.or(i64.or(a, b), i64.or(c, d)))
}
function add(x1, x2, x3, x4, y1, y2, y3, y4) -> r1, r2, r3, r4
{
let t := i64.add(x4, y4)
let r := i64.add(t, 0)
let r_c := i64.or(i64.lt_u(t, x4), i64.lt_u(r, t))
r4 := r
let t_1 := i64.add(x3, y3)
let r_1 := i64.add(t_1, r_c)
let r_c_1 := i64.or(i64.lt_u(t_1, x3), i64.lt_u(r_1, t_1))
r3 := r_1
let t_2 := i64.add(x2, y2)
let r_2 := i64.add(t_2, r_c_1)
let r_c_2 := i64.or(i64.lt_u(t_2, x2), i64.lt_u(r_2, t_2))
r2 := r_2
let t_3 := i64.add(x1, y1)
let r_3 := i64.add(t_3, r_c_2)
drop(i64.or(i64.lt_u(t_3, x1), i64.lt_u(r_3, t_3)))
r1 := r_3
}
function and(x1, x2, x3, x4, y1, y2, y3, y4) -> r1, r2, r3, r4
{
r1 := i64.and(x1, y1)
r2 := i64.and(x2, y2)
r3 := i64.and(x3, y3)
r4 := i64.and(x4, y4)
}
function iszero(x1, x2, x3, x4) -> r1, r2, r3, r4
{
r4 := i64.eqz(i64.or(i64.or(x1, x2), i64.or(x3, x4)))
}
}
Wasm text representation:
(module
(global $global_ (mut i64) (i64.const 0))
(global $global__1 (mut i64) (i64.const 0))
(global $global__2 (mut i64) (i64.const 0))
(func $main
(local $_1 i64)
(local $_2 i64)
(local $_3 i64)
(local $_4 i64)
(local $_5 i64)
(local $_6 i64)
(local $_7 i64)
(local $_8 i64)
(block
(set_local $_1 (datasize (i64.const 18446744073709551615)))
(set_local $_2 (get_global $global_))
(set_local $_3 (get_global $global__1))
(set_local $_4 (get_global $global__2))
)
(block
(set_local $_5 (dataoffset (i64.const 18446744073709551615)))
(set_local $_6 (get_global $global_))
(set_local $_7 (get_global $global__1))
(set_local $_8 (get_global $global__2))
)
(datacopy (i64.const 0) (i64.const 0) (i64.const 0) (i64.const 0) (get_local $_5) (get_local $_6) (get_local $_7) (get_local $_8) (get_local $_1) (get_local $_2) (get_local $_3) (get_local $_4))
)
(func $fun_f_20
(param $vloc_x i64)
(param $vloc_x_1 i64)
(param $vloc_x_2 i64)
(param $vloc_x_3 i64)
(result i64)
(local $vloc i64)
(local $vloc_1 i64)
(local $vloc_2 i64)
(local $vloc_3 i64)
(local $return_flag i64)
(local $return_flag_1 i64)
(local $return_flag_2 i64)
(local $return_flag_3 i64)
(local $return_flag_4 i64)
(local $r1 i64)
(local $mask i64)
(local $r1_1 i64)
(local $r2 i64)
(local $r3 i64)
(local $_1 i64)
(local $_2 i64)
(local $_3 i64)
(local $_4 i64)
(local $_5 i64)
(local $_6 i64)
(local $_7 i64)
(local $_8 i64)
(local $_9 i64)
(local $_10 i64)
(local $_11 i64)
(local $_12 i64)
(local $_13 i64)
(local $_14 i64)
(local $_15 i64)
(local $_16 i64)
(set_local $return_flag (i64.const 0))
(set_local $return_flag_1 (get_local $return_flag))
(set_local $return_flag_2 (get_local $return_flag))
(set_local $return_flag_3 (get_local $return_flag))
(set_local $return_flag_4 (i64.const 1))
(block $label_
(loop
(br_if $label_ (i64.eqz (call $or_bool (get_local $return_flag) (get_local $return_flag_2) (get_local $return_flag_3) (get_local $return_flag_4)))) (block $label__3
(block $label__4
(loop
(br_if $label__4 (i64.eqz (call $or_bool (get_local $return_flag) (get_local $return_flag_2) (get_local $return_flag_3) (get_local $return_flag_4)))) (block $label__5
(set_local $r1 (i64.const 0))
(if (i64.ne (get_local $r1) (i64.or (i64.or (get_local $r1) (get_local $r1)) (i64.or (get_local $r1) (i64.eqz (i64.or (i64.or (get_local $vloc_x) (get_local $vloc_x_1)) (i64.or (get_local $vloc_x_2) (get_local $vloc_x_3))))))) (then
(break $label__4)
))
(drop (i64.ne (get_local $r1) (i64.or (i64.or (get_local $r1) (get_local $r1)) (i64.or (get_local $r1) (get_local $r1))))) (set_local $mask (i64.const 18446744073709551615))
(set_local $r1_1 (i64.xor (get_local $return_flag_1) (get_local $mask)))
(set_local $r2 (i64.xor (get_local $return_flag_1) (get_local $mask)))
(set_local $r3 (i64.xor (get_local $return_flag_1) (get_local $mask)))
(block
(set_local $_1 (call $add (get_local $vloc_x) (get_local $vloc_x_1) (get_local $vloc_x_2) (get_local $vloc_x_3) (get_local $r1_1) (get_local $r2) (get_local $r3) (i64.xor (get_local $return_flag_1) (get_local $mask))))
(set_local $_2 (get_global $global_))
(set_local $_3 (get_global $global__1))
(set_local $_4 (get_global $global__2))
)
(block
(set_local $_5 (call $fun_f_20 (get_local $_1) (get_local $_2) (get_local $_3) (get_local $_4)))
(set_local $_6 (get_global $global_))
(set_local $_7 (get_global $global__1))
(set_local $_8 (get_global $global__2))
)
(block
(set_local $_9 (call $and (get_local $return_flag_1) (get_local $return_flag_1) (get_local $return_flag_1) (i64.const 1) (get_local $r1) (get_local $r1) (get_local $r1) (get_local $r1)))
(set_local $_10 (get_global $global_))
(set_local $_11 (get_global $global__1))
(set_local $_12 (get_global $global__2))
)
(drop (call $or_bool (get_local $_9) (get_local $_10) (get_local $_11) (get_local $_12))) (set_local $vloc (get_local $r1))
(set_local $vloc_1 (get_local $r1))
(set_local $vloc_2 (get_local $r1))
(set_local $vloc_3 (get_local $r1))
(set_local $return_flag (get_local $return_flag_1))
(set_local $return_flag_2 (get_local $return_flag_1))
(set_local $return_flag_3 (get_local $return_flag_1))
(set_local $return_flag_4 (get_local $return_flag_1))
(break $label__4)
)
)
)
(block
(set_local $_13 (call $iszero (get_local $return_flag) (get_local $return_flag_2) (get_local $return_flag_3) (get_local $return_flag_4)))
(set_local $_14 (get_global $global_))
(set_local $_15 (get_global $global__1))
(set_local $_16 (get_global $global__2))
)
(if (call $or_bool (get_local $_13) (get_local $_14) (get_local $_15) (get_local $_16)) (then
(break $label__4)
))
(break $label__4)
)
)
)
(set_global $global_ (get_local $vloc_1))
(set_global $global__1 (get_local $vloc_2))
(set_global $global__2 (get_local $vloc_3))
(get_local $vloc)
)
(func $or_bool
(param $a i64)
(param $b i64)
(param $c i64)
(param $d i64)
(result i64)
(local $r i64)
(set_local $r (i64.ne (i64.const 0) (i64.or (i64.or (get_local $a) (get_local $b)) (i64.or (get_local $c) (get_local $d)))))
(get_local $r)
)
(func $add
(param $x1 i64)
(param $x2 i64)
(param $x3 i64)
(param $x4 i64)
(param $y1 i64)
(param $y2 i64)
(param $y3 i64)
(param $y4 i64)
(result i64)
(local $r1 i64)
(local $r2 i64)
(local $r3 i64)
(local $r4 i64)
(local $t i64)
(local $r i64)
(local $r_c i64)
(local $t_1 i64)
(local $r_1 i64)
(local $r_c_1 i64)
(local $t_2 i64)
(local $r_2 i64)
(local $r_c_2 i64)
(local $t_3 i64)
(local $r_3 i64)
(set_local $t (i64.add (get_local $x4) (get_local $y4)))
(set_local $r (i64.add (get_local $t) (i64.const 0)))
(set_local $r_c (i64.or (i64.lt_u (get_local $t) (get_local $x4)) (i64.lt_u (get_local $r) (get_local $t))))
(set_local $r4 (get_local $r))
(set_local $t_1 (i64.add (get_local $x3) (get_local $y3)))
(set_local $r_1 (i64.add (get_local $t_1) (get_local $r_c)))
(set_local $r_c_1 (i64.or (i64.lt_u (get_local $t_1) (get_local $x3)) (i64.lt_u (get_local $r_1) (get_local $t_1))))
(set_local $r3 (get_local $r_1))
(set_local $t_2 (i64.add (get_local $x2) (get_local $y2)))
(set_local $r_2 (i64.add (get_local $t_2) (get_local $r_c_1)))
(set_local $r_c_2 (i64.or (i64.lt_u (get_local $t_2) (get_local $x2)) (i64.lt_u (get_local $r_2) (get_local $t_2))))
(set_local $r2 (get_local $r_2))
(set_local $t_3 (i64.add (get_local $x1) (get_local $y1)))
(set_local $r_3 (i64.add (get_local $t_3) (get_local $r_c_2)))
(drop (i64.or (i64.lt_u (get_local $t_3) (get_local $x1)) (i64.lt_u (get_local $r_3) (get_local $t_3)))) (set_local $r1 (get_local $r_3))
(set_global $global_ (get_local $r2))
(set_global $global__1 (get_local $r3))
(set_global $global__2 (get_local $r4))
(get_local $r1)
)
(func $and
(param $x1 i64)
(param $x2 i64)
(param $x3 i64)
(param $x4 i64)
(param $y1 i64)
(param $y2 i64)
(param $y3 i64)
(param $y4 i64)
(result i64)
(local $r1 i64)
(local $r2 i64)
(local $r3 i64)
(local $r4 i64)
(set_local $r1 (i64.and (get_local $x1) (get_local $y1)))
(set_local $r2 (i64.and (get_local $x2) (get_local $y2)))
(set_local $r3 (i64.and (get_local $x3) (get_local $y3)))
(set_local $r4 (i64.and (get_local $x4) (get_local $y4)))
(set_global $global_ (get_local $r2))
(set_global $global__1 (get_local $r3))
(set_global $global__2 (get_local $r4))
(get_local $r1)
)
(func $iszero
(param $x1 i64)
(param $x2 i64)
(param $x3 i64)
(param $x4 i64)
(result i64)
(local $r1 i64)
(local $r2 i64)
(local $r3 i64)
(local $r4 i64)
(set_local $r4 (i64.eqz (i64.or (i64.or (get_local $x1) (get_local $x2)) (i64.or (get_local $x3) (get_local $x4)))))
(set_global $global_ (get_local $r2))
(set_global $global__1 (get_local $r3))
(set_global $global__2 (get_local $r4))
(get_local $r1)
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment