Created
May 29, 2019 21:23
-
-
Save chriseth/c95c20393e0dd1063d4366983b4bc4c9 to your computer and use it in GitHub Desktop.
Solidity to EWasm code generation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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