mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6800 from ethereum/skipEmptyDump
Skip empty entries in memory and storage dump.
This commit is contained in:
commit
6132f0aea9
@ -25,6 +25,8 @@ public:
|
|||||||
using mutable_value_type = typename std::conditional<std::is_const<_T>::value, typename std::remove_const<_T>::type, _T>::type;
|
using mutable_value_type = typename std::conditional<std::is_const<_T>::value, typename std::remove_const<_T>::type, _T>::type;
|
||||||
using string_type = typename std::conditional<std::is_const<_T>::value, std::string const, std::string>::type;
|
using string_type = typename std::conditional<std::is_const<_T>::value, std::string const, std::string>::type;
|
||||||
using vector_type = typename std::conditional<std::is_const<_T>::value, std::vector<typename std::remove_const<_T>::type> const, std::vector<_T>>::type;
|
using vector_type = typename std::conditional<std::is_const<_T>::value, std::vector<typename std::remove_const<_T>::type> const, std::vector<_T>>::type;
|
||||||
|
using iterator = _T*;
|
||||||
|
using const_iterator = _T const*;
|
||||||
|
|
||||||
static_assert(std::is_pod<value_type>::value, "vector_ref can only be used with PODs due to its low-level treatment of data.");
|
static_assert(std::is_pod<value_type>::value, "vector_ref can only be used with PODs due to its low-level treatment of data.");
|
||||||
|
|
||||||
|
@ -53,13 +53,9 @@ YulInterpreterTest::YulInterpreterTest(string const& _filename)
|
|||||||
BOOST_THROW_EXCEPTION(runtime_error("Cannot open test case: \"" + _filename + "\"."));
|
BOOST_THROW_EXCEPTION(runtime_error("Cannot open test case: \"" + _filename + "\"."));
|
||||||
file.exceptions(ios::badbit);
|
file.exceptions(ios::badbit);
|
||||||
|
|
||||||
|
m_source = parseSourceAndSettings(file);
|
||||||
|
|
||||||
string line;
|
string line;
|
||||||
while (getline(file, line))
|
|
||||||
{
|
|
||||||
if (boost::algorithm::starts_with(line, "// ----"))
|
|
||||||
break;
|
|
||||||
m_source += std::move(line) + "\n";
|
|
||||||
}
|
|
||||||
while (getline(file, line))
|
while (getline(file, line))
|
||||||
if (boost::algorithm::starts_with(line, "// "))
|
if (boost::algorithm::starts_with(line, "// "))
|
||||||
m_expectation += line.substr(3) + "\n";
|
m_expectation += line.substr(3) + "\n";
|
||||||
@ -142,15 +138,7 @@ string YulInterpreterTest::interpret()
|
|||||||
}
|
}
|
||||||
|
|
||||||
stringstream result;
|
stringstream result;
|
||||||
result << "Trace:" << endl;;
|
state.dumpTraceAndState(result);
|
||||||
for (auto const& line: interpreter.trace())
|
|
||||||
result << " " << line << endl;
|
|
||||||
result << "Memory dump:\n";
|
|
||||||
for (size_t i = 0; i < state.memory.size(); i += 0x20)
|
|
||||||
result << " " << std::hex << std::setw(4) << i << ": " << toHex(bytesConstRef(state.memory.data() + i, 0x20).toBytes()) << endl;
|
|
||||||
result << "Storage dump:" << endl;
|
|
||||||
for (auto const& slot: state.storage)
|
|
||||||
result << " " << slot.first.hex() << ": " << slot.second.hex() << endl;
|
|
||||||
return result.str();
|
return result.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace yul
|
|||||||
namespace test
|
namespace test
|
||||||
{
|
{
|
||||||
|
|
||||||
class YulInterpreterTest: public dev::solidity::test::TestCase
|
class YulInterpreterTest: public dev::solidity::test::EVMVersionRestrictedTestCase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<TestCase> create(Config const& _config)
|
static std::unique_ptr<TestCase> create(Config const& _config)
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// MSTORE_AT_SIZE(32, 32) [0000000000000000000000000000000000000000000000000000000000000002]
|
|
||||||
// MSTORE_AT_SIZE(0, 32) [0000000000000000000000000000000000000000000000000000000000000003]
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// 0: 0000000000000000000000000000000000000000000000000000000000000003
|
// 0: 0000000000000000000000000000000000000000000000000000000000000003
|
||||||
// 20: 0000000000000000000000000000000000000000000000000000000000000002
|
// 20: 0000000000000000000000000000000000000000000000000000000000000002
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
object "main"
|
object "main"
|
||||||
{
|
{
|
||||||
code {
|
code {
|
||||||
datacopy(0, dataoffset("main"), datasize("main"))
|
datacopy(0, and(dataoffset("main"), 15), and(datasize("main"), 15))
|
||||||
datacopy(32, dataoffset("sub"), datasize("sub"))
|
datacopy(32, and(dataoffset("sub"), 15), and(datasize("sub"), 15))
|
||||||
sstore(0, mload(0))
|
sstore(0, mload(0))
|
||||||
sstore(1, mload(32))
|
sstore(1, mload(32))
|
||||||
}
|
}
|
||||||
@ -10,105 +10,9 @@ object "main"
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// MSTORE_AT_SIZE(0, 2916)
|
|
||||||
// MSTORE_AT_SIZE(32, 265)
|
|
||||||
// MLOAD_FROM_SIZE(0, 32)
|
|
||||||
// SSTORE(0, 0)
|
|
||||||
// MLOAD_FROM_SIZE(32, 32)
|
|
||||||
// SSTORE(1, 0)
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// 0: 0000000000000000000000000000000000000000000000000000000000000000
|
// 0: 6465636f00000000000000000000000000000000000000000000000000000000
|
||||||
// 20: 0000000000000000000000000000000000000000000000000000000000000000
|
// 20: 636f6465636f6465000000000000000000000000000000000000000000000000
|
||||||
// 40: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 60: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 80: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// a0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// c0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// e0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 100: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 120: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 140: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 160: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 180: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 1a0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 1c0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 1e0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 200: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 220: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 240: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 260: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 280: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 2a0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 2c0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 2e0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 300: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 320: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 340: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 360: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 380: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 3a0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 3c0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 3e0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 400: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 420: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 440: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 460: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 480: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 4a0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 4c0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 4e0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 500: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 520: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 540: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 560: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 580: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 5a0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 5c0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 5e0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 600: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 620: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 640: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 660: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 680: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 6a0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 6c0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 6e0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 700: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 720: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 740: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 760: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 780: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 7a0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 7c0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 7e0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 800: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 820: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 840: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 860: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 880: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 8a0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 8c0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 8e0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 900: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 920: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 940: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 960: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 980: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 9a0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 9c0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 9e0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// a00: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// a20: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// a40: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// a60: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// a80: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// aa0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// ac0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// ae0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// b00: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// b20: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// b40: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// b60: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000000
|
// 0000000000000000000000000000000000000000000000000000000000000000: 6465636f00000000000000000000000000000000000000000000000000000000
|
||||||
// 0000000000000000000000000000000000000000000000000000000000000001: 0000000000000000000000000000000000000000000000000000000000000000
|
// 0000000000000000000000000000000000000000000000000000000000000001: 636f6465636f6465000000000000000000000000000000000000000000000000
|
||||||
|
@ -8,8 +8,6 @@ object "main"
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// SSTORE(0, 110)
|
|
||||||
// SSTORE(1, 1804)
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
// 0000000000000000000000000000000000000000000000000000000000000000: 000000000000000000000000000000000000000000000000000000000000006e
|
// 0000000000000000000000000000000000000000000000000000000000000000: 000000000000000000000000000000000000000000000000000000000000006e
|
||||||
|
@ -8,8 +8,6 @@ object "main"
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// SSTORE(0, 2916)
|
|
||||||
// SSTORE(1, 265)
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000b64
|
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000b64
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// MSTORE_AT_SIZE(0, 32) [8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e39]
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// 0: 8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e39
|
// 0: 8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e39
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
|
@ -4,14 +4,7 @@
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// GAS()
|
|
||||||
// MLOAD_FROM_SIZE(0, 32)
|
|
||||||
// MSTORE_AT_SIZE(48, 32)
|
|
||||||
// CALL(153, 69, 5, 0, 32, 48, 32)
|
// CALL(153, 69, 5, 0, 32, 48, 32)
|
||||||
// SSTORE(100, 1)
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// 0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 20: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 40: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
// 0000000000000000000000000000000000000000000000000000000000000064: 0000000000000000000000000000000000000000000000000000000000000001
|
// 0000000000000000000000000000000000000000000000000000000000000064: 0000000000000000000000000000000000000000000000000000000000000001
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// SSTORE(13, 42)
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
// 000000000000000000000000000000000000000000000000000000000000000d: 000000000000000000000000000000000000000000000000000000000000002a
|
// 000000000000000000000000000000000000000000000000000000000000000d: 000000000000000000000000000000000000000000000000000000000000002a
|
||||||
|
@ -5,16 +5,6 @@
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// MSTORE_AT_SIZE(10, 32) [0000000000000000000000000000000000000000000000000000000000002000]
|
|
||||||
// MSTORE_AT_SIZE(15, 32) [0000000000000000000000000000000000000000000000000000000000003000]
|
|
||||||
// MSTORE_AT_SIZE(20, 32) [0000000000000000000000000000000000000000000000000000000000004000]
|
|
||||||
// MSTORE_AT_SIZE(25, 32) [0000000000000000000000000000000000000000000000000000000000005000]
|
|
||||||
// MSTORE_AT_SIZE(30, 32) [0000000000000000000000000000000000000000000000000000000000006000]
|
|
||||||
// MSTORE_AT_SIZE(35, 32) [0000000000000000000000000000000000000000000000000000000000007000]
|
|
||||||
// MSTORE_AT_SIZE(40, 32) [0000000000000000000000000000000000000000000000000000000000008000]
|
|
||||||
// MSTORE_AT_SIZE(45, 32) [0000000000000000000000000000000000000000000000000000000000009000]
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// 0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 20: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 40: 0000000000000000000000900000000000000000000000000000000000000000
|
// 40: 0000000000000000000000900000000000000000000000000000000000000000
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
|
@ -5,33 +5,18 @@
|
|||||||
}
|
}
|
||||||
function foo_0(x) -> y
|
function foo_0(x) -> y
|
||||||
{
|
{
|
||||||
|
y := 1
|
||||||
mstore8(1, 1)
|
mstore8(1, 1)
|
||||||
for {
|
for { } slt(1, keccak256(1, msize())) { let x_1 := foo_0(x) }
|
||||||
}
|
|
||||||
slt(1, keccak256(1, msize()))
|
|
||||||
{
|
|
||||||
let x_1 := foo_0(x)
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
|
y := add(y, 1)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// MSTORE_AT_SIZE(1, 1) [0101]
|
|
||||||
// MSIZE()
|
|
||||||
// MLOAD_FROM_SIZE(1, 32)
|
|
||||||
// MSTORE_AT_SIZE(1, 1) [0101]
|
|
||||||
// MSIZE()
|
|
||||||
// MLOAD_FROM_SIZE(1, 64)
|
|
||||||
// MSIZE()
|
|
||||||
// MLOAD_FROM_SIZE(1, 96)
|
|
||||||
// SSTORE(0, 0)
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// 0: 0001000000000000000000000000000000000000000000000000000000000000
|
// 0: 0001000000000000000000000000000000000000000000000000000000000000
|
||||||
// 20: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 40: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 60: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000000
|
// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000002
|
||||||
|
21
test/libyul/yulInterpreterTests/side_effect_free.yul
Normal file
21
test/libyul/yulInterpreterTests/side_effect_free.yul
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
// These can be removed by the optimizer and should not
|
||||||
|
// appear in the trace.
|
||||||
|
pop(gas())
|
||||||
|
pop(extcodesize(0))
|
||||||
|
pop(extcodehash(0))
|
||||||
|
pop(returndatasize())
|
||||||
|
pop(sload(0))
|
||||||
|
pop(pc())
|
||||||
|
pop(msize())
|
||||||
|
pop(mload(0))
|
||||||
|
pop(sload(0))
|
||||||
|
pop(msize())
|
||||||
|
pop(keccak256(0, 10))
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// EVMVersion: >=constantinople
|
||||||
|
// ----
|
||||||
|
// Trace:
|
||||||
|
// Memory dump:
|
||||||
|
// Storage dump:
|
@ -3,8 +3,6 @@
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// MSTORE_AT_SIZE(10, 32) [000000000000000000000000000000000000000000000000000000000000000b]
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// 0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 20: 0000000000000000000b00000000000000000000000000000000000000000000
|
// 20: 0000000000000000000b00000000000000000000000000000000000000000000
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Trace:
|
// Trace:
|
||||||
// MSTORE_AT_SIZE(1, 32) [0000000000000000000000000000000000000000000000000000000000000002]
|
|
||||||
// Memory dump:
|
// Memory dump:
|
||||||
// 0: 0000000000000000000000000000000000000000000000000000000000000000
|
|
||||||
// 20: 0200000000000000000000000000000000000000000000000000000000000000
|
// 20: 0200000000000000000000000000000000000000000000000000000000000000
|
||||||
// Storage dump:
|
// Storage dump:
|
||||||
|
@ -35,7 +35,5 @@ void yulFuzzerUtil::interpret(
|
|||||||
state.maxMemSize = _maxMemory;
|
state.maxMemSize = _maxMemory;
|
||||||
Interpreter interpreter(state, _dialect);
|
Interpreter interpreter(state, _dialect);
|
||||||
interpreter(*_ast);
|
interpreter(*_ast);
|
||||||
_os << "Trace:" << endl;
|
state.dumpTraceAndState(_os);
|
||||||
for (auto const& line: interpreter.trace())
|
|
||||||
_os << " " << line << endl;
|
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ u256 EVMInstructionInterpreter::eval(
|
|||||||
// --------------- blockchain stuff ---------------
|
// --------------- blockchain stuff ---------------
|
||||||
case Instruction::KECCAK256:
|
case Instruction::KECCAK256:
|
||||||
{
|
{
|
||||||
if (!logMemoryRead(arg[0], arg[1]))
|
if (!accessMemory(arg[0], arg[1]))
|
||||||
return u256("0x1234cafe1234cafe1234cafe") + arg[0];
|
return u256("0x1234cafe1234cafe1234cafe") + arg[0];
|
||||||
uint64_t offset = uint64_t(arg[0] & uint64_t(-1));
|
uint64_t offset = uint64_t(arg[0] & uint64_t(-1));
|
||||||
uint64_t size = uint64_t(arg[1] & uint64_t(-1));
|
uint64_t size = uint64_t(arg[1] & uint64_t(-1));
|
||||||
@ -207,7 +207,7 @@ u256 EVMInstructionInterpreter::eval(
|
|||||||
case Instruction::CALLDATASIZE:
|
case Instruction::CALLDATASIZE:
|
||||||
return m_state.calldata.size();
|
return m_state.calldata.size();
|
||||||
case Instruction::CALLDATACOPY:
|
case Instruction::CALLDATACOPY:
|
||||||
if (logMemoryWrite(arg[0], arg[2]))
|
if (accessMemory(arg[0], arg[2]))
|
||||||
copyZeroExtended(
|
copyZeroExtended(
|
||||||
m_state.memory, m_state.calldata,
|
m_state.memory, m_state.calldata,
|
||||||
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
|
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
|
||||||
@ -216,7 +216,7 @@ u256 EVMInstructionInterpreter::eval(
|
|||||||
case Instruction::CODESIZE:
|
case Instruction::CODESIZE:
|
||||||
return m_state.code.size();
|
return m_state.code.size();
|
||||||
case Instruction::CODECOPY:
|
case Instruction::CODECOPY:
|
||||||
if (logMemoryWrite(arg[0], arg[2]))
|
if (accessMemory(arg[0], arg[2]))
|
||||||
copyZeroExtended(
|
copyZeroExtended(
|
||||||
m_state.memory, m_state.code,
|
m_state.memory, m_state.code,
|
||||||
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
|
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
|
||||||
@ -225,14 +225,12 @@ u256 EVMInstructionInterpreter::eval(
|
|||||||
case Instruction::GASPRICE:
|
case Instruction::GASPRICE:
|
||||||
return m_state.gasprice;
|
return m_state.gasprice;
|
||||||
case Instruction::EXTCODESIZE:
|
case Instruction::EXTCODESIZE:
|
||||||
logTrace(_instruction, arg);
|
|
||||||
return u256(keccak256(h256(arg[0]))) & 0xffffff;
|
return u256(keccak256(h256(arg[0]))) & 0xffffff;
|
||||||
case Instruction::EXTCODEHASH:
|
case Instruction::EXTCODEHASH:
|
||||||
logTrace(_instruction, arg);
|
|
||||||
return u256(keccak256(h256(arg[0] + 1)));
|
return u256(keccak256(h256(arg[0] + 1)));
|
||||||
case Instruction::EXTCODECOPY:
|
case Instruction::EXTCODECOPY:
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
if (logMemoryWrite(arg[1], arg[3]))
|
if (accessMemory(arg[1], arg[3]))
|
||||||
// TODO this way extcodecopy and codecopy do the same thing.
|
// TODO this way extcodecopy and codecopy do the same thing.
|
||||||
copyZeroExtended(
|
copyZeroExtended(
|
||||||
m_state.memory, m_state.code,
|
m_state.memory, m_state.code,
|
||||||
@ -240,11 +238,10 @@ u256 EVMInstructionInterpreter::eval(
|
|||||||
);
|
);
|
||||||
return 0;
|
return 0;
|
||||||
case Instruction::RETURNDATASIZE:
|
case Instruction::RETURNDATASIZE:
|
||||||
logTrace(_instruction, arg);
|
|
||||||
return m_state.returndata.size();
|
return m_state.returndata.size();
|
||||||
case Instruction::RETURNDATACOPY:
|
case Instruction::RETURNDATACOPY:
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
if (logMemoryWrite(arg[0], arg[2]))
|
if (accessMemory(arg[0], arg[2]))
|
||||||
copyZeroExtended(
|
copyZeroExtended(
|
||||||
m_state.memory, m_state.returndata,
|
m_state.memory, m_state.returndata,
|
||||||
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
|
size_t(arg[0]), size_t(arg[1]), size_t(arg[2])
|
||||||
@ -267,86 +264,81 @@ u256 EVMInstructionInterpreter::eval(
|
|||||||
return m_state.gaslimit;
|
return m_state.gaslimit;
|
||||||
// --------------- memory / storage / logs ---------------
|
// --------------- memory / storage / logs ---------------
|
||||||
case Instruction::MLOAD:
|
case Instruction::MLOAD:
|
||||||
if (logMemoryRead(arg[0], 0x20))
|
if (accessMemory(arg[0], 0x20))
|
||||||
return u256(*reinterpret_cast<h256 const*>(m_state.memory.data() + size_t(arg[0])));
|
return u256(*reinterpret_cast<h256 const*>(m_state.memory.data() + size_t(arg[0])));
|
||||||
else
|
else
|
||||||
return 0x1234 + arg[0];
|
return 0x1234 + arg[0];
|
||||||
case Instruction::MSTORE:
|
case Instruction::MSTORE:
|
||||||
if (logMemoryWrite(arg[0], 0x20, h256(arg[1]).asBytes()))
|
if (accessMemory(arg[0], 0x20))
|
||||||
*reinterpret_cast<h256*>(m_state.memory.data() + size_t(arg[0])) = h256(arg[1]);
|
*reinterpret_cast<h256*>(m_state.memory.data() + size_t(arg[0])) = h256(arg[1]);
|
||||||
return 0;
|
return 0;
|
||||||
case Instruction::MSTORE8:
|
case Instruction::MSTORE8:
|
||||||
if (logMemoryWrite(arg[0], 1, bytes{1, uint8_t(arg[1] & 0xff)}))
|
if (accessMemory(arg[0], 1))
|
||||||
m_state.memory[size_t(arg[0])] = uint8_t(arg[1] & 0xff);
|
m_state.memory[size_t(arg[0])] = uint8_t(arg[1] & 0xff);
|
||||||
return 0;
|
return 0;
|
||||||
case Instruction::SLOAD:
|
case Instruction::SLOAD:
|
||||||
logTrace(_instruction, arg);
|
|
||||||
return m_state.storage[h256(arg[0])];
|
return m_state.storage[h256(arg[0])];
|
||||||
case Instruction::SSTORE:
|
case Instruction::SSTORE:
|
||||||
logTrace(Instruction::SSTORE, arg);
|
|
||||||
m_state.storage[h256(arg[0])] = h256(arg[1]);
|
m_state.storage[h256(arg[0])] = h256(arg[1]);
|
||||||
return 0;
|
return 0;
|
||||||
case Instruction::PC:
|
case Instruction::PC:
|
||||||
logTrace(_instruction);
|
|
||||||
return 0x77;
|
return 0x77;
|
||||||
case Instruction::MSIZE:
|
case Instruction::MSIZE:
|
||||||
logTrace(_instruction);
|
|
||||||
return m_state.msize;
|
return m_state.msize;
|
||||||
case Instruction::GAS:
|
case Instruction::GAS:
|
||||||
logTrace(_instruction);
|
|
||||||
return 0x99;
|
return 0x99;
|
||||||
case Instruction::LOG0:
|
case Instruction::LOG0:
|
||||||
logMemoryRead(arg[0], arg[1]);
|
accessMemory(arg[0], arg[1]);
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
return 0;
|
return 0;
|
||||||
case Instruction::LOG1:
|
case Instruction::LOG1:
|
||||||
logMemoryRead(arg[0], arg[1]);
|
accessMemory(arg[0], arg[1]);
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
return 0;
|
return 0;
|
||||||
case Instruction::LOG2:
|
case Instruction::LOG2:
|
||||||
logMemoryRead(arg[0], arg[1]);
|
accessMemory(arg[0], arg[1]);
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
return 0;
|
return 0;
|
||||||
case Instruction::LOG3:
|
case Instruction::LOG3:
|
||||||
logMemoryRead(arg[0], arg[1]);
|
accessMemory(arg[0], arg[1]);
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
return 0;
|
return 0;
|
||||||
case Instruction::LOG4:
|
case Instruction::LOG4:
|
||||||
logMemoryRead(arg[0], arg[1]);
|
accessMemory(arg[0], arg[1]);
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
return 0;
|
return 0;
|
||||||
// --------------- calls ---------------
|
// --------------- calls ---------------
|
||||||
case Instruction::CREATE:
|
case Instruction::CREATE:
|
||||||
logMemoryRead(arg[1], arg[2]);
|
accessMemory(arg[1], arg[2]);
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
return 0xcccccc + arg[1];
|
return 0xcccccc + arg[1];
|
||||||
case Instruction::CREATE2:
|
case Instruction::CREATE2:
|
||||||
logMemoryRead(arg[2], arg[3]);
|
accessMemory(arg[2], arg[3]);
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
return 0xdddddd + arg[1];
|
return 0xdddddd + arg[1];
|
||||||
case Instruction::CALL:
|
case Instruction::CALL:
|
||||||
case Instruction::CALLCODE:
|
case Instruction::CALLCODE:
|
||||||
// TODO assign returndata
|
// TODO assign returndata
|
||||||
logMemoryRead(arg[3], arg[4]);
|
accessMemory(arg[3], arg[4]);
|
||||||
logMemoryWrite(arg[5], arg[6]);
|
accessMemory(arg[5], arg[6]);
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
return arg[0] & 1;
|
return arg[0] & 1;
|
||||||
case Instruction::DELEGATECALL:
|
case Instruction::DELEGATECALL:
|
||||||
case Instruction::STATICCALL:
|
case Instruction::STATICCALL:
|
||||||
logMemoryRead(arg[2], arg[3]);
|
accessMemory(arg[2], arg[3]);
|
||||||
logMemoryWrite(arg[4], arg[5]);
|
accessMemory(arg[4], arg[5]);
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
return 0;
|
return 0;
|
||||||
case Instruction::RETURN:
|
case Instruction::RETURN:
|
||||||
{
|
{
|
||||||
bytes data;
|
bytes data;
|
||||||
if (logMemoryRead(arg[0], arg[1]))
|
if (accessMemory(arg[0], arg[1]))
|
||||||
data = bytesConstRef(m_state.memory.data() + size_t(arg[0]), size_t(arg[1])).toBytes();
|
data = bytesConstRef(m_state.memory.data() + size_t(arg[0]), size_t(arg[1])).toBytes();
|
||||||
logTrace(_instruction, arg, data);
|
logTrace(_instruction, arg, data);
|
||||||
throw ExplicitlyTerminated();
|
throw ExplicitlyTerminated();
|
||||||
}
|
}
|
||||||
case Instruction::REVERT:
|
case Instruction::REVERT:
|
||||||
logMemoryRead(arg[0], arg[1]);
|
accessMemory(arg[0], arg[1]);
|
||||||
logTrace(_instruction, arg);
|
logTrace(_instruction, arg);
|
||||||
throw ExplicitlyTerminated();
|
throw ExplicitlyTerminated();
|
||||||
case Instruction::INVALID:
|
case Instruction::INVALID:
|
||||||
@ -456,7 +448,7 @@ u256 EVMInstructionInterpreter::evalBuiltin(BuiltinFunctionForEVM const& _fun, c
|
|||||||
else if (_fun.name == "datacopy"_yulstring)
|
else if (_fun.name == "datacopy"_yulstring)
|
||||||
{
|
{
|
||||||
// This is identical to codecopy.
|
// This is identical to codecopy.
|
||||||
if (logMemoryWrite(_arguments.at(0), _arguments.at(2)))
|
if (accessMemory(_arguments.at(0), _arguments.at(2)))
|
||||||
copyZeroExtended(
|
copyZeroExtended(
|
||||||
m_state.memory,
|
m_state.memory,
|
||||||
m_state.code,
|
m_state.code,
|
||||||
@ -470,20 +462,9 @@ u256 EVMInstructionInterpreter::evalBuiltin(BuiltinFunctionForEVM const& _fun, c
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EVMInstructionInterpreter::logMemoryRead(u256 const& _offset, u256 const& _size)
|
|
||||||
{
|
|
||||||
return logMemory(false, _offset, _size);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EVMInstructionInterpreter::logMemoryWrite(u256 const& _offset, u256 const& _size, bytes const& _data)
|
bool EVMInstructionInterpreter::accessMemory(u256 const& _offset, u256 const& _size)
|
||||||
{
|
{
|
||||||
return logMemory(true, _offset, _size, _data);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EVMInstructionInterpreter::logMemory(bool _write, u256 const& _offset, u256 const& _size, bytes const& _data)
|
|
||||||
{
|
|
||||||
logTrace(_write ? "MSTORE_AT_SIZE" : "MLOAD_FROM_SIZE", {_offset, _size}, _data);
|
|
||||||
|
|
||||||
if (((_offset + _size) >= _offset) && ((_offset + _size + 0x1f) >= (_offset + _size)))
|
if (((_offset + _size) >= _offset) && ((_offset + _size + 0x1f) >= (_offset + _size)))
|
||||||
{
|
{
|
||||||
u256 newSize = (_offset + _size + 0x1f) & ~u256(0x1f);
|
u256 newSize = (_offset + _size + 0x1f) & ~u256(0x1f);
|
||||||
|
@ -75,14 +75,9 @@ public:
|
|||||||
dev::u256 evalBuiltin(BuiltinFunctionForEVM const& _fun, std::vector<dev::u256> const& _arguments);
|
dev::u256 evalBuiltin(BuiltinFunctionForEVM const& _fun, std::vector<dev::u256> const& _arguments);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Record a memory read in the trace. Also updates m_state.msize
|
/// Resizes the memory to accommodate the memory access.
|
||||||
/// @returns true if m_state.memory can be used at that offset.
|
/// @returns false if memory would have to be expanded beyond m_state.maxMemSize.
|
||||||
bool logMemoryRead(dev::u256 const& _offset, dev::u256 const& _size = 32);
|
bool accessMemory(dev::u256 const& _offset, dev::u256 const& _size = 32);
|
||||||
/// Record a memory write in the trace. Also updates m_state.msize
|
|
||||||
/// @returns true if m_state.memory can be used at that offset.
|
|
||||||
bool logMemoryWrite(dev::u256 const& _offset, dev::u256 const& _size = 32, dev::bytes const& _data = {});
|
|
||||||
|
|
||||||
bool logMemory(bool _write, dev::u256 const& _offset, dev::u256 const& _size = 32, dev::bytes const& _data = {});
|
|
||||||
|
|
||||||
void logTrace(dev::eth::Instruction _instruction, std::vector<dev::u256> const& _arguments = {}, dev::bytes const& _data = {});
|
void logTrace(dev::eth::Instruction _instruction, std::vector<dev::u256> const& _arguments = {}, dev::bytes const& _data = {});
|
||||||
/// Appends a log to the trace representing an instruction or similar operation by string,
|
/// Appends a log to the trace representing an instruction or similar operation by string,
|
||||||
|
@ -32,12 +32,33 @@
|
|||||||
#include <libdevcore/FixedHash.h>
|
#include <libdevcore/FixedHash.h>
|
||||||
|
|
||||||
#include <boost/range/adaptor/reversed.hpp>
|
#include <boost/range/adaptor/reversed.hpp>
|
||||||
|
#include <boost/algorithm/cxx11/all_of.hpp>
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace dev;
|
using namespace dev;
|
||||||
using namespace yul;
|
using namespace yul;
|
||||||
using namespace yul::test;
|
using namespace yul::test;
|
||||||
|
|
||||||
|
void InterpreterState::dumpTraceAndState(ostream& _out) const
|
||||||
|
{
|
||||||
|
_out << "Trace:" << endl;
|
||||||
|
for (auto const& line: trace)
|
||||||
|
_out << " " << line << endl;
|
||||||
|
_out << "Memory dump:\n";
|
||||||
|
for (size_t i = 0; i < memory.size(); i += 0x20)
|
||||||
|
{
|
||||||
|
bytesConstRef data(memory.data() + i, 0x20);
|
||||||
|
if (boost::algorithm::all_of_equal(data, 0))
|
||||||
|
continue;
|
||||||
|
_out << " " << std::hex << std::setw(4) << i << ": " << toHex(data.toBytes()) << endl;
|
||||||
|
}
|
||||||
|
_out << "Storage dump:" << endl;
|
||||||
|
for (auto const& slot: storage)
|
||||||
|
if (slot.second != h256(0))
|
||||||
|
_out << " " << slot.first.hex() << ": " << slot.second.hex() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
void Interpreter::operator()(ExpressionStatement const& _expressionStatement)
|
void Interpreter::operator()(ExpressionStatement const& _expressionStatement)
|
||||||
{
|
{
|
||||||
|
@ -92,6 +92,8 @@ struct InterpreterState
|
|||||||
size_t maxSteps = 0;
|
size_t maxSteps = 0;
|
||||||
size_t numSteps = 0;
|
size_t numSteps = 0;
|
||||||
LoopState loopState = LoopState::Default;
|
LoopState loopState = LoopState::Default;
|
||||||
|
|
||||||
|
void dumpTraceAndState(std::ostream& _out) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,15 +98,7 @@ void interpret(string const& _source)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "Trace:" << endl;
|
state.dumpTraceAndState(cout);
|
||||||
for (auto const& line: interpreter.trace())
|
|
||||||
cout << " " << line << endl;
|
|
||||||
cout << "Memory dump:" << endl;
|
|
||||||
for (size_t i = 0; i < state.memory.size(); i += 0x20)
|
|
||||||
cout << " " << std::hex << std::setw(4) << i << ": " << toHex(bytesConstRef(state.memory.data() + i, 0x20).toBytes()) << endl;
|
|
||||||
cout << "Storage dump:" << endl;
|
|
||||||
for (auto const& slot: state.storage)
|
|
||||||
cout << " " << slot.first.hex() << ": " << slot.second.hex() << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user