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,