From 91312e657bcc378e8a6b96b34b17d7c471a68c26 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 21 May 2019 11:46:37 +0200 Subject: [PATCH 1/5] Skip empty entries in memory and storage dump. --- libdevcore/vector_ref.h | 2 + test/libyul/YulInterpreterTest.cpp | 10 +- test/libyul/yulInterpreterTests/datacopy.yul | 94 ------------------- .../yulInterpreterTests/external_call.yul | 3 - test/libyul/yulInterpreterTests/loop.yul | 2 - .../recursive_function_for_loop.yul | 4 - .../yulInterpreterTests/simple_mstore.yul | 1 - .../yulInterpreterTests/switch_statement.yul | 1 - test/tools/ossfuzz/yulFuzzerCommon.cpp | 4 +- test/tools/yulInterpreter/Interpreter.cpp | 21 +++++ test/tools/yulInterpreter/Interpreter.h | 2 + test/tools/yulrun.cpp | 10 +- 12 files changed, 28 insertions(+), 126 deletions(-) diff --git a/libdevcore/vector_ref.h b/libdevcore/vector_ref.h index b4dcff651..a866f6628 100644 --- a/libdevcore/vector_ref.h +++ b/libdevcore/vector_ref.h @@ -25,6 +25,8 @@ public: using mutable_value_type = typename std::conditional::value, typename std::remove_const<_T>::type, _T>::type; using string_type = typename std::conditional::value, std::string const, std::string>::type; using vector_type = typename std::conditional::value, std::vector::type> const, std::vector<_T>>::type; + using iterator = _T*; + using const_iterator = _T const*; static_assert(std::is_pod::value, "vector_ref can only be used with PODs due to its low-level treatment of data."); diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index 606f1c989..b918fd8ee 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -142,15 +142,7 @@ string YulInterpreterTest::interpret() } stringstream result; - result << "Trace:" << endl;; - 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; + state.dumpTraceAndState(result); return result.str(); } diff --git a/test/libyul/yulInterpreterTests/datacopy.yul b/test/libyul/yulInterpreterTests/datacopy.yul index b083b1fe2..cccfdea07 100644 --- a/test/libyul/yulInterpreterTests/datacopy.yul +++ b/test/libyul/yulInterpreterTests/datacopy.yul @@ -17,98 +17,4 @@ object "main" // MLOAD_FROM_SIZE(32, 32) // SSTORE(1, 0) // Memory dump: -// 0: 0000000000000000000000000000000000000000000000000000000000000000 -// 20: 0000000000000000000000000000000000000000000000000000000000000000 -// 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: -// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000000 -// 0000000000000000000000000000000000000000000000000000000000000001: 0000000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libyul/yulInterpreterTests/external_call.yul b/test/libyul/yulInterpreterTests/external_call.yul index a7e0c6bae..6bfb44cd4 100644 --- a/test/libyul/yulInterpreterTests/external_call.yul +++ b/test/libyul/yulInterpreterTests/external_call.yul @@ -10,8 +10,5 @@ // CALL(153, 69, 5, 0, 32, 48, 32) // SSTORE(100, 1) // Memory dump: -// 0: 0000000000000000000000000000000000000000000000000000000000000000 -// 20: 0000000000000000000000000000000000000000000000000000000000000000 -// 40: 0000000000000000000000000000000000000000000000000000000000000000 // Storage dump: // 0000000000000000000000000000000000000000000000000000000000000064: 0000000000000000000000000000000000000000000000000000000000000001 diff --git a/test/libyul/yulInterpreterTests/loop.yul b/test/libyul/yulInterpreterTests/loop.yul index 45f584ab0..03d4ae3f3 100644 --- a/test/libyul/yulInterpreterTests/loop.yul +++ b/test/libyul/yulInterpreterTests/loop.yul @@ -14,7 +14,5 @@ // MSTORE_AT_SIZE(40, 32) [0000000000000000000000000000000000000000000000000000000000008000] // MSTORE_AT_SIZE(45, 32) [0000000000000000000000000000000000000000000000000000000000009000] // Memory dump: -// 0: 0000000000000000000000000000000000000000000000000000000000000000 -// 20: 0000000000000000000000000000000000000000000000000000000000000000 // 40: 0000000000000000000000900000000000000000000000000000000000000000 // Storage dump: diff --git a/test/libyul/yulInterpreterTests/recursive_function_for_loop.yul b/test/libyul/yulInterpreterTests/recursive_function_for_loop.yul index 003c71ee6..87e540cf5 100644 --- a/test/libyul/yulInterpreterTests/recursive_function_for_loop.yul +++ b/test/libyul/yulInterpreterTests/recursive_function_for_loop.yul @@ -30,8 +30,4 @@ // SSTORE(0, 0) // Memory dump: // 0: 0001000000000000000000000000000000000000000000000000000000000000 -// 20: 0000000000000000000000000000000000000000000000000000000000000000 -// 40: 0000000000000000000000000000000000000000000000000000000000000000 -// 60: 0000000000000000000000000000000000000000000000000000000000000000 // Storage dump: -// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libyul/yulInterpreterTests/simple_mstore.yul b/test/libyul/yulInterpreterTests/simple_mstore.yul index 879b03801..f1e90b95e 100644 --- a/test/libyul/yulInterpreterTests/simple_mstore.yul +++ b/test/libyul/yulInterpreterTests/simple_mstore.yul @@ -5,6 +5,5 @@ // Trace: // MSTORE_AT_SIZE(10, 32) [000000000000000000000000000000000000000000000000000000000000000b] // Memory dump: -// 0: 0000000000000000000000000000000000000000000000000000000000000000 // 20: 0000000000000000000b00000000000000000000000000000000000000000000 // Storage dump: diff --git a/test/libyul/yulInterpreterTests/switch_statement.yul b/test/libyul/yulInterpreterTests/switch_statement.yul index 06ac3703a..2d429093d 100644 --- a/test/libyul/yulInterpreterTests/switch_statement.yul +++ b/test/libyul/yulInterpreterTests/switch_statement.yul @@ -8,6 +8,5 @@ // Trace: // MSTORE_AT_SIZE(1, 32) [0000000000000000000000000000000000000000000000000000000000000002] // Memory dump: -// 0: 0000000000000000000000000000000000000000000000000000000000000000 // 20: 0200000000000000000000000000000000000000000000000000000000000000 // Storage dump: diff --git a/test/tools/ossfuzz/yulFuzzerCommon.cpp b/test/tools/ossfuzz/yulFuzzerCommon.cpp index 4d28554a2..0931b8e41 100644 --- a/test/tools/ossfuzz/yulFuzzerCommon.cpp +++ b/test/tools/ossfuzz/yulFuzzerCommon.cpp @@ -35,7 +35,5 @@ void yulFuzzerUtil::interpret( state.maxMemSize = _maxMemory; Interpreter interpreter(state, _dialect); interpreter(*_ast); - _os << "Trace:" << endl; - for (auto const& line: interpreter.trace()) - _os << " " << line << endl; + state.dumpTraceAndState(_os); } diff --git a/test/tools/yulInterpreter/Interpreter.cpp b/test/tools/yulInterpreter/Interpreter.cpp index ff6a0cc99..7bcd4771e 100644 --- a/test/tools/yulInterpreter/Interpreter.cpp +++ b/test/tools/yulInterpreter/Interpreter.cpp @@ -32,12 +32,33 @@ #include #include +#include + +#include using namespace std; using namespace dev; using namespace yul; 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) { diff --git a/test/tools/yulInterpreter/Interpreter.h b/test/tools/yulInterpreter/Interpreter.h index cf449a017..6fc20280a 100644 --- a/test/tools/yulInterpreter/Interpreter.h +++ b/test/tools/yulInterpreter/Interpreter.h @@ -92,6 +92,8 @@ struct InterpreterState size_t maxSteps = 0; size_t numSteps = 0; LoopState loopState = LoopState::Default; + + void dumpTraceAndState(std::ostream& _out) const; }; /** diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index 9a559d220..fb544231f 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -98,15 +98,7 @@ void interpret(string const& _source) { } - cout << "Trace:" << endl; - 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; + state.dumpTraceAndState(cout); } } From 3ef03258ec2c0c25a1e1bc694a3839651e9505ff Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 23 May 2019 11:35:12 +0200 Subject: [PATCH 2/5] Remove memory logging. --- .../EVMInstructionInterpreter.cpp | 57 ++++++++----------- .../EVMInstructionInterpreter.h | 11 +--- 2 files changed, 26 insertions(+), 42 deletions(-) diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index 13b8066fa..7a1e7bebb 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -186,7 +186,7 @@ u256 EVMInstructionInterpreter::eval( // --------------- blockchain stuff --------------- case Instruction::KECCAK256: { - if (!logMemoryRead(arg[0], arg[1])) + if (!accessMemory(arg[0], arg[1])) return u256("0x1234cafe1234cafe1234cafe") + arg[0]; uint64_t offset = uint64_t(arg[0] & uint64_t(-1)); uint64_t size = uint64_t(arg[1] & uint64_t(-1)); @@ -207,7 +207,7 @@ u256 EVMInstructionInterpreter::eval( case Instruction::CALLDATASIZE: return m_state.calldata.size(); case Instruction::CALLDATACOPY: - if (logMemoryWrite(arg[0], arg[2])) + if (accessMemory(arg[0], arg[2])) copyZeroExtended( m_state.memory, m_state.calldata, size_t(arg[0]), size_t(arg[1]), size_t(arg[2]) @@ -216,7 +216,7 @@ u256 EVMInstructionInterpreter::eval( case Instruction::CODESIZE: return m_state.code.size(); case Instruction::CODECOPY: - if (logMemoryWrite(arg[0], arg[2])) + if (accessMemory(arg[0], arg[2])) copyZeroExtended( m_state.memory, m_state.code, size_t(arg[0]), size_t(arg[1]), size_t(arg[2]) @@ -232,7 +232,7 @@ u256 EVMInstructionInterpreter::eval( return u256(keccak256(h256(arg[0] + 1))); case Instruction::EXTCODECOPY: 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. copyZeroExtended( m_state.memory, m_state.code, @@ -244,7 +244,7 @@ u256 EVMInstructionInterpreter::eval( return m_state.returndata.size(); case Instruction::RETURNDATACOPY: logTrace(_instruction, arg); - if (logMemoryWrite(arg[0], arg[2])) + if (accessMemory(arg[0], arg[2])) copyZeroExtended( m_state.memory, m_state.returndata, size_t(arg[0]), size_t(arg[1]), size_t(arg[2]) @@ -267,16 +267,16 @@ u256 EVMInstructionInterpreter::eval( return m_state.gaslimit; // --------------- memory / storage / logs --------------- case Instruction::MLOAD: - if (logMemoryRead(arg[0], 0x20)) + if (accessMemory(arg[0], 0x20)) return u256(*reinterpret_cast(m_state.memory.data() + size_t(arg[0]))); else return 0x1234 + arg[0]; case Instruction::MSTORE: - if (logMemoryWrite(arg[0], 0x20, h256(arg[1]).asBytes())) + if (accessMemory(arg[0], 0x20)) *reinterpret_cast(m_state.memory.data() + size_t(arg[0])) = h256(arg[1]); return 0; 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); return 0; case Instruction::SLOAD: @@ -296,57 +296,57 @@ u256 EVMInstructionInterpreter::eval( logTrace(_instruction); return 0x99; case Instruction::LOG0: - logMemoryRead(arg[0], arg[1]); + accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); return 0; case Instruction::LOG1: - logMemoryRead(arg[0], arg[1]); + accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); return 0; case Instruction::LOG2: - logMemoryRead(arg[0], arg[1]); + accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); return 0; case Instruction::LOG3: - logMemoryRead(arg[0], arg[1]); + accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); return 0; case Instruction::LOG4: - logMemoryRead(arg[0], arg[1]); + accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); return 0; // --------------- calls --------------- case Instruction::CREATE: - logMemoryRead(arg[1], arg[2]); + accessMemory(arg[1], arg[2]); logTrace(_instruction, arg); return 0xcccccc + arg[1]; case Instruction::CREATE2: - logMemoryRead(arg[2], arg[3]); + accessMemory(arg[2], arg[3]); logTrace(_instruction, arg); return 0xdddddd + arg[1]; case Instruction::CALL: case Instruction::CALLCODE: // TODO assign returndata - logMemoryRead(arg[3], arg[4]); - logMemoryWrite(arg[5], arg[6]); + accessMemory(arg[3], arg[4]); + accessMemory(arg[5], arg[6]); logTrace(_instruction, arg); return arg[0] & 1; case Instruction::DELEGATECALL: case Instruction::STATICCALL: - logMemoryRead(arg[2], arg[3]); - logMemoryWrite(arg[4], arg[5]); + accessMemory(arg[2], arg[3]); + accessMemory(arg[4], arg[5]); logTrace(_instruction, arg); return 0; case Instruction::RETURN: { 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(); logTrace(_instruction, arg, data); throw ExplicitlyTerminated(); } case Instruction::REVERT: - logMemoryRead(arg[0], arg[1]); + accessMemory(arg[0], arg[1]); logTrace(_instruction, arg); throw ExplicitlyTerminated(); case Instruction::INVALID: @@ -456,7 +456,7 @@ u256 EVMInstructionInterpreter::evalBuiltin(BuiltinFunctionForEVM const& _fun, c else if (_fun.name == "datacopy"_yulstring) { // This is identical to codecopy. - if (logMemoryWrite(_arguments.at(0), _arguments.at(2))) + if (accessMemory(_arguments.at(0), _arguments.at(2))) copyZeroExtended( m_state.memory, m_state.code, @@ -470,20 +470,9 @@ u256 EVMInstructionInterpreter::evalBuiltin(BuiltinFunctionForEVM const& _fun, c 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))) { u256 newSize = (_offset + _size + 0x1f) & ~u256(0x1f); diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.h b/test/tools/yulInterpreter/EVMInstructionInterpreter.h index 970b8094b..0c087410a 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.h +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.h @@ -75,14 +75,9 @@ public: dev::u256 evalBuiltin(BuiltinFunctionForEVM const& _fun, std::vector const& _arguments); private: - /// Record a memory read in the trace. Also updates m_state.msize - /// @returns true if m_state.memory can be used at that offset. - bool logMemoryRead(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 = {}); + /// Resizes the memory to accommodate the memory access. + /// @returns false if memory would have to be expanded beyond m_state.maxMemSize. + bool accessMemory(dev::u256 const& _offset, dev::u256 const& _size = 32); void logTrace(dev::eth::Instruction _instruction, std::vector const& _arguments = {}, dev::bytes const& _data = {}); /// Appends a log to the trace representing an instruction or similar operation by string, From 1ca3edf6a1f2e18ba49bfdc3341d481e742c576f Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 23 May 2019 11:44:07 +0200 Subject: [PATCH 3/5] Remove side-effect-free instructions from the trace. --- test/tools/yulInterpreter/EVMInstructionInterpreter.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp index 7a1e7bebb..a86614b0c 100644 --- a/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp +++ b/test/tools/yulInterpreter/EVMInstructionInterpreter.cpp @@ -225,10 +225,8 @@ u256 EVMInstructionInterpreter::eval( case Instruction::GASPRICE: return m_state.gasprice; case Instruction::EXTCODESIZE: - logTrace(_instruction, arg); return u256(keccak256(h256(arg[0]))) & 0xffffff; case Instruction::EXTCODEHASH: - logTrace(_instruction, arg); return u256(keccak256(h256(arg[0] + 1))); case Instruction::EXTCODECOPY: logTrace(_instruction, arg); @@ -240,7 +238,6 @@ u256 EVMInstructionInterpreter::eval( ); return 0; case Instruction::RETURNDATASIZE: - logTrace(_instruction, arg); return m_state.returndata.size(); case Instruction::RETURNDATACOPY: logTrace(_instruction, arg); @@ -280,20 +277,15 @@ u256 EVMInstructionInterpreter::eval( m_state.memory[size_t(arg[0])] = uint8_t(arg[1] & 0xff); return 0; case Instruction::SLOAD: - logTrace(_instruction, arg); return m_state.storage[h256(arg[0])]; case Instruction::SSTORE: - logTrace(Instruction::SSTORE, arg); m_state.storage[h256(arg[0])] = h256(arg[1]); return 0; case Instruction::PC: - logTrace(_instruction); return 0x77; case Instruction::MSIZE: - logTrace(_instruction); return m_state.msize; case Instruction::GAS: - logTrace(_instruction); return 0x99; case Instruction::LOG0: accessMemory(arg[0], arg[1]); From 14545852d17964513a4504d0dd1d01ccefe15caf Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 23 May 2019 12:22:17 +0200 Subject: [PATCH 4/5] Make YulInterpreterTest EVM version aware. --- test/libyul/YulInterpreterTest.cpp | 8 ++------ test/libyul/YulInterpreterTest.h | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index b918fd8ee..d473c3a5c 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -53,13 +53,9 @@ YulInterpreterTest::YulInterpreterTest(string const& _filename) BOOST_THROW_EXCEPTION(runtime_error("Cannot open test case: \"" + _filename + "\".")); file.exceptions(ios::badbit); + m_source = parseSourceAndSettings(file); + string line; - while (getline(file, line)) - { - if (boost::algorithm::starts_with(line, "// ----")) - break; - m_source += std::move(line) + "\n"; - } while (getline(file, line)) if (boost::algorithm::starts_with(line, "// ")) m_expectation += line.substr(3) + "\n"; diff --git a/test/libyul/YulInterpreterTest.h b/test/libyul/YulInterpreterTest.h index 5f3eb3761..4263b7336 100644 --- a/test/libyul/YulInterpreterTest.h +++ b/test/libyul/YulInterpreterTest.h @@ -37,7 +37,7 @@ namespace yul namespace test { -class YulInterpreterTest: public dev::solidity::test::TestCase +class YulInterpreterTest: public dev::solidity::test::EVMVersionRestrictedTestCase { public: static std::unique_ptr create(Config const& _config) From 3c548a1d76c2656fe7672d23c9ceb703a0c058ac Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 23 May 2019 12:01:02 +0200 Subject: [PATCH 5/5] Update tests. --- .../yulInterpreterTests/ambiguous_vars.yul | 2 -- test/libyul/yulInterpreterTests/datacopy.yul | 14 ++++++------- .../libyul/yulInterpreterTests/dataoffset.yul | 2 -- test/libyul/yulInterpreterTests/datasize.yul | 2 -- test/libyul/yulInterpreterTests/exp.yul | 1 - .../yulInterpreterTests/external_call.yul | 4 ---- .../yulInterpreterTests/function_calls.yul | 1 - test/libyul/yulInterpreterTests/loop.yul | 8 ------- .../recursive_function_for_loop.yul | 19 ++++------------- .../yulInterpreterTests/side_effect_free.yul | 21 +++++++++++++++++++ .../yulInterpreterTests/simple_mstore.yul | 1 - .../yulInterpreterTests/switch_statement.yul | 1 - 12 files changed, 31 insertions(+), 45 deletions(-) create mode 100644 test/libyul/yulInterpreterTests/side_effect_free.yul diff --git a/test/libyul/yulInterpreterTests/ambiguous_vars.yul b/test/libyul/yulInterpreterTests/ambiguous_vars.yul index c5c723e99..25e0928ae 100644 --- a/test/libyul/yulInterpreterTests/ambiguous_vars.yul +++ b/test/libyul/yulInterpreterTests/ambiguous_vars.yul @@ -8,8 +8,6 @@ } // ---- // Trace: -// MSTORE_AT_SIZE(32, 32) [0000000000000000000000000000000000000000000000000000000000000002] -// MSTORE_AT_SIZE(0, 32) [0000000000000000000000000000000000000000000000000000000000000003] // Memory dump: // 0: 0000000000000000000000000000000000000000000000000000000000000003 // 20: 0000000000000000000000000000000000000000000000000000000000000002 diff --git a/test/libyul/yulInterpreterTests/datacopy.yul b/test/libyul/yulInterpreterTests/datacopy.yul index cccfdea07..fb8998c8b 100644 --- a/test/libyul/yulInterpreterTests/datacopy.yul +++ b/test/libyul/yulInterpreterTests/datacopy.yul @@ -1,8 +1,8 @@ object "main" { code { - datacopy(0, dataoffset("main"), datasize("main")) - datacopy(32, dataoffset("sub"), datasize("sub")) + datacopy(0, and(dataoffset("main"), 15), and(datasize("main"), 15)) + datacopy(32, and(dataoffset("sub"), 15), and(datasize("sub"), 15)) sstore(0, mload(0)) sstore(1, mload(32)) } @@ -10,11 +10,9 @@ object "main" } // ---- // 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: +// 0: 6465636f00000000000000000000000000000000000000000000000000000000 +// 20: 636f6465636f6465000000000000000000000000000000000000000000000000 // Storage dump: +// 0000000000000000000000000000000000000000000000000000000000000000: 6465636f00000000000000000000000000000000000000000000000000000000 +// 0000000000000000000000000000000000000000000000000000000000000001: 636f6465636f6465000000000000000000000000000000000000000000000000 diff --git a/test/libyul/yulInterpreterTests/dataoffset.yul b/test/libyul/yulInterpreterTests/dataoffset.yul index c4757624a..399a8c95c 100644 --- a/test/libyul/yulInterpreterTests/dataoffset.yul +++ b/test/libyul/yulInterpreterTests/dataoffset.yul @@ -8,8 +8,6 @@ object "main" } // ---- // Trace: -// SSTORE(0, 110) -// SSTORE(1, 1804) // Memory dump: // Storage dump: // 0000000000000000000000000000000000000000000000000000000000000000: 000000000000000000000000000000000000000000000000000000000000006e diff --git a/test/libyul/yulInterpreterTests/datasize.yul b/test/libyul/yulInterpreterTests/datasize.yul index a0400eea8..6e38e9321 100644 --- a/test/libyul/yulInterpreterTests/datasize.yul +++ b/test/libyul/yulInterpreterTests/datasize.yul @@ -8,8 +8,6 @@ object "main" } // ---- // Trace: -// SSTORE(0, 2916) -// SSTORE(1, 265) // Memory dump: // Storage dump: // 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000b64 diff --git a/test/libyul/yulInterpreterTests/exp.yul b/test/libyul/yulInterpreterTests/exp.yul index 1cdba5839..07e7d7f72 100644 --- a/test/libyul/yulInterpreterTests/exp.yul +++ b/test/libyul/yulInterpreterTests/exp.yul @@ -3,7 +3,6 @@ } // ---- // Trace: -// MSTORE_AT_SIZE(0, 32) [8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e39] // Memory dump: // 0: 8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e39 // Storage dump: diff --git a/test/libyul/yulInterpreterTests/external_call.yul b/test/libyul/yulInterpreterTests/external_call.yul index 6bfb44cd4..b0d3383a4 100644 --- a/test/libyul/yulInterpreterTests/external_call.yul +++ b/test/libyul/yulInterpreterTests/external_call.yul @@ -4,11 +4,7 @@ } // ---- // Trace: -// GAS() -// MLOAD_FROM_SIZE(0, 32) -// MSTORE_AT_SIZE(48, 32) // CALL(153, 69, 5, 0, 32, 48, 32) -// SSTORE(100, 1) // Memory dump: // Storage dump: // 0000000000000000000000000000000000000000000000000000000000000064: 0000000000000000000000000000000000000000000000000000000000000001 diff --git a/test/libyul/yulInterpreterTests/function_calls.yul b/test/libyul/yulInterpreterTests/function_calls.yul index 3738a9a2c..2abc26380 100644 --- a/test/libyul/yulInterpreterTests/function_calls.yul +++ b/test/libyul/yulInterpreterTests/function_calls.yul @@ -8,7 +8,6 @@ } // ---- // Trace: -// SSTORE(13, 42) // Memory dump: // Storage dump: // 000000000000000000000000000000000000000000000000000000000000000d: 000000000000000000000000000000000000000000000000000000000000002a diff --git a/test/libyul/yulInterpreterTests/loop.yul b/test/libyul/yulInterpreterTests/loop.yul index 03d4ae3f3..08ed090c3 100644 --- a/test/libyul/yulInterpreterTests/loop.yul +++ b/test/libyul/yulInterpreterTests/loop.yul @@ -5,14 +5,6 @@ } // ---- // 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: // 40: 0000000000000000000000900000000000000000000000000000000000000000 // Storage dump: diff --git a/test/libyul/yulInterpreterTests/recursive_function_for_loop.yul b/test/libyul/yulInterpreterTests/recursive_function_for_loop.yul index 87e540cf5..b3cd4b48c 100644 --- a/test/libyul/yulInterpreterTests/recursive_function_for_loop.yul +++ b/test/libyul/yulInterpreterTests/recursive_function_for_loop.yul @@ -5,29 +5,18 @@ } function foo_0(x) -> y { + y := 1 mstore8(1, 1) - for { - } - slt(1, keccak256(1, msize())) - { - let x_1 := foo_0(x) - } + for { } slt(1, keccak256(1, msize())) { let x_1 := foo_0(x) } { + y := add(y, 1) continue } } } // ---- // 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: // 0: 0001000000000000000000000000000000000000000000000000000000000000 // Storage dump: +// 0000000000000000000000000000000000000000000000000000000000000000: 0000000000000000000000000000000000000000000000000000000000000002 diff --git a/test/libyul/yulInterpreterTests/side_effect_free.yul b/test/libyul/yulInterpreterTests/side_effect_free.yul new file mode 100644 index 000000000..8eac1f5a9 --- /dev/null +++ b/test/libyul/yulInterpreterTests/side_effect_free.yul @@ -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: diff --git a/test/libyul/yulInterpreterTests/simple_mstore.yul b/test/libyul/yulInterpreterTests/simple_mstore.yul index f1e90b95e..3beef347d 100644 --- a/test/libyul/yulInterpreterTests/simple_mstore.yul +++ b/test/libyul/yulInterpreterTests/simple_mstore.yul @@ -3,7 +3,6 @@ } // ---- // Trace: -// MSTORE_AT_SIZE(10, 32) [000000000000000000000000000000000000000000000000000000000000000b] // Memory dump: // 20: 0000000000000000000b00000000000000000000000000000000000000000000 // Storage dump: diff --git a/test/libyul/yulInterpreterTests/switch_statement.yul b/test/libyul/yulInterpreterTests/switch_statement.yul index 2d429093d..1a067ee1b 100644 --- a/test/libyul/yulInterpreterTests/switch_statement.yul +++ b/test/libyul/yulInterpreterTests/switch_statement.yul @@ -6,7 +6,6 @@ } // ---- // Trace: -// MSTORE_AT_SIZE(1, 32) [0000000000000000000000000000000000000000000000000000000000000002] // Memory dump: // 20: 0200000000000000000000000000000000000000000000000000000000000000 // Storage dump: