From c7f75bd9dcf328027096d829603a242306709cad Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 18 Dec 2019 00:03:52 +0100 Subject: [PATCH 01/36] Set version to 0.6.1. --- CMakeLists.txt | 2 +- Changelog.md | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 30073fd08ef6..fb8c1a49c811 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.6.0") +set(PROJECT_VERSION "0.6.1") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) include(TestBigEndian) diff --git a/Changelog.md b/Changelog.md index e8731b5fa5bf..9b4d81ff7fb5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,15 @@ +### 0.6.1 (unreleased) + +Language Features: + + +Compiler Features: + + +Bugfixes: + + + ### 0.6.0 (2019-12-17) Breaking changes: From 4b026fa63355a19b64e43c0c15d6c6e8a9ed230a Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 18 Dec 2019 01:10:07 +0100 Subject: [PATCH 02/36] Update gas costs. --- test/libsolidity/GasCosts.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/libsolidity/GasCosts.cpp b/test/libsolidity/GasCosts.cpp index 6b6adf2e3cc9..de90c9076bf8 100644 --- a/test/libsolidity/GasCosts.cpp +++ b/test/libsolidity/GasCosts.cpp @@ -99,7 +99,7 @@ BOOST_AUTO_TEST_CASE(string_storage) auto evmVersion = dev::test::Options::get().evmVersion(); if (evmVersion <= EVMVersion::byzantium()) - CHECK_DEPLOY_GAS(134145, 130831, evmVersion); + CHECK_DEPLOY_GAS(134209, 130895, evmVersion); // This is only correct on >=Constantinople. else if (Options::get().useABIEncoderV2) { @@ -107,22 +107,22 @@ BOOST_AUTO_TEST_CASE(string_storage) { // Costs with 0 are cases which cannot be triggered in tests. if (evmVersion < EVMVersion::istanbul()) - CHECK_DEPLOY_GAS(0, 123969, evmVersion); + CHECK_DEPLOY_GAS(0, 124033, evmVersion); else - CHECK_DEPLOY_GAS(0, 110969, evmVersion); + CHECK_DEPLOY_GAS(0, 110981, evmVersion); } else { if (evmVersion < EVMVersion::istanbul()) - CHECK_DEPLOY_GAS(147771, 131687, evmVersion); + CHECK_DEPLOY_GAS(147835, 131687, evmVersion); else - CHECK_DEPLOY_GAS(131859, 117231, evmVersion); + CHECK_DEPLOY_GAS(131871, 117231, evmVersion); } } else if (evmVersion < EVMVersion::istanbul()) - CHECK_DEPLOY_GAS(126929, 119659, evmVersion); + CHECK_DEPLOY_GAS(126993, 119723, evmVersion); else - CHECK_DEPLOY_GAS(114345, 107335, evmVersion); + CHECK_DEPLOY_GAS(114357, 107347, evmVersion); if (evmVersion >= EVMVersion::byzantium()) { From 7d8c4c24eef4b9b7944f9c163912c773464710a6 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Tue, 17 Dec 2019 21:37:05 +0100 Subject: [PATCH 03/36] Add arithmetic test cases for most of EVM->Ewasm translator --- libyul/backends/wasm/EVMToEWasmTranslator.cpp | 8 +++-- test/libyul/EWasmTranslationTest.cpp | 2 +- .../ewasmTranslationTests/arithmetic_add.yul | 35 ++++++++++++++++++ .../arithmetic_addmod.yul | 20 +++++++++++ .../ewasmTranslationTests/arithmetic_div.yul | 23 ++++++++++++ .../ewasmTranslationTests/arithmetic_exp.yul | 25 +++++++++++++ .../ewasmTranslationTests/arithmetic_mod.yul | 25 +++++++++++++ .../ewasmTranslationTests/arithmetic_mul.yul | 36 +++++++++++++++++++ .../arithmetic_mulmod.yul | 22 ++++++++++++ .../ewasmTranslationTests/arithmetic_sdiv.yul | 25 +++++++++++++ .../ewasmTranslationTests/arithmetic_smod.yul | 29 +++++++++++++++ .../ewasmTranslationTests/arithmetic_sub.yul | 36 +++++++++++++++++++ test/libyul/ewasmTranslationTests/shifts.yul | 5 +++ .../ewasmTranslationTests/signextend.yul | 11 ++++++ 14 files changed, 299 insertions(+), 3 deletions(-) create mode 100644 test/libyul/ewasmTranslationTests/arithmetic_add.yul create mode 100644 test/libyul/ewasmTranslationTests/arithmetic_addmod.yul create mode 100644 test/libyul/ewasmTranslationTests/arithmetic_div.yul create mode 100644 test/libyul/ewasmTranslationTests/arithmetic_exp.yul create mode 100644 test/libyul/ewasmTranslationTests/arithmetic_mod.yul create mode 100644 test/libyul/ewasmTranslationTests/arithmetic_mul.yul create mode 100644 test/libyul/ewasmTranslationTests/arithmetic_mulmod.yul create mode 100644 test/libyul/ewasmTranslationTests/arithmetic_sdiv.yul create mode 100644 test/libyul/ewasmTranslationTests/arithmetic_smod.yul create mode 100644 test/libyul/ewasmTranslationTests/arithmetic_sub.yul create mode 100644 test/libyul/ewasmTranslationTests/signextend.yul diff --git a/libyul/backends/wasm/EVMToEWasmTranslator.cpp b/libyul/backends/wasm/EVMToEWasmTranslator.cpp index 54e80fdcd10a..bd95c27a5a6a 100644 --- a/libyul/backends/wasm/EVMToEWasmTranslator.cpp +++ b/libyul/backends/wasm/EVMToEWasmTranslator.cpp @@ -138,6 +138,10 @@ function div(x1, x2, x3, x4, y1, y2, y3, y4) -> r1, r2, r3, r4 { // TODO implement properly r4 := i64.div_u(x4, y4) } +function sdiv(x1, x2, x3, x4, y1, y2, y3, y4) -> r1, r2, r3, r4 { + // TODO implement properly + unreachable() +} function mod(x1, x2, x3, x4, y1, y2, y3, y4) -> r1, r2, r3, r4 { // TODO implement properly r4 := i64.rem_u(x4, y4) @@ -318,11 +322,11 @@ function sar(x1, x2, x3, x4, y1, y2, y3, y4) -> z1, z2, z3, z4 { // TODO implement unreachable() } -function addmod(x1, x2, x3, x4, y1, y2, y3, y4) -> z1, z2, z3, z4 { +function addmod(x1, x2, x3, x4, y1, y2, y3, y4, m1, m2, m3, m4) -> z1, z2, z3, z4 { // TODO implement unreachable() } -function mulmod(x1, x2, x3, x4, y1, y2, y3, y4) -> z1, z2, z3, z4 { +function mulmod(x1, x2, x3, x4, y1, y2, y3, y4, m1, m2, m3, m4) -> z1, z2, z3, z4 { // TODO implement unreachable() } diff --git a/test/libyul/EWasmTranslationTest.cpp b/test/libyul/EWasmTranslationTest.cpp index dc174ff7be74..b38bb8b5c77e 100644 --- a/test/libyul/EWasmTranslationTest.cpp +++ b/test/libyul/EWasmTranslationTest.cpp @@ -131,7 +131,7 @@ string EWasmTranslationTest::interpret() { InterpreterState state; state.maxTraceSize = 10000; - state.maxSteps = 10000; + state.maxSteps = 100000; WasmDialect dialect; Interpreter interpreter(state, dialect); try diff --git a/test/libyul/ewasmTranslationTests/arithmetic_add.yul b/test/libyul/ewasmTranslationTests/arithmetic_add.yul new file mode 100644 index 000000000000..b2203070fcf4 --- /dev/null +++ b/test/libyul/ewasmTranslationTests/arithmetic_add.yul @@ -0,0 +1,35 @@ +{ + sstore(0, add(0, 1)) + sstore(1, add(1, not(0))) + sstore(2, add(0, 0)) + sstore(3, add(1, 2)) + sstore(4, add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1)) + sstore(5, add( + 0x8000000000000000000000000000000000000000000000000000000000000000, 1 + )) + sstore(6, add(not(0), 1)) + sstore(7, add(0xffffffffffffffffffffffffffffffff, 1)) + sstore(8, add(0xffffffffffffffff, 1)) + sstore(9, add(0xffffffffffffffffffffffffffffffff0000000000000000, 1)) + sstore(10, add(0xffffffffffffffffffffffffffffffffffffffffffffffff, 3)) + sstore(11, add(0xffffffffffffffffffffffffffffffff, 3)) + sstore(12, add(0xffffffffffffffff, 3)) + sstore(13, add(0xffffffffffffffffffffffffffffffff0000000000000000, 3)) +} +// ---- +// Trace: +// Memory dump: +// 0: 000000000000000000000000000000000000000000000000000000000000000d +// 20: 0000000000000000ffffffffffffffffffffffffffffffff0000000000000003 +// Storage dump: +// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000001 +// 0000000000000000000000000000000000000000000000000000000000000003: 0000000000000000000000000000000000000000000000000000000000000003 +// 0000000000000000000000000000000000000000000000000000000000000004: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// 0000000000000000000000000000000000000000000000000000000000000005: 8000000000000000000000000000000000000000000000000000000000000001 +// 0000000000000000000000000000000000000000000000000000000000000007: 0000000000000000000000000000000100000000000000000000000000000000 +// 0000000000000000000000000000000000000000000000000000000000000008: 0000000000000000000000000000000000000000000000010000000000000000 +// 0000000000000000000000000000000000000000000000000000000000000009: 0000000000000000ffffffffffffffffffffffffffffffff0000000000000001 +// 000000000000000000000000000000000000000000000000000000000000000a: 0000000000000001000000000000000000000000000000000000000000000002 +// 000000000000000000000000000000000000000000000000000000000000000b: 0000000000000000000000000000000100000000000000000000000000000002 +// 000000000000000000000000000000000000000000000000000000000000000c: 0000000000000000000000000000000000000000000000010000000000000002 +// 000000000000000000000000000000000000000000000000000000000000000d: 0000000000000000ffffffffffffffffffffffffffffffff0000000000000003 diff --git a/test/libyul/ewasmTranslationTests/arithmetic_addmod.yul b/test/libyul/ewasmTranslationTests/arithmetic_addmod.yul new file mode 100644 index 000000000000..c1d43a731048 --- /dev/null +++ b/test/libyul/ewasmTranslationTests/arithmetic_addmod.yul @@ -0,0 +1,20 @@ +{ + sstore(0, addmod(0, 1, 1)) + sstore(1, addmod(0, 1, 2)) + sstore(2, addmod(3, 1, 2)) + sstore(3, addmod(1, not(0), 5)) + sstore(4, addmod(0, 0, 0)) + sstore(5, addmod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1, 1)) + sstore(6, addmod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1, 0)) + sstore(7, addmod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 1, 5)) + sstore(8, addmod( + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 5 + )) +} +// ---- +// Trace: +// INVALID() +// Memory dump: +// Storage dump: diff --git a/test/libyul/ewasmTranslationTests/arithmetic_div.yul b/test/libyul/ewasmTranslationTests/arithmetic_div.yul new file mode 100644 index 000000000000..3d97f464cc38 --- /dev/null +++ b/test/libyul/ewasmTranslationTests/arithmetic_div.yul @@ -0,0 +1,23 @@ +{ + sstore(0, div(0, 1)) + sstore(1, div(1, not(0))) + sstore(2, div(0, 0)) + sstore(3, div(1, 2)) + sstore(4, div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1)) + sstore(5, div( + 0x8000000000000000000000000000000000000000000000000000000000000000, 1 + )) + sstore(6, div(not(0), 1)) + sstore(7, div(0xffffffffffffffffffffffffffffffff, 1)) + sstore(8, div(0xffffffffffffffff, 1)) + sstore(9, div(0xffffffffffffffffffffffffffffffff0000000000000000, 1)) + sstore(10, div(0xffffffffffffffffffffffffffffffffffffffffffffffff, 3)) + sstore(11, div(0xffffffffffffffffffffffffffffffff, 3)) + sstore(12, div(0xffffffffffffffff, 3)) + sstore(13, div(0xffffffffffffffffffffffffffffffff0000000000000000, 3)) +} +// ---- +// Trace: +// Memory dump: +// 0: 0000000000000000000000000000000000000000000000000000000000000001 +// Storage dump: diff --git a/test/libyul/ewasmTranslationTests/arithmetic_exp.yul b/test/libyul/ewasmTranslationTests/arithmetic_exp.yul new file mode 100644 index 000000000000..328ac9c3be41 --- /dev/null +++ b/test/libyul/ewasmTranslationTests/arithmetic_exp.yul @@ -0,0 +1,25 @@ +{ + sstore(0, exp(0, 1)) + sstore(1, exp(1, not(0))) + sstore(2, exp(0, 0)) + sstore(3, exp(1, 2)) + sstore(4, exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1)) + sstore(5, exp( + 0x8000000000000000000000000000000000000000000000000000000000000000, 1 + )) + sstore(6, exp(not(0), 1)) + sstore(7, exp(0xffffffffffffffffffffffffffffffff, 2)) + sstore(8, exp(0xffffffffffffffff, 2)) + sstore(9, exp(0xffffffffffffffffffffffffffffffff0000000000000000, 2)) + sstore(10, exp(0xffffffffffffffffffffffffffffffffffffffffffffffff, 3)) + sstore(11, exp(0xffffffffffffffffffffffffffffffff, 3)) + sstore(12, exp(0xffffffffffffffff, 3)) + sstore(13, exp(0xffffffffffffffffffffffffffffffff0000000000000000, 3)) + sstore(14, exp(2, 256)) + sstore(15, exp(2, 255)) +} +// ---- +// Trace: +// INVALID() +// Memory dump: +// Storage dump: diff --git a/test/libyul/ewasmTranslationTests/arithmetic_mod.yul b/test/libyul/ewasmTranslationTests/arithmetic_mod.yul new file mode 100644 index 000000000000..4aa5c6997b45 --- /dev/null +++ b/test/libyul/ewasmTranslationTests/arithmetic_mod.yul @@ -0,0 +1,25 @@ +{ + sstore(0, mod(0, 1)) + sstore(1, mod(1, not(0))) + sstore(2, mod(0, 0)) + sstore(3, mod(1, 2)) + sstore(4, mod(not(0), 1)) + sstore(5, mod( + 0x8000000000000000000000000000000000000000000000000000000000000000, 1 + )) + sstore(6, mod(not(0), 1)) + sstore(7, mod(0xffffffffffffffffffffffffffffffff, 1)) + sstore(8, mod(0xffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffe)) + sstore(9, mod(0xffffffffffffffffffffffffffffffffffffffffffffffff, 5)) + sstore(10, mod(0xffffffffffffffffffffffffffffffffffffffffffffffff, 4)) + sstore(11, mod(0xffffffffffffffffffffffffffffffff, 3)) + sstore(12, mod(0xffffffffffffffff, 3)) + sstore(13, mod(0xffffffffffffffffffffffffffffffff0000000000000000, 0xffffffffffffffff43342553000)) +} +// ---- +// Trace: +// Memory dump: +// 0: 0000000000000000000000000000000000000000000000000000000000000001 +// 20: 0000000000000000000000000000000000000000000000000000000000000001 +// Storage dump: +// 0000000000000000000000000000000000000000000000000000000000000001: 0000000000000000000000000000000000000000000000000000000000000001 diff --git a/test/libyul/ewasmTranslationTests/arithmetic_mul.yul b/test/libyul/ewasmTranslationTests/arithmetic_mul.yul new file mode 100644 index 000000000000..73e1bf3d86ba --- /dev/null +++ b/test/libyul/ewasmTranslationTests/arithmetic_mul.yul @@ -0,0 +1,36 @@ +{ + sstore(0, mul(0, 1)) + sstore(1, mul(1, not(0))) + sstore(2, mul(0, 0)) + sstore(3, mul(1, 2)) + sstore(4, mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1)) + sstore(5, mul( + 0x8000000000000000000000000000000000000000000000000000000000000000, 1 + )) + sstore(6, mul(not(0), 1)) + sstore(7, mul(0xffffffffffffffffffffffffffffffff, 1)) + sstore(8, mul(0xffffffffffffffff, 1)) + sstore(9, mul(0xffffffffffffffffffffffffffffffff0000000000000000, 1)) + sstore(10, mul(0xffffffffffffffffffffffffffffffffffffffffffffffff, 3)) + sstore(11, mul(0xffffffffffffffffffffffffffffffff, 3)) + sstore(12, mul(0xffffffffffffffff, 3)) + sstore(13, mul(0xffffffffffffffffffffffffffffffff0000000000000000, 3)) +} +// ---- +// Trace: +// Memory dump: +// 0: 000000000000000000000000000000000000000000000000000000000000000d +// 20: 0000000000000002fffffffffffffffffffffffffffffffd0000000000000000 +// Storage dump: +// 0000000000000000000000000000000000000000000000000000000000000001: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// 0000000000000000000000000000000000000000000000000000000000000003: 0000000000000000000000000000000000000000000000000000000000000002 +// 0000000000000000000000000000000000000000000000000000000000000004: fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +// 0000000000000000000000000000000000000000000000000000000000000005: 8000000000000000000000000000000000000000000000000000000000000000 +// 0000000000000000000000000000000000000000000000000000000000000006: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// 0000000000000000000000000000000000000000000000000000000000000007: 00000000000000000000000000000000ffffffffffffffffffffffffffffffff +// 0000000000000000000000000000000000000000000000000000000000000008: 000000000000000000000000000000000000000000000000ffffffffffffffff +// 0000000000000000000000000000000000000000000000000000000000000009: 0000000000000000ffffffffffffffffffffffffffffffff0000000000000000 +// 000000000000000000000000000000000000000000000000000000000000000a: 0000000000000002fffffffffffffffffffffffffffffffffffffffffffffffd +// 000000000000000000000000000000000000000000000000000000000000000b: 00000000000000000000000000000002fffffffffffffffffffffffffffffffd +// 000000000000000000000000000000000000000000000000000000000000000c: 000000000000000000000000000000000000000000000002fffffffffffffffd +// 000000000000000000000000000000000000000000000000000000000000000d: 0000000000000002fffffffffffffffffffffffffffffffd0000000000000000 diff --git a/test/libyul/ewasmTranslationTests/arithmetic_mulmod.yul b/test/libyul/ewasmTranslationTests/arithmetic_mulmod.yul new file mode 100644 index 000000000000..094723ae02c7 --- /dev/null +++ b/test/libyul/ewasmTranslationTests/arithmetic_mulmod.yul @@ -0,0 +1,22 @@ +{ + sstore(0, mulmod(0, 1, 2)) + sstore(1, mulmod(1, not(0), 5)) + sstore(2, mulmod(0, 0, 5)) + sstore(3, mulmod(1, 3, 2)) + sstore(4, mulmod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 1, + 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) + sstore(5, mulmod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1, 1)) + sstore(6, mulmod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 1, 0)) + sstore(7, mulmod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, 1, 5)) + sstore(8, mulmod( + not(0), + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 25 + )) +} +// ---- +// Trace: +// INVALID() +// Memory dump: +// Storage dump: diff --git a/test/libyul/ewasmTranslationTests/arithmetic_sdiv.yul b/test/libyul/ewasmTranslationTests/arithmetic_sdiv.yul new file mode 100644 index 000000000000..fd4364185328 --- /dev/null +++ b/test/libyul/ewasmTranslationTests/arithmetic_sdiv.yul @@ -0,0 +1,25 @@ +{ + sstore(0, sdiv(0, 1)) + sstore(1, sdiv(0, not(0))) + sstore(2, sdiv(0, 0)) + sstore(3, sdiv(1, 2)) + sstore(4, sdiv(not(0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe)) + sstore(5, sdiv(0x8000000000000000000000000000000000000000000000000000000000000000, not(0))) + sstore(6, sdiv(not(0), 0x8000000000000000000000000000000000000000000000000000000000000000)) + sstore(7, sdiv(0x7000000000000000000000000000000000000000000000000000000000000000, 1)) + sstore(8, sdiv(1, 0x7000000000000000000000000000000000000000000000000000000000000000)) + sstore(9, sdiv(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, not(0))) + sstore(10, sdiv(not(0), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) + sstore(11, sdiv(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 1)) + sstore(12, sdiv(not(0), not(0))) + sstore(13, sdiv( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe + )) + sstore(14, sdiv(0x8000000000000000000000000000000000000000000000000000000000000001, not(0))) +} +// ---- +// Trace: +// INVALID() +// Memory dump: +// Storage dump: diff --git a/test/libyul/ewasmTranslationTests/arithmetic_smod.yul b/test/libyul/ewasmTranslationTests/arithmetic_smod.yul new file mode 100644 index 000000000000..97983a463c42 --- /dev/null +++ b/test/libyul/ewasmTranslationTests/arithmetic_smod.yul @@ -0,0 +1,29 @@ +{ + sstore(0, smod(0, 1)) + sstore(1, smod(1, not(0))) + sstore(2, smod(0, 0)) + sstore(3, smod(1, 2)) + sstore(4, smod(not(0), 1)) + sstore(5, smod( + 0x8000000000000000000000000000000000000000000000000000000000000000, 1 + )) + sstore(6, smod(not(0), 1)) + sstore(7, smod(0xffffffffffffffffffffffffffffffff, 1)) + sstore(8, smod(0xffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffe)) + sstore(9, smod(0xffffffffffffffffffffffffffffffffffffffffffffffff, 5)) + sstore(10, smod(0xffffffffffffffffffffffffffffffffffffffffffffffff, 4)) + sstore(11, smod(0xffffffffffffffffffffffffffffffff, 3)) + sstore(12, smod(0xffffffffffffffff, 3)) + sstore(13, smod(0xffffffffffffffffffffffffffffffff0000000000000000, 0xffffffffffffffff43342553000)) + sstore(14, smod( + 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd, + 0xffffffffffffffff43342553000 + )) +} +// ---- +// Trace: +// Memory dump: +// 0: 0000000000000000000000000000000000000000000000000000000000000001 +// 20: 0000000000000000000000000000000000000000000000000000000000000001 +// Storage dump: +// 0000000000000000000000000000000000000000000000000000000000000001: 0000000000000000000000000000000000000000000000000000000000000001 diff --git a/test/libyul/ewasmTranslationTests/arithmetic_sub.yul b/test/libyul/ewasmTranslationTests/arithmetic_sub.yul new file mode 100644 index 000000000000..fefb5d682439 --- /dev/null +++ b/test/libyul/ewasmTranslationTests/arithmetic_sub.yul @@ -0,0 +1,36 @@ +{ + sstore(0, sub(0, 1)) + sstore(1, sub(1, not(0))) + sstore(2, sub(0, 0)) + sstore(3, sub(1, 2)) + sstore(4, sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 1)) + sstore(5, sub( + 0x8000000000000000000000000000000000000000000000000000000000000000, 1 + )) + sstore(6, sub(not(0), 1)) + sstore(7, sub(not(0), not(0))) + sstore(8, sub(0x1000000000000000000000000000000000000000000000000, 1)) + sstore(9, sub(0x100000000000000000000000000000000, 1)) + sstore(10, sub(0x10000000000000000, 1)) + sstore(11, sub(0x1000000000000000000000000000000000000000000000000, 3)) + sstore(12, sub(0x100000000000000000000000000000000, 3)) + sstore(13, sub(0x10000000000000000, 3)) +} +// ---- +// Trace: +// Memory dump: +// 0: 000000000000000000000000000000000000000000000000000000000000000d +// 20: 000000000000000000000000000000000000000000000000fffffffffffffffd +// Storage dump: +// 0000000000000000000000000000000000000000000000000000000000000000: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// 0000000000000000000000000000000000000000000000000000000000000001: 0000000000000000000000000000000000000000000000000000000000000002 +// 0000000000000000000000000000000000000000000000000000000000000003: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// 0000000000000000000000000000000000000000000000000000000000000004: fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +// 0000000000000000000000000000000000000000000000000000000000000005: 7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +// 0000000000000000000000000000000000000000000000000000000000000006: fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe +// 0000000000000000000000000000000000000000000000000000000000000008: 0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff +// 0000000000000000000000000000000000000000000000000000000000000009: 00000000000000000000000000000000ffffffffffffffffffffffffffffffff +// 000000000000000000000000000000000000000000000000000000000000000a: 000000000000000000000000000000000000000000000000ffffffffffffffff +// 000000000000000000000000000000000000000000000000000000000000000b: 0000000000000000fffffffffffffffffffffffffffffffffffffffffffffffd +// 000000000000000000000000000000000000000000000000000000000000000c: 00000000000000000000000000000000fffffffffffffffffffffffffffffffd +// 000000000000000000000000000000000000000000000000000000000000000d: 000000000000000000000000000000000000000000000000fffffffffffffffd diff --git a/test/libyul/ewasmTranslationTests/shifts.yul b/test/libyul/ewasmTranslationTests/shifts.yul index f49092a30007..c3e9b6036a44 100644 --- a/test/libyul/ewasmTranslationTests/shifts.yul +++ b/test/libyul/ewasmTranslationTests/shifts.yul @@ -4,11 +4,16 @@ let z := shr(136, y) sstore(0, y) sstore(1, z) + sstore(2, sar(136, 0x801112131415161718191a1b1c1d1e1f20000000000000000000000000000000)) + sstore(3, sar(256, 0x801112131415161718191a1b1c1d1e1f20000000000000000000000000000000)) + sstore(4, sar(136, 0x701112131415161718191a1b1c1d1e1f20000000000000000000000000000000)) + sstore(5, sar(256, 0x701112131415161718191a1b1c1d1e1f20000000000000000000000000000000)) } // ==== // EVMVersion: >=constantinople // ---- // Trace: +// INVALID() // Memory dump: // 0: 0000000000000000000000000000000000000000000000000000000000000001 // 20: 0000000000000000000000000000000000101112131415161718191a1b1c1d1e diff --git a/test/libyul/ewasmTranslationTests/signextend.yul b/test/libyul/ewasmTranslationTests/signextend.yul new file mode 100644 index 000000000000..4b54332193a4 --- /dev/null +++ b/test/libyul/ewasmTranslationTests/signextend.yul @@ -0,0 +1,11 @@ +{ + sstore(0, signextend(0, 0x86)) + sstore(1, signextend(0, 0x76)) + sstore(2, signextend(32, not(0))) + sstore(3, signextend(5, 0xff8844553322)) +} +// ---- +// Trace: +// INVALID() +// Memory dump: +// Storage dump: From 7d60cc17299768f11ef14847d60474618fd3d461 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 18 Dec 2019 13:22:46 +0000 Subject: [PATCH 04/36] Fix tracing LOG instruction in the Yul Ewasm interpreter --- test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp index fe8d28f70fa6..7b70a8360b91 100644 --- a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp +++ b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp @@ -248,7 +248,10 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a return writeU128(arg[0], m_state.gasprice); else if (_fun == "eth.log"_yulstring) { - logTrace(eth::Instruction::LOG0, {}); + uint64_t numberOfTopics = arg[2]; + if (numberOfTopics > 4) + throw ExplicitlyTerminated(); + logTrace(eth::logInstruction(numberOfTopics), {}); return 0; } else if (_fun == "eth.getBlockNumber"_yulstring) From 9f1e8086bb256131773ac52f6ec47981fc24c630 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 18 Dec 2019 14:43:26 +0000 Subject: [PATCH 05/36] Fix returning code size in Yul Ewasm interpreter --- test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp index 7b70a8360b91..1f9d113f77da 100644 --- a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp +++ b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp @@ -215,7 +215,7 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a return 0; } else if (_fun == "eth.getCodeSize"_yulstring) - return writeU256(arg[0], m_state.code.size()); + return m_state.code.size(); else if (_fun == "eth.getBlockCoinbase"_yulstring) return writeAddress(arg[0], m_state.coinbase); else if (_fun == "eth.create"_yulstring) From b3caf35e88d9aa4e4562c2a30042a0a40e76fbcf Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 18 Dec 2019 14:44:10 +0000 Subject: [PATCH 06/36] Change writeU256/writeU128/writeAddress not to return anything in Yul Ewasm interpreter --- .../EWasmBuiltinInterpreter.cpp | 54 ++++++++++++++----- .../yulInterpreter/EWasmBuiltinInterpreter.h | 6 +-- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp index 1f9d113f77da..9a8c89262a9a 100644 --- a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp +++ b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp @@ -139,18 +139,27 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a return readMemoryWord(arg[0]); } else if (_fun == "eth.getAddress"_yulstring) - return writeAddress(arg[0], m_state.address); + { + writeAddress(arg[0], m_state.address); + return 0; + } else if (_fun == "eth.getExternalBalance"_yulstring) + { // TODO this does not read the address, but is consistent with // EVM interpreter implementation. // If we take the address into account, this needs to use readAddress. - return writeU128(arg[0], m_state.balance); + writeU128(arg[0], m_state.balance); + return 0; + } else if (_fun == "eth.getBlockHash"_yulstring) { if (arg[0] >= m_state.blockNumber || arg[0] + 256 < m_state.blockNumber) return 1; else - return writeU256(arg[1], 0xaaaaaaaa + u256(arg[0] - m_state.blockNumber - 256)); + { + writeU256(arg[1], 0xaaaaaaaa + u256(arg[0] - m_state.blockNumber - 256)); + return 0; + } } else if (_fun == "eth.call"_yulstring) { @@ -199,12 +208,21 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a return 0; } else if (_fun == "eth.storageLoad"_yulstring) - return writeU256(arg[1], m_state.storage[h256(readU256(arg[0]))]); + { + writeU256(arg[1], m_state.storage[h256(readU256(arg[0]))]); + return 0; + } else if (_fun == "eth.getCaller"_yulstring) + { // TODO should this only write 20 bytes? - return writeAddress(arg[0], m_state.caller); + writeAddress(arg[0], m_state.caller); + return 0; + } else if (_fun == "eth.getCallValue"_yulstring) - return writeU128(arg[0], m_state.callvalue); + { + writeU128(arg[0], m_state.callvalue); + return 0; + } else if (_fun == "eth.codeCopy"_yulstring) { if (accessMemory(arg[0], arg[2])) @@ -217,7 +235,10 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a else if (_fun == "eth.getCodeSize"_yulstring) return m_state.code.size(); else if (_fun == "eth.getBlockCoinbase"_yulstring) - return writeAddress(arg[0], m_state.coinbase); + { + writeAddress(arg[0], m_state.coinbase); + return 0; + } else if (_fun == "eth.create"_yulstring) { // TODO access memory @@ -226,7 +247,10 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a return 0xcccccc + arg[1]; } else if (_fun == "eth.getBlockDifficulty"_yulstring) - return writeU256(arg[0], m_state.difficulty); + { + writeU256(arg[0], m_state.difficulty); + return 0; + } else if (_fun == "eth.externalCodeCopy"_yulstring) { // TODO use readAddress to read address. @@ -245,7 +269,10 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a else if (_fun == "eth.getBlockGasLimit"_yulstring) return uint64_t(m_state.gaslimit); else if (_fun == "eth.getTxGasPrice"_yulstring) - return writeU128(arg[0], m_state.gasprice); + { + writeU128(arg[0], m_state.gasprice); + return 0; + } else if (_fun == "eth.log"_yulstring) { uint64_t numberOfTopics = arg[2]; @@ -257,7 +284,10 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a else if (_fun == "eth.getBlockNumber"_yulstring) return m_state.blockNumber; else if (_fun == "eth.getTxOrigin"_yulstring) - return writeAddress(arg[0], m_state.origin); + { + writeAddress(arg[0], m_state.origin); + return 0; + } else if (_fun == "eth.finish"_yulstring) { bytes data; @@ -338,7 +368,7 @@ void EWasmBuiltinInterpreter::writeMemoryWord(uint64_t _offset, uint64_t _value) m_state.memory[_offset + i] = uint8_t((_value >> (i * 8)) & 0xff); } -u256 EWasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _croppedTo) +void EWasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _croppedTo) { accessMemory(_offset, _croppedTo); for (size_t i = 0; i < _croppedTo; i++) @@ -346,8 +376,6 @@ u256 EWasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _c m_state.memory[_offset + _croppedTo - 1 - i] = uint8_t(_value & 0xff); _value >>= 8; } - - return {}; } u256 EWasmBuiltinInterpreter::readU256(uint64_t _offset, size_t _croppedTo) diff --git a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.h b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.h index e96cbbae2359..8472b4a22974 100644 --- a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.h +++ b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.h @@ -88,9 +88,9 @@ class EWasmBuiltinInterpreter void writeMemoryWord(uint64_t _offset, uint64_t _value); /// Helper for eth.* builtins. Writes to memory (big-endian) and always returns zero. - dev::u256 writeU256(uint64_t _offset, dev::u256 _value, size_t _croppedTo = 32); - dev::u256 writeU128(uint64_t _offset, dev::u256 _value) { return writeU256(_offset, std::move(_value), 16); } - dev::u256 writeAddress(uint64_t _offset, dev::u256 _value) { return writeU256(_offset, std::move(_value), 20); } + void writeU256(uint64_t _offset, dev::u256 _value, size_t _croppedTo = 32); + void writeU128(uint64_t _offset, dev::u256 _value) { writeU256(_offset, std::move(_value), 16); } + void writeAddress(uint64_t _offset, dev::u256 _value) { writeU256(_offset, std::move(_value), 20); } /// Helper for eth.* builtins. Reads from memory (big-endian) and returns the value; dev::u256 readU256(uint64_t _offset, size_t _croppedTo = 32); dev::u256 readU128(uint64_t _offset) { return readU256(_offset, 16); } From 7d3ccee921e9dcf7e140e88dda406040f9ac77cb Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 18 Dec 2019 14:56:29 +0000 Subject: [PATCH 07/36] Fix implementation of getCodeSize in Ewasm --- libyul/backends/wasm/EVMToEWasmTranslator.cpp | 3 +-- libyul/backends/wasm/WasmDialect.cpp | 2 +- test/libyul/ewasmTranslationTests/smoke_create.yul | 1 - test/libyul/ewasmTranslationTests/smoke_create2.yul | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/libyul/backends/wasm/EVMToEWasmTranslator.cpp b/libyul/backends/wasm/EVMToEWasmTranslator.cpp index bd95c27a5a6a..e75e55b55e86 100644 --- a/libyul/backends/wasm/EVMToEWasmTranslator.cpp +++ b/libyul/backends/wasm/EVMToEWasmTranslator.cpp @@ -401,8 +401,7 @@ function calldatacopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4) { // Needed? function codesize() -> z1, z2, z3, z4 { - eth.getCodeSize(0) - z1, z2, z3, z4 := mload_internal(0) + z4 := eth.getCodeSize() } function codecopy(x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4) { eth.codeCopy( diff --git a/libyul/backends/wasm/WasmDialect.cpp b/libyul/backends/wasm/WasmDialect.cpp index 69ba02413db6..fb230562e32a 100644 --- a/libyul/backends/wasm/WasmDialect.cpp +++ b/libyul/backends/wasm/WasmDialect.cpp @@ -120,7 +120,7 @@ void WasmDialect::addEthereumExternals() {"getCaller", {i32ptr}, {}}, {"getCallValue", {i32ptr}, {}}, {"codeCopy", {i32ptr, i32, i32}, {}}, - {"getCodeSize", {i32ptr}, {}}, + {"getCodeSize", {}, {i32}}, {"getBlockCoinbase", {i32ptr}, {}}, {"create", {i32ptr, i32ptr, i32, i32ptr}, {i32}}, {"getBlockDifficulty", {i32ptr}, {}}, diff --git a/test/libyul/ewasmTranslationTests/smoke_create.yul b/test/libyul/ewasmTranslationTests/smoke_create.yul index 6f038cdc86aa..ae6d457c4dc8 100644 --- a/test/libyul/ewasmTranslationTests/smoke_create.yul +++ b/test/libyul/ewasmTranslationTests/smoke_create.yul @@ -7,6 +7,5 @@ // Trace: // INVALID() // Memory dump: -// 0: 0000000000000000000000000000000000000000000000000000000000000014 // 40: 636f6465636f6465636f6465636f6465636f6465000000000000000000000000 // Storage dump: diff --git a/test/libyul/ewasmTranslationTests/smoke_create2.yul b/test/libyul/ewasmTranslationTests/smoke_create2.yul index 347574d6b64e..32d789ea9abb 100644 --- a/test/libyul/ewasmTranslationTests/smoke_create2.yul +++ b/test/libyul/ewasmTranslationTests/smoke_create2.yul @@ -9,6 +9,5 @@ // Trace: // INVALID() // Memory dump: -// 0: 0000000000000000000000000000000000000000000000000000000000000014 // 80: 636f6465636f6465636f6465636f6465636f6465000000000000000000000000 // Storage dump: From cec45a7df51af134109a606d2f3e222a72abb747 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 11 Dec 2019 13:27:24 +0000 Subject: [PATCH 08/36] Rename EWasmCodeTransform to WasmCodeTransform --- libyul/CMakeLists.txt | 4 +- libyul/backends/wasm/EWasmObjectCompiler.cpp | 4 +- ...odeTransform.cpp => WasmCodeTransform.cpp} | 58 +++++++++---------- ...asmCodeTransform.h => WasmCodeTransform.h} | 6 +- 4 files changed, 36 insertions(+), 36 deletions(-) rename libyul/backends/wasm/{EWasmCodeTransform.cpp => WasmCodeTransform.cpp} (83%) rename libyul/backends/wasm/{EWasmCodeTransform.h => WasmCodeTransform.h} (98%) diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 2a0577edcc1a..2fa66f432a60 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -46,14 +46,14 @@ add_library(yul backends/evm/NoOutputAssembly.cpp backends/wasm/EVMToEWasmTranslator.cpp backends/wasm/EVMToEWasmTranslator.h - backends/wasm/EWasmCodeTransform.cpp - backends/wasm/EWasmCodeTransform.h backends/wasm/EWasmObjectCompiler.cpp backends/wasm/EWasmObjectCompiler.h backends/wasm/BinaryTransform.cpp backends/wasm/BinaryTransform.h backends/wasm/TextTransform.cpp backends/wasm/TextTransform.h + backends/wasm/WasmCodeTransform.cpp + backends/wasm/WasmCodeTransform.h backends/wasm/WasmDialect.cpp backends/wasm/WasmDialect.h backends/wasm/WordSizeTransform.cpp diff --git a/libyul/backends/wasm/EWasmObjectCompiler.cpp b/libyul/backends/wasm/EWasmObjectCompiler.cpp index 9f0e30f47839..f487884abe69 100644 --- a/libyul/backends/wasm/EWasmObjectCompiler.cpp +++ b/libyul/backends/wasm/EWasmObjectCompiler.cpp @@ -20,7 +20,7 @@ #include -#include +#include #include #include @@ -44,7 +44,7 @@ wasm::Module EWasmObjectCompiler::run(Object& _object) yulAssert(_object.analysisInfo, "No analysis info."); yulAssert(_object.code, "No code."); - wasm::Module module = EWasmCodeTransform::run(m_dialect, *_object.code); + wasm::Module module = WasmCodeTransform::run(m_dialect, *_object.code); for (auto& subNode: _object.subObjects) if (Object* subObject = dynamic_cast(subNode.get())) diff --git a/libyul/backends/wasm/EWasmCodeTransform.cpp b/libyul/backends/wasm/WasmCodeTransform.cpp similarity index 83% rename from libyul/backends/wasm/EWasmCodeTransform.cpp rename to libyul/backends/wasm/WasmCodeTransform.cpp index 88fc86bf4b37..51f80af17cec 100644 --- a/libyul/backends/wasm/EWasmCodeTransform.cpp +++ b/libyul/backends/wasm/WasmCodeTransform.cpp @@ -15,10 +15,10 @@ along with solidity. If not, see . */ /** -* Common code generator for translating Yul / inline assembly to EWasm. +* Common code generator for translating Yul / inline assembly to Wasm. */ -#include +#include #include @@ -36,11 +36,11 @@ using namespace std; using namespace dev; using namespace yul; -wasm::Module EWasmCodeTransform::run(Dialect const& _dialect, yul::Block const& _ast) +wasm::Module WasmCodeTransform::run(Dialect const& _dialect, yul::Block const& _ast) { wasm::Module module; - EWasmCodeTransform transform(_dialect, _ast); + WasmCodeTransform transform(_dialect, _ast); for (auto const& statement: _ast.statements) { @@ -59,7 +59,7 @@ wasm::Module EWasmCodeTransform::run(Dialect const& _dialect, yul::Block const& return module; } -wasm::Expression EWasmCodeTransform::generateMultiAssignment( +wasm::Expression WasmCodeTransform::generateMultiAssignment( vector _variableNames, unique_ptr _firstValue ) @@ -82,7 +82,7 @@ wasm::Expression EWasmCodeTransform::generateMultiAssignment( return { std::move(block) }; } -wasm::Expression EWasmCodeTransform::operator()(VariableDeclaration const& _varDecl) +wasm::Expression WasmCodeTransform::operator()(VariableDeclaration const& _varDecl) { vector variableNames; for (auto const& var: _varDecl.variables) @@ -97,7 +97,7 @@ wasm::Expression EWasmCodeTransform::operator()(VariableDeclaration const& _varD return wasm::BuiltinCall{"nop", {}}; } -wasm::Expression EWasmCodeTransform::operator()(Assignment const& _assignment) +wasm::Expression WasmCodeTransform::operator()(Assignment const& _assignment) { vector variableNames; for (auto const& var: _assignment.variableNames) @@ -105,12 +105,12 @@ wasm::Expression EWasmCodeTransform::operator()(Assignment const& _assignment) return generateMultiAssignment(move(variableNames), visit(*_assignment.value)); } -wasm::Expression EWasmCodeTransform::operator()(ExpressionStatement const& _statement) +wasm::Expression WasmCodeTransform::operator()(ExpressionStatement const& _statement) { return visitReturnByValue(_statement.expression); } -wasm::Expression EWasmCodeTransform::operator()(FunctionCall const& _call) +wasm::Expression WasmCodeTransform::operator()(FunctionCall const& _call) { bool typeConversionNeeded = false; @@ -171,19 +171,19 @@ wasm::Expression EWasmCodeTransform::operator()(FunctionCall const& _call) return {std::move(funCall)}; } -wasm::Expression EWasmCodeTransform::operator()(Identifier const& _identifier) +wasm::Expression WasmCodeTransform::operator()(Identifier const& _identifier) { return wasm::LocalVariable{_identifier.name.str()}; } -wasm::Expression EWasmCodeTransform::operator()(Literal const& _literal) +wasm::Expression WasmCodeTransform::operator()(Literal const& _literal) { u256 value = valueOfLiteral(_literal); yulAssert(value <= numeric_limits::max(), "Literal too large: " + value.str()); return wasm::Literal{uint64_t(value)}; } -wasm::Expression EWasmCodeTransform::operator()(If const& _if) +wasm::Expression WasmCodeTransform::operator()(If const& _if) { // TODO converting i64 to i32 might not always be needed. @@ -197,7 +197,7 @@ wasm::Expression EWasmCodeTransform::operator()(If const& _if) }; } -wasm::Expression EWasmCodeTransform::operator()(Switch const& _switch) +wasm::Expression WasmCodeTransform::operator()(Switch const& _switch) { wasm::Block block; string condition = m_nameDispenser.newName("condition"_yulstring).str(); @@ -237,13 +237,13 @@ wasm::Expression EWasmCodeTransform::operator()(Switch const& _switch) return { std::move(block) }; } -wasm::Expression EWasmCodeTransform::operator()(FunctionDefinition const&) +wasm::Expression WasmCodeTransform::operator()(FunctionDefinition const&) { yulAssert(false, "Should not have visited here."); return {}; } -wasm::Expression EWasmCodeTransform::operator()(ForLoop const& _for) +wasm::Expression WasmCodeTransform::operator()(ForLoop const& _for) { string breakLabel = newLabel(); string continueLabel = newLabel(); @@ -262,37 +262,37 @@ wasm::Expression EWasmCodeTransform::operator()(ForLoop const& _for) return { wasm::Block{breakLabel, make_vector(move(loop))} }; } -wasm::Expression EWasmCodeTransform::operator()(Break const&) +wasm::Expression WasmCodeTransform::operator()(Break const&) { return wasm::Break{wasm::Label{m_breakContinueLabelNames.top().first}}; } -wasm::Expression EWasmCodeTransform::operator()(Continue const&) +wasm::Expression WasmCodeTransform::operator()(Continue const&) { return wasm::Break{wasm::Label{m_breakContinueLabelNames.top().second}}; } -wasm::Expression EWasmCodeTransform::operator()(Leave const&) +wasm::Expression WasmCodeTransform::operator()(Leave const&) { return wasm::Return{}; } -wasm::Expression EWasmCodeTransform::operator()(Block const& _block) +wasm::Expression WasmCodeTransform::operator()(Block const& _block) { return wasm::Block{{}, visit(_block.statements)}; } -unique_ptr EWasmCodeTransform::visit(yul::Expression const& _expression) +unique_ptr WasmCodeTransform::visit(yul::Expression const& _expression) { return make_unique(std::visit(*this, _expression)); } -wasm::Expression EWasmCodeTransform::visitReturnByValue(yul::Expression const& _expression) +wasm::Expression WasmCodeTransform::visitReturnByValue(yul::Expression const& _expression) { return std::visit(*this, _expression); } -vector EWasmCodeTransform::visit(vector const& _expressions) +vector WasmCodeTransform::visit(vector const& _expressions) { vector ret; for (auto const& e: _expressions) @@ -300,12 +300,12 @@ vector EWasmCodeTransform::visit(vector const return ret; } -wasm::Expression EWasmCodeTransform::visit(yul::Statement const& _statement) +wasm::Expression WasmCodeTransform::visit(yul::Statement const& _statement) { return std::visit(*this, _statement); } -vector EWasmCodeTransform::visit(vector const& _statements) +vector WasmCodeTransform::visit(vector const& _statements) { vector ret; for (auto const& s: _statements) @@ -313,7 +313,7 @@ vector EWasmCodeTransform::visit(vector const& return ret; } -wasm::FunctionDefinition EWasmCodeTransform::translateFunction(yul::FunctionDefinition const& _fun) +wasm::FunctionDefinition WasmCodeTransform::translateFunction(yul::FunctionDefinition const& _fun) { wasm::FunctionDefinition fun; fun.name = _fun.name.str(); @@ -344,7 +344,7 @@ wasm::FunctionDefinition EWasmCodeTransform::translateFunction(yul::FunctionDefi return fun; } -wasm::Expression EWasmCodeTransform::injectTypeConversionIfNeeded(wasm::FunctionCall _call) const +wasm::Expression WasmCodeTransform::injectTypeConversionIfNeeded(wasm::FunctionCall _call) const { wasm::FunctionImport const& import = m_functionsToImport.at(YulString{_call.functionName}); for (size_t i = 0; i < _call.arguments.size(); ++i) @@ -361,7 +361,7 @@ wasm::Expression EWasmCodeTransform::injectTypeConversionIfNeeded(wasm::Function return {std::move(_call)}; } -vector EWasmCodeTransform::injectTypeConversionIfNeeded( +vector WasmCodeTransform::injectTypeConversionIfNeeded( vector _arguments, vector const& _parameterTypes ) const @@ -378,12 +378,12 @@ vector EWasmCodeTransform::injectTypeConversionIfNeeded( return _arguments; } -string EWasmCodeTransform::newLabel() +string WasmCodeTransform::newLabel() { return m_nameDispenser.newName("label_"_yulstring).str(); } -void EWasmCodeTransform::allocateGlobals(size_t _amount) +void WasmCodeTransform::allocateGlobals(size_t _amount) { while (m_globalVariables.size() < _amount) m_globalVariables.emplace_back(wasm::GlobalVariableDeclaration{ diff --git a/libyul/backends/wasm/EWasmCodeTransform.h b/libyul/backends/wasm/WasmCodeTransform.h similarity index 98% rename from libyul/backends/wasm/EWasmCodeTransform.h rename to libyul/backends/wasm/WasmCodeTransform.h index 35700553c63a..1a606d5ab900 100644 --- a/libyul/backends/wasm/EWasmCodeTransform.h +++ b/libyul/backends/wasm/WasmCodeTransform.h @@ -15,7 +15,7 @@ along with solidity. If not, see . */ /** - * Common code generator for translating Yul / inline assembly to EWasm. + * Common code generator for translating Yul / inline assembly to Wasm. */ #pragma once @@ -32,7 +32,7 @@ namespace yul { struct AsmAnalysisInfo; -class EWasmCodeTransform +class WasmCodeTransform { public: static wasm::Module run(Dialect const& _dialect, yul::Block const& _ast); @@ -54,7 +54,7 @@ class EWasmCodeTransform wasm::Expression operator()(yul::Block const& _block); private: - EWasmCodeTransform( + WasmCodeTransform( Dialect const& _dialect, Block const& _ast ): From 018960ebb197125816c99c0db3a3c868c1d20b89 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 12 Dec 2019 12:48:43 +0000 Subject: [PATCH 09/36] Rename EWasmObjectCompiler to WasmObjectCompiler --- libsolidity/interface/CompilerStack.cpp | 4 ---- libyul/AssemblyStack.cpp | 4 ++-- libyul/CMakeLists.txt | 4 ++-- ...{EWasmObjectCompiler.cpp => WasmObjectCompiler.cpp} | 10 +++++----- .../{EWasmObjectCompiler.h => WasmObjectCompiler.h} | 7 ++++--- 5 files changed, 13 insertions(+), 16 deletions(-) rename libyul/backends/wasm/{EWasmObjectCompiler.cpp => WasmObjectCompiler.cpp} (83%) rename libyul/backends/wasm/{EWasmObjectCompiler.h => WasmObjectCompiler.h} (88%) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 9d9a0a7b30d0..4cb085883ec8 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -51,10 +51,6 @@ #include #include -#include -#include -#include -#include #include #include diff --git a/libyul/AssemblyStack.cpp b/libyul/AssemblyStack.cpp index 6dc84ac81464..ce10727d2cb3 100644 --- a/libyul/AssemblyStack.cpp +++ b/libyul/AssemblyStack.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -220,7 +220,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const Dialect const& dialect = languageToDialect(m_language, EVMVersion{}); MachineAssemblyObject object; - auto result = EWasmObjectCompiler::compile(*m_parserResult, dialect); + auto result = WasmObjectCompiler::compile(*m_parserResult, dialect); object.assembly = std::move(result.first); object.bytecode = make_shared(); object.bytecode->bytecode = std::move(result.second); diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 2fa66f432a60..2304e76667e7 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -46,8 +46,6 @@ add_library(yul backends/evm/NoOutputAssembly.cpp backends/wasm/EVMToEWasmTranslator.cpp backends/wasm/EVMToEWasmTranslator.h - backends/wasm/EWasmObjectCompiler.cpp - backends/wasm/EWasmObjectCompiler.h backends/wasm/BinaryTransform.cpp backends/wasm/BinaryTransform.h backends/wasm/TextTransform.cpp @@ -56,6 +54,8 @@ add_library(yul backends/wasm/WasmCodeTransform.h backends/wasm/WasmDialect.cpp backends/wasm/WasmDialect.h + backends/wasm/WasmObjectCompiler.cpp + backends/wasm/WasmObjectCompiler.h backends/wasm/WordSizeTransform.cpp backends/wasm/WordSizeTransform.h optimiser/ASTCopier.cpp diff --git a/libyul/backends/wasm/EWasmObjectCompiler.cpp b/libyul/backends/wasm/WasmObjectCompiler.cpp similarity index 83% rename from libyul/backends/wasm/EWasmObjectCompiler.cpp rename to libyul/backends/wasm/WasmObjectCompiler.cpp index f487884abe69..b65318ae3b88 100644 --- a/libyul/backends/wasm/EWasmObjectCompiler.cpp +++ b/libyul/backends/wasm/WasmObjectCompiler.cpp @@ -18,7 +18,7 @@ * Compiler that transforms Yul Objects to Wasm text and binary representation (Ewasm flavoured). */ -#include +#include #include #include @@ -32,14 +32,14 @@ using namespace yul; using namespace std; -pair EWasmObjectCompiler::compile(Object& _object, Dialect const& _dialect) +pair WasmObjectCompiler::compile(Object& _object, Dialect const& _dialect) { - EWasmObjectCompiler compiler(_dialect); + WasmObjectCompiler compiler(_dialect); wasm::Module module = compiler.run(_object); return {wasm::TextTransform().run(module), wasm::BinaryTransform::run(module)}; } -wasm::Module EWasmObjectCompiler::run(Object& _object) +wasm::Module WasmObjectCompiler::run(Object& _object) { yulAssert(_object.analysisInfo, "No analysis info."); yulAssert(_object.code, "No code."); @@ -50,7 +50,7 @@ wasm::Module EWasmObjectCompiler::run(Object& _object) if (Object* subObject = dynamic_cast(subNode.get())) module.subModules[subObject->name.str()] = run(*subObject); else - yulAssert(false, "Data is not yet supported for EWasm."); + yulAssert(false, "Data is not yet supported for Wasm."); return module; } diff --git a/libyul/backends/wasm/EWasmObjectCompiler.h b/libyul/backends/wasm/WasmObjectCompiler.h similarity index 88% rename from libyul/backends/wasm/EWasmObjectCompiler.h rename to libyul/backends/wasm/WasmObjectCompiler.h index a4fcf1af89c5..2805f0b06094 100644 --- a/libyul/backends/wasm/EWasmObjectCompiler.h +++ b/libyul/backends/wasm/WasmObjectCompiler.h @@ -28,6 +28,7 @@ namespace dev { using bytes = std::vector; } + namespace yul { struct Object; @@ -37,13 +38,13 @@ namespace wasm struct Module; } -class EWasmObjectCompiler +class WasmObjectCompiler { public: - /// Compiles the given object and returns the WAST and the binary representation. + /// Compiles the given object and returns the Wasm text and binary representation. static std::pair compile(Object& _object, Dialect const& _dialect); private: - EWasmObjectCompiler(Dialect const& _dialect): + WasmObjectCompiler(Dialect const& _dialect): m_dialect(_dialect) {} From 7effc94f24f11932c29680758c2bb8a6255d362c Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 12 Dec 2019 12:52:27 +0000 Subject: [PATCH 10/36] Rename EVMToEWasmTranslator to EVMToEwasmTranslator --- libyul/AssemblyStack.cpp | 4 ++-- libyul/CMakeLists.txt | 4 ++-- ...ranslator.cpp => EVMToEwasmTranslator.cpp} | 8 +++---- ...asmTranslator.h => EVMToEwasmTranslator.h} | 6 ++--- test/CMakeLists.txt | 4 ++-- test/InteractiveTests.h | 4 ++-- ...ationTest.cpp => EwasmTranslationTest.cpp} | 22 +++++++++---------- ...anslationTest.h => EwasmTranslationTest.h} | 6 ++--- test/tools/CMakeLists.txt | 2 +- 9 files changed, 30 insertions(+), 30 deletions(-) rename libyul/backends/wasm/{EVMToEWasmTranslator.cpp => EVMToEwasmTranslator.cpp} (98%) rename libyul/backends/wasm/{EVMToEWasmTranslator.h => EVMToEwasmTranslator.h} (85%) rename test/libyul/{EWasmTranslationTest.cpp => EwasmTranslationTest.cpp} (86%) rename test/libyul/{EWasmTranslationTest.h => EwasmTranslationTest.h} (90%) diff --git a/libyul/AssemblyStack.cpp b/libyul/AssemblyStack.cpp index ce10727d2cb3..dcc9b887a865 100644 --- a/libyul/AssemblyStack.cpp +++ b/libyul/AssemblyStack.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -112,7 +112,7 @@ void AssemblyStack::translate(AssemblyStack::Language _targetLanguage) "Invalid language combination" ); - *m_parserResult = EVMToEWasmTranslator( + *m_parserResult = EVMToEwasmTranslator( languageToDialect(m_language, m_evmVersion) ).run(*parserResult()); diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 2304e76667e7..23aca8bb2d58 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -44,8 +44,8 @@ add_library(yul backends/evm/EVMMetrics.h backends/evm/NoOutputAssembly.h backends/evm/NoOutputAssembly.cpp - backends/wasm/EVMToEWasmTranslator.cpp - backends/wasm/EVMToEWasmTranslator.h + backends/wasm/EVMToEwasmTranslator.cpp + backends/wasm/EVMToEwasmTranslator.h backends/wasm/BinaryTransform.cpp backends/wasm/BinaryTransform.h backends/wasm/TextTransform.cpp diff --git a/libyul/backends/wasm/EVMToEWasmTranslator.cpp b/libyul/backends/wasm/EVMToEwasmTranslator.cpp similarity index 98% rename from libyul/backends/wasm/EVMToEWasmTranslator.cpp rename to libyul/backends/wasm/EVMToEwasmTranslator.cpp index e75e55b55e86..20a608708334 100644 --- a/libyul/backends/wasm/EVMToEWasmTranslator.cpp +++ b/libyul/backends/wasm/EVMToEwasmTranslator.cpp @@ -15,10 +15,10 @@ along with solidity. If not, see . */ /** - * Translates Yul code from EVM dialect to eWasm dialect. + * Translates Yul code from EVM dialect to Ewasm dialect. */ -#include +#include #include #include @@ -701,7 +701,7 @@ function invalid() { } -Object EVMToEWasmTranslator::run(Object const& _object) +Object EVMToEwasmTranslator::run(Object const& _object) { if (!m_polyfill) parsePolyfill(); @@ -749,7 +749,7 @@ Object EVMToEWasmTranslator::run(Object const& _object) return ret; } -void EVMToEWasmTranslator::parsePolyfill() +void EVMToEwasmTranslator::parsePolyfill() { ErrorList errors; ErrorReporter errorReporter(errors); diff --git a/libyul/backends/wasm/EVMToEWasmTranslator.h b/libyul/backends/wasm/EVMToEwasmTranslator.h similarity index 85% rename from libyul/backends/wasm/EVMToEWasmTranslator.h rename to libyul/backends/wasm/EVMToEwasmTranslator.h index daefa2cce7b0..73563fc053c4 100644 --- a/libyul/backends/wasm/EVMToEWasmTranslator.h +++ b/libyul/backends/wasm/EVMToEwasmTranslator.h @@ -15,7 +15,7 @@ along with solidity. If not, see . */ /** - * Translates Yul code from EVM dialect to eWasm dialect. + * Translates Yul code from EVM dialect to Ewasm dialect. */ #pragma once @@ -28,10 +28,10 @@ namespace yul { struct Object; -class EVMToEWasmTranslator: public ASTModifier +class EVMToEwasmTranslator: public ASTModifier { public: - EVMToEWasmTranslator(Dialect const& _evmDialect): m_dialect(_evmDialect) {} + EVMToEwasmTranslator(Dialect const& _evmDialect): m_dialect(_evmDialect) {} Object run(Object const& _object); private: diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8424e957b391..609f9f047d4e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -131,8 +131,8 @@ set(libyul_sources libyul/Common.cpp libyul/Common.h libyul/CompilabilityChecker.cpp - libyul/EWasmTranslationTest.cpp - libyul/EWasmTranslationTest.h + libyul/EwasmTranslationTest.cpp + libyul/EwasmTranslationTest.h libyul/FunctionSideEffects.cpp libyul/FunctionSideEffects.h libyul/Inliner.cpp diff --git a/test/InteractiveTests.h b/test/InteractiveTests.h index e1cb6c08fd5e..4a4c4df7cf51 100644 --- a/test/InteractiveTests.h +++ b/test/InteractiveTests.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include @@ -56,7 +56,7 @@ struct Testsuite Testsuite const g_interactiveTestsuites[] = { /* Title Path Subpath SMT NeedsVM Creator function */ - {"EWasm Translation", "libyul", "ewasmTranslationTests",false,false, &yul::test::EWasmTranslationTest::create}, + {"Ewasm Translation", "libyul", "ewasmTranslationTests",false,false, &yul::test::EwasmTranslationTest::create}, {"Yul Optimizer", "libyul", "yulOptimizerTests", false, false, &yul::test::YulOptimizerTest::create}, {"Yul Interpreter", "libyul", "yulInterpreterTests", false, false, &yul::test::YulInterpreterTest::create}, {"Yul Object Compiler", "libyul", "objectCompiler", false, false, &yul::test::ObjectCompilerTest::create}, diff --git a/test/libyul/EWasmTranslationTest.cpp b/test/libyul/EwasmTranslationTest.cpp similarity index 86% rename from test/libyul/EWasmTranslationTest.cpp rename to test/libyul/EwasmTranslationTest.cpp index b38bb8b5c77e..b0583537e4c7 100644 --- a/test/libyul/EWasmTranslationTest.cpp +++ b/test/libyul/EwasmTranslationTest.cpp @@ -15,7 +15,7 @@ along with solidity. If not, see . */ -#include +#include #include @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -47,7 +47,7 @@ using namespace dev::solidity::test; using namespace std; -EWasmTranslationTest::EWasmTranslationTest(string const& _filename) +EwasmTranslationTest::EwasmTranslationTest(string const& _filename) { boost::filesystem::path path(_filename); @@ -60,12 +60,12 @@ EWasmTranslationTest::EWasmTranslationTest(string const& _filename) m_expectation = parseSimpleExpectations(file); } -TestCase::TestResult EWasmTranslationTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted) +TestCase::TestResult EwasmTranslationTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted) { if (!parse(_stream, _linePrefix, _formatted)) return TestResult::FatalError; - *m_object = EVMToEWasmTranslator( + *m_object = EVMToEwasmTranslator( EVMDialect::strictAssemblyForEVMObjects(dev::test::Options::get().evmVersion()) ).run(*m_object); @@ -89,17 +89,17 @@ TestCase::TestResult EWasmTranslationTest::run(ostream& _stream, string const& _ return TestResult::Success; } -void EWasmTranslationTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const +void EwasmTranslationTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const { printIndented(_stream, m_source, _linePrefix); } -void EWasmTranslationTest::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const +void EwasmTranslationTest::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const { printIndented(_stream, m_obtainedResult, _linePrefix); } -void EWasmTranslationTest::printIndented(ostream& _stream, string const& _output, string const& _linePrefix) const +void EwasmTranslationTest::printIndented(ostream& _stream, string const& _output, string const& _linePrefix) const { stringstream output(_output); string line; @@ -107,7 +107,7 @@ void EWasmTranslationTest::printIndented(ostream& _stream, string const& _output _stream << _linePrefix << line << endl; } -bool EWasmTranslationTest::parse(ostream& _stream, string const& _linePrefix, bool const _formatted) +bool EwasmTranslationTest::parse(ostream& _stream, string const& _linePrefix, bool const _formatted) { AssemblyStack stack( dev::test::Options::get().evmVersion(), @@ -127,7 +127,7 @@ bool EWasmTranslationTest::parse(ostream& _stream, string const& _linePrefix, bo } } -string EWasmTranslationTest::interpret() +string EwasmTranslationTest::interpret() { InterpreterState state; state.maxTraceSize = 10000; @@ -147,7 +147,7 @@ string EWasmTranslationTest::interpret() return result.str(); } -void EWasmTranslationTest::printErrors(ostream& _stream, ErrorList const& _errors) +void EwasmTranslationTest::printErrors(ostream& _stream, ErrorList const& _errors) { SourceReferenceFormatter formatter(_stream); diff --git a/test/libyul/EWasmTranslationTest.h b/test/libyul/EwasmTranslationTest.h similarity index 90% rename from test/libyul/EWasmTranslationTest.h rename to test/libyul/EwasmTranslationTest.h index c63c305f9966..23c00262558c 100644 --- a/test/libyul/EWasmTranslationTest.h +++ b/test/libyul/EwasmTranslationTest.h @@ -32,15 +32,15 @@ namespace yul namespace test { -class EWasmTranslationTest: public dev::solidity::test::EVMVersionRestrictedTestCase +class EwasmTranslationTest: public dev::solidity::test::EVMVersionRestrictedTestCase { public: static std::unique_ptr create(Config const& _config) { - return std::make_unique(_config.filename); + return std::make_unique(_config.filename); } - explicit EWasmTranslationTest(std::string const& _filename); + explicit EwasmTranslationTest(std::string const& _filename); TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 46156c219de0..acc70c2dcfd0 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -32,7 +32,7 @@ add_executable(isoltest ../libsolidity/SMTCheckerTest.cpp ../libsolidity/SMTCheckerJSONTest.cpp ../libyul/Common.cpp - ../libyul/EWasmTranslationTest.cpp + ../libyul/EwasmTranslationTest.cpp ../libyul/FunctionSideEffects.cpp ../libyul/ObjectCompilerTest.cpp ../libyul/YulOptimizerTest.cpp From d867f5339bd219f76f04837b6bc03ddba435ec70 Mon Sep 17 00:00:00 2001 From: rodiazet Date: Wed, 18 Dec 2019 19:48:29 +0100 Subject: [PATCH 11/36] [WASM] add i64.clz and i64.store8 to Wasm dialect and EWasm interpreter. dsads --- libyul/backends/wasm/WasmDialect.cpp | 6 ++++ .../EWasmBuiltinInterpreter.cpp | 30 ++++++++++++++++++- .../yulInterpreter/EWasmBuiltinInterpreter.h | 3 ++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/libyul/backends/wasm/WasmDialect.cpp b/libyul/backends/wasm/WasmDialect.cpp index fb230562e32a..8e0cba8f9c0a 100644 --- a/libyul/backends/wasm/WasmDialect.cpp +++ b/libyul/backends/wasm/WasmDialect.cpp @@ -56,10 +56,16 @@ WasmDialect::WasmDialect(): addFunction("i64.eqz", 1, 1); m_functions["i64.eqz"_yulstring].returns.front() = "i32"_yulstring; + addFunction("i64.clz", 1, 1); + addFunction("i64.store", 2, 0, false); m_functions["i64.store"_yulstring].parameters.front() = "i32"_yulstring; m_functions["i64.store"_yulstring].sideEffects.invalidatesStorage = false; + addFunction("i64.store8", 2, 0, false); + m_functions["i64.store8"_yulstring].parameters.front() = "i32"_yulstring; + m_functions["i64.store8"_yulstring].sideEffects.invalidatesStorage = false; + addFunction("i64.load", 1, 1, false); m_functions["i64.load"_yulstring].parameters.front() = "i32"_yulstring; m_functions["i64.load"_yulstring].sideEffects.invalidatesStorage = false; diff --git a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp index 9a8c89262a9a..a35a6f491682 100644 --- a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp +++ b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp @@ -49,6 +49,21 @@ void copyZeroExtended( _target[_targetOffset + i] = _sourceOffset + i < _source.size() ? _source[_sourceOffset + i] : 0; } +/// Count leading zeros for uint64 +uint64_t clz(uint64_t _v) +{ + if (_v == 0) + return 64; + + uint64_t r = 0; + while (!(_v & 0x8000000000000000)) + { + r += 1; + _v = _v << 1; + } + return r; +} + } using u512 = boost::multiprecision::number>; @@ -119,6 +134,8 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a return arg[0] != arg[1] ? 1 : 0; else if (_fun == "i64.eqz"_yulstring) return arg[0] == 0 ? 1 : 0; + else if (_fun == "i64.clz"_yulstring) + return clz(arg[0]); else if (_fun == "i64.lt_u"_yulstring) return arg[0] < arg[1] ? 1 : 0; else if (_fun == "i64.gt_u"_yulstring) @@ -133,6 +150,12 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a writeMemoryWord(arg[0], arg[1]); return 0; } + else if (_fun == "i64.store8"_yulstring) + { + accessMemory(arg[0], 1); + writeMemoryByte(arg[0], static_cast(arg[1] & 0xff)); + return 0; + } else if (_fun == "i64.load"_yulstring) { accessMemory(arg[0], 8); @@ -148,7 +171,7 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a // TODO this does not read the address, but is consistent with // EVM interpreter implementation. // If we take the address into account, this needs to use readAddress. - writeU128(arg[0], m_state.balance); + writeU128(arg[1], m_state.balance); return 0; } else if (_fun == "eth.getBlockHash"_yulstring) @@ -368,6 +391,11 @@ void EWasmBuiltinInterpreter::writeMemoryWord(uint64_t _offset, uint64_t _value) m_state.memory[_offset + i] = uint8_t((_value >> (i * 8)) & 0xff); } +void EWasmBuiltinInterpreter::writeMemoryByte(uint64_t _offset, uint8_t _value) +{ + m_state.memory[_offset] = _value; +} + void EWasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _croppedTo) { accessMemory(_offset, _croppedTo); diff --git a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.h b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.h index 8472b4a22974..363c11f453d0 100644 --- a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.h +++ b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.h @@ -86,6 +86,9 @@ class EWasmBuiltinInterpreter /// Writes a word to memory (little-endian) /// Does not adjust msize, use @a accessMemory for that void writeMemoryWord(uint64_t _offset, uint64_t _value); + /// Writes a byte to memory + /// Does not adjust msize, use @a accessMemory for that + void writeMemoryByte(uint64_t _offset, uint8_t _value); /// Helper for eth.* builtins. Writes to memory (big-endian) and always returns zero. void writeU256(uint64_t _offset, dev::u256 _value, size_t _croppedTo = 32); From 1e59c1916605fa7fe3e6274c291c34e61b3cb4be Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 18 Dec 2019 21:54:30 +0100 Subject: [PATCH 12/36] Dialect setting for yul optimizer tests. --- test/libyul/YulOptimizerTest.cpp | 26 ++++++++++++++----- test/libyul/YulOptimizerTest.h | 1 - .../disambiguator/for_statement.yul | 2 +- .../disambiguator/funtion_call.yul | 2 +- .../disambiguator/if_statement.yul | 2 +- .../disambiguator/long_names.yul | 2 +- .../disambiguator/smoke_yul.yul | 2 +- .../disambiguator/switch_statement.yul | 2 +- .../disambiguator/variables.yul | 2 +- .../disambiguator/variables_clash.yul | 2 +- .../variables_inside_functions.yul | 2 +- .../expressionInliner/simple.yul | 2 +- .../expressionInliner/with_args.yul | 2 +- .../functionGrouper/empty_block.yul | 2 +- .../functionGrouper/multi_fun_mixed.yul | 2 +- .../functionGrouper/nested_fun.yul | 2 +- .../functionGrouper/single_fun.yul | 2 +- .../functionHoister/empty_block.yul | 2 +- .../functionHoister/multi_mixed.yul | 2 +- .../functionHoister/nested.yul | 2 +- .../functionHoister/single.yul | 2 +- .../mainFunction/empty_block.yul | 2 +- .../mainFunction/multi_fun_mixed.yul | 2 +- .../mainFunction/nested_fun.yul | 2 +- .../mainFunction/sigle_fun.yul | 2 +- .../yulOptimizerTests/mainFunction/smoke.yul | 2 +- 26 files changed, 43 insertions(+), 32 deletions(-) diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 221f3414d48e..8b0561378014 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -98,12 +99,24 @@ YulOptimizerTest::YulOptimizerTest(string const& _filename) file.exceptions(ios::badbit); m_source = parseSourceAndSettings(file); - if (m_settings.count("yul")) + if (m_settings.count("dialect")) { - m_yul = true; - m_validatedSettings["yul"] = "true"; - m_settings.erase("yul"); + auto dialectName = m_settings["dialect"]; + if (dialectName == "yul") + m_dialect = &Dialect::yul(); + else if (dialectName == "ewasm") + m_dialect = &WasmDialect::instance(); + else if (dialectName == "evm") + m_dialect = &EVMDialect::strictAssemblyForEVMObjects(dev::test::Options::get().evmVersion()); + else + BOOST_THROW_EXCEPTION(runtime_error("Invalid dialect " + dialectName)); + + m_validatedSettings["dialect"] = dialectName; + m_settings.erase("dialect"); } + else + m_dialect = &EVMDialect::strictAssemblyForEVMObjects(dev::test::Options::get().evmVersion()); + if (m_settings.count("step")) { m_validatedSettings["step"] = m_settings["step"]; @@ -350,7 +363,7 @@ TestCase::TestResult YulOptimizerTest::run(ostream& _stream, string const& _line return TestResult::FatalError; } - m_obtainedResult = AsmPrinter{m_yul}(*m_ast) + "\n"; + m_obtainedResult = AsmPrinter{m_dialect->flavour == AsmFlavour::Yul}(*m_ast) + "\n"; if (m_optimizerStep != m_validatedSettings["step"]) { @@ -406,7 +419,7 @@ bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool c { AssemblyStack stack( dev::test::Options::get().evmVersion(), - m_yul ? AssemblyStack::Language::Yul : AssemblyStack::Language::StrictAssembly, + m_dialect->flavour == AsmFlavour::Yul ? AssemblyStack::Language::Yul : AssemblyStack::Language::StrictAssembly, dev::solidity::OptimiserSettings::none() ); if (!stack.parseAndAnalyze("", m_source) || !stack.errors().empty()) @@ -415,7 +428,6 @@ bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool c printErrors(_stream, stack.errors()); return false; } - m_dialect = m_yul ? &Dialect::yul() : &EVMDialect::strictAssemblyForEVMObjects(dev::test::Options::get().evmVersion()); m_ast = stack.parserResult()->code; m_analysisInfo = stack.parserResult()->analysisInfo; return true; diff --git a/test/libyul/YulOptimizerTest.h b/test/libyul/YulOptimizerTest.h index a9cc04ab1965..d74e3fc166ce 100644 --- a/test/libyul/YulOptimizerTest.h +++ b/test/libyul/YulOptimizerTest.h @@ -71,7 +71,6 @@ class YulOptimizerTest: public dev::solidity::test::EVMVersionRestrictedTestCase static void printErrors(std::ostream& _stream, langutil::ErrorList const& _errors); std::string m_source; - bool m_yul = false; std::string m_optimizerStep; std::string m_expectation; diff --git a/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul index ae7c0e1140c9..79b372972a8f 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul @@ -8,7 +8,7 @@ } // ==== // step: disambiguator -// yul: true +// dialect: yul // ---- // { // { let a:u256, b:u256 } diff --git a/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul b/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul index b081ebe6f119..fe54227d35bd 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul @@ -8,7 +8,7 @@ } // ==== // step: disambiguator -// yul: true +// dialect: yul // ---- // { // { diff --git a/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul index 5dd6ac3bf59d..2dee55ae7e2f 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul @@ -7,7 +7,7 @@ } // ==== // step: disambiguator -// yul: true +// dialect: yul // ---- // { // { let a:u256, b:u256, c:u256 } diff --git a/test/libyul/yulOptimizerTests/disambiguator/long_names.yul b/test/libyul/yulOptimizerTests/disambiguator/long_names.yul index 2b9f3e522cb3..b5db97637adb 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/long_names.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/long_names.yul @@ -1,7 +1,7 @@ { { let aanteuhdaoneudbrgkjiuaothduiathudaoeuh:u256 } { let aanteuhdaoneudbrgkjiuaothduiathudaoeuh:u256 } } // ==== // step: disambiguator -// yul: true +// dialect: yul // ---- // { // { diff --git a/test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul b/test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul index d0702de6fc23..2ed2b9ad10f6 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul @@ -1,6 +1,6 @@ { } // ==== // step: disambiguator -// yul: true +// dialect: yul // ---- // { } diff --git a/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul index 497f4985c5ac..647c78fda6ea 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul @@ -9,7 +9,7 @@ } // ==== // step: disambiguator -// yul: true +// dialect: yul // ---- // { // { let a:u256, b:u256, c:u256 } diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables.yul b/test/libyul/yulOptimizerTests/disambiguator/variables.yul index 2d3318702970..319809706808 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/variables.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/variables.yul @@ -1,7 +1,7 @@ { { let a:u256 } { let a:u256 } } // ==== // step: disambiguator -// yul: true +// dialect: yul // ---- // { // { let a:u256 } diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul b/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul index 9501b8a1c97b..9474dfc86cb8 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul @@ -1,7 +1,7 @@ { { let a:u256 let a_1:u256 } { let a:u256 } } // ==== // step: disambiguator -// yul: true +// dialect: yul // ---- // { // { diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul b/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul index b160f032c390..66d36e43120b 100644 --- a/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul +++ b/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul @@ -7,7 +7,7 @@ } // ==== // step: disambiguator -// yul: true +// dialect: yul // ---- // { // { diff --git a/test/libyul/yulOptimizerTests/expressionInliner/simple.yul b/test/libyul/yulOptimizerTests/expressionInliner/simple.yul index 4302da79f67d..c1a1c147e222 100644 --- a/test/libyul/yulOptimizerTests/expressionInliner/simple.yul +++ b/test/libyul/yulOptimizerTests/expressionInliner/simple.yul @@ -4,7 +4,7 @@ } // ==== // step: expressionInliner -// yul: true +// dialect: yul // ---- // { // function f() -> x:u256 diff --git a/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul b/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul index 2bdd8ffd886b..8dd694aec5af 100644 --- a/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul +++ b/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul @@ -4,7 +4,7 @@ } // ==== // step: expressionInliner -// yul: true +// dialect: yul // ---- // { // function f(a:u256) -> x:u256 diff --git a/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul b/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul index 51699b7a8dbd..950118647507 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul @@ -1,7 +1,7 @@ { let a:u256 { } function f() -> x:bool { let b:u256 := 4:u256 {} for {} f() {} {} } } // ==== // step: functionGrouper -// yul: true +// dialect: yul // ---- // { // { diff --git a/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul b/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul index 73af943aad04..559452a98a19 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul @@ -6,7 +6,7 @@ } // ==== // step: functionGrouper -// yul: true +// dialect: yul // ---- // { // { diff --git a/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul b/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul index ac67a4461312..14b28fbabb8d 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul @@ -10,7 +10,7 @@ } // ==== // step: functionGrouper -// yul: true +// dialect: yul // ---- // { // { let a:u256 } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul b/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul index ec72697a757d..94af922877e9 100644 --- a/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul +++ b/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul @@ -3,7 +3,7 @@ } // ==== // step: functionGrouper -// yul: true +// dialect: yul // ---- // { // { let a:u256 } diff --git a/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul b/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul index 4d3b90d45af1..4a7c0a7a22a4 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul @@ -9,7 +9,7 @@ } // ==== // step: functionHoister -// yul: true +// dialect: yul // ---- // { // let a:u256 diff --git a/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul b/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul index 7d41d59e7401..78e4b49aba87 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul @@ -7,7 +7,7 @@ } // ==== // step: functionHoister -// yul: true +// dialect: yul // ---- // { // let a:u256 diff --git a/test/libyul/yulOptimizerTests/functionHoister/nested.yul b/test/libyul/yulOptimizerTests/functionHoister/nested.yul index 50d96290710e..8135985037a5 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/nested.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/nested.yul @@ -8,7 +8,7 @@ } // ==== // step: functionHoister -// yul: true +// dialect: yul // ---- // { // let a:u256 diff --git a/test/libyul/yulOptimizerTests/functionHoister/single.yul b/test/libyul/yulOptimizerTests/functionHoister/single.yul index 70c3ecb3db48..70ecfdb8e082 100644 --- a/test/libyul/yulOptimizerTests/functionHoister/single.yul +++ b/test/libyul/yulOptimizerTests/functionHoister/single.yul @@ -4,7 +4,7 @@ } // ==== // step: functionHoister -// yul: true +// dialect: yul // ---- // { // let a:u256 diff --git a/test/libyul/yulOptimizerTests/mainFunction/empty_block.yul b/test/libyul/yulOptimizerTests/mainFunction/empty_block.yul index efe904d89db4..09a04e1d3734 100644 --- a/test/libyul/yulOptimizerTests/mainFunction/empty_block.yul +++ b/test/libyul/yulOptimizerTests/mainFunction/empty_block.yul @@ -9,7 +9,7 @@ } // ==== // step: mainFunction -// yul: true +// dialect: yul // ---- // { // function main() diff --git a/test/libyul/yulOptimizerTests/mainFunction/multi_fun_mixed.yul b/test/libyul/yulOptimizerTests/mainFunction/multi_fun_mixed.yul index 2f4de38b6e4d..7aaab11e5a0f 100644 --- a/test/libyul/yulOptimizerTests/mainFunction/multi_fun_mixed.yul +++ b/test/libyul/yulOptimizerTests/mainFunction/multi_fun_mixed.yul @@ -7,7 +7,7 @@ } // ==== // step: mainFunction -// yul: true +// dialect: yul // ---- // { // function main() diff --git a/test/libyul/yulOptimizerTests/mainFunction/nested_fun.yul b/test/libyul/yulOptimizerTests/mainFunction/nested_fun.yul index 2c9d120b3c55..61cb672333a0 100644 --- a/test/libyul/yulOptimizerTests/mainFunction/nested_fun.yul +++ b/test/libyul/yulOptimizerTests/mainFunction/nested_fun.yul @@ -8,7 +8,7 @@ } // ==== // step: mainFunction -// yul: true +// dialect: yul // ---- // { // function main() diff --git a/test/libyul/yulOptimizerTests/mainFunction/sigle_fun.yul b/test/libyul/yulOptimizerTests/mainFunction/sigle_fun.yul index c7de4344118a..63154e8c3ffb 100644 --- a/test/libyul/yulOptimizerTests/mainFunction/sigle_fun.yul +++ b/test/libyul/yulOptimizerTests/mainFunction/sigle_fun.yul @@ -4,7 +4,7 @@ } // ==== // step: mainFunction -// yul: true +// dialect: yul // ---- // { // function main() diff --git a/test/libyul/yulOptimizerTests/mainFunction/smoke.yul b/test/libyul/yulOptimizerTests/mainFunction/smoke.yul index 3ae7cb5f743e..54ad2d843e7f 100644 --- a/test/libyul/yulOptimizerTests/mainFunction/smoke.yul +++ b/test/libyul/yulOptimizerTests/mainFunction/smoke.yul @@ -1,7 +1,7 @@ {} // ==== // step: mainFunction -// yul: true +// dialect: yul // ---- // { // function main() From 47a8e5fbd138b2ab55adcec41edd502c69dc7512 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 18 Dec 2019 22:54:34 +0000 Subject: [PATCH 13/36] Fix getExternalCodeSize in the Yul Ewasm interpreter --- test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp index a35a6f491682..0dd1d75385b1 100644 --- a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp +++ b/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp @@ -286,7 +286,8 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a return 0; } else if (_fun == "eth.getExternalCodeSize"_yulstring) - return u256(keccak256(h256(readAddress(arg[0])))) & 0xffffff; + // Generate "random" code length. Make sure it fits the page size. + return u256(keccak256(h256(readAddress(arg[0])))) & 0xfff; else if (_fun == "eth.getGasLeft"_yulstring) return 0x99; else if (_fun == "eth.getBlockGasLimit"_yulstring) From 65e59ecd0606e10aadfd423f07ca0457a7a198e6 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Mon, 9 Dec 2019 16:36:12 +0000 Subject: [PATCH 14/36] Rename EWasm/ewasm/eWasm to Ewasm --- libsolidity/interface/CompilerStack.cpp | 34 +++++++------- libsolidity/interface/CompilerStack.h | 22 ++++----- libsolidity/interface/StandardCompiler.cpp | 14 +++--- libyul/AssemblyStack.cpp | 10 ++-- libyul/AssemblyStack.h | 8 ++-- libyul/backends/wasm/BinaryTransform.cpp | 2 +- libyul/backends/wasm/BinaryTransform.h | 2 +- libyul/backends/wasm/TextTransform.cpp | 2 +- libyul/backends/wasm/TextTransform.h | 2 +- solc/CommandLineInterface.cpp | 53 +++++++++++----------- solc/CommandLineInterface.h | 2 +- test/cmdlineTests/evm_to_wasm/output | 2 +- 12 files changed, 76 insertions(+), 77 deletions(-) diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 4cb085883ec8..73824297e909 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -77,7 +77,7 @@ CompilerStack::CompilerStack(ReadCallback::Callback const& _readFile): m_readFile{_readFile}, m_enabledSMTSolvers{smt::SMTSolverChoice::All()}, m_generateIR{false}, - m_generateEWasm{false}, + m_generateEwasm{false}, m_errorList{}, m_errorReporter{m_errorList} { @@ -200,7 +200,7 @@ void CompilerStack::reset(bool _keepSettings) m_evmVersion = langutil::EVMVersion(); m_enabledSMTSolvers = smt::SMTSolverChoice::All(); m_generateIR = false; - m_generateEWasm = false; + m_generateEwasm = false; m_revertStrings = RevertStrings::Default; m_optimiserSettings = OptimiserSettings::minimal(); m_metadataLiteralSources = false; @@ -463,10 +463,10 @@ bool CompilerStack::compile() if (isRequestedContract(*contract)) { compileContract(*contract, otherCompilers); - if (m_generateIR || m_generateEWasm) + if (m_generateIR || m_generateEwasm) generateIR(*contract); - if (m_generateEWasm) - generateEWasm(*contract); + if (m_generateEwasm) + generateEwasm(*contract); } m_stackState = CompilationSuccessful; this->link(); @@ -592,20 +592,20 @@ string const& CompilerStack::yulIROptimized(string const& _contractName) const return contract(_contractName).yulIROptimized; } -string const& CompilerStack::eWasm(string const& _contractName) const +string const& CompilerStack::ewasm(string const& _contractName) const { if (m_stackState != CompilationSuccessful) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Compilation was not successful.")); - return contract(_contractName).eWasm; + return contract(_contractName).ewasm; } -eth::LinkerObject const& CompilerStack::eWasmObject(string const& _contractName) const +eth::LinkerObject const& CompilerStack::ewasmObject(string const& _contractName) const { if (m_stackState != CompilationSuccessful) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Compilation was not successful.")); - return contract(_contractName).eWasmObject; + return contract(_contractName).ewasmObject; } eth::LinkerObject const& CompilerStack::object(string const& _contractName) const @@ -1069,15 +1069,15 @@ void CompilerStack::generateIR(ContractDefinition const& _contract) tie(compiledContract.yulIR, compiledContract.yulIROptimized) = generator.run(_contract); } -void CompilerStack::generateEWasm(ContractDefinition const& _contract) +void CompilerStack::generateEwasm(ContractDefinition const& _contract) { solAssert(m_stackState >= AnalysisPerformed, ""); if (m_hasError) - BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Called generateEWasm with errors.")); + BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Called generateEwasm with errors.")); Contract& compiledContract = m_contracts.at(_contract.fullyQualifiedName()); solAssert(!compiledContract.yulIROptimized.empty(), ""); - if (!compiledContract.eWasm.empty()) + if (!compiledContract.ewasm.empty()) return; // Re-parse the Yul IR in EVM dialect @@ -1085,15 +1085,15 @@ void CompilerStack::generateEWasm(ContractDefinition const& _contract) stack.parseAndAnalyze("", compiledContract.yulIROptimized); stack.optimize(); - stack.translate(yul::AssemblyStack::Language::EWasm); + stack.translate(yul::AssemblyStack::Language::Ewasm); stack.optimize(); //cout << yul::AsmPrinter{}(*stack.parserResult()->code) << endl; - // Turn into eWasm text representation. - auto result = stack.assemble(yul::AssemblyStack::Machine::eWasm); - compiledContract.eWasm = std::move(result.assembly); - compiledContract.eWasmObject = std::move(*result.bytecode); + // Turn into Ewasm text representation. + auto result = stack.assemble(yul::AssemblyStack::Machine::Ewasm); + compiledContract.ewasm = std::move(result.assembly); + compiledContract.ewasmObject = std::move(*result.bytecode); } CompilerStack::Contract const& CompilerStack::contract(string const& _contractName) const diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h index 3133acfe8baf..9f4f42348c98 100644 --- a/libsolidity/interface/CompilerStack.h +++ b/libsolidity/interface/CompilerStack.h @@ -178,8 +178,8 @@ class CompilerStack: boost::noncopyable /// Enable experimental generation of Yul IR code. void enableIRGeneration(bool _enable = true) { m_generateIR = _enable; } - /// Enable experimental generation of eWasm code. If enabled, IR is also generated. - void enableEWasmGeneration(bool _enable = true) { m_generateEWasm = _enable; } + /// Enable experimental generation of Ewasm code. If enabled, IR is also generated. + void enableEwasmGeneration(bool _enable = true) { m_generateEwasm = _enable; } /// @arg _metadataLiteralSources When true, store sources as literals in the contract metadata. /// Must be set before parsing. @@ -251,11 +251,11 @@ class CompilerStack: boost::noncopyable /// @returns the optimized IR representation of a contract. std::string const& yulIROptimized(std::string const& _contractName) const; - /// @returns the eWasm text representation of a contract. - std::string const& eWasm(std::string const& _contractName) const; + /// @returns the Ewasm text representation of a contract. + std::string const& ewasm(std::string const& _contractName) const; - /// @returns the eWasm representation of a contract. - eth::LinkerObject const& eWasmObject(std::string const& _contractName) const; + /// @returns the Ewasm representation of a contract. + eth::LinkerObject const& ewasmObject(std::string const& _contractName) const; /// @returns the assembled object for a contract. eth::LinkerObject const& object(std::string const& _contractName) const; @@ -338,8 +338,8 @@ class CompilerStack: boost::noncopyable eth::LinkerObject runtimeObject; ///< Runtime object. std::string yulIR; ///< Experimental Yul IR code. std::string yulIROptimized; ///< Optimized experimental Yul IR code. - std::string eWasm; ///< Experimental eWasm text representation - eth::LinkerObject eWasmObject; ///< Experimental eWasm code + std::string ewasm; ///< Experimental Ewasm text representation + eth::LinkerObject ewasmObject; ///< Experimental Ewasm code mutable std::unique_ptr metadata; ///< The metadata json that will be hashed into the chain. mutable std::unique_ptr abi; mutable std::unique_ptr storageLayout; @@ -374,8 +374,8 @@ class CompilerStack: boost::noncopyable /// The IR is stored but otherwise unused. void generateIR(ContractDefinition const& _contract); - /// Generate eWasm representation for a single contract. - void generateEWasm(ContractDefinition const& _contract); + /// Generate Ewasm representation for a single contract. + void generateEwasm(ContractDefinition const& _contract); /// Links all the known library addresses in the available objects. Any unknown /// library will still be kept as an unlinked placeholder in the objects. @@ -436,7 +436,7 @@ class CompilerStack: boost::noncopyable smt::SMTSolverChoice m_enabledSMTSolvers; std::map> m_requestedContractNames; bool m_generateIR; - bool m_generateEWasm; + bool m_generateEwasm; std::map m_libraries; /// list of path prefix remappings, e.g. mylibrary: github.com/ethereum = /usr/local/ethereum /// "context:prefix=target" diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 25f6a5199fca..a7162348caf5 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -247,9 +247,9 @@ bool isBinaryRequested(Json::Value const& _outputSelection) return false; } -/// @returns true if any eWasm code was requested. Note that as an exception, '*' does not +/// @returns true if any Ewasm code was requested. Note that as an exception, '*' does not /// yet match "ewasm.wast" or "ewasm" -bool isEWasmRequested(Json::Value const& _outputSelection) +bool isEwasmRequested(Json::Value const& _outputSelection) { if (!_outputSelection.isObject()) return false; @@ -267,7 +267,7 @@ bool isEWasmRequested(Json::Value const& _outputSelection) /// yet match "ir" or "irOptimized" bool isIRRequested(Json::Value const& _outputSelection) { - if (isEWasmRequested(_outputSelection)) + if (isEwasmRequested(_outputSelection)) return true; if (!_outputSelection.isObject()) @@ -780,7 +780,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting compilerStack.enableIRGeneration(isIRRequested(_inputsAndSettings.outputSelection)); - compilerStack.enableEWasmGeneration(isEWasmRequested(_inputsAndSettings.outputSelection)); + compilerStack.enableEwasmGeneration(isEwasmRequested(_inputsAndSettings.outputSelection)); Json::Value errors = std::move(_inputsAndSettings.errors); @@ -956,11 +956,11 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "irOptimized", wildcardMatchesExperimental)) contractData["irOptimized"] = compilerStack.yulIROptimized(contractName); - // eWasm + // Ewasm if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "ewasm.wast", wildcardMatchesExperimental)) - contractData["ewasm"]["wast"] = compilerStack.eWasm(contractName); + contractData["ewasm"]["wast"] = compilerStack.ewasm(contractName); if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "ewasm.wasm", wildcardMatchesExperimental)) - contractData["ewasm"]["wasm"] = compilerStack.eWasmObject(contractName).toHex(); + contractData["ewasm"]["wasm"] = compilerStack.ewasmObject(contractName).toHex(); // EVM Json::Value evmData(Json::objectValue); diff --git a/libyul/AssemblyStack.cpp b/libyul/AssemblyStack.cpp index dcc9b887a865..4b6d71692e24 100644 --- a/libyul/AssemblyStack.cpp +++ b/libyul/AssemblyStack.cpp @@ -16,7 +16,7 @@ */ /** * Full assembly stack that can support EVM-assembly and Yul as input and EVM, EVM1.5 and - * eWasm as output. + * Ewasm as output. */ @@ -59,7 +59,7 @@ Dialect const& languageToDialect(AssemblyStack::Language _language, EVMVersion _ return EVMDialect::strictAssemblyForEVMObjects(_version); case AssemblyStack::Language::Yul: return Dialect::yul(); - case AssemblyStack::Language::EWasm: + case AssemblyStack::Language::Ewasm: return WasmDialect::instance(); } yulAssert(false, ""); @@ -108,7 +108,7 @@ void AssemblyStack::translate(AssemblyStack::Language _targetLanguage) return; solAssert( - m_language == Language::StrictAssembly && _targetLanguage == Language::EWasm, + m_language == Language::StrictAssembly && _targetLanguage == Language::Ewasm, "Invalid language combination" ); @@ -214,9 +214,9 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const /// TODO: fill out text representation return object; } - case Machine::eWasm: + case Machine::Ewasm: { - yulAssert(m_language == Language::EWasm, ""); + yulAssert(m_language == Language::Ewasm, ""); Dialect const& dialect = languageToDialect(m_language, EVMVersion{}); MachineAssemblyObject object; diff --git a/libyul/AssemblyStack.h b/libyul/AssemblyStack.h index a6dcd0b37236..6c3549331a6e 100644 --- a/libyul/AssemblyStack.h +++ b/libyul/AssemblyStack.h @@ -16,7 +16,7 @@ */ /** * Full assembly stack that can support EVM-assembly and Yul as input and EVM, EVM1.5 and - * eWasm as output. + * Ewasm as output. */ #pragma once @@ -52,13 +52,13 @@ struct MachineAssemblyObject /* * Full assembly stack that can support EVM-assembly and Yul as input and EVM, EVM1.5 and - * eWasm as output. + * Ewasm as output. */ class AssemblyStack { public: - enum class Language { Yul, Assembly, StrictAssembly, EWasm }; - enum class Machine { EVM, EVM15, eWasm }; + enum class Language { Yul, Assembly, StrictAssembly, Ewasm }; + enum class Machine { EVM, EVM15, Ewasm }; AssemblyStack(): AssemblyStack(langutil::EVMVersion{}, Language::Assembly, dev::solidity::OptimiserSettings::none()) diff --git a/libyul/backends/wasm/BinaryTransform.cpp b/libyul/backends/wasm/BinaryTransform.cpp index b87ab0c1916f..1dee4daeef6b 100644 --- a/libyul/backends/wasm/BinaryTransform.cpp +++ b/libyul/backends/wasm/BinaryTransform.cpp @@ -15,7 +15,7 @@ along with solidity. If not, see . */ /** - * EWasm to binary encoder. + * Component that transforms internal Wasm representation to binary. */ #include diff --git a/libyul/backends/wasm/BinaryTransform.h b/libyul/backends/wasm/BinaryTransform.h index b57943af197c..132f38ca24f0 100644 --- a/libyul/backends/wasm/BinaryTransform.h +++ b/libyul/backends/wasm/BinaryTransform.h @@ -15,7 +15,7 @@ along with solidity. If not, see . */ /** - * EWasm to binary encoder. + * Component that transforms internal Wasm representation to binary. */ #pragma once diff --git a/libyul/backends/wasm/TextTransform.cpp b/libyul/backends/wasm/TextTransform.cpp index f3589f5e904c..49e617e55d3f 100644 --- a/libyul/backends/wasm/TextTransform.cpp +++ b/libyul/backends/wasm/TextTransform.cpp @@ -15,7 +15,7 @@ along with solidity. If not, see . */ /** - * Component that transforms interval Wasm representation to text. + * Component that transforms internal Wasm representation to text. */ #include diff --git a/libyul/backends/wasm/TextTransform.h b/libyul/backends/wasm/TextTransform.h index 602a67fe147f..2424939a8cbb 100644 --- a/libyul/backends/wasm/TextTransform.h +++ b/libyul/backends/wasm/TextTransform.h @@ -15,7 +15,7 @@ along with solidity. If not, see . */ /** - * Component that transforms interval Wasm representation to text. + * Component that transforms internal Wasm representation to text. */ #pragma once diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 6834e62ff188..ab6ef0840397 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -116,7 +116,7 @@ static string const g_strErrorRecovery = "error-recovery"; static string const g_strEVM = "evm"; static string const g_strEVM15 = "evm15"; static string const g_strEVMVersion = "evm-version"; -static string const g_streWasm = "ewasm"; +static string const g_strEwasm = "ewasm"; static string const g_strGas = "gas"; static string const g_strHelp = "help"; static string const g_strInputFile = "input-file"; @@ -125,7 +125,6 @@ static string const g_strYul = "yul"; static string const g_strYulDialect = "yul-dialect"; static string const g_strIR = "ir"; static string const g_strIPFS = "ipfs"; -static string const g_strEWasm = "ewasm"; static string const g_strLicense = "license"; static string const g_strLibraries = "libraries"; static string const g_strLink = "link"; @@ -187,7 +186,7 @@ static string const g_argHelp = g_strHelp; static string const g_argInputFile = g_strInputFile; static string const g_argYul = g_strYul; static string const g_argIR = g_strIR; -static string const g_argEWasm = g_strEWasm; +static string const g_argEwasm = g_strEwasm; static string const g_argLibraries = g_strLibraries; static string const g_argLink = g_strLink; static string const g_argMachine = g_strMachine; @@ -234,14 +233,14 @@ static set const g_machineArgs { g_strEVM, g_strEVM15, - g_streWasm + g_strEwasm }; /// Possible arguments to for --yul-dialect static set const g_yulDialectArgs { g_strEVM, - g_streWasm + g_strEwasm }; /// Possible arguments to for --metadata-hash @@ -345,23 +344,23 @@ void CommandLineInterface::handleIR(string const& _contractName) } } -void CommandLineInterface::handleEWasm(string const& _contractName) +void CommandLineInterface::handleEwasm(string const& _contractName) { - if (m_args.count(g_argEWasm)) + if (m_args.count(g_argEwasm)) { if (m_args.count(g_argOutputDir)) { - createFile(m_compiler->filesystemFriendlyName(_contractName) + ".wast", m_compiler->eWasm(_contractName)); + createFile(m_compiler->filesystemFriendlyName(_contractName) + ".wast", m_compiler->ewasm(_contractName)); createFile( m_compiler->filesystemFriendlyName(_contractName) + ".wasm", - asString(m_compiler->eWasmObject(_contractName).bytecode) + asString(m_compiler->ewasmObject(_contractName).bytecode) ); } else { - sout() << "EWasm text:" << endl; - sout() << m_compiler->eWasm(_contractName) << endl; - sout() << "EWasm binary (hex): " << m_compiler->eWasmObject(_contractName).toHex() << endl; + sout() << "Ewasm text:" << endl; + sout() << m_compiler->ewasm(_contractName) << endl; + sout() << "Ewasm binary (hex): " << m_compiler->ewasmObject(_contractName).toHex() << endl; } } } @@ -776,7 +775,7 @@ Allowed options)", (g_argBinaryRuntime.c_str(), "Binary of the runtime part of the contracts in hex.") (g_argAbi.c_str(), "ABI specification of the contracts.") (g_argIR.c_str(), "Intermediate Representation (IR) of all contracts (EXPERIMENTAL).") - (g_argEWasm.c_str(), "EWasm text representation of all contracts (EXPERIMENTAL).") + (g_argEwasm.c_str(), "Ewasm text representation of all contracts (EXPERIMENTAL).") (g_argSignatureHashes.c_str(), "Function signature hashes of the contracts.") (g_argNatspecUser.c_str(), "Natspec user documentation of all contracts.") (g_argNatspecDev.c_str(), "Natspec developer documentation of all contracts.") @@ -981,27 +980,27 @@ bool CommandLineInterface::processInput() targetMachine = Machine::EVM; else if (machine == g_strEVM15) targetMachine = Machine::EVM15; - else if (machine == g_streWasm) - targetMachine = Machine::eWasm; + else if (machine == g_strEwasm) + targetMachine = Machine::Ewasm; else { serr() << "Invalid option for --machine: " << machine << endl; return false; } } - if (targetMachine == Machine::eWasm && inputLanguage == Input::StrictAssembly) - inputLanguage = Input::EWasm; + if (targetMachine == Machine::Ewasm && inputLanguage == Input::StrictAssembly) + inputLanguage = Input::Ewasm; if (m_args.count(g_strYulDialect)) { string dialect = m_args[g_strYulDialect].as(); if (dialect == g_strEVM) inputLanguage = Input::StrictAssembly; - else if (dialect == g_streWasm) + else if (dialect == g_strEwasm) { - inputLanguage = Input::EWasm; - if (targetMachine != Machine::eWasm) + inputLanguage = Input::Ewasm; + if (targetMachine != Machine::Ewasm) { - serr() << "If you select eWasm as --yul-dialect, --machine has to be eWasm as well." << endl; + serr() << "If you select Ewasm as --yul-dialect, --machine has to be Ewasm as well." << endl; return false; } } @@ -1011,7 +1010,7 @@ bool CommandLineInterface::processInput() return false; } } - if (optimize && (inputLanguage != Input::StrictAssembly && inputLanguage != Input::EWasm)) + if (optimize && (inputLanguage != Input::StrictAssembly && inputLanguage != Input::Ewasm)) { serr() << "Optimizer can only be used for strict assembly. Use --" << @@ -1074,7 +1073,7 @@ bool CommandLineInterface::processInput() // TODO: Perhaps we should not compile unless requested m_compiler->enableIRGeneration(m_args.count(g_argIR)); - m_compiler->enableEWasmGeneration(m_args.count(g_argEWasm)); + m_compiler->enableEwasmGeneration(m_args.count(g_argEwasm)); OptimiserSettings settings = m_args.count(g_argOptimize) ? OptimiserSettings::standard() : OptimiserSettings::minimal(); settings.expectedExecutionsPerDeployment = m_args[g_argOptimizeRuns].as(); @@ -1453,7 +1452,7 @@ bool CommandLineInterface::assemble( string machine = _targetMachine == yul::AssemblyStack::Machine::EVM ? "EVM" : _targetMachine == yul::AssemblyStack::Machine::EVM15 ? "EVM 1.5" : - "eWasm"; + "Ewasm"; sout() << endl << "======= " << src.first << " (" << machine << ") =======" << endl; yul::AssemblyStack& stack = assemblyStacks[src.first]; @@ -1461,9 +1460,9 @@ bool CommandLineInterface::assemble( sout() << endl << "Pretty printed source:" << endl; sout() << stack.print() << endl; - if (_language != yul::AssemblyStack::Language::EWasm && _targetMachine == yul::AssemblyStack::Machine::eWasm) + if (_language != yul::AssemblyStack::Language::Ewasm && _targetMachine == yul::AssemblyStack::Machine::Ewasm) { - stack.translate(yul::AssemblyStack::Language::EWasm); + stack.translate(yul::AssemblyStack::Language::Ewasm); stack.optimize(); sout() << endl << "==========================" << endl; @@ -1554,7 +1553,7 @@ void CommandLineInterface::outputCompilationResults() handleBytecode(contract); handleIR(contract); - handleEWasm(contract); + handleEwasm(contract); handleSignatureHashes(contract); handleMetadata(contract); handleABI(contract); diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index cca76c53f7e7..02fda03831db 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -67,7 +67,7 @@ class CommandLineInterface void handleBinary(std::string const& _contract); void handleOpcode(std::string const& _contract); void handleIR(std::string const& _contract); - void handleEWasm(std::string const& _contract); + void handleEwasm(std::string const& _contract); void handleBytecode(std::string const& _contract); void handleSignatureHashes(std::string const& _contract); void handleMetadata(std::string const& _contract); diff --git a/test/cmdlineTests/evm_to_wasm/output b/test/cmdlineTests/evm_to_wasm/output index 3b1e0fab7434..a85239b230df 100644 --- a/test/cmdlineTests/evm_to_wasm/output +++ b/test/cmdlineTests/evm_to_wasm/output @@ -1,5 +1,5 @@ -======= evm_to_wasm/input.sol (eWasm) ======= +======= evm_to_wasm/input.sol (Ewasm) ======= Pretty printed source: object "object" { From 9c27e98b83964ff5be09a48afe28c36653e524a6 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Thu, 12 Dec 2019 12:57:07 +0000 Subject: [PATCH 15/36] Rename EWasmBuiltinInterpreter to EwasmBuiltinInterpreter --- test/tools/yulInterpreter/CMakeLists.txt | 4 ++-- ...preter.cpp => EwasmBuiltinInterpreter.cpp} | 24 +++++++++---------- ...nterpreter.h => EwasmBuiltinInterpreter.h} | 8 +++---- test/tools/yulInterpreter/Interpreter.cpp | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) rename test/tools/yulInterpreter/{EWasmBuiltinInterpreter.cpp => EwasmBuiltinInterpreter.cpp} (93%) rename test/tools/yulInterpreter/{EWasmBuiltinInterpreter.h => EwasmBuiltinInterpreter.h} (94%) diff --git a/test/tools/yulInterpreter/CMakeLists.txt b/test/tools/yulInterpreter/CMakeLists.txt index 02d53d69764b..95f4c3f3d43a 100644 --- a/test/tools/yulInterpreter/CMakeLists.txt +++ b/test/tools/yulInterpreter/CMakeLists.txt @@ -1,8 +1,8 @@ set(sources EVMInstructionInterpreter.h EVMInstructionInterpreter.cpp - EWasmBuiltinInterpreter.h - EWasmBuiltinInterpreter.cpp + EwasmBuiltinInterpreter.h + EwasmBuiltinInterpreter.cpp Interpreter.h Interpreter.cpp ) diff --git a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp b/test/tools/yulInterpreter/EwasmBuiltinInterpreter.cpp similarity index 93% rename from test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp rename to test/tools/yulInterpreter/EwasmBuiltinInterpreter.cpp index 0dd1d75385b1..1f1ed9e60bcd 100644 --- a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.cpp +++ b/test/tools/yulInterpreter/EwasmBuiltinInterpreter.cpp @@ -15,10 +15,10 @@ along with solidity. If not, see . */ /** - * Yul interpreter module that evaluates EWasm builtins. + * Yul interpreter module that evaluates Ewasm builtins. */ -#include +#include #include @@ -68,7 +68,7 @@ uint64_t clz(uint64_t _v) using u512 = boost::multiprecision::number>; -u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _arguments) +u256 EwasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _arguments) { vector arg; for (u256 const& a: _arguments) @@ -355,7 +355,7 @@ u256 EWasmBuiltinInterpreter::evalBuiltin(YulString _fun, vector const& _a return 0; } -bool EWasmBuiltinInterpreter::accessMemory(u256 const& _offset, u256 const& _size) +bool EwasmBuiltinInterpreter::accessMemory(u256 const& _offset, u256 const& _size) { if (((_offset + _size) >= _offset) && ((_offset + _size + 0x1f) >= (_offset + _size))) { @@ -369,7 +369,7 @@ bool EWasmBuiltinInterpreter::accessMemory(u256 const& _offset, u256 const& _siz return false; } -bytes EWasmBuiltinInterpreter::readMemory(uint64_t _offset, uint64_t _size) +bytes EwasmBuiltinInterpreter::readMemory(uint64_t _offset, uint64_t _size) { yulAssert(_size <= 0xffff, "Too large read."); bytes data(size_t(_size), uint8_t(0)); @@ -378,7 +378,7 @@ bytes EWasmBuiltinInterpreter::readMemory(uint64_t _offset, uint64_t _size) return data; } -uint64_t EWasmBuiltinInterpreter::readMemoryWord(uint64_t _offset) +uint64_t EwasmBuiltinInterpreter::readMemoryWord(uint64_t _offset) { uint64_t r = 0; for (size_t i = 0; i < 8; i++) @@ -386,18 +386,18 @@ uint64_t EWasmBuiltinInterpreter::readMemoryWord(uint64_t _offset) return r; } -void EWasmBuiltinInterpreter::writeMemoryWord(uint64_t _offset, uint64_t _value) +void EwasmBuiltinInterpreter::writeMemoryWord(uint64_t _offset, uint64_t _value) { for (size_t i = 0; i < 8; i++) m_state.memory[_offset + i] = uint8_t((_value >> (i * 8)) & 0xff); } -void EWasmBuiltinInterpreter::writeMemoryByte(uint64_t _offset, uint8_t _value) +void EwasmBuiltinInterpreter::writeMemoryByte(uint64_t _offset, uint8_t _value) { m_state.memory[_offset] = _value; } -void EWasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _croppedTo) +void EwasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _croppedTo) { accessMemory(_offset, _croppedTo); for (size_t i = 0; i < _croppedTo; i++) @@ -407,7 +407,7 @@ void EWasmBuiltinInterpreter::writeU256(uint64_t _offset, u256 _value, size_t _c } } -u256 EWasmBuiltinInterpreter::readU256(uint64_t _offset, size_t _croppedTo) +u256 EwasmBuiltinInterpreter::readU256(uint64_t _offset, size_t _croppedTo) { accessMemory(_offset, _croppedTo); u256 value; @@ -417,12 +417,12 @@ u256 EWasmBuiltinInterpreter::readU256(uint64_t _offset, size_t _croppedTo) return value; } -void EWasmBuiltinInterpreter::logTrace(dev::eth::Instruction _instruction, std::vector const& _arguments, bytes const& _data) +void EwasmBuiltinInterpreter::logTrace(dev::eth::Instruction _instruction, std::vector const& _arguments, bytes const& _data) { logTrace(dev::eth::instructionInfo(_instruction).name, _arguments, _data); } -void EWasmBuiltinInterpreter::logTrace(std::string const& _pseudoInstruction, std::vector const& _arguments, bytes const& _data) +void EwasmBuiltinInterpreter::logTrace(std::string const& _pseudoInstruction, std::vector const& _arguments, bytes const& _data) { string message = _pseudoInstruction + "("; for (size_t i = 0; i < _arguments.size(); ++i) diff --git a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.h b/test/tools/yulInterpreter/EwasmBuiltinInterpreter.h similarity index 94% rename from test/tools/yulInterpreter/EWasmBuiltinInterpreter.h rename to test/tools/yulInterpreter/EwasmBuiltinInterpreter.h index 363c11f453d0..a9c733f8e005 100644 --- a/test/tools/yulInterpreter/EWasmBuiltinInterpreter.h +++ b/test/tools/yulInterpreter/EwasmBuiltinInterpreter.h @@ -15,7 +15,7 @@ along with solidity. If not, see . */ /** - * Yul interpreter module that evaluates EWasm builtins. + * Yul interpreter module that evaluates Ewasm builtins. */ #pragma once @@ -45,7 +45,7 @@ namespace test struct InterpreterState; /** - * Interprets EWasm builtins based on the current state and logs instructions with + * Interprets Ewasm builtins based on the current state and logs instructions with * side-effects. * * Since this is mainly meant to be used for differential fuzz testing, it is focused @@ -63,10 +63,10 @@ struct InterpreterState; * The main focus is that the generated execution trace is the same for equivalent executions * and likely to be different for non-equivalent executions. */ -class EWasmBuiltinInterpreter +class EwasmBuiltinInterpreter { public: - explicit EWasmBuiltinInterpreter(InterpreterState& _state): + explicit EwasmBuiltinInterpreter(InterpreterState& _state): m_state(_state) {} /// Evaluate builtin function diff --git a/test/tools/yulInterpreter/Interpreter.cpp b/test/tools/yulInterpreter/Interpreter.cpp index d50c15b11f41..64f73803a4c3 100644 --- a/test/tools/yulInterpreter/Interpreter.cpp +++ b/test/tools/yulInterpreter/Interpreter.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include @@ -246,7 +246,7 @@ void ExpressionEvaluator::operator()(FunctionCall const& _funCall) else if (WasmDialect const* dialect = dynamic_cast(&m_dialect)) if (dialect->builtin(_funCall.functionName.name)) { - EWasmBuiltinInterpreter interpreter(m_state); + EwasmBuiltinInterpreter interpreter(m_state); setValue(interpreter.evalBuiltin(_funCall.functionName.name, values())); return; } From 7db88cfedde49cff2977550a326a587b96c8c40e Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 19 Dec 2019 23:22:19 +0100 Subject: [PATCH 16/36] Remove `yul::Instruction`. --- libsolidity/analysis/ViewPureChecker.cpp | 4 ---- libyul/AsmAnalysis.cpp | 10 ---------- libyul/AsmAnalysis.h | 1 - libyul/AsmData.h | 6 ------ libyul/AsmParser.h | 4 +++- libyul/backends/evm/AbstractAssembly.h | 1 - libyul/backends/evm/EVMCodeTransform.cpp | 10 ---------- libyul/backends/evm/EVMCodeTransform.h | 1 - 8 files changed, 3 insertions(+), 34 deletions(-) diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index aa97ae7bbdc5..4da77ead7733 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -43,10 +43,6 @@ class AssemblyViewPureChecker m_dialect(_dialect), m_reportMutability(_reportMutability) {} - void operator()(yul::Instruction const& _instruction) - { - checkInstruction(_instruction.location, _instruction.instruction); - } void operator()(yul::Literal const&) {} void operator()(yul::Identifier const&) {} void operator()(yul::ExpressionStatement const& _expr) diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 64b1ad4c5e70..e03ef7cb0348 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -86,16 +86,6 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, return analysisInfo; } -bool AsmAnalyzer::operator()(yul::Instruction const& _instruction) -{ - yulAssert(false, "The use of non-functional instructions is disallowed. Please use functional notation instead."); - auto const& info = instructionInfo(_instruction.instruction); - m_stackHeight += info.ret - info.args; - m_info.stackHeightInfo[&_instruction] = m_stackHeight; - warnOnInstructions(_instruction.instruction, _instruction.location); - return true; -} - bool AsmAnalyzer::operator()(Literal const& _literal) { expectValidType(_literal.type.str(), _literal.location); diff --git a/libyul/AsmAnalysis.h b/libyul/AsmAnalysis.h index 2ee77f71b4b6..b16e2bfed9ac 100644 --- a/libyul/AsmAnalysis.h +++ b/libyul/AsmAnalysis.h @@ -77,7 +77,6 @@ class AsmAnalyzer /// Asserts on failure. static AsmAnalysisInfo analyzeStrictAssertCorrect(Dialect const& _dialect, Object const& _object); - bool operator()(Instruction const&); bool operator()(Literal const& _literal); bool operator()(Identifier const&); bool operator()(ExpressionStatement const&); diff --git a/libyul/AsmData.h b/libyul/AsmData.h index c80fa7cfa360..5c7a058b5bdd 100644 --- a/libyul/AsmData.h +++ b/libyul/AsmData.h @@ -25,12 +25,8 @@ #include #include -#include #include -#include - -#include #include namespace yul @@ -41,8 +37,6 @@ using Type = YulString; struct TypedName { langutil::SourceLocation location; YulString name; Type type; }; using TypedNameList = std::vector; -/// Direct EVM instruction (except PUSHi and JUMPDEST) -struct Instruction { langutil::SourceLocation location; dev::eth::Instruction instruction; }; /// Literal number or string (up to 32 bytes) enum class LiteralKind { Number, Boolean, String }; struct Literal { langutil::SourceLocation location; LiteralKind kind; YulString value; Type type; }; diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index 5438494cdd3c..0967828f3362 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -56,7 +58,7 @@ class Parser: public langutil::ParserBase static std::map const& instructions(); protected: - using ElementaryOperation = std::variant; + using ElementaryOperation = std::variant; /// Creates an inline assembly node with the given source location. template T createWithLocation(langutil::SourceLocation const& _loc = {}) const diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index 0d9a558df313..ad4a757e2f7d 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -43,7 +43,6 @@ enum class Instruction: uint8_t; namespace yul { -struct Instruction; struct Identifier; /// diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index 51b31aae5c0e..ba2561e0bf6b 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -350,16 +350,6 @@ void CodeTransform::operator()(Literal const& _literal) checkStackHeight(&_literal); } -void CodeTransform::operator()(yul::Instruction const& _instruction) -{ - yulAssert(!m_allowStackOpt, ""); - yulAssert(!m_evm15 || _instruction.instruction != dev::eth::Instruction::JUMP, "Bare JUMP instruction used for EVM1.5"); - yulAssert(!m_evm15 || _instruction.instruction != dev::eth::Instruction::JUMPI, "Bare JUMPI instruction used for EVM1.5"); - m_assembly.setSourceLocation(_instruction.location); - m_assembly.appendInstruction(_instruction.instruction); - checkStackHeight(&_instruction); -} - void CodeTransform::operator()(If const& _if) { visitExpression(*_if.condition); diff --git a/libyul/backends/evm/EVMCodeTransform.h b/libyul/backends/evm/EVMCodeTransform.h index 6cf6bb3076fb..d0615faf111b 100644 --- a/libyul/backends/evm/EVMCodeTransform.h +++ b/libyul/backends/evm/EVMCodeTransform.h @@ -170,7 +170,6 @@ class CodeTransform void deleteVariable(Scope::Variable const& _var); public: - void operator()(Instruction const& _instruction); void operator()(Literal const& _literal); void operator()(Identifier const& _identifier); void operator()(FunctionCall const&); From bc71f6146772b5b239f7791801177237a9c3b48a Mon Sep 17 00:00:00 2001 From: Jason Cobb Date: Thu, 19 Dec 2019 18:01:43 -0500 Subject: [PATCH 17/36] Add ScopableAnnotation --- libsolidity/ast/ASTAnnotations.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 6d3c890927ab..268532976b10 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -75,6 +75,13 @@ struct SourceUnitAnnotation: ASTAnnotation std::set experimentalFeatures; }; +struct ScopableAnnotation +{ + /// The scope this declaration resides in. Can be nullptr if it is the global scope. + /// Available only after name and type resolution step. + ASTNode const* scope = nullptr; +}; + struct ImportAnnotation: ASTAnnotation { /// The absolute path of the source unit to import. From be14d5f28d0cc71f5e6a12c4c3bd81678f49a252 Mon Sep 17 00:00:00 2001 From: Jason Cobb Date: Thu, 19 Dec 2019 18:04:46 -0500 Subject: [PATCH 18/36] Add DeclarationAnnotation --- libsolidity/ast/AST.cpp | 7 +++++++ libsolidity/ast/AST.h | 2 ++ libsolidity/ast/ASTAnnotations.h | 4 ++++ 3 files changed, 13 insertions(+) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 140fe7a993e0..cd8a66ad789a 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -449,6 +449,13 @@ string Scopable::sourceUnitName() const return sourceUnit().annotation().path; } +DeclarationAnnotation& Declaration::annotation() const +{ + if (!m_annotation) + m_annotation = make_unique(); + return dynamic_cast(*m_annotation); +} + bool VariableDeclaration::isLValue() const { // Constant declared variables are Read-Only diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index f761fe7afcf9..871760a41f11 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -231,6 +231,8 @@ class Declaration: public ASTNode, public Scopable /// @returns null when it is not accessible as a function. virtual FunctionTypePointer functionType(bool /*_internal*/) const { return {}; } + DeclarationAnnotation& annotation() const override; + protected: virtual Visibility defaultVisibility() const { return Visibility::Public; } diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 268532976b10..8fa02a3fece6 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -82,6 +82,10 @@ struct ScopableAnnotation ASTNode const* scope = nullptr; }; +struct DeclarationAnnotation: ASTAnnotation, ScopableAnnotation +{ +}; + struct ImportAnnotation: ASTAnnotation { /// The absolute path of the source unit to import. From 30b1b39901befd2f7e911ee9083c27f6b52eb07e Mon Sep 17 00:00:00 2001 From: Jason Cobb Date: Thu, 19 Dec 2019 18:14:53 -0500 Subject: [PATCH 19/36] Have other annotations subclass DeclarationAnnotation --- libsolidity/ast/ASTAnnotations.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 8fa02a3fece6..107da87f5eb9 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -86,7 +86,7 @@ struct DeclarationAnnotation: ASTAnnotation, ScopableAnnotation { }; -struct ImportAnnotation: ASTAnnotation +struct ImportAnnotation: DeclarationAnnotation { /// The absolute path of the source unit to import. std::string absolutePath; @@ -94,7 +94,7 @@ struct ImportAnnotation: ASTAnnotation SourceUnit const* sourceUnit = nullptr; }; -struct TypeDeclarationAnnotation: ASTAnnotation +struct TypeDeclarationAnnotation: DeclarationAnnotation { /// The name of this type, prefixed by proper namespaces if globally accessible. std::string canonicalName; @@ -115,7 +115,7 @@ struct ContractDefinitionAnnotation: TypeDeclarationAnnotation, DocumentedAnnota std::map baseConstructorArguments; }; -struct CallableDeclarationAnnotation: ASTAnnotation +struct CallableDeclarationAnnotation: DeclarationAnnotation { /// The set of functions/modifiers/events this callable overrides. std::set baseFunctions; @@ -135,7 +135,7 @@ struct ModifierDefinitionAnnotation: CallableDeclarationAnnotation, DocumentedAn { }; -struct VariableDeclarationAnnotation: ASTAnnotation +struct VariableDeclarationAnnotation: DeclarationAnnotation { /// Type of variable (type of identifier referencing this variable). TypePointer type = nullptr; From 69fd185903e86e55fef1740395417d763887afdc Mon Sep 17 00:00:00 2001 From: Jason Cobb Date: Thu, 19 Dec 2019 20:20:27 -0500 Subject: [PATCH 20/36] Add new annotations for Scopables --- libsolidity/ast/AST.cpp | 21 +++++++++++++++++++++ libsolidity/ast/AST.h | 6 ++++++ libsolidity/ast/ASTAnnotations.h | 12 ++++++++++++ 3 files changed, 39 insertions(+) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index cd8a66ad789a..a7d5e73cad2f 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -660,6 +660,27 @@ InlineAssemblyAnnotation& InlineAssembly::annotation() const return dynamic_cast(*m_annotation); } +BlockAnnotation& Block::annotation() const +{ + if (!m_annotation) + m_annotation = make_unique(); + return dynamic_cast(*m_annotation); +} + +TryCatchClauseAnnotation& TryCatchClause::annotation() const +{ + if (!m_annotation) + m_annotation = make_unique(); + return dynamic_cast(*m_annotation); +} + +ForStatementAnnotation& ForStatement::annotation() const +{ + if (!m_annotation) + m_annotation = make_unique(); + return dynamic_cast(*m_annotation); +} + ReturnAnnotation& Return::annotation() const { if (!m_annotation) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 871760a41f11..4abaf93e3008 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -1171,6 +1171,8 @@ class Block: public Statement, public Scopable std::vector> const& statements() const { return m_statements; } + BlockAnnotation& annotation() const override; + private: std::vector> m_statements; }; @@ -1250,6 +1252,8 @@ class TryCatchClause: public ASTNode, public Scopable ParameterList const* parameters() const { return m_parameters.get(); } Block const& block() const { return *m_block; } + TryCatchClauseAnnotation& annotation() const override; + private: ASTPointer m_errorName; ASTPointer m_parameters; @@ -1359,6 +1363,8 @@ class ForStatement: public BreakableStatement, public Scopable ExpressionStatement const* loopExpression() const { return m_loopExpression.get(); } Statement const& body() const { return *m_body; } + ForStatementAnnotation& annotation() const override; + private: /// For statement's initialization expression. for (XXX; ; ). Can be empty ASTPointer m_initExpression; diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index 107da87f5eb9..0f11b1c5a924 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -163,6 +163,18 @@ struct InlineAssemblyAnnotation: StatementAnnotation std::shared_ptr analysisInfo; }; +struct BlockAnnotation: StatementAnnotation, ScopableAnnotation +{ +}; + +struct TryCatchClauseAnnotation: ASTAnnotation, ScopableAnnotation +{ +}; + +struct ForStatementAnnotation: StatementAnnotation, ScopableAnnotation +{ +}; + struct ReturnAnnotation: StatementAnnotation { /// Reference to the return parameters of the function. From 6679f92c8afbf1f0361702320b0123dc59addff1 Mon Sep 17 00:00:00 2001 From: Jason Cobb Date: Thu, 19 Dec 2019 20:49:43 -0500 Subject: [PATCH 21/36] Move all references to scope into annotation --- libsolidity/analysis/NameAndTypeResolver.cpp | 8 ++++---- libsolidity/ast/AST.h | 6 ++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 21f8a5d19194..6881e14d6f0d 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -639,7 +639,7 @@ void DeclarationRegistrationHelper::endVisit(FunctionDefinition&) bool DeclarationRegistrationHelper::visit(TryCatchClause& _tryCatchClause) { - _tryCatchClause.setScope(m_currentScope); + _tryCatchClause.annotation().scope = m_currentScope; enterNewSubScope(_tryCatchClause); return true; } @@ -675,7 +675,7 @@ void DeclarationRegistrationHelper::endVisit(FunctionTypeName&) bool DeclarationRegistrationHelper::visit(Block& _block) { - _block.setScope(m_currentScope); + _block.annotation().scope = m_currentScope; enterNewSubScope(_block); return true; } @@ -687,7 +687,7 @@ void DeclarationRegistrationHelper::endVisit(Block&) bool DeclarationRegistrationHelper::visit(ForStatement& _for) { - _for.setScope(m_currentScope); + _for.annotation().scope = m_currentScope; enterNewSubScope(_for); return true; } @@ -761,7 +761,7 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, warnAboutShadowing, inactive, m_errorReporter); - _declaration.setScope(m_currentScope); + _declaration.annotation().scope = m_currentScope; if (_opensScope) enterNewSubScope(_declaration); } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 4abaf93e3008..f687f20c9df5 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -159,8 +159,7 @@ class Scopable virtual ~Scopable() = default; /// @returns the scope this declaration resides in. Can be nullptr if it is the global scope. /// Available only after name and type resolution step. - ASTNode const* scope() const { return m_scope; } - void setScope(ASTNode const* _scope) { m_scope = _scope; } + ASTNode const* scope() const { return annotation().scope; } /// @returns the source unit this scopable is present in. SourceUnit const& sourceUnit() const; @@ -172,8 +171,7 @@ class Scopable /// Can be combined with annotation().canonicalName (if present) to form a globally unique name. std::string sourceUnitName() const; -protected: - ASTNode const* m_scope = nullptr; + virtual ScopableAnnotation& annotation() const = 0; }; /** From c44916cbd5897416a1aaef6aeadce2dc728ffe9c Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 20 Dec 2019 08:29:25 +0100 Subject: [PATCH 22/36] Changelog entry for try/catch. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 9b4d81ff7fb5..817ee9180162 100644 --- a/Changelog.md +++ b/Changelog.md @@ -45,6 +45,7 @@ Language Features: * Allow global enums and structs. * Allow public variables to override external functions. * Allow underscores as delimiters in hex strings. + * Allow to react on failing external calls using ``try`` and ``catch``. * Introduce syntax for array slices and implement them for dynamic calldata arrays. * Introduce ``push()`` for dynamic storage arrays. It returns a reference to the newly allocated element, if applicable. * Introduce ``virtual`` and ``override`` keywords. From aab8b9bc36ddf10ae45ab458f2136392959e1266 Mon Sep 17 00:00:00 2001 From: chriseth Date: Sun, 29 Dec 2019 14:21:23 +0100 Subject: [PATCH 23/36] Fix redundant assignment removal in combination with break / continue. --- .../optimiser/RedundantAssignEliminator.cpp | 31 +++++++++---------- libyul/optimiser/RedundantAssignEliminator.h | 2 -- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/libyul/optimiser/RedundantAssignEliminator.cpp b/libyul/optimiser/RedundantAssignEliminator.cpp index aca44d0b3ef8..38c7881a009f 100644 --- a/libyul/optimiser/RedundantAssignEliminator.cpp +++ b/libyul/optimiser/RedundantAssignEliminator.cpp @@ -280,29 +280,28 @@ void RedundantAssignEliminator::changeUndecidedTo(YulString _variable, Redundant void RedundantAssignEliminator::finalize(YulString _variable, RedundantAssignEliminator::State _finalState) { - finalize(m_assignments, _variable, _finalState); - for (auto& assignments: m_forLoopInfo.pendingBreakStmts) - finalize(assignments, _variable, _finalState); - for (auto& assignments: m_forLoopInfo.pendingContinueStmts) - finalize(assignments, _variable, _finalState); -} + std::map assignments; + joinMap(assignments, std::move(m_assignments[_variable]), State::join); + m_assignments.erase(_variable); -void RedundantAssignEliminator::finalize( - TrackedAssignments& _assignments, - YulString _variable, - RedundantAssignEliminator::State _finalState -) -{ - for (auto const& assignment: _assignments[_variable]) + for (auto& breakAssignments: m_forLoopInfo.pendingBreakStmts) + { + joinMap(assignments, std::move(breakAssignments[_variable]), State::join); + breakAssignments.erase(_variable); + } + for (auto& continueAssignments: m_forLoopInfo.pendingContinueStmts) + { + joinMap(assignments, std::move(continueAssignments[_variable]), State::join); + continueAssignments.erase(_variable); + } + + for (auto const& assignment: assignments) { State const state = assignment.second == State::Undecided ? _finalState : assignment.second; if (state == State::Unused && SideEffectsCollector{*m_dialect, *assignment.first->value}.movable()) - // TODO the only point where we actually need this - // to be a set is for the for loop m_pendingRemovals.insert(assignment.first); } - _assignments.erase(_variable); } void AssignmentRemover::operator()(Block& _block) diff --git a/libyul/optimiser/RedundantAssignEliminator.h b/libyul/optimiser/RedundantAssignEliminator.h index fec6a271448d..7849708d6351 100644 --- a/libyul/optimiser/RedundantAssignEliminator.h +++ b/libyul/optimiser/RedundantAssignEliminator.h @@ -161,8 +161,6 @@ class RedundantAssignEliminator: public ASTWalker /// assignments to the final state. In this case, this also applies to pending /// break and continue TrackedAssignments. void finalize(YulString _variable, State _finalState); - /// Helper function for the above. - void finalize(TrackedAssignments& _assignments, YulString _variable, State _finalState); Dialect const* m_dialect; std::set m_declaredVariables; From 3994c9135f84a7f7b9b93286d313f67773c6e193 Mon Sep 17 00:00:00 2001 From: chriseth Date: Sun, 29 Dec 2019 15:16:54 +0100 Subject: [PATCH 24/36] Tests. --- .../remove_break.yul | 26 ++++++++++++++++++ .../remove_continue.yul | 27 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_break.yul create mode 100644 test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_continue.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_break.yul b/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_break.yul new file mode 100644 index 000000000000..8e75d82edb7c --- /dev/null +++ b/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_break.yul @@ -0,0 +1,26 @@ +{ + let i := 0 + for {} lt(i, 2) { i := add(i, 1) } + { + let x + x := 1337 + if lt(i,1) { + x := 42 + break + } + mstore(0, x) + } +} +// ==== +// step: redundantAssignEliminator +// ---- +// { +// let i := 0 +// for { } lt(i, 2) { i := add(i, 1) } +// { +// let x +// x := 1337 +// if lt(i, 1) { break } +// mstore(0, x) +// } +// } diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_continue.yul b/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_continue.yul new file mode 100644 index 000000000000..f5a29382b393 --- /dev/null +++ b/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_continue.yul @@ -0,0 +1,27 @@ +{ + let i := 0 + for {} lt(i, 2) { i := add(i, 1) } + { + let x + x := 1337 + if lt(i,1) { + x := 42 + continue + } + mstore(0, x) + } +} + +// ==== +// step: redundantAssignEliminator +// ---- +// { +// let i := 0 +// for { } lt(i, 2) { i := add(i, 1) } +// { +// let x +// x := 1337 +// if lt(i, 1) { continue } +// mstore(0, x) +// } +// } From c3f43fd1e6f16e9d3b57eec863e6c4660b73d8c5 Mon Sep 17 00:00:00 2001 From: chriseth Date: Sun, 29 Dec 2019 15:14:43 +0100 Subject: [PATCH 25/36] Changelog entry. --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index 9b4d81ff7fb5..8b05393c2608 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: Bugfixes: + * Yul Optimizer: Fix bug in redundant assignment remover in combination with break and continue statements. From 1e50fc61e46eb81c607cb9d649c93decfd99cbad Mon Sep 17 00:00:00 2001 From: chriseth Date: Sun, 29 Dec 2019 14:21:23 +0100 Subject: [PATCH 26/36] Fix redundant assignment removal in combination with break / continue. --- .../optimiser/RedundantAssignEliminator.cpp | 31 +++++++++---------- libyul/optimiser/RedundantAssignEliminator.h | 2 -- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/libyul/optimiser/RedundantAssignEliminator.cpp b/libyul/optimiser/RedundantAssignEliminator.cpp index 477814e221c5..3c619ad45600 100644 --- a/libyul/optimiser/RedundantAssignEliminator.cpp +++ b/libyul/optimiser/RedundantAssignEliminator.cpp @@ -268,29 +268,28 @@ void RedundantAssignEliminator::changeUndecidedTo(YulString _variable, Redundant void RedundantAssignEliminator::finalize(YulString _variable, RedundantAssignEliminator::State _finalState) { - finalize(m_assignments, _variable, _finalState); - for (auto& assignments: m_forLoopInfo.pendingBreakStmts) - finalize(assignments, _variable, _finalState); - for (auto& assignments: m_forLoopInfo.pendingContinueStmts) - finalize(assignments, _variable, _finalState); -} + std::map assignments; + joinMap(assignments, std::move(m_assignments[_variable]), State::join); + m_assignments.erase(_variable); -void RedundantAssignEliminator::finalize( - TrackedAssignments& _assignments, - YulString _variable, - RedundantAssignEliminator::State _finalState -) -{ - for (auto const& assignment: _assignments[_variable]) + for (auto& breakAssignments: m_forLoopInfo.pendingBreakStmts) + { + joinMap(assignments, std::move(breakAssignments[_variable]), State::join); + breakAssignments.erase(_variable); + } + for (auto& continueAssignments: m_forLoopInfo.pendingContinueStmts) + { + joinMap(assignments, std::move(continueAssignments[_variable]), State::join); + continueAssignments.erase(_variable); + } + + for (auto const& assignment: assignments) { State const state = assignment.second == State::Undecided ? _finalState : assignment.second; if (state == State::Unused && SideEffectsCollector{*m_dialect, *assignment.first->value}.movable()) - // TODO the only point where we actually need this - // to be a set is for the for loop m_pendingRemovals.insert(assignment.first); } - _assignments.erase(_variable); } void AssignmentRemover::operator()(Block& _block) diff --git a/libyul/optimiser/RedundantAssignEliminator.h b/libyul/optimiser/RedundantAssignEliminator.h index 65ddc19ae97f..0b68c10941e0 100644 --- a/libyul/optimiser/RedundantAssignEliminator.h +++ b/libyul/optimiser/RedundantAssignEliminator.h @@ -158,8 +158,6 @@ class RedundantAssignEliminator: public ASTWalker /// assignments to the final state. In this case, this also applies to pending /// break and continue TrackedAssignments. void finalize(YulString _variable, State _finalState); - /// Helper function for the above. - void finalize(TrackedAssignments& _assignments, YulString _variable, State _finalState); Dialect const* m_dialect; std::set m_declaredVariables; From 92c3511f47158ecaf1bba717eded84410f55132f Mon Sep 17 00:00:00 2001 From: chriseth Date: Sun, 29 Dec 2019 15:16:54 +0100 Subject: [PATCH 27/36] Tests. --- .../remove_break.yul | 26 ++++++++++++++++++ .../remove_continue.yul | 27 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_break.yul create mode 100644 test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_continue.yul diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_break.yul b/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_break.yul new file mode 100644 index 000000000000..8e75d82edb7c --- /dev/null +++ b/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_break.yul @@ -0,0 +1,26 @@ +{ + let i := 0 + for {} lt(i, 2) { i := add(i, 1) } + { + let x + x := 1337 + if lt(i,1) { + x := 42 + break + } + mstore(0, x) + } +} +// ==== +// step: redundantAssignEliminator +// ---- +// { +// let i := 0 +// for { } lt(i, 2) { i := add(i, 1) } +// { +// let x +// x := 1337 +// if lt(i, 1) { break } +// mstore(0, x) +// } +// } diff --git a/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_continue.yul b/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_continue.yul new file mode 100644 index 000000000000..f5a29382b393 --- /dev/null +++ b/test/libyul/yulOptimizerTests/redundantAssignEliminator/remove_continue.yul @@ -0,0 +1,27 @@ +{ + let i := 0 + for {} lt(i, 2) { i := add(i, 1) } + { + let x + x := 1337 + if lt(i,1) { + x := 42 + continue + } + mstore(0, x) + } +} + +// ==== +// step: redundantAssignEliminator +// ---- +// { +// let i := 0 +// for { } lt(i, 2) { i := add(i, 1) } +// { +// let x +// x := 1337 +// if lt(i, 1) { continue } +// mstore(0, x) +// } +// } From 29c0b73dff95a471738fc316931fbaf7fa30fc18 Mon Sep 17 00:00:00 2001 From: chriseth Date: Sun, 29 Dec 2019 15:51:27 +0100 Subject: [PATCH 28/36] Bug list entry. --- docs/bugs.json | 11 +++++++++++ docs/bugs_by_version.json | 4 +++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/bugs.json b/docs/bugs.json index 5d94131a19c8..2bb6a4848637 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,4 +1,15 @@ [ + { + "name": "YulOptimizerRedundantAssignmentBreakContinue", + "summary": "The Yul optimizer can remove essential assignments to variables declared inside for loops when Yul's continue or break statement is used. You are unlikely to be affected if you do not use inline assembly with for loops and continue and break statements.", + "description": "The Yul optimizer has a stage that remove assignments to variables that are overwritten again or are not used in all following control-flow branches. This logic incorrectly removes such assignments to variables declared inside a for loop if they can be removed in a control-flow branch that ends with ``break`` or ``continue`` even though they cannot be removed in other control-flow branches. Variables declared outside of the respective for loop are not affected.", + "introduced": "0.6.0", + "fixed": "0.6.1", + "severity": "medium", + "conditions": { + "yulOptimizer": true + } + }, { "name": "ABIEncoderV2LoopYulOptimizer", "summary": "If both the experimental ABIEncoderV2 and the experimental Yul optimizer are activated, one component of the Yul optimizer may reuse data in memory that has been changed in the meantime.", diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 0fa1e1076e71..26524d9a4b3e 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -856,7 +856,9 @@ "released": "2019-05-28" }, "0.6.0": { - "bugs": [], + "bugs": [ + "YulOptimizerRedundantAssignmentBreakContinue" + ], "released": "2019-12-17" } } \ No newline at end of file From 27727a7af32d43d648a126a7574eb8bbee7a19c1 Mon Sep 17 00:00:00 2001 From: elenadimitrova Date: Thu, 2 Jan 2020 12:39:10 +0200 Subject: [PATCH 29/36] Rename solium to ethlint --- docs/resources.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/resources.rst b/docs/resources.rst index 4335c3deb04b..3a9e3c0c2f45 100644 --- a/docs/resources.rst +++ b/docs/resources.rst @@ -33,7 +33,7 @@ Solidity Integrations * `Solidity IDE `_ Browser-based IDE with integrated compiler, Ganache and local file system support. - * `Solium `_ + * `Ethlint `_ Linter to identify and fix style and security issues in Solidity. * `Superblocks Lab `_ @@ -48,7 +48,7 @@ Solidity Integrations Plugin for the Atom editor that provides Solidity linting. * `Atom Solium Linter `_ - Configurable Solidty linter for Atom using Solium as a base. + Configurable Solidity linter for Atom using Solium (now Ethlint) as a base. * Eclipse: From d972a10b4f438d17f6aabd71500d94b41309a064 Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Thu, 2 Jan 2020 12:43:56 +0100 Subject: [PATCH 30/36] Review 1 --- docs/bugs.json | 2 +- test/libsolidity/SolidityEndToEndTest.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/bugs.json b/docs/bugs.json index 2bb6a4848637..1f0f34de5604 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -2,7 +2,7 @@ { "name": "YulOptimizerRedundantAssignmentBreakContinue", "summary": "The Yul optimizer can remove essential assignments to variables declared inside for loops when Yul's continue or break statement is used. You are unlikely to be affected if you do not use inline assembly with for loops and continue and break statements.", - "description": "The Yul optimizer has a stage that remove assignments to variables that are overwritten again or are not used in all following control-flow branches. This logic incorrectly removes such assignments to variables declared inside a for loop if they can be removed in a control-flow branch that ends with ``break`` or ``continue`` even though they cannot be removed in other control-flow branches. Variables declared outside of the respective for loop are not affected.", + "description": "The Yul optimizer has a stage that removes assignments to variables that are overwritten again or are not used in all following control-flow branches. This logic incorrectly removes such assignments to variables declared inside a for loop if they can be removed in a control-flow branch that ends with ``break`` or ``continue`` even though they cannot be removed in other control-flow branches. Variables declared outside of the respective for loop are not affected.", "introduced": "0.6.0", "fixed": "0.6.1", "severity": "medium", diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 72772f048620..c1ed1d67e95b 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -14319,8 +14319,6 @@ BOOST_AUTO_TEST_CASE(event_wrong_abi_name) )"; compileAndRun(sourceCode, 0, "ClientReceipt", bytes()); compileAndRun(sourceCode, 0, "Test", bytes(), map{{"ClientReceipt", m_contractAddress}}); - u256 value(18); - u256 id(0x1234); callContractFunction("f()"); BOOST_REQUIRE_EQUAL(numLogs(), 1); From 1c2096a360f1590e41cd535524201d1f7f346297 Mon Sep 17 00:00:00 2001 From: chriseth Date: Sun, 29 Dec 2019 15:14:43 +0100 Subject: [PATCH 31/36] Changelog entry. --- Changelog.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index f09fb0355c19..72461f021077 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,9 +1,14 @@ +### 0.5.16 (2020-01-02) + +Bugfixes: + * Yul Optimizer: Fix bug in redundant assignment remover in combination with break and continue statements. + + ### 0.5.15 (2019-12-17) Bugfixes: * Yul Optimizer: Fix incorrect redundant load optimization crossing user-defined functions that contain for-loops with memory / storage writes. - ### 0.5.14 (2019-12-09) Language Features: From 8328f826a1c3aca400c463b58cd7f43d71f87f97 Mon Sep 17 00:00:00 2001 From: chriseth Date: Sun, 29 Dec 2019 15:51:27 +0100 Subject: [PATCH 32/36] Bug list entry. --- docs/bugs.json | 11 +++++++++++ docs/bugs_by_version.json | 24 ++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/docs/bugs.json b/docs/bugs.json index 5d94131a19c8..52b062c8a4f9 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,4 +1,15 @@ [ + { + "name": "YulOptimizerRedundantAssignmentBreakContinue0.5", + "summary": "The Yul optimizer can remove essential assignments to variables declared inside for loops when Yul's continue or break statement is used. You are unlikely to be affected if you do not use inline assembly with for loops and continue and break statements.", + "description": "The Yul optimizer has a stage that remove assignments to variables that are overwritten again or are not used in all following control-flow branches. This logic incorrectly removes such assignments to varibales declared inside a for loop if they can be removed in a control-flow branch that ends with ``break`` or ``continue`` even though they cannot be removed in other control-flow branches. Variables declared outside of the respective for loop are not affected.", + "introduced": "0.5.8", + "fixed": "0.5.16", + "severity": "low", + "conditions": { + "yulOptimizer": true + } + }, { "name": "ABIEncoderV2LoopYulOptimizer", "summary": "If both the experimental ABIEncoderV2 and the experimental Yul optimizer are activated, one component of the Yul optimizer may reuse data in memory that has been changed in the meantime.", diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 1a0e99749db3..a9ce0be92f7a 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -742,32 +742,46 @@ }, "0.5.10": { "bugs": [ + "YulOptimizerRedundantAssignmentBreakContinue0.5", "ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers" ], "released": "2019-06-25" }, "0.5.11": { - "bugs": [], + "bugs": [ + "YulOptimizerRedundantAssignmentBreakContinue0.5" + ], "released": "2019-08-12" }, "0.5.12": { - "bugs": [], + "bugs": [ + "YulOptimizerRedundantAssignmentBreakContinue0.5" + ], "released": "2019-10-01" }, "0.5.13": { - "bugs": [], + "bugs": [ + "YulOptimizerRedundantAssignmentBreakContinue0.5" + ], "released": "2019-11-14" }, "0.5.14": { "bugs": [ + "YulOptimizerRedundantAssignmentBreakContinue0.5", "ABIEncoderV2LoopYulOptimizer" ], "released": "2019-12-09" }, "0.5.15": { - "bugs": [], + "bugs": [ + "YulOptimizerRedundantAssignmentBreakContinue0.5" + ], "released": "2019-12-17" }, + "0.5.16": { + "bugs": [], + "released": "2020-01-02" + }, "0.5.2": { "bugs": [ "SignedArrayStorageCopy", @@ -840,6 +854,7 @@ }, "0.5.8": { "bugs": [ + "YulOptimizerRedundantAssignmentBreakContinue0.5", "ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers", "SignedArrayStorageCopy", "ABIEncoderV2StorageArrayWithMultiSlotElement", @@ -849,6 +864,7 @@ }, "0.5.9": { "bugs": [ + "YulOptimizerRedundantAssignmentBreakContinue0.5", "ABIEncoderV2CalldataStructsWithStaticallySizedAndDynamicallyEncodedMembers", "SignedArrayStorageCopy", "ABIEncoderV2StorageArrayWithMultiSlotElement" From 026f7c37af8e75b7ae7cbebd8e30eba032b6ef0f Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Thu, 2 Jan 2020 12:54:52 +0100 Subject: [PATCH 33/36] Review 1 --- docs/bugs.json | 2 +- test/libsolidity/SolidityEndToEndTest.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/bugs.json b/docs/bugs.json index 52b062c8a4f9..bbb9e93fa180 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -2,7 +2,7 @@ { "name": "YulOptimizerRedundantAssignmentBreakContinue0.5", "summary": "The Yul optimizer can remove essential assignments to variables declared inside for loops when Yul's continue or break statement is used. You are unlikely to be affected if you do not use inline assembly with for loops and continue and break statements.", - "description": "The Yul optimizer has a stage that remove assignments to variables that are overwritten again or are not used in all following control-flow branches. This logic incorrectly removes such assignments to varibales declared inside a for loop if they can be removed in a control-flow branch that ends with ``break`` or ``continue`` even though they cannot be removed in other control-flow branches. Variables declared outside of the respective for loop are not affected.", + "description": "The Yul optimizer has a stage that removes assignments to variables that are overwritten again or are not used in all following control-flow branches. This logic incorrectly removes such assignments to variables declared inside a for loop if they can be removed in a control-flow branch that ends with ``break`` or ``continue`` even though they cannot be removed in other control-flow branches. Variables declared outside of the respective for loop are not affected.", "introduced": "0.5.8", "fixed": "0.5.16", "severity": "low", diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index bc03c2ef8cfc..dfe135db9c7a 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -14718,8 +14718,6 @@ BOOST_AUTO_TEST_CASE(event_wrong_abi_name) )"; compileAndRun(sourceCode, 0, "ClientReceipt", bytes()); compileAndRun(sourceCode, 0, "Test", bytes(), map{{"ClientReceipt", m_contractAddress}}); - u256 value(18); - u256 id(0x1234); callContractFunction("f()"); BOOST_REQUIRE_EQUAL(numLogs(), 1); From 9c3226ce7558bfa639ca06ddd7214ae9bf4e1fc9 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 2 Jan 2020 19:52:34 +0100 Subject: [PATCH 34/36] Set version to 0.5.16. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 10b830a6ca5b..0c84c6d15d34 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ include(EthPolicy) eth_policy() # project name and version should be set after cmake_policy CMP0048 -set(PROJECT_VERSION "0.5.15") +set(PROJECT_VERSION "0.5.16") project(solidity VERSION ${PROJECT_VERSION} LANGUAGES C CXX) include(TestBigEndian) From 385e1bf70a0389009af0da2f2f6054cd5b246619 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 2 Jan 2020 19:48:43 +0100 Subject: [PATCH 35/36] Set release date. --- Changelog.md | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Changelog.md b/Changelog.md index cee949e695a3..4487b30e4a8a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,16 +1,9 @@ -### 0.6.1 (unreleased) - -Language Features: - - -Compiler Features: - +### 0.6.1 (2020-01-02) Bugfixes: * Yul Optimizer: Fix bug in redundant assignment remover in combination with break and continue statements. - ### 0.6.0 (2019-12-17) Breaking changes: From 30a2d712c09cdce7254c19b294c5e39e78d85191 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 2 Jan 2020 23:51:49 +0100 Subject: [PATCH 36/36] Bug list entry. --- docs/bugs_by_version.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 3b8422053355..4c9a01c64544 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -876,5 +876,9 @@ "YulOptimizerRedundantAssignmentBreakContinue" ], "released": "2019-12-17" + }, + "0.6.1": { + "bugs": [], + "released": "2020-01-02" } } \ No newline at end of file