From fa5c0293f5a74f916f3a856ddac6550ef0e3f5b5 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 18 Sep 2024 21:57:31 +0700 Subject: [PATCH 001/101] Copy interpreter tool from test as basis --- libyul/CMakeLists.txt | 4 + .../interpreter/EVMInstructionInterpreter.cpp | 704 ++++++++++++++++++ .../interpreter/EVMInstructionInterpreter.h | 176 +++++ libyul/tools/interpreter/Interpreter.cpp | 500 +++++++++++++ libyul/tools/interpreter/Interpreter.h | 312 ++++++++ 5 files changed, 1696 insertions(+) create mode 100644 libyul/tools/interpreter/EVMInstructionInterpreter.cpp create mode 100644 libyul/tools/interpreter/EVMInstructionInterpreter.h create mode 100644 libyul/tools/interpreter/Interpreter.cpp create mode 100644 libyul/tools/interpreter/Interpreter.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index cc4c5051c4bd..53a202c17e8a 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -202,6 +202,10 @@ add_library(yul optimiser/VarDeclInitializer.h optimiser/VarNameCleaner.cpp optimiser/VarNameCleaner.h + tools/interpreter/Interpreter.cpp + tools/interpreter/Interpreter.h + tools/interpreter/EVMInstructionInterpreter.cpp + tools/interpreter/EVMInstructionInterpreter.h ) target_link_libraries(yul PUBLIC evmasm solutil langutil smtutil fmt::fmt-header-only) diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.cpp b/libyul/tools/interpreter/EVMInstructionInterpreter.cpp new file mode 100644 index 000000000000..933c8ba6a41a --- /dev/null +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.cpp @@ -0,0 +1,704 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Yul interpreter module that evaluates EVM instructions. + */ + +#include + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +using namespace solidity; +using namespace solidity::evmasm; +using namespace solidity::yul; +using namespace solidity::yul::tools::interpreter; + +using solidity::util::h160; +using solidity::util::h256; +using solidity::util::keccak256; + +namespace +{ + +/// Reads 32 bytes from @a _data at position @a _offset bytes while +/// interpreting @a _data to be padded with an infinite number of zero +/// bytes beyond its end. +u256 readZeroExtended(bytes const& _data, u256 const& _offset) +{ + if (_offset >= _data.size()) + return 0; + else if (_offset + 32 <= _data.size()) + return *reinterpret_cast(_data.data() + static_cast(_offset)); + else + { + size_t off = static_cast(_offset); + u256 val; + for (size_t i = 0; i < 32; ++i) + { + val <<= 8; + if (off + i < _data.size()) + val += _data[off + i]; + } + return val; + } +} + +} + +namespace solidity::yul::tools::interpreter +{ + +void copyZeroExtended( + std::map& _target, + bytes const& _source, + size_t _targetOffset, + size_t _sourceOffset, + size_t _size +) +{ + for (size_t i = 0; i < _size; ++i) + _target[_targetOffset + i] = (_sourceOffset + i < _source.size() ? _source[_sourceOffset + i] : 0); +} + +void copyZeroExtendedWithOverlap( + std::map& _target, + std::map const& _source, + size_t _targetOffset, + size_t _sourceOffset, + size_t _size +) +{ + if (_targetOffset >= _sourceOffset) + for (size_t i = _size; i > 0; --i) + _target[_targetOffset + i - 1] = (_source.count(_sourceOffset + i - 1) != 0 ? _source.at(_sourceOffset + i - 1) : 0); + else + for (size_t i = 0; i < _size; ++i) + _target[_targetOffset + i] = (_source.count(_sourceOffset + i) != 0 ? _source.at(_sourceOffset + i) : 0); +} + +} + +using u512 = boost::multiprecision::number>; + +u256 EVMInstructionInterpreter::eval( + evmasm::Instruction _instruction, + std::vector const& _arguments +) +{ + using namespace solidity::evmasm; + using evmasm::Instruction; + + auto info = instructionInfo(_instruction, m_evmVersion); + yulAssert(static_cast(info.args) == _arguments.size(), ""); + + auto const& arg = _arguments; + switch (_instruction) + { + case Instruction::STOP: + logTrace(_instruction); + BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); + // --------------- arithmetic --------------- + case Instruction::ADD: + return arg[0] + arg[1]; + case Instruction::MUL: + return arg[0] * arg[1]; + case Instruction::SUB: + return arg[0] - arg[1]; + case Instruction::DIV: + return arg[1] == 0 ? 0 : arg[0] / arg[1]; + case Instruction::SDIV: + return arg[1] == 0 ? 0 : s2u(u2s(arg[0]) / u2s(arg[1])); + case Instruction::MOD: + return arg[1] == 0 ? 0 : arg[0] % arg[1]; + case Instruction::SMOD: + return arg[1] == 0 ? 0 : s2u(u2s(arg[0]) % u2s(arg[1])); + case Instruction::EXP: + return exp256(arg[0], arg[1]); + case Instruction::NOT: + return ~arg[0]; + case Instruction::LT: + return arg[0] < arg[1] ? 1 : 0; + case Instruction::GT: + return arg[0] > arg[1] ? 1 : 0; + case Instruction::SLT: + return u2s(arg[0]) < u2s(arg[1]) ? 1 : 0; + case Instruction::SGT: + return u2s(arg[0]) > u2s(arg[1]) ? 1 : 0; + case Instruction::EQ: + return arg[0] == arg[1] ? 1 : 0; + case Instruction::ISZERO: + return arg[0] == 0 ? 1 : 0; + case Instruction::AND: + return arg[0] & arg[1]; + case Instruction::OR: + return arg[0] | arg[1]; + case Instruction::XOR: + return arg[0] ^ arg[1]; + case Instruction::BYTE: + return arg[0] >= 32 ? 0 : (arg[1] >> unsigned(8 * (31 - arg[0]))) & 0xff; + case Instruction::SHL: + return arg[0] > 255 ? 0 : (arg[1] << unsigned(arg[0])); + case Instruction::SHR: + return arg[0] > 255 ? 0 : (arg[1] >> unsigned(arg[0])); + case Instruction::SAR: + { + static u256 const hibit = u256(1) << 255; + if (arg[0] >= 256) + return arg[1] & hibit ? u256(-1) : 0; + else + { + unsigned amount = unsigned(arg[0]); + u256 v = arg[1] >> amount; + if (arg[1] & hibit) + v |= u256(-1) << (256 - amount); + return v; + } + } + case Instruction::ADDMOD: + return arg[2] == 0 ? 0 : u256((u512(arg[0]) + u512(arg[1])) % arg[2]); + case Instruction::MULMOD: + return arg[2] == 0 ? 0 : u256((u512(arg[0]) * u512(arg[1])) % arg[2]); + case Instruction::SIGNEXTEND: + if (arg[0] >= 31) + return arg[1]; + else + { + unsigned testBit = unsigned(arg[0]) * 8 + 7; + u256 ret = arg[1]; + u256 mask = ((u256(1) << testBit) - 1); + if (boost::multiprecision::bit_test(ret, testBit)) + ret |= ~mask; + else + ret &= mask; + return ret; + } + // --------------- blockchain stuff --------------- + case Instruction::KECCAK256: + { + 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)); + return u256(keccak256(m_state.readMemory(offset, size))); + } + case Instruction::ADDRESS: + return h256(m_state.address, h256::AlignRight); + case Instruction::BALANCE: + if (arg[0] == h256(m_state.address, h256::AlignRight)) + return m_state.selfbalance; + else + return m_state.balance; + case Instruction::SELFBALANCE: + return m_state.selfbalance; + case Instruction::ORIGIN: + return h256(m_state.origin, h256::AlignRight); + case Instruction::CALLER: + return h256(m_state.caller, h256::AlignRight); + case Instruction::CALLVALUE: + return m_state.callvalue; + case Instruction::CALLDATALOAD: + return readZeroExtended(m_state.calldata, arg[0]); + case Instruction::CALLDATASIZE: + return m_state.calldata.size(); + case Instruction::CALLDATACOPY: + 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]) + ); + logTrace(_instruction, arg); + return 0; + case Instruction::CODESIZE: + return m_state.code.size(); + case Instruction::CODECOPY: + 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]) + ); + logTrace(_instruction, arg); + return 0; + case Instruction::GASPRICE: + return m_state.gasprice; + case Instruction::CHAINID: + return m_state.chainid; + case Instruction::BASEFEE: + return m_state.basefee; + case Instruction::BLOBHASH: + return blobHash(arg[0]); + case Instruction::BLOBBASEFEE: + return m_state.blobbasefee; + case Instruction::EXTCODESIZE: + return u256(keccak256(h256(arg[0]))) & 0xffffff; + case Instruction::EXTCODEHASH: + return u256(keccak256(h256(arg[0] + 1))); + case Instruction::EXTCODECOPY: + if (accessMemory(arg[1], arg[3])) + // TODO this way extcodecopy and codecopy do the same thing. + copyZeroExtended( + m_state.memory, m_state.code, + size_t(arg[1]), size_t(arg[2]), size_t(arg[3]) + ); + logTrace(_instruction, arg); + return 0; + case Instruction::RETURNDATASIZE: + return m_state.returndata.size(); + case Instruction::RETURNDATACOPY: + 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]) + ); + logTrace(_instruction, arg); + return 0; + case Instruction::MCOPY: + if (accessMemory(arg[1], arg[2]) && accessMemory(arg[0], arg[2])) + copyZeroExtendedWithOverlap( + m_state.memory, + m_state.memory, + static_cast(arg[0]), + static_cast(arg[1]), + static_cast(arg[2]) + ); + logTrace(_instruction, arg); + return 0; + case Instruction::BLOCKHASH: + if (arg[0] >= m_state.blockNumber || arg[0] + 256 < m_state.blockNumber) + return 0; + else + return 0xaaaaaaaa + (arg[0] - m_state.blockNumber - 256); + case Instruction::COINBASE: + return h256(m_state.coinbase, h256::AlignRight); + case Instruction::TIMESTAMP: + return m_state.timestamp; + case Instruction::NUMBER: + return m_state.blockNumber; + case Instruction::PREVRANDAO: + return (m_evmVersion < langutil::EVMVersion::paris()) ? m_state.difficulty : m_state.prevrandao; + case Instruction::GASLIMIT: + return m_state.gaslimit; + // --------------- memory / storage / logs --------------- + case Instruction::MLOAD: + accessMemory(arg[0], 0x20); + return readMemoryWord(arg[0]); + case Instruction::MSTORE: + accessMemory(arg[0], 0x20); + writeMemoryWord(arg[0], arg[1]); + return 0; + case Instruction::MSTORE8: + accessMemory(arg[0], 1); + m_state.memory[arg[0]] = uint8_t(arg[1] & 0xff); + return 0; + case Instruction::SLOAD: + return m_state.storage[h256(arg[0])]; + case Instruction::SSTORE: + m_state.storage[h256(arg[0])] = h256(arg[1]); + return 0; + case Instruction::PC: + return 0x77; + case Instruction::MSIZE: + return m_state.msize; + case Instruction::GAS: + return 0x99; + case Instruction::LOG0: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + return 0; + case Instruction::LOG1: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + return 0; + case Instruction::LOG2: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + return 0; + case Instruction::LOG3: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + return 0; + case Instruction::LOG4: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + return 0; + case Instruction::TLOAD: + return m_state.transientStorage[h256(arg[0])]; + case Instruction::TSTORE: + m_state.transientStorage[h256(arg[0])] = h256(arg[1]); + return 0; + // --------------- calls --------------- + case Instruction::CREATE: + accessMemory(arg[1], arg[2]); + logTrace(_instruction, arg); + if (arg[2] != 0) + return (0xcccccc + arg[1]) & u256("0xffffffffffffffffffffffffffffffffffffffff"); + else + return 0xcccccc; + case Instruction::CREATE2: + accessMemory(arg[1], arg[2]); + logTrace(_instruction, arg); + if (arg[2] != 0) + return (0xdddddd + arg[1]) & u256("0xffffffffffffffffffffffffffffffffffffffff"); + else + return 0xdddddd; + case Instruction::CALL: + case Instruction::CALLCODE: + accessMemory(arg[3], arg[4]); + accessMemory(arg[5], arg[6]); + logTrace(_instruction, arg); + // Randomly fail based on the called address if it isn't a call to self. + // Used for fuzzing. + return ( + (arg[0] > 0) && + (arg[1] == util::h160::Arith(m_state.address) || (arg[1] & 1)) + ) ? 1 : 0; + case Instruction::DELEGATECALL: + case Instruction::STATICCALL: + accessMemory(arg[2], arg[3]); + accessMemory(arg[4], arg[5]); + logTrace(_instruction, arg); + // Randomly fail based on the called address if it isn't a call to self. + // Used for fuzzing. + return ( + (arg[0] > 0) && + (arg[1] == util::h160::Arith(m_state.address) || (arg[1] & 1)) + ) ? 1 : 0; + case Instruction::RETURN: + { + m_state.returndata = {}; + if (accessMemory(arg[0], arg[1])) + m_state.returndata = m_state.readMemory(arg[0], arg[1]); + logTrace(_instruction, arg, m_state.returndata); + BOOST_THROW_EXCEPTION(ExplicitlyTerminatedWithReturn()); + } + case Instruction::REVERT: + accessMemory(arg[0], arg[1]); + logTrace(_instruction, arg); + m_state.storage.clear(); + m_state.transientStorage.clear(); + BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); + case Instruction::INVALID: + logTrace(_instruction); + m_state.storage.clear(); + m_state.transientStorage.clear(); + m_state.trace.clear(); + BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); + case Instruction::SELFDESTRUCT: + logTrace(_instruction, arg); + m_state.storage.clear(); + m_state.transientStorage.clear(); + m_state.trace.clear(); + BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); + case Instruction::POP: + break; + // --------------- invalid in strict assembly --------------- + case Instruction::JUMP: + case Instruction::JUMPI: + case Instruction::JUMPDEST: + case Instruction::PUSH0: + case Instruction::PUSH1: + case Instruction::PUSH2: + case Instruction::PUSH3: + case Instruction::PUSH4: + case Instruction::PUSH5: + case Instruction::PUSH6: + case Instruction::PUSH7: + case Instruction::PUSH8: + case Instruction::PUSH9: + case Instruction::PUSH10: + case Instruction::PUSH11: + case Instruction::PUSH12: + case Instruction::PUSH13: + case Instruction::PUSH14: + case Instruction::PUSH15: + case Instruction::PUSH16: + case Instruction::PUSH17: + case Instruction::PUSH18: + case Instruction::PUSH19: + case Instruction::PUSH20: + case Instruction::PUSH21: + case Instruction::PUSH22: + case Instruction::PUSH23: + case Instruction::PUSH24: + case Instruction::PUSH25: + case Instruction::PUSH26: + case Instruction::PUSH27: + case Instruction::PUSH28: + case Instruction::PUSH29: + case Instruction::PUSH30: + case Instruction::PUSH31: + case Instruction::PUSH32: + case Instruction::DUP1: + case Instruction::DUP2: + case Instruction::DUP3: + case Instruction::DUP4: + case Instruction::DUP5: + case Instruction::DUP6: + case Instruction::DUP7: + case Instruction::DUP8: + case Instruction::DUP9: + case Instruction::DUP10: + case Instruction::DUP11: + case Instruction::DUP12: + case Instruction::DUP13: + case Instruction::DUP14: + case Instruction::DUP15: + case Instruction::DUP16: + case Instruction::SWAP1: + case Instruction::SWAP2: + case Instruction::SWAP3: + case Instruction::SWAP4: + case Instruction::SWAP5: + case Instruction::SWAP6: + case Instruction::SWAP7: + case Instruction::SWAP8: + case Instruction::SWAP9: + case Instruction::SWAP10: + case Instruction::SWAP11: + case Instruction::SWAP12: + case Instruction::SWAP13: + case Instruction::SWAP14: + case Instruction::SWAP15: + case Instruction::SWAP16: + { + yulAssert(false, ""); + return 0; + } + } + + return 0; +} + +u256 EVMInstructionInterpreter::evalBuiltin( + BuiltinFunctionForEVM const& _fun, + std::vector const& _arguments, + std::vector const& _evaluatedArguments +) +{ + if (_fun.instruction) + return eval(*_fun.instruction, _evaluatedArguments); + + std::string fun = _fun.name.str(); + // Evaluate datasize/offset/copy instructions + if (fun == "datasize" || fun == "dataoffset") + { + std::string arg = formatLiteral(std::get(_arguments.at(0))); + if (arg.length() < 32) + arg.resize(32, 0); + if (fun == "datasize") + return u256(keccak256(arg)) & 0xfff; + else + { + // Force different value than for datasize + arg[31]++; + arg[31]++; + return u256(keccak256(arg)) & 0xfff; + } + } + else if (fun == "datacopy") + { + // This is identical to codecopy. + if ( + _evaluatedArguments.at(2) != 0 && + accessMemory(_evaluatedArguments.at(0), _evaluatedArguments.at(2)) + ) + copyZeroExtended( + m_state.memory, + m_state.code, + size_t(_evaluatedArguments.at(0)), + size_t(_evaluatedArguments.at(1) & std::numeric_limits::max()), + size_t(_evaluatedArguments.at(2)) + ); + return 0; + } + else if (fun == "memoryguard") + return _evaluatedArguments.at(0); + else + yulAssert(false, "Unknown builtin: " + fun); + return 0; +} + + +bool EVMInstructionInterpreter::accessMemory(u256 const& _offset, u256 const& _size) +{ + if (_size == 0) + return true; + + if (_offset <= (_offset + _size) && (_offset + _size) <= (_offset + _size + 0x1f)) + { + u256 newMSize = (_offset + _size + 0x1f) & ~u256(0x1f); + m_state.msize = std::max(m_state.msize, newMSize); + // We only record accesses to contiguous memory chunks that are at most s_maxRangeSize bytes + // in size and at an offset of at most numeric_limits::max() - s_maxRangeSize + return _size <= s_maxRangeSize && _offset <= u256(std::numeric_limits::max() - s_maxRangeSize); + } + + m_state.msize = u256(-1); + return false; +} + +bytes EVMInstructionInterpreter::readMemory(u256 const& _offset, u256 const& _size) +{ + yulAssert(_size <= s_maxRangeSize, "Too large read."); + bytes data(size_t(_size), uint8_t(0)); + for (size_t i = 0; i < data.size(); ++i) + data[i] = m_state.memory[_offset + i]; + return data; +} + +u256 EVMInstructionInterpreter::readMemoryWord(u256 const& _offset) +{ + return u256(h256(m_state.readMemory(_offset, 32))); +} + +void EVMInstructionInterpreter::writeMemoryWord(u256 const& _offset, u256 const& _value) +{ + for (size_t i = 0; i < 32; i++) + m_state.memory[_offset + i] = uint8_t((_value >> (8 * (31 - i))) & 0xff); +} + + +void EVMInstructionInterpreter::logTrace( + evmasm::Instruction _instruction, + std::vector const& _arguments, + bytes const& _data +) +{ + logTrace( + evmasm::instructionInfo(_instruction, m_evmVersion).name, + SemanticInformation::memory(_instruction) == SemanticInformation::Effect::Write, + _arguments, + _data + ); +} + +void EVMInstructionInterpreter::logTrace( + std::string const& _pseudoInstruction, + bool _writesToMemory, + std::vector const& _arguments, + bytes const& _data +) +{ + if (!(_writesToMemory && memWriteTracingDisabled())) + { + std::string message = _pseudoInstruction + "("; + std::pair inputMemoryPtrModified = isInputMemoryPtrModified(_pseudoInstruction, _arguments); + for (size_t i = 0; i < _arguments.size(); ++i) + { + bool printZero = inputMemoryPtrModified.first && inputMemoryPtrModified.second == i; + u256 arg = printZero ? 0 : _arguments[i]; + message += (i > 0 ? ", " : "") + formatNumber(arg); + } + message += ")"; + if (!_data.empty()) + message += " [" + util::toHex(_data) + "]"; + m_state.trace.emplace_back(std::move(message)); + if (m_state.maxTraceSize > 0 && m_state.trace.size() >= m_state.maxTraceSize) + { + m_state.trace.emplace_back("Trace size limit reached."); + BOOST_THROW_EXCEPTION(TraceLimitReached()); + } + } +} + +std::pair EVMInstructionInterpreter::isInputMemoryPtrModified( + std::string const& _pseudoInstruction, + std::vector const& _arguments +) +{ + if (_pseudoInstruction == "RETURN" || _pseudoInstruction == "REVERT") + { + if (_arguments[1] == 0) + return {true, 0}; + else + return {false, 0}; + } + else if ( + _pseudoInstruction == "RETURNDATACOPY" || _pseudoInstruction == "CALLDATACOPY" + || _pseudoInstruction == "CODECOPY") + { + if (_arguments[2] == 0) + return {true, 0}; + else + return {false, 0}; + } + else if (_pseudoInstruction == "EXTCODECOPY") + { + if (_arguments[3] == 0) + return {true, 1}; + else + return {false, 0}; + } + else if ( + _pseudoInstruction == "LOG0" || _pseudoInstruction == "LOG1" || _pseudoInstruction == "LOG2" + || _pseudoInstruction == "LOG3" || _pseudoInstruction == "LOG4") + { + if (_arguments[1] == 0) + return {true, 0}; + else + return {false, 0}; + } + if (_pseudoInstruction == "CREATE" || _pseudoInstruction == "CREATE2") + { + if (_arguments[2] == 0) + return {true, 1}; + else + return {false, 0}; + } + if (_pseudoInstruction == "CALL" || _pseudoInstruction == "CALLCODE") + { + if (_arguments[4] == 0) + return {true, 3}; + else + return {false, 0}; + } + else if (_pseudoInstruction == "DELEGATECALL" || _pseudoInstruction == "STATICCALL") + { + if (_arguments[3] == 0) + return {true, 2}; + else + return {false, 0}; + } + else + return {false, 0}; +} + +h256 EVMInstructionInterpreter::blobHash(u256 const& _index) +{ + yulAssert(m_evmVersion.hasBlobHash()); + if (_index >= m_state.blobCommitments.size()) + return util::FixedHash<32>{}; + + h256 hashedCommitment = h256(picosha2::hash256(toBigEndian(m_state.blobCommitments[static_cast(_index)]))); + yulAssert(m_state.blobHashVersion.size == 1); + hashedCommitment[0] = *m_state.blobHashVersion.data(); + yulAssert(hashedCommitment.size == 32); + return hashedCommitment; +} diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.h b/libyul/tools/interpreter/EVMInstructionInterpreter.h new file mode 100644 index 000000000000..ea0bc965ac64 --- /dev/null +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.h @@ -0,0 +1,176 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Yul interpreter module that evaluates EVM instructions. + */ + +#pragma once + +#include + +#include +#include +#include + +#include + +#include + +namespace solidity::evmasm +{ +enum class Instruction: uint8_t; +} + +namespace solidity::yul +{ +class YulString; +struct BuiltinFunctionForEVM; +} + +namespace solidity::yul::tools::interpreter +{ + +/// Copy @a _size bytes of @a _source at offset @a _sourceOffset to +/// @a _target at offset @a _targetOffset. Behaves as if @a _source would +/// continue with an infinite sequence of zero bytes beyond its end. +void copyZeroExtended( + std::map& _target, + bytes const& _source, + size_t _targetOffset, + size_t _sourceOffset, + size_t _size +); + +/// Copy @a _size bytes of @a _source at offset @a _sourceOffset to +/// @a _target at offset @a _targetOffset. Behaves as if @a _source would +/// continue with an infinite sequence of zero bytes beyond its end. +/// When target and source areas overlap, behaves as if the data was copied +/// using an intermediate buffer. +void copyZeroExtendedWithOverlap( + std::map& _target, + std::map const& _source, + size_t _targetOffset, + size_t _sourceOffset, + size_t _size +); + +struct InterpreterState; + +/** + * Interprets EVM instructions 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 + * on a single contract only, does not do any gas counting and differs from the correct + * implementation in many ways: + * + * - If memory access to a "large" memory position is performed, a deterministic + * value is returned. Data that is stored in a "large" memory position is not + * retained. + * - The blockhash instruction returns a fixed value if the argument is in range. + * - Extcodesize returns a deterministic value depending on the address. + * - Extcodecopy copies a deterministic value depending on the address. + * - And many other things + * + * 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 EVMInstructionInterpreter +{ +public: + explicit EVMInstructionInterpreter(langutil::EVMVersion _evmVersion, InterpreterState& _state, bool _disableMemWriteTrace): + m_evmVersion(_evmVersion), + m_state(_state), + m_disableMemoryWriteInstructions(_disableMemWriteTrace) + {} + /// Evaluate instruction + u256 eval(evmasm::Instruction _instruction, std::vector const& _arguments); + /// Evaluate builtin function + u256 evalBuiltin( + BuiltinFunctionForEVM const& _fun, + std::vector const& _arguments, + std::vector const& _evaluatedArguments + ); + + /// @returns the blob versioned hash + util::h256 blobHash(u256 const& _index); + +private: + /// Checks if the memory access is valid and adjusts msize accordingly. + /// @returns true if memory access is valid, false otherwise + /// A valid memory access must satisfy all of the following pre-requisites: + /// - Sum of @param _offset and @param _size do not overflow modulo u256 + /// - Sum of @param _offset, @param _size, and 31 do not overflow modulo u256 (see note below) + /// - @param _size is lesser than or equal to @a s_maxRangeSize + /// - @param _offset is lesser than or equal to the difference of numeric_limits::max() + /// and @a s_maxRangeSize + /// Note: Memory expansion is carried out in multiples of 32 bytes. + bool accessMemory(u256 const& _offset, u256 const& _size = 32); + /// @returns the memory contents at the provided address. + /// Does not adjust msize, use @a accessMemory for that + bytes readMemory(u256 const& _offset, u256 const& _size = 32); + /// @returns the memory contents at the provided address. + /// Does not adjust msize, use @a accessMemory for that + u256 readMemoryWord(u256 const& _offset); + /// @returns writes a word to memory + /// Does not adjust msize, use @a accessMemory for that + void writeMemoryWord(u256 const& _offset, u256 const& _value); + + void logTrace( + evmasm::Instruction _instruction, + std::vector const& _arguments = {}, + bytes const& _data = {} + ); + /// Appends a log to the trace representing an instruction or similar operation by string, + /// with arguments and auxiliary data (if nonempty). Flag @param _writesToMemory indicates + /// whether the instruction writes to (true) or does not write to (false) memory. + void logTrace( + std::string const& _pseudoInstruction, + bool _writesToMemory, + std::vector const& _arguments = {}, + bytes const& _data = {} + ); + + /// @returns a pair of boolean and size_t whose first value is true if @param _pseudoInstruction + /// is a Yul instruction that the Yul optimizer's loadResolver step rewrites the input + /// memory pointer value to zero if that instruction's read length (contained within @param + // _arguments) is zero, and whose second value is the positional index of the input memory + // pointer argument. + /// If the Yul instruction is unaffected or affected but read length is non-zero, the first + /// value is false. + std::pair isInputMemoryPtrModified( + std::string const& _pseudoInstruction, + std::vector const& _arguments + ); + + /// @returns disable trace flag. + bool memWriteTracingDisabled() + { + return m_disableMemoryWriteInstructions; + } + + langutil::EVMVersion m_evmVersion; + InterpreterState& m_state; + /// Flag to disable trace of instructions that write to memory. + bool m_disableMemoryWriteInstructions; +public: + /// Maximum length for range-based memory access operations. + static constexpr unsigned s_maxRangeSize = 0xffff; +}; + +} // solidity::yul::test diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp new file mode 100644 index 000000000000..746ad82da6d7 --- /dev/null +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -0,0 +1,500 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Yul interpreter. + */ + +#include + +#include + +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include + +using namespace solidity; +using namespace solidity::yul; +using namespace solidity::yul::tools::interpreter; + +using solidity::util::h256; + +void InterpreterState::dumpStorage(std::ostream& _out) const +{ + for (auto const& [slot, value]: storage) + if (value != h256{}) + _out << " " << slot.hex() << ": " << value.hex() << std::endl; +} + +void InterpreterState::dumpTransientStorage(std::ostream& _out) const +{ + for (auto const& [slot, value]: transientStorage) + if (value != h256{}) + _out << " " << slot.hex() << ": " << value.hex() << std::endl; +} + +void InterpreterState::dumpTraceAndState(std::ostream& _out, bool _disableMemoryTrace) const +{ + _out << "Trace:" << std::endl; + for (auto const& line: trace) + _out << " " << line << std::endl; + if (!_disableMemoryTrace) + { + _out << "Memory dump:\n"; + std::map words; + for (auto const& [offset, value]: memory) + words[(offset / 0x20) * 0x20] |= u256(uint32_t(value)) << (256 - 8 - 8 * static_cast(offset % 0x20)); + for (auto const& [offset, value]: words) + if (value != 0) + _out << " " << std::uppercase << std::hex << std::setw(4) << offset << ": " << h256(value).hex() << std::endl; + } + _out << "Storage dump:" << std::endl; + dumpStorage(_out); + + _out << "Transient storage dump:" << std::endl; + dumpTransientStorage(_out); + + if (!calldata.empty()) + { + _out << "Calldata dump:"; + + for (size_t offset = 0; offset < calldata.size(); ++offset) + if (calldata[offset] != 0) + { + if (offset % 32 == 0) + _out << + std::endl << + " " << + std::uppercase << + std::hex << + std::setfill(' ') << + std::setw(4) << + offset << + ": "; + + _out << + std::hex << + std::setw(2) << + std::setfill('0') << + static_cast(calldata[offset]); + } + + _out << std::endl; + } +} + +void Interpreter::run( + InterpreterState& _state, + Dialect const& _dialect, + Block const& _ast, + bool _disableExternalCalls, + bool _disableMemoryTrace +) +{ + Scope scope; + Interpreter{_state, _dialect, scope, _disableExternalCalls, _disableMemoryTrace}(_ast); +} + +void Interpreter::operator()(ExpressionStatement const& _expressionStatement) +{ + evaluateMulti(_expressionStatement.expression); +} + +void Interpreter::operator()(Assignment const& _assignment) +{ + solAssert(_assignment.value, ""); + std::vector values = evaluateMulti(*_assignment.value); + solAssert(values.size() == _assignment.variableNames.size(), ""); + for (size_t i = 0; i < values.size(); ++i) + { + YulName varName = _assignment.variableNames.at(i).name; + solAssert(m_variables.count(varName), ""); + m_variables[varName] = values.at(i); + } +} + +void Interpreter::operator()(VariableDeclaration const& _declaration) +{ + std::vector values(_declaration.variables.size(), 0); + if (_declaration.value) + values = evaluateMulti(*_declaration.value); + + solAssert(values.size() == _declaration.variables.size(), ""); + for (size_t i = 0; i < values.size(); ++i) + { + YulName varName = _declaration.variables.at(i).name; + solAssert(!m_variables.count(varName), ""); + m_variables[varName] = values.at(i); + m_scope->names.emplace(varName, nullptr); + } +} + +void Interpreter::operator()(If const& _if) +{ + solAssert(_if.condition, ""); + if (evaluate(*_if.condition) != 0) + (*this)(_if.body); +} + +void Interpreter::operator()(Switch const& _switch) +{ + solAssert(_switch.expression, ""); + u256 val = evaluate(*_switch.expression); + solAssert(!_switch.cases.empty(), ""); + for (auto const& c: _switch.cases) + // Default case has to be last. + if (!c.value || evaluate(*c.value) == val) + { + (*this)(c.body); + break; + } +} + +void Interpreter::operator()(FunctionDefinition const&) +{ +} + +void Interpreter::operator()(ForLoop const& _forLoop) +{ + solAssert(_forLoop.condition, ""); + + enterScope(_forLoop.pre); + ScopeGuard g([this]{ leaveScope(); }); + + for (auto const& statement: _forLoop.pre.statements) + { + visit(statement); + if (m_state.controlFlowState == ControlFlowState::Leave) + return; + } + while (evaluate(*_forLoop.condition) != 0) + { + // Increment step for each loop iteration for loops with + // an empty body and post blocks to prevent a deadlock. + if (_forLoop.body.statements.size() == 0 && _forLoop.post.statements.size() == 0) + incrementStep(); + + m_state.controlFlowState = ControlFlowState::Default; + (*this)(_forLoop.body); + if (m_state.controlFlowState == ControlFlowState::Break || m_state.controlFlowState == ControlFlowState::Leave) + break; + + m_state.controlFlowState = ControlFlowState::Default; + (*this)(_forLoop.post); + if (m_state.controlFlowState == ControlFlowState::Leave) + break; + } + if (m_state.controlFlowState != ControlFlowState::Leave) + m_state.controlFlowState = ControlFlowState::Default; +} + +void Interpreter::operator()(Break const&) +{ + m_state.controlFlowState = ControlFlowState::Break; +} + +void Interpreter::operator()(Continue const&) +{ + m_state.controlFlowState = ControlFlowState::Continue; +} + +void Interpreter::operator()(Leave const&) +{ + m_state.controlFlowState = ControlFlowState::Leave; +} + +void Interpreter::operator()(Block const& _block) +{ + enterScope(_block); + // Register functions. + for (auto const& statement: _block.statements) + if (std::holds_alternative(statement)) + { + FunctionDefinition const& funDef = std::get(statement); + m_scope->names.emplace(funDef.name, &funDef); + } + + for (auto const& statement: _block.statements) + { + incrementStep(); + visit(statement); + if (m_state.controlFlowState != ControlFlowState::Default) + break; + } + + leaveScope(); +} + +u256 Interpreter::evaluate(Expression const& _expression) +{ + ExpressionEvaluator ev(m_state, m_dialect, *m_scope, m_variables, m_disableExternalCalls, m_disableMemoryTrace); + ev.visit(_expression); + return ev.value(); +} + +std::vector Interpreter::evaluateMulti(Expression const& _expression) +{ + ExpressionEvaluator ev(m_state, m_dialect, *m_scope, m_variables, m_disableExternalCalls, m_disableMemoryTrace); + ev.visit(_expression); + return ev.values(); +} + +void Interpreter::enterScope(Block const& _block) +{ + if (!m_scope->subScopes.count(&_block)) + m_scope->subScopes[&_block] = std::make_unique(Scope{ + {}, + {}, + m_scope + }); + m_scope = m_scope->subScopes[&_block].get(); +} + +void Interpreter::leaveScope() +{ + for (auto const& [var, funDeclaration]: m_scope->names) + if (!funDeclaration) + m_variables.erase(var); + m_scope = m_scope->parent; + yulAssert(m_scope, ""); +} + +void Interpreter::incrementStep() +{ + m_state.numSteps++; + if (m_state.maxSteps > 0 && m_state.numSteps >= m_state.maxSteps) + { + m_state.trace.emplace_back("Interpreter execution step limit reached."); + BOOST_THROW_EXCEPTION(StepLimitReached()); + } +} + +void ExpressionEvaluator::operator()(Literal const& _literal) +{ + incrementStep(); + setValue(_literal.value.value()); +} + +void ExpressionEvaluator::operator()(Identifier const& _identifier) +{ + solAssert(m_variables.count(_identifier.name), ""); + incrementStep(); + setValue(m_variables.at(_identifier.name)); +} + +void ExpressionEvaluator::operator()(FunctionCall const& _funCall) +{ + std::vector> const* literalArguments = nullptr; + if (BuiltinFunction const* builtin = m_dialect.builtin(_funCall.functionName.name)) + if (!builtin->literalArguments.empty()) + literalArguments = &builtin->literalArguments; + evaluateArgs(_funCall.arguments, literalArguments); + + if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) + { + if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) + { + EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state, m_disableMemoryTrace); + + u256 const value = interpreter.evalBuiltin(*fun, _funCall.arguments, values()); + + if ( + !m_disableExternalCalls && + fun->instruction && + evmasm::isCallInstruction(*fun->instruction) + ) + runExternalCall(*fun->instruction); + + setValue(value); + return; + } + } + + Scope* scope = &m_scope; + for (; scope; scope = scope->parent) + if (scope->names.count(_funCall.functionName.name)) + break; + yulAssert(scope, ""); + + FunctionDefinition const* fun = scope->names.at(_funCall.functionName.name); + yulAssert(fun, "Function not found."); + yulAssert(m_values.size() == fun->parameters.size(), ""); + std::map variables; + for (size_t i = 0; i < fun->parameters.size(); ++i) + variables[fun->parameters.at(i).name] = m_values.at(i); + for (size_t i = 0; i < fun->returnVariables.size(); ++i) + variables[fun->returnVariables.at(i).name] = 0; + + m_state.controlFlowState = ControlFlowState::Default; + std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); + (*interpreter)(fun->body); + m_state.controlFlowState = ControlFlowState::Default; + + m_values.clear(); + for (auto const& retVar: fun->returnVariables) + m_values.emplace_back(interpreter->valueOfVariable(retVar.name)); +} + +u256 ExpressionEvaluator::value() const +{ + solAssert(m_values.size() == 1, ""); + return m_values.front(); +} + +void ExpressionEvaluator::setValue(u256 _value) +{ + m_values.clear(); + m_values.emplace_back(std::move(_value)); +} + +void ExpressionEvaluator::evaluateArgs( + std::vector const& _expr, + std::vector> const* _literalArguments +) +{ + incrementStep(); + std::vector values; + size_t i = 0; + /// Function arguments are evaluated in reverse. + for (auto const& expr: _expr | ranges::views::reverse) + { + if (!_literalArguments || !_literalArguments->at(_expr.size() - i - 1)) + visit(expr); + else + { + if (std::get(expr).value.unlimited()) + { + yulAssert(std::get(expr).kind == LiteralKind::String); + m_values = {0xdeadbeef}; + } + else + m_values = {std::get(expr).value.value()}; + } + + values.push_back(value()); + ++i; + } + m_values = std::move(values); + std::reverse(m_values.begin(), m_values.end()); +} + +void ExpressionEvaluator::incrementStep() +{ + m_nestingLevel++; + if (m_state.maxExprNesting > 0 && m_nestingLevel > m_state.maxExprNesting) + { + m_state.trace.emplace_back("Maximum expression nesting level reached."); + BOOST_THROW_EXCEPTION(ExpressionNestingLimitReached()); + } +} + +void ExpressionEvaluator::runExternalCall(evmasm::Instruction _instruction) +{ + u256 memOutOffset = 0; + u256 memOutSize = 0; + u256 callvalue = 0; + u256 memInOffset = 0; + u256 memInSize = 0; + + // Setup memOut* values + if ( + _instruction == evmasm::Instruction::CALL || + _instruction == evmasm::Instruction::CALLCODE + ) + { + memOutOffset = values()[5]; + memOutSize = values()[6]; + callvalue = values()[2]; + memInOffset = values()[3]; + memInSize = values()[4]; + } + else if ( + _instruction == evmasm::Instruction::DELEGATECALL || + _instruction == evmasm::Instruction::STATICCALL + ) + { + memOutOffset = values()[4]; + memOutSize = values()[5]; + memInOffset = values()[2]; + memInSize = values()[3]; + } + else + yulAssert(false); + + // Don't execute external call if it isn't our own address + if (values()[1] != util::h160::Arith(m_state.address)) + return; + + Scope tmpScope; + InterpreterState tmpState; + tmpState.calldata = m_state.readMemory(memInOffset, memInSize); + tmpState.callvalue = callvalue; + tmpState.numInstance = m_state.numInstance + 1; + + yulAssert(tmpState.numInstance < 1024, "Detected more than 1024 recursive calls, aborting..."); + + // Create new interpreter for the called contract + std::unique_ptr newInterpreter = makeInterpreterNew(tmpState, tmpScope); + + Scope* abstractRootScope = &m_scope; + Scope* fileScope = nullptr; + Block const* ast = nullptr; + + // Find file scope + while (abstractRootScope->parent) + { + fileScope = abstractRootScope; + abstractRootScope = abstractRootScope->parent; + } + + // Get AST for file scope + for (auto&& [block, scope]: abstractRootScope->subScopes) + if (scope.get() == fileScope) + { + ast = block; + break; + } + + yulAssert(ast); + + try + { + (*newInterpreter)(*ast); + } + catch (ExplicitlyTerminatedWithReturn const&) + { + // Copy return data to our memory + copyZeroExtended( + m_state.memory, + newInterpreter->returnData(), + memOutOffset.convert_to(), + 0, + memOutSize.convert_to() + ); + m_state.returndata = newInterpreter->returnData(); + } +} diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h new file mode 100644 index 000000000000..a7ca6413957a --- /dev/null +++ b/libyul/tools/interpreter/Interpreter.h @@ -0,0 +1,312 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Yul interpreter. + */ + +#pragma once + +#include +#include + +#include + +#include +#include + +#include + +#include + +namespace solidity::yul +{ +struct Dialect; +} + +namespace solidity::yul::tools::interpreter +{ + +class InterpreterTerminatedGeneric: public util::Exception +{ +}; + +class ExplicitlyTerminated: public InterpreterTerminatedGeneric +{ +}; + +class ExplicitlyTerminatedWithReturn: public ExplicitlyTerminated +{ +}; + +class StepLimitReached: public InterpreterTerminatedGeneric +{ +}; + +class TraceLimitReached: public InterpreterTerminatedGeneric +{ +}; + +class ExpressionNestingLimitReached: public InterpreterTerminatedGeneric +{ +}; + +enum class ControlFlowState +{ + Default, + Continue, + Break, + Leave +}; + +struct InterpreterState +{ + bytes calldata; + bytes returndata; + std::map memory; + /// This is different than memory.size() because we ignore gas. + u256 msize; + std::map storage; + std::map transientStorage; + util::h160 address = util::h160("0x0000000000000000000000000000000011111111"); + u256 balance = 0x22222222; + u256 selfbalance = 0x22223333; + util::h160 origin = util::h160("0x0000000000000000000000000000000033333333"); + util::h160 caller = util::h160("0x0000000000000000000000000000000044444444"); + u256 callvalue = 0x55555555; + /// Deployed code + bytes code = util::asBytes("codecodecodecodecode"); + u256 gasprice = 0x66666666; + util::h160 coinbase = util::h160("0x0000000000000000000000000000000077777777"); + u256 timestamp = 0x88888888; + u256 blockNumber = 1024; + u256 difficulty = 0x9999999; + u256 prevrandao = (u256(1) << 64) + 1; + u256 gaslimit = 4000000; + u256 chainid = 0x01; + /// The minimum value of basefee: 7 wei. + u256 basefee = 0x07; + /// The minimum value of blobbasefee: 1 wei. + u256 blobbasefee = 0x01; + /// Log of changes / effects. Sholud be structured data in the future. + std::vector trace; + /// This is actually an input parameter that more or less limits the runtime. + size_t maxTraceSize = 0; + size_t maxSteps = 0; + size_t numSteps = 0; + size_t maxExprNesting = 0; + ControlFlowState controlFlowState = ControlFlowState::Default; + + /// Number of the current state instance, used for recursion protection + size_t numInstance = 0; + + // Blob commitment hash version + util::FixedHash<1> const blobHashVersion = util::FixedHash<1>(1); + // Blob commitments + std::array const blobCommitments = {0x01, 0x02}; + + /// Prints execution trace and non-zero storage to @param _out. + /// Flag @param _disableMemoryTrace, if set, does not produce a memory dump. This + /// avoids false positives reports by the fuzzer when certain optimizer steps are + /// activated e.g., Redundant store eliminator, Equal store eliminator. + void dumpTraceAndState(std::ostream& _out, bool _disableMemoryTrace) const; + /// Prints non-zero storage to @param _out. + void dumpStorage(std::ostream& _out) const; + /// Prints non-zero transient storage to @param _out. + void dumpTransientStorage(std::ostream& _out) const; + + bytes readMemory(u256 const& _offset, u256 const& _size) + { + yulAssert(_size <= 0xffff, "Too large read."); + bytes data(size_t(_size), uint8_t(0)); + for (size_t i = 0; i < data.size(); ++i) + data[i] = memory[_offset + i]; + return data; + } +}; + +/** + * Scope structure built and maintained during execution. + */ +struct Scope +{ + /// Used for variables and functions. Value is nullptr for variables. + std::map names; + std::map> subScopes; + Scope* parent = nullptr; +}; + +/** + * Yul interpreter. + */ +class Interpreter: public ASTWalker +{ +public: + /// Executes the Yul interpreter. Flag @param _disableMemoryTracing if set ensures that + /// instructions that write to memory do not affect @param _state. This + /// avoids false positives reports by the fuzzer when certain optimizer steps are + /// activated e.g., Redundant store eliminator, Equal store eliminator. + static void run( + InterpreterState& _state, + Dialect const& _dialect, + Block const& _ast, + bool _disableExternalCalls, + bool _disableMemoryTracing + ); + + Interpreter( + InterpreterState& _state, + Dialect const& _dialect, + Scope& _scope, + bool _disableExternalCalls, + bool _disableMemoryTracing, + std::map _variables = {} + ): + m_dialect(_dialect), + m_state(_state), + m_variables(std::move(_variables)), + m_scope(&_scope), + m_disableExternalCalls(_disableExternalCalls), + m_disableMemoryTrace(_disableMemoryTracing) + { + } + + void operator()(ExpressionStatement const& _statement) override; + void operator()(Assignment const& _assignment) override; + void operator()(VariableDeclaration const& _varDecl) override; + void operator()(If const& _if) override; + void operator()(Switch const& _switch) override; + void operator()(FunctionDefinition const&) override; + void operator()(ForLoop const&) override; + void operator()(Break const&) override; + void operator()(Continue const&) override; + void operator()(Leave const&) override; + void operator()(Block const& _block) override; + + bytes returnData() const { return m_state.returndata; } + std::vector const& trace() const { return m_state.trace; } + + u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } + +protected: + /// Asserts that the expression evaluates to exactly one value and returns it. + virtual u256 evaluate(Expression const& _expression); + /// Evaluates the expression and returns its value. + virtual std::vector evaluateMulti(Expression const& _expression); + + void enterScope(Block const& _block); + void leaveScope(); + + /// Increment interpreter step count, throwing exception if step limit + /// is reached. + void incrementStep(); + + Dialect const& m_dialect; + InterpreterState& m_state; + /// Values of variables. + std::map m_variables; + Scope* m_scope; + /// If not set, external calls (e.g. using `call()`) to the same contract + /// are evaluated in a new parser instance. + bool m_disableExternalCalls; + bool m_disableMemoryTrace; +}; + +/** + * Yul expression evaluator. + */ +class ExpressionEvaluator: public ASTWalker +{ +public: + ExpressionEvaluator( + InterpreterState& _state, + Dialect const& _dialect, + Scope& _scope, + std::map const& _variables, + bool _disableExternalCalls, + bool _disableMemoryTrace + ): + m_state(_state), + m_dialect(_dialect), + m_variables(_variables), + m_scope(_scope), + m_disableExternalCalls(_disableExternalCalls), + m_disableMemoryTrace(_disableMemoryTrace) + {} + + void operator()(Literal const&) override; + void operator()(Identifier const&) override; + void operator()(FunctionCall const& _funCall) override; + + /// Asserts that the expression has exactly one value and returns it. + u256 value() const; + /// Returns the list of values of the expression. + std::vector values() const { return m_values; } + +protected: + void runExternalCall(evmasm::Instruction _instruction); + virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const + { + return std::make_unique( + m_state, + m_dialect, + m_scope, + m_disableExternalCalls, + m_disableMemoryTrace, + std::move(_variables) + ); + } + virtual std::unique_ptr makeInterpreterNew(InterpreterState& _state, Scope& _scope) const + { + return std::make_unique( + _state, + m_dialect, + _scope, + m_disableExternalCalls, + m_disableMemoryTrace + ); + } + + void setValue(u256 _value); + + /// Evaluates the given expression from right to left and + /// stores it in m_value. + void evaluateArgs( + std::vector const& _expr, + std::vector> const* _literalArguments + ); + + /// Increment evaluation count, throwing exception if the + /// nesting level is beyond the upper bound configured in + /// the interpreter state. + void incrementStep(); + + InterpreterState& m_state; + Dialect const& m_dialect; + /// Values of variables. + std::map const& m_variables; + Scope& m_scope; + /// Current value of the expression + std::vector m_values; + /// Current expression nesting level + unsigned m_nestingLevel = 0; + bool m_disableExternalCalls; + /// Flag to disable memory tracing + bool m_disableMemoryTrace; +}; + +} From 5b63c18cabf162799ffed241fc3ed03f9c6dde23 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 19 Sep 2024 00:26:27 +0700 Subject: [PATCH 002/101] Add new Result type --- libyul/tools/interpreter/Interpreter.h | 57 +++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index a7ca6413957a..cc0ab80f5042 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -41,30 +41,42 @@ struct Dialect; namespace solidity::yul::tools::interpreter { -class InterpreterTerminatedGeneric: public util::Exception +template +class ExecutionTerminatedCommon { +public: + bool operator==(T) const { return true; } + bool operator!=(T) const { return false; } }; -class ExplicitlyTerminated: public InterpreterTerminatedGeneric +class ExplicitlyTerminated : public ExecutionTerminatedCommon { }; -class ExplicitlyTerminatedWithReturn: public ExplicitlyTerminated +class ExplicitlyTerminatedWithReturn : public ExecutionTerminatedCommon { }; -class StepLimitReached: public InterpreterTerminatedGeneric +class StepLimitReached : public ExecutionTerminatedCommon { }; -class TraceLimitReached: public InterpreterTerminatedGeneric +class TraceLimitReached : public ExecutionTerminatedCommon { }; -class ExpressionNestingLimitReached: public InterpreterTerminatedGeneric +class ExpressionNestingLimitReached : public ExecutionTerminatedCommon { }; +using ExecutionTerminated = std::variant< + ExplicitlyTerminated, + ExplicitlyTerminatedWithReturn, + StepLimitReached, + TraceLimitReached, + ExpressionNestingLimitReached +>; + enum class ControlFlowState { Default, @@ -73,6 +85,39 @@ enum class ControlFlowState Leave }; +struct ExecutionOk +{ + ControlFlowState state; + + bool operator==(ExecutionOk other) const + { + return state == other.state; + } + + bool operator!=(ExecutionOk other) const + { + return state != other.state; + } +}; + +struct EvaluationOk +{ + std::vector values; + + EvaluationOk(u256 _x): + values{_x} + { + } + + EvaluationOk(std::vector const& _values): + values(_values) + { + } +}; + +using ExecutionResult = std::variant; +using EvaluationResult = std::variant; + struct InterpreterState { bytes calldata; From 4f30344a3bc55b3b54a398fa6f72cb4822f3ab7f Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 19 Sep 2024 00:27:19 +0700 Subject: [PATCH 003/101] Change interface of the interpreter to have custom return type --- libyul/tools/interpreter/Interpreter.h | 59 ++++++++++++-------------- 1 file changed, 26 insertions(+), 33 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index cc0ab80f5042..c26f7542cddd 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -22,7 +22,8 @@ #pragma once #include -#include +#include +#include #include @@ -154,7 +155,6 @@ struct InterpreterState size_t maxSteps = 0; size_t numSteps = 0; size_t maxExprNesting = 0; - ControlFlowState controlFlowState = ControlFlowState::Default; /// Number of the current state instance, used for recursion protection size_t numInstance = 0; @@ -198,7 +198,7 @@ struct Scope /** * Yul interpreter. */ -class Interpreter: public ASTWalker +class Interpreter { public: /// Executes the Yul interpreter. Flag @param _disableMemoryTracing if set ensures that @@ -230,17 +230,19 @@ class Interpreter: public ASTWalker { } - void operator()(ExpressionStatement const& _statement) override; - void operator()(Assignment const& _assignment) override; - void operator()(VariableDeclaration const& _varDecl) override; - void operator()(If const& _if) override; - void operator()(Switch const& _switch) override; - void operator()(FunctionDefinition const&) override; - void operator()(ForLoop const&) override; - void operator()(Break const&) override; - void operator()(Continue const&) override; - void operator()(Leave const&) override; - void operator()(Block const& _block) override; + ExecutionResult operator()(ExpressionStatement const& _statement); + ExecutionResult operator()(Assignment const& _assignment); + ExecutionResult operator()(VariableDeclaration const& _varDecl); + ExecutionResult operator()(If const& _if); + ExecutionResult operator()(Switch const& _switch); + ExecutionResult operator()(FunctionDefinition const&); + ExecutionResult operator()(ForLoop const&); + ExecutionResult operator()(Break const&); + ExecutionResult operator()(Continue const&); + ExecutionResult operator()(Leave const&); + ExecutionResult operator()(Block const& _block); + + ExecutionResult visit(Statement const& _st); bytes returnData() const { return m_state.returndata; } std::vector const& trace() const { return m_state.trace; } @@ -248,17 +250,15 @@ class Interpreter: public ASTWalker u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } protected: - /// Asserts that the expression evaluates to exactly one value and returns it. - virtual u256 evaluate(Expression const& _expression); - /// Evaluates the expression and returns its value. - virtual std::vector evaluateMulti(Expression const& _expression); + // evaluate the expression and assert that the number of return variable is _numReturnVars + virtual EvaluationResult evaluate(Expression const& _expression, size_t _numReturnVars); void enterScope(Block const& _block); void leaveScope(); /// Increment interpreter step count, throwing exception if step limit /// is reached. - void incrementStep(); + std::optional incrementStep(); Dialect const& m_dialect; InterpreterState& m_state; @@ -274,7 +274,7 @@ class Interpreter: public ASTWalker /** * Yul expression evaluator. */ -class ExpressionEvaluator: public ASTWalker +class ExpressionEvaluator { public: ExpressionEvaluator( @@ -293,14 +293,11 @@ class ExpressionEvaluator: public ASTWalker m_disableMemoryTrace(_disableMemoryTrace) {} - void operator()(Literal const&) override; - void operator()(Identifier const&) override; - void operator()(FunctionCall const& _funCall) override; + EvaluationResult operator()(Literal const&); + EvaluationResult operator()(Identifier const&); + EvaluationResult operator()(FunctionCall const& _funCall); - /// Asserts that the expression has exactly one value and returns it. - u256 value() const; - /// Returns the list of values of the expression. - std::vector values() const { return m_values; } + EvaluationResult visit(Expression const& _st); protected: void runExternalCall(evmasm::Instruction _instruction); @@ -326,11 +323,9 @@ class ExpressionEvaluator: public ASTWalker ); } - void setValue(u256 _value); - /// Evaluates the given expression from right to left and /// stores it in m_value. - void evaluateArgs( + EvaluationResult evaluateArgs( std::vector const& _expr, std::vector> const* _literalArguments ); @@ -338,15 +333,13 @@ class ExpressionEvaluator: public ASTWalker /// Increment evaluation count, throwing exception if the /// nesting level is beyond the upper bound configured in /// the interpreter state. - void incrementStep(); + std::optional incrementStep(); InterpreterState& m_state; Dialect const& m_dialect; /// Values of variables. std::map const& m_variables; Scope& m_scope; - /// Current value of the expression - std::vector m_values; /// Current expression nesting level unsigned m_nestingLevel = 0; bool m_disableExternalCalls; From d78dc8da19d6541a11c7998a26c953a5c34c1643 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 19 Sep 2024 00:27:46 +0700 Subject: [PATCH 004/101] Implement visit function with new return type --- libyul/tools/interpreter/Interpreter.cpp | 234 +++++++++++++---------- 1 file changed, 134 insertions(+), 100 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index 746ad82da6d7..db370a41e07a 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -31,6 +31,7 @@ #include #include +#include #include @@ -119,29 +120,38 @@ void Interpreter::run( Interpreter{_state, _dialect, scope, _disableExternalCalls, _disableMemoryTrace}(_ast); } -void Interpreter::operator()(ExpressionStatement const& _expressionStatement) +ExecutionResult Interpreter::operator()(ExpressionStatement const& _expressionStatement) { - evaluateMulti(_expressionStatement.expression); + EvaluationResult res = evaluate(_expressionStatement.expression, 0); + if (auto* terminated = std::get_if(&res)) return *terminated; + return ExecutionOk{ ControlFlowState::Default }; } -void Interpreter::operator()(Assignment const& _assignment) +ExecutionResult Interpreter::operator()(Assignment const& _assignment) { solAssert(_assignment.value, ""); - std::vector values = evaluateMulti(*_assignment.value); - solAssert(values.size() == _assignment.variableNames.size(), ""); + EvaluationResult evalRes = evaluate(*_assignment.value, _assignment.variableNames.size()); + if (auto* terminated = std::get_if(&evalRes)) return *terminated; + + std::vector const& values = std::get(evalRes).values; for (size_t i = 0; i < values.size(); ++i) { YulName varName = _assignment.variableNames.at(i).name; solAssert(m_variables.count(varName), ""); m_variables[varName] = values.at(i); } + return ExecutionOk { ControlFlowState::Default }; } -void Interpreter::operator()(VariableDeclaration const& _declaration) +ExecutionResult Interpreter::operator()(VariableDeclaration const& _declaration) { std::vector values(_declaration.variables.size(), 0); if (_declaration.value) - values = evaluateMulti(*_declaration.value); + { + EvaluationResult evalRes = evaluate(*_declaration.value, _declaration.variables.size()); + if (auto* terminated = std::get_if(&evalRes)) return *terminated; + values = std::get(evalRes).values; + } solAssert(values.size() == _declaration.variables.size(), ""); for (size_t i = 0; i < values.size(); ++i) @@ -151,34 +161,51 @@ void Interpreter::operator()(VariableDeclaration const& _declaration) m_variables[varName] = values.at(i); m_scope->names.emplace(varName, nullptr); } + return ExecutionOk { ControlFlowState::Default }; } -void Interpreter::operator()(If const& _if) +ExecutionResult Interpreter::operator()(If const& _if) { solAssert(_if.condition, ""); - if (evaluate(*_if.condition) != 0) - (*this)(_if.body); + EvaluationResult conditionRes = evaluate(*_if.condition, 1); + if (auto* terminated = std::get_if(&conditionRes)) return *terminated; + + if (std::get(conditionRes).values.at(0) != 0) + return (*this)(_if.body); + return ExecutionOk { ControlFlowState::Default }; } -void Interpreter::operator()(Switch const& _switch) +ExecutionResult Interpreter::operator()(Switch const& _switch) { solAssert(_switch.expression, ""); - u256 val = evaluate(*_switch.expression); solAssert(!_switch.cases.empty(), ""); + + EvaluationResult expressionRes = evaluate(*_switch.expression, 1); + if (auto* terminated = std::get_if(&expressionRes)) return *terminated; + + u256 val = std::get(expressionRes).values.at(0); for (auto const& c: _switch.cases) + { + bool caseMatched = false; // Default case has to be last. - if (!c.value || evaluate(*c.value) == val) + if (!c.value) caseMatched = true; + else { - (*this)(c.body); - break; + EvaluationResult caseRes = evaluate(*c.value, 1); + if (auto* terminated = std::get_if(&caseRes)) return *terminated; + caseMatched = std::get(caseRes).values.at(0) == val; } + if (caseMatched) return (*this)(c.body); + } + return ExecutionOk { ControlFlowState::Default }; } -void Interpreter::operator()(FunctionDefinition const&) +ExecutionResult Interpreter::operator()(FunctionDefinition const&) { + return ExecutionOk{ ControlFlowState::Default }; } -void Interpreter::operator()(ForLoop const& _forLoop) +ExecutionResult Interpreter::operator()(ForLoop const& _forLoop) { solAssert(_forLoop.condition, ""); @@ -187,49 +214,65 @@ void Interpreter::operator()(ForLoop const& _forLoop) for (auto const& statement: _forLoop.pre.statements) { - visit(statement); - if (m_state.controlFlowState == ControlFlowState::Leave) - return; + ExecutionResult execRes = visit(statement); + if (execRes == ExecutionResult(ExecutionOk { ControlFlowState::Leave })) + return execRes; } - while (evaluate(*_forLoop.condition) != 0) + while (true) { + { + EvaluationResult conditionRes = evaluate(*_forLoop.condition, 1); + if (auto* terminated = std::get_if(&conditionRes)) return *terminated; + if (std::get(conditionRes).values.at(0) == 0) break; + } + // Increment step for each loop iteration for loops with // an empty body and post blocks to prevent a deadlock. if (_forLoop.body.statements.size() == 0 && _forLoop.post.statements.size() == 0) - incrementStep(); + if (auto terminated = incrementStep()) return *terminated; - m_state.controlFlowState = ControlFlowState::Default; - (*this)(_forLoop.body); - if (m_state.controlFlowState == ControlFlowState::Break || m_state.controlFlowState == ControlFlowState::Leave) - break; + { + ExecutionResult bodyRes = (*this)(_forLoop.body); + if ( + std::holds_alternative(bodyRes) || + bodyRes == ExecutionResult(ExecutionOk{ ControlFlowState::Leave }) + ) return bodyRes; - m_state.controlFlowState = ControlFlowState::Default; - (*this)(_forLoop.post); - if (m_state.controlFlowState == ControlFlowState::Leave) - break; + if (bodyRes == ExecutionResult(ExecutionOk{ ControlFlowState::Break })) + return ExecutionOk { ControlFlowState::Default }; + } + + { + ExecutionResult postRes = (*this)(_forLoop.post); + if ( + std::holds_alternative(postRes) || + postRes == ExecutionResult(ExecutionOk{ ControlFlowState::Leave }) + ) return postRes; + } } - if (m_state.controlFlowState != ControlFlowState::Leave) - m_state.controlFlowState = ControlFlowState::Default; + return ExecutionOk { ControlFlowState::Default }; } -void Interpreter::operator()(Break const&) +ExecutionResult Interpreter::operator()(Break const&) { - m_state.controlFlowState = ControlFlowState::Break; + return ExecutionOk{ ControlFlowState::Break }; } -void Interpreter::operator()(Continue const&) +ExecutionResult Interpreter::operator()(Continue const&) { - m_state.controlFlowState = ControlFlowState::Continue; + return ExecutionOk{ ControlFlowState::Continue }; } -void Interpreter::operator()(Leave const&) +ExecutionResult Interpreter::operator()(Leave const&) { - m_state.controlFlowState = ControlFlowState::Leave; + return ExecutionOk{ ControlFlowState::Leave }; } -void Interpreter::operator()(Block const& _block) +ExecutionResult Interpreter::operator()(Block const& _block) { enterScope(_block); + ScopeGuard guard([this] { leaveScope(); }); + // Register functions. for (auto const& statement: _block.statements) if (std::holds_alternative(statement)) @@ -240,27 +283,27 @@ void Interpreter::operator()(Block const& _block) for (auto const& statement: _block.statements) { - incrementStep(); - visit(statement); - if (m_state.controlFlowState != ControlFlowState::Default) - break; + if (auto terminated = incrementStep()) return *terminated; + ExecutionResult statementRes = visit(statement); + if (statementRes != ExecutionResult(ExecutionOk{ ControlFlowState::Default })) + return statementRes; } - - leaveScope(); + return ExecutionOk{ ControlFlowState::Default }; } -u256 Interpreter::evaluate(Expression const& _expression) +ExecutionResult Interpreter::visit(Statement const& _st) { - ExpressionEvaluator ev(m_state, m_dialect, *m_scope, m_variables, m_disableExternalCalls, m_disableMemoryTrace); - ev.visit(_expression); - return ev.value(); + return std::visit(*this, _st); } -std::vector Interpreter::evaluateMulti(Expression const& _expression) +EvaluationResult Interpreter::evaluate(Expression const& _expression, size_t _numReturnVars) { ExpressionEvaluator ev(m_state, m_dialect, *m_scope, m_variables, m_disableExternalCalls, m_disableMemoryTrace); - ev.visit(_expression); - return ev.values(); + EvaluationResult res = ev.visit(_expression); + if (auto* resOk = std::get_if(&res)) + yulAssert(resOk->values.size() == _numReturnVars, ""); + + return res; } void Interpreter::enterScope(Block const& _block) @@ -283,36 +326,37 @@ void Interpreter::leaveScope() yulAssert(m_scope, ""); } -void Interpreter::incrementStep() +std::optional Interpreter::incrementStep() { m_state.numSteps++; if (m_state.maxSteps > 0 && m_state.numSteps >= m_state.maxSteps) - { - m_state.trace.emplace_back("Interpreter execution step limit reached."); - BOOST_THROW_EXCEPTION(StepLimitReached()); - } + return StepLimitReached(); + return std::nullopt; } -void ExpressionEvaluator::operator()(Literal const& _literal) +EvaluationResult ExpressionEvaluator::operator()(Literal const& _literal) { - incrementStep(); - setValue(_literal.value.value()); + if (auto terminated = incrementStep()) return *terminated; + return EvaluationOk(_literal.value.value()); } -void ExpressionEvaluator::operator()(Identifier const& _identifier) +EvaluationResult ExpressionEvaluator::operator()(Identifier const& _identifier) { solAssert(m_variables.count(_identifier.name), ""); - incrementStep(); - setValue(m_variables.at(_identifier.name)); + if (auto terminated = incrementStep()) return *terminated; + return EvaluationOk(m_variables.at(_identifier.name)); } -void ExpressionEvaluator::operator()(FunctionCall const& _funCall) +EvaluationResult ExpressionEvaluator::operator()(FunctionCall const& _funCall) { std::vector> const* literalArguments = nullptr; if (BuiltinFunction const* builtin = m_dialect.builtin(_funCall.functionName.name)) if (!builtin->literalArguments.empty()) literalArguments = &builtin->literalArguments; - evaluateArgs(_funCall.arguments, literalArguments); + EvaluationResult argsRes = evaluateArgs(_funCall.arguments, literalArguments); + if (auto* terminated = std::get_if(&argsRes)) return *terminated; + + std::vector argsValues = std::get(argsRes).values; if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) { @@ -320,7 +364,7 @@ void ExpressionEvaluator::operator()(FunctionCall const& _funCall) { EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state, m_disableMemoryTrace); - u256 const value = interpreter.evalBuiltin(*fun, _funCall.arguments, values()); + u256 const value = interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); if ( !m_disableExternalCalls && @@ -329,8 +373,7 @@ void ExpressionEvaluator::operator()(FunctionCall const& _funCall) ) runExternalCall(*fun->instruction); - setValue(value); - return; + return EvaluationOk(value); } } @@ -342,74 +385,65 @@ void ExpressionEvaluator::operator()(FunctionCall const& _funCall) FunctionDefinition const* fun = scope->names.at(_funCall.functionName.name); yulAssert(fun, "Function not found."); - yulAssert(m_values.size() == fun->parameters.size(), ""); + yulAssert(argsValues.size() == fun->parameters.size(), ""); std::map variables; for (size_t i = 0; i < fun->parameters.size(); ++i) - variables[fun->parameters.at(i).name] = m_values.at(i); + variables[fun->parameters.at(i).name] = argsValues.at(i); for (size_t i = 0; i < fun->returnVariables.size(); ++i) variables[fun->returnVariables.at(i).name] = 0; - m_state.controlFlowState = ControlFlowState::Default; std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); - (*interpreter)(fun->body); - m_state.controlFlowState = ControlFlowState::Default; + ExecutionResult funcBodyRes = (*interpreter)(fun->body); + if (auto* terminated = std::get_if(&funcBodyRes)) return *terminated; - m_values.clear(); + std::vector returnedValues; for (auto const& retVar: fun->returnVariables) - m_values.emplace_back(interpreter->valueOfVariable(retVar.name)); + returnedValues.emplace_back(interpreter->valueOfVariable(retVar.name)); + return EvaluationOk(returnedValues); } -u256 ExpressionEvaluator::value() const -{ - solAssert(m_values.size() == 1, ""); - return m_values.front(); -} - -void ExpressionEvaluator::setValue(u256 _value) -{ - m_values.clear(); - m_values.emplace_back(std::move(_value)); -} - -void ExpressionEvaluator::evaluateArgs( +EvaluationResult ExpressionEvaluator::evaluateArgs( std::vector const& _expr, std::vector> const* _literalArguments ) { - incrementStep(); + if (auto terminated = incrementStep()) return *terminated; std::vector values; size_t i = 0; /// Function arguments are evaluated in reverse. for (auto const& expr: _expr | ranges::views::reverse) { if (!_literalArguments || !_literalArguments->at(_expr.size() - i - 1)) - visit(expr); + { + EvaluationResult exprRes = visit(expr); + if (auto* terminated = std::get_if(&exprRes)) return *terminated; + std::vector const& exprValues = std::get(exprRes).values; + yulAssert(exprValues.size() == 1, ""); + values.push_back(exprValues.at(0)); + } else { if (std::get(expr).value.unlimited()) { yulAssert(std::get(expr).kind == LiteralKind::String); - m_values = {0xdeadbeef}; + values.push_back(0xdeadbeef); } else - m_values = {std::get(expr).value.value()}; + values.push_back(std::get(expr).value.value()); } - values.push_back(value()); ++i; } - m_values = std::move(values); - std::reverse(m_values.begin(), m_values.end()); + std::reverse(values.begin(), values.end()); + return EvaluationOk(values); } -void ExpressionEvaluator::incrementStep() +std::optional ExpressionEvaluator::incrementStep() { m_nestingLevel++; if (m_state.maxExprNesting > 0 && m_nestingLevel > m_state.maxExprNesting) - { - m_state.trace.emplace_back("Maximum expression nesting level reached."); - BOOST_THROW_EXCEPTION(ExpressionNestingLimitReached()); - } + return ExpressionNestingLimitReached(); + return std::nullopt; } void ExpressionEvaluator::runExternalCall(evmasm::Instruction _instruction) From 5e3c790f97c2e1a7bd002c9edda8aa3ae93e2583 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 19 Sep 2024 00:32:43 +0700 Subject: [PATCH 005/101] Remove runExternalCall --- libyul/tools/interpreter/Interpreter.cpp | 99 +----------------------- libyul/tools/interpreter/Interpreter.h | 12 --- 2 files changed, 2 insertions(+), 109 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index db370a41e07a..bbc5d3af362a 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -112,12 +112,11 @@ void Interpreter::run( InterpreterState& _state, Dialect const& _dialect, Block const& _ast, - bool _disableExternalCalls, bool _disableMemoryTrace ) { Scope scope; - Interpreter{_state, _dialect, scope, _disableExternalCalls, _disableMemoryTrace}(_ast); + Interpreter{_state, _dialect, scope, _disableMemoryTrace}(_ast); } ExecutionResult Interpreter::operator()(ExpressionStatement const& _expressionStatement) @@ -298,7 +297,7 @@ ExecutionResult Interpreter::visit(Statement const& _st) EvaluationResult Interpreter::evaluate(Expression const& _expression, size_t _numReturnVars) { - ExpressionEvaluator ev(m_state, m_dialect, *m_scope, m_variables, m_disableExternalCalls, m_disableMemoryTrace); + ExpressionEvaluator ev(m_state, m_dialect, *m_scope, m_variables, m_disableMemoryTrace); EvaluationResult res = ev.visit(_expression); if (auto* resOk = std::get_if(&res)) yulAssert(resOk->values.size() == _numReturnVars, ""); @@ -366,13 +365,6 @@ EvaluationResult ExpressionEvaluator::operator()(FunctionCall const& _funCall) u256 const value = interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); - if ( - !m_disableExternalCalls && - fun->instruction && - evmasm::isCallInstruction(*fun->instruction) - ) - runExternalCall(*fun->instruction); - return EvaluationOk(value); } } @@ -445,90 +437,3 @@ std::optional ExpressionEvaluator::incrementStep() return ExpressionNestingLimitReached(); return std::nullopt; } - -void ExpressionEvaluator::runExternalCall(evmasm::Instruction _instruction) -{ - u256 memOutOffset = 0; - u256 memOutSize = 0; - u256 callvalue = 0; - u256 memInOffset = 0; - u256 memInSize = 0; - - // Setup memOut* values - if ( - _instruction == evmasm::Instruction::CALL || - _instruction == evmasm::Instruction::CALLCODE - ) - { - memOutOffset = values()[5]; - memOutSize = values()[6]; - callvalue = values()[2]; - memInOffset = values()[3]; - memInSize = values()[4]; - } - else if ( - _instruction == evmasm::Instruction::DELEGATECALL || - _instruction == evmasm::Instruction::STATICCALL - ) - { - memOutOffset = values()[4]; - memOutSize = values()[5]; - memInOffset = values()[2]; - memInSize = values()[3]; - } - else - yulAssert(false); - - // Don't execute external call if it isn't our own address - if (values()[1] != util::h160::Arith(m_state.address)) - return; - - Scope tmpScope; - InterpreterState tmpState; - tmpState.calldata = m_state.readMemory(memInOffset, memInSize); - tmpState.callvalue = callvalue; - tmpState.numInstance = m_state.numInstance + 1; - - yulAssert(tmpState.numInstance < 1024, "Detected more than 1024 recursive calls, aborting..."); - - // Create new interpreter for the called contract - std::unique_ptr newInterpreter = makeInterpreterNew(tmpState, tmpScope); - - Scope* abstractRootScope = &m_scope; - Scope* fileScope = nullptr; - Block const* ast = nullptr; - - // Find file scope - while (abstractRootScope->parent) - { - fileScope = abstractRootScope; - abstractRootScope = abstractRootScope->parent; - } - - // Get AST for file scope - for (auto&& [block, scope]: abstractRootScope->subScopes) - if (scope.get() == fileScope) - { - ast = block; - break; - } - - yulAssert(ast); - - try - { - (*newInterpreter)(*ast); - } - catch (ExplicitlyTerminatedWithReturn const&) - { - // Copy return data to our memory - copyZeroExtended( - m_state.memory, - newInterpreter->returnData(), - memOutOffset.convert_to(), - 0, - memOutSize.convert_to() - ); - m_state.returndata = newInterpreter->returnData(); - } -} diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index c26f7542cddd..b8884b2bc639 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -209,7 +209,6 @@ class Interpreter InterpreterState& _state, Dialect const& _dialect, Block const& _ast, - bool _disableExternalCalls, bool _disableMemoryTracing ); @@ -217,7 +216,6 @@ class Interpreter InterpreterState& _state, Dialect const& _dialect, Scope& _scope, - bool _disableExternalCalls, bool _disableMemoryTracing, std::map _variables = {} ): @@ -225,7 +223,6 @@ class Interpreter m_state(_state), m_variables(std::move(_variables)), m_scope(&_scope), - m_disableExternalCalls(_disableExternalCalls), m_disableMemoryTrace(_disableMemoryTracing) { } @@ -265,9 +262,6 @@ class Interpreter /// Values of variables. std::map m_variables; Scope* m_scope; - /// If not set, external calls (e.g. using `call()`) to the same contract - /// are evaluated in a new parser instance. - bool m_disableExternalCalls; bool m_disableMemoryTrace; }; @@ -282,14 +276,12 @@ class ExpressionEvaluator Dialect const& _dialect, Scope& _scope, std::map const& _variables, - bool _disableExternalCalls, bool _disableMemoryTrace ): m_state(_state), m_dialect(_dialect), m_variables(_variables), m_scope(_scope), - m_disableExternalCalls(_disableExternalCalls), m_disableMemoryTrace(_disableMemoryTrace) {} @@ -300,14 +292,12 @@ class ExpressionEvaluator EvaluationResult visit(Expression const& _st); protected: - void runExternalCall(evmasm::Instruction _instruction); virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const { return std::make_unique( m_state, m_dialect, m_scope, - m_disableExternalCalls, m_disableMemoryTrace, std::move(_variables) ); @@ -318,7 +308,6 @@ class ExpressionEvaluator _state, m_dialect, _scope, - m_disableExternalCalls, m_disableMemoryTrace ); } @@ -342,7 +331,6 @@ class ExpressionEvaluator Scope& m_scope; /// Current expression nesting level unsigned m_nestingLevel = 0; - bool m_disableExternalCalls; /// Flag to disable memory tracing bool m_disableMemoryTrace; }; From a1a972111b0ecec1c5474e655ff9b815a26a5b2b Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:16:36 +0700 Subject: [PATCH 006/101] Minor comment edit --- libyul/tools/interpreter/Interpreter.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index b8884b2bc639..103bdac284d9 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -253,8 +253,8 @@ class Interpreter void enterScope(Block const& _block); void leaveScope(); - /// Increment interpreter step count, throwing exception if step limit - /// is reached. + /// Increment interpreter step count, returning StepLimitReached if step + /// limit is reached. std::optional incrementStep(); Dialect const& m_dialect; @@ -319,9 +319,9 @@ class ExpressionEvaluator std::vector> const* _literalArguments ); - /// Increment evaluation count, throwing exception if the - /// nesting level is beyond the upper bound configured in - /// the interpreter state. + /// Increment evaluation count, returning ExpressionNestingLimitReached if + /// the nesting level is beyond the upper bound configured in the + /// interpreter state. std::optional incrementStep(); InterpreterState& m_state; From 92d889451685ab70c57dcfb131eabd6028042573 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:20:45 +0700 Subject: [PATCH 007/101] Implement visit(Expression) for ExpressionEvaluator --- libyul/tools/interpreter/Interpreter.cpp | 5 +++++ libyul/tools/interpreter/Interpreter.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index bbc5d3af362a..dba64058faca 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -333,6 +333,11 @@ std::optional Interpreter::incrementStep() return std::nullopt; } +EvaluationResult ExpressionEvaluator::visit(Expression const& _st) +{ + return std::visit(*this, _st); +} + EvaluationResult ExpressionEvaluator::operator()(Literal const& _literal) { if (auto terminated = incrementStep()) return *terminated; diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index 103bdac284d9..15536aa458b3 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -285,12 +285,12 @@ class ExpressionEvaluator m_disableMemoryTrace(_disableMemoryTrace) {} + EvaluationResult visit(Expression const& _st); + EvaluationResult operator()(Literal const&); EvaluationResult operator()(Identifier const&); EvaluationResult operator()(FunctionCall const& _funCall); - EvaluationResult visit(Expression const& _st); - protected: virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const { From f4078ad5cadf960e224ec87e5e9748b2810032a3 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:22:43 +0700 Subject: [PATCH 008/101] Force incrementStep logic to be done at visit function --- libyul/tools/interpreter/Interpreter.cpp | 25 +++++++++--------------- libyul/tools/interpreter/Interpreter.h | 4 ++-- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index dba64058faca..7c14c2dd7d7a 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -225,13 +225,8 @@ ExecutionResult Interpreter::operator()(ForLoop const& _forLoop) if (std::get(conditionRes).values.at(0) == 0) break; } - // Increment step for each loop iteration for loops with - // an empty body and post blocks to prevent a deadlock. - if (_forLoop.body.statements.size() == 0 && _forLoop.post.statements.size() == 0) - if (auto terminated = incrementStep()) return *terminated; - { - ExecutionResult bodyRes = (*this)(_forLoop.body); + ExecutionResult bodyRes = visit(_forLoop.body); if ( std::holds_alternative(bodyRes) || bodyRes == ExecutionResult(ExecutionOk{ ControlFlowState::Leave }) @@ -242,7 +237,7 @@ ExecutionResult Interpreter::operator()(ForLoop const& _forLoop) } { - ExecutionResult postRes = (*this)(_forLoop.post); + ExecutionResult postRes = visit(_forLoop.post); if ( std::holds_alternative(postRes) || postRes == ExecutionResult(ExecutionOk{ ControlFlowState::Leave }) @@ -282,7 +277,6 @@ ExecutionResult Interpreter::operator()(Block const& _block) for (auto const& statement: _block.statements) { - if (auto terminated = incrementStep()) return *terminated; ExecutionResult statementRes = visit(statement); if (statementRes != ExecutionResult(ExecutionOk{ ControlFlowState::Default })) return statementRes; @@ -292,6 +286,7 @@ ExecutionResult Interpreter::operator()(Block const& _block) ExecutionResult Interpreter::visit(Statement const& _st) { + if (auto terminated = incrementStep()) return *terminated; return std::visit(*this, _st); } @@ -333,21 +328,14 @@ std::optional Interpreter::incrementStep() return std::nullopt; } -EvaluationResult ExpressionEvaluator::visit(Expression const& _st) -{ - return std::visit(*this, _st); -} - EvaluationResult ExpressionEvaluator::operator()(Literal const& _literal) { - if (auto terminated = incrementStep()) return *terminated; return EvaluationOk(_literal.value.value()); } EvaluationResult ExpressionEvaluator::operator()(Identifier const& _identifier) { solAssert(m_variables.count(_identifier.name), ""); - if (auto terminated = incrementStep()) return *terminated; return EvaluationOk(m_variables.at(_identifier.name)); } @@ -399,12 +387,17 @@ EvaluationResult ExpressionEvaluator::operator()(FunctionCall const& _funCall) return EvaluationOk(returnedValues); } +EvaluationResult ExpressionEvaluator::visit(Expression const& _st) +{ + if (auto terminated = incrementStep()) return *terminated; + return std::visit(*this, _st); +} + EvaluationResult ExpressionEvaluator::evaluateArgs( std::vector const& _expr, std::vector> const* _literalArguments ) { - if (auto terminated = incrementStep()) return *terminated; std::vector values; size_t i = 0; /// Function arguments are evaluated in reverse. diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index 15536aa458b3..103bdac284d9 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -285,12 +285,12 @@ class ExpressionEvaluator m_disableMemoryTrace(_disableMemoryTrace) {} - EvaluationResult visit(Expression const& _st); - EvaluationResult operator()(Literal const&); EvaluationResult operator()(Identifier const&); EvaluationResult operator()(FunctionCall const& _funCall); + EvaluationResult visit(Expression const& _st); + protected: virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const { From ba8d51530547c4c08d57fc8a67d16cde51c4100c Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:37:31 +0700 Subject: [PATCH 009/101] Merge ExpressionEvaluator into Interpreter --- libyul/tools/interpreter/Interpreter.cpp | 27 ++++----- libyul/tools/interpreter/Interpreter.h | 76 ++++++++---------------- 2 files changed, 38 insertions(+), 65 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index 7c14c2dd7d7a..97258033dd69 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -286,14 +286,13 @@ ExecutionResult Interpreter::operator()(Block const& _block) ExecutionResult Interpreter::visit(Statement const& _st) { - if (auto terminated = incrementStep()) return *terminated; + if (auto terminated = incrementStatementStep()) return *terminated; return std::visit(*this, _st); } EvaluationResult Interpreter::evaluate(Expression const& _expression, size_t _numReturnVars) { - ExpressionEvaluator ev(m_state, m_dialect, *m_scope, m_variables, m_disableMemoryTrace); - EvaluationResult res = ev.visit(_expression); + EvaluationResult res = visit(_expression); if (auto* resOk = std::get_if(&res)) yulAssert(resOk->values.size() == _numReturnVars, ""); @@ -320,7 +319,7 @@ void Interpreter::leaveScope() yulAssert(m_scope, ""); } -std::optional Interpreter::incrementStep() +std::optional Interpreter::incrementStatementStep() { m_state.numSteps++; if (m_state.maxSteps > 0 && m_state.numSteps >= m_state.maxSteps) @@ -328,18 +327,18 @@ std::optional Interpreter::incrementStep() return std::nullopt; } -EvaluationResult ExpressionEvaluator::operator()(Literal const& _literal) +EvaluationResult Interpreter::operator()(Literal const& _literal) { return EvaluationOk(_literal.value.value()); } -EvaluationResult ExpressionEvaluator::operator()(Identifier const& _identifier) +EvaluationResult Interpreter::operator()(Identifier const& _identifier) { solAssert(m_variables.count(_identifier.name), ""); return EvaluationOk(m_variables.at(_identifier.name)); } -EvaluationResult ExpressionEvaluator::operator()(FunctionCall const& _funCall) +EvaluationResult Interpreter::operator()(FunctionCall const& _funCall) { std::vector> const* literalArguments = nullptr; if (BuiltinFunction const* builtin = m_dialect.builtin(_funCall.functionName.name)) @@ -362,7 +361,7 @@ EvaluationResult ExpressionEvaluator::operator()(FunctionCall const& _funCall) } } - Scope* scope = &m_scope; + Scope* scope = m_scope; for (; scope; scope = scope->parent) if (scope->names.count(_funCall.functionName.name)) break; @@ -387,13 +386,13 @@ EvaluationResult ExpressionEvaluator::operator()(FunctionCall const& _funCall) return EvaluationOk(returnedValues); } -EvaluationResult ExpressionEvaluator::visit(Expression const& _st) +EvaluationResult Interpreter::visit(Expression const& _st) { - if (auto terminated = incrementStep()) return *terminated; + if (auto terminated = incrementExpressionStep()) return *terminated; return std::visit(*this, _st); } -EvaluationResult ExpressionEvaluator::evaluateArgs( +EvaluationResult Interpreter::evaluateArgs( std::vector const& _expr, std::vector> const* _literalArguments ) @@ -428,10 +427,10 @@ EvaluationResult ExpressionEvaluator::evaluateArgs( return EvaluationOk(values); } -std::optional ExpressionEvaluator::incrementStep() +std::optional Interpreter::incrementExpressionStep() { - m_nestingLevel++; - if (m_state.maxExprNesting > 0 && m_nestingLevel > m_state.maxExprNesting) + m_expressionNestingLevel++; + if (m_state.maxExprNesting > 0 && m_expressionNestingLevel > m_state.maxExprNesting) return ExpressionNestingLimitReached(); return std::nullopt; } diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index 103bdac284d9..74b90cbc086b 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -227,6 +227,8 @@ class Interpreter { } + // Statement visit methods + ExecutionResult operator()(ExpressionStatement const& _statement); ExecutionResult operator()(Assignment const& _assignment); ExecutionResult operator()(VariableDeclaration const& _varDecl); @@ -241,49 +243,7 @@ class Interpreter ExecutionResult visit(Statement const& _st); - bytes returnData() const { return m_state.returndata; } - std::vector const& trace() const { return m_state.trace; } - - u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } - -protected: - // evaluate the expression and assert that the number of return variable is _numReturnVars - virtual EvaluationResult evaluate(Expression const& _expression, size_t _numReturnVars); - - void enterScope(Block const& _block); - void leaveScope(); - - /// Increment interpreter step count, returning StepLimitReached if step - /// limit is reached. - std::optional incrementStep(); - - Dialect const& m_dialect; - InterpreterState& m_state; - /// Values of variables. - std::map m_variables; - Scope* m_scope; - bool m_disableMemoryTrace; -}; - -/** - * Yul expression evaluator. - */ -class ExpressionEvaluator -{ -public: - ExpressionEvaluator( - InterpreterState& _state, - Dialect const& _dialect, - Scope& _scope, - std::map const& _variables, - bool _disableMemoryTrace - ): - m_state(_state), - m_dialect(_dialect), - m_variables(_variables), - m_scope(_scope), - m_disableMemoryTrace(_disableMemoryTrace) - {} + // Expression visit methods EvaluationResult operator()(Literal const&); EvaluationResult operator()(Identifier const&); @@ -291,13 +251,18 @@ class ExpressionEvaluator EvaluationResult visit(Expression const& _st); + bytes returnData() const { return m_state.returndata; } + std::vector const& trace() const { return m_state.trace; } + + u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } + protected: virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const { return std::make_unique( m_state, m_dialect, - m_scope, + *m_scope, m_disableMemoryTrace, std::move(_variables) ); @@ -319,20 +284,29 @@ class ExpressionEvaluator std::vector> const* _literalArguments ); + // evaluate the expression and assert that the number of return variable is _numReturnVars + virtual EvaluationResult evaluate(Expression const& _expression, size_t _numReturnVars); + + void enterScope(Block const& _block); + void leaveScope(); + + /// Increment interpreter step count, returning StepLimitReached if step + /// limit is reached. + std::optional incrementStatementStep(); + /// Increment evaluation count, returning ExpressionNestingLimitReached if /// the nesting level is beyond the upper bound configured in the /// interpreter state. - std::optional incrementStep(); + std::optional incrementExpressionStep(); - InterpreterState& m_state; Dialect const& m_dialect; + InterpreterState& m_state; /// Values of variables. - std::map const& m_variables; - Scope& m_scope; - /// Current expression nesting level - unsigned m_nestingLevel = 0; - /// Flag to disable memory tracing + std::map m_variables; + Scope* m_scope; bool m_disableMemoryTrace; + + unsigned m_expressionNestingLevel = 0; }; } From cdbb05cb5b78fc67fb28ecf305ce61ac13cbf03e Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:40:09 +0700 Subject: [PATCH 010/101] Reorder methods --- libyul/tools/interpreter/Interpreter.cpp | 74 ++++++++++++------------ libyul/tools/interpreter/Interpreter.h | 6 +- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index 97258033dd69..0c2afd2d1702 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -290,43 +290,6 @@ ExecutionResult Interpreter::visit(Statement const& _st) return std::visit(*this, _st); } -EvaluationResult Interpreter::evaluate(Expression const& _expression, size_t _numReturnVars) -{ - EvaluationResult res = visit(_expression); - if (auto* resOk = std::get_if(&res)) - yulAssert(resOk->values.size() == _numReturnVars, ""); - - return res; -} - -void Interpreter::enterScope(Block const& _block) -{ - if (!m_scope->subScopes.count(&_block)) - m_scope->subScopes[&_block] = std::make_unique(Scope{ - {}, - {}, - m_scope - }); - m_scope = m_scope->subScopes[&_block].get(); -} - -void Interpreter::leaveScope() -{ - for (auto const& [var, funDeclaration]: m_scope->names) - if (!funDeclaration) - m_variables.erase(var); - m_scope = m_scope->parent; - yulAssert(m_scope, ""); -} - -std::optional Interpreter::incrementStatementStep() -{ - m_state.numSteps++; - if (m_state.maxSteps > 0 && m_state.numSteps >= m_state.maxSteps) - return StepLimitReached(); - return std::nullopt; -} - EvaluationResult Interpreter::operator()(Literal const& _literal) { return EvaluationOk(_literal.value.value()); @@ -392,6 +355,15 @@ EvaluationResult Interpreter::visit(Expression const& _st) return std::visit(*this, _st); } +EvaluationResult Interpreter::evaluate(Expression const& _expression, size_t _numReturnVars) +{ + EvaluationResult res = visit(_expression); + if (auto* resOk = std::get_if(&res)) + yulAssert(resOk->values.size() == _numReturnVars, ""); + + return res; +} + EvaluationResult Interpreter::evaluateArgs( std::vector const& _expr, std::vector> const* _literalArguments @@ -427,6 +399,34 @@ EvaluationResult Interpreter::evaluateArgs( return EvaluationOk(values); } +void Interpreter::enterScope(Block const& _block) +{ + if (!m_scope->subScopes.count(&_block)) + m_scope->subScopes[&_block] = std::make_unique(Scope{ + {}, + {}, + m_scope + }); + m_scope = m_scope->subScopes[&_block].get(); +} + +void Interpreter::leaveScope() +{ + for (auto const& [var, funDeclaration]: m_scope->names) + if (!funDeclaration) + m_variables.erase(var); + m_scope = m_scope->parent; + yulAssert(m_scope, ""); +} + +std::optional Interpreter::incrementStatementStep() +{ + m_state.numSteps++; + if (m_state.maxSteps > 0 && m_state.numSteps >= m_state.maxSteps) + return StepLimitReached(); + return std::nullopt; +} + std::optional Interpreter::incrementExpressionStep() { m_expressionNestingLevel++; diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index 74b90cbc086b..063a5cec2555 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -277,6 +277,9 @@ class Interpreter ); } + // evaluate the expression and assert that the number of return variable is _numReturnVars + virtual EvaluationResult evaluate(Expression const& _expression, size_t _numReturnVars); + /// Evaluates the given expression from right to left and /// stores it in m_value. EvaluationResult evaluateArgs( @@ -284,9 +287,6 @@ class Interpreter std::vector> const* _literalArguments ); - // evaluate the expression and assert that the number of return variable is _numReturnVars - virtual EvaluationResult evaluate(Expression const& _expression, size_t _numReturnVars); - void enterScope(Block const& _block); void leaveScope(); From 02877d153f583988cf0c3aba756ee4eece908623 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:43:54 +0700 Subject: [PATCH 011/101] Reset expressionNestingLevel after each incrementStatementStep --- libyul/tools/interpreter/Interpreter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index 0c2afd2d1702..bb36fd8cf184 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -424,6 +424,9 @@ std::optional Interpreter::incrementStatementStep() m_state.numSteps++; if (m_state.maxSteps > 0 && m_state.numSteps >= m_state.maxSteps) return StepLimitReached(); + + // Reset m_expressionNestingLevel, preparing for new expression. + m_expressionNestingLevel = 0; return std::nullopt; } From 352fb644e373f718880184db7d2b6c4bf14dec65 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:45:12 +0700 Subject: [PATCH 012/101] Remove redundant makeInterpreterNew function --- libyul/tools/interpreter/Interpreter.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index 063a5cec2555..15fde52bee8d 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -267,15 +267,6 @@ class Interpreter std::move(_variables) ); } - virtual std::unique_ptr makeInterpreterNew(InterpreterState& _state, Scope& _scope) const - { - return std::make_unique( - _state, - m_dialect, - _scope, - m_disableMemoryTrace - ); - } // evaluate the expression and assert that the number of return variable is _numReturnVars virtual EvaluationResult evaluate(Expression const& _expression, size_t _numReturnVars); From 05b6540dfeec5895f1cd10bab147b9139dd5033b Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:48:18 +0700 Subject: [PATCH 013/101] Remove unused disableMemoryTrace --- libyul/tools/interpreter/Interpreter.cpp | 7 +++---- libyul/tools/interpreter/Interpreter.h | 13 +++---------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index bb36fd8cf184..e12c383fa528 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -111,12 +111,11 @@ void InterpreterState::dumpTraceAndState(std::ostream& _out, bool _disableMemory void Interpreter::run( InterpreterState& _state, Dialect const& _dialect, - Block const& _ast, - bool _disableMemoryTrace + Block const& _ast ) { Scope scope; - Interpreter{_state, _dialect, scope, _disableMemoryTrace}(_ast); + Interpreter{_state, _dialect, scope}(_ast); } ExecutionResult Interpreter::operator()(ExpressionStatement const& _expressionStatement) @@ -316,7 +315,7 @@ EvaluationResult Interpreter::operator()(FunctionCall const& _funCall) { if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) { - EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state, m_disableMemoryTrace); + EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state, false); u256 const value = interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index 15fde52bee8d..514d7e58d9ef 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -201,29 +201,23 @@ struct Scope class Interpreter { public: - /// Executes the Yul interpreter. Flag @param _disableMemoryTracing if set ensures that - /// instructions that write to memory do not affect @param _state. This - /// avoids false positives reports by the fuzzer when certain optimizer steps are - /// activated e.g., Redundant store eliminator, Equal store eliminator. + /// Executes the Yul interpreter. static void run( InterpreterState& _state, Dialect const& _dialect, - Block const& _ast, - bool _disableMemoryTracing + Block const& _ast ); Interpreter( InterpreterState& _state, Dialect const& _dialect, Scope& _scope, - bool _disableMemoryTracing, std::map _variables = {} ): m_dialect(_dialect), m_state(_state), m_variables(std::move(_variables)), - m_scope(&_scope), - m_disableMemoryTrace(_disableMemoryTracing) + m_scope(&_scope) { } @@ -263,7 +257,6 @@ class Interpreter m_state, m_dialect, *m_scope, - m_disableMemoryTrace, std::move(_variables) ); } From e94f923308f0b9e3420712a80326df6fe5183baf Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:52:14 +0700 Subject: [PATCH 014/101] Remove state with side effect from InterpreterState --- libyul/tools/interpreter/Interpreter.cpp | 64 ------------------------ libyul/tools/interpreter/Interpreter.h | 57 --------------------- 2 files changed, 121 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index e12c383fa528..36ff5899ba58 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -44,70 +44,6 @@ using namespace solidity::yul::tools::interpreter; using solidity::util::h256; -void InterpreterState::dumpStorage(std::ostream& _out) const -{ - for (auto const& [slot, value]: storage) - if (value != h256{}) - _out << " " << slot.hex() << ": " << value.hex() << std::endl; -} - -void InterpreterState::dumpTransientStorage(std::ostream& _out) const -{ - for (auto const& [slot, value]: transientStorage) - if (value != h256{}) - _out << " " << slot.hex() << ": " << value.hex() << std::endl; -} - -void InterpreterState::dumpTraceAndState(std::ostream& _out, bool _disableMemoryTrace) const -{ - _out << "Trace:" << std::endl; - for (auto const& line: trace) - _out << " " << line << std::endl; - if (!_disableMemoryTrace) - { - _out << "Memory dump:\n"; - std::map words; - for (auto const& [offset, value]: memory) - words[(offset / 0x20) * 0x20] |= u256(uint32_t(value)) << (256 - 8 - 8 * static_cast(offset % 0x20)); - for (auto const& [offset, value]: words) - if (value != 0) - _out << " " << std::uppercase << std::hex << std::setw(4) << offset << ": " << h256(value).hex() << std::endl; - } - _out << "Storage dump:" << std::endl; - dumpStorage(_out); - - _out << "Transient storage dump:" << std::endl; - dumpTransientStorage(_out); - - if (!calldata.empty()) - { - _out << "Calldata dump:"; - - for (size_t offset = 0; offset < calldata.size(); ++offset) - if (calldata[offset] != 0) - { - if (offset % 32 == 0) - _out << - std::endl << - " " << - std::uppercase << - std::hex << - std::setfill(' ') << - std::setw(4) << - offset << - ": "; - - _out << - std::hex << - std::setw(2) << - std::setfill('0') << - static_cast(calldata[offset]); - } - - _out << std::endl; - } -} - void Interpreter::run( InterpreterState& _state, Dialect const& _dialect, diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index 514d7e58d9ef..e44bcd52bea6 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -121,35 +121,6 @@ using EvaluationResult = std::variant; struct InterpreterState { - bytes calldata; - bytes returndata; - std::map memory; - /// This is different than memory.size() because we ignore gas. - u256 msize; - std::map storage; - std::map transientStorage; - util::h160 address = util::h160("0x0000000000000000000000000000000011111111"); - u256 balance = 0x22222222; - u256 selfbalance = 0x22223333; - util::h160 origin = util::h160("0x0000000000000000000000000000000033333333"); - util::h160 caller = util::h160("0x0000000000000000000000000000000044444444"); - u256 callvalue = 0x55555555; - /// Deployed code - bytes code = util::asBytes("codecodecodecodecode"); - u256 gasprice = 0x66666666; - util::h160 coinbase = util::h160("0x0000000000000000000000000000000077777777"); - u256 timestamp = 0x88888888; - u256 blockNumber = 1024; - u256 difficulty = 0x9999999; - u256 prevrandao = (u256(1) << 64) + 1; - u256 gaslimit = 4000000; - u256 chainid = 0x01; - /// The minimum value of basefee: 7 wei. - u256 basefee = 0x07; - /// The minimum value of blobbasefee: 1 wei. - u256 blobbasefee = 0x01; - /// Log of changes / effects. Sholud be structured data in the future. - std::vector trace; /// This is actually an input parameter that more or less limits the runtime. size_t maxTraceSize = 0; size_t maxSteps = 0; @@ -158,30 +129,6 @@ struct InterpreterState /// Number of the current state instance, used for recursion protection size_t numInstance = 0; - - // Blob commitment hash version - util::FixedHash<1> const blobHashVersion = util::FixedHash<1>(1); - // Blob commitments - std::array const blobCommitments = {0x01, 0x02}; - - /// Prints execution trace and non-zero storage to @param _out. - /// Flag @param _disableMemoryTrace, if set, does not produce a memory dump. This - /// avoids false positives reports by the fuzzer when certain optimizer steps are - /// activated e.g., Redundant store eliminator, Equal store eliminator. - void dumpTraceAndState(std::ostream& _out, bool _disableMemoryTrace) const; - /// Prints non-zero storage to @param _out. - void dumpStorage(std::ostream& _out) const; - /// Prints non-zero transient storage to @param _out. - void dumpTransientStorage(std::ostream& _out) const; - - bytes readMemory(u256 const& _offset, u256 const& _size) - { - yulAssert(_size <= 0xffff, "Too large read."); - bytes data(size_t(_size), uint8_t(0)); - for (size_t i = 0; i < data.size(); ++i) - data[i] = memory[_offset + i]; - return data; - } }; /** @@ -245,9 +192,6 @@ class Interpreter EvaluationResult visit(Expression const& _st); - bytes returnData() const { return m_state.returndata; } - std::vector const& trace() const { return m_state.trace; } - u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } protected: @@ -288,7 +232,6 @@ class Interpreter /// Values of variables. std::map m_variables; Scope* m_scope; - bool m_disableMemoryTrace; unsigned m_expressionNestingLevel = 0; }; From bfd8e8e7f26b4d7e4c1499041312095e35aa7402 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:55:44 +0700 Subject: [PATCH 015/101] Move Interpreter Config to a separate struct --- libyul/tools/interpreter/Interpreter.cpp | 4 ++-- libyul/tools/interpreter/Interpreter.h | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index 36ff5899ba58..d8fcd9f9187a 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -357,7 +357,7 @@ void Interpreter::leaveScope() std::optional Interpreter::incrementStatementStep() { m_state.numSteps++; - if (m_state.maxSteps > 0 && m_state.numSteps >= m_state.maxSteps) + if (m_state.config.maxSteps > 0 && m_state.numSteps >= m_state.config.maxSteps) return StepLimitReached(); // Reset m_expressionNestingLevel, preparing for new expression. @@ -368,7 +368,7 @@ std::optional Interpreter::incrementStatementStep() std::optional Interpreter::incrementExpressionStep() { m_expressionNestingLevel++; - if (m_state.maxExprNesting > 0 && m_expressionNestingLevel > m_state.maxExprNesting) + if (m_state.config.maxExprNesting > 0 && m_expressionNestingLevel > m_state.config.maxExprNesting) return ExpressionNestingLimitReached(); return std::nullopt; } diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index e44bcd52bea6..9591e36f27d8 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -119,13 +119,18 @@ struct EvaluationOk using ExecutionResult = std::variant; using EvaluationResult = std::variant; -struct InterpreterState +struct InterpreterConfig { - /// This is actually an input parameter that more or less limits the runtime. size_t maxTraceSize = 0; size_t maxSteps = 0; - size_t numSteps = 0; size_t maxExprNesting = 0; +}; + +struct InterpreterState +{ + InterpreterConfig const config; + + size_t numSteps = 0; /// Number of the current state instance, used for recursion protection size_t numInstance = 0; From 89f005aab83e190d4048eddf9bdfa7cc5000639e Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 22:57:16 +0700 Subject: [PATCH 016/101] Remove redundant numInstance --- libyul/tools/interpreter/Interpreter.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index 9591e36f27d8..afec90eb30e0 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -131,9 +131,6 @@ struct InterpreterState InterpreterConfig const config; size_t numSteps = 0; - - /// Number of the current state instance, used for recursion protection - size_t numInstance = 0; }; /** From f1e68e5ec463666d04813b5e1c026cc106e9c7d1 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 23:09:15 +0700 Subject: [PATCH 017/101] Add recursion depth check --- libyul/tools/interpreter/Interpreter.cpp | 7 ++++++- libyul/tools/interpreter/Interpreter.h | 14 +++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index d8fcd9f9187a..9129948649e2 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -51,7 +51,7 @@ void Interpreter::run( ) { Scope scope; - Interpreter{_state, _dialect, scope}(_ast); + Interpreter{_state, _dialect, scope, 0}(_ast); } ExecutionResult Interpreter::operator()(ExpressionStatement const& _expressionStatement) @@ -360,6 +360,11 @@ std::optional Interpreter::incrementStatementStep() if (m_state.config.maxSteps > 0 && m_state.numSteps >= m_state.config.maxSteps) return StepLimitReached(); + // Checking recursion depth here because we are sure that a statement + // inside the body evaluated. + if (m_state.config.maxRecursionDepth > 0 && m_recursionDepth > m_state.config.maxRecursionDepth) + return RecursionDepthLimitReached(); + // Reset m_expressionNestingLevel, preparing for new expression. m_expressionNestingLevel = 0; return std::nullopt; diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index afec90eb30e0..3a56cc07e492 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -66,6 +66,10 @@ class TraceLimitReached : public ExecutionTerminatedCommon { }; +class RecursionDepthLimitReached : public ExecutionTerminatedCommon +{ +}; + class ExpressionNestingLimitReached : public ExecutionTerminatedCommon { }; @@ -75,6 +79,7 @@ using ExecutionTerminated = std::variant< ExplicitlyTerminatedWithReturn, StepLimitReached, TraceLimitReached, + RecursionDepthLimitReached, ExpressionNestingLimitReached >; @@ -124,6 +129,7 @@ struct InterpreterConfig size_t maxTraceSize = 0; size_t maxSteps = 0; size_t maxExprNesting = 0; + size_t maxRecursionDepth = 0; }; struct InterpreterState @@ -161,12 +167,16 @@ class Interpreter InterpreterState& _state, Dialect const& _dialect, Scope& _scope, + size_t _callerRecursionDepth, std::map _variables = {} ): m_dialect(_dialect), m_state(_state), m_variables(std::move(_variables)), - m_scope(&_scope) + m_scope(&_scope), + + // The only place that increases recursion depth + m_recursionDepth(_callerRecursionDepth + 1) { } @@ -203,6 +213,7 @@ class Interpreter m_state, m_dialect, *m_scope, + m_recursionDepth, std::move(_variables) ); } @@ -235,6 +246,7 @@ class Interpreter std::map m_variables; Scope* m_scope; + size_t const m_recursionDepth = 0; unsigned m_expressionNestingLevel = 0; }; From 4ff53cbf7ce3f02fc454e55c7e357f459e7dafb8 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 23:17:58 +0700 Subject: [PATCH 018/101] Remove functions with side-effect from EVMInstructionInterpreter --- .../interpreter/EVMInstructionInterpreter.cpp | 157 ------------------ .../interpreter/EVMInstructionInterpreter.h | 84 +--------- libyul/tools/interpreter/Interpreter.cpp | 2 +- 3 files changed, 6 insertions(+), 237 deletions(-) diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.cpp b/libyul/tools/interpreter/EVMInstructionInterpreter.cpp index 933c8ba6a41a..087ca5efeebe 100644 --- a/libyul/tools/interpreter/EVMInstructionInterpreter.cpp +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.cpp @@ -545,160 +545,3 @@ u256 EVMInstructionInterpreter::evalBuiltin( return 0; } - -bool EVMInstructionInterpreter::accessMemory(u256 const& _offset, u256 const& _size) -{ - if (_size == 0) - return true; - - if (_offset <= (_offset + _size) && (_offset + _size) <= (_offset + _size + 0x1f)) - { - u256 newMSize = (_offset + _size + 0x1f) & ~u256(0x1f); - m_state.msize = std::max(m_state.msize, newMSize); - // We only record accesses to contiguous memory chunks that are at most s_maxRangeSize bytes - // in size and at an offset of at most numeric_limits::max() - s_maxRangeSize - return _size <= s_maxRangeSize && _offset <= u256(std::numeric_limits::max() - s_maxRangeSize); - } - - m_state.msize = u256(-1); - return false; -} - -bytes EVMInstructionInterpreter::readMemory(u256 const& _offset, u256 const& _size) -{ - yulAssert(_size <= s_maxRangeSize, "Too large read."); - bytes data(size_t(_size), uint8_t(0)); - for (size_t i = 0; i < data.size(); ++i) - data[i] = m_state.memory[_offset + i]; - return data; -} - -u256 EVMInstructionInterpreter::readMemoryWord(u256 const& _offset) -{ - return u256(h256(m_state.readMemory(_offset, 32))); -} - -void EVMInstructionInterpreter::writeMemoryWord(u256 const& _offset, u256 const& _value) -{ - for (size_t i = 0; i < 32; i++) - m_state.memory[_offset + i] = uint8_t((_value >> (8 * (31 - i))) & 0xff); -} - - -void EVMInstructionInterpreter::logTrace( - evmasm::Instruction _instruction, - std::vector const& _arguments, - bytes const& _data -) -{ - logTrace( - evmasm::instructionInfo(_instruction, m_evmVersion).name, - SemanticInformation::memory(_instruction) == SemanticInformation::Effect::Write, - _arguments, - _data - ); -} - -void EVMInstructionInterpreter::logTrace( - std::string const& _pseudoInstruction, - bool _writesToMemory, - std::vector const& _arguments, - bytes const& _data -) -{ - if (!(_writesToMemory && memWriteTracingDisabled())) - { - std::string message = _pseudoInstruction + "("; - std::pair inputMemoryPtrModified = isInputMemoryPtrModified(_pseudoInstruction, _arguments); - for (size_t i = 0; i < _arguments.size(); ++i) - { - bool printZero = inputMemoryPtrModified.first && inputMemoryPtrModified.second == i; - u256 arg = printZero ? 0 : _arguments[i]; - message += (i > 0 ? ", " : "") + formatNumber(arg); - } - message += ")"; - if (!_data.empty()) - message += " [" + util::toHex(_data) + "]"; - m_state.trace.emplace_back(std::move(message)); - if (m_state.maxTraceSize > 0 && m_state.trace.size() >= m_state.maxTraceSize) - { - m_state.trace.emplace_back("Trace size limit reached."); - BOOST_THROW_EXCEPTION(TraceLimitReached()); - } - } -} - -std::pair EVMInstructionInterpreter::isInputMemoryPtrModified( - std::string const& _pseudoInstruction, - std::vector const& _arguments -) -{ - if (_pseudoInstruction == "RETURN" || _pseudoInstruction == "REVERT") - { - if (_arguments[1] == 0) - return {true, 0}; - else - return {false, 0}; - } - else if ( - _pseudoInstruction == "RETURNDATACOPY" || _pseudoInstruction == "CALLDATACOPY" - || _pseudoInstruction == "CODECOPY") - { - if (_arguments[2] == 0) - return {true, 0}; - else - return {false, 0}; - } - else if (_pseudoInstruction == "EXTCODECOPY") - { - if (_arguments[3] == 0) - return {true, 1}; - else - return {false, 0}; - } - else if ( - _pseudoInstruction == "LOG0" || _pseudoInstruction == "LOG1" || _pseudoInstruction == "LOG2" - || _pseudoInstruction == "LOG3" || _pseudoInstruction == "LOG4") - { - if (_arguments[1] == 0) - return {true, 0}; - else - return {false, 0}; - } - if (_pseudoInstruction == "CREATE" || _pseudoInstruction == "CREATE2") - { - if (_arguments[2] == 0) - return {true, 1}; - else - return {false, 0}; - } - if (_pseudoInstruction == "CALL" || _pseudoInstruction == "CALLCODE") - { - if (_arguments[4] == 0) - return {true, 3}; - else - return {false, 0}; - } - else if (_pseudoInstruction == "DELEGATECALL" || _pseudoInstruction == "STATICCALL") - { - if (_arguments[3] == 0) - return {true, 2}; - else - return {false, 0}; - } - else - return {false, 0}; -} - -h256 EVMInstructionInterpreter::blobHash(u256 const& _index) -{ - yulAssert(m_evmVersion.hasBlobHash()); - if (_index >= m_state.blobCommitments.size()) - return util::FixedHash<32>{}; - - h256 hashedCommitment = h256(picosha2::hash256(toBigEndian(m_state.blobCommitments[static_cast(_index)]))); - yulAssert(m_state.blobHashVersion.size == 1); - hashedCommitment[0] = *m_state.blobHashVersion.data(); - yulAssert(hashedCommitment.size == 32); - return hashedCommitment; -} diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.h b/libyul/tools/interpreter/EVMInstructionInterpreter.h index ea0bc965ac64..df5bac92a121 100644 --- a/libyul/tools/interpreter/EVMInstructionInterpreter.h +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.h @@ -72,34 +72,19 @@ void copyZeroExtendedWithOverlap( struct InterpreterState; /** - * Interprets EVM instructions 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 - * on a single contract only, does not do any gas counting and differs from the correct - * implementation in many ways: - * - * - If memory access to a "large" memory position is performed, a deterministic - * value is returned. Data that is stored in a "large" memory position is not - * retained. - * - The blockhash instruction returns a fixed value if the argument is in range. - * - Extcodesize returns a deterministic value depending on the address. - * - Extcodecopy copies a deterministic value depending on the address. - * - And many other things - * - * The main focus is that the generated execution trace is the same for equivalent executions - * and likely to be different for non-equivalent executions. + * Interprets EVM instructions based on the current state without side-effect. */ class EVMInstructionInterpreter { public: - explicit EVMInstructionInterpreter(langutil::EVMVersion _evmVersion, InterpreterState& _state, bool _disableMemWriteTrace): + explicit EVMInstructionInterpreter(langutil::EVMVersion _evmVersion, InterpreterState& _state): m_evmVersion(_evmVersion), - m_state(_state), - m_disableMemoryWriteInstructions(_disableMemWriteTrace) + m_state(_state) {} + /// Evaluate instruction u256 eval(evmasm::Instruction _instruction, std::vector const& _arguments); + /// Evaluate builtin function u256 evalBuiltin( BuiltinFunctionForEVM const& _fun, @@ -107,70 +92,11 @@ class EVMInstructionInterpreter std::vector const& _evaluatedArguments ); - /// @returns the blob versioned hash - util::h256 blobHash(u256 const& _index); - private: - /// Checks if the memory access is valid and adjusts msize accordingly. - /// @returns true if memory access is valid, false otherwise - /// A valid memory access must satisfy all of the following pre-requisites: - /// - Sum of @param _offset and @param _size do not overflow modulo u256 - /// - Sum of @param _offset, @param _size, and 31 do not overflow modulo u256 (see note below) - /// - @param _size is lesser than or equal to @a s_maxRangeSize - /// - @param _offset is lesser than or equal to the difference of numeric_limits::max() - /// and @a s_maxRangeSize - /// Note: Memory expansion is carried out in multiples of 32 bytes. - bool accessMemory(u256 const& _offset, u256 const& _size = 32); - /// @returns the memory contents at the provided address. - /// Does not adjust msize, use @a accessMemory for that - bytes readMemory(u256 const& _offset, u256 const& _size = 32); - /// @returns the memory contents at the provided address. - /// Does not adjust msize, use @a accessMemory for that - u256 readMemoryWord(u256 const& _offset); - /// @returns writes a word to memory - /// Does not adjust msize, use @a accessMemory for that - void writeMemoryWord(u256 const& _offset, u256 const& _value); - - void logTrace( - evmasm::Instruction _instruction, - std::vector const& _arguments = {}, - bytes const& _data = {} - ); - /// Appends a log to the trace representing an instruction or similar operation by string, - /// with arguments and auxiliary data (if nonempty). Flag @param _writesToMemory indicates - /// whether the instruction writes to (true) or does not write to (false) memory. - void logTrace( - std::string const& _pseudoInstruction, - bool _writesToMemory, - std::vector const& _arguments = {}, - bytes const& _data = {} - ); - - /// @returns a pair of boolean and size_t whose first value is true if @param _pseudoInstruction - /// is a Yul instruction that the Yul optimizer's loadResolver step rewrites the input - /// memory pointer value to zero if that instruction's read length (contained within @param - // _arguments) is zero, and whose second value is the positional index of the input memory - // pointer argument. - /// If the Yul instruction is unaffected or affected but read length is non-zero, the first - /// value is false. - std::pair isInputMemoryPtrModified( - std::string const& _pseudoInstruction, - std::vector const& _arguments - ); - - /// @returns disable trace flag. - bool memWriteTracingDisabled() - { - return m_disableMemoryWriteInstructions; - } langutil::EVMVersion m_evmVersion; InterpreterState& m_state; - /// Flag to disable trace of instructions that write to memory. - bool m_disableMemoryWriteInstructions; public: - /// Maximum length for range-based memory access operations. - static constexpr unsigned s_maxRangeSize = 0xffff; }; } // solidity::yul::test diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index 9129948649e2..e3d73a8ab4ac 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -251,7 +251,7 @@ EvaluationResult Interpreter::operator()(FunctionCall const& _funCall) { if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) { - EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state, false); + EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state); u256 const value = interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); From 2563fb340ccd6541dc7acf16eb2d2e3d3f763527 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 23:41:13 +0700 Subject: [PATCH 019/101] Declare ImpureBuiltinEncountered and EVMInstructionInterpretedResult --- libyul/tools/interpreter/EVMInstructionInterpreter.h | 8 +++++--- libyul/tools/interpreter/Interpreter.h | 7 ++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.h b/libyul/tools/interpreter/EVMInstructionInterpreter.h index df5bac92a121..1c15fc6292e5 100644 --- a/libyul/tools/interpreter/EVMInstructionInterpreter.h +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.h @@ -23,6 +23,8 @@ #include +#include + #include #include #include @@ -69,7 +71,7 @@ void copyZeroExtendedWithOverlap( size_t _size ); -struct InterpreterState; +using EVMInstructionInterpretedResult = std::variant; /** * Interprets EVM instructions based on the current state without side-effect. @@ -83,10 +85,10 @@ class EVMInstructionInterpreter {} /// Evaluate instruction - u256 eval(evmasm::Instruction _instruction, std::vector const& _arguments); + EVMInstructionInterpretedResult eval(evmasm::Instruction _instruction, std::vector const& _arguments); /// Evaluate builtin function - u256 evalBuiltin( + EVMInstructionInterpretedResult evalBuiltin( BuiltinFunctionForEVM const& _fun, std::vector const& _arguments, std::vector const& _evaluatedArguments diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index 3a56cc07e492..490405bc7d9e 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -74,13 +74,18 @@ class ExpressionNestingLimitReached : public ExecutionTerminatedCommon +{ +}; + using ExecutionTerminated = std::variant< ExplicitlyTerminated, ExplicitlyTerminatedWithReturn, StepLimitReached, TraceLimitReached, RecursionDepthLimitReached, - ExpressionNestingLimitReached + ExpressionNestingLimitReached, + ImpureBuiltinEncountered >; enum class ControlFlowState From f48f2ef2a08ea9ce9103f0829c017c197873beb8 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 23:58:20 +0700 Subject: [PATCH 020/101] Return ImpureBuiltinEncountered for all builtin with side-effect --- .../interpreter/EVMInstructionInterpreter.cpp | 224 ++---------------- 1 file changed, 24 insertions(+), 200 deletions(-) diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.cpp b/libyul/tools/interpreter/EVMInstructionInterpreter.cpp index 087ca5efeebe..44688918b6a3 100644 --- a/libyul/tools/interpreter/EVMInstructionInterpreter.cpp +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.cpp @@ -108,7 +108,7 @@ void copyZeroExtendedWithOverlap( using u512 = boost::multiprecision::number>; -u256 EVMInstructionInterpreter::eval( +EVMInstructionInterpretedResult EVMInstructionInterpreter::eval( evmasm::Instruction _instruction, std::vector const& _arguments ) @@ -123,8 +123,7 @@ u256 EVMInstructionInterpreter::eval( switch (_instruction) { case Instruction::STOP: - logTrace(_instruction); - BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); + return ExplicitlyTerminated(); // --------------- arithmetic --------------- case Instruction::ADD: return arg[0] + arg[1]; @@ -202,220 +201,65 @@ u256 EVMInstructionInterpreter::eval( } // --------------- blockchain stuff --------------- case Instruction::KECCAK256: - { - 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)); - return u256(keccak256(m_state.readMemory(offset, size))); - } case Instruction::ADDRESS: - return h256(m_state.address, h256::AlignRight); case Instruction::BALANCE: - if (arg[0] == h256(m_state.address, h256::AlignRight)) - return m_state.selfbalance; - else - return m_state.balance; case Instruction::SELFBALANCE: - return m_state.selfbalance; case Instruction::ORIGIN: - return h256(m_state.origin, h256::AlignRight); case Instruction::CALLER: - return h256(m_state.caller, h256::AlignRight); case Instruction::CALLVALUE: - return m_state.callvalue; case Instruction::CALLDATALOAD: - return readZeroExtended(m_state.calldata, arg[0]); case Instruction::CALLDATASIZE: - return m_state.calldata.size(); case Instruction::CALLDATACOPY: - 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]) - ); - logTrace(_instruction, arg); - return 0; case Instruction::CODESIZE: - return m_state.code.size(); case Instruction::CODECOPY: - 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]) - ); - logTrace(_instruction, arg); - return 0; case Instruction::GASPRICE: - return m_state.gasprice; case Instruction::CHAINID: - return m_state.chainid; case Instruction::BASEFEE: - return m_state.basefee; case Instruction::BLOBHASH: - return blobHash(arg[0]); case Instruction::BLOBBASEFEE: - return m_state.blobbasefee; case Instruction::EXTCODESIZE: - return u256(keccak256(h256(arg[0]))) & 0xffffff; case Instruction::EXTCODEHASH: - return u256(keccak256(h256(arg[0] + 1))); case Instruction::EXTCODECOPY: - if (accessMemory(arg[1], arg[3])) - // TODO this way extcodecopy and codecopy do the same thing. - copyZeroExtended( - m_state.memory, m_state.code, - size_t(arg[1]), size_t(arg[2]), size_t(arg[3]) - ); - logTrace(_instruction, arg); - return 0; case Instruction::RETURNDATASIZE: - return m_state.returndata.size(); case Instruction::RETURNDATACOPY: - 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]) - ); - logTrace(_instruction, arg); - return 0; case Instruction::MCOPY: - if (accessMemory(arg[1], arg[2]) && accessMemory(arg[0], arg[2])) - copyZeroExtendedWithOverlap( - m_state.memory, - m_state.memory, - static_cast(arg[0]), - static_cast(arg[1]), - static_cast(arg[2]) - ); - logTrace(_instruction, arg); - return 0; case Instruction::BLOCKHASH: - if (arg[0] >= m_state.blockNumber || arg[0] + 256 < m_state.blockNumber) - return 0; - else - return 0xaaaaaaaa + (arg[0] - m_state.blockNumber - 256); case Instruction::COINBASE: - return h256(m_state.coinbase, h256::AlignRight); case Instruction::TIMESTAMP: - return m_state.timestamp; case Instruction::NUMBER: - return m_state.blockNumber; case Instruction::PREVRANDAO: - return (m_evmVersion < langutil::EVMVersion::paris()) ? m_state.difficulty : m_state.prevrandao; case Instruction::GASLIMIT: - return m_state.gaslimit; + return ImpureBuiltinEncountered(); // --------------- memory / storage / logs --------------- case Instruction::MLOAD: - accessMemory(arg[0], 0x20); - return readMemoryWord(arg[0]); case Instruction::MSTORE: - accessMemory(arg[0], 0x20); - writeMemoryWord(arg[0], arg[1]); - return 0; case Instruction::MSTORE8: - accessMemory(arg[0], 1); - m_state.memory[arg[0]] = uint8_t(arg[1] & 0xff); - return 0; case Instruction::SLOAD: - return m_state.storage[h256(arg[0])]; case Instruction::SSTORE: - m_state.storage[h256(arg[0])] = h256(arg[1]); - return 0; case Instruction::PC: - return 0x77; case Instruction::MSIZE: - return m_state.msize; case Instruction::GAS: - return 0x99; case Instruction::LOG0: - accessMemory(arg[0], arg[1]); - logTrace(_instruction, arg); - return 0; case Instruction::LOG1: - accessMemory(arg[0], arg[1]); - logTrace(_instruction, arg); - return 0; case Instruction::LOG2: - accessMemory(arg[0], arg[1]); - logTrace(_instruction, arg); - return 0; case Instruction::LOG3: - accessMemory(arg[0], arg[1]); - logTrace(_instruction, arg); - return 0; case Instruction::LOG4: - accessMemory(arg[0], arg[1]); - logTrace(_instruction, arg); - return 0; case Instruction::TLOAD: - return m_state.transientStorage[h256(arg[0])]; case Instruction::TSTORE: - m_state.transientStorage[h256(arg[0])] = h256(arg[1]); - return 0; + return ImpureBuiltinEncountered(); // --------------- calls --------------- case Instruction::CREATE: - accessMemory(arg[1], arg[2]); - logTrace(_instruction, arg); - if (arg[2] != 0) - return (0xcccccc + arg[1]) & u256("0xffffffffffffffffffffffffffffffffffffffff"); - else - return 0xcccccc; case Instruction::CREATE2: - accessMemory(arg[1], arg[2]); - logTrace(_instruction, arg); - if (arg[2] != 0) - return (0xdddddd + arg[1]) & u256("0xffffffffffffffffffffffffffffffffffffffff"); - else - return 0xdddddd; case Instruction::CALL: case Instruction::CALLCODE: - accessMemory(arg[3], arg[4]); - accessMemory(arg[5], arg[6]); - logTrace(_instruction, arg); - // Randomly fail based on the called address if it isn't a call to self. - // Used for fuzzing. - return ( - (arg[0] > 0) && - (arg[1] == util::h160::Arith(m_state.address) || (arg[1] & 1)) - ) ? 1 : 0; case Instruction::DELEGATECALL: case Instruction::STATICCALL: - accessMemory(arg[2], arg[3]); - accessMemory(arg[4], arg[5]); - logTrace(_instruction, arg); - // Randomly fail based on the called address if it isn't a call to self. - // Used for fuzzing. - return ( - (arg[0] > 0) && - (arg[1] == util::h160::Arith(m_state.address) || (arg[1] & 1)) - ) ? 1 : 0; case Instruction::RETURN: - { - m_state.returndata = {}; - if (accessMemory(arg[0], arg[1])) - m_state.returndata = m_state.readMemory(arg[0], arg[1]); - logTrace(_instruction, arg, m_state.returndata); - BOOST_THROW_EXCEPTION(ExplicitlyTerminatedWithReturn()); - } case Instruction::REVERT: - accessMemory(arg[0], arg[1]); - logTrace(_instruction, arg); - m_state.storage.clear(); - m_state.transientStorage.clear(); - BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); case Instruction::INVALID: - logTrace(_instruction); - m_state.storage.clear(); - m_state.transientStorage.clear(); - m_state.trace.clear(); - BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); case Instruction::SELFDESTRUCT: - logTrace(_instruction, arg); - m_state.storage.clear(); - m_state.transientStorage.clear(); - m_state.trace.clear(); - BOOST_THROW_EXCEPTION(ExplicitlyTerminated()); + return ImpureBuiltinEncountered(); + case Instruction::POP: break; // --------------- invalid in strict assembly --------------- @@ -493,12 +337,14 @@ u256 EVMInstructionInterpreter::eval( } } + yulAssert(false, "Unknown instruction with opcode " + std::to_string(static_cast(_instruction))); return 0; } -u256 EVMInstructionInterpreter::evalBuiltin( +EVMInstructionInterpretedResult EVMInstructionInterpreter::evalBuiltin( BuiltinFunctionForEVM const& _fun, - std::vector const& _arguments, + std::vector const& /* _arguments */, // This was required to execute some builtin. + // But all of them are impure. std::vector const& _evaluatedArguments ) { @@ -506,42 +352,20 @@ u256 EVMInstructionInterpreter::evalBuiltin( return eval(*_fun.instruction, _evaluatedArguments); std::string fun = _fun.name.str(); - // Evaluate datasize/offset/copy instructions - if (fun == "datasize" || fun == "dataoffset") - { - std::string arg = formatLiteral(std::get(_arguments.at(0))); - if (arg.length() < 32) - arg.resize(32, 0); - if (fun == "datasize") - return u256(keccak256(arg)) & 0xfff; - else - { - // Force different value than for datasize - arg[31]++; - arg[31]++; - return u256(keccak256(arg)) & 0xfff; - } - } - else if (fun == "datacopy") - { - // This is identical to codecopy. - if ( - _evaluatedArguments.at(2) != 0 && - accessMemory(_evaluatedArguments.at(0), _evaluatedArguments.at(2)) - ) - copyZeroExtended( - m_state.memory, - m_state.code, - size_t(_evaluatedArguments.at(0)), - size_t(_evaluatedArguments.at(1) & std::numeric_limits::max()), - size_t(_evaluatedArguments.at(2)) - ); - return 0; - } - else if (fun == "memoryguard") - return _evaluatedArguments.at(0); - else - yulAssert(false, "Unknown builtin: " + fun); + + static std::set const NON_INSTRUCTION_BUILTIN_NAME = { + "datasize", + "dataoffset", + "datacopy", + "memoryguard", + "loadimmutable", + "setimmutable", + "linkersymbol" + }; + if (NON_INSTRUCTION_BUILTIN_NAME.count(fun)) + return ImpureBuiltinEncountered(); + + yulAssert(false, "Unknown builtin: " + fun); return 0; } From e996ec434dcb4ca974b4edf821587608c51ccd3a Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 24 Sep 2024 23:58:54 +0700 Subject: [PATCH 021/101] Use EVMInstructionInterpretedResult in Interpreter --- libyul/tools/interpreter/Interpreter.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index e3d73a8ab4ac..e76e27f71489 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -252,10 +252,9 @@ EvaluationResult Interpreter::operator()(FunctionCall const& _funCall) if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) { EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state); - - u256 const value = interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); - - return EvaluationOk(value); + EVMInstructionInterpretedResult const value = interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); + if (auto* terminated = std::get_if(&value)) return *terminated; + return EvaluationOk(std::get(value)); } } From 749e8508a0feda863112070bf46b2f98ac389568 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 25 Sep 2024 00:13:22 +0700 Subject: [PATCH 022/101] Bring back empty body and post check when visiting ForLoop --- libyul/tools/interpreter/Interpreter.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/Interpreter.cpp index e76e27f71489..6bf799f61806 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/Interpreter.cpp @@ -160,8 +160,13 @@ ExecutionResult Interpreter::operator()(ForLoop const& _forLoop) if (std::get(conditionRes).values.at(0) == 0) break; } + // Increment step for each loop iteration for loops with + // an empty body and post blocks to prevent a deadlock. + if (_forLoop.body.statements.size() == 0 && _forLoop.post.statements.size() == 0) + if (auto terminated = incrementStatementStep()) return *terminated; + { - ExecutionResult bodyRes = visit(_forLoop.body); + ExecutionResult bodyRes = (*this)(_forLoop.body); if ( std::holds_alternative(bodyRes) || bodyRes == ExecutionResult(ExecutionOk{ ControlFlowState::Leave }) @@ -172,7 +177,7 @@ ExecutionResult Interpreter::operator()(ForLoop const& _forLoop) } { - ExecutionResult postRes = visit(_forLoop.post); + ExecutionResult postRes = (*this)(_forLoop.post); if ( std::holds_alternative(postRes) || postRes == ExecutionResult(ExecutionOk{ ControlFlowState::Leave }) From d3d86ba457ed3267daa441edf864ef97345ccd93 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 25 Sep 2024 00:15:17 +0700 Subject: [PATCH 023/101] Remove unused function in EVMInstructionInterpreter --- .../interpreter/EVMInstructionInterpreter.cpp | 64 ------------------- .../interpreter/EVMInstructionInterpreter.h | 24 ------- 2 files changed, 88 deletions(-) diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.cpp b/libyul/tools/interpreter/EVMInstructionInterpreter.cpp index 44688918b6a3..0d883e8ddb89 100644 --- a/libyul/tools/interpreter/EVMInstructionInterpreter.cpp +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.cpp @@ -34,8 +34,6 @@ #include #include -#include - using namespace solidity; using namespace solidity::evmasm; using namespace solidity::yul; @@ -43,68 +41,6 @@ using namespace solidity::yul::tools::interpreter; using solidity::util::h160; using solidity::util::h256; -using solidity::util::keccak256; - -namespace -{ - -/// Reads 32 bytes from @a _data at position @a _offset bytes while -/// interpreting @a _data to be padded with an infinite number of zero -/// bytes beyond its end. -u256 readZeroExtended(bytes const& _data, u256 const& _offset) -{ - if (_offset >= _data.size()) - return 0; - else if (_offset + 32 <= _data.size()) - return *reinterpret_cast(_data.data() + static_cast(_offset)); - else - { - size_t off = static_cast(_offset); - u256 val; - for (size_t i = 0; i < 32; ++i) - { - val <<= 8; - if (off + i < _data.size()) - val += _data[off + i]; - } - return val; - } -} - -} - -namespace solidity::yul::tools::interpreter -{ - -void copyZeroExtended( - std::map& _target, - bytes const& _source, - size_t _targetOffset, - size_t _sourceOffset, - size_t _size -) -{ - for (size_t i = 0; i < _size; ++i) - _target[_targetOffset + i] = (_sourceOffset + i < _source.size() ? _source[_sourceOffset + i] : 0); -} - -void copyZeroExtendedWithOverlap( - std::map& _target, - std::map const& _source, - size_t _targetOffset, - size_t _sourceOffset, - size_t _size -) -{ - if (_targetOffset >= _sourceOffset) - for (size_t i = _size; i > 0; --i) - _target[_targetOffset + i - 1] = (_source.count(_sourceOffset + i - 1) != 0 ? _source.at(_sourceOffset + i - 1) : 0); - else - for (size_t i = 0; i < _size; ++i) - _target[_targetOffset + i] = (_source.count(_sourceOffset + i) != 0 ? _source.at(_sourceOffset + i) : 0); -} - -} using u512 = boost::multiprecision::number>; diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.h b/libyul/tools/interpreter/EVMInstructionInterpreter.h index 1c15fc6292e5..08209637c311 100644 --- a/libyul/tools/interpreter/EVMInstructionInterpreter.h +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.h @@ -47,30 +47,6 @@ struct BuiltinFunctionForEVM; namespace solidity::yul::tools::interpreter { -/// Copy @a _size bytes of @a _source at offset @a _sourceOffset to -/// @a _target at offset @a _targetOffset. Behaves as if @a _source would -/// continue with an infinite sequence of zero bytes beyond its end. -void copyZeroExtended( - std::map& _target, - bytes const& _source, - size_t _targetOffset, - size_t _sourceOffset, - size_t _size -); - -/// Copy @a _size bytes of @a _source at offset @a _sourceOffset to -/// @a _target at offset @a _targetOffset. Behaves as if @a _source would -/// continue with an infinite sequence of zero bytes beyond its end. -/// When target and source areas overlap, behaves as if the data was copied -/// using an intermediate buffer. -void copyZeroExtendedWithOverlap( - std::map& _target, - std::map const& _source, - size_t _targetOffset, - size_t _sourceOffset, - size_t _size -); - using EVMInstructionInterpretedResult = std::variant; /** From 63a6d6d30da4445ac6238c02f0231b555cbc22cd Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 25 Sep 2024 00:21:33 +0700 Subject: [PATCH 024/101] Move result types into a separate file --- .../interpreter/EVMInstructionInterpreter.h | 2 +- libyul/tools/interpreter/Interpreter.h | 89 +------------- libyul/tools/interpreter/Results.h | 115 ++++++++++++++++++ 3 files changed, 118 insertions(+), 88 deletions(-) create mode 100644 libyul/tools/interpreter/Results.h diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.h b/libyul/tools/interpreter/EVMInstructionInterpreter.h index 08209637c311..78d261a4b849 100644 --- a/libyul/tools/interpreter/EVMInstructionInterpreter.h +++ b/libyul/tools/interpreter/EVMInstructionInterpreter.h @@ -23,7 +23,7 @@ #include -#include +#include #include #include diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/Interpreter.h index 490405bc7d9e..ee11d8fe49f3 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/Interpreter.h @@ -21,6 +21,8 @@ #pragma once +#include + #include #include #include @@ -42,93 +44,6 @@ struct Dialect; namespace solidity::yul::tools::interpreter { -template -class ExecutionTerminatedCommon -{ -public: - bool operator==(T) const { return true; } - bool operator!=(T) const { return false; } -}; - -class ExplicitlyTerminated : public ExecutionTerminatedCommon -{ -}; - -class ExplicitlyTerminatedWithReturn : public ExecutionTerminatedCommon -{ -}; - -class StepLimitReached : public ExecutionTerminatedCommon -{ -}; - -class TraceLimitReached : public ExecutionTerminatedCommon -{ -}; - -class RecursionDepthLimitReached : public ExecutionTerminatedCommon -{ -}; - -class ExpressionNestingLimitReached : public ExecutionTerminatedCommon -{ -}; - -class ImpureBuiltinEncountered : public ExecutionTerminatedCommon -{ -}; - -using ExecutionTerminated = std::variant< - ExplicitlyTerminated, - ExplicitlyTerminatedWithReturn, - StepLimitReached, - TraceLimitReached, - RecursionDepthLimitReached, - ExpressionNestingLimitReached, - ImpureBuiltinEncountered ->; - -enum class ControlFlowState -{ - Default, - Continue, - Break, - Leave -}; - -struct ExecutionOk -{ - ControlFlowState state; - - bool operator==(ExecutionOk other) const - { - return state == other.state; - } - - bool operator!=(ExecutionOk other) const - { - return state != other.state; - } -}; - -struct EvaluationOk -{ - std::vector values; - - EvaluationOk(u256 _x): - values{_x} - { - } - - EvaluationOk(std::vector const& _values): - values(_values) - { - } -}; - -using ExecutionResult = std::variant; -using EvaluationResult = std::variant; - struct InterpreterConfig { size_t maxTraceSize = 0; diff --git a/libyul/tools/interpreter/Results.h b/libyul/tools/interpreter/Results.h new file mode 100644 index 000000000000..9e2151f16c27 --- /dev/null +++ b/libyul/tools/interpreter/Results.h @@ -0,0 +1,115 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +// +#pragma once + +#include + +#include + +namespace solidity::yul::tools::interpreter +{ + +template +class ExecutionTerminatedCommon +{ +public: + bool operator==(T) const { return true; } + bool operator!=(T) const { return false; } +}; + +class ExplicitlyTerminated : public ExecutionTerminatedCommon +{ +}; + +class ExplicitlyTerminatedWithReturn : public ExecutionTerminatedCommon +{ +}; + +class StepLimitReached : public ExecutionTerminatedCommon +{ +}; + +class TraceLimitReached : public ExecutionTerminatedCommon +{ +}; + +class RecursionDepthLimitReached : public ExecutionTerminatedCommon +{ +}; + +class ExpressionNestingLimitReached : public ExecutionTerminatedCommon +{ +}; + +class ImpureBuiltinEncountered : public ExecutionTerminatedCommon +{ +}; + +using ExecutionTerminated = std::variant< + ExplicitlyTerminated, + ExplicitlyTerminatedWithReturn, + StepLimitReached, + TraceLimitReached, + RecursionDepthLimitReached, + ExpressionNestingLimitReached, + ImpureBuiltinEncountered +>; + +enum class ControlFlowState +{ + Default, + Continue, + Break, + Leave +}; + +struct ExecutionOk +{ + ControlFlowState state; + + bool operator==(ExecutionOk other) const + { + return state == other.state; + } + + bool operator!=(ExecutionOk other) const + { + return state != other.state; + } +}; + +struct EvaluationOk +{ + std::vector values; + + EvaluationOk(u256 _x): + values{_x} + { + } + + EvaluationOk(std::vector const& _values): + values(_values) + { + } +}; + +using ExecutionResult = std::variant; +using EvaluationResult = std::variant; + +} From 2d89cc3da4390b8ebd299bbe331f6895eb35cde8 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 15:29:46 +0700 Subject: [PATCH 025/101] Add Pure* prefix --- libyul/CMakeLists.txt | 8 +-- ....cpp => PureEVMInstructionInterpreter.cpp} | 8 +-- ...eter.h => PureEVMInstructionInterpreter.h} | 7 ++- .../{Interpreter.cpp => PureInterpreter.cpp} | 63 ++++++++++--------- .../{Interpreter.h => PureInterpreter.h} | 20 +++--- 5 files changed, 54 insertions(+), 52 deletions(-) rename libyul/tools/interpreter/{EVMInstructionInterpreter.cpp => PureEVMInstructionInterpreter.cpp} (96%) rename libyul/tools/interpreter/{EVMInstructionInterpreter.h => PureEVMInstructionInterpreter.h} (89%) rename libyul/tools/interpreter/{Interpreter.cpp => PureInterpreter.cpp} (83%) rename libyul/tools/interpreter/{Interpreter.h => PureInterpreter.h} (91%) diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 53a202c17e8a..c7f998fc8bed 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -202,10 +202,10 @@ add_library(yul optimiser/VarDeclInitializer.h optimiser/VarNameCleaner.cpp optimiser/VarNameCleaner.h - tools/interpreter/Interpreter.cpp - tools/interpreter/Interpreter.h - tools/interpreter/EVMInstructionInterpreter.cpp - tools/interpreter/EVMInstructionInterpreter.h + tools/interpreter/PureInterpreter.cpp + tools/interpreter/PureInterpreter.h + tools/interpreter/PureEVMInstructionInterpreter.cpp + tools/interpreter/PureEVMInstructionInterpreter.h ) target_link_libraries(yul PUBLIC evmasm solutil langutil smtutil fmt::fmt-header-only) diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.cpp b/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp similarity index 96% rename from libyul/tools/interpreter/EVMInstructionInterpreter.cpp rename to libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp index 0d883e8ddb89..398872ddaaaa 100644 --- a/libyul/tools/interpreter/EVMInstructionInterpreter.cpp +++ b/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp @@ -19,9 +19,9 @@ * Yul interpreter module that evaluates EVM instructions. */ -#include +#include -#include +#include #include #include @@ -44,7 +44,7 @@ using solidity::util::h256; using u512 = boost::multiprecision::number>; -EVMInstructionInterpretedResult EVMInstructionInterpreter::eval( +EVMInstructionInterpretedResult PureEVMInstructionInterpreter::eval( evmasm::Instruction _instruction, std::vector const& _arguments ) @@ -277,7 +277,7 @@ EVMInstructionInterpretedResult EVMInstructionInterpreter::eval( return 0; } -EVMInstructionInterpretedResult EVMInstructionInterpreter::evalBuiltin( +EVMInstructionInterpretedResult PureEVMInstructionInterpreter::evalBuiltin( BuiltinFunctionForEVM const& _fun, std::vector const& /* _arguments */, // This was required to execute some builtin. // But all of them are impure. diff --git a/libyul/tools/interpreter/EVMInstructionInterpreter.h b/libyul/tools/interpreter/PureEVMInstructionInterpreter.h similarity index 89% rename from libyul/tools/interpreter/EVMInstructionInterpreter.h rename to libyul/tools/interpreter/PureEVMInstructionInterpreter.h index 78d261a4b849..d8c116ca1bc4 100644 --- a/libyul/tools/interpreter/EVMInstructionInterpreter.h +++ b/libyul/tools/interpreter/PureEVMInstructionInterpreter.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -52,10 +53,10 @@ using EVMInstructionInterpretedResult = std::variant; /** * Interprets EVM instructions based on the current state without side-effect. */ -class EVMInstructionInterpreter +class PureEVMInstructionInterpreter { public: - explicit EVMInstructionInterpreter(langutil::EVMVersion _evmVersion, InterpreterState& _state): + explicit PureEVMInstructionInterpreter(langutil::EVMVersion _evmVersion, PureInterpreterState& _state): m_evmVersion(_evmVersion), m_state(_state) {} @@ -73,7 +74,7 @@ class EVMInstructionInterpreter private: langutil::EVMVersion m_evmVersion; - InterpreterState& m_state; + PureInterpreterState& m_state; public: }; diff --git a/libyul/tools/interpreter/Interpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp similarity index 83% rename from libyul/tools/interpreter/Interpreter.cpp rename to libyul/tools/interpreter/PureInterpreter.cpp index 6bf799f61806..e343791474d0 100644 --- a/libyul/tools/interpreter/Interpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -19,9 +19,9 @@ * Yul interpreter. */ -#include +#include -#include +#include #include #include @@ -44,24 +44,24 @@ using namespace solidity::yul::tools::interpreter; using solidity::util::h256; -void Interpreter::run( - InterpreterState& _state, +void PureInterpreter::run( + PureInterpreterState& _state, Dialect const& _dialect, Block const& _ast ) { Scope scope; - Interpreter{_state, _dialect, scope, 0}(_ast); + PureInterpreter{_state, _dialect, scope, 0}(_ast); } -ExecutionResult Interpreter::operator()(ExpressionStatement const& _expressionStatement) +ExecutionResult PureInterpreter::operator()(ExpressionStatement const& _expressionStatement) { EvaluationResult res = evaluate(_expressionStatement.expression, 0); if (auto* terminated = std::get_if(&res)) return *terminated; return ExecutionOk{ ControlFlowState::Default }; } -ExecutionResult Interpreter::operator()(Assignment const& _assignment) +ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) { solAssert(_assignment.value, ""); EvaluationResult evalRes = evaluate(*_assignment.value, _assignment.variableNames.size()); @@ -77,7 +77,7 @@ ExecutionResult Interpreter::operator()(Assignment const& _assignment) return ExecutionOk { ControlFlowState::Default }; } -ExecutionResult Interpreter::operator()(VariableDeclaration const& _declaration) +ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declaration) { std::vector values(_declaration.variables.size(), 0); if (_declaration.value) @@ -98,7 +98,7 @@ ExecutionResult Interpreter::operator()(VariableDeclaration const& _declaration) return ExecutionOk { ControlFlowState::Default }; } -ExecutionResult Interpreter::operator()(If const& _if) +ExecutionResult PureInterpreter::operator()(If const& _if) { solAssert(_if.condition, ""); EvaluationResult conditionRes = evaluate(*_if.condition, 1); @@ -109,7 +109,7 @@ ExecutionResult Interpreter::operator()(If const& _if) return ExecutionOk { ControlFlowState::Default }; } -ExecutionResult Interpreter::operator()(Switch const& _switch) +ExecutionResult PureInterpreter::operator()(Switch const& _switch) { solAssert(_switch.expression, ""); solAssert(!_switch.cases.empty(), ""); @@ -134,12 +134,12 @@ ExecutionResult Interpreter::operator()(Switch const& _switch) return ExecutionOk { ControlFlowState::Default }; } -ExecutionResult Interpreter::operator()(FunctionDefinition const&) +ExecutionResult PureInterpreter::operator()(FunctionDefinition const&) { return ExecutionOk{ ControlFlowState::Default }; } -ExecutionResult Interpreter::operator()(ForLoop const& _forLoop) +ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) { solAssert(_forLoop.condition, ""); @@ -157,7 +157,8 @@ ExecutionResult Interpreter::operator()(ForLoop const& _forLoop) { EvaluationResult conditionRes = evaluate(*_forLoop.condition, 1); if (auto* terminated = std::get_if(&conditionRes)) return *terminated; - if (std::get(conditionRes).values.at(0) == 0) break; + if (std::get(conditionRes).values.at(0) == 0) + break; } // Increment step for each loop iteration for loops with @@ -187,22 +188,22 @@ ExecutionResult Interpreter::operator()(ForLoop const& _forLoop) return ExecutionOk { ControlFlowState::Default }; } -ExecutionResult Interpreter::operator()(Break const&) +ExecutionResult PureInterpreter::operator()(Break const&) { return ExecutionOk{ ControlFlowState::Break }; } -ExecutionResult Interpreter::operator()(Continue const&) +ExecutionResult PureInterpreter::operator()(Continue const&) { return ExecutionOk{ ControlFlowState::Continue }; } -ExecutionResult Interpreter::operator()(Leave const&) +ExecutionResult PureInterpreter::operator()(Leave const&) { return ExecutionOk{ ControlFlowState::Leave }; } -ExecutionResult Interpreter::operator()(Block const& _block) +ExecutionResult PureInterpreter::operator()(Block const& _block) { enterScope(_block); ScopeGuard guard([this] { leaveScope(); }); @@ -218,30 +219,30 @@ ExecutionResult Interpreter::operator()(Block const& _block) for (auto const& statement: _block.statements) { ExecutionResult statementRes = visit(statement); - if (statementRes != ExecutionResult(ExecutionOk{ ControlFlowState::Default })) + if (statementRes != ExecutionResult(ExecutionOk {ControlFlowState::Default})) return statementRes; } return ExecutionOk{ ControlFlowState::Default }; } -ExecutionResult Interpreter::visit(Statement const& _st) +ExecutionResult PureInterpreter::visit(Statement const& _st) { if (auto terminated = incrementStatementStep()) return *terminated; return std::visit(*this, _st); } -EvaluationResult Interpreter::operator()(Literal const& _literal) +EvaluationResult PureInterpreter::operator()(Literal const& _literal) { return EvaluationOk(_literal.value.value()); } -EvaluationResult Interpreter::operator()(Identifier const& _identifier) +EvaluationResult PureInterpreter::operator()(Identifier const& _identifier) { solAssert(m_variables.count(_identifier.name), ""); return EvaluationOk(m_variables.at(_identifier.name)); } -EvaluationResult Interpreter::operator()(FunctionCall const& _funCall) +EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) { std::vector> const* literalArguments = nullptr; if (BuiltinFunction const* builtin = m_dialect.builtin(_funCall.functionName.name)) @@ -256,7 +257,7 @@ EvaluationResult Interpreter::operator()(FunctionCall const& _funCall) { if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) { - EVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state); + PureEVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state); EVMInstructionInterpretedResult const value = interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); if (auto* terminated = std::get_if(&value)) return *terminated; return EvaluationOk(std::get(value)); @@ -278,7 +279,7 @@ EvaluationResult Interpreter::operator()(FunctionCall const& _funCall) for (size_t i = 0; i < fun->returnVariables.size(); ++i) variables[fun->returnVariables.at(i).name] = 0; - std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); + std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); ExecutionResult funcBodyRes = (*interpreter)(fun->body); if (auto* terminated = std::get_if(&funcBodyRes)) return *terminated; @@ -288,13 +289,13 @@ EvaluationResult Interpreter::operator()(FunctionCall const& _funCall) return EvaluationOk(returnedValues); } -EvaluationResult Interpreter::visit(Expression const& _st) +EvaluationResult PureInterpreter::visit(Expression const& _st) { if (auto terminated = incrementExpressionStep()) return *terminated; return std::visit(*this, _st); } -EvaluationResult Interpreter::evaluate(Expression const& _expression, size_t _numReturnVars) +EvaluationResult PureInterpreter::evaluate(Expression const& _expression, size_t _numReturnVars) { EvaluationResult res = visit(_expression); if (auto* resOk = std::get_if(&res)) @@ -303,7 +304,7 @@ EvaluationResult Interpreter::evaluate(Expression const& _expression, size_t _nu return res; } -EvaluationResult Interpreter::evaluateArgs( +EvaluationResult PureInterpreter::evaluateArgs( std::vector const& _expr, std::vector> const* _literalArguments ) @@ -338,7 +339,7 @@ EvaluationResult Interpreter::evaluateArgs( return EvaluationOk(values); } -void Interpreter::enterScope(Block const& _block) +void PureInterpreter::enterScope(Block const& _block) { if (!m_scope->subScopes.count(&_block)) m_scope->subScopes[&_block] = std::make_unique(Scope{ @@ -349,7 +350,7 @@ void Interpreter::enterScope(Block const& _block) m_scope = m_scope->subScopes[&_block].get(); } -void Interpreter::leaveScope() +void PureInterpreter::leaveScope() { for (auto const& [var, funDeclaration]: m_scope->names) if (!funDeclaration) @@ -358,7 +359,7 @@ void Interpreter::leaveScope() yulAssert(m_scope, ""); } -std::optional Interpreter::incrementStatementStep() +std::optional PureInterpreter::incrementStatementStep() { m_state.numSteps++; if (m_state.config.maxSteps > 0 && m_state.numSteps >= m_state.config.maxSteps) @@ -374,7 +375,7 @@ std::optional Interpreter::incrementStatementStep() return std::nullopt; } -std::optional Interpreter::incrementExpressionStep() +std::optional PureInterpreter::incrementExpressionStep() { m_expressionNestingLevel++; if (m_state.config.maxExprNesting > 0 && m_expressionNestingLevel > m_state.config.maxExprNesting) diff --git a/libyul/tools/interpreter/Interpreter.h b/libyul/tools/interpreter/PureInterpreter.h similarity index 91% rename from libyul/tools/interpreter/Interpreter.h rename to libyul/tools/interpreter/PureInterpreter.h index ee11d8fe49f3..0166c5bd3bdb 100644 --- a/libyul/tools/interpreter/Interpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -44,7 +44,7 @@ struct Dialect; namespace solidity::yul::tools::interpreter { -struct InterpreterConfig +struct PureInterpreterConfig { size_t maxTraceSize = 0; size_t maxSteps = 0; @@ -52,9 +52,9 @@ struct InterpreterConfig size_t maxRecursionDepth = 0; }; -struct InterpreterState +struct PureInterpreterState { - InterpreterConfig const config; + PureInterpreterConfig const config; size_t numSteps = 0; }; @@ -73,18 +73,18 @@ struct Scope /** * Yul interpreter. */ -class Interpreter +class PureInterpreter { public: /// Executes the Yul interpreter. static void run( - InterpreterState& _state, + PureInterpreterState& _state, Dialect const& _dialect, Block const& _ast ); - Interpreter( - InterpreterState& _state, + PureInterpreter( + PureInterpreterState& _state, Dialect const& _dialect, Scope& _scope, size_t _callerRecursionDepth, @@ -127,9 +127,9 @@ class Interpreter u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } protected: - virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const + virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const { - return std::make_unique( + return std::make_unique( m_state, m_dialect, *m_scope, @@ -161,7 +161,7 @@ class Interpreter std::optional incrementExpressionStep(); Dialect const& m_dialect; - InterpreterState& m_state; + PureInterpreterState& m_state; /// Values of variables. std::map m_variables; Scope* m_scope; From d1a2c377031fe32b09dac681304cc31f02be6b53 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 15:14:40 +0700 Subject: [PATCH 026/101] Move PureInterpreterState into a separate file --- .../PureEVMInstructionInterpreter.h | 2 +- libyul/tools/interpreter/PureInterpreter.h | 16 +------- .../tools/interpreter/PureInterpreterState.h | 41 +++++++++++++++++++ 3 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 libyul/tools/interpreter/PureInterpreterState.h diff --git a/libyul/tools/interpreter/PureEVMInstructionInterpreter.h b/libyul/tools/interpreter/PureEVMInstructionInterpreter.h index d8c116ca1bc4..03fe946669cf 100644 --- a/libyul/tools/interpreter/PureEVMInstructionInterpreter.h +++ b/libyul/tools/interpreter/PureEVMInstructionInterpreter.h @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/tools/interpreter/PureInterpreter.h index 0166c5bd3bdb..521de74655df 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -21,6 +21,7 @@ #pragma once +#include #include #include @@ -44,21 +45,6 @@ struct Dialect; namespace solidity::yul::tools::interpreter { -struct PureInterpreterConfig -{ - size_t maxTraceSize = 0; - size_t maxSteps = 0; - size_t maxExprNesting = 0; - size_t maxRecursionDepth = 0; -}; - -struct PureInterpreterState -{ - PureInterpreterConfig const config; - - size_t numSteps = 0; -}; - /** * Scope structure built and maintained during execution. */ diff --git a/libyul/tools/interpreter/PureInterpreterState.h b/libyul/tools/interpreter/PureInterpreterState.h new file mode 100644 index 000000000000..22132e69a6fa --- /dev/null +++ b/libyul/tools/interpreter/PureInterpreterState.h @@ -0,0 +1,41 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +namespace solidity::yul::tools::interpreter +{ + +struct PureInterpreterConfig +{ + size_t maxTraceSize = 0; + size_t maxSteps = 0; + size_t maxExprNesting = 0; + size_t maxRecursionDepth = 0; +}; + +struct PureInterpreterState +{ + PureInterpreterConfig const config; + + size_t numSteps = 0; +}; + +} From 0b4c0392015e6428be0ce2ffaed985d9ed2f9677 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 15:31:17 +0700 Subject: [PATCH 027/101] Add Results and PureInterpreterState into CMakeLists --- libyul/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index c7f998fc8bed..2a27ecd86c44 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -202,6 +202,8 @@ add_library(yul optimiser/VarDeclInitializer.h optimiser/VarNameCleaner.cpp optimiser/VarNameCleaner.h + tools/interpreter/Results.h + tools/interpreter/PureInterpreterState.h tools/interpreter/PureInterpreter.cpp tools/interpreter/PureInterpreter.h tools/interpreter/PureEVMInstructionInterpreter.cpp From 3b791fc20903906a02b8a624f8420a6d22ddf4d3 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 16:12:53 +0700 Subject: [PATCH 028/101] Separate function definition and variable declaration in Scope --- libyul/tools/interpreter/PureInterpreter.cpp | 31 ++++++++++---------- libyul/tools/interpreter/PureInterpreter.h | 4 +-- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index e343791474d0..4e7b77021554 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -93,7 +93,7 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat YulName varName = _declaration.variables.at(i).name; solAssert(!m_variables.count(varName), ""); m_variables[varName] = values.at(i); - m_scope->names.emplace(varName, nullptr); + m_scope->declaredVariables.emplace_back(varName); } return ExecutionOk { ControlFlowState::Default }; } @@ -213,7 +213,7 @@ ExecutionResult PureInterpreter::operator()(Block const& _block) if (std::holds_alternative(statement)) { FunctionDefinition const& funDef = std::get(statement); - m_scope->names.emplace(funDef.name, &funDef); + m_scope->definedFunctions.emplace(funDef.name, funDef); } for (auto const& statement: _block.statements) @@ -266,25 +266,24 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) Scope* scope = m_scope; for (; scope; scope = scope->parent) - if (scope->names.count(_funCall.functionName.name)) + if (scope->definedFunctions.count(_funCall.functionName.name)) break; yulAssert(scope, ""); - FunctionDefinition const* fun = scope->names.at(_funCall.functionName.name); - yulAssert(fun, "Function not found."); - yulAssert(argsValues.size() == fun->parameters.size(), ""); + FunctionDefinition const& fun = scope->definedFunctions.at(_funCall.functionName.name); + yulAssert(argsValues.size() == fun.parameters.size(), ""); std::map variables; - for (size_t i = 0; i < fun->parameters.size(); ++i) - variables[fun->parameters.at(i).name] = argsValues.at(i); - for (size_t i = 0; i < fun->returnVariables.size(); ++i) - variables[fun->returnVariables.at(i).name] = 0; + for (size_t i = 0; i < fun.parameters.size(); ++i) + variables[fun.parameters.at(i).name] = argsValues.at(i); + for (size_t i = 0; i < fun.returnVariables.size(); ++i) + variables[fun.returnVariables.at(i).name] = 0; std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); - ExecutionResult funcBodyRes = (*interpreter)(fun->body); + ExecutionResult funcBodyRes = (*interpreter)(fun.body); if (auto* terminated = std::get_if(&funcBodyRes)) return *terminated; std::vector returnedValues; - for (auto const& retVar: fun->returnVariables) + for (auto const& retVar: fun.returnVariables) returnedValues.emplace_back(interpreter->valueOfVariable(retVar.name)); return EvaluationOk(returnedValues); } @@ -343,6 +342,7 @@ void PureInterpreter::enterScope(Block const& _block) { if (!m_scope->subScopes.count(&_block)) m_scope->subScopes[&_block] = std::make_unique(Scope{ + {}, {}, {}, m_scope @@ -352,9 +352,10 @@ void PureInterpreter::enterScope(Block const& _block) void PureInterpreter::leaveScope() { - for (auto const& [var, funDeclaration]: m_scope->names) - if (!funDeclaration) - m_variables.erase(var); + for (auto const& varName: m_scope->declaredVariables) + m_variables.erase(varName); + m_scope->declaredVariables.clear(); + m_scope = m_scope->parent; yulAssert(m_scope, ""); } diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/tools/interpreter/PureInterpreter.h index 521de74655df..37ee23d67104 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -50,8 +50,8 @@ namespace solidity::yul::tools::interpreter */ struct Scope { - /// Used for variables and functions. Value is nullptr for variables. - std::map names; + std::map definedFunctions; + std::vector declaredVariables; std::map> subScopes; Scope* parent = nullptr; }; From 8ad17ced3bd32049078198b45c3d558117e9bf54 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 16:14:48 +0700 Subject: [PATCH 029/101] Make Scope parent constant pointer --- libyul/tools/interpreter/PureInterpreter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/tools/interpreter/PureInterpreter.h index 37ee23d67104..4bf21c3e01b1 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -53,7 +53,7 @@ struct Scope std::map definedFunctions; std::vector declaredVariables; std::map> subScopes; - Scope* parent = nullptr; + Scope* const parent = nullptr; }; /** From 429d5a52eaa817490f1fae3f67959e8cb1a1f031 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 16:18:59 +0700 Subject: [PATCH 030/101] Move Scope to a separate file --- libyul/CMakeLists.txt | 1 + libyul/tools/interpreter/PureInterpreter.h | 12 +----------- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 2a27ecd86c44..778dcb982902 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -204,6 +204,7 @@ add_library(yul optimiser/VarNameCleaner.h tools/interpreter/Results.h tools/interpreter/PureInterpreterState.h + tools/interpreter/Scope.h tools/interpreter/PureInterpreter.cpp tools/interpreter/PureInterpreter.h tools/interpreter/PureEVMInstructionInterpreter.cpp diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/tools/interpreter/PureInterpreter.h index 4bf21c3e01b1..f874646d176d 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -45,17 +46,6 @@ struct Dialect; namespace solidity::yul::tools::interpreter { -/** - * Scope structure built and maintained during execution. - */ -struct Scope -{ - std::map definedFunctions; - std::vector declaredVariables; - std::map> subScopes; - Scope* const parent = nullptr; -}; - /** * Yul interpreter. */ From 4511ccc901af80cd1cd8f4e4c034cf66d194d8e5 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 16:59:52 +0700 Subject: [PATCH 031/101] Make Scope class. Add utilities to Scope. --- libyul/CMakeLists.txt | 1 + libyul/tools/interpreter/Scope.cpp | 66 ++++++++++++++++++++++++++++++ libyul/tools/interpreter/Scope.h | 66 ++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 libyul/tools/interpreter/Scope.cpp create mode 100644 libyul/tools/interpreter/Scope.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 778dcb982902..f04c53b50d8c 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -205,6 +205,7 @@ add_library(yul tools/interpreter/Results.h tools/interpreter/PureInterpreterState.h tools/interpreter/Scope.h + tools/interpreter/Scope.cpp tools/interpreter/PureInterpreter.cpp tools/interpreter/PureInterpreter.h tools/interpreter/PureEVMInstructionInterpreter.cpp diff --git a/libyul/tools/interpreter/Scope.cpp b/libyul/tools/interpreter/Scope.cpp new file mode 100644 index 000000000000..8cfa6cc4f19b --- /dev/null +++ b/libyul/tools/interpreter/Scope.cpp @@ -0,0 +1,66 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include + +#include + +using namespace solidity; +using namespace solidity::yul; +using namespace solidity::yul::tools::interpreter; + +Scope* Scope::getSubscope(Block const& _block) +{ + auto [it, isNew] = m_subScopes.try_emplace(&_block, nullptr); + if (!isNew) return it->second.get(); + + it->second = std::make_unique(this); + Scope* subscope = it->second.get(); + + for (auto const& statement: _block.statements) + if (auto const* funDef = std::get_if(&statement)) + subscope->m_definedFunctions.emplace(funDef->name, *funDef); + + return subscope; +} + +void Scope::addDeclaredVariable(YulName const& _name) +{ + m_declaredVariables.push_back(_name); +} + +void Scope::cleanupVariables(std::map& _variables) +{ + for (YulName const& varName: m_declaredVariables) + _variables.erase(varName); + + m_declaredVariables.clear(); +} + +FunctionDefinition const& Scope::getFunction(YulName const& _functionName) const +{ + for (Scope const* scope = this; scope != nullptr; scope = scope->m_parent) + { + auto it = scope->m_definedFunctions.find(_functionName); + if (it != scope->m_definedFunctions.end()) + return it->second; + } + solAssert(false, ""); +} diff --git a/libyul/tools/interpreter/Scope.h b/libyul/tools/interpreter/Scope.h new file mode 100644 index 000000000000..37f46cf85b4d --- /dev/null +++ b/libyul/tools/interpreter/Scope.h @@ -0,0 +1,66 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +#pragma once + +#include +#include + +#include + +#include +#include + +namespace solidity::yul::tools::interpreter +{ + +/** + * Scope structure built and maintained during execution. + */ +class Scope +{ +public: + Scope(Scope* const _parent = nullptr): + m_definedFunctions(), + m_declaredVariables(), + m_subScopes(), + m_parent(_parent) + {} + + Scope* parent() const + { + return m_parent; + } + + Scope* getSubscope(Block const& _block); + + void addDeclaredVariable(YulName const& _name); + + /// Note: m_declaredVariables will be cleared after this function + void cleanupVariables(std::map& _variables); + + /// Throw an error if function with the given name is not found. + FunctionDefinition const& getFunction(YulName const& _functionName) const; + +private: + std::map m_definedFunctions; + std::vector m_declaredVariables; + std::map> m_subScopes; + Scope* const m_parent; +}; + +} From 6d1dd0d38174c6df74ca812a8838bdcb3bc73d88 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 17:00:04 +0700 Subject: [PATCH 032/101] Use new Scope class in PureInterpreter --- libyul/tools/interpreter/PureInterpreter.cpp | 33 +++----------------- 1 file changed, 5 insertions(+), 28 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index 4e7b77021554..3717beed0baa 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -93,7 +93,7 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat YulName varName = _declaration.variables.at(i).name; solAssert(!m_variables.count(varName), ""); m_variables[varName] = values.at(i); - m_scope->declaredVariables.emplace_back(varName); + m_scope->addDeclaredVariable(varName); } return ExecutionOk { ControlFlowState::Default }; } @@ -208,14 +208,6 @@ ExecutionResult PureInterpreter::operator()(Block const& _block) enterScope(_block); ScopeGuard guard([this] { leaveScope(); }); - // Register functions. - for (auto const& statement: _block.statements) - if (std::holds_alternative(statement)) - { - FunctionDefinition const& funDef = std::get(statement); - m_scope->definedFunctions.emplace(funDef.name, funDef); - } - for (auto const& statement: _block.statements) { ExecutionResult statementRes = visit(statement); @@ -264,13 +256,8 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) } } - Scope* scope = m_scope; - for (; scope; scope = scope->parent) - if (scope->definedFunctions.count(_funCall.functionName.name)) - break; - yulAssert(scope, ""); + FunctionDefinition const& fun = m_scope->getFunction(_funCall.functionName.name); - FunctionDefinition const& fun = scope->definedFunctions.at(_funCall.functionName.name); yulAssert(argsValues.size() == fun.parameters.size(), ""); std::map variables; for (size_t i = 0; i < fun.parameters.size(); ++i) @@ -340,23 +327,13 @@ EvaluationResult PureInterpreter::evaluateArgs( void PureInterpreter::enterScope(Block const& _block) { - if (!m_scope->subScopes.count(&_block)) - m_scope->subScopes[&_block] = std::make_unique(Scope{ - {}, - {}, - {}, - m_scope - }); - m_scope = m_scope->subScopes[&_block].get(); + m_scope = m_scope->getSubscope(_block); } void PureInterpreter::leaveScope() { - for (auto const& varName: m_scope->declaredVariables) - m_variables.erase(varName); - m_scope->declaredVariables.clear(); - - m_scope = m_scope->parent; + m_scope->cleanupVariables(m_variables); + m_scope = m_scope->parent(); yulAssert(m_scope, ""); } From 626b794119ea1fcad5815bfe4ef70b61a9f4dba8 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 17:12:45 +0700 Subject: [PATCH 033/101] Create VariableValuesMap alias --- libyul/CMakeLists.txt | 1 + libyul/tools/interpreter/PureInterpreter.cpp | 2 +- libyul/tools/interpreter/PureInterpreter.h | 9 +++--- libyul/tools/interpreter/Scope.cpp | 2 +- libyul/tools/interpreter/Scope.h | 4 ++- libyul/tools/interpreter/types.h | 31 ++++++++++++++++++++ 6 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 libyul/tools/interpreter/types.h diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index f04c53b50d8c..0c3b67a26e5b 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -206,6 +206,7 @@ add_library(yul tools/interpreter/PureInterpreterState.h tools/interpreter/Scope.h tools/interpreter/Scope.cpp + tools/interpreter/types.h tools/interpreter/PureInterpreter.cpp tools/interpreter/PureInterpreter.h tools/interpreter/PureEVMInstructionInterpreter.cpp diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index 3717beed0baa..eb1dfe5cac38 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -259,7 +259,7 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) FunctionDefinition const& fun = m_scope->getFunction(_funCall.functionName.name); yulAssert(argsValues.size() == fun.parameters.size(), ""); - std::map variables; + VariableValuesMap variables; for (size_t i = 0; i < fun.parameters.size(); ++i) variables[fun.parameters.at(i).name] = argsValues.at(i); for (size_t i = 0; i < fun.returnVariables.size(); ++i) diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/tools/interpreter/PureInterpreter.h index f874646d176d..61f1b3e1d52e 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,7 @@ class PureInterpreter Dialect const& _dialect, Scope& _scope, size_t _callerRecursionDepth, - std::map _variables = {} + VariableValuesMap _variables = {} ): m_dialect(_dialect), m_state(_state), @@ -103,7 +104,7 @@ class PureInterpreter u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } protected: - virtual std::unique_ptr makeInterpreterCopy(std::map _variables = {}) const + virtual std::unique_ptr makeInterpreterCopy(VariableValuesMap _variables = {}) const { return std::make_unique( m_state, @@ -138,8 +139,8 @@ class PureInterpreter Dialect const& m_dialect; PureInterpreterState& m_state; - /// Values of variables. - std::map m_variables; + + VariableValuesMap m_variables; Scope* m_scope; size_t const m_recursionDepth = 0; diff --git a/libyul/tools/interpreter/Scope.cpp b/libyul/tools/interpreter/Scope.cpp index 8cfa6cc4f19b..fd2529353dae 100644 --- a/libyul/tools/interpreter/Scope.cpp +++ b/libyul/tools/interpreter/Scope.cpp @@ -46,7 +46,7 @@ void Scope::addDeclaredVariable(YulName const& _name) m_declaredVariables.push_back(_name); } -void Scope::cleanupVariables(std::map& _variables) +void Scope::cleanupVariables(VariableValuesMap& _variables) { for (YulName const& varName: m_declaredVariables) _variables.erase(varName); diff --git a/libyul/tools/interpreter/Scope.h b/libyul/tools/interpreter/Scope.h index 37f46cf85b4d..b52079dc8d4e 100644 --- a/libyul/tools/interpreter/Scope.h +++ b/libyul/tools/interpreter/Scope.h @@ -17,6 +17,8 @@ // SPDX-License-Identifier: GPL-3.0 #pragma once +#include + #include #include @@ -51,7 +53,7 @@ class Scope void addDeclaredVariable(YulName const& _name); /// Note: m_declaredVariables will be cleared after this function - void cleanupVariables(std::map& _variables); + void cleanupVariables(VariableValuesMap& _variables); /// Throw an error if function with the given name is not found. FunctionDefinition const& getFunction(YulName const& _functionName) const; diff --git a/libyul/tools/interpreter/types.h b/libyul/tools/interpreter/types.h new file mode 100644 index 000000000000..c01da44832ea --- /dev/null +++ b/libyul/tools/interpreter/types.h @@ -0,0 +1,31 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +#pragma once + +#include + +#include + +#include + +namespace solidity::yul::tools::interpreter +{ + +using VariableValuesMap = std::map; + +} From f2b3b69dbe05bbdc3c32b75c64d4f9d90c4bf668 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 17:45:12 +0700 Subject: [PATCH 034/101] Fix behavior of POP instruction --- .../PureEVMInstructionInterpreter.cpp | 24 +++++++++---------- .../PureEVMInstructionInterpreter.h | 6 ++--- libyul/tools/interpreter/PureInterpreter.cpp | 4 ++-- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp index 398872ddaaaa..2b03141ec4cf 100644 --- a/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp @@ -44,7 +44,7 @@ using solidity::util::h256; using u512 = boost::multiprecision::number>; -EVMInstructionInterpretedResult PureEVMInstructionInterpreter::eval( +EvaluationResult PureEVMInstructionInterpreter::eval( evmasm::Instruction _instruction, std::vector const& _arguments ) @@ -80,17 +80,17 @@ EVMInstructionInterpretedResult PureEVMInstructionInterpreter::eval( case Instruction::NOT: return ~arg[0]; case Instruction::LT: - return arg[0] < arg[1] ? 1 : 0; + return arg[0] < arg[1] ? u256(1) : u256(0); case Instruction::GT: - return arg[0] > arg[1] ? 1 : 0; + return arg[0] > arg[1] ? u256(1) : u256(0); case Instruction::SLT: - return u2s(arg[0]) < u2s(arg[1]) ? 1 : 0; + return u2s(arg[0]) < u2s(arg[1]) ? u256(1) : u256(0); case Instruction::SGT: - return u2s(arg[0]) > u2s(arg[1]) ? 1 : 0; + return u2s(arg[0]) > u2s(arg[1]) ? u256(1) : u256(0); case Instruction::EQ: - return arg[0] == arg[1] ? 1 : 0; + return arg[0] == arg[1] ? u256(1) : u256(0); case Instruction::ISZERO: - return arg[0] == 0 ? 1 : 0; + return arg[0] == 0 ? u256(1) : u256(0); case Instruction::AND: return arg[0] & arg[1]; case Instruction::OR: @@ -197,7 +197,7 @@ EVMInstructionInterpretedResult PureEVMInstructionInterpreter::eval( return ImpureBuiltinEncountered(); case Instruction::POP: - break; + return std::vector(); // --------------- invalid in strict assembly --------------- case Instruction::JUMP: case Instruction::JUMPI: @@ -269,15 +269,15 @@ EVMInstructionInterpretedResult PureEVMInstructionInterpreter::eval( case Instruction::SWAP16: { yulAssert(false, ""); - return 0; + return u256(); } } yulAssert(false, "Unknown instruction with opcode " + std::to_string(static_cast(_instruction))); - return 0; + return u256(); } -EVMInstructionInterpretedResult PureEVMInstructionInterpreter::evalBuiltin( +EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( BuiltinFunctionForEVM const& _fun, std::vector const& /* _arguments */, // This was required to execute some builtin. // But all of them are impure. @@ -302,6 +302,6 @@ EVMInstructionInterpretedResult PureEVMInstructionInterpreter::evalBuiltin( return ImpureBuiltinEncountered(); yulAssert(false, "Unknown builtin: " + fun); - return 0; + return u256(); } diff --git a/libyul/tools/interpreter/PureEVMInstructionInterpreter.h b/libyul/tools/interpreter/PureEVMInstructionInterpreter.h index 03fe946669cf..15b5acc99bee 100644 --- a/libyul/tools/interpreter/PureEVMInstructionInterpreter.h +++ b/libyul/tools/interpreter/PureEVMInstructionInterpreter.h @@ -48,8 +48,6 @@ struct BuiltinFunctionForEVM; namespace solidity::yul::tools::interpreter { -using EVMInstructionInterpretedResult = std::variant; - /** * Interprets EVM instructions based on the current state without side-effect. */ @@ -62,10 +60,10 @@ class PureEVMInstructionInterpreter {} /// Evaluate instruction - EVMInstructionInterpretedResult eval(evmasm::Instruction _instruction, std::vector const& _arguments); + EvaluationResult eval(evmasm::Instruction _instruction, std::vector const& _arguments); /// Evaluate builtin function - EVMInstructionInterpretedResult evalBuiltin( + EvaluationResult evalBuiltin( BuiltinFunctionForEVM const& _fun, std::vector const& _arguments, std::vector const& _evaluatedArguments diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index eb1dfe5cac38..a0560ef55f93 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -250,9 +250,9 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) { PureEVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state); - EVMInstructionInterpretedResult const value = interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); + EvaluationResult value = interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); if (auto* terminated = std::get_if(&value)) return *terminated; - return EvaluationOk(std::get(value)); + return value; } } From 15abbcc7d5ef1f8ac417ac9dac97f7f8ecada639 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 17:56:07 +0700 Subject: [PATCH 035/101] Add stack trace to state --- libyul/tools/interpreter/PureInterpreter.cpp | 4 ++ .../tools/interpreter/PureInterpreterState.h | 56 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index a0560ef55f93..c57a2fe02a90 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -266,12 +266,16 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) variables[fun.returnVariables.at(i).name] = 0; std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); + + m_state.addTrace(fun, argsValues); ExecutionResult funcBodyRes = (*interpreter)(fun.body); if (auto* terminated = std::get_if(&funcBodyRes)) return *terminated; std::vector returnedValues; for (auto const& retVar: fun.returnVariables) returnedValues.emplace_back(interpreter->valueOfVariable(retVar.name)); + m_state.addTrace(fun, returnedValues); + return EvaluationOk(returnedValues); } diff --git a/libyul/tools/interpreter/PureInterpreterState.h b/libyul/tools/interpreter/PureInterpreterState.h index 22132e69a6fa..c271b26549c2 100644 --- a/libyul/tools/interpreter/PureInterpreterState.h +++ b/libyul/tools/interpreter/PureInterpreterState.h @@ -18,14 +18,57 @@ #pragma once +#include + +#include +#include + #include +#include +#include namespace solidity::yul::tools::interpreter { +class TraceLimitReached: public util::Exception +{ +}; + +struct FunctionCallTrace +{ + FunctionDefinition const& definition; + std::vector params; + + FunctionCallTrace( + FunctionDefinition const& _definition, + std::vector const& _params + ): + definition(_definition), + params(_params) + {} +}; + +struct FunctionReturnTrace +{ + FunctionDefinition const& definition; + std::vector returnedValues; + + FunctionReturnTrace( + FunctionDefinition const& _definition, + std::vector const& _returnedValues + ): + definition(_definition), + returnedValues(_returnedValues) + {} +}; + +using LogTraceEntry = std::variant; + struct PureInterpreterConfig { + // set to 0 to disable tracing size_t maxTraceSize = 0; + size_t maxSteps = 0; size_t maxExprNesting = 0; size_t maxRecursionDepth = 0; @@ -36,6 +79,19 @@ struct PureInterpreterState PureInterpreterConfig const config; size_t numSteps = 0; + std::vector traces; + + /// Add a log trace. + /// Will do nothing if config.maxTraceSize == 0 + /// - the log entry will not be constructed in this case + template + void addTrace(const Args&... args) + { + if (config.maxTraceSize == 0) return; + if (traces.size() > config.maxTraceSize) + BOOST_THROW_EXCEPTION(TraceLimitReached()); + traces.emplace_back(std::in_place_type, args...); + } }; } From 17bf46ba15c9409a20e1f4f987ee1a18dbb515bc Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 21:07:17 +0700 Subject: [PATCH 036/101] Remove TraceLimitReached from ExecutionTerminated --- libyul/tools/interpreter/Results.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libyul/tools/interpreter/Results.h b/libyul/tools/interpreter/Results.h index 9e2151f16c27..9bdb97f27f6f 100644 --- a/libyul/tools/interpreter/Results.h +++ b/libyul/tools/interpreter/Results.h @@ -45,10 +45,6 @@ class StepLimitReached : public ExecutionTerminatedCommon { }; -class TraceLimitReached : public ExecutionTerminatedCommon -{ -}; - class RecursionDepthLimitReached : public ExecutionTerminatedCommon { }; @@ -65,7 +61,6 @@ using ExecutionTerminated = std::variant< ExplicitlyTerminated, ExplicitlyTerminatedWithReturn, StepLimitReached, - TraceLimitReached, RecursionDepthLimitReached, ExpressionNestingLimitReached, ImpureBuiltinEncountered From e219ef323b4e02a7dc868bbfd2b5584ef47838e1 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 21:35:48 +0700 Subject: [PATCH 037/101] Add dumpTraces function --- libyul/CMakeLists.txt | 1 + .../interpreter/PureInterpreterState.cpp | 77 +++++++++++++++++++ .../tools/interpreter/PureInterpreterState.h | 2 + 3 files changed, 80 insertions(+) create mode 100644 libyul/tools/interpreter/PureInterpreterState.cpp diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 0c3b67a26e5b..0e0b6c297bed 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -204,6 +204,7 @@ add_library(yul optimiser/VarNameCleaner.h tools/interpreter/Results.h tools/interpreter/PureInterpreterState.h + tools/interpreter/PureInterpreterState.cpp tools/interpreter/Scope.h tools/interpreter/Scope.cpp tools/interpreter/types.h diff --git a/libyul/tools/interpreter/PureInterpreterState.cpp b/libyul/tools/interpreter/PureInterpreterState.cpp new file mode 100644 index 000000000000..597e17885e11 --- /dev/null +++ b/libyul/tools/interpreter/PureInterpreterState.cpp @@ -0,0 +1,77 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include + +#include + +#include + +#include +#include + +using namespace solidity::yul::tools::interpreter; + +void PureInterpreterState::dumpTraces(std::ostream& _out) const +{ + static std::string_view const INDENT = " "; + static std::string_view const BAR = "│ "; + + _out << "Call trace:\n"; + std::vector stackTrace; + + auto print_values = [&](std::vector const& vec) + { + bool isFirst = true; + for (auto x: vec) + { + if (!isFirst) + _out << ", "; + isFirst = false; + _out << x; + } + }; + + for (auto const& trace: traces) { + _out << INDENT; + for (size_t i = 0, callLevel = stackTrace.size(); i < callLevel; ++i) + _out << BAR; + + std::visit(util::GenericVisitor{ + [&](FunctionCallTrace const& callTrace) { + _out << "[CALL] " << callTrace.definition.name.str() << "("; + print_values(callTrace.params); + _out << ")"; + stackTrace.push_back(&callTrace); + }, + [&](FunctionReturnTrace const& returnTrace) { + solAssert(!stackTrace.empty()); + bool areIdentical = &stackTrace.back()->definition == &returnTrace.definition; + solAssert(areIdentical); + + _out << "[RETURN] "; + print_values(returnTrace.returnedValues); + stackTrace.pop_back(); + } + }, trace); + + _out << std::endl; + } +} diff --git a/libyul/tools/interpreter/PureInterpreterState.h b/libyul/tools/interpreter/PureInterpreterState.h index c271b26549c2..24d4a4fb9973 100644 --- a/libyul/tools/interpreter/PureInterpreterState.h +++ b/libyul/tools/interpreter/PureInterpreterState.h @@ -92,6 +92,8 @@ struct PureInterpreterState BOOST_THROW_EXCEPTION(TraceLimitReached()); traces.emplace_back(std::in_place_type, args...); } + + void dumpTraces(std::ostream& _out) const; }; } From 6cde83c7da1943692b57564d07d9cee9f4516c5c Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 21:53:37 +0700 Subject: [PATCH 038/101] Add execute statements function --- libyul/tools/interpreter/PureInterpreter.cpp | 10 +++++++--- libyul/tools/interpreter/PureInterpreter.h | 4 ++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index c57a2fe02a90..bbbd9f4295e8 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -146,9 +146,8 @@ ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) enterScope(_forLoop.pre); ScopeGuard g([this]{ leaveScope(); }); - for (auto const& statement: _forLoop.pre.statements) { - ExecutionResult execRes = visit(statement); + ExecutionResult execRes = execute(_forLoop.pre.statements); if (execRes == ExecutionResult(ExecutionOk { ControlFlowState::Leave })) return execRes; } @@ -208,7 +207,12 @@ ExecutionResult PureInterpreter::operator()(Block const& _block) enterScope(_block); ScopeGuard guard([this] { leaveScope(); }); - for (auto const& statement: _block.statements) + return execute(_block.statements); +} + +ExecutionResult PureInterpreter::execute(std::vector const& _statements) +{ + for (auto const& statement: _statements) { ExecutionResult statementRes = visit(statement); if (statementRes != ExecutionResult(ExecutionOk {ControlFlowState::Default})) diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/tools/interpreter/PureInterpreter.h index 61f1b3e1d52e..d3a21076acbc 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -91,6 +91,10 @@ class PureInterpreter ExecutionResult operator()(Leave const&); ExecutionResult operator()(Block const& _block); + /// Only execute the statements in order. + /// Will not alter the scope. + ExecutionResult execute(std::vector const& _statements); + ExecutionResult visit(Statement const& _st); // Expression visit methods From 840ce767c118a685f2a379210869a2080ab33749 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 21:56:50 +0700 Subject: [PATCH 039/101] Add UnlimitedLiteralEncountered result type --- libyul/tools/interpreter/PureInterpreter.cpp | 5 +---- libyul/tools/interpreter/Results.h | 7 ++++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index bbbd9f4295e8..feddf4237ff5 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -319,10 +319,7 @@ EvaluationResult PureInterpreter::evaluateArgs( else { if (std::get(expr).value.unlimited()) - { - yulAssert(std::get(expr).kind == LiteralKind::String); - values.push_back(0xdeadbeef); - } + return UnlimitedLiteralEncountered(); else values.push_back(std::get(expr).value.value()); } diff --git a/libyul/tools/interpreter/Results.h b/libyul/tools/interpreter/Results.h index 9bdb97f27f6f..29b40d711e12 100644 --- a/libyul/tools/interpreter/Results.h +++ b/libyul/tools/interpreter/Results.h @@ -57,13 +57,18 @@ class ImpureBuiltinEncountered : public ExecutionTerminatedCommon +{ +}; + using ExecutionTerminated = std::variant< ExplicitlyTerminated, ExplicitlyTerminatedWithReturn, StepLimitReached, RecursionDepthLimitReached, ExpressionNestingLimitReached, - ImpureBuiltinEncountered + ImpureBuiltinEncountered, + UnlimitedLiteralEncountered >; enum class ControlFlowState From e1834b9d39e71cc011c33d0facbff9118e009ed8 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 22:34:32 +0700 Subject: [PATCH 040/101] Change calculation flow for evaluateArgs --- libyul/tools/interpreter/PureInterpreter.cpp | 21 +++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index feddf4237ff5..3ed60e0ab4bc 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -303,30 +302,28 @@ EvaluationResult PureInterpreter::evaluateArgs( std::vector> const* _literalArguments ) { - std::vector values; - size_t i = 0; + std::vector values(_expr.size()); + /// Function arguments are evaluated in reverse. - for (auto const& expr: _expr | ranges::views::reverse) + for (size_t i = _expr.size(); i-- > 0; ) { - if (!_literalArguments || !_literalArguments->at(_expr.size() - i - 1)) + auto const& expr = _expr[i]; + bool isLiteral = _literalArguments && _literalArguments->at(i); + if (!isLiteral) { - EvaluationResult exprRes = visit(expr); + EvaluationResult exprRes = evaluate(expr, 1); if (auto* terminated = std::get_if(&exprRes)) return *terminated; std::vector const& exprValues = std::get(exprRes).values; - yulAssert(exprValues.size() == 1, ""); - values.push_back(exprValues.at(0)); + values[i] = exprValues.at(0); } else { if (std::get(expr).value.unlimited()) return UnlimitedLiteralEncountered(); else - values.push_back(std::get(expr).value.value()); + values[i] = std::get(expr).value.value(); } - - ++i; } - std::reverse(values.begin(), values.end()); return EvaluationOk(values); } From 07e619b155f97bc29ca1eb086b4e05a79914c401 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 22:36:28 +0700 Subject: [PATCH 041/101] Add move constructor for EvaluationOk --- libyul/tools/interpreter/PureInterpreter.cpp | 4 ++-- libyul/tools/interpreter/Results.h | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index 3ed60e0ab4bc..a6971e43c151 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -279,7 +279,7 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) returnedValues.emplace_back(interpreter->valueOfVariable(retVar.name)); m_state.addTrace(fun, returnedValues); - return EvaluationOk(returnedValues); + return EvaluationOk(std::move(returnedValues)); } EvaluationResult PureInterpreter::visit(Expression const& _st) @@ -324,7 +324,7 @@ EvaluationResult PureInterpreter::evaluateArgs( values[i] = std::get(expr).value.value(); } } - return EvaluationOk(values); + return EvaluationOk(std::move(values)); } void PureInterpreter::enterScope(Block const& _block) diff --git a/libyul/tools/interpreter/Results.h b/libyul/tools/interpreter/Results.h index 29b40d711e12..cf8a6868119e 100644 --- a/libyul/tools/interpreter/Results.h +++ b/libyul/tools/interpreter/Results.h @@ -107,6 +107,11 @@ struct EvaluationOk values(_values) { } + + EvaluationOk(std::vector&& _values): + values(std::move(_values)) + { + } }; using ExecutionResult = std::variant; From ec482562fdfdf272fa91b15dbfbf2dbafdf02cea Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 22:39:31 +0700 Subject: [PATCH 042/101] Disable EvaluationOk lvalue constructor --- libyul/tools/interpreter/Results.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libyul/tools/interpreter/Results.h b/libyul/tools/interpreter/Results.h index cf8a6868119e..169a1c16dfbb 100644 --- a/libyul/tools/interpreter/Results.h +++ b/libyul/tools/interpreter/Results.h @@ -103,10 +103,8 @@ struct EvaluationOk { } - EvaluationOk(std::vector const& _values): - values(_values) - { - } + /// Disable lvalue constructor to encourage rvalue usage. + EvaluationOk(std::vector const& _values) = delete; EvaluationOk(std::vector&& _values): values(std::move(_values)) From de3fb6046b4fa0ece956532d286718f925e86802 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 22:49:32 +0700 Subject: [PATCH 043/101] Make EvaluationOk constructor explicit --- .../PureEVMInstructionInterpreter.cpp | 62 +++++++++---------- libyul/tools/interpreter/Results.h | 9 ++- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp index 2b03141ec4cf..354b5e1c868e 100644 --- a/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp @@ -62,68 +62,68 @@ EvaluationResult PureEVMInstructionInterpreter::eval( return ExplicitlyTerminated(); // --------------- arithmetic --------------- case Instruction::ADD: - return arg[0] + arg[1]; + return EvaluationOk(arg[0] + arg[1]); case Instruction::MUL: - return arg[0] * arg[1]; + return EvaluationOk(arg[0] * arg[1]); case Instruction::SUB: - return arg[0] - arg[1]; + return EvaluationOk(arg[0] - arg[1]); case Instruction::DIV: - return arg[1] == 0 ? 0 : arg[0] / arg[1]; + return EvaluationOk(arg[1] == 0 ? 0 : arg[0] / arg[1]); case Instruction::SDIV: - return arg[1] == 0 ? 0 : s2u(u2s(arg[0]) / u2s(arg[1])); + return EvaluationOk(arg[1] == 0 ? 0 : s2u(u2s(arg[0]) / u2s(arg[1]))); case Instruction::MOD: - return arg[1] == 0 ? 0 : arg[0] % arg[1]; + return EvaluationOk(arg[1] == 0 ? 0 : arg[0] % arg[1]); case Instruction::SMOD: - return arg[1] == 0 ? 0 : s2u(u2s(arg[0]) % u2s(arg[1])); + return EvaluationOk(arg[1] == 0 ? 0 : s2u(u2s(arg[0]) % u2s(arg[1]))); case Instruction::EXP: - return exp256(arg[0], arg[1]); + return EvaluationOk(exp256(arg[0], arg[1])); case Instruction::NOT: - return ~arg[0]; + return EvaluationOk(~arg[0]); case Instruction::LT: - return arg[0] < arg[1] ? u256(1) : u256(0); + return EvaluationOk(arg[0] < arg[1] ? u256(1) : u256(0)); case Instruction::GT: - return arg[0] > arg[1] ? u256(1) : u256(0); + return EvaluationOk(arg[0] > arg[1] ? u256(1) : u256(0)); case Instruction::SLT: - return u2s(arg[0]) < u2s(arg[1]) ? u256(1) : u256(0); + return EvaluationOk(u2s(arg[0]) < u2s(arg[1]) ? u256(1) : u256(0)); case Instruction::SGT: - return u2s(arg[0]) > u2s(arg[1]) ? u256(1) : u256(0); + return EvaluationOk(u2s(arg[0]) > u2s(arg[1]) ? u256(1) : u256(0)); case Instruction::EQ: - return arg[0] == arg[1] ? u256(1) : u256(0); + return EvaluationOk(arg[0] == arg[1] ? u256(1) : u256(0)); case Instruction::ISZERO: - return arg[0] == 0 ? u256(1) : u256(0); + return EvaluationOk(arg[0] == 0 ? u256(1) : u256(0)); case Instruction::AND: - return arg[0] & arg[1]; + return EvaluationOk(arg[0] & arg[1]); case Instruction::OR: - return arg[0] | arg[1]; + return EvaluationOk(arg[0] | arg[1]); case Instruction::XOR: - return arg[0] ^ arg[1]; + return EvaluationOk(arg[0] ^ arg[1]); case Instruction::BYTE: - return arg[0] >= 32 ? 0 : (arg[1] >> unsigned(8 * (31 - arg[0]))) & 0xff; + return EvaluationOk(arg[0] >= 32 ? 0 : (arg[1] >> unsigned(8 * (31 - arg[0]))) & 0xff); case Instruction::SHL: - return arg[0] > 255 ? 0 : (arg[1] << unsigned(arg[0])); + return EvaluationOk(arg[0] > 255 ? 0 : (arg[1] << unsigned(arg[0]))); case Instruction::SHR: - return arg[0] > 255 ? 0 : (arg[1] >> unsigned(arg[0])); + return EvaluationOk(arg[0] > 255 ? 0 : (arg[1] >> unsigned(arg[0]))); case Instruction::SAR: { static u256 const hibit = u256(1) << 255; if (arg[0] >= 256) - return arg[1] & hibit ? u256(-1) : 0; + return EvaluationOk(arg[1] & hibit ? u256(-1) : 0); else { unsigned amount = unsigned(arg[0]); u256 v = arg[1] >> amount; if (arg[1] & hibit) v |= u256(-1) << (256 - amount); - return v; + return EvaluationOk(v); } } case Instruction::ADDMOD: - return arg[2] == 0 ? 0 : u256((u512(arg[0]) + u512(arg[1])) % arg[2]); + return EvaluationOk(arg[2] == 0 ? 0 : u256((u512(arg[0]) + u512(arg[1])) % arg[2])); case Instruction::MULMOD: - return arg[2] == 0 ? 0 : u256((u512(arg[0]) * u512(arg[1])) % arg[2]); + return EvaluationOk(arg[2] == 0 ? 0 : u256((u512(arg[0]) * u512(arg[1])) % arg[2])); case Instruction::SIGNEXTEND: if (arg[0] >= 31) - return arg[1]; + return EvaluationOk(arg[1]); else { unsigned testBit = unsigned(arg[0]) * 8 + 7; @@ -133,7 +133,7 @@ EvaluationResult PureEVMInstructionInterpreter::eval( ret |= ~mask; else ret &= mask; - return ret; + return EvaluationOk(ret); } // --------------- blockchain stuff --------------- case Instruction::KECCAK256: @@ -197,7 +197,7 @@ EvaluationResult PureEVMInstructionInterpreter::eval( return ImpureBuiltinEncountered(); case Instruction::POP: - return std::vector(); + return EvaluationOk(); // --------------- invalid in strict assembly --------------- case Instruction::JUMP: case Instruction::JUMPI: @@ -269,12 +269,12 @@ EvaluationResult PureEVMInstructionInterpreter::eval( case Instruction::SWAP16: { yulAssert(false, ""); - return u256(); + return EvaluationOk(0); } } yulAssert(false, "Unknown instruction with opcode " + std::to_string(static_cast(_instruction))); - return u256(); + return EvaluationOk(0); } EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( @@ -302,6 +302,6 @@ EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( return ImpureBuiltinEncountered(); yulAssert(false, "Unknown builtin: " + fun); - return u256(); + return EvaluationOk(0); } diff --git a/libyul/tools/interpreter/Results.h b/libyul/tools/interpreter/Results.h index 169a1c16dfbb..f3e4b816a3ff 100644 --- a/libyul/tools/interpreter/Results.h +++ b/libyul/tools/interpreter/Results.h @@ -98,7 +98,12 @@ struct EvaluationOk { std::vector values; - EvaluationOk(u256 _x): + explicit EvaluationOk(): + values() + { + } + + explicit EvaluationOk(u256 _x): values{_x} { } @@ -106,7 +111,7 @@ struct EvaluationOk /// Disable lvalue constructor to encourage rvalue usage. EvaluationOk(std::vector const& _values) = delete; - EvaluationOk(std::vector&& _values): + explicit EvaluationOk(std::vector&& _values): values(std::move(_values)) { } From 62f005f93534433ae36b8b7d25293895e318dbcd Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 22:56:44 +0700 Subject: [PATCH 044/101] Optimize std::vector usage --- libyul/tools/interpreter/PureInterpreter.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index a6971e43c151..22e504ff35a5 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -66,7 +66,7 @@ ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) EvaluationResult evalRes = evaluate(*_assignment.value, _assignment.variableNames.size()); if (auto* terminated = std::get_if(&evalRes)) return *terminated; - std::vector const& values = std::get(evalRes).values; + std::vector const& values = std::move(std::get(evalRes).values); for (size_t i = 0; i < values.size(); ++i) { YulName varName = _assignment.variableNames.at(i).name; @@ -78,12 +78,16 @@ ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declaration) { - std::vector values(_declaration.variables.size(), 0); + std::vector values; if (_declaration.value) { EvaluationResult evalRes = evaluate(*_declaration.value, _declaration.variables.size()); if (auto* terminated = std::get_if(&evalRes)) return *terminated; - values = std::get(evalRes).values; + values = std::move(std::get(evalRes).values); + } + else + { + values.assign(_declaration.variables.size(), 0); } solAssert(values.size() == _declaration.variables.size(), ""); @@ -246,7 +250,7 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) EvaluationResult argsRes = evaluateArgs(_funCall.arguments, literalArguments); if (auto* terminated = std::get_if(&argsRes)) return *terminated; - std::vector argsValues = std::get(argsRes).values; + std::vector argsValues = std::move(std::get(argsRes).values); if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) { @@ -275,6 +279,7 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) if (auto* terminated = std::get_if(&funcBodyRes)) return *terminated; std::vector returnedValues; + returnedValues.reserve(fun.returnVariables.size()); for (auto const& retVar: fun.returnVariables) returnedValues.emplace_back(interpreter->valueOfVariable(retVar.name)); m_state.addTrace(fun, returnedValues); From f597107079340b8176db7510193f2919dd6e11d9 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 23:20:51 +0700 Subject: [PATCH 045/101] Copy YulInterpreterTest suite to YulPureInterpreterTest --- test/CMakeLists.txt | 2 + test/libyul/YulPureInterpreterTest.cpp | 114 +++++++++++++++++++++++++ test/libyul/YulPureInterpreterTest.h | 53 ++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 test/libyul/YulPureInterpreterTest.cpp create mode 100644 test/libyul/YulPureInterpreterTest.h diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index da115f0d4a5b..8f5558a0211e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -164,6 +164,8 @@ set(libyul_sources libyul/SyntaxTest.cpp libyul/YulInterpreterTest.cpp libyul/YulInterpreterTest.h + libyul/YulPureInterpreterTest.h + libyul/YulPureInterpreterTest.cpp libyul/YulOptimizerTest.cpp libyul/YulOptimizerTest.h libyul/YulOptimizerTestCommon.cpp diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp new file mode 100644 index 000000000000..a9b1af3ffedf --- /dev/null +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -0,0 +1,114 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include + +using namespace solidity; +using namespace solidity::util; +using namespace solidity::langutil; +using namespace solidity::yul; +using namespace solidity::yul::test; +using namespace solidity::frontend; +using namespace solidity::frontend::test; + +YulPureInterpreterTest::YulPureInterpreterTest(std::string const& _filename): + EVMVersionRestrictedTestCase(_filename) +{ + m_source = m_reader.source(); + m_expectation = m_reader.simpleExpectations(); + m_simulateExternalCallsToSelf = m_reader.boolSetting("simulateExternalCall", false); +} + +TestCase::TestResult YulPureInterpreterTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) +{ + if (!parse(_stream, _linePrefix, _formatted)) + return TestResult::FatalError; + + m_obtainedResult = interpret(); + + return checkResult(_stream, _linePrefix, _formatted); +} + +bool YulPureInterpreterTest::parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) +{ + YulStack stack( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion(), + YulStack::Language::StrictAssembly, + solidity::frontend::OptimiserSettings::none(), + DebugInfoSelection::All() + ); + if (stack.parseAndAnalyze("", m_source)) + { + m_ast = stack.parserResult()->code(); + m_analysisInfo = stack.parserResult()->analysisInfo; + return true; + } + else + { + AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << std::endl; + SourceReferenceFormatter{_stream, stack, true, false} + .printErrorInformation(stack.errors()); + return false; + } +} + +std::string YulPureInterpreterTest::interpret() +{ + InterpreterState state; + state.maxTraceSize = 32; + state.maxSteps = 512; + state.maxExprNesting = 64; + try + { + Interpreter::run( + state, + EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()), + m_ast->root(), + /*disableExternalCalls=*/ !m_simulateExternalCallsToSelf, + /*disableMemoryTracing=*/ false + ); + } + catch (InterpreterTerminatedGeneric const&) + { + } + + std::stringstream result; + state.dumpTraceAndState(result, false); + return result.str(); +} diff --git a/test/libyul/YulPureInterpreterTest.h b/test/libyul/YulPureInterpreterTest.h new file mode 100644 index 000000000000..805134c8ef48 --- /dev/null +++ b/test/libyul/YulPureInterpreterTest.h @@ -0,0 +1,53 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include + +namespace solidity::yul +{ +struct AsmAnalysisInfo; +class AST; +} + +namespace solidity::yul::test +{ + +class YulPureInterpreterTest: public solidity::frontend::test::EVMVersionRestrictedTestCase +{ +public: + static std::unique_ptr create(Config const& _config) + { + return std::make_unique(_config.filename); + } + + explicit YulPureInterpreterTest(std::string const& _filename); + + TestResult run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; + +private: + bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted); + std::string interpret(); + + std::shared_ptr m_ast; + std::shared_ptr m_analysisInfo; + bool m_simulateExternalCallsToSelf = false; +}; + +} From 06f972a08a3439486b507f5b91ed1c950dbb45ee Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 23:26:19 +0700 Subject: [PATCH 046/101] Read interpreter config from test settings --- test/libyul/YulPureInterpreterTest.cpp | 8 ++++++-- test/libyul/YulPureInterpreterTest.h | 4 +++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index a9b1af3ffedf..68183aec0873 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -51,7 +51,11 @@ YulPureInterpreterTest::YulPureInterpreterTest(std::string const& _filename): { m_source = m_reader.source(); m_expectation = m_reader.simpleExpectations(); - m_simulateExternalCallsToSelf = m_reader.boolSetting("simulateExternalCall", false); + + m_config.maxTraceSize = m_reader.sizetSetting("maxTraceSize", 128); + m_config.maxExprNesting = m_reader.sizetSetting("maxExprNesting", 64); + m_config.maxSteps = m_reader.sizetSetting("maxSteps", 512); + m_config.maxRecursionDepth = m_reader.sizetSetting("maxRecursionDepth", 64); } TestCase::TestResult YulPureInterpreterTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) @@ -100,7 +104,7 @@ std::string YulPureInterpreterTest::interpret() state, EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()), m_ast->root(), - /*disableExternalCalls=*/ !m_simulateExternalCallsToSelf, + /*disableExternalCalls=*/ false, /*disableMemoryTracing=*/ false ); } diff --git a/test/libyul/YulPureInterpreterTest.h b/test/libyul/YulPureInterpreterTest.h index 805134c8ef48..c1a757530343 100644 --- a/test/libyul/YulPureInterpreterTest.h +++ b/test/libyul/YulPureInterpreterTest.h @@ -20,6 +20,8 @@ #include +#include + namespace solidity::yul { struct AsmAnalysisInfo; @@ -47,7 +49,7 @@ class YulPureInterpreterTest: public solidity::frontend::test::EVMVersionRestric std::shared_ptr m_ast; std::shared_ptr m_analysisInfo; - bool m_simulateExternalCallsToSelf = false; + tools::interpreter::PureInterpreterConfig m_config; }; } From 0e853899931f17b8aa144e39183a197b4efc4d4a Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 23:28:35 +0700 Subject: [PATCH 047/101] Make PureInterpreter.run returns ExecutionResult --- libyul/tools/interpreter/PureInterpreter.cpp | 4 ++-- libyul/tools/interpreter/PureInterpreter.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index 22e504ff35a5..eaabdc575d1d 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -43,14 +43,14 @@ using namespace solidity::yul::tools::interpreter; using solidity::util::h256; -void PureInterpreter::run( +ExecutionResult PureInterpreter::run( PureInterpreterState& _state, Dialect const& _dialect, Block const& _ast ) { Scope scope; - PureInterpreter{_state, _dialect, scope, 0}(_ast); + return PureInterpreter{_state, _dialect, scope, 0}(_ast); } ExecutionResult PureInterpreter::operator()(ExpressionStatement const& _expressionStatement) diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/tools/interpreter/PureInterpreter.h index d3a21076acbc..92a1fcf62f32 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -54,7 +54,7 @@ class PureInterpreter { public: /// Executes the Yul interpreter. - static void run( + static ExecutionResult run( PureInterpreterState& _state, Dialect const& _dialect, Block const& _ast From b2526f0fe03fb430eff9dd39f543bc690a2addf6 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 23:31:00 +0700 Subject: [PATCH 048/101] Add default value for traces --- libyul/tools/interpreter/PureInterpreterState.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libyul/tools/interpreter/PureInterpreterState.h b/libyul/tools/interpreter/PureInterpreterState.h index 24d4a4fb9973..86c8ba40245f 100644 --- a/libyul/tools/interpreter/PureInterpreterState.h +++ b/libyul/tools/interpreter/PureInterpreterState.h @@ -79,7 +79,7 @@ struct PureInterpreterState PureInterpreterConfig const config; size_t numSteps = 0; - std::vector traces; + std::vector traces = {}; /// Add a log trace. /// Will do nothing if config.maxTraceSize == 0 From 0d4397d3c3adbf37dd9696a75712b2c62977d3d2 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 23:41:49 +0700 Subject: [PATCH 049/101] Use new PureInterpreter in test --- test/libyul/YulPureInterpreterTest.cpp | 47 ++++++++++++++++++-------- test/libyul/YulPureInterpreterTest.h | 2 ++ 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index 68183aec0873..851267006588 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -18,7 +18,7 @@ #include -#include +#include #include @@ -32,12 +32,11 @@ #include #include +#include #include #include -#include - using namespace solidity; using namespace solidity::util; using namespace solidity::langutil; @@ -46,6 +45,8 @@ using namespace solidity::yul::test; using namespace solidity::frontend; using namespace solidity::frontend::test; +using namespace solidity::yul::tools::interpreter; + YulPureInterpreterTest::YulPureInterpreterTest(std::string const& _filename): EVMVersionRestrictedTestCase(_filename) { @@ -94,25 +95,41 @@ bool YulPureInterpreterTest::parse(std::ostream& _stream, std::string const& _li std::string YulPureInterpreterTest::interpret() { - InterpreterState state; - state.maxTraceSize = 32; - state.maxSteps = 512; - state.maxExprNesting = 64; + PureInterpreterState state { m_config }; + + std::stringstream resultStream; try { - Interpreter::run( + ExecutionResult res = PureInterpreter::run( state, EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()), - m_ast->root(), - /*disableExternalCalls=*/ false, - /*disableMemoryTracing=*/ false + m_ast->root() ); + dumpExecutionResult(resultStream, res); } - catch (InterpreterTerminatedGeneric const&) + catch (TraceLimitReached const&) { + resultStream << "Trace limit reached!"; } + state.dumpTraces(resultStream); + return resultStream.str(); +} - std::stringstream result; - state.dumpTraceAndState(result, false); - return result.str(); +void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, tools::interpreter::ExecutionResult res) +{ + _stream << "Execution result: "; + _stream << std::visit(GenericVisitor { + [&](ExecutionOk) { return "ExecutionOk"; }, + [&](ExecutionTerminated terminated) { + return std::visit(GenericVisitor{ + [&](ExplicitlyTerminated) { return "ExplicitlyTerminated"; }, + [&](ExplicitlyTerminatedWithReturn) { return "ExplicitlyTerminatedWithReturn"; }, + [&](StepLimitReached) { return "StepLimitReached"; }, + [&](RecursionDepthLimitReached) { return "RecursionDepthLimitReached"; }, + [&](ExpressionNestingLimitReached) { return "ExpressionNestingLimitReached"; }, + [&](ImpureBuiltinEncountered) { return "ImpureBuiltinEncountered"; }, + [&](UnlimitedLiteralEncountered) { return "UnlimitedLiteralEncountered"; } + }, terminated); + } + }, res); } diff --git a/test/libyul/YulPureInterpreterTest.h b/test/libyul/YulPureInterpreterTest.h index c1a757530343..d874d7464d99 100644 --- a/test/libyul/YulPureInterpreterTest.h +++ b/test/libyul/YulPureInterpreterTest.h @@ -21,6 +21,7 @@ #include #include +#include namespace solidity::yul { @@ -46,6 +47,7 @@ class YulPureInterpreterTest: public solidity::frontend::test::EVMVersionRestric private: bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted); std::string interpret(); + void dumpExecutionResult(std::ostream& _stream, tools::interpreter::ExecutionResult res); std::shared_ptr m_ast; std::shared_ptr m_analysisInfo; From 62c18967a55fc15faf487d288f8afdab0603095e Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sat, 28 Sep 2024 23:52:26 +0700 Subject: [PATCH 050/101] Make TraceLimitReached a ExecutionTerminated result again --- libyul/tools/interpreter/PureInterpreter.cpp | 6 +++-- .../tools/interpreter/PureInterpreterState.h | 14 +++++----- libyul/tools/interpreter/Results.h | 8 +++++- test/libyul/YulPureInterpreterTest.cpp | 27 ++++++++----------- 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index eaabdc575d1d..030a7370a97d 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -274,7 +274,8 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); - m_state.addTrace(fun, argsValues); + if (auto terminated = m_state.addTrace(fun, argsValues)) return *terminated; + ExecutionResult funcBodyRes = (*interpreter)(fun.body); if (auto* terminated = std::get_if(&funcBodyRes)) return *terminated; @@ -282,7 +283,8 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) returnedValues.reserve(fun.returnVariables.size()); for (auto const& retVar: fun.returnVariables) returnedValues.emplace_back(interpreter->valueOfVariable(retVar.name)); - m_state.addTrace(fun, returnedValues); + + if (auto terminated = m_state.addTrace(fun, returnedValues)) return *terminated; return EvaluationOk(std::move(returnedValues)); } diff --git a/libyul/tools/interpreter/PureInterpreterState.h b/libyul/tools/interpreter/PureInterpreterState.h index 86c8ba40245f..a9b98a30187d 100644 --- a/libyul/tools/interpreter/PureInterpreterState.h +++ b/libyul/tools/interpreter/PureInterpreterState.h @@ -18,9 +18,10 @@ #pragma once +#include + #include -#include #include #include @@ -30,10 +31,6 @@ namespace solidity::yul::tools::interpreter { -class TraceLimitReached: public util::Exception -{ -}; - struct FunctionCallTrace { FunctionDefinition const& definition; @@ -85,12 +82,13 @@ struct PureInterpreterState /// Will do nothing if config.maxTraceSize == 0 /// - the log entry will not be constructed in this case template - void addTrace(const Args&... args) + std::optional addTrace(const Args&... args) { - if (config.maxTraceSize == 0) return; + if (config.maxTraceSize == 0) return std::nullopt; if (traces.size() > config.maxTraceSize) - BOOST_THROW_EXCEPTION(TraceLimitReached()); + return TraceLimitReached(); traces.emplace_back(std::in_place_type, args...); + return std::nullopt; } void dumpTraces(std::ostream& _out) const; diff --git a/libyul/tools/interpreter/Results.h b/libyul/tools/interpreter/Results.h index f3e4b816a3ff..d4c0a94fdfaf 100644 --- a/libyul/tools/interpreter/Results.h +++ b/libyul/tools/interpreter/Results.h @@ -61,6 +61,11 @@ class UnlimitedLiteralEncountered : public ExecutionTerminatedCommon +{ +}; + + using ExecutionTerminated = std::variant< ExplicitlyTerminated, ExplicitlyTerminatedWithReturn, @@ -68,7 +73,8 @@ using ExecutionTerminated = std::variant< RecursionDepthLimitReached, ExpressionNestingLimitReached, ImpureBuiltinEncountered, - UnlimitedLiteralEncountered + UnlimitedLiteralEncountered, + TraceLimitReached >; enum class ControlFlowState diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index 851267006588..db2093d3ed36 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -95,23 +95,17 @@ bool YulPureInterpreterTest::parse(std::ostream& _stream, std::string const& _li std::string YulPureInterpreterTest::interpret() { - PureInterpreterState state { m_config }; - std::stringstream resultStream; - try - { - ExecutionResult res = PureInterpreter::run( - state, - EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()), - m_ast->root() - ); - dumpExecutionResult(resultStream, res); - } - catch (TraceLimitReached const&) - { - resultStream << "Trace limit reached!"; - } + + PureInterpreterState state { m_config }; + ExecutionResult res = PureInterpreter::run( + state, + EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()), + m_ast->root() + ); + dumpExecutionResult(resultStream, res); state.dumpTraces(resultStream); + return resultStream.str(); } @@ -128,7 +122,8 @@ void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, tools::i [&](RecursionDepthLimitReached) { return "RecursionDepthLimitReached"; }, [&](ExpressionNestingLimitReached) { return "ExpressionNestingLimitReached"; }, [&](ImpureBuiltinEncountered) { return "ImpureBuiltinEncountered"; }, - [&](UnlimitedLiteralEncountered) { return "UnlimitedLiteralEncountered"; } + [&](UnlimitedLiteralEncountered) { return "UnlimitedLiteralEncountered"; }, + [&](TraceLimitReached) { return "TraceLimitReached"; } }, terminated); } }, res); From a50e6b384b5428102c754f266cd6542977ca8b8f Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 10:21:45 +0700 Subject: [PATCH 051/101] Remove PureInterpreter.run method --- libyul/tools/interpreter/PureInterpreter.cpp | 10 ---------- libyul/tools/interpreter/PureInterpreter.h | 7 ------- 2 files changed, 17 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index 030a7370a97d..a31490c35797 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -43,16 +43,6 @@ using namespace solidity::yul::tools::interpreter; using solidity::util::h256; -ExecutionResult PureInterpreter::run( - PureInterpreterState& _state, - Dialect const& _dialect, - Block const& _ast -) -{ - Scope scope; - return PureInterpreter{_state, _dialect, scope, 0}(_ast); -} - ExecutionResult PureInterpreter::operator()(ExpressionStatement const& _expressionStatement) { EvaluationResult res = evaluate(_expressionStatement.expression, 0); diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/tools/interpreter/PureInterpreter.h index 92a1fcf62f32..2ba3e952d739 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -53,13 +53,6 @@ namespace solidity::yul::tools::interpreter class PureInterpreter { public: - /// Executes the Yul interpreter. - static ExecutionResult run( - PureInterpreterState& _state, - Dialect const& _dialect, - Block const& _ast - ); - PureInterpreter( PureInterpreterState& _state, Dialect const& _dialect, From 563cca273cdb87a28f235e7388da237c1b5641dc Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 10:50:36 +0700 Subject: [PATCH 052/101] Add function to get allVariables from interpreter --- libyul/tools/interpreter/PureInterpreter.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/tools/interpreter/PureInterpreter.h index 2ba3e952d739..c905fee9f3e5 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -99,6 +99,7 @@ class PureInterpreter EvaluationResult visit(Expression const& _st); u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } + VariableValuesMap const& allVariables() const { return m_variables; } protected: virtual std::unique_ptr makeInterpreterCopy(VariableValuesMap _variables = {}) const From 6c4c9756a33ebd51f85032288902e54103739ab8 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 10:51:41 +0700 Subject: [PATCH 053/101] Dump more data after interpreter --- test/libyul/YulPureInterpreterTest.cpp | 52 ++++++++++++++++++++++---- test/libyul/YulPureInterpreterTest.h | 12 +++++- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index db2093d3ed36..8a3f3ad42840 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -93,25 +93,51 @@ bool YulPureInterpreterTest::parse(std::ostream& _stream, std::string const& _li } } -std::string YulPureInterpreterTest::interpret() +std::string YulPureInterpreterTest::interpret() const { std::stringstream resultStream; + Block const& block = m_ast->root(); + PureInterpreterState state { m_config }; - ExecutionResult res = PureInterpreter::run( + Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()); + tools::interpreter::Scope rootScope; + tools::interpreter::Scope* subscope = rootScope.getSubscope(block); + + PureInterpreter interpreter(state, dialect, *subscope, 0); + ExecutionResult res = interpreter.execute(block.statements); + VariableValuesMap const& outterMostVariables = interpreter.allVariables(); + + dumpExecutionData( + resultStream, + res, state, - EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()), - m_ast->root() + outterMostVariables ); - dumpExecutionResult(resultStream, res); - state.dumpTraces(resultStream); return resultStream.str(); } -void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, tools::interpreter::ExecutionResult res) +void YulPureInterpreterTest::dumpExecutionData( + std::ostream& _stream, + tools::interpreter::ExecutionResult _res, + tools::interpreter::PureInterpreterState const& _state, + VariableValuesMap const& _outterMostVariables +) const { _stream << "Execution result: "; + dumpExecutionResult(_stream, _res); + _stream << std::endl; + + _stream << "Outter most variable values:" << std::endl; + dumpVariables(_stream, _outterMostVariables); + _stream << std::endl; + + _state.dumpTraces(_stream); +} + +void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, tools::interpreter::ExecutionResult _res) const +{ _stream << std::visit(GenericVisitor { [&](ExecutionOk) { return "ExecutionOk"; }, [&](ExecutionTerminated terminated) { @@ -126,5 +152,15 @@ void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, tools::i [&](TraceLimitReached) { return "TraceLimitReached"; } }, terminated); } - }, res); + }, _res); +} + +void YulPureInterpreterTest::dumpVariables( + std::ostream& _stream, + tools::interpreter::VariableValuesMap const& _variables +) const +{ + static std::string_view const INDENT = " "; + for (auto const& [name, value]: _variables) + _stream << INDENT << name.str() << " = " << value << std::endl; } diff --git a/test/libyul/YulPureInterpreterTest.h b/test/libyul/YulPureInterpreterTest.h index d874d7464d99..a5e123a7617f 100644 --- a/test/libyul/YulPureInterpreterTest.h +++ b/test/libyul/YulPureInterpreterTest.h @@ -21,6 +21,7 @@ #include #include +#include #include namespace solidity::yul @@ -46,8 +47,15 @@ class YulPureInterpreterTest: public solidity::frontend::test::EVMVersionRestric private: bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted); - std::string interpret(); - void dumpExecutionResult(std::ostream& _stream, tools::interpreter::ExecutionResult res); + std::string interpret() const; + void dumpExecutionData( + std::ostream& _stream, + tools::interpreter::ExecutionResult _res, + tools::interpreter::PureInterpreterState const& _state, + tools::interpreter::VariableValuesMap const& _outterMostVariables + ) const; + void dumpExecutionResult(std::ostream& _stream, tools::interpreter::ExecutionResult _res) const; + void dumpVariables(std::ostream& _stream, tools::interpreter::VariableValuesMap const& _variables) const; std::shared_ptr m_ast; std::shared_ptr m_analysisInfo; From cc68c2b9100726278f1499e15e6b5595e8e861cc Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 10:59:17 +0700 Subject: [PATCH 054/101] Register YulPureInterpreterTest --- test/InteractiveTests.h | 2 ++ test/tools/CMakeLists.txt | 1 + 2 files changed, 3 insertions(+) diff --git a/test/InteractiveTests.h b/test/InteractiveTests.h index e043fcdbe676..16399ca68042 100644 --- a/test/InteractiveTests.h +++ b/test/InteractiveTests.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,7 @@ Testsuite const g_interactiveTestsuites[] = { Title Path Subpath SMT NeedsVM Creator function */ {"Yul Optimizer", "libyul", "yulOptimizerTests", false, false, &yul::test::YulOptimizerTest::create}, {"Yul Interpreter", "libyul", "yulInterpreterTests", false, false, &yul::test::YulInterpreterTest::create}, + {"Yul Pure Interpreter", "libyul", "yulPureInterpreterTests", false, false, &yul::test::YulPureInterpreterTest::create}, {"Yul Object Compiler", "libyul", "objectCompiler", false, false, &yul::test::ObjectCompilerTest::create}, {"Yul Control Flow Graph", "libyul", "yulControlFlowGraph", false, false, &yul::test::ControlFlowGraphTest::create}, {"Yul SSA Control Flow Graph", "libyul", "yulSSAControlFlowGraph", false, false, &yul::test::SSAControlFlowGraphTest::create}, diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index 5c1d41b7f595..ad1f838d25d9 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -51,6 +51,7 @@ add_executable(isoltest ../libyul/YulOptimizerTest.cpp ../libyul/YulOptimizerTestCommon.cpp ../libyul/YulInterpreterTest.cpp + ../libyul/YulPureInterpreterTest.cpp ) target_compile_definitions(isoltest PRIVATE ISOLTEST) target_link_libraries(isoltest PRIVATE evmc libsolc solidity yulInterpreter evmasm Boost::boost Boost::program_options Boost::unit_test_framework Threads::Threads) From 7768be9e8040335e00024846bb78dc37d1ac2b81 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 15:18:01 +0700 Subject: [PATCH 055/101] Add hex printing and sort variable names --- test/libyul/YulPureInterpreterTest.cpp | 25 ++++++++++++++++++++++++- test/libyul/YulPureInterpreterTest.h | 3 +++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index 8a3f3ad42840..ad4629b6d619 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -45,6 +45,8 @@ using namespace solidity::yul::test; using namespace solidity::frontend; using namespace solidity::frontend::test; +using solidity::util::h256; + using namespace solidity::yul::tools::interpreter; YulPureInterpreterTest::YulPureInterpreterTest(std::string const& _filename): @@ -57,6 +59,8 @@ YulPureInterpreterTest::YulPureInterpreterTest(std::string const& _filename): m_config.maxExprNesting = m_reader.sizetSetting("maxExprNesting", 64); m_config.maxSteps = m_reader.sizetSetting("maxSteps", 512); m_config.maxRecursionDepth = m_reader.sizetSetting("maxRecursionDepth", 64); + + m_printHex = m_reader.boolSetting("printHex", false); } TestCase::TestResult YulPureInterpreterTest::run(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted) @@ -161,6 +165,25 @@ void YulPureInterpreterTest::dumpVariables( ) const { static std::string_view const INDENT = " "; + + // _variables are sorted by id. We should sort them by name + std::map sortedVariables; for (auto const& [name, value]: _variables) - _stream << INDENT << name.str() << " = " << value << std::endl; + sortedVariables[name.str()] = value; + + for (auto const& [name, value]: sortedVariables) + { + _stream << INDENT << name << " = "; + dumpValue(_stream, value); + _stream << std::endl; + } +} + +void YulPureInterpreterTest::dumpValue( + std::ostream& _stream, + u256 _value +) const +{ + if (m_printHex) _stream << "0x" << h256(_value).hex(); + else _stream << _value; } diff --git a/test/libyul/YulPureInterpreterTest.h b/test/libyul/YulPureInterpreterTest.h index a5e123a7617f..68e8d5f5a0ca 100644 --- a/test/libyul/YulPureInterpreterTest.h +++ b/test/libyul/YulPureInterpreterTest.h @@ -56,10 +56,13 @@ class YulPureInterpreterTest: public solidity::frontend::test::EVMVersionRestric ) const; void dumpExecutionResult(std::ostream& _stream, tools::interpreter::ExecutionResult _res) const; void dumpVariables(std::ostream& _stream, tools::interpreter::VariableValuesMap const& _variables) const; + void dumpValue(std::ostream& _stream, u256 _value) const; std::shared_ptr m_ast; std::shared_ptr m_analysisInfo; tools::interpreter::PureInterpreterConfig m_config; + + bool m_printHex; }; } From ba938920e0132678cfc0b2110d476cc56fd29d51 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 15:16:17 +0700 Subject: [PATCH 056/101] Filter and add existing interpreter tests to pure interpreterTest --- .../ambiguous_vars.yul | 19 ++++ .../bounded_recursion.yul | 21 ++++ test/libyul/yulPureInterpreterTests/exp.yul | 11 +++ .../expr_nesting_depth_exceeded.yul | 17 ++++ .../expr_nesting_depth_not_exceeded.yul | 18 ++++ .../function_calls.yul | 16 +++ .../function_scopes.yul | 39 ++++++++ .../yulPureInterpreterTests/hex_literals.yul | 13 +++ .../infinite_recursion.yul | 13 +++ .../infinite_recursion_tracelimit.yul | 26 +++++ test/libyul/yulPureInterpreterTests/leave.yul | 21 ++++ .../leave_for_init.yul | 18 ++++ test/libyul/yulPureInterpreterTests/loop.yul | 28 ++++++ .../pop_byte_shr_func.yul | 13 +++ .../yulPureInterpreterTests/recursion.yul | 97 +++++++++++++++++++ .../shadowed_symbol.yul | 22 +++++ test/libyul/yulPureInterpreterTests/smoke.yul | 6 ++ .../switch_statement.yul | 13 +++ 18 files changed, 411 insertions(+) create mode 100644 test/libyul/yulPureInterpreterTests/ambiguous_vars.yul create mode 100644 test/libyul/yulPureInterpreterTests/bounded_recursion.yul create mode 100644 test/libyul/yulPureInterpreterTests/exp.yul create mode 100644 test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul create mode 100644 test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul create mode 100644 test/libyul/yulPureInterpreterTests/function_calls.yul create mode 100644 test/libyul/yulPureInterpreterTests/function_scopes.yul create mode 100644 test/libyul/yulPureInterpreterTests/hex_literals.yul create mode 100644 test/libyul/yulPureInterpreterTests/infinite_recursion.yul create mode 100644 test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul create mode 100644 test/libyul/yulPureInterpreterTests/leave.yul create mode 100644 test/libyul/yulPureInterpreterTests/leave_for_init.yul create mode 100644 test/libyul/yulPureInterpreterTests/loop.yul create mode 100644 test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul create mode 100644 test/libyul/yulPureInterpreterTests/recursion.yul create mode 100644 test/libyul/yulPureInterpreterTests/shadowed_symbol.yul create mode 100644 test/libyul/yulPureInterpreterTests/smoke.yul create mode 100644 test/libyul/yulPureInterpreterTests/switch_statement.yul diff --git a/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul b/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul new file mode 100644 index 000000000000..54e749345ebd --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul @@ -0,0 +1,19 @@ +{ + function fake_mstore(pos, val) { } + { + let a := 0x20 + fake_mstore(a, 2) + } + let a + fake_mstore(a, 3) +} +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// a = 0 +// +// Call trace: +// [CALL] fake_mstore(32, 2) +// │ [RETURN] +// [CALL] fake_mstore(0, 3) +// │ [RETURN] diff --git a/test/libyul/yulPureInterpreterTests/bounded_recursion.yul b/test/libyul/yulPureInterpreterTests/bounded_recursion.yul new file mode 100644 index 000000000000..49ab91820ecf --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/bounded_recursion.yul @@ -0,0 +1,21 @@ +{ + function f(x) -> y { + if lt(x, 150) { + y := f(add(x, 1)) + } + if eq(x, 150) { + y := x + } + } + let res := f(0) +} + +// ==== +// maxRecursionDepth: 160 +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// res = 150 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/exp.yul b/test/libyul/yulPureInterpreterTests/exp.yul new file mode 100644 index 000000000000..25a6337ee5bc --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/exp.yul @@ -0,0 +1,11 @@ +{ + let res := exp(3,not(1)) +} +// ==== +// printHex: true +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// res = 0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e39 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul new file mode 100644 index 000000000000..4b934248b845 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul @@ -0,0 +1,17 @@ +{ + function f(x) -> y + { + // 32 nested additions are computed in + // exactly 66 expression evaluation steps + y := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,x)))))))))))))))))))))))))))))))) + } + pop(f(0)) +} +// ==== +// maxExprNesting: 64 +// ---- +// Execution result: ExpressionNestingLimitReached +// Outter most variable values: +// +// Call trace: +// [CALL] f(0) diff --git a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul new file mode 100644 index 000000000000..837e767a7070 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul @@ -0,0 +1,18 @@ +{ + function f(x) -> y + { + // 31 nested additions are computed in + // exactly 64 expression evaluation steps + y := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,x))))))))))))))))))))))))))))))) + } + pop(f(0)) +} +// ==== +// maxExprNesting: 64 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: +// [CALL] f(0) +// │ [RETURN] 31 diff --git a/test/libyul/yulPureInterpreterTests/function_calls.yul b/test/libyul/yulPureInterpreterTests/function_calls.yul new file mode 100644 index 000000000000..c9a2e9b32126 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/function_calls.yul @@ -0,0 +1,16 @@ +{ + function f(a, b) -> x, y { + x := add(a, b) + y := mul(a, b) + } + let r, t := f(6, 7) +} +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// r = 13 +// t = 42 +// +// Call trace: +// [CALL] f(6, 7) +// │ [RETURN] 13, 42 diff --git a/test/libyul/yulPureInterpreterTests/function_scopes.yul b/test/libyul/yulPureInterpreterTests/function_scopes.yul new file mode 100644 index 000000000000..7d3768d19cda --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/function_scopes.yul @@ -0,0 +1,39 @@ +{ + function fake_sstore(pos, val) {} + + f(1) + function f(i) { + if i { g(1) } + function g(j) { + if j { h() } + f(0) + function h() { + g(0) + } + } + fake_sstore(i, add(i, 7)) + } +} +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: +// [CALL] f(1) +// │ [CALL] g(1) +// │ │ [CALL] h() +// │ │ │ [CALL] g(0) +// │ │ │ │ [CALL] f(0) +// │ │ │ │ │ [CALL] fake_sstore(0, 7) +// │ │ │ │ │ │ [RETURN] +// │ │ │ │ │ [RETURN] +// │ │ │ │ [RETURN] +// │ │ │ [RETURN] +// │ │ [CALL] f(0) +// │ │ │ [CALL] fake_sstore(0, 7) +// │ │ │ │ [RETURN] +// │ │ │ [RETURN] +// │ │ [RETURN] +// │ [CALL] fake_sstore(1, 8) +// │ │ [RETURN] +// │ [RETURN] diff --git a/test/libyul/yulPureInterpreterTests/hex_literals.yul b/test/libyul/yulPureInterpreterTests/hex_literals.yul new file mode 100644 index 000000000000..ca85bdde4aac --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/hex_literals.yul @@ -0,0 +1,13 @@ +{ + let x := hex"112233445566778899aabbccddeeff6677889900" + let y := hex"1234_abcd" +} +// ==== +// printHex: true +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// x = 0x112233445566778899aabbccddeeff6677889900000000000000000000000000 +// y = 0x1234abcd00000000000000000000000000000000000000000000000000000000 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/infinite_recursion.yul b/test/libyul/yulPureInterpreterTests/infinite_recursion.yul new file mode 100644 index 000000000000..9ad3d966f284 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/infinite_recursion.yul @@ -0,0 +1,13 @@ +{ + function f() { + f() + } + f() +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: RecursionDepthLimitReached +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul b/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul new file mode 100644 index 000000000000..4f5e3f27cf83 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul @@ -0,0 +1,26 @@ +{ + function f() { + f() + } + f() +} +// Setting so that trace limit hit first +// ==== +// maxRecursionDepth: 1000 +// maxTraceSize: 10 +// ---- +// Execution result: TraceLimitReached +// Outter most variable values: +// +// Call trace: +// [CALL] f() +// │ [CALL] f() +// │ │ [CALL] f() +// │ │ │ [CALL] f() +// │ │ │ │ [CALL] f() +// │ │ │ │ │ [CALL] f() +// │ │ │ │ │ │ [CALL] f() +// │ │ │ │ │ │ │ [CALL] f() +// │ │ │ │ │ │ │ │ [CALL] f() +// │ │ │ │ │ │ │ │ │ [CALL] f() +// │ │ │ │ │ │ │ │ │ │ [CALL] f() diff --git a/test/libyul/yulPureInterpreterTests/leave.yul b/test/libyul/yulPureInterpreterTests/leave.yul new file mode 100644 index 000000000000..743837bba805 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/leave.yul @@ -0,0 +1,21 @@ +{ + function f() -> x, y + { + for { x := 0 } lt(x, 10) { x := add(x, 1) } { + if eq(x, 5) { y := 1 leave } + } + x := 9 + } + let a, b := f() +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// a = 5 +// b = 1 +// +// Call trace: +// [CALL] f() +// │ [RETURN] 5, 1 diff --git a/test/libyul/yulPureInterpreterTests/leave_for_init.yul b/test/libyul/yulPureInterpreterTests/leave_for_init.yul new file mode 100644 index 000000000000..ad237897831a --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/leave_for_init.yul @@ -0,0 +1,18 @@ +{ + function f() -> x + { + for { leave x := 2 } eq(x, 0) { } { + } + } + let a := f() +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// a = 0 +// +// Call trace: +// [CALL] f() +// │ [RETURN] 0 diff --git a/test/libyul/yulPureInterpreterTests/loop.yul b/test/libyul/yulPureInterpreterTests/loop.yul new file mode 100644 index 000000000000..ab0d330efbd4 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/loop.yul @@ -0,0 +1,28 @@ +{ + function fake_mstore(pos, val) {} + + for { let x := 2 } lt(x, 10) { x := add(x, 1) } { + fake_mstore(mul(x, 5), mul(x, 0x1000)) + } +} +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: +// [CALL] fake_mstore(10, 8192) +// │ [RETURN] +// [CALL] fake_mstore(15, 12288) +// │ [RETURN] +// [CALL] fake_mstore(20, 16384) +// │ [RETURN] +// [CALL] fake_mstore(25, 20480) +// │ [RETURN] +// [CALL] fake_mstore(30, 24576) +// │ [RETURN] +// [CALL] fake_mstore(35, 28672) +// │ [RETURN] +// [CALL] fake_mstore(40, 32768) +// │ [RETURN] +// [CALL] fake_mstore(45, 36864) +// │ [RETURN] diff --git a/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul b/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul new file mode 100644 index 000000000000..833e4c2bfa79 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul @@ -0,0 +1,13 @@ +{ + function f() -> x { x := 0x1337 } + pop(byte(0, shr(0x8, f()))) +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: +// [CALL] f() +// │ [RETURN] 4919 diff --git a/test/libyul/yulPureInterpreterTests/recursion.yul b/test/libyul/yulPureInterpreterTests/recursion.yul new file mode 100644 index 000000000000..1e5670caaff9 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/recursion.yul @@ -0,0 +1,97 @@ +{ + function fib(i) -> y { + y := 1 + if gt(i, 2) { + y := add(fib(sub(i, 1)), fib(sub(i, 2))) + } + } + let res := fib(8) +} +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// res = 21 +// +// Call trace: +// [CALL] fib(8) +// │ [CALL] fib(6) +// │ │ [CALL] fib(4) +// │ │ │ [CALL] fib(2) +// │ │ │ │ [RETURN] 1 +// │ │ │ [CALL] fib(3) +// │ │ │ │ [CALL] fib(1) +// │ │ │ │ │ [RETURN] 1 +// │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ [RETURN] 1 +// │ │ │ │ [RETURN] 2 +// │ │ │ [RETURN] 3 +// │ │ [CALL] fib(5) +// │ │ │ [CALL] fib(3) +// │ │ │ │ [CALL] fib(1) +// │ │ │ │ │ [RETURN] 1 +// │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ [RETURN] 1 +// │ │ │ │ [RETURN] 2 +// │ │ │ [CALL] fib(4) +// │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ [RETURN] 1 +// │ │ │ │ [CALL] fib(3) +// │ │ │ │ │ [CALL] fib(1) +// │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ [RETURN] 2 +// │ │ │ │ [RETURN] 3 +// │ │ │ [RETURN] 5 +// │ │ [RETURN] 8 +// │ [CALL] fib(7) +// │ │ [CALL] fib(5) +// │ │ │ [CALL] fib(3) +// │ │ │ │ [CALL] fib(1) +// │ │ │ │ │ [RETURN] 1 +// │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ [RETURN] 1 +// │ │ │ │ [RETURN] 2 +// │ │ │ [CALL] fib(4) +// │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ [RETURN] 1 +// │ │ │ │ [CALL] fib(3) +// │ │ │ │ │ [CALL] fib(1) +// │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ [RETURN] 2 +// │ │ │ │ [RETURN] 3 +// │ │ │ [RETURN] 5 +// │ │ [CALL] fib(6) +// │ │ │ [CALL] fib(4) +// │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ [RETURN] 1 +// │ │ │ │ [CALL] fib(3) +// │ │ │ │ │ [CALL] fib(1) +// │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ [RETURN] 2 +// │ │ │ │ [RETURN] 3 +// │ │ │ [CALL] fib(5) +// │ │ │ │ [CALL] fib(3) +// │ │ │ │ │ [CALL] fib(1) +// │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ [RETURN] 2 +// │ │ │ │ [CALL] fib(4) +// │ │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ [CALL] fib(3) +// │ │ │ │ │ │ [CALL] fib(1) +// │ │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ │ [CALL] fib(2) +// │ │ │ │ │ │ │ [RETURN] 1 +// │ │ │ │ │ │ [RETURN] 2 +// │ │ │ │ │ [RETURN] 3 +// │ │ │ │ [RETURN] 5 +// │ │ │ [RETURN] 8 +// │ │ [RETURN] 13 +// │ [RETURN] 21 diff --git a/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul b/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul new file mode 100644 index 000000000000..d658c8f53112 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul @@ -0,0 +1,22 @@ +{ + function f() + { + // Variable declaration does not shadow namesake function declaration + // because latter not visible here. + let shadow_id + } + { + // Function named `shadow_id` is in scope now. + f() + function shadow_id() {} + } +} +// ==== +// EVMVersion: >=constantinople +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: +// [CALL] f() +// │ [RETURN] diff --git a/test/libyul/yulPureInterpreterTests/smoke.yul b/test/libyul/yulPureInterpreterTests/smoke.yul new file mode 100644 index 000000000000..5e5c27965d25 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/smoke.yul @@ -0,0 +1,6 @@ +{} +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/switch_statement.yul b/test/libyul/yulPureInterpreterTests/switch_statement.yul new file mode 100644 index 000000000000..368118277fa9 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/switch_statement.yul @@ -0,0 +1,13 @@ +{ + let x + switch 7 + case 7 { x := 1 } + case 3 { x := 2 } + default { x := 3 } +} +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// x = 1 +// +// Call trace: From 3a08b5e29368299fa5aa0259bb2cbed3834fa00d Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 15:57:10 +0700 Subject: [PATCH 057/101] Add tests for all impure instructions --- .../impure_instructions/address.yul | 12 ++++++++++++ .../impure_instructions/balance.yul | 13 +++++++++++++ .../impure_instructions/basefee.yul | 12 ++++++++++++ .../impure_instructions/blobbasefee.yul | 12 ++++++++++++ .../impure_instructions/blobhash.yul | 12 ++++++++++++ .../impure_instructions/blockhash.yul | 12 ++++++++++++ .../impure_instructions/call.yul | 12 ++++++++++++ .../impure_instructions/callcode.yul | 12 ++++++++++++ .../impure_instructions/calldatacopy.yul | 12 ++++++++++++ .../impure_instructions/calldataload.yul | 12 ++++++++++++ .../impure_instructions/calldatasize.yul | 12 ++++++++++++ .../impure_instructions/caller.yul | 12 ++++++++++++ .../impure_instructions/callvalue.yul | 12 ++++++++++++ .../impure_instructions/chainid.yul | 12 ++++++++++++ .../impure_instructions/codecopy.yul | 12 ++++++++++++ .../impure_instructions/codesize.yul | 12 ++++++++++++ .../impure_instructions/coinbase.yul | 12 ++++++++++++ .../impure_instructions/create.yul | 12 ++++++++++++ .../impure_instructions/create2.yul | 12 ++++++++++++ .../impure_instructions/delegatecall.yul | 12 ++++++++++++ .../impure_instructions/extcodecopy.yul | 12 ++++++++++++ .../impure_instructions/extcodehash.yul | 12 ++++++++++++ .../impure_instructions/extcodesize.yul | 12 ++++++++++++ .../impure_instructions/gas.yul | 12 ++++++++++++ .../impure_instructions/gaslimit.yul | 12 ++++++++++++ .../impure_instructions/gasprice.yul | 12 ++++++++++++ .../impure_instructions/invalid.yul | 12 ++++++++++++ .../impure_instructions/keccak256.yul | 12 ++++++++++++ .../impure_instructions/log0.yul | 12 ++++++++++++ .../impure_instructions/log1.yul | 12 ++++++++++++ .../impure_instructions/log2.yul | 12 ++++++++++++ .../impure_instructions/log3.yul | 12 ++++++++++++ .../impure_instructions/log4.yul | 12 ++++++++++++ .../impure_instructions/mcopy.yul | 12 ++++++++++++ .../impure_instructions/mload.yul | 12 ++++++++++++ .../impure_instructions/msize.yul | 12 ++++++++++++ .../impure_instructions/mstore.yul | 12 ++++++++++++ .../impure_instructions/mstore8.yul | 12 ++++++++++++ .../impure_instructions/number.yul | 12 ++++++++++++ .../impure_instructions/origin.yul | 12 ++++++++++++ .../impure_instructions/prevrandao.yul | 12 ++++++++++++ .../impure_instructions/return.yul | 12 ++++++++++++ .../impure_instructions/returndatacopy.yul | 12 ++++++++++++ .../impure_instructions/returndatasize.yul | 12 ++++++++++++ .../impure_instructions/revert.yul | 12 ++++++++++++ .../impure_instructions/selfbalance.yul | 12 ++++++++++++ .../impure_instructions/selfdestruct.yul | 12 ++++++++++++ .../impure_instructions/sload.yul | 12 ++++++++++++ .../impure_instructions/sstore.yul | 12 ++++++++++++ .../impure_instructions/staticcall.yul | 12 ++++++++++++ .../impure_instructions/timestamp.yul | 12 ++++++++++++ .../impure_instructions/tload.yul | 12 ++++++++++++ .../impure_instructions/tstore.yul | 12 ++++++++++++ 53 files changed, 637 insertions(+) create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/address.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/balance.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/blockhash.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/call.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/callcode.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/calldatacopy.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/calldataload.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/calldatasize.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/caller.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/callvalue.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/codecopy.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/codesize.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/coinbase.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/create.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/delegatecall.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/extcodecopy.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/extcodesize.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/gas.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/gaslimit.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/gasprice.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/invalid.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/keccak256.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/log0.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/log1.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/log2.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/log3.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/log4.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/mload.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/msize.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/mstore.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/mstore8.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/number.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/origin.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/return.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/revert.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/selfdestruct.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/sload.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/sstore.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/timestamp.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/address.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/address.yul new file mode 100644 index 000000000000..85f453227f1e --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/address.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(address()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/balance.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/balance.yul new file mode 100644 index 000000000000..343c777c168d --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/balance.yul @@ -0,0 +1,13 @@ +{ + let x + x := 1 + pop(balance(0)) + x := 2 +} + +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul new file mode 100644 index 000000000000..9f0825bbd412 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(basefee()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul new file mode 100644 index 000000000000..9477ba9fe89c --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(blobbasefee()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul new file mode 100644 index 000000000000..187c54071c4c --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(blobhash(0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/blockhash.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/blockhash.yul new file mode 100644 index 000000000000..b3f078952b71 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/blockhash.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(blockhash(0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/call.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/call.yul new file mode 100644 index 000000000000..5346b910e010 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/call.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(call(0, 0, 0, 0, 0, 0, 0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/callcode.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/callcode.yul new file mode 100644 index 000000000000..489430a97749 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/callcode.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(callcode(0, 0, 0, 0, 0, 0, 0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/calldatacopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/calldatacopy.yul new file mode 100644 index 000000000000..1f8d66b07e44 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/calldatacopy.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + calldatacopy(0, 0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/calldataload.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/calldataload.yul new file mode 100644 index 000000000000..ed682252efda --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/calldataload.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(calldataload(0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/calldatasize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/calldatasize.yul new file mode 100644 index 000000000000..f33f3506704b --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/calldatasize.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(calldatasize()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/caller.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/caller.yul new file mode 100644 index 000000000000..09dfea15762e --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/caller.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(caller()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/callvalue.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/callvalue.yul new file mode 100644 index 000000000000..a9331db9ee30 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/callvalue.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(callvalue()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul new file mode 100644 index 000000000000..cdb6f3d5d50f --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(chainid()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/codecopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/codecopy.yul new file mode 100644 index 000000000000..c1ffaaefd140 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/codecopy.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + codecopy(0, 0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/codesize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/codesize.yul new file mode 100644 index 000000000000..c9327400fb01 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/codesize.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(codesize()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/coinbase.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/coinbase.yul new file mode 100644 index 000000000000..2d00acf9936d --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/coinbase.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(coinbase()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/create.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/create.yul new file mode 100644 index 000000000000..b4637db2e0fa --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/create.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(create(0, 0, 0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul new file mode 100644 index 000000000000..b008705e817c --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(create2(0, 0, 0, 0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/delegatecall.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/delegatecall.yul new file mode 100644 index 000000000000..e336b215ad53 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/delegatecall.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(delegatecall(0, 0, 0, 0, 0, 0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodecopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodecopy.yul new file mode 100644 index 000000000000..70a99ced2059 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodecopy.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + extcodecopy(0, 0, 0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul new file mode 100644 index 000000000000..6b8f893e2bf3 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(extcodehash(0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodesize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodesize.yul new file mode 100644 index 000000000000..25ac2437e092 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodesize.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(extcodesize(0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/gas.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/gas.yul new file mode 100644 index 000000000000..96ab94aca8c8 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/gas.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(gas()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/gaslimit.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/gaslimit.yul new file mode 100644 index 000000000000..ee89b9542ff5 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/gaslimit.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(gaslimit()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/gasprice.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/gasprice.yul new file mode 100644 index 000000000000..cc3ceb842ce5 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/gasprice.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(gasprice()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/invalid.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/invalid.yul new file mode 100644 index 000000000000..d2dec601bb31 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/invalid.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + invalid() + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/keccak256.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/keccak256.yul new file mode 100644 index 000000000000..d4c39c1e6ef9 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/keccak256.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(keccak256(0, 0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/log0.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/log0.yul new file mode 100644 index 000000000000..b0b6f995f839 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/log0.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + log0(0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/log1.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/log1.yul new file mode 100644 index 000000000000..b23f79da5a3c --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/log1.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + log1(0, 0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/log2.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/log2.yul new file mode 100644 index 000000000000..b59dce457496 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/log2.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + log2(0, 0, 0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/log3.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/log3.yul new file mode 100644 index 000000000000..1acf5915e3d9 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/log3.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + log3(0, 0, 0, 0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/log4.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/log4.yul new file mode 100644 index 000000000000..882f1ee64892 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/log4.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + log4(0, 0, 0, 0, 0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul new file mode 100644 index 000000000000..78146c5656df --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + mcopy(0, 0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/mload.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/mload.yul new file mode 100644 index 000000000000..bb39322ac2a0 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/mload.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(mload(0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/msize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/msize.yul new file mode 100644 index 000000000000..1d2c0329558e --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/msize.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(msize()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/mstore.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/mstore.yul new file mode 100644 index 000000000000..b9a5a0581b91 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/mstore.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + mstore(0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/mstore8.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/mstore8.yul new file mode 100644 index 000000000000..95420fdfa978 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/mstore8.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + mstore8(0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/number.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/number.yul new file mode 100644 index 000000000000..20694912ee50 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/number.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(number()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/origin.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/origin.yul new file mode 100644 index 000000000000..72230c8caa99 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/origin.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(origin()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul new file mode 100644 index 000000000000..ea6ec685c757 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(prevrandao()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/return.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/return.yul new file mode 100644 index 000000000000..dae8d649a4e1 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/return.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + return(0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul new file mode 100644 index 000000000000..59d0c5dd144b --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + returndatacopy(0, 0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul new file mode 100644 index 000000000000..3f274cfb8db9 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(returndatasize()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/revert.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/revert.yul new file mode 100644 index 000000000000..76f38d5782e8 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/revert.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + revert(0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul new file mode 100644 index 000000000000..080742b798eb --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(selfbalance()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/selfdestruct.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/selfdestruct.yul new file mode 100644 index 000000000000..e072b95c0e8b --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/selfdestruct.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + selfdestruct(0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/sload.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/sload.yul new file mode 100644 index 000000000000..5fb2cba5e9d1 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/sload.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(sload(0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/sstore.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/sstore.yul new file mode 100644 index 000000000000..a0f641445dc7 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/sstore.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + sstore(0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul new file mode 100644 index 000000000000..7677738e89a4 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(staticcall(0, 0, 0, 0, 0, 0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/timestamp.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/timestamp.yul new file mode 100644 index 000000000000..a558b5000d54 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/timestamp.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(timestamp()) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul new file mode 100644 index 000000000000..1cfd3a4b4cdf --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + pop(tload(0)) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul new file mode 100644 index 000000000000..7de0654c7cab --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul @@ -0,0 +1,12 @@ +{ + let x + x := 1 + tstore(0, 0) + x := 2 +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: From 96db37355ac59e66c9f69c660835742305b5db2b Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 16:36:33 +0700 Subject: [PATCH 058/101] Add test for all pure instructions --- .../pure_instructions/.generate-test.py | 174 ++++++++++++++++++ .../pure_instructions/add.yul | 77 ++++++++ .../pure_instructions/addmod.yul | 77 ++++++++ .../pure_instructions/and.yul | 77 ++++++++ .../pure_instructions/byte.yul | 62 +++++++ .../pure_instructions/div.yul | 77 ++++++++ .../pure_instructions/eq.yul | 77 ++++++++ .../pure_instructions/exp.yul | 77 ++++++++ .../pure_instructions/gt.yul | 77 ++++++++ .../pure_instructions/iszero.yul | 24 +++ .../pure_instructions/lt.yul | 77 ++++++++ .../pure_instructions/mod.yul | 77 ++++++++ .../pure_instructions/mul.yul | 77 ++++++++ .../pure_instructions/mulmod.yul | 77 ++++++++ .../pure_instructions/not.yul | 24 +++ .../pure_instructions/or.yul | 77 ++++++++ .../pure_instructions/sar.yul | 77 ++++++++ .../pure_instructions/sdiv.yul | 77 ++++++++ .../pure_instructions/sgt.yul | 77 ++++++++ .../pure_instructions/shl.yul | 77 ++++++++ .../pure_instructions/shr.yul | 77 ++++++++ .../pure_instructions/signextend.yul | 77 ++++++++ .../pure_instructions/slt.yul | 77 ++++++++ .../pure_instructions/smod.yul | 77 ++++++++ .../pure_instructions/sub.yul | 77 ++++++++ .../pure_instructions/xor.yul | 77 ++++++++ 26 files changed, 1978 insertions(+) create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/add.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/and.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/div.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/not.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/or.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul create mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py new file mode 100644 index 000000000000..45fe68eae109 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py @@ -0,0 +1,174 @@ +# pyright: strict + +from itertools import product +import random +import os + +from typing import Callable, Iterable, Union + +os.chdir(os.path.dirname(os.path.abspath(__file__))) + +random.seed(20240823) + +MX = 2**256 + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test(fn_name: str, *, param_cnt: int, calc: Callable[[tuple[int, ...]], int], test_numbers: Union[Iterable[int], None] = None): + print('Generating test for', fn_name) + + src: list[str] = [] + src.append('{') + src.append(""" + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + """) + + if test_numbers is None: + if param_cnt == 1: + test_numbers = [ + 0, 1, 2, 3, + MX - 1, MX - 2, MX - 3, + random.randrange(MX), random.randrange(MX), random.randrange(MX), random.randrange(MX) + ] + else: + test_numbers = [0, 1, 2, MX - 1, MX - 2, random.randrange(MX), random.randrange(MX), random.randrange(MX)] + + param_set = list(product(test_numbers, repeat=param_cnt)) + + for p in param_set: + res = u256(calc(p)) + # printing hex to save space + src.append(f' check({fn_name}({', '.join(hex(i) for i in p)}), {hex(res)})') + src.append('}') + + src.append('// ====') + src.append('// maxTraceSize: 0') + + with open(fn_name + '.yul', 'w') as f: + print('\n'.join(src), file=f) + +def main(): + gen_test('add', + param_cnt = 2, + calc = lambda p: p[0] + p[1]) + gen_test('mul', + param_cnt = 2, + calc = lambda p: p[0] * p[1]) + gen_test('sub', + param_cnt = 2, + calc = lambda p: p[0] - p[1]) + gen_test('div', + param_cnt = 2, + calc = lambda p: p[0] // p[1] if p[1] != 0 else 0) + gen_test('sdiv', + param_cnt = 2, + calc = signed_div) + gen_test('mod', + param_cnt = 2, + calc = lambda p: p[0] % p[1] if p[1] != 0 else 0) + gen_test('smod', + param_cnt = 2, + calc = signed_mod) + gen_test('exp', + param_cnt = 2, + calc = lambda p: pow(p[0], p[1], MX)) + gen_test('not', + param_cnt = 1, + calc = lambda p: ~p[0]) + gen_test('lt', + param_cnt = 2, + calc = lambda p: p[0] < p[1]) + gen_test('gt', + param_cnt = 2, + calc = lambda p: p[0] > p[1]) + gen_test('slt', + param_cnt = 2, + calc = lambda p: u2s(p[0]) < u2s(p[1])) + gen_test('sgt', + param_cnt = 2, + calc = lambda p: u2s(p[0]) > u2s(p[1])) + gen_test('eq', + param_cnt = 2, + calc = lambda p: p[0] == p[1]) + gen_test('iszero', + param_cnt = 1, + calc = lambda p: p[0] == 0) + gen_test('and', + param_cnt = 2, + calc=lambda p: p[0] & p[1]) + gen_test('or', + param_cnt = 2, + calc = lambda p: p[0] | p[1]) + gen_test('xor', + param_cnt = 2, + calc = lambda p: p[0] ^ p[1]) + gen_test('byte', + param_cnt = 2, + test_numbers = [ + random.randrange(MX), random.randrange(MX), random.randrange(MX), + random.randrange(1, 32), random.randrange(1, 32), random.randrange(1, 32), + 0 + ], + calc = lambda p: 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xff) + gen_test('shl', + param_cnt = 2, + calc = lambda p: p[1] << p[0] if p[0] < 32 else 0) + gen_test('shr', + param_cnt = 2, + calc = lambda p: p[1] >> p[0]) + gen_test('sar', + param_cnt = 2, + calc = sar) + gen_test('addmod', + param_cnt = 3, + test_numbers = [random.randrange(0, MX) for _ in range(3)] + [0], + calc = lambda p: (p[0] + p[1]) % p[2] if p[2] != 0 else 0) + gen_test('mulmod', + param_cnt = 3, + test_numbers = [random.randrange(0, MX) for _ in range(3)] + [0], + calc = lambda p: (p[0] * p[1]) % p[2] if p[2] != 0 else 0) + gen_test('signextend', + param_cnt = 2, + calc = signextend) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res + +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +if __name__ == '__main__': + main() diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul new file mode 100644 index 000000000000..4934b62ca2a3 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(add(0x0, 0x0), 0x0) + check(add(0x0, 0x1), 0x1) + check(add(0x0, 0x2), 0x2) + check(add(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(add(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(add(0x0, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e) + check(add(0x0, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb) + check(add(0x0, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574) + check(add(0x1, 0x0), 0x1) + check(add(0x1, 0x1), 0x2) + check(add(0x1, 0x2), 0x3) + check(add(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(add(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(add(0x1, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398f) + check(add(0x1, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efc) + check(add(0x1, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e575) + check(add(0x2, 0x0), 0x2) + check(add(0x2, 0x1), 0x3) + check(add(0x2, 0x2), 0x4) + check(add(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(add(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(add(0x2, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b33990) + check(add(0x2, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efd) + check(add(0x2, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e576) + check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) + check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398d) + check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efa) + check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e573) + check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398c) + check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1ef9) + check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e572) + check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x0), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e) + check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x1), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398f) + check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x2), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b33990) + check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398d) + check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398c) + check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x638a6e388cf11081b2e62616b8e3be4be4c12052e95614e3b93cdd8fcf66731c) + check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x5d3c3368d3cf1ddc8a0e4036f8c137f37e47783e6633e6b6deff48a54e0d5889) + check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x7fb80915e27333205ab37631d761b147aef85386ae437f3bc7162eaebf7b1f02) + check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x0), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb) + check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x1), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efc) + check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x2), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efd) + check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efa) + check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1ef9) + check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x5d3c3368d3cf1ddc8a0e4036f8c137f37e47783e6633e6b6deff48a54e0d5889) + check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x56edf8991aad2b3761365a57389eb19b17cdd029e311b88a04c1b3baccb43df6) + check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x7969ce462951407b31db9052173f2aef487eab722b21510eecd899c43e22046f) + check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x0), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574) + check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x1), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e575) + check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x2), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e576) + check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e573) + check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e572) + check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x7fb80915e27333205ab37631d761b147aef85386ae437f3bc7162eaebf7b1f02) + check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x7969ce462951407b31db9052173f2aef487eab722b21510eecd899c43e22046f) + check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x9be5a3f337f555bf0280c64cf5dfa443792f86ba7330e993d4ef7fcdaf8fcae8) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul new file mode 100644 index 000000000000..84e60a296359 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x0) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x65d1cf826d6464457ae01220a0b5fdf6b37c83bec35900b77d52b314abe9e47e) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x369f68bf83db6415dd647089401beb7bbe37d9e8ea95ec53050df3454fd8ba3f) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0), 0x0) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x32c0ed0fcae805766b9849917b7ea7f8606d2e93dcddad9076fbd6f717139e56) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x696055cf4ec3698c48fcba1abb9a93741ea5087cc77399e37c09ca3c66ec5895) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0), 0x0) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x61f353d2b47105a60913eb28dc18ba7355b1d869b5a0c1f4ef4096c67324c895) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0xc7c5235521d569eb83f3fd497cceb86a092e5c2878f9c2ac6c9349db1f0ead13) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0), 0x0) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x0) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0, 0x0), 0x0) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x32c0ed0fcae805766b9849917b7ea7f8606d2e93dcddad9076fbd6f717139e56) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x696055cf4ec3698c48fcba1abb9a93741ea5087cc77399e37c09ca3c66ec5895) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0), 0x0) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x6581da1f95d00aecd7309322f6fd4ff0c0da5d27b9bb5b20edf7adee2e273cac) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x0) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x9c2142df19ab6f02b49503ac37193b6c7f123710a4514773f305a1337dfff6eb) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0), 0x0) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x94b440e27f590b1c74ac34ba5797626bb61f06fd927e6f85663c6dbd8a3866eb) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x2f3266c2e989002f9d7ba197609a127af544a9d5d8c314647844bfcf5c112a3f) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0), 0x0) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x32c0ed0fcae805766b9849917b7ea7f8606d2e93dcddad9076fbd6f717139e56) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x0) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a) + check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0, 0x0), 0x0) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x61f353d2b47105a60913eb28dc18ba7355b1d869b5a0c1f4ef4096c67324c895) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0xc7c5235521d569eb83f3fd497cceb86a092e5c2878f9c2ac6c9349db1f0ead13) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0), 0x0) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x94b440e27f590b1c74ac34ba5797626bb61f06fd927e6f85663c6dbd8a3866eb) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x2f3266c2e989002f9d7ba197609a127af544a9d5d8c314647844bfcf5c112a3f) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0), 0x0) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x2b53eb133095a1902baf7a9f9bfccef79779fe80cb0ad5a1ea32a381234c0e56) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x5e64cd85d312005f3af7432ec13424f5ea8953abb18628c8f0897f9eb822547e) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x0) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0), 0x0) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x61f353d2b47105a60913eb28dc18ba7355b1d869b5a0c1f4ef4096c67324c895) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x2f3266c2e989002f9d7ba197609a127af544a9d5d8c314647844bfcf5c112a3f) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x0) + check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0, 0x0), 0x0) + check(addmod(0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x0) + check(addmod(0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) + check(addmod(0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) + check(addmod(0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0), 0x0) + check(addmod(0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x32c0ed0fcae805766b9849917b7ea7f8606d2e93dcddad9076fbd6f717139e56) + check(addmod(0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x0) + check(addmod(0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a) + check(addmod(0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0), 0x0) + check(addmod(0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x61f353d2b47105a60913eb28dc18ba7355b1d869b5a0c1f4ef4096c67324c895) + check(addmod(0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x2f3266c2e989002f9d7ba197609a127af544a9d5d8c314647844bfcf5c112a3f) + check(addmod(0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x0) + check(addmod(0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0), 0x0) + check(addmod(0x0, 0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x0) + check(addmod(0x0, 0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x0) + check(addmod(0x0, 0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x0) + check(addmod(0x0, 0x0, 0x0), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul new file mode 100644 index 000000000000..c884d6de84c1 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(and(0x0, 0x0), 0x0) + check(and(0x0, 0x1), 0x0) + check(and(0x0, 0x2), 0x0) + check(and(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(and(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(and(0x0, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0x0) + check(and(0x0, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0x0) + check(and(0x0, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0x0) + check(and(0x1, 0x0), 0x0) + check(and(0x1, 0x1), 0x1) + check(and(0x1, 0x2), 0x0) + check(and(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(and(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(and(0x1, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0x0) + check(and(0x1, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0x1) + check(and(0x1, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0x1) + check(and(0x2, 0x0), 0x0) + check(and(0x2, 0x1), 0x0) + check(and(0x2, 0x2), 0x2) + check(and(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) + check(and(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) + check(and(0x2, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0x2) + check(and(0x2, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0x0) + check(and(0x2, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0x2) + check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) + check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x2) + check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) + check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) + check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) + check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x2) + check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) + check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da70) + check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44ba) + check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0x0), 0x0) + check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0x1), 0x0) + check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0x2), 0x2) + check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) + check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) + check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) + check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xc3400802848010df4642206021051440870162a506200c1c0911383c44039050) + check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0x8842088480815896109824c024810a628e04220806000d1e4891327d001c0012) + check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0x0), 0x0) + check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0x1), 0x1) + check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0x2), 0x0) + check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) + check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da70) + check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xc3400802848010df4642206021051440870162a506200c1c0911383c44039050) + check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) + check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa0d40c20808a10960020204820310044867833404610ec1c0a31f0be02c04031) + check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0x0), 0x0) + check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0x1), 0x1) + check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0x2), 0x2) + check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) + check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44ba) + check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0x8842088480815896109824c024810a628e04220806000d1e4891327d001c0012) + check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xa0d40c20808a10960020204820310044867833404610ec1c0a31f0be02c04031) + check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul new file mode 100644 index 000000000000..20e4c828adf8 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul @@ -0,0 +1,62 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x0) + check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x0) + check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x0) + check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x16), 0x0) + check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x9), 0x0) + check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x1f), 0x0) + check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x0), 0x0) + check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x0) + check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x0) + check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x0) + check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x16), 0x0) + check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x9), 0x0) + check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x1f), 0x0) + check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x0), 0x0) + check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x0) + check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x0) + check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x0) + check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x16), 0x0) + check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x9), 0x0) + check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x1f), 0x0) + check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x0), 0x0) + check(byte(0x16, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x3f) + check(byte(0x16, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x94) + check(byte(0x16, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x86) + check(byte(0x16, 0x16), 0x0) + check(byte(0x16, 0x9), 0x0) + check(byte(0x16, 0x1f), 0x0) + check(byte(0x16, 0x0), 0x0) + check(byte(0x9, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0xb6) + check(byte(0x9, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x46) + check(byte(0x9, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x21) + check(byte(0x9, 0x16), 0x0) + check(byte(0x9, 0x9), 0x0) + check(byte(0x9, 0x1f), 0x0) + check(byte(0x9, 0x0), 0x0) + check(byte(0x1f, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x48) + check(byte(0x1f, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x55) + check(byte(0x1f, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0xd2) + check(byte(0x1f, 0x16), 0x16) + check(byte(0x1f, 0x9), 0x9) + check(byte(0x1f, 0x1f), 0x1f) + check(byte(0x1f, 0x0), 0x0) + check(byte(0x0, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x1) + check(byte(0x0, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x27) + check(byte(0x0, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0xc9) + check(byte(0x0, 0x16), 0x0) + check(byte(0x0, 0x9), 0x0) + check(byte(0x0, 0x1f), 0x0) + check(byte(0x0, 0x0), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul new file mode 100644 index 000000000000..1fbb1f32c825 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(div(0x0, 0x0), 0x0) + check(div(0x0, 0x1), 0x0) + check(div(0x0, 0x2), 0x0) + check(div(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(div(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(div(0x0, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) + check(div(0x0, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x0) + check(div(0x0, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) + check(div(0x1, 0x0), 0x0) + check(div(0x1, 0x1), 0x1) + check(div(0x1, 0x2), 0x0) + check(div(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(div(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(div(0x1, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) + check(div(0x1, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x0) + check(div(0x1, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) + check(div(0x2, 0x0), 0x0) + check(div(0x2, 0x1), 0x2) + check(div(0x2, 0x2), 0x1) + check(div(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(div(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(div(0x2, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) + check(div(0x2, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x0) + check(div(0x2, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) + check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x2) + check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x3) + check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x1) + check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x2) + check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x3) + check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x1) + check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x0), 0x0) + check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x1), 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629) + check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x2), 0x2d65c95bfa430883b5d982e4abaef484c97ce7141ba0bfc76e65fc591f542b14) + check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x1) + check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x1) + check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) + check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x0), 0x0) + check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x1), 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765) + check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x2), 0x28b52e8dc6c55df2aad8686e2ae031899ab24eb525514acf34b0ad89679d93b2) + check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) + check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x1) + check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) + check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x0), 0x0) + check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x1), 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9) + check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x2), 0x7f7fef2ec891ae92afc5e7a659b3dd36646809a80cfbdb4bb30c8dfb5554d674) + check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x2) + check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x3) + check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x1) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul new file mode 100644 index 000000000000..bd3ea49e7044 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(eq(0x0, 0x0), 0x1) + check(eq(0x0, 0x1), 0x0) + check(eq(0x0, 0x2), 0x0) + check(eq(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(eq(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(eq(0x0, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) + check(eq(0x0, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) + check(eq(0x0, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) + check(eq(0x1, 0x0), 0x0) + check(eq(0x1, 0x1), 0x1) + check(eq(0x1, 0x2), 0x0) + check(eq(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(eq(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(eq(0x1, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) + check(eq(0x1, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) + check(eq(0x1, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) + check(eq(0x2, 0x0), 0x0) + check(eq(0x2, 0x1), 0x0) + check(eq(0x2, 0x2), 0x1) + check(eq(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(eq(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(eq(0x2, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) + check(eq(0x2, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) + check(eq(0x2, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) + check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) + check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) + check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) + check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) + check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) + check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) + check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0x0), 0x0) + check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0x1), 0x0) + check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0x2), 0x0) + check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x1) + check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) + check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) + check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0x0), 0x0) + check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0x1), 0x0) + check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0x2), 0x0) + check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) + check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x1) + check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) + check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0x0), 0x0) + check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0x1), 0x0) + check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0x2), 0x0) + check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) + check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) + check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x1) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul new file mode 100644 index 000000000000..57cd9d975c46 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(exp(0x0, 0x0), 0x1) + check(exp(0x0, 0x1), 0x0) + check(exp(0x0, 0x2), 0x0) + check(exp(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(exp(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(exp(0x0, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) + check(exp(0x0, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) + check(exp(0x0, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) + check(exp(0x1, 0x0), 0x1) + check(exp(0x1, 0x1), 0x1) + check(exp(0x1, 0x2), 0x1) + check(exp(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(exp(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(exp(0x1, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x1) + check(exp(0x1, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x1) + check(exp(0x1, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x1) + check(exp(0x2, 0x0), 0x1) + check(exp(0x2, 0x1), 0x2) + check(exp(0x2, 0x2), 0x4) + check(exp(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(exp(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(exp(0x2, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) + check(exp(0x2, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) + check(exp(0x2, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) + check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x1) + check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) + check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x1) + check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x1) + check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x1) + check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x4) + check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) + check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) + check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) + check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x0), 0x1) + check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x1), 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a) + check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x2), 0xb17aeaa2a9c8f5f1d46aa1515d5f3e230f509fe7ca6ba039c0fbd6be278690a4) + check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) + check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) + check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) + check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x0), 0x1) + check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x1), 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc) + check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x2), 0xdf116dc43f6b4886976bf644b66644ab5cad4ed96cb72a36bc0486d46be8c210) + check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) + check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) + check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) + check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x0), 0x1) + check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x1), 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693) + check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x2), 0x669ad199e78968258dc1ae2be39498fa8658b5dc6a931db517a3255a0fabd869) + check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x6b794c2d72683939f9b9e84d6b481559bde3d5c30350d1411657dbe7df2b179b) + check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xf0208681cb5ff5bf36ad1452abc978c11b97dfb52228b3e6ec0de61afa3f37d9) + check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x8f8682f8609105950657f517a2f2c8c36a009c7e8d8d1d26f7333c24d3061ec9) + check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x7f34de7e2347950ac013638f82b3943c35e8a7950b6fe59a29d5f12c839f44f1) + check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x78a7112f259370251244c8bc2d31c0666e71009f1fc5bb97852fd11f93eb310b) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul new file mode 100644 index 000000000000..102171b50556 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(gt(0x0, 0x0), 0x0) + check(gt(0x0, 0x1), 0x0) + check(gt(0x0, 0x2), 0x0) + check(gt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(gt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(gt(0x0, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) + check(gt(0x0, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + check(gt(0x0, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) + check(gt(0x1, 0x0), 0x1) + check(gt(0x1, 0x1), 0x0) + check(gt(0x1, 0x2), 0x0) + check(gt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(gt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(gt(0x1, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) + check(gt(0x1, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + check(gt(0x1, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) + check(gt(0x2, 0x0), 0x1) + check(gt(0x2, 0x1), 0x1) + check(gt(0x2, 0x2), 0x0) + check(gt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(gt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(gt(0x2, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) + check(gt(0x2, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + check(gt(0x2, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) + check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x1) + check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) + check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) + check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x1) + check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x1) + check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) + check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x1) + check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x1) + check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x1) + check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x1) + check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x1) + check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) + check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x0), 0x1) + check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x1), 0x1) + check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x2), 0x1) + check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) + check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) + check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x0), 0x1) + check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x1), 0x1) + check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x2), 0x1) + check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x1) + check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) + check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x0), 0x1) + check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x1), 0x1) + check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x2), 0x1) + check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) + check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul new file mode 100644 index 000000000000..5486a5d8f318 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul @@ -0,0 +1,24 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(iszero(0x0), 0x1) + check(iszero(0x1), 0x0) + check(iszero(0x2), 0x0) + check(iszero(0x3), 0x0) + check(iszero(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(iszero(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(iszero(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd), 0x0) + check(iszero(0xdc91451b4d11884662ecce3baf532f24813b65c6e9ff858cb3269bf73ce701a9), 0x0) + check(iszero(0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701), 0x0) + check(iszero(0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be), 0x0) + check(iszero(0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul new file mode 100644 index 000000000000..5259b9c739ef --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(lt(0x0, 0x0), 0x0) + check(lt(0x0, 0x1), 0x1) + check(lt(0x0, 0x2), 0x1) + check(lt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(lt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(lt(0x0, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) + check(lt(0x0, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x1) + check(lt(0x0, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) + check(lt(0x1, 0x0), 0x0) + check(lt(0x1, 0x1), 0x0) + check(lt(0x1, 0x2), 0x1) + check(lt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(lt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(lt(0x1, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) + check(lt(0x1, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x1) + check(lt(0x1, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) + check(lt(0x2, 0x0), 0x0) + check(lt(0x2, 0x1), 0x0) + check(lt(0x2, 0x2), 0x0) + check(lt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(lt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(lt(0x2, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) + check(lt(0x2, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x1) + check(lt(0x2, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) + check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x0) + check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) + check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) + check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x0) + check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) + check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) + check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x0), 0x0) + check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x1), 0x0) + check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x2), 0x0) + check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x0) + check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) + check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) + check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x0), 0x0) + check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x1), 0x0) + check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x2), 0x0) + check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) + check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) + check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) + check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x0), 0x0) + check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x1), 0x0) + check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x2), 0x0) + check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) + check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) + check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul new file mode 100644 index 000000000000..ad0bf68fd279 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(mod(0x0, 0x0), 0x0) + check(mod(0x0, 0x1), 0x0) + check(mod(0x0, 0x2), 0x0) + check(mod(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(mod(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(mod(0x0, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x0) + check(mod(0x0, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x0) + check(mod(0x0, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x0) + check(mod(0x1, 0x0), 0x0) + check(mod(0x1, 0x1), 0x0) + check(mod(0x1, 0x2), 0x1) + check(mod(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(mod(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(mod(0x1, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x1) + check(mod(0x1, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x1) + check(mod(0x1, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x1) + check(mod(0x2, 0x0), 0x0) + check(mod(0x2, 0x1), 0x0) + check(mod(0x2, 0x2), 0x0) + check(mod(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) + check(mod(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) + check(mod(0x2, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x2) + check(mod(0x2, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x2) + check(mod(0x2, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x2) + check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) + check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x3bf102f6117471a23f1fd0f25e36c48659661437efe1d3792957359d9ade119) + check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x732b22cd113ddfb8d9052370a100ab70cf1fa5bd01890b58d6bf2227eeaf12d) + check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x795dbec8994a98a257d2e5526a6147d04e8ba050dbab7e31f323d2e59481e88) + check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x3bf102f6117471a23f1fd0f25e36c48659661437efe1d3792957359d9ade118) + check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x732b22cd113ddfb8d9052370a100ab70cf1fa5bd01890b58d6bf2227eeaf12c) + check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x795dbec8994a98a257d2e5526a6147d04e8ba050dbab7e31f323d2e59481e87) + check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x0), 0x0) + check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x1), 0x0) + check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x2), 0x1) + check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1) + check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1) + check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x0) + check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x2c1fc3e0e95b6a35cb650d70202cdf5e3a39990b89aa63098d8b271fafce35f) + check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1) + check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x0), 0x0) + check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x1), 0x0) + check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x2), 0x0) + check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) + check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) + check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) + check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x0) + check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) + check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x0), 0x0) + check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x1), 0x0) + check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x2), 0x1) + check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d) + check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d) + check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x28c33963b7a7a8aba4294566241935e264a0d2343b41723d8e08297f8684f0ac) + check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x43c5f3d0fac4c76b8e8e696ae6f63da3cd66ae0ec4bc37d5827cc47cb710799) + check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul new file mode 100644 index 000000000000..5e6e56de0452 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(mul(0x0, 0x0), 0x0) + check(mul(0x0, 0x1), 0x0) + check(mul(0x0, 0x2), 0x0) + check(mul(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(mul(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(mul(0x0, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x0) + check(mul(0x0, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x0) + check(mul(0x0, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x0) + check(mul(0x1, 0x0), 0x0) + check(mul(0x1, 0x1), 0x1) + check(mul(0x1, 0x2), 0x2) + check(mul(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(mul(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(mul(0x1, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a) + check(mul(0x1, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4) + check(mul(0x1, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16) + check(mul(0x2, 0x0), 0x0) + check(mul(0x2, 0x1), 0x2) + check(mul(0x2, 0x2), 0x4) + check(mul(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(mul(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + check(mul(0x2, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0xb20876cdcf7b2d6bc6d0eece4ef9f8030aade0af57846dea12e23725d4e106f4) + check(mul(0x2, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x328d50f6f6022108b3ca926e011be58e75a8bf8ad9e39ea26d94a99fec577d68) + check(mul(0x2, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x6bc1f5f0b1d04e000899c7ae9f19a91c2b747c79e74ce5fedd36b8b2466db62c) + check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) + check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x26fbc4991842694a1c978898d88303fe7aa90fa8543dc90af68ee46d158f7c86) + check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x66b9578484feef7ba61ab6c8ff720d38c52ba03a930e30aec935ab3009d4414c) + check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0xca1f0507a717d8fffbb31c28b0732b71ea45c1c30c598d009164a3a6dcc924ea) + check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) + check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4) + check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x4df789323084d294392f1131b10607fcf5521f50a87b9215ed1dc8da2b1ef90c) + check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0xcd72af0909fddef74c356d91fee41a718a574075261c615d926b566013a88298) + check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x943e0a0f4e2fb1fff766385160e656e3d48b838618b31a0122c9474db99249d4) + check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x0), 0x0) + check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x1), 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a) + check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x2), 0xb20876cdcf7b2d6bc6d0eece4ef9f8030aade0af57846dea12e23725d4e106f4) + check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x26fbc4991842694a1c978898d88303fe7aa90fa8543dc90af68ee46d158f7c86) + check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4df789323084d294392f1131b10607fcf5521f50a87b9215ed1dc8da2b1ef90c) + check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x5e212ad86e15d56a8b8dc59640978d62434da71e22e251daa07794f656461624) + check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x72b7563189e6fb81a6e0c7e6ac6ae5cf9f65d32c803940a15b56442faa2efdc8) + check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x2c78a699a972d189ec393219bb4f65066d56fdf47055c43b7095704dcfe0aa7c) + check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x0), 0x0) + check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x1), 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4) + check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x2), 0x328d50f6f6022108b3ca926e011be58e75a8bf8ad9e39ea26d94a99fec577d68) + check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x66b9578484feef7ba61ab6c8ff720d38c52ba03a930e30aec935ab3009d4414c) + check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xcd72af0909fddef74c356d91fee41a718a574075261c615d926b566013a88298) + check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x72b7563189e6fb81a6e0c7e6ac6ae5cf9f65d32c803940a15b56442faa2efdc8) + check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x55fa1bc0326d6284b14f80cb3633885cd52b77b32521d9e1a0aca1138e87ae90) + check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0xaaaa01c250e883022bf70da9614aa53fd00e10bbbc7bb19e3b31165769de5f78) + check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x0), 0x0) + check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x1), 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16) + check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x2), 0x6bc1f5f0b1d04e000899c7ae9f19a91c2b747c79e74ce5fedd36b8b2466db62c) + check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xca1f0507a717d8fffbb31c28b0732b71ea45c1c30c598d009164a3a6dcc924ea) + check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x943e0a0f4e2fb1fff766385160e656e3d48b838618b31a0122c9474db99249d4) + check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x2c78a699a972d189ec393219bb4f65066d56fdf47055c43b7095704dcfe0aa7c) + check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0xaaaa01c250e883022bf70da9614aa53fd00e10bbbc7bb19e3b31165769de5f78) + check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0xd9d221a1c3d2f657ff36ba234d8aff13efcc67f6767406e1231830f52cc6a5e4) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul new file mode 100644 index 000000000000..f2e6ad879ba8 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x168054808d0b4226e2f7d20f66d64728fd7734583dd36b66d7966a085cbcfda0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x14fc3916121454e5ab8985b6c8045fd2a9c752dc8d0cd64706cfc963b8627024) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x53239a8c18c5fa9453f5afe8c7ecf59e5b7dbb4a7aa4c2f9edd7dd4838eeb0de) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x424eb1213861699d29b2da1027f6aea380d49af89b36be4d470a68b72e34cc2c) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0, 0x0), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x53239a8c18c5fa9453f5afe8c7ecf59e5b7dbb4a7aa4c2f9edd7dd4838eeb0de) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x521eb72d6d9a85f5f224d67f52fd342fd66eebe8fe610d679833992645442e8) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x4cf32ce1ebb97062a7f1962bbb5a94a4509467560ad9267ba07dfd126496b44d) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0xedca0f5f035e9b37e93b80abedf46b7ef6c3083be21e6fd53a25f57a0e040384) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0, 0x0), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x424eb1213861699d29b2da1027f6aea380d49af89b36be4d470a68b72e34cc2c) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0xedca0f5f035e9b37e93b80abedf46b7ef6c3083be21e6fd53a25f57a0e040384) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x434c7978cc53f57ae0e7c10a07575970cdc89ca7874438066521ef135520988d) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x2180c8bb61f74bb31ea694c77ab5b96436c5bf60c350cb227f0f4e194e678d31) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0, 0x0), 0x0) + check(mulmod(0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0), 0x0) + check(mulmod(0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0), 0x0) + check(mulmod(0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0), 0x0) + check(mulmod(0x0, 0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) + check(mulmod(0x0, 0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) + check(mulmod(0x0, 0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) + check(mulmod(0x0, 0x0, 0x0), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul new file mode 100644 index 000000000000..3a2e629fcb0e --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul @@ -0,0 +1,24 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(not(0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(not(0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(not(0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + check(not(0x3), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + check(not(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(not(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(not(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd), 0x2) + check(not(0xb9caa39ea86683d4e096bd6edd32ae3ead3c1b3a5c0c9ff6aaf9f46e9859aa7e), 0x46355c6157997c2b1f69429122cd51c152c3e4c5a3f3600955060b9167a65581) + check(not(0xe4fe151407cfb034d8ec5ae737b2fb264e0b4084b976fa07648d31ec1b1bedcb), 0x1b01eaebf8304fcb2713a518c84d04d9b1f4bf7b468905f89b72ce13e4e41234) + check(not(0xd6bfc8a63b534b270ddfd63ce081db9109bc4355465b6a40b200b01fac47eb4e), 0x29403759c4acb4d8f22029c31f7e246ef643bcaab9a495bf4dff4fe053b814b1) + check(not(0xe40000700672cffea275f0f1a48f6096ffb97924fa63024f6d5411b5a529a84d), 0x1bffff8ff98d30015d8a0f0e5b709f69004686db059cfdb092abee4a5ad657b2) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul new file mode 100644 index 000000000000..b37ab923a456 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(or(0x0, 0x0), 0x0) + check(or(0x0, 0x1), 0x1) + check(or(0x0, 0x2), 0x2) + check(or(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(or(0x0, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) + check(or(0x0, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) + check(or(0x0, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) + check(or(0x1, 0x0), 0x1) + check(or(0x1, 0x1), 0x1) + check(or(0x1, 0x2), 0x3) + check(or(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0x1, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) + check(or(0x1, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b53) + check(or(0x1, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cff) + check(or(0x2, 0x0), 0x2) + check(or(0x2, 0x1), 0x3) + check(or(0x2, 0x2), 0x2) + check(or(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(or(0x2, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f3) + check(or(0x2, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) + check(or(0x2, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) + check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x0), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) + check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) + check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x2), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f3) + check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) + check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0xbb5dfd12555ffe715f4e766f7ffed9fb9bfffbee9ff6bfb7f18e9ebeeffb9bf3) + check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x7addff63f69ee6e55f5eedef7fdffbfef3b77fee9ff46bd5f1fe0cfccf8fdeff) + check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x0), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) + check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x1), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b53) + check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x2), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) + check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0xbb5dfd12555ffe715f4e766f7ffed9fb9bfffbee9ff6bfb7f18e9ebeeffb9bf3) + check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) + check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0xf1dd7773f7df7eb54f1ebfe17fff6bb7fb7bf7ae8f76fdf7f0fe96eaef7f5ffe) + check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x0), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) + check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x1), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cff) + check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x2), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) + check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x7addff63f69ee6e55f5eedef7fdffbfef3b77fee9ff46bd5f1fe0cfccf8fdeff) + check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0xf1dd7773f7df7eb54f1ebfe17fff6bb7fb7bf7ae8f76fdf7f0fe96eaef7f5ffe) + check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul new file mode 100644 index 000000000000..05ac2d97f136 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(sar(0x0, 0x0), 0x0) + check(sar(0x0, 0x1), 0x1) + check(sar(0x0, 0x2), 0x2) + check(sar(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(sar(0x0, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb) + check(sar(0x0, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979) + check(sar(0x0, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c) + check(sar(0x1, 0x0), 0x0) + check(sar(0x1, 0x1), 0x0) + check(sar(0x1, 0x2), 0x1) + check(sar(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x1, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xe4a4b0b5ab81acc1193f45fa3d9f041e96aa99e28af4d1a9c6e6ead742ce3465) + check(sar(0x1, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x2ee4bc6eb8ef0d1c046a2da9c70e398fe0999af96de414d753adc956885e3cbc) + check(sar(0x1, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x3e08e31677e058c595c611f22023507bfa4715f195e5e0a4acdcd494f86c46ce) + check(sar(0x2, 0x0), 0x0) + check(sar(0x2, 0x1), 0x0) + check(sar(0x2, 0x2), 0x0) + check(sar(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x2, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xf252585ad5c0d6608c9fa2fd1ecf820f4b554cf1457a68d4e373756ba1671a32) + check(sar(0x2, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x17725e375c77868e023516d4e3871cc7f04ccd7cb6f20a6ba9d6e4ab442f1e5e) + check(sar(0x2, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x1f04718b3bf02c62cae308f91011a83dfd238af8caf2f052566e6a4a7c362367) + check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x0) + check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) + check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x0) + check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) + check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0x0), 0x0) + check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0x1), 0x0) + check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0x2), 0x0) + check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x0) + check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) + check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0x0), 0x0) + check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0x1), 0x0) + check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0x2), 0x0) + check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x0) + check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) + check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x0), 0x0) + check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x1), 0x0) + check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x2), 0x0) + check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x0) + check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul new file mode 100644 index 000000000000..255bfb8ef16c --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(sdiv(0x0, 0x0), 0x0) + check(sdiv(0x0, 0x1), 0x0) + check(sdiv(0x0, 0x2), 0x0) + check(sdiv(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(sdiv(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(sdiv(0x0, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + check(sdiv(0x0, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + check(sdiv(0x0, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) + check(sdiv(0x1, 0x0), 0x0) + check(sdiv(0x1, 0x1), 0x1) + check(sdiv(0x1, 0x2), 0x0) + check(sdiv(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sdiv(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(sdiv(0x1, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + check(sdiv(0x1, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + check(sdiv(0x1, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) + check(sdiv(0x2, 0x0), 0x0) + check(sdiv(0x2, 0x1), 0x2) + check(sdiv(0x2, 0x2), 0x1) + check(sdiv(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(sdiv(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sdiv(0x2, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + check(sdiv(0x2, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + check(sdiv(0x2, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) + check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) + check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) + check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) + check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x0), 0x0) + check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x1), 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8) + check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x2), 0xc6fff557944126ae170ad7e402c64834d1755bc187ba8328981f335a04647b64) + check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x72001550d77db2a3d1ea5037fa736f965d15487cf08af9aecfc1994bf7370938) + check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x39000aa86bbed951e8f5281bfd39b7cb2e8aa43e78457cd767e0cca5fb9b849c) + check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x1) + check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x116) + check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x0), 0x0) + check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x1), 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6) + check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x2), 0xc6a4459992f1746943c22cb0393cb9b6b3e38d5163e6d588c031b4c128bec7b) + check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xe72b774ccda1d172d787ba69f8d868c929838e55d383254ee7f9c967dae8270a) + check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xf395bba666d0e8b96bc3dd34fc6c346494c1c72ae9c192a773fce4b3ed741385) + check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x1) + check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc4) + check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x0), 0x0) + check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x1), 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5) + check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x2), 0xffcb9810fc2988f075d60661a3640ea695fd3d2b5129a44cab4d81b977c159f3) + check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x68cfde07acee1f1453f33cb937e2b2d40585a95dacb766a964fc8d107d4c1b) + check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x3467ef03d6770f8a29f99e5c9bf1596a02c2d4aed65bb354b27e46883ea60d) + check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x1) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul new file mode 100644 index 000000000000..90dfdd9d9d32 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(sgt(0x0, 0x0), 0x0) + check(sgt(0x0, 0x1), 0x0) + check(sgt(0x0, 0x2), 0x0) + check(sgt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(sgt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(sgt(0x0, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + check(sgt(0x0, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + check(sgt(0x0, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + check(sgt(0x1, 0x0), 0x1) + check(sgt(0x1, 0x1), 0x0) + check(sgt(0x1, 0x2), 0x0) + check(sgt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(sgt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(sgt(0x1, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + check(sgt(0x1, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + check(sgt(0x1, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + check(sgt(0x2, 0x0), 0x1) + check(sgt(0x2, 0x1), 0x1) + check(sgt(0x2, 0x2), 0x0) + check(sgt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(sgt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(sgt(0x2, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + check(sgt(0x2, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + check(sgt(0x2, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x0), 0x0) + check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x1), 0x0) + check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x2), 0x0) + check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x0) + check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x0), 0x1) + check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x1), 0x1) + check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x2), 0x1) + check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x0), 0x1) + check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x1), 0x1) + check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x2), 0x1) + check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x1) + check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul new file mode 100644 index 000000000000..9647160f2c5a --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(shl(0x0, 0x0), 0x0) + check(shl(0x0, 0x1), 0x1) + check(shl(0x0, 0x2), 0x2) + check(shl(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(shl(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(shl(0x0, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9) + check(shl(0x0, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a) + check(shl(0x0, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951) + check(shl(0x1, 0x0), 0x0) + check(shl(0x1, 0x1), 0x2) + check(shl(0x1, 0x2), 0x4) + check(shl(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(shl(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + check(shl(0x1, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0xc5f180d19556f397126a43965fdc0465af1d2d7a32c3d3d4fd2e386d2f96fd2) + check(shl(0x1, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0xc64b6e35896bfda7e82d9d3f3931aadbaf2221b8d6d0f1dddecff225c89556d4) + check(shl(0x1, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x61eeb35c944b39051996f7eb6d90f18dfcdf8b5aeddd2c1b58440be727f7b2a2) + check(shl(0x2, 0x0), 0x0) + check(shl(0x2, 0x1), 0x4) + check(shl(0x2, 0x2), 0x8) + check(shl(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + check(shl(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8) + check(shl(0x2, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x18be301a32aade72e24d4872cbfb808cb5e3a5af46587a7a9fa5c70da5f2dfa4) + check(shl(0x2, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x8c96dc6b12d7fb4fd05b3a7e726355b75e444371ada1e3bbbd9fe44b912aada8) + check(shl(0x2, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0xc3dd66b92896720a332defd6db21e31bf9bf16b5dbba5836b08817ce4fef6544) + check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x0) + check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x0) + check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) + check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x0) + check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x0) + check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) + check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0x0), 0x0) + check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0x1), 0x0) + check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0x2), 0x0) + check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x0) + check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x0) + check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) + check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0x0), 0x0) + check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0x1), 0x0) + check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0x2), 0x0) + check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x0) + check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x0) + check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) + check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0x0), 0x0) + check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0x1), 0x0) + check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0x2), 0x0) + check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x0) + check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x0) + check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul new file mode 100644 index 000000000000..94a7acf56c47 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(shr(0x0, 0x0), 0x0) + check(shr(0x0, 0x1), 0x1) + check(shr(0x0, 0x2), 0x2) + check(shr(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(shr(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(shr(0x0, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0) + check(shr(0x0, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb) + check(shr(0x0, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de) + check(shr(0x1, 0x0), 0x0) + check(shr(0x1, 0x1), 0x0) + check(shr(0x1, 0x2), 0x1) + check(shr(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(shr(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(shr(0x1, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x5a47af7f111d77bb1a7a6583d1476c2b3f3cc7deab46e216f81e27c7e3f22ce8) + check(shr(0x1, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x713f359d1c4bb8d3f7302983742ecfbc35e96e24141be8670e1e468da869f5f5) + check(shr(0x1, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x28b8533510bca86d0177840526d76e1424734179948fcc171f4e8f1fe801586f) + check(shr(0x2, 0x0), 0x0) + check(shr(0x2, 0x1), 0x0) + check(shr(0x2, 0x2), 0x0) + check(shr(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(shr(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(shr(0x2, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x2d23d7bf888ebbdd8d3d32c1e8a3b6159f9e63ef55a3710b7c0f13e3f1f91674) + check(shr(0x2, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x389f9ace8e25dc69fb9814c1ba1767de1af4b7120a0df433870f2346d434fafa) + check(shr(0x2, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x145c299a885e543680bbc202936bb70a1239a0bcca47e60b8fa7478ff400ac37) + check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x0) + check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x0) + check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) + check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x0) + check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x0) + check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) + check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0x0), 0x0) + check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0x1), 0x0) + check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0x2), 0x0) + check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x0) + check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x0) + check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) + check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0x0), 0x0) + check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0x1), 0x0) + check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0x2), 0x0) + check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x0) + check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x0) + check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) + check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0x0), 0x0) + check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0x1), 0x0) + check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0x2), 0x0) + check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x0) + check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x0) + check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul new file mode 100644 index 000000000000..dbe11f6b5446 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(signextend(0x0, 0x0), 0x0) + check(signextend(0x0, 0x1), 0x1) + check(signextend(0x0, 0x2), 0x2) + check(signextend(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(signextend(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(signextend(0x0, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb4) + check(signextend(0x0, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a) + check(signextend(0x0, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb5) + check(signextend(0x1, 0x0), 0x0) + check(signextend(0x1, 0x1), 0x1) + check(signextend(0x1, 0x2), 0x2) + check(signextend(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(signextend(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(signextend(0x1, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x47b4) + check(signextend(0x1, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x308a) + check(signextend(0x1, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbdb5) + check(signextend(0x2, 0x0), 0x0) + check(signextend(0x2, 0x1), 0x1) + check(signextend(0x2, 0x2), 0x2) + check(signextend(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(signextend(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(signextend(0x2, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffff347b4) + check(signextend(0x2, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc2308a) + check(signextend(0x2, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x6bdb5) + check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) + check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x2) + check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4) + check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a) + check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5) + check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x1) + check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x2) + check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4) + check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a) + check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5) + check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x0), 0x0) + check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x1), 0x1) + check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x2), 0x2) + check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4) + check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a) + check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5) + check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x0), 0x0) + check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x1), 0x1) + check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x2), 0x2) + check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4) + check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a) + check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5) + check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x0), 0x0) + check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x1), 0x1) + check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x2), 0x2) + check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4) + check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a) + check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul new file mode 100644 index 000000000000..9cba6e433bf2 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(slt(0x0, 0x0), 0x0) + check(slt(0x0, 0x1), 0x1) + check(slt(0x0, 0x2), 0x1) + check(slt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(slt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(slt(0x0, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + check(slt(0x0, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + check(slt(0x0, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + check(slt(0x1, 0x0), 0x0) + check(slt(0x1, 0x1), 0x0) + check(slt(0x1, 0x2), 0x1) + check(slt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(slt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(slt(0x1, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + check(slt(0x1, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + check(slt(0x1, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + check(slt(0x2, 0x0), 0x0) + check(slt(0x2, 0x1), 0x0) + check(slt(0x2, 0x2), 0x0) + check(slt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(slt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(slt(0x2, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + check(slt(0x2, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + check(slt(0x2, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x1) + check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) + check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) + check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x1) + check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x1) + check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x1) + check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x0), 0x1) + check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x1), 0x1) + check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x2), 0x1) + check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x0), 0x0) + check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x1), 0x0) + check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x2), 0x0) + check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x0) + check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x0), 0x1) + check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x1), 0x1) + check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x2), 0x1) + check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x1) + check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul new file mode 100644 index 000000000000..1771ad50caab --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(smod(0x0, 0x0), 0x0) + check(smod(0x0, 0x1), 0x0) + check(smod(0x0, 0x2), 0x0) + check(smod(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(smod(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(smod(0x0, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x0) + check(smod(0x0, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x0) + check(smod(0x0, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x0) + check(smod(0x1, 0x0), 0x0) + check(smod(0x1, 0x1), 0x0) + check(smod(0x1, 0x2), 0x1) + check(smod(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(smod(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(smod(0x1, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x1) + check(smod(0x1, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x1) + check(smod(0x1, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x1) + check(smod(0x2, 0x0), 0x0) + check(smod(0x2, 0x1), 0x0) + check(smod(0x2, 0x2), 0x0) + check(smod(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(smod(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(smod(0x2, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x2) + check(smod(0x2, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x2) + check(smod(0x2, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x2) + check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0x0), 0x0) + check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0x1), 0x0) + check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0x2), 0x0) + check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x0) + check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e) + check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e) + check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0x0), 0x0) + check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0x1), 0x0) + check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0x2), 0x0) + check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x2de0e2b2148d4fdfbb10ae6c22e13021868ba21254f722574111f1417d6dd8a) + check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x0) + check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c) + check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0x0), 0x0) + check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0x1), 0x0) + check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0xf8f140d5a8fce565089e7a9fe349aa55884d0a49d71044525e82d52c31eeea37) + check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xfd8fdd6d1200102f72369fc103780e7f09a5662debf102681fdcfaac94e2cdd1) + check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul new file mode 100644 index 000000000000..f1f072dabf24 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(sub(0x0, 0x0), 0x0) + check(sub(0x0, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sub(0x0, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(sub(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(sub(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) + check(sub(0x0, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e84) + check(sub(0x0, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd6) + check(sub(0x0, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9de) + check(sub(0x1, 0x0), 0x1) + check(sub(0x1, 0x1), 0x0) + check(sub(0x1, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sub(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) + check(sub(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x3) + check(sub(0x1, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e85) + check(sub(0x1, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd7) + check(sub(0x1, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9df) + check(sub(0x2, 0x0), 0x2) + check(sub(0x2, 0x1), 0x1) + check(sub(0x2, 0x2), 0x0) + check(sub(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x3) + check(sub(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4) + check(sub(0x2, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e86) + check(sub(0x2, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd8) + check(sub(0x2, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9e0) + check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e83) + check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd5) + check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9dd) + check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e82) + check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd4) + check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9dc) + check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x0), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c) + check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x1), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17b) + check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x2), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17a) + check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17d) + check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17e) + check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0x0) + check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0x228806570f98613dae80c1017cf27cdee2891468b68f92e6e004d07cb67cef52) + check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x9566d2426a939b57cfabe27acfe34dc5e5537cf2e39944bdb0597528c809db5a) + check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x0), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a) + check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x1), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd40229) + check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x2), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd40228) + check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022b) + check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022c) + check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xdd77f9a8f0679ec2517f3efe830d83211d76eb9749706d191ffb2f83498310ae) + check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0x0) + check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x72decbeb5afb3a1a212b217952f0d0e702ca688a2d09b1d6d054a4ac118cec08) + check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x0), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622) + check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x1), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471621) + check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x2), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471620) + check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471623) + check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471624) + check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0x6a992dbd956c64a830541d85301cb23a1aac830d1c66bb424fa68ad737f624a6) + check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0x8d213414a504c5e5ded4de86ad0f2f18fd359775d2f64e292fab5b53ee7313f8) + check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul new file mode 100644 index 000000000000..a80579e556fd --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul @@ -0,0 +1,77 @@ +{ + + function check(a, b) + { if iszero(eq(a, b)) { revert(0, 0) } } + + check(xor(0x0, 0x0), 0x0) + check(xor(0x0, 0x1), 0x1) + check(xor(0x0, 0x2), 0x2) + check(xor(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(xor(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(xor(0x0, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea) + check(xor(0x0, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f) + check(xor(0x0, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a) + check(xor(0x1, 0x0), 0x1) + check(xor(0x1, 0x1), 0x0) + check(xor(0x1, 0x2), 0x3) + check(xor(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(xor(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(xor(0x1, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63eb) + check(xor(0x1, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43e) + check(xor(0x1, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82b) + check(xor(0x2, 0x0), 0x2) + check(xor(0x2, 0x1), 0x3) + check(xor(0x2, 0x2), 0x0) + check(xor(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + check(xor(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + check(xor(0x2, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63e8) + check(xor(0x2, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43d) + check(xor(0x2, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf828) + check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x7dea1e8624891ec6074d85f1ac0a80b1d4ddd9a56f9935fcde0810809c029c15) + check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0xd0a99270ccd90226c167cdb767654d8ba12321f5a4ec95764b1f2dfd304d0bc0) + check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x243f36f7257b26334d71056c8a43dfe9720231bc14326b4c295817806e1407d5) + check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x7dea1e8624891ec6074d85f1ac0a80b1d4ddd9a56f9935fcde0810809c029c14) + check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0xd0a99270ccd90226c167cdb767654d8ba12321f5a4ec95764b1f2dfd304d0bc1) + check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x243f36f7257b26334d71056c8a43dfe9720231bc14326b4c295817806e1407d4) + check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x0), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea) + check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x1), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63eb) + check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x2), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63e8) + check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x7dea1e8624891ec6074d85f1ac0a80b1d4ddd9a56f9935fcde0810809c029c15) + check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x7dea1e8624891ec6074d85f1ac0a80b1d4ddd9a56f9935fcde0810809c029c14) + check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x0) + check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0xad438cf6e8501ce0c62a4846cb6fcd3a75fef850cb75a08a95173d7dac4f97d5) + check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x59d5287101f238f54a3c809d26495f58a6dfe8197bab5eb0f7500700f2169bc0) + check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x0), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f) + check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x1), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43e) + check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x2), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43d) + check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xd0a99270ccd90226c167cdb767654d8ba12321f5a4ec95764b1f2dfd304d0bc0) + check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xd0a99270ccd90226c167cdb767654d8ba12321f5a4ec95764b1f2dfd304d0bc1) + check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0xad438cf6e8501ce0c62a4846cb6fcd3a75fef850cb75a08a95173d7dac4f97d5) + check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x0) + check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xf496a487e9a224158c16c8dbed269262d3211049b0defe3a62473a7d5e590c15) + check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x0), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a) + check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x1), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82b) + check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x2), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf828) + check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x243f36f7257b26334d71056c8a43dfe9720231bc14326b4c295817806e1407d5) + check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x243f36f7257b26334d71056c8a43dfe9720231bc14326b4c295817806e1407d4) + check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x59d5287101f238f54a3c809d26495f58a6dfe8197bab5eb0f7500700f2169bc0) + check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0xf496a487e9a224158c16c8dbed269262d3211049b0defe3a62473a7d5e590c15) + check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x0) +} +// ==== +// maxTraceSize: 0 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// +// Call trace: From 1ac087fd80d5e8d6b4264858c94984002ce7b9a2 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 16:41:24 +0700 Subject: [PATCH 059/101] Change expr_nesting_depth_not_exceeded to run expression multiple time --- .../expr_nesting_depth_not_exceeded.yul | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul index 837e767a7070..c3354c9b8b6a 100644 --- a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul +++ b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul @@ -1,11 +1,16 @@ { - function f(x) -> y + function f(x) -> t { // 31 nested additions are computed in // exactly 64 expression evaluation steps - y := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,x))))))))))))))))))))))))))))))) + let y := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,x))))))))))))))))))))))))))))))) + let z := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,y))))))))))))))))))))))))))))))) + t := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,z))))))))))))))))))))))))))))))) + } + for { let i := 0 } lt(i, 10) { i := add(i, 1) } + { + pop(f(i)) } - pop(f(0)) } // ==== // maxExprNesting: 64 @@ -15,4 +20,22 @@ // // Call trace: // [CALL] f(0) -// │ [RETURN] 31 +// │ [RETURN] 93 +// [CALL] f(1) +// │ [RETURN] 94 +// [CALL] f(2) +// │ [RETURN] 95 +// [CALL] f(3) +// │ [RETURN] 96 +// [CALL] f(4) +// │ [RETURN] 97 +// [CALL] f(5) +// │ [RETURN] 98 +// [CALL] f(6) +// │ [RETURN] 99 +// [CALL] f(7) +// │ [RETURN] 100 +// [CALL] f(8) +// │ [RETURN] 101 +// [CALL] f(9) +// │ [RETURN] 102 From 41a382ba957b6fb9063d9491efee748014a133ad Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 16:47:54 +0700 Subject: [PATCH 060/101] Add test for StepLimitReached --- .../step_limit_not_reached.yul | 14 ++++++++++++++ .../yulPureInterpreterTests/step_limit_reached.yul | 14 ++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 test/libyul/yulPureInterpreterTests/step_limit_not_reached.yul create mode 100644 test/libyul/yulPureInterpreterTests/step_limit_reached.yul diff --git a/test/libyul/yulPureInterpreterTests/step_limit_not_reached.yul b/test/libyul/yulPureInterpreterTests/step_limit_not_reached.yul new file mode 100644 index 000000000000..7e9ec6ed8063 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/step_limit_not_reached.yul @@ -0,0 +1,14 @@ +{ + let i + for { i := 0 } lt(i, 100) { i := add(i, 1) } + { + } +} +// ==== +// maxSteps: 200 +// ---- +// Execution result: ExecutionOk +// Outter most variable values: +// i = 100 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/step_limit_reached.yul b/test/libyul/yulPureInterpreterTests/step_limit_reached.yul new file mode 100644 index 000000000000..4b7dc05476aa --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/step_limit_reached.yul @@ -0,0 +1,14 @@ +{ + let i + for { i := 0 } lt(i, 100) { i := add(i, 1) } + { + } +} +// ==== +// maxSteps: 100 +// ---- +// Execution result: StepLimitReached +// Outter most variable values: +// i = 96 +// +// Call trace: From 965697eca4ac2a412d327688a6dbc6749957e985 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 17:07:26 +0700 Subject: [PATCH 061/101] Add test for impure non instructions --- .../impure_instructions/datacopy.yul | 14 ++++++++++++++ .../impure_instructions/dataoffset.yul | 18 ++++++++++++++++++ .../impure_instructions/datasize.yul | 18 ++++++++++++++++++ .../impure_instructions/linkersymbol.yul | 18 ++++++++++++++++++ .../impure_instructions/loadimmutable.yul | 18 ++++++++++++++++++ .../impure_instructions/memoryguard.yul | 14 ++++++++++++++ .../impure_instructions/setimmutable.yul | 18 ++++++++++++++++++ 7 files changed, 118 insertions(+) create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/datacopy.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul create mode 100644 test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/datacopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/datacopy.yul new file mode 100644 index 000000000000..495f68146058 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/datacopy.yul @@ -0,0 +1,14 @@ +object "obj" { + code { + let x + x := 1 + datacopy(0, 0, 0) + x := 2 + } +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul new file mode 100644 index 000000000000..7df4a6dd586b --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul @@ -0,0 +1,18 @@ +object "obj" { + code { + let x + x := 1 + pop(dataoffset("obj")) + x := 2 + } +} +// "obj" was evaluated before `dataoffset` +// Expection for this test should be changed to `ImpureBuiltinEncountered` +// if in the future if "obj" is evaluated after + +// ---- +// Execution result: UnlimitedLiteralEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul new file mode 100644 index 000000000000..6cb1d460c179 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul @@ -0,0 +1,18 @@ +object "obj" { + code { + let x + x := 1 + pop(datasize("obj")) + x := 2 + } +} +// "obj" was evaluated before `datasize` +// Expection for this test should be changed to `ImpureBuiltinEncountered` +// if in the future if "obj" is evaluated after + +// ---- +// Execution result: UnlimitedLiteralEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul new file mode 100644 index 000000000000..a89cc787120a --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul @@ -0,0 +1,18 @@ +object "obj" { + code { + let x + x := 1 + pop(linkersymbol("foo")) + x := 2 + } +} +// "foo" was evaluated before `linkersymbol` +// Expection for this test should be changed to `ImpureBuiltinEncountered` +// if in the future if "foo" is evaluated after + +// ---- +// Execution result: UnlimitedLiteralEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul new file mode 100644 index 000000000000..d4dfbbdd16a0 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul @@ -0,0 +1,18 @@ +object "obj" { + code { + let x + x := 1 + pop(loadimmutable("foo")) + x := 2 + } +} +// "foo" was evaluated before `loadimmutable` +// Expection for this test should be changed to `ImpureBuiltinEncountered` +// if in the future if "foo" is evaluated after + +// ---- +// Execution result: UnlimitedLiteralEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul new file mode 100644 index 000000000000..4b18df5a1dc7 --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul @@ -0,0 +1,14 @@ +object "obj" { + code { + let x + x := 1 + pop(memoryguard(0)) + x := 2 + } +} +// ---- +// Execution result: ImpureBuiltinEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul new file mode 100644 index 000000000000..1d90f54fdc8b --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul @@ -0,0 +1,18 @@ +object "obj" { + code { + let x + x := 1 + setimmutable(0, "foo", 0) + x := 2 + } +} +// "foo" was evaluated before `setimmutable` +// Expection for this test should be changed to `ImpureBuiltinEncountered` +// if in the future if "foo" is evaluated after + +// ---- +// Execution result: UnlimitedLiteralEncountered +// Outter most variable values: +// x = 1 +// +// Call trace: From 3ac91956d95e527475d0c4447dbae05ccfc20a6f Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 17:17:23 +0700 Subject: [PATCH 062/101] Add check for verbatim --- libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp index 354b5e1c868e..e3947eaf39f7 100644 --- a/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp @@ -34,6 +34,8 @@ #include #include +#include + using namespace solidity; using namespace solidity::evmasm; using namespace solidity::yul; @@ -288,6 +290,9 @@ EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( return eval(*_fun.instruction, _evaluatedArguments); std::string fun = _fun.name.str(); + bool isVerbatim = boost::starts_with(fun, "verbatim"); + if (isVerbatim) + return ImpureBuiltinEncountered(); static std::set const NON_INSTRUCTION_BUILTIN_NAME = { "datasize", From 50acc291f18a506d36bcadb2b538a30f2f0b3461 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 17:17:38 +0700 Subject: [PATCH 063/101] Add verbatim test --- test/libyul/yulPureInterpreterTests/verbatim.yul | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 test/libyul/yulPureInterpreterTests/verbatim.yul diff --git a/test/libyul/yulPureInterpreterTests/verbatim.yul b/test/libyul/yulPureInterpreterTests/verbatim.yul new file mode 100644 index 000000000000..512cf3759c5a --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/verbatim.yul @@ -0,0 +1,12 @@ +{ + let double := verbatim_1i_1o(hex"600202", 1) +} +// The hext sequence was evaluated before verbatim +// Expection for this test should be changed to `ImpureBuiltinEncountered` +// if in the future if the hex sequence is evaluated after. + +// ---- +// Execution result: UnlimitedLiteralEncountered +// Outter most variable values: +// +// Call trace: From 2dd454384402e58668988d958ddd4c7103f1b77e Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 17:19:21 +0700 Subject: [PATCH 064/101] Remove redundant public: --- libyul/tools/interpreter/PureEVMInstructionInterpreter.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libyul/tools/interpreter/PureEVMInstructionInterpreter.h b/libyul/tools/interpreter/PureEVMInstructionInterpreter.h index 15b5acc99bee..fbf081f330a2 100644 --- a/libyul/tools/interpreter/PureEVMInstructionInterpreter.h +++ b/libyul/tools/interpreter/PureEVMInstructionInterpreter.h @@ -73,7 +73,6 @@ class PureEVMInstructionInterpreter langutil::EVMVersion m_evmVersion; PureInterpreterState& m_state; -public: }; } // solidity::yul::test From 62a0a96cd22fefe5508e663a5ed9638ee7697d59 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 17:28:12 +0700 Subject: [PATCH 065/101] Optimize map usage --- libyul/tools/interpreter/PureInterpreter.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index a31490c35797..402b0c4c4848 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -60,8 +60,8 @@ ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) for (size_t i = 0; i < values.size(); ++i) { YulName varName = _assignment.variableNames.at(i).name; - solAssert(m_variables.count(varName), ""); - m_variables[varName] = values.at(i); + auto [_, isNew] = m_variables.insert_or_assign(varName, values.at(i)); + solAssert(!isNew, ""); } return ExecutionOk { ControlFlowState::Default }; } @@ -84,8 +84,8 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat for (size_t i = 0; i < values.size(); ++i) { YulName varName = _declaration.variables.at(i).name; - solAssert(!m_variables.count(varName), ""); - m_variables[varName] = values.at(i); + auto [_, isNew] = m_variables.insert_or_assign(varName, values.at(i)); + solAssert(isNew, ""); m_scope->addDeclaredVariable(varName); } return ExecutionOk { ControlFlowState::Default }; @@ -227,8 +227,9 @@ EvaluationResult PureInterpreter::operator()(Literal const& _literal) EvaluationResult PureInterpreter::operator()(Identifier const& _identifier) { - solAssert(m_variables.count(_identifier.name), ""); - return EvaluationOk(m_variables.at(_identifier.name)); + auto it = m_variables.find(_identifier.name); + solAssert(it != m_variables.end(), ""); + return EvaluationOk(it->second); } EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) From 7cda001a694dd122697eec8e37fac9b3ce3921a8 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 17:32:00 +0700 Subject: [PATCH 066/101] Remove redundant terminated check --- libyul/tools/interpreter/PureInterpreter.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index 402b0c4c4848..6b94e865c3c1 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -248,9 +248,7 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) { PureEVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state); - EvaluationResult value = interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); - if (auto* terminated = std::get_if(&value)) return *terminated; - return value; + return interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); } } From 1e46f78fef0b710483757da3bada2d0028f49a9d Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 17:35:37 +0700 Subject: [PATCH 067/101] Remove redundant terminated result --- libyul/tools/interpreter/Results.h | 5 ----- test/libyul/YulPureInterpreterTest.cpp | 1 - 2 files changed, 6 deletions(-) diff --git a/libyul/tools/interpreter/Results.h b/libyul/tools/interpreter/Results.h index d4c0a94fdfaf..767fb4c676dc 100644 --- a/libyul/tools/interpreter/Results.h +++ b/libyul/tools/interpreter/Results.h @@ -37,10 +37,6 @@ class ExplicitlyTerminated : public ExecutionTerminatedCommon -{ -}; - class StepLimitReached : public ExecutionTerminatedCommon { }; @@ -68,7 +64,6 @@ class TraceLimitReached: public ExecutionTerminatedCommon using ExecutionTerminated = std::variant< ExplicitlyTerminated, - ExplicitlyTerminatedWithReturn, StepLimitReached, RecursionDepthLimitReached, ExpressionNestingLimitReached, diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index ad4629b6d619..1b464a8744a2 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -147,7 +147,6 @@ void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, tools::i [&](ExecutionTerminated terminated) { return std::visit(GenericVisitor{ [&](ExplicitlyTerminated) { return "ExplicitlyTerminated"; }, - [&](ExplicitlyTerminatedWithReturn) { return "ExplicitlyTerminatedWithReturn"; }, [&](StepLimitReached) { return "StepLimitReached"; }, [&](RecursionDepthLimitReached) { return "RecursionDepthLimitReached"; }, [&](ExpressionNestingLimitReached) { return "ExpressionNestingLimitReached"; }, From bfba77c9d902d7b6eeaa4be0b0a0057cf98c99c3 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 17:36:29 +0700 Subject: [PATCH 068/101] Add test for stop instruction --- test/libyul/yulPureInterpreterTests/stop.yul | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 test/libyul/yulPureInterpreterTests/stop.yul diff --git a/test/libyul/yulPureInterpreterTests/stop.yul b/test/libyul/yulPureInterpreterTests/stop.yul new file mode 100644 index 000000000000..485c93b4b51c --- /dev/null +++ b/test/libyul/yulPureInterpreterTests/stop.yul @@ -0,0 +1,11 @@ +{ + let x := 1 + stop() + x := 2 +} +// ---- +// Execution result: ExplicitlyTerminated +// Outter most variable values: +// x = 1 +// +// Call trace: From 7d6255ea5a627f67914997631322b5b2ec56614c Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 18:01:35 +0700 Subject: [PATCH 069/101] Update tests to remove trailing space --- .../tools/interpreter/PureInterpreterState.cpp | 4 +++- .../yulPureInterpreterTests/ambiguous_vars.yul | 4 ++-- .../function_scopes.yul | 18 +++++++++--------- test/libyul/yulPureInterpreterTests/loop.yul | 16 ++++++++-------- .../pure_instructions/.generate-test.py | 2 +- .../pure_instructions/add.yul | 2 +- .../pure_instructions/addmod.yul | 2 +- .../pure_instructions/and.yul | 2 +- .../pure_instructions/byte.yul | 2 +- .../pure_instructions/div.yul | 2 +- .../pure_instructions/eq.yul | 2 +- .../pure_instructions/exp.yul | 2 +- .../pure_instructions/gt.yul | 2 +- .../pure_instructions/iszero.yul | 2 +- .../pure_instructions/lt.yul | 2 +- .../pure_instructions/mod.yul | 2 +- .../pure_instructions/mul.yul | 2 +- .../pure_instructions/mulmod.yul | 2 +- .../pure_instructions/not.yul | 2 +- .../pure_instructions/or.yul | 2 +- .../pure_instructions/sar.yul | 2 +- .../pure_instructions/sdiv.yul | 2 +- .../pure_instructions/sgt.yul | 2 +- .../pure_instructions/shl.yul | 2 +- .../pure_instructions/shr.yul | 2 +- .../pure_instructions/signextend.yul | 2 +- .../pure_instructions/slt.yul | 2 +- .../pure_instructions/smod.yul | 2 +- .../pure_instructions/sub.yul | 2 +- .../pure_instructions/xor.yul | 2 +- .../shadowed_symbol.yul | 2 +- 31 files changed, 49 insertions(+), 47 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreterState.cpp b/libyul/tools/interpreter/PureInterpreterState.cpp index 597e17885e11..71fe9e864819 100644 --- a/libyul/tools/interpreter/PureInterpreterState.cpp +++ b/libyul/tools/interpreter/PureInterpreterState.cpp @@ -66,7 +66,9 @@ void PureInterpreterState::dumpTraces(std::ostream& _out) const bool areIdentical = &stackTrace.back()->definition == &returnTrace.definition; solAssert(areIdentical); - _out << "[RETURN] "; + _out << "[RETURN]"; + if (!returnTrace.returnedValues.empty()) + _out << " "; print_values(returnTrace.returnedValues); stackTrace.pop_back(); } diff --git a/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul b/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul index 54e749345ebd..2da7f9fb01a3 100644 --- a/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul +++ b/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul @@ -14,6 +14,6 @@ // // Call trace: // [CALL] fake_mstore(32, 2) -// │ [RETURN] +// │ [RETURN] // [CALL] fake_mstore(0, 3) -// │ [RETURN] +// │ [RETURN] diff --git a/test/libyul/yulPureInterpreterTests/function_scopes.yul b/test/libyul/yulPureInterpreterTests/function_scopes.yul index 7d3768d19cda..70397840b74f 100644 --- a/test/libyul/yulPureInterpreterTests/function_scopes.yul +++ b/test/libyul/yulPureInterpreterTests/function_scopes.yul @@ -25,15 +25,15 @@ // │ │ │ [CALL] g(0) // │ │ │ │ [CALL] f(0) // │ │ │ │ │ [CALL] fake_sstore(0, 7) -// │ │ │ │ │ │ [RETURN] -// │ │ │ │ │ [RETURN] -// │ │ │ │ [RETURN] -// │ │ │ [RETURN] +// │ │ │ │ │ │ [RETURN] +// │ │ │ │ │ [RETURN] +// │ │ │ │ [RETURN] +// │ │ │ [RETURN] // │ │ [CALL] f(0) // │ │ │ [CALL] fake_sstore(0, 7) -// │ │ │ │ [RETURN] -// │ │ │ [RETURN] -// │ │ [RETURN] +// │ │ │ │ [RETURN] +// │ │ │ [RETURN] +// │ │ [RETURN] // │ [CALL] fake_sstore(1, 8) -// │ │ [RETURN] -// │ [RETURN] +// │ │ [RETURN] +// │ [RETURN] diff --git a/test/libyul/yulPureInterpreterTests/loop.yul b/test/libyul/yulPureInterpreterTests/loop.yul index ab0d330efbd4..6d4aadca4d48 100644 --- a/test/libyul/yulPureInterpreterTests/loop.yul +++ b/test/libyul/yulPureInterpreterTests/loop.yul @@ -11,18 +11,18 @@ // // Call trace: // [CALL] fake_mstore(10, 8192) -// │ [RETURN] +// │ [RETURN] // [CALL] fake_mstore(15, 12288) -// │ [RETURN] +// │ [RETURN] // [CALL] fake_mstore(20, 16384) -// │ [RETURN] +// │ [RETURN] // [CALL] fake_mstore(25, 20480) -// │ [RETURN] +// │ [RETURN] // [CALL] fake_mstore(30, 24576) -// │ [RETURN] +// │ [RETURN] // [CALL] fake_mstore(35, 28672) -// │ [RETURN] +// │ [RETURN] // [CALL] fake_mstore(40, 32768) -// │ [RETURN] +// │ [RETURN] // [CALL] fake_mstore(45, 36864) -// │ [RETURN] +// │ [RETURN] diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py index 45fe68eae109..96414d647433 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py @@ -26,7 +26,7 @@ def gen_test(fn_name: str, *, param_cnt: int, calc: Callable[[tuple[int, ...]], src.append(""" function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - """) +""") if test_numbers is None: if param_cnt == 1: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul index 4934b62ca2a3..e9ad7c771d13 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(add(0x0, 0x0), 0x0) check(add(0x0, 0x1), 0x1) check(add(0x0, 0x2), 0x2) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul index 84e60a296359..99b69c04e184 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x0) check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x65d1cf826d6464457ae01220a0b5fdf6b37c83bec35900b77d52b314abe9e47e) check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x369f68bf83db6415dd647089401beb7bbe37d9e8ea95ec53050df3454fd8ba3f) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul index c884d6de84c1..86916c37c4ca 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(and(0x0, 0x0), 0x0) check(and(0x0, 0x1), 0x0) check(and(0x0, 0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul index 20e4c828adf8..c0fef10f08a3 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x0) check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x0) check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul index 1fbb1f32c825..06fb573f0b08 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(div(0x0, 0x0), 0x0) check(div(0x0, 0x1), 0x0) check(div(0x0, 0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul index bd3ea49e7044..f8d4b9517ef6 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(eq(0x0, 0x0), 0x1) check(eq(0x0, 0x1), 0x0) check(eq(0x0, 0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul index 57cd9d975c46..7850976a4537 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(exp(0x0, 0x0), 0x1) check(exp(0x0, 0x1), 0x0) check(exp(0x0, 0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul index 102171b50556..a51c2c42175d 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(gt(0x0, 0x0), 0x0) check(gt(0x0, 0x1), 0x0) check(gt(0x0, 0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul index 5486a5d8f318..731386d0a703 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(iszero(0x0), 0x1) check(iszero(0x1), 0x0) check(iszero(0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul index 5259b9c739ef..753288d72570 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(lt(0x0, 0x0), 0x0) check(lt(0x0, 0x1), 0x1) check(lt(0x0, 0x2), 0x1) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul index ad0bf68fd279..38997b2f2348 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(mod(0x0, 0x0), 0x0) check(mod(0x0, 0x1), 0x0) check(mod(0x0, 0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul index 5e6e56de0452..a34c1ee6fff7 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(mul(0x0, 0x0), 0x0) check(mul(0x0, 0x1), 0x0) check(mul(0x0, 0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul index f2e6ad879ba8..78326db0d194 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x168054808d0b4226e2f7d20f66d64728fd7734583dd36b66d7966a085cbcfda0) check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x14fc3916121454e5ab8985b6c8045fd2a9c752dc8d0cd64706cfc963b8627024) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul index 3a2e629fcb0e..afcbd2ceee14 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(not(0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) check(not(0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) check(not(0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul index b37ab923a456..5538b73de373 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(or(0x0, 0x0), 0x0) check(or(0x0, 0x1), 0x1) check(or(0x0, 0x2), 0x2) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul index 05ac2d97f136..2d43330010f5 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(sar(0x0, 0x0), 0x0) check(sar(0x0, 0x1), 0x1) check(sar(0x0, 0x2), 0x2) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul index 255bfb8ef16c..aff15c770041 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(sdiv(0x0, 0x0), 0x0) check(sdiv(0x0, 0x1), 0x0) check(sdiv(0x0, 0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul index 90dfdd9d9d32..f4208c01755c 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(sgt(0x0, 0x0), 0x0) check(sgt(0x0, 0x1), 0x0) check(sgt(0x0, 0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul index 9647160f2c5a..690b08ea0ef9 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(shl(0x0, 0x0), 0x0) check(shl(0x0, 0x1), 0x1) check(shl(0x0, 0x2), 0x2) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul index 94a7acf56c47..37d44a05ab00 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(shr(0x0, 0x0), 0x0) check(shr(0x0, 0x1), 0x1) check(shr(0x0, 0x2), 0x2) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul index dbe11f6b5446..1b924af29bd2 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(signextend(0x0, 0x0), 0x0) check(signextend(0x0, 0x1), 0x1) check(signextend(0x0, 0x2), 0x2) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul index 9cba6e433bf2..9a700a7193a2 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(slt(0x0, 0x0), 0x0) check(slt(0x0, 0x1), 0x1) check(slt(0x0, 0x2), 0x1) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul index 1771ad50caab..50bfad9029a7 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(smod(0x0, 0x0), 0x0) check(smod(0x0, 0x1), 0x0) check(smod(0x0, 0x2), 0x0) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul index f1f072dabf24..ff2fa11daa56 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(sub(0x0, 0x0), 0x0) check(sub(0x0, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) check(sub(0x0, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul index a80579e556fd..8741a14e8094 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul @@ -2,7 +2,7 @@ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } - + check(xor(0x0, 0x0), 0x0) check(xor(0x0, 0x1), 0x1) check(xor(0x0, 0x2), 0x2) diff --git a/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul b/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul index d658c8f53112..de906dd685c4 100644 --- a/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul +++ b/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul @@ -19,4 +19,4 @@ // // Call trace: // [CALL] f() -// │ [RETURN] +// │ [RETURN] From a8f4d1600fab077fe85b19f73cc5737bb97a546b Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 18:02:59 +0700 Subject: [PATCH 070/101] Fix styling for addTrace --- libyul/tools/interpreter/PureInterpreterState.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreterState.h b/libyul/tools/interpreter/PureInterpreterState.h index a9b98a30187d..f757a3804907 100644 --- a/libyul/tools/interpreter/PureInterpreterState.h +++ b/libyul/tools/interpreter/PureInterpreterState.h @@ -82,12 +82,12 @@ struct PureInterpreterState /// Will do nothing if config.maxTraceSize == 0 /// - the log entry will not be constructed in this case template - std::optional addTrace(const Args&... args) + std::optional addTrace(Args const&... _args) { if (config.maxTraceSize == 0) return std::nullopt; if (traces.size() > config.maxTraceSize) return TraceLimitReached(); - traces.emplace_back(std::in_place_type, args...); + traces.emplace_back(std::in_place_type, _args...); return std::nullopt; } From 38e4cc63aac3192bdbd2ab3af36d4475c288c317 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 18:10:16 +0700 Subject: [PATCH 071/101] Fix spelling --- test/libyul/YulPureInterpreterTest.cpp | 10 +++++----- test/libyul/YulPureInterpreterTest.h | 2 +- test/libyul/yulPureInterpreterTests/ambiguous_vars.yul | 2 +- .../yulPureInterpreterTests/bounded_recursion.yul | 2 +- test/libyul/yulPureInterpreterTests/exp.yul | 2 +- .../expr_nesting_depth_exceeded.yul | 2 +- .../expr_nesting_depth_not_exceeded.yul | 2 +- test/libyul/yulPureInterpreterTests/function_calls.yul | 2 +- .../libyul/yulPureInterpreterTests/function_scopes.yul | 2 +- test/libyul/yulPureInterpreterTests/hex_literals.yul | 2 +- .../impure_instructions/address.yul | 2 +- .../impure_instructions/balance.yul | 2 +- .../impure_instructions/basefee.yul | 2 +- .../impure_instructions/blobbasefee.yul | 2 +- .../impure_instructions/blobhash.yul | 2 +- .../impure_instructions/blockhash.yul | 2 +- .../impure_instructions/call.yul | 2 +- .../impure_instructions/callcode.yul | 2 +- .../impure_instructions/calldatacopy.yul | 2 +- .../impure_instructions/calldataload.yul | 2 +- .../impure_instructions/calldatasize.yul | 2 +- .../impure_instructions/caller.yul | 2 +- .../impure_instructions/callvalue.yul | 2 +- .../impure_instructions/chainid.yul | 2 +- .../impure_instructions/codecopy.yul | 2 +- .../impure_instructions/codesize.yul | 2 +- .../impure_instructions/coinbase.yul | 2 +- .../impure_instructions/create.yul | 2 +- .../impure_instructions/create2.yul | 2 +- .../impure_instructions/datacopy.yul | 2 +- .../impure_instructions/dataoffset.yul | 2 +- .../impure_instructions/datasize.yul | 2 +- .../impure_instructions/delegatecall.yul | 2 +- .../impure_instructions/extcodecopy.yul | 2 +- .../impure_instructions/extcodehash.yul | 2 +- .../impure_instructions/extcodesize.yul | 2 +- .../impure_instructions/gas.yul | 2 +- .../impure_instructions/gaslimit.yul | 2 +- .../impure_instructions/gasprice.yul | 2 +- .../impure_instructions/invalid.yul | 2 +- .../impure_instructions/keccak256.yul | 2 +- .../impure_instructions/linkersymbol.yul | 2 +- .../impure_instructions/loadimmutable.yul | 2 +- .../impure_instructions/log0.yul | 2 +- .../impure_instructions/log1.yul | 2 +- .../impure_instructions/log2.yul | 2 +- .../impure_instructions/log3.yul | 2 +- .../impure_instructions/log4.yul | 2 +- .../impure_instructions/mcopy.yul | 2 +- .../impure_instructions/memoryguard.yul | 2 +- .../impure_instructions/mload.yul | 2 +- .../impure_instructions/msize.yul | 2 +- .../impure_instructions/mstore.yul | 2 +- .../impure_instructions/mstore8.yul | 2 +- .../impure_instructions/number.yul | 2 +- .../impure_instructions/origin.yul | 2 +- .../impure_instructions/prevrandao.yul | 2 +- .../impure_instructions/return.yul | 2 +- .../impure_instructions/returndatacopy.yul | 2 +- .../impure_instructions/returndatasize.yul | 2 +- .../impure_instructions/revert.yul | 2 +- .../impure_instructions/selfbalance.yul | 2 +- .../impure_instructions/selfdestruct.yul | 2 +- .../impure_instructions/setimmutable.yul | 2 +- .../impure_instructions/sload.yul | 2 +- .../impure_instructions/sstore.yul | 2 +- .../impure_instructions/staticcall.yul | 2 +- .../impure_instructions/timestamp.yul | 2 +- .../impure_instructions/tload.yul | 2 +- .../impure_instructions/tstore.yul | 2 +- .../yulPureInterpreterTests/infinite_recursion.yul | 2 +- .../infinite_recursion_tracelimit.yul | 2 +- test/libyul/yulPureInterpreterTests/leave.yul | 2 +- test/libyul/yulPureInterpreterTests/leave_for_init.yul | 2 +- test/libyul/yulPureInterpreterTests/loop.yul | 2 +- .../yulPureInterpreterTests/pop_byte_shr_func.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/add.yul | 2 +- .../pure_instructions/addmod.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/and.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/byte.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/div.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/eq.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/exp.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/gt.yul | 2 +- .../pure_instructions/iszero.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/lt.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/mod.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/mul.yul | 2 +- .../pure_instructions/mulmod.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/not.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/or.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/sar.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/sdiv.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/sgt.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/shl.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/shr.yul | 2 +- .../pure_instructions/signextend.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/slt.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/smod.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/sub.yul | 2 +- .../yulPureInterpreterTests/pure_instructions/xor.yul | 2 +- test/libyul/yulPureInterpreterTests/recursion.yul | 2 +- .../libyul/yulPureInterpreterTests/shadowed_symbol.yul | 2 +- test/libyul/yulPureInterpreterTests/smoke.yul | 2 +- .../yulPureInterpreterTests/step_limit_not_reached.yul | 2 +- .../yulPureInterpreterTests/step_limit_reached.yul | 2 +- test/libyul/yulPureInterpreterTests/stop.yul | 2 +- .../yulPureInterpreterTests/switch_statement.yul | 2 +- test/libyul/yulPureInterpreterTests/verbatim.yul | 2 +- 109 files changed, 113 insertions(+), 113 deletions(-) diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index 1b464a8744a2..0916b17152a9 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -110,13 +110,13 @@ std::string YulPureInterpreterTest::interpret() const PureInterpreter interpreter(state, dialect, *subscope, 0); ExecutionResult res = interpreter.execute(block.statements); - VariableValuesMap const& outterMostVariables = interpreter.allVariables(); + VariableValuesMap const& outerMostVariables = interpreter.allVariables(); dumpExecutionData( resultStream, res, state, - outterMostVariables + outerMostVariables ); return resultStream.str(); @@ -126,15 +126,15 @@ void YulPureInterpreterTest::dumpExecutionData( std::ostream& _stream, tools::interpreter::ExecutionResult _res, tools::interpreter::PureInterpreterState const& _state, - VariableValuesMap const& _outterMostVariables + VariableValuesMap const& _outerMostVariables ) const { _stream << "Execution result: "; dumpExecutionResult(_stream, _res); _stream << std::endl; - _stream << "Outter most variable values:" << std::endl; - dumpVariables(_stream, _outterMostVariables); + _stream << "Outer most variable values:" << std::endl; + dumpVariables(_stream, _outerMostVariables); _stream << std::endl; _state.dumpTraces(_stream); diff --git a/test/libyul/YulPureInterpreterTest.h b/test/libyul/YulPureInterpreterTest.h index 68e8d5f5a0ca..4083106b40b1 100644 --- a/test/libyul/YulPureInterpreterTest.h +++ b/test/libyul/YulPureInterpreterTest.h @@ -52,7 +52,7 @@ class YulPureInterpreterTest: public solidity::frontend::test::EVMVersionRestric std::ostream& _stream, tools::interpreter::ExecutionResult _res, tools::interpreter::PureInterpreterState const& _state, - tools::interpreter::VariableValuesMap const& _outterMostVariables + tools::interpreter::VariableValuesMap const& _outerMostVariables ) const; void dumpExecutionResult(std::ostream& _stream, tools::interpreter::ExecutionResult _res) const; void dumpVariables(std::ostream& _stream, tools::interpreter::VariableValuesMap const& _variables) const; diff --git a/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul b/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul index 2da7f9fb01a3..046c89600ea3 100644 --- a/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul +++ b/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul @@ -9,7 +9,7 @@ } // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // a = 0 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/bounded_recursion.yul b/test/libyul/yulPureInterpreterTests/bounded_recursion.yul index 49ab91820ecf..a1d6bd8ab5f1 100644 --- a/test/libyul/yulPureInterpreterTests/bounded_recursion.yul +++ b/test/libyul/yulPureInterpreterTests/bounded_recursion.yul @@ -15,7 +15,7 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // res = 150 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/exp.yul b/test/libyul/yulPureInterpreterTests/exp.yul index 25a6337ee5bc..8bd3f0d20354 100644 --- a/test/libyul/yulPureInterpreterTests/exp.yul +++ b/test/libyul/yulPureInterpreterTests/exp.yul @@ -5,7 +5,7 @@ // printHex: true // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // res = 0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e39 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul index 4b934248b845..fbce52ca4bd2 100644 --- a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul +++ b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul @@ -11,7 +11,7 @@ // maxExprNesting: 64 // ---- // Execution result: ExpressionNestingLimitReached -// Outter most variable values: +// Outer most variable values: // // Call trace: // [CALL] f(0) diff --git a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul index c3354c9b8b6a..037780831d34 100644 --- a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul +++ b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul @@ -16,7 +16,7 @@ // maxExprNesting: 64 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: // [CALL] f(0) diff --git a/test/libyul/yulPureInterpreterTests/function_calls.yul b/test/libyul/yulPureInterpreterTests/function_calls.yul index c9a2e9b32126..1a186455bef2 100644 --- a/test/libyul/yulPureInterpreterTests/function_calls.yul +++ b/test/libyul/yulPureInterpreterTests/function_calls.yul @@ -7,7 +7,7 @@ } // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // r = 13 // t = 42 // diff --git a/test/libyul/yulPureInterpreterTests/function_scopes.yul b/test/libyul/yulPureInterpreterTests/function_scopes.yul index 70397840b74f..9dfaee5ade5d 100644 --- a/test/libyul/yulPureInterpreterTests/function_scopes.yul +++ b/test/libyul/yulPureInterpreterTests/function_scopes.yul @@ -16,7 +16,7 @@ } // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: // [CALL] f(1) diff --git a/test/libyul/yulPureInterpreterTests/hex_literals.yul b/test/libyul/yulPureInterpreterTests/hex_literals.yul index ca85bdde4aac..2710e20c4d02 100644 --- a/test/libyul/yulPureInterpreterTests/hex_literals.yul +++ b/test/libyul/yulPureInterpreterTests/hex_literals.yul @@ -6,7 +6,7 @@ // printHex: true // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // x = 0x112233445566778899aabbccddeeff6677889900000000000000000000000000 // y = 0x1234abcd00000000000000000000000000000000000000000000000000000000 // diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/address.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/address.yul index 85f453227f1e..2b1ddf47fb92 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/address.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/address.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/balance.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/balance.yul index 343c777c168d..0c33e9f953e2 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/balance.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/balance.yul @@ -7,7 +7,7 @@ // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul index 9f0825bbd412..9650fcc14b9e 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul index 9477ba9fe89c..78b3430d0796 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul index 187c54071c4c..11804c315769 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/blockhash.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/blockhash.yul index b3f078952b71..840636457eff 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/blockhash.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/blockhash.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/call.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/call.yul index 5346b910e010..e10d9383cb3a 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/call.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/call.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/callcode.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/callcode.yul index 489430a97749..d08fd104b923 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/callcode.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/callcode.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/calldatacopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/calldatacopy.yul index 1f8d66b07e44..4608344ffc66 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/calldatacopy.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/calldatacopy.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/calldataload.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/calldataload.yul index ed682252efda..5c13eac0866d 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/calldataload.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/calldataload.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/calldatasize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/calldatasize.yul index f33f3506704b..95d11a8fef14 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/calldatasize.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/calldatasize.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/caller.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/caller.yul index 09dfea15762e..2a5b2eb2b0cb 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/caller.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/caller.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/callvalue.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/callvalue.yul index a9331db9ee30..438d54dba655 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/callvalue.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/callvalue.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul index cdb6f3d5d50f..01d702f4faad 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/codecopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/codecopy.yul index c1ffaaefd140..bdc57e21d796 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/codecopy.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/codecopy.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/codesize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/codesize.yul index c9327400fb01..ab8c05b8aa68 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/codesize.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/codesize.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/coinbase.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/coinbase.yul index 2d00acf9936d..374b57add637 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/coinbase.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/coinbase.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/create.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/create.yul index b4637db2e0fa..304bc59125be 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/create.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/create.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul index b008705e817c..618d8bfd6bac 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/datacopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/datacopy.yul index 495f68146058..e3d883a7e5de 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/datacopy.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/datacopy.yul @@ -8,7 +8,7 @@ object "obj" { } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul index 7df4a6dd586b..681525dabb6b 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul @@ -12,7 +12,7 @@ object "obj" { // ---- // Execution result: UnlimitedLiteralEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul index 6cb1d460c179..d9294743cb44 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul @@ -12,7 +12,7 @@ object "obj" { // ---- // Execution result: UnlimitedLiteralEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/delegatecall.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/delegatecall.yul index e336b215ad53..8346243bdd57 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/delegatecall.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/delegatecall.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodecopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodecopy.yul index 70a99ced2059..5e4e5479876d 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodecopy.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodecopy.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul index 6b8f893e2bf3..a0f8a3f83187 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodesize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodesize.yul index 25ac2437e092..2b4bb24921ed 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodesize.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodesize.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/gas.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/gas.yul index 96ab94aca8c8..51cfd8452bdf 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/gas.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/gas.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/gaslimit.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/gaslimit.yul index ee89b9542ff5..e4baab65f772 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/gaslimit.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/gaslimit.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/gasprice.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/gasprice.yul index cc3ceb842ce5..9feb75d9b39b 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/gasprice.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/gasprice.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/invalid.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/invalid.yul index d2dec601bb31..623675f47880 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/invalid.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/invalid.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/keccak256.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/keccak256.yul index d4c39c1e6ef9..59f5588db8b3 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/keccak256.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/keccak256.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul index a89cc787120a..38fdc1cc0ee1 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul @@ -12,7 +12,7 @@ object "obj" { // ---- // Execution result: UnlimitedLiteralEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul index d4dfbbdd16a0..77fe97228465 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul @@ -12,7 +12,7 @@ object "obj" { // ---- // Execution result: UnlimitedLiteralEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/log0.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/log0.yul index b0b6f995f839..4cbaaffba8b0 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/log0.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/log0.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/log1.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/log1.yul index b23f79da5a3c..68349084d031 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/log1.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/log1.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/log2.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/log2.yul index b59dce457496..6aa5d02bad13 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/log2.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/log2.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/log3.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/log3.yul index 1acf5915e3d9..226bd9b8e5a3 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/log3.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/log3.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/log4.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/log4.yul index 882f1ee64892..ff17f28e4d46 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/log4.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/log4.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul index 78146c5656df..0fdc24bec63f 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul index 4b18df5a1dc7..e3f6bc5d5d78 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul @@ -8,7 +8,7 @@ object "obj" { } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/mload.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/mload.yul index bb39322ac2a0..f24b3085e930 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/mload.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/mload.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/msize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/msize.yul index 1d2c0329558e..3d61b9693890 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/msize.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/msize.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/mstore.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/mstore.yul index b9a5a0581b91..f37ecd811b70 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/mstore.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/mstore.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/mstore8.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/mstore8.yul index 95420fdfa978..adb7d77ed826 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/mstore8.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/mstore8.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/number.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/number.yul index 20694912ee50..4f82d9e6ba2c 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/number.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/number.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/origin.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/origin.yul index 72230c8caa99..fc32d6729038 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/origin.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/origin.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul index ea6ec685c757..253732bea4ef 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/return.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/return.yul index dae8d649a4e1..6857eefcac63 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/return.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/return.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul index 59d0c5dd144b..605867bd47ea 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul index 3f274cfb8db9..a504fda49176 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/revert.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/revert.yul index 76f38d5782e8..f41c9dde356e 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/revert.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/revert.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul index 080742b798eb..95abe003f4ec 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/selfdestruct.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/selfdestruct.yul index e072b95c0e8b..b09b497881b6 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/selfdestruct.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/selfdestruct.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul index 1d90f54fdc8b..2145426ef4d2 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul @@ -12,7 +12,7 @@ object "obj" { // ---- // Execution result: UnlimitedLiteralEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/sload.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/sload.yul index 5fb2cba5e9d1..a8cd1ba78116 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/sload.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/sload.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/sstore.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/sstore.yul index a0f641445dc7..9187d6e43c1f 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/sstore.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/sstore.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul index 7677738e89a4..360dab33b6c0 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/timestamp.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/timestamp.yul index a558b5000d54..c600011d7603 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/timestamp.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/timestamp.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul index 1cfd3a4b4cdf..ec991b559203 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul index 7de0654c7cab..4726cdb67edb 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul @@ -6,7 +6,7 @@ } // ---- // Execution result: ImpureBuiltinEncountered -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/infinite_recursion.yul b/test/libyul/yulPureInterpreterTests/infinite_recursion.yul index 9ad3d966f284..ce61e1d11748 100644 --- a/test/libyul/yulPureInterpreterTests/infinite_recursion.yul +++ b/test/libyul/yulPureInterpreterTests/infinite_recursion.yul @@ -8,6 +8,6 @@ // maxTraceSize: 0 // ---- // Execution result: RecursionDepthLimitReached -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul b/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul index 4f5e3f27cf83..cb0bb5da30d3 100644 --- a/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul +++ b/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul @@ -10,7 +10,7 @@ // maxTraceSize: 10 // ---- // Execution result: TraceLimitReached -// Outter most variable values: +// Outer most variable values: // // Call trace: // [CALL] f() diff --git a/test/libyul/yulPureInterpreterTests/leave.yul b/test/libyul/yulPureInterpreterTests/leave.yul index 743837bba805..c85ba4c67239 100644 --- a/test/libyul/yulPureInterpreterTests/leave.yul +++ b/test/libyul/yulPureInterpreterTests/leave.yul @@ -12,7 +12,7 @@ // EVMVersion: >=constantinople // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // a = 5 // b = 1 // diff --git a/test/libyul/yulPureInterpreterTests/leave_for_init.yul b/test/libyul/yulPureInterpreterTests/leave_for_init.yul index ad237897831a..8299f8e572d4 100644 --- a/test/libyul/yulPureInterpreterTests/leave_for_init.yul +++ b/test/libyul/yulPureInterpreterTests/leave_for_init.yul @@ -10,7 +10,7 @@ // EVMVersion: >=constantinople // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // a = 0 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/loop.yul b/test/libyul/yulPureInterpreterTests/loop.yul index 6d4aadca4d48..69b16297a9df 100644 --- a/test/libyul/yulPureInterpreterTests/loop.yul +++ b/test/libyul/yulPureInterpreterTests/loop.yul @@ -7,7 +7,7 @@ } // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: // [CALL] fake_mstore(10, 8192) diff --git a/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul b/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul index 833e4c2bfa79..dff8433808ae 100644 --- a/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul +++ b/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul @@ -6,7 +6,7 @@ // EVMVersion: >=constantinople // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: // [CALL] f() diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul index e9ad7c771d13..492d8522a108 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul index 99b69c04e184..d82d8dd2503f 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul index 86916c37c4ca..677b8e924e1c 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul index c0fef10f08a3..2c5f014fb312 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul @@ -57,6 +57,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul index 06fb573f0b08..c301946a8c4f 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul index f8d4b9517ef6..dc7e7bcc5f55 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul index 7850976a4537..a492c6c5c636 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul index a51c2c42175d..1da16455a860 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul index 731386d0a703..4dd535dd9003 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul @@ -19,6 +19,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul index 753288d72570..3427690e5f75 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul index 38997b2f2348..2a912548a1a0 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul index a34c1ee6fff7..2bb51c2bcdfa 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul index 78326db0d194..d5887ae81993 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul index afcbd2ceee14..71caf36036cb 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul @@ -19,6 +19,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul index 5538b73de373..a06bdde66a2d 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul index 2d43330010f5..daed23f11d2e 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul index aff15c770041..241fe9a19099 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul index f4208c01755c..56b422946402 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul index 690b08ea0ef9..013626e37a41 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul index 37d44a05ab00..d3e7bb3ef2b7 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul index 1b924af29bd2..e295a0c6ae97 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul index 9a700a7193a2..499a7ffbb861 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul index 50bfad9029a7..fa2afc4e679a 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul index ff2fa11daa56..91eabfd6d22d 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul index 8741a14e8094..de9872b308a4 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul @@ -72,6 +72,6 @@ // maxTraceSize: 0 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/recursion.yul b/test/libyul/yulPureInterpreterTests/recursion.yul index 1e5670caaff9..3114c69c1159 100644 --- a/test/libyul/yulPureInterpreterTests/recursion.yul +++ b/test/libyul/yulPureInterpreterTests/recursion.yul @@ -9,7 +9,7 @@ } // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // res = 21 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul b/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul index de906dd685c4..ac5f5b3ca308 100644 --- a/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul +++ b/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul @@ -15,7 +15,7 @@ // EVMVersion: >=constantinople // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: // [CALL] f() diff --git a/test/libyul/yulPureInterpreterTests/smoke.yul b/test/libyul/yulPureInterpreterTests/smoke.yul index 5e5c27965d25..6e42acabe472 100644 --- a/test/libyul/yulPureInterpreterTests/smoke.yul +++ b/test/libyul/yulPureInterpreterTests/smoke.yul @@ -1,6 +1,6 @@ {} // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/step_limit_not_reached.yul b/test/libyul/yulPureInterpreterTests/step_limit_not_reached.yul index 7e9ec6ed8063..6da456ef36ac 100644 --- a/test/libyul/yulPureInterpreterTests/step_limit_not_reached.yul +++ b/test/libyul/yulPureInterpreterTests/step_limit_not_reached.yul @@ -8,7 +8,7 @@ // maxSteps: 200 // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // i = 100 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/step_limit_reached.yul b/test/libyul/yulPureInterpreterTests/step_limit_reached.yul index 4b7dc05476aa..c8f2d9e380a8 100644 --- a/test/libyul/yulPureInterpreterTests/step_limit_reached.yul +++ b/test/libyul/yulPureInterpreterTests/step_limit_reached.yul @@ -8,7 +8,7 @@ // maxSteps: 100 // ---- // Execution result: StepLimitReached -// Outter most variable values: +// Outer most variable values: // i = 96 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/stop.yul b/test/libyul/yulPureInterpreterTests/stop.yul index 485c93b4b51c..9949bdf05d03 100644 --- a/test/libyul/yulPureInterpreterTests/stop.yul +++ b/test/libyul/yulPureInterpreterTests/stop.yul @@ -5,7 +5,7 @@ } // ---- // Execution result: ExplicitlyTerminated -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/switch_statement.yul b/test/libyul/yulPureInterpreterTests/switch_statement.yul index 368118277fa9..fa69ce75113e 100644 --- a/test/libyul/yulPureInterpreterTests/switch_statement.yul +++ b/test/libyul/yulPureInterpreterTests/switch_statement.yul @@ -7,7 +7,7 @@ } // ---- // Execution result: ExecutionOk -// Outter most variable values: +// Outer most variable values: // x = 1 // // Call trace: diff --git a/test/libyul/yulPureInterpreterTests/verbatim.yul b/test/libyul/yulPureInterpreterTests/verbatim.yul index 512cf3759c5a..33572c94a32b 100644 --- a/test/libyul/yulPureInterpreterTests/verbatim.yul +++ b/test/libyul/yulPureInterpreterTests/verbatim.yul @@ -7,6 +7,6 @@ // ---- // Execution result: UnlimitedLiteralEncountered -// Outter most variable values: +// Outer most variable values: // // Call trace: From 326bdfe7a2e94f69b4786cadfed4f5465e3dce7a Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 18:12:31 +0700 Subject: [PATCH 072/101] Fix linting error for generate-test.py --- .../pure_instructions/.generate-test.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py index 96414d647433..291d7d1ec673 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py @@ -18,7 +18,13 @@ def u256(num: int): def u2s(num: int): return int(num) - MX if (int(num) >> 255) > 0 else int(num) -def gen_test(fn_name: str, *, param_cnt: int, calc: Callable[[tuple[int, ...]], int], test_numbers: Union[Iterable[int], None] = None): +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None +): print('Generating test for', fn_name) src: list[str] = [] From 6d7a4ba6ce720b97f45082f8eae85186371f5fb8 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 21:17:53 +0700 Subject: [PATCH 073/101] Update EVMVersion in tests --- .../impure_instructions/basefee.yul | 2 ++ .../impure_instructions/blobbasefee.yul | 2 ++ .../impure_instructions/blobhash.yul | 2 ++ .../impure_instructions/chainid.yul | 2 ++ .../impure_instructions/create2.yul | 2 ++ .../impure_instructions/extcodehash.yul | 2 ++ .../yulPureInterpreterTests/impure_instructions/mcopy.yul | 2 ++ .../impure_instructions/prevrandao.yul | 2 ++ .../impure_instructions/returndatacopy.yul | 2 ++ .../impure_instructions/returndatasize.yul | 2 ++ .../impure_instructions/selfbalance.yul | 2 ++ .../impure_instructions/staticcall.yul | 2 ++ .../yulPureInterpreterTests/impure_instructions/tload.yul | 2 ++ .../impure_instructions/tstore.yul | 2 ++ .../pure_instructions/.generate-test.py | 8 +++++++- .../yulPureInterpreterTests/pure_instructions/sar.yul | 1 + .../yulPureInterpreterTests/pure_instructions/shl.yul | 1 + .../yulPureInterpreterTests/pure_instructions/shr.yul | 1 + 18 files changed, 38 insertions(+), 1 deletion(-) diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul index 9650fcc14b9e..4d19b863c801 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/basefee.yul @@ -4,6 +4,8 @@ pop(basefee()) x := 2 } +// ==== +// EVMVersion: >=london // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul index 78b3430d0796..ebfda71d46c9 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/blobbasefee.yul @@ -4,6 +4,8 @@ pop(blobbasefee()) x := 2 } +// ==== +// EVMVersion: >=cancun // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul index 11804c315769..e369f9ff41bc 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/blobhash.yul @@ -4,6 +4,8 @@ pop(blobhash(0)) x := 2 } +// ==== +// EVMVersion: >=cancun // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul index 01d702f4faad..49ac970dbbad 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/chainid.yul @@ -4,6 +4,8 @@ pop(chainid()) x := 2 } +// ==== +// EVMVersion: >=istanbul // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul index 618d8bfd6bac..7867259ab3ed 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/create2.yul @@ -4,6 +4,8 @@ pop(create2(0, 0, 0, 0)) x := 2 } +// ==== +// EVMVersion: >=constantinople // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul index a0f8a3f83187..8053a682cef0 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/extcodehash.yul @@ -4,6 +4,8 @@ pop(extcodehash(0)) x := 2 } +// ==== +// EVMVersion: >=constantinople // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul index 0fdc24bec63f..11eed638ff96 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/mcopy.yul @@ -4,6 +4,8 @@ mcopy(0, 0, 0) x := 2 } +// ==== +// EVMVersion: >=cancun // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul index 253732bea4ef..1d0a2a21d066 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/prevrandao.yul @@ -4,6 +4,8 @@ pop(prevrandao()) x := 2 } +// ==== +// EVMVersion: >=paris // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul index 605867bd47ea..d91a9afbce39 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatacopy.yul @@ -4,6 +4,8 @@ returndatacopy(0, 0, 0) x := 2 } +// ==== +// EVMVersion: >=byzantium // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul index a504fda49176..3cd311947fcd 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/returndatasize.yul @@ -4,6 +4,8 @@ pop(returndatasize()) x := 2 } +// ==== +// EVMVersion: >=byzantium // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul index 95abe003f4ec..250af8158473 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/selfbalance.yul @@ -4,6 +4,8 @@ pop(selfbalance()) x := 2 } +// ==== +// EVMVersion: >=istanbul // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul index 360dab33b6c0..1cef1ddf9748 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/staticcall.yul @@ -4,6 +4,8 @@ pop(staticcall(0, 0, 0, 0, 0, 0)) x := 2 } +// ==== +// EVMVersion: >=byzantium // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul index ec991b559203..fd2e7af9b4c0 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/tload.yul @@ -4,6 +4,8 @@ pop(tload(0)) x := 2 } +// ==== +// EVMVersion: >=cancun // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul index 4726cdb67edb..1f514d02999d 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/tstore.yul @@ -4,6 +4,8 @@ tstore(0, 0) x := 2 } +// ==== +// EVMVersion: >=cancun // ---- // Execution result: ImpureBuiltinEncountered // Outer most variable values: diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py index 291d7d1ec673..4304ffc9497c 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py @@ -23,7 +23,8 @@ def gen_test( *, param_cnt: int, calc: Callable[[tuple[int, ...]], int], - test_numbers: Union[Iterable[int], None] = None + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, ): print('Generating test for', fn_name) @@ -54,6 +55,8 @@ def gen_test( src.append('// ====') src.append('// maxTraceSize: 0') + if evm_version is not None: + src.append(f'// EVMVersion: {evm_version}') with open(fn_name + '.yul', 'w') as f: print('\n'.join(src), file=f) @@ -122,12 +125,15 @@ def main(): ], calc = lambda p: 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xff) gen_test('shl', + evm_version='>=constantinople', param_cnt = 2, calc = lambda p: p[1] << p[0] if p[0] < 32 else 0) gen_test('shr', + evm_version='>=constantinople', param_cnt = 2, calc = lambda p: p[1] >> p[0]) gen_test('sar', + evm_version='>=constantinople', param_cnt = 2, calc = sar) gen_test('addmod', diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul index daed23f11d2e..89821bab93dd 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul @@ -69,6 +69,7 @@ check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) } // ==== +// EVMVersion: >=constantinople // maxTraceSize: 0 // ---- // Execution result: ExecutionOk diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul index 013626e37a41..d1c4c1a99ad2 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul @@ -69,6 +69,7 @@ check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) } // ==== +// EVMVersion: >=constantinople // maxTraceSize: 0 // ---- // Execution result: ExecutionOk diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul index d3e7bb3ef2b7..db36f407876b 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul @@ -69,6 +69,7 @@ check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) } // ==== +// EVMVersion: >=constantinople // maxTraceSize: 0 // ---- // Execution result: ExecutionOk From 0d5223376e642f15845b79aa90084e63da9fb692 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 21:29:05 +0700 Subject: [PATCH 074/101] Add encoding when open file when generate test --- .../yulPureInterpreterTests/pure_instructions/.generate-test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py index 4304ffc9497c..6d66be6c3483 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py @@ -58,7 +58,7 @@ def gen_test( if evm_version is not None: src.append(f'// EVMVersion: {evm_version}') - with open(fn_name + '.yul', 'w') as f: + with open(fn_name + '.yul', 'w', encoding='utf-8') as f: print('\n'.join(src), file=f) def main(): From ea1c2976bf7f60e1fd26c6c2ed9524f023f5bfc1 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 21:29:50 +0700 Subject: [PATCH 075/101] Fix spelling Expection -> Expectation --- .../yulPureInterpreterTests/impure_instructions/dataoffset.yul | 2 +- .../yulPureInterpreterTests/impure_instructions/datasize.yul | 2 +- .../impure_instructions/linkersymbol.yul | 2 +- .../impure_instructions/loadimmutable.yul | 2 +- .../impure_instructions/setimmutable.yul | 2 +- test/libyul/yulPureInterpreterTests/verbatim.yul | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul index 681525dabb6b..5b0735631a3a 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/dataoffset.yul @@ -7,7 +7,7 @@ object "obj" { } } // "obj" was evaluated before `dataoffset` -// Expection for this test should be changed to `ImpureBuiltinEncountered` +// Expectation for this test should be changed to `ImpureBuiltinEncountered` // if in the future if "obj" is evaluated after // ---- diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul index d9294743cb44..ae0ca9d014db 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/datasize.yul @@ -7,7 +7,7 @@ object "obj" { } } // "obj" was evaluated before `datasize` -// Expection for this test should be changed to `ImpureBuiltinEncountered` +// Expectation for this test should be changed to `ImpureBuiltinEncountered` // if in the future if "obj" is evaluated after // ---- diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul index 38fdc1cc0ee1..278e2dd18826 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/linkersymbol.yul @@ -7,7 +7,7 @@ object "obj" { } } // "foo" was evaluated before `linkersymbol` -// Expection for this test should be changed to `ImpureBuiltinEncountered` +// Expectation for this test should be changed to `ImpureBuiltinEncountered` // if in the future if "foo" is evaluated after // ---- diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul index 77fe97228465..f02999d1b9b8 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/loadimmutable.yul @@ -7,7 +7,7 @@ object "obj" { } } // "foo" was evaluated before `loadimmutable` -// Expection for this test should be changed to `ImpureBuiltinEncountered` +// Expectation for this test should be changed to `ImpureBuiltinEncountered` // if in the future if "foo" is evaluated after // ---- diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul index 2145426ef4d2..b7a5f1482d34 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/setimmutable.yul @@ -7,7 +7,7 @@ object "obj" { } } // "foo" was evaluated before `setimmutable` -// Expection for this test should be changed to `ImpureBuiltinEncountered` +// Expectation for this test should be changed to `ImpureBuiltinEncountered` // if in the future if "foo" is evaluated after // ---- diff --git a/test/libyul/yulPureInterpreterTests/verbatim.yul b/test/libyul/yulPureInterpreterTests/verbatim.yul index 33572c94a32b..b1b2026aa743 100644 --- a/test/libyul/yulPureInterpreterTests/verbatim.yul +++ b/test/libyul/yulPureInterpreterTests/verbatim.yul @@ -2,7 +2,7 @@ let double := verbatim_1i_1o(hex"600202", 1) } // The hext sequence was evaluated before verbatim -// Expection for this test should be changed to `ImpureBuiltinEncountered` +// Expectation for this test should be changed to `ImpureBuiltinEncountered` // if in the future if the hex sequence is evaluated after. // ---- From 4fc66cab5673032a67073c55744f889d72325bb0 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 21:37:13 +0700 Subject: [PATCH 076/101] Remove virtual modifier from PureInterpreter functions --- libyul/tools/interpreter/PureInterpreter.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/tools/interpreter/PureInterpreter.h index c905fee9f3e5..44ed99a817e3 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/tools/interpreter/PureInterpreter.h @@ -102,7 +102,7 @@ class PureInterpreter VariableValuesMap const& allVariables() const { return m_variables; } protected: - virtual std::unique_ptr makeInterpreterCopy(VariableValuesMap _variables = {}) const + std::unique_ptr makeInterpreterCopy(VariableValuesMap _variables = {}) const { return std::make_unique( m_state, @@ -114,7 +114,7 @@ class PureInterpreter } // evaluate the expression and assert that the number of return variable is _numReturnVars - virtual EvaluationResult evaluate(Expression const& _expression, size_t _numReturnVars); + EvaluationResult evaluate(Expression const& _expression, size_t _numReturnVars); /// Evaluates the given expression from right to left and /// stores it in m_value. From 3483faa663e0901a41a045c2720f33f4f3484400 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Sun, 29 Sep 2024 21:43:39 +0700 Subject: [PATCH 077/101] Remove unused m_state --- libyul/tools/interpreter/PureEVMInstructionInterpreter.h | 6 ++---- libyul/tools/interpreter/PureInterpreter.cpp | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/libyul/tools/interpreter/PureEVMInstructionInterpreter.h b/libyul/tools/interpreter/PureEVMInstructionInterpreter.h index fbf081f330a2..c720ed87b317 100644 --- a/libyul/tools/interpreter/PureEVMInstructionInterpreter.h +++ b/libyul/tools/interpreter/PureEVMInstructionInterpreter.h @@ -54,9 +54,8 @@ namespace solidity::yul::tools::interpreter class PureEVMInstructionInterpreter { public: - explicit PureEVMInstructionInterpreter(langutil::EVMVersion _evmVersion, PureInterpreterState& _state): - m_evmVersion(_evmVersion), - m_state(_state) + explicit PureEVMInstructionInterpreter(langutil::EVMVersion _evmVersion): + m_evmVersion(_evmVersion) {} /// Evaluate instruction @@ -72,7 +71,6 @@ class PureEVMInstructionInterpreter private: langutil::EVMVersion m_evmVersion; - PureInterpreterState& m_state; }; } // solidity::yul::test diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/tools/interpreter/PureInterpreter.cpp index 6b94e865c3c1..11dcf1f2d089 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/tools/interpreter/PureInterpreter.cpp @@ -247,7 +247,7 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) { if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) { - PureEVMInstructionInterpreter interpreter(dialect->evmVersion(), m_state); + PureEVMInstructionInterpreter interpreter(dialect->evmVersion()); return interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); } } From 82a8d360e15b31a6b7a4225cb15a56230a848438 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 8 Oct 2024 23:02:52 +0700 Subject: [PATCH 078/101] Drop tools/ subdirectory --- libyul/CMakeLists.txt | 20 +++++++++---------- .../PureEVMInstructionInterpreter.cpp | 6 +++--- .../PureEVMInstructionInterpreter.h | 6 +++--- .../interpreter/PureInterpreter.cpp | 6 +++--- .../{tools => }/interpreter/PureInterpreter.h | 10 +++++----- .../interpreter/PureInterpreterState.cpp | 4 ++-- .../interpreter/PureInterpreterState.h | 4 ++-- libyul/{tools => }/interpreter/Results.h | 2 +- libyul/{tools => }/interpreter/Scope.cpp | 4 ++-- libyul/{tools => }/interpreter/Scope.h | 4 ++-- libyul/{tools => }/interpreter/types.h | 2 +- test/libyul/YulPureInterpreterTest.cpp | 16 +++++++-------- test/libyul/YulPureInterpreterTest.h | 18 ++++++++--------- 13 files changed, 51 insertions(+), 51 deletions(-) rename libyul/{tools => }/interpreter/PureEVMInstructionInterpreter.cpp (98%) rename libyul/{tools => }/interpreter/PureEVMInstructionInterpreter.h (92%) rename libyul/{tools => }/interpreter/PureInterpreter.cpp (98%) rename libyul/{tools => }/interpreter/PureInterpreter.h (94%) rename libyul/{tools => }/interpreter/PureInterpreterState.cpp (95%) rename libyul/{tools => }/interpreter/PureInterpreterState.h (96%) rename libyul/{tools => }/interpreter/Results.h (98%) rename libyul/{tools => }/interpreter/Scope.cpp (95%) rename libyul/{tools => }/interpreter/Scope.h (94%) rename libyul/{tools => }/interpreter/types.h (94%) diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index 0e0b6c297bed..593535bcaf2b 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -202,16 +202,16 @@ add_library(yul optimiser/VarDeclInitializer.h optimiser/VarNameCleaner.cpp optimiser/VarNameCleaner.h - tools/interpreter/Results.h - tools/interpreter/PureInterpreterState.h - tools/interpreter/PureInterpreterState.cpp - tools/interpreter/Scope.h - tools/interpreter/Scope.cpp - tools/interpreter/types.h - tools/interpreter/PureInterpreter.cpp - tools/interpreter/PureInterpreter.h - tools/interpreter/PureEVMInstructionInterpreter.cpp - tools/interpreter/PureEVMInstructionInterpreter.h + interpreter/Results.h + interpreter/PureInterpreterState.h + interpreter/PureInterpreterState.cpp + interpreter/Scope.h + interpreter/Scope.cpp + interpreter/types.h + interpreter/PureInterpreter.cpp + interpreter/PureInterpreter.h + interpreter/PureEVMInstructionInterpreter.cpp + interpreter/PureEVMInstructionInterpreter.h ) target_link_libraries(yul PUBLIC evmasm solutil langutil smtutil fmt::fmt-header-only) diff --git a/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp similarity index 98% rename from libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp rename to libyul/interpreter/PureEVMInstructionInterpreter.cpp index e3947eaf39f7..50e694c4816f 100644 --- a/libyul/tools/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -19,9 +19,9 @@ * Yul interpreter module that evaluates EVM instructions. */ -#include +#include -#include +#include #include #include @@ -39,7 +39,7 @@ using namespace solidity; using namespace solidity::evmasm; using namespace solidity::yul; -using namespace solidity::yul::tools::interpreter; +using namespace solidity::yul::interpreter; using solidity::util::h160; using solidity::util::h256; diff --git a/libyul/tools/interpreter/PureEVMInstructionInterpreter.h b/libyul/interpreter/PureEVMInstructionInterpreter.h similarity index 92% rename from libyul/tools/interpreter/PureEVMInstructionInterpreter.h rename to libyul/interpreter/PureEVMInstructionInterpreter.h index c720ed87b317..d380dda1c344 100644 --- a/libyul/tools/interpreter/PureEVMInstructionInterpreter.h +++ b/libyul/interpreter/PureEVMInstructionInterpreter.h @@ -23,8 +23,8 @@ #include -#include -#include +#include +#include #include #include @@ -45,7 +45,7 @@ class YulString; struct BuiltinFunctionForEVM; } -namespace solidity::yul::tools::interpreter +namespace solidity::yul::interpreter { /** diff --git a/libyul/tools/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp similarity index 98% rename from libyul/tools/interpreter/PureInterpreter.cpp rename to libyul/interpreter/PureInterpreter.cpp index 11dcf1f2d089..566641646aba 100644 --- a/libyul/tools/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -19,9 +19,9 @@ * Yul interpreter. */ -#include +#include -#include +#include #include #include @@ -39,7 +39,7 @@ using namespace solidity; using namespace solidity::yul; -using namespace solidity::yul::tools::interpreter; +using namespace solidity::yul::interpreter; using solidity::util::h256; diff --git a/libyul/tools/interpreter/PureInterpreter.h b/libyul/interpreter/PureInterpreter.h similarity index 94% rename from libyul/tools/interpreter/PureInterpreter.h rename to libyul/interpreter/PureInterpreter.h index 44ed99a817e3..42233c31cbb6 100644 --- a/libyul/tools/interpreter/PureInterpreter.h +++ b/libyul/interpreter/PureInterpreter.h @@ -21,10 +21,10 @@ #pragma once -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -44,7 +44,7 @@ namespace solidity::yul struct Dialect; } -namespace solidity::yul::tools::interpreter +namespace solidity::yul::interpreter { /** diff --git a/libyul/tools/interpreter/PureInterpreterState.cpp b/libyul/interpreter/PureInterpreterState.cpp similarity index 95% rename from libyul/tools/interpreter/PureInterpreterState.cpp rename to libyul/interpreter/PureInterpreterState.cpp index 71fe9e864819..193111d1cd7b 100644 --- a/libyul/tools/interpreter/PureInterpreterState.cpp +++ b/libyul/interpreter/PureInterpreterState.cpp @@ -16,7 +16,7 @@ */ // SPDX-License-Identifier: GPL-3.0 -#include +#include #include @@ -27,7 +27,7 @@ #include #include -using namespace solidity::yul::tools::interpreter; +using namespace solidity::yul::interpreter; void PureInterpreterState::dumpTraces(std::ostream& _out) const { diff --git a/libyul/tools/interpreter/PureInterpreterState.h b/libyul/interpreter/PureInterpreterState.h similarity index 96% rename from libyul/tools/interpreter/PureInterpreterState.h rename to libyul/interpreter/PureInterpreterState.h index f757a3804907..282accfeea8f 100644 --- a/libyul/tools/interpreter/PureInterpreterState.h +++ b/libyul/interpreter/PureInterpreterState.h @@ -18,7 +18,7 @@ #pragma once -#include +#include #include @@ -28,7 +28,7 @@ #include #include -namespace solidity::yul::tools::interpreter +namespace solidity::yul::interpreter { struct FunctionCallTrace diff --git a/libyul/tools/interpreter/Results.h b/libyul/interpreter/Results.h similarity index 98% rename from libyul/tools/interpreter/Results.h rename to libyul/interpreter/Results.h index 767fb4c676dc..a535ba773ef7 100644 --- a/libyul/tools/interpreter/Results.h +++ b/libyul/interpreter/Results.h @@ -22,7 +22,7 @@ #include -namespace solidity::yul::tools::interpreter +namespace solidity::yul::interpreter { template diff --git a/libyul/tools/interpreter/Scope.cpp b/libyul/interpreter/Scope.cpp similarity index 95% rename from libyul/tools/interpreter/Scope.cpp rename to libyul/interpreter/Scope.cpp index fd2529353dae..e6cc963169e6 100644 --- a/libyul/tools/interpreter/Scope.cpp +++ b/libyul/interpreter/Scope.cpp @@ -16,7 +16,7 @@ */ // SPDX-License-Identifier: GPL-3.0 -#include +#include #include @@ -24,7 +24,7 @@ using namespace solidity; using namespace solidity::yul; -using namespace solidity::yul::tools::interpreter; +using namespace solidity::yul::interpreter; Scope* Scope::getSubscope(Block const& _block) { diff --git a/libyul/tools/interpreter/Scope.h b/libyul/interpreter/Scope.h similarity index 94% rename from libyul/tools/interpreter/Scope.h rename to libyul/interpreter/Scope.h index b52079dc8d4e..bf7df5dc1094 100644 --- a/libyul/tools/interpreter/Scope.h +++ b/libyul/interpreter/Scope.h @@ -17,7 +17,7 @@ // SPDX-License-Identifier: GPL-3.0 #pragma once -#include +#include #include #include @@ -27,7 +27,7 @@ #include #include -namespace solidity::yul::tools::interpreter +namespace solidity::yul::interpreter { /** diff --git a/libyul/tools/interpreter/types.h b/libyul/interpreter/types.h similarity index 94% rename from libyul/tools/interpreter/types.h rename to libyul/interpreter/types.h index c01da44832ea..a5f27e34547a 100644 --- a/libyul/tools/interpreter/types.h +++ b/libyul/interpreter/types.h @@ -23,7 +23,7 @@ #include -namespace solidity::yul::tools::interpreter +namespace solidity::yul::interpreter { using VariableValuesMap = std::map; diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index 0916b17152a9..c701e64be927 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -18,7 +18,7 @@ #include -#include +#include #include @@ -47,7 +47,7 @@ using namespace solidity::frontend::test; using solidity::util::h256; -using namespace solidity::yul::tools::interpreter; +using namespace solidity::yul::interpreter; YulPureInterpreterTest::YulPureInterpreterTest(std::string const& _filename): EVMVersionRestrictedTestCase(_filename) @@ -105,8 +105,8 @@ std::string YulPureInterpreterTest::interpret() const PureInterpreterState state { m_config }; Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()); - tools::interpreter::Scope rootScope; - tools::interpreter::Scope* subscope = rootScope.getSubscope(block); + interpreter::Scope rootScope; + interpreter::Scope* subscope = rootScope.getSubscope(block); PureInterpreter interpreter(state, dialect, *subscope, 0); ExecutionResult res = interpreter.execute(block.statements); @@ -124,8 +124,8 @@ std::string YulPureInterpreterTest::interpret() const void YulPureInterpreterTest::dumpExecutionData( std::ostream& _stream, - tools::interpreter::ExecutionResult _res, - tools::interpreter::PureInterpreterState const& _state, + interpreter::ExecutionResult _res, + interpreter::PureInterpreterState const& _state, VariableValuesMap const& _outerMostVariables ) const { @@ -140,7 +140,7 @@ void YulPureInterpreterTest::dumpExecutionData( _state.dumpTraces(_stream); } -void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, tools::interpreter::ExecutionResult _res) const +void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, interpreter::ExecutionResult _res) const { _stream << std::visit(GenericVisitor { [&](ExecutionOk) { return "ExecutionOk"; }, @@ -160,7 +160,7 @@ void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, tools::i void YulPureInterpreterTest::dumpVariables( std::ostream& _stream, - tools::interpreter::VariableValuesMap const& _variables + interpreter::VariableValuesMap const& _variables ) const { static std::string_view const INDENT = " "; diff --git a/test/libyul/YulPureInterpreterTest.h b/test/libyul/YulPureInterpreterTest.h index 4083106b40b1..463a0705b0ed 100644 --- a/test/libyul/YulPureInterpreterTest.h +++ b/test/libyul/YulPureInterpreterTest.h @@ -20,9 +20,9 @@ #include -#include -#include -#include +#include +#include +#include namespace solidity::yul { @@ -50,17 +50,17 @@ class YulPureInterpreterTest: public solidity::frontend::test::EVMVersionRestric std::string interpret() const; void dumpExecutionData( std::ostream& _stream, - tools::interpreter::ExecutionResult _res, - tools::interpreter::PureInterpreterState const& _state, - tools::interpreter::VariableValuesMap const& _outerMostVariables + interpreter::ExecutionResult _res, + interpreter::PureInterpreterState const& _state, + interpreter::VariableValuesMap const& _outerMostVariables ) const; - void dumpExecutionResult(std::ostream& _stream, tools::interpreter::ExecutionResult _res) const; - void dumpVariables(std::ostream& _stream, tools::interpreter::VariableValuesMap const& _variables) const; + void dumpExecutionResult(std::ostream& _stream, interpreter::ExecutionResult _res) const; + void dumpVariables(std::ostream& _stream, interpreter::VariableValuesMap const& _variables) const; void dumpValue(std::ostream& _stream, u256 _value) const; std::shared_ptr m_ast; std::shared_ptr m_analysisInfo; - tools::interpreter::PureInterpreterConfig m_config; + interpreter::PureInterpreterConfig m_config; bool m_printHex; }; From c3f7dd88e7b91559e377adb67fc40e913ed084ea Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 8 Oct 2024 23:25:09 +0700 Subject: [PATCH 079/101] Move u512 to libsolutil/Numeric.h --- libyul/interpreter/PureEVMInstructionInterpreter.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp index 50e694c4816f..76a9f803ccdc 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -44,8 +44,6 @@ using namespace solidity::yul::interpreter; using solidity::util::h160; using solidity::util::h256; -using u512 = boost::multiprecision::number>; - EvaluationResult PureEVMInstructionInterpreter::eval( evmasm::Instruction _instruction, std::vector const& _arguments From 3fc0d1492de0103478fe48e5d141e4497812dd68 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 8 Oct 2024 23:55:32 +0700 Subject: [PATCH 080/101] Remove comment about instruction being _impure_ --- libyul/interpreter/PureEVMInstructionInterpreter.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp index 76a9f803ccdc..e493bd372a80 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -280,7 +280,6 @@ EvaluationResult PureEVMInstructionInterpreter::eval( EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( BuiltinFunctionForEVM const& _fun, std::vector const& /* _arguments */, // This was required to execute some builtin. - // But all of them are impure. std::vector const& _evaluatedArguments ) { From 808ff96cd2b708f31ed6f716becbb1f8f340a696 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 9 Oct 2024 00:06:27 +0700 Subject: [PATCH 081/101] Use util::unreachable in PureEVMInstructionInterpreter::eval --- libyul/interpreter/PureEVMInstructionInterpreter.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp index e493bd372a80..22e286ed146c 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -268,13 +268,11 @@ EvaluationResult PureEVMInstructionInterpreter::eval( case Instruction::SWAP15: case Instruction::SWAP16: { - yulAssert(false, ""); - return EvaluationOk(0); + yulAssert(false, "Instruction not allowed in strict assembly."); } } - yulAssert(false, "Unknown instruction with opcode " + std::to_string(static_cast(_instruction))); - return EvaluationOk(0); + util::unreachable(); } EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( From a42757cb95958a8b7ad8651dfa4422ac533e935e Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 9 Oct 2024 00:10:12 +0700 Subject: [PATCH 082/101] Fix styling: return on separate line --- libyul/interpreter/PureInterpreter.cpp | 54 +++++++++++++++++--------- libyul/interpreter/Scope.cpp | 3 +- 2 files changed, 38 insertions(+), 19 deletions(-) diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index 566641646aba..48151da3b8a8 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -46,7 +46,8 @@ using solidity::util::h256; ExecutionResult PureInterpreter::operator()(ExpressionStatement const& _expressionStatement) { EvaluationResult res = evaluate(_expressionStatement.expression, 0); - if (auto* terminated = std::get_if(&res)) return *terminated; + if (auto* terminated = std::get_if(&res)) + return *terminated; return ExecutionOk{ ControlFlowState::Default }; } @@ -54,7 +55,8 @@ ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) { solAssert(_assignment.value, ""); EvaluationResult evalRes = evaluate(*_assignment.value, _assignment.variableNames.size()); - if (auto* terminated = std::get_if(&evalRes)) return *terminated; + if (auto* terminated = std::get_if(&evalRes)) + return *terminated; std::vector const& values = std::move(std::get(evalRes).values); for (size_t i = 0; i < values.size(); ++i) @@ -72,7 +74,8 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat if (_declaration.value) { EvaluationResult evalRes = evaluate(*_declaration.value, _declaration.variables.size()); - if (auto* terminated = std::get_if(&evalRes)) return *terminated; + if (auto* terminated = std::get_if(&evalRes)) + return *terminated; values = std::move(std::get(evalRes).values); } else @@ -95,7 +98,8 @@ ExecutionResult PureInterpreter::operator()(If const& _if) { solAssert(_if.condition, ""); EvaluationResult conditionRes = evaluate(*_if.condition, 1); - if (auto* terminated = std::get_if(&conditionRes)) return *terminated; + if (auto* terminated = std::get_if(&conditionRes)) + return *terminated; if (std::get(conditionRes).values.at(0) != 0) return (*this)(_if.body); @@ -108,7 +112,8 @@ ExecutionResult PureInterpreter::operator()(Switch const& _switch) solAssert(!_switch.cases.empty(), ""); EvaluationResult expressionRes = evaluate(*_switch.expression, 1); - if (auto* terminated = std::get_if(&expressionRes)) return *terminated; + if (auto* terminated = std::get_if(&expressionRes)) + return *terminated; u256 val = std::get(expressionRes).values.at(0); for (auto const& c: _switch.cases) @@ -119,10 +124,12 @@ ExecutionResult PureInterpreter::operator()(Switch const& _switch) else { EvaluationResult caseRes = evaluate(*c.value, 1); - if (auto* terminated = std::get_if(&caseRes)) return *terminated; + if (auto* terminated = std::get_if(&caseRes)) + return *terminated; caseMatched = std::get(caseRes).values.at(0) == val; } - if (caseMatched) return (*this)(c.body); + if (caseMatched) + return (*this)(c.body); } return ExecutionOk { ControlFlowState::Default }; } @@ -148,7 +155,8 @@ ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) { { EvaluationResult conditionRes = evaluate(*_forLoop.condition, 1); - if (auto* terminated = std::get_if(&conditionRes)) return *terminated; + if (auto* terminated = std::get_if(&conditionRes)) + return *terminated; if (std::get(conditionRes).values.at(0) == 0) break; } @@ -156,14 +164,16 @@ ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) // Increment step for each loop iteration for loops with // an empty body and post blocks to prevent a deadlock. if (_forLoop.body.statements.size() == 0 && _forLoop.post.statements.size() == 0) - if (auto terminated = incrementStatementStep()) return *terminated; + if (auto terminated = incrementStatementStep()) + return *terminated; { ExecutionResult bodyRes = (*this)(_forLoop.body); if ( std::holds_alternative(bodyRes) || bodyRes == ExecutionResult(ExecutionOk{ ControlFlowState::Leave }) - ) return bodyRes; + ) + return bodyRes; if (bodyRes == ExecutionResult(ExecutionOk{ ControlFlowState::Break })) return ExecutionOk { ControlFlowState::Default }; @@ -174,7 +184,8 @@ ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) if ( std::holds_alternative(postRes) || postRes == ExecutionResult(ExecutionOk{ ControlFlowState::Leave }) - ) return postRes; + ) + return postRes; } } return ExecutionOk { ControlFlowState::Default }; @@ -216,7 +227,8 @@ ExecutionResult PureInterpreter::execute(std::vector const& _statemen ExecutionResult PureInterpreter::visit(Statement const& _st) { - if (auto terminated = incrementStatementStep()) return *terminated; + if (auto terminated = incrementStatementStep()) + return *terminated; return std::visit(*this, _st); } @@ -239,7 +251,8 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) if (!builtin->literalArguments.empty()) literalArguments = &builtin->literalArguments; EvaluationResult argsRes = evaluateArgs(_funCall.arguments, literalArguments); - if (auto* terminated = std::get_if(&argsRes)) return *terminated; + if (auto* terminated = std::get_if(&argsRes)) + return *terminated; std::vector argsValues = std::move(std::get(argsRes).values); @@ -263,24 +276,28 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); - if (auto terminated = m_state.addTrace(fun, argsValues)) return *terminated; + if (auto terminated = m_state.addTrace(fun, argsValues)) + return *terminated; ExecutionResult funcBodyRes = (*interpreter)(fun.body); - if (auto* terminated = std::get_if(&funcBodyRes)) return *terminated; + if (auto* terminated = std::get_if(&funcBodyRes)) + return *terminated; std::vector returnedValues; returnedValues.reserve(fun.returnVariables.size()); for (auto const& retVar: fun.returnVariables) returnedValues.emplace_back(interpreter->valueOfVariable(retVar.name)); - if (auto terminated = m_state.addTrace(fun, returnedValues)) return *terminated; + if (auto terminated = m_state.addTrace(fun, returnedValues)) + return *terminated; return EvaluationOk(std::move(returnedValues)); } EvaluationResult PureInterpreter::visit(Expression const& _st) { - if (auto terminated = incrementExpressionStep()) return *terminated; + if (auto terminated = incrementExpressionStep()) + return *terminated; return std::visit(*this, _st); } @@ -308,7 +325,8 @@ EvaluationResult PureInterpreter::evaluateArgs( if (!isLiteral) { EvaluationResult exprRes = evaluate(expr, 1); - if (auto* terminated = std::get_if(&exprRes)) return *terminated; + if (auto* terminated = std::get_if(&exprRes)) + return *terminated; std::vector const& exprValues = std::get(exprRes).values; values[i] = exprValues.at(0); } diff --git a/libyul/interpreter/Scope.cpp b/libyul/interpreter/Scope.cpp index e6cc963169e6..0f5688e64208 100644 --- a/libyul/interpreter/Scope.cpp +++ b/libyul/interpreter/Scope.cpp @@ -29,7 +29,8 @@ using namespace solidity::yul::interpreter; Scope* Scope::getSubscope(Block const& _block) { auto [it, isNew] = m_subScopes.try_emplace(&_block, nullptr); - if (!isNew) return it->second.get(); + if (!isNew) + return it->second.get(); it->second = std::make_unique(this); Scope* subscope = it->second.get(); From d61e952762845cac7a65e76e9dc0c92add4ec13c Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 9 Oct 2024 00:21:29 +0700 Subject: [PATCH 083/101] Fix styling: spacing surround constructor call --- libyul/interpreter/PureInterpreter.cpp | 34 +++++++++++++------------- test/libyul/YulPureInterpreterTest.cpp | 2 +- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index 48151da3b8a8..e27b391cf585 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -48,7 +48,7 @@ ExecutionResult PureInterpreter::operator()(ExpressionStatement const& _expressi EvaluationResult res = evaluate(_expressionStatement.expression, 0); if (auto* terminated = std::get_if(&res)) return *terminated; - return ExecutionOk{ ControlFlowState::Default }; + return ExecutionOk{ControlFlowState::Default}; } ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) @@ -65,7 +65,7 @@ ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) auto [_, isNew] = m_variables.insert_or_assign(varName, values.at(i)); solAssert(!isNew, ""); } - return ExecutionOk { ControlFlowState::Default }; + return ExecutionOk{ControlFlowState::Default}; } ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declaration) @@ -91,7 +91,7 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat solAssert(isNew, ""); m_scope->addDeclaredVariable(varName); } - return ExecutionOk { ControlFlowState::Default }; + return ExecutionOk{ControlFlowState::Default}; } ExecutionResult PureInterpreter::operator()(If const& _if) @@ -103,7 +103,7 @@ ExecutionResult PureInterpreter::operator()(If const& _if) if (std::get(conditionRes).values.at(0) != 0) return (*this)(_if.body); - return ExecutionOk { ControlFlowState::Default }; + return ExecutionOk{ControlFlowState::Default}; } ExecutionResult PureInterpreter::operator()(Switch const& _switch) @@ -131,12 +131,12 @@ ExecutionResult PureInterpreter::operator()(Switch const& _switch) if (caseMatched) return (*this)(c.body); } - return ExecutionOk { ControlFlowState::Default }; + return ExecutionOk{ControlFlowState::Default}; } ExecutionResult PureInterpreter::operator()(FunctionDefinition const&) { - return ExecutionOk{ ControlFlowState::Default }; + return ExecutionOk{ControlFlowState::Default}; } ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) @@ -148,7 +148,7 @@ ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) { ExecutionResult execRes = execute(_forLoop.pre.statements); - if (execRes == ExecutionResult(ExecutionOk { ControlFlowState::Leave })) + if (execRes == ExecutionResult(ExecutionOk{ControlFlowState::Leave})) return execRes; } while (true) @@ -171,39 +171,39 @@ ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) ExecutionResult bodyRes = (*this)(_forLoop.body); if ( std::holds_alternative(bodyRes) || - bodyRes == ExecutionResult(ExecutionOk{ ControlFlowState::Leave }) + bodyRes == ExecutionResult(ExecutionOk{ControlFlowState::Leave}) ) return bodyRes; - if (bodyRes == ExecutionResult(ExecutionOk{ ControlFlowState::Break })) - return ExecutionOk { ControlFlowState::Default }; + if (bodyRes == ExecutionResult(ExecutionOk{ControlFlowState::Break})) + return ExecutionOk{ControlFlowState::Default}; } { ExecutionResult postRes = (*this)(_forLoop.post); if ( std::holds_alternative(postRes) || - postRes == ExecutionResult(ExecutionOk{ ControlFlowState::Leave }) + postRes == ExecutionResult(ExecutionOk{ControlFlowState::Leave}) ) return postRes; } } - return ExecutionOk { ControlFlowState::Default }; + return ExecutionOk{ControlFlowState::Default}; } ExecutionResult PureInterpreter::operator()(Break const&) { - return ExecutionOk{ ControlFlowState::Break }; + return ExecutionOk{ControlFlowState::Break}; } ExecutionResult PureInterpreter::operator()(Continue const&) { - return ExecutionOk{ ControlFlowState::Continue }; + return ExecutionOk{ControlFlowState::Continue}; } ExecutionResult PureInterpreter::operator()(Leave const&) { - return ExecutionOk{ ControlFlowState::Leave }; + return ExecutionOk{ControlFlowState::Leave}; } ExecutionResult PureInterpreter::operator()(Block const& _block) @@ -219,10 +219,10 @@ ExecutionResult PureInterpreter::execute(std::vector const& _statemen for (auto const& statement: _statements) { ExecutionResult statementRes = visit(statement); - if (statementRes != ExecutionResult(ExecutionOk {ControlFlowState::Default})) + if (statementRes != ExecutionResult(ExecutionOk{ControlFlowState::Default})) return statementRes; } - return ExecutionOk{ ControlFlowState::Default }; + return ExecutionOk{ControlFlowState::Default}; } ExecutionResult PureInterpreter::visit(Statement const& _st) diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index c701e64be927..5e87ba50b827 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -103,7 +103,7 @@ std::string YulPureInterpreterTest::interpret() const Block const& block = m_ast->root(); - PureInterpreterState state { m_config }; + PureInterpreterState state{m_config}; Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()); interpreter::Scope rootScope; interpreter::Scope* subscope = rootScope.getSubscope(block); From 2b1d4b18e094551d0e8d25b0a4e86f79363f264c Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 9 Oct 2024 00:23:30 +0700 Subject: [PATCH 084/101] Fix styling: format python code --- .../pure_instructions/.generate-test.py | 204 +++++++++--------- 1 file changed, 101 insertions(+), 103 deletions(-) diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py index 6d66be6c3483..4a526d96e319 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py @@ -12,12 +12,15 @@ MX = 2**256 + def u256(num: int): return int(num) % MX + def u2s(num: int): return int(num) - MX if (int(num) >> 255) > 0 else int(num) + def gen_test( fn_name: str, *, @@ -26,146 +29,139 @@ def gen_test( test_numbers: Union[Iterable[int], None] = None, evm_version: Union[str, None] = None, ): - print('Generating test for', fn_name) + print("Generating test for", fn_name) src: list[str] = [] - src.append('{') - src.append(""" + src.append("{") + src.append( + """ function check(a, b) { if iszero(eq(a, b)) { revert(0, 0) } } -""") +""" + ) if test_numbers is None: if param_cnt == 1: test_numbers = [ - 0, 1, 2, 3, - MX - 1, MX - 2, MX - 3, - random.randrange(MX), random.randrange(MX), random.randrange(MX), random.randrange(MX) + 0, + 1, + 2, + 3, + MX - 1, + MX - 2, + MX - 3, + random.randrange(MX), + random.randrange(MX), + random.randrange(MX), + random.randrange(MX), ] else: - test_numbers = [0, 1, 2, MX - 1, MX - 2, random.randrange(MX), random.randrange(MX), random.randrange(MX)] + test_numbers = [ + 0, + 1, + 2, + MX - 1, + MX - 2, + random.randrange(MX), + random.randrange(MX), + random.randrange(MX), + ] param_set = list(product(test_numbers, repeat=param_cnt)) for p in param_set: res = u256(calc(p)) # printing hex to save space - src.append(f' check({fn_name}({', '.join(hex(i) for i in p)}), {hex(res)})') - src.append('}') + src.append(f" check({fn_name}({', '.join(hex(i) for i in p)}), {hex(res)})") + src.append("}") - src.append('// ====') - src.append('// maxTraceSize: 0') + src.append("// ====") + src.append("// maxTraceSize: 0") if evm_version is not None: - src.append(f'// EVMVersion: {evm_version}') + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) - with open(fn_name + '.yul', 'w', encoding='utf-8') as f: - print('\n'.join(src), file=f) def main(): - gen_test('add', - param_cnt = 2, - calc = lambda p: p[0] + p[1]) - gen_test('mul', - param_cnt = 2, - calc = lambda p: p[0] * p[1]) - gen_test('sub', - param_cnt = 2, - calc = lambda p: p[0] - p[1]) - gen_test('div', - param_cnt = 2, - calc = lambda p: p[0] // p[1] if p[1] != 0 else 0) - gen_test('sdiv', - param_cnt = 2, - calc = signed_div) - gen_test('mod', - param_cnt = 2, - calc = lambda p: p[0] % p[1] if p[1] != 0 else 0) - gen_test('smod', - param_cnt = 2, - calc = signed_mod) - gen_test('exp', - param_cnt = 2, - calc = lambda p: pow(p[0], p[1], MX)) - gen_test('not', - param_cnt = 1, - calc = lambda p: ~p[0]) - gen_test('lt', - param_cnt = 2, - calc = lambda p: p[0] < p[1]) - gen_test('gt', - param_cnt = 2, - calc = lambda p: p[0] > p[1]) - gen_test('slt', - param_cnt = 2, - calc = lambda p: u2s(p[0]) < u2s(p[1])) - gen_test('sgt', - param_cnt = 2, - calc = lambda p: u2s(p[0]) > u2s(p[1])) - gen_test('eq', - param_cnt = 2, - calc = lambda p: p[0] == p[1]) - gen_test('iszero', - param_cnt = 1, - calc = lambda p: p[0] == 0) - gen_test('and', - param_cnt = 2, - calc=lambda p: p[0] & p[1]) - gen_test('or', - param_cnt = 2, - calc = lambda p: p[0] | p[1]) - gen_test('xor', - param_cnt = 2, - calc = lambda p: p[0] ^ p[1]) - gen_test('byte', - param_cnt = 2, - test_numbers = [ - random.randrange(MX), random.randrange(MX), random.randrange(MX), - random.randrange(1, 32), random.randrange(1, 32), random.randrange(1, 32), - 0 - ], - calc = lambda p: 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xff) - gen_test('shl', - evm_version='>=constantinople', - param_cnt = 2, - calc = lambda p: p[1] << p[0] if p[0] < 32 else 0) - gen_test('shr', - evm_version='>=constantinople', - param_cnt = 2, - calc = lambda p: p[1] >> p[0]) - gen_test('sar', - evm_version='>=constantinople', - param_cnt = 2, - calc = sar) - gen_test('addmod', - param_cnt = 3, - test_numbers = [random.randrange(0, MX) for _ in range(3)] + [0], - calc = lambda p: (p[0] + p[1]) % p[2] if p[2] != 0 else 0) - gen_test('mulmod', - param_cnt = 3, - test_numbers = [random.randrange(0, MX) for _ in range(3)] + [0], - calc = lambda p: (p[0] * p[1]) % p[2] if p[2] != 0 else 0) - gen_test('signextend', - param_cnt = 2, - calc = signextend) + gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) + gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) + gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) + gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) + gen_test("sdiv", param_cnt=2, calc=signed_div) + gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) + gen_test("smod", param_cnt=2, calc=signed_mod) + gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) + gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) + gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) + gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) + gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) + gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) + gen_test("eq", param_cnt=2, calc=lambda p: p[0] == p[1]) + gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) + gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) + gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) + gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) + gen_test( + "byte", + param_cnt=2, + test_numbers=[ + random.randrange(MX), + random.randrange(MX), + random.randrange(MX), + random.randrange(1, 32), + random.randrange(1, 32), + random.randrange(1, 32), + 0, + ], + calc=lambda p: 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF, + ) + gen_test( + "shl", + evm_version=">=constantinople", + param_cnt=2, + calc=lambda p: p[1] << p[0] if p[0] < 32 else 0, + ) + gen_test( + "shr", evm_version=">=constantinople", param_cnt=2, calc=lambda p: p[1] >> p[0] + ) + gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) + gen_test( + "addmod", + param_cnt=3, + test_numbers=[random.randrange(0, MX) for _ in range(3)] + [0], + calc=lambda p: (p[0] + p[1]) % p[2] if p[2] != 0 else 0, + ) + gen_test( + "mulmod", + param_cnt=3, + test_numbers=[random.randrange(0, MX) for _ in range(3)] + [0], + calc=lambda p: (p[0] * p[1]) % p[2] if p[2] != 0 else 0, + ) + gen_test("signextend", param_cnt=2, calc=signextend) + def signed_div(p: tuple[int, ...]): (a, b) = u2s(p[0]), u2s(p[1]) if b == 0: - return 0 + return 0 res = abs(a) // abs(b) if (a < 0) != (b < 0): res = -res return res + def signed_mod(p: tuple[int, ...]): (a, b) = u2s(p[0]), u2s(p[1]) if b == 0: - return 0 + return 0 res = abs(a) % abs(b) if a < 0: res = -res return res + def sar(p: tuple[int, ...]): (sh, val) = p high_bit = val >> 255 @@ -173,6 +169,7 @@ def sar(p: tuple[int, ...]): val |= u256(-high_bit) << max(0, 255 - sh) return val + def signextend(p: tuple[int, ...]): (byte_pos, val) = p byte_pos = min(byte_pos, 32) @@ -182,5 +179,6 @@ def signextend(p: tuple[int, ...]): return val | (u256(-1) << mask_shift) return val & ((1 << mask_shift) - 1) -if __name__ == '__main__': + +if __name__ == "__main__": main() From 0ffe4fe9515e7aa42471ce2a7f81881964a287d5 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 9 Oct 2024 00:35:03 +0700 Subject: [PATCH 085/101] Fix styling: yul test indentation --- .../ambiguous_vars.yul | 14 +++++------ .../bounded_recursion.yul | 19 ++++++++------ test/libyul/yulPureInterpreterTests/exp.yul | 2 +- .../expr_nesting_depth_exceeded.yul | 14 +++++------ .../expr_nesting_depth_not_exceeded.yul | 25 +++++++++++-------- .../function_scopes.yul | 14 +++++++---- .../infinite_recursion.yul | 6 ++--- .../infinite_recursion_tracelimit.yul | 6 ++--- test/libyul/yulPureInterpreterTests/leave.yul | 19 ++++++++------ .../leave_for_init.yul | 10 ++++---- .../pop_byte_shr_func.yul | 4 +-- .../yulPureInterpreterTests/recursion.yul | 14 ++++++----- .../shadowed_symbol.yul | 22 ++++++++-------- .../switch_statement.yul | 6 ++--- 14 files changed, 96 insertions(+), 79 deletions(-) diff --git a/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul b/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul index 046c89600ea3..f9b658de62ff 100644 --- a/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul +++ b/test/libyul/yulPureInterpreterTests/ambiguous_vars.yul @@ -1,11 +1,11 @@ { - function fake_mstore(pos, val) { } - { - let a := 0x20 - fake_mstore(a, 2) - } - let a - fake_mstore(a, 3) + function fake_mstore(pos, val) { } + { + let a := 0x20 + fake_mstore(a, 2) + } + let a + fake_mstore(a, 3) } // ---- // Execution result: ExecutionOk diff --git a/test/libyul/yulPureInterpreterTests/bounded_recursion.yul b/test/libyul/yulPureInterpreterTests/bounded_recursion.yul index a1d6bd8ab5f1..bdbf1c114bd0 100644 --- a/test/libyul/yulPureInterpreterTests/bounded_recursion.yul +++ b/test/libyul/yulPureInterpreterTests/bounded_recursion.yul @@ -1,13 +1,16 @@ { - function f(x) -> y { - if lt(x, 150) { - y := f(add(x, 1)) + function f(x) -> y + { + if lt(x, 150) + { + y := f(add(x, 1)) + } + if eq(x, 150) + { + y := x + } } - if eq(x, 150) { - y := x - } - } - let res := f(0) + let res := f(0) } // ==== diff --git a/test/libyul/yulPureInterpreterTests/exp.yul b/test/libyul/yulPureInterpreterTests/exp.yul index 8bd3f0d20354..309178bc4151 100644 --- a/test/libyul/yulPureInterpreterTests/exp.yul +++ b/test/libyul/yulPureInterpreterTests/exp.yul @@ -1,5 +1,5 @@ { - let res := exp(3,not(1)) + let res := exp(3,not(1)) } // ==== // printHex: true diff --git a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul index fbce52ca4bd2..7e842452d6e2 100644 --- a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul +++ b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_exceeded.yul @@ -1,11 +1,11 @@ { - function f(x) -> y - { - // 32 nested additions are computed in - // exactly 66 expression evaluation steps - y := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,x)))))))))))))))))))))))))))))))) - } - pop(f(0)) + function f(x) -> y + { + // 32 nested additions are computed in + // exactly 66 expression evaluation steps + y := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,x)))))))))))))))))))))))))))))))) + } + pop(f(0)) } // ==== // maxExprNesting: 64 diff --git a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul index 037780831d34..739fefdf44cf 100644 --- a/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul +++ b/test/libyul/yulPureInterpreterTests/expr_nesting_depth_not_exceeded.yul @@ -1,16 +1,19 @@ { - function f(x) -> t - { - // 31 nested additions are computed in - // exactly 64 expression evaluation steps - let y := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,x))))))))))))))))))))))))))))))) - let z := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,y))))))))))))))))))))))))))))))) + function f(x) -> t + { + let y, z + + // 31 nested additions are computed in + // exactly 64 expression evaluation steps + y := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,x))))))))))))))))))))))))))))))) + z := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,y))))))))))))))))))))))))))))))) t := add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,add(0x1,z))))))))))))))))))))))))))))))) - } - for { let i := 0 } lt(i, 10) { i := add(i, 1) } - { - pop(f(i)) - } + } + + for { let i := 0 } lt(i, 10) { i := add(i, 1) } + { + pop(f(i)) + } } // ==== // maxExprNesting: 64 diff --git a/test/libyul/yulPureInterpreterTests/function_scopes.yul b/test/libyul/yulPureInterpreterTests/function_scopes.yul index 9dfaee5ade5d..1816fa0088c6 100644 --- a/test/libyul/yulPureInterpreterTests/function_scopes.yul +++ b/test/libyul/yulPureInterpreterTests/function_scopes.yul @@ -2,14 +2,18 @@ function fake_sstore(pos, val) {} f(1) - function f(i) { + function f(i) + { if i { g(1) } - function g(j) { + + function g(j) + { if j { h() } + f(0) - function h() { - g(0) - } + + function h() + { g(0) } } fake_sstore(i, add(i, 7)) } diff --git a/test/libyul/yulPureInterpreterTests/infinite_recursion.yul b/test/libyul/yulPureInterpreterTests/infinite_recursion.yul index ce61e1d11748..62b01e864824 100644 --- a/test/libyul/yulPureInterpreterTests/infinite_recursion.yul +++ b/test/libyul/yulPureInterpreterTests/infinite_recursion.yul @@ -1,8 +1,8 @@ { - function f() { + function f() { + f() + } f() - } - f() } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul b/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul index cb0bb5da30d3..e9a319d7aa09 100644 --- a/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul +++ b/test/libyul/yulPureInterpreterTests/infinite_recursion_tracelimit.yul @@ -1,8 +1,8 @@ { - function f() { + function f() { + f() + } f() - } - f() } // Setting so that trace limit hit first // ==== diff --git a/test/libyul/yulPureInterpreterTests/leave.yul b/test/libyul/yulPureInterpreterTests/leave.yul index c85ba4c67239..15939a69b61e 100644 --- a/test/libyul/yulPureInterpreterTests/leave.yul +++ b/test/libyul/yulPureInterpreterTests/leave.yul @@ -1,12 +1,17 @@ { - function f() -> x, y - { - for { x := 0 } lt(x, 10) { x := add(x, 1) } { - if eq(x, 5) { y := 1 leave } + function f() -> x, y + { + for { x := 0 } lt(x, 10) { x := add(x, 1) } + { + if eq(x, 5) + { + y := 1 + leave + } + } + x := 9 } - x := 9 - } - let a, b := f() + let a, b := f() } // ==== // EVMVersion: >=constantinople diff --git a/test/libyul/yulPureInterpreterTests/leave_for_init.yul b/test/libyul/yulPureInterpreterTests/leave_for_init.yul index 8299f8e572d4..10f19be815b2 100644 --- a/test/libyul/yulPureInterpreterTests/leave_for_init.yul +++ b/test/libyul/yulPureInterpreterTests/leave_for_init.yul @@ -1,10 +1,10 @@ { - function f() -> x - { - for { leave x := 2 } eq(x, 0) { } { + function f() -> x + { + for { leave x := 2 } eq(x, 0) { } + { } } - } - let a := f() + let a := f() } // ==== // EVMVersion: >=constantinople diff --git a/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul b/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul index dff8433808ae..bbcf98bd3067 100644 --- a/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul +++ b/test/libyul/yulPureInterpreterTests/pop_byte_shr_func.yul @@ -1,6 +1,6 @@ { - function f() -> x { x := 0x1337 } - pop(byte(0, shr(0x8, f()))) + function f() -> x { x := 0x1337 } + pop(byte(0, shr(0x8, f()))) } // ==== // EVMVersion: >=constantinople diff --git a/test/libyul/yulPureInterpreterTests/recursion.yul b/test/libyul/yulPureInterpreterTests/recursion.yul index 3114c69c1159..bbecff29f012 100644 --- a/test/libyul/yulPureInterpreterTests/recursion.yul +++ b/test/libyul/yulPureInterpreterTests/recursion.yul @@ -1,11 +1,13 @@ { - function fib(i) -> y { - y := 1 - if gt(i, 2) { - y := add(fib(sub(i, 1)), fib(sub(i, 2))) + function fib(i) -> y + { + y := 1 + if gt(i, 2) + { + y := add(fib(sub(i, 1)), fib(sub(i, 2))) + } } - } - let res := fib(8) + let res := fib(8) } // ---- // Execution result: ExecutionOk diff --git a/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul b/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul index ac5f5b3ca308..77cd1f9eaa4d 100644 --- a/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul +++ b/test/libyul/yulPureInterpreterTests/shadowed_symbol.yul @@ -1,15 +1,15 @@ { - function f() - { - // Variable declaration does not shadow namesake function declaration - // because latter not visible here. - let shadow_id - } - { - // Function named `shadow_id` is in scope now. - f() - function shadow_id() {} - } + function f() + { + // Variable declaration does not shadow namesake function declaration + // because latter not visible here. + let shadow_id + } + { + // Function named `shadow_id` is in scope now. + f() + function shadow_id() {} + } } // ==== // EVMVersion: >=constantinople diff --git a/test/libyul/yulPureInterpreterTests/switch_statement.yul b/test/libyul/yulPureInterpreterTests/switch_statement.yul index fa69ce75113e..85b22b6de644 100644 --- a/test/libyul/yulPureInterpreterTests/switch_statement.yul +++ b/test/libyul/yulPureInterpreterTests/switch_statement.yul @@ -1,9 +1,9 @@ { let x switch 7 - case 7 { x := 1 } - case 3 { x := 2 } - default { x := 3 } + case 7 { x := 1 } + case 3 { x := 2 } + default { x := 3 } } // ---- // Execution result: ExecutionOk From 1e57604d882666f2a98aaa7f01d3de8d9a4f1da3 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 9 Oct 2024 00:39:07 +0700 Subject: [PATCH 086/101] Remove empty string message in assert --- .../PureEVMInstructionInterpreter.cpp | 2 +- libyul/interpreter/PureInterpreter.cpp | 24 +++++++++---------- libyul/interpreter/Scope.cpp | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp index 22e286ed146c..b61da01b860e 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -53,7 +53,7 @@ EvaluationResult PureEVMInstructionInterpreter::eval( using evmasm::Instruction; auto info = instructionInfo(_instruction, m_evmVersion); - yulAssert(static_cast(info.args) == _arguments.size(), ""); + yulAssert(static_cast(info.args) == _arguments.size()); auto const& arg = _arguments; switch (_instruction) diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index e27b391cf585..56f26b813374 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -53,7 +53,7 @@ ExecutionResult PureInterpreter::operator()(ExpressionStatement const& _expressi ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) { - solAssert(_assignment.value, ""); + solAssert(_assignment.value); EvaluationResult evalRes = evaluate(*_assignment.value, _assignment.variableNames.size()); if (auto* terminated = std::get_if(&evalRes)) return *terminated; @@ -63,7 +63,7 @@ ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) { YulName varName = _assignment.variableNames.at(i).name; auto [_, isNew] = m_variables.insert_or_assign(varName, values.at(i)); - solAssert(!isNew, ""); + solAssert(!isNew); } return ExecutionOk{ControlFlowState::Default}; } @@ -83,12 +83,12 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat values.assign(_declaration.variables.size(), 0); } - solAssert(values.size() == _declaration.variables.size(), ""); + solAssert(values.size() == _declaration.variables.size()); for (size_t i = 0; i < values.size(); ++i) { YulName varName = _declaration.variables.at(i).name; auto [_, isNew] = m_variables.insert_or_assign(varName, values.at(i)); - solAssert(isNew, ""); + solAssert(isNew); m_scope->addDeclaredVariable(varName); } return ExecutionOk{ControlFlowState::Default}; @@ -96,7 +96,7 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat ExecutionResult PureInterpreter::operator()(If const& _if) { - solAssert(_if.condition, ""); + solAssert(_if.condition); EvaluationResult conditionRes = evaluate(*_if.condition, 1); if (auto* terminated = std::get_if(&conditionRes)) return *terminated; @@ -108,8 +108,8 @@ ExecutionResult PureInterpreter::operator()(If const& _if) ExecutionResult PureInterpreter::operator()(Switch const& _switch) { - solAssert(_switch.expression, ""); - solAssert(!_switch.cases.empty(), ""); + solAssert(_switch.expression); + solAssert(!_switch.cases.empty()); EvaluationResult expressionRes = evaluate(*_switch.expression, 1); if (auto* terminated = std::get_if(&expressionRes)) @@ -141,7 +141,7 @@ ExecutionResult PureInterpreter::operator()(FunctionDefinition const&) ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) { - solAssert(_forLoop.condition, ""); + solAssert(_forLoop.condition); enterScope(_forLoop.pre); ScopeGuard g([this]{ leaveScope(); }); @@ -240,7 +240,7 @@ EvaluationResult PureInterpreter::operator()(Literal const& _literal) EvaluationResult PureInterpreter::operator()(Identifier const& _identifier) { auto it = m_variables.find(_identifier.name); - solAssert(it != m_variables.end(), ""); + solAssert(it != m_variables.end()); return EvaluationOk(it->second); } @@ -267,7 +267,7 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) FunctionDefinition const& fun = m_scope->getFunction(_funCall.functionName.name); - yulAssert(argsValues.size() == fun.parameters.size(), ""); + yulAssert(argsValues.size() == fun.parameters.size()); VariableValuesMap variables; for (size_t i = 0; i < fun.parameters.size(); ++i) variables[fun.parameters.at(i).name] = argsValues.at(i); @@ -305,7 +305,7 @@ EvaluationResult PureInterpreter::evaluate(Expression const& _expression, size_t { EvaluationResult res = visit(_expression); if (auto* resOk = std::get_if(&res)) - yulAssert(resOk->values.size() == _numReturnVars, ""); + yulAssert(resOk->values.size() == _numReturnVars); return res; } @@ -350,7 +350,7 @@ void PureInterpreter::leaveScope() { m_scope->cleanupVariables(m_variables); m_scope = m_scope->parent(); - yulAssert(m_scope, ""); + yulAssert(m_scope); } std::optional PureInterpreter::incrementStatementStep() diff --git a/libyul/interpreter/Scope.cpp b/libyul/interpreter/Scope.cpp index 0f5688e64208..77d638a2d48b 100644 --- a/libyul/interpreter/Scope.cpp +++ b/libyul/interpreter/Scope.cpp @@ -63,5 +63,5 @@ FunctionDefinition const& Scope::getFunction(YulName const& _functionName) const if (it != scope->m_definedFunctions.end()) return it->second; } - solAssert(false, ""); + solAssert(false); } From 99cc80b045efddb0f7dbfa996b57412eb93bd2ac Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Wed, 9 Oct 2024 00:56:22 +0700 Subject: [PATCH 087/101] Make variable name explicit --- .../PureEVMInstructionInterpreter.cpp | 14 +- .../PureEVMInstructionInterpreter.h | 2 +- libyul/interpreter/PureInterpreter.cpp | 132 +++++++++--------- libyul/interpreter/PureInterpreter.h | 8 +- libyul/interpreter/PureInterpreterState.cpp | 6 +- libyul/interpreter/Results.h | 4 +- libyul/interpreter/Scope.cpp | 4 +- test/libyul/YulPureInterpreterTest.cpp | 12 +- test/libyul/YulPureInterpreterTest.h | 4 +- 9 files changed, 93 insertions(+), 93 deletions(-) diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp index b61da01b860e..fb8b6f28595a 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -276,16 +276,16 @@ EvaluationResult PureEVMInstructionInterpreter::eval( } EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( - BuiltinFunctionForEVM const& _fun, + BuiltinFunctionForEVM const& _builtinFunction, std::vector const& /* _arguments */, // This was required to execute some builtin. std::vector const& _evaluatedArguments ) { - if (_fun.instruction) - return eval(*_fun.instruction, _evaluatedArguments); + if (_builtinFunction.instruction) + return eval(*_builtinFunction.instruction, _evaluatedArguments); - std::string fun = _fun.name.str(); - bool isVerbatim = boost::starts_with(fun, "verbatim"); + std::string functionName = _builtinFunction.name.str(); + bool isVerbatim = boost::starts_with(functionName, "verbatim"); if (isVerbatim) return ImpureBuiltinEncountered(); @@ -298,10 +298,10 @@ EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( "setimmutable", "linkersymbol" }; - if (NON_INSTRUCTION_BUILTIN_NAME.count(fun)) + if (NON_INSTRUCTION_BUILTIN_NAME.count(functionName)) return ImpureBuiltinEncountered(); - yulAssert(false, "Unknown builtin: " + fun); + yulAssert(false, "Unknown builtin: " + functionName); return EvaluationOk(0); } diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.h b/libyul/interpreter/PureEVMInstructionInterpreter.h index d380dda1c344..859523b1becd 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.h +++ b/libyul/interpreter/PureEVMInstructionInterpreter.h @@ -63,7 +63,7 @@ class PureEVMInstructionInterpreter /// Evaluate builtin function EvaluationResult evalBuiltin( - BuiltinFunctionForEVM const& _fun, + BuiltinFunctionForEVM const& _builtinFunction, std::vector const& _arguments, std::vector const& _evaluatedArguments ); diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index 56f26b813374..7442f7cafd84 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -45,8 +45,8 @@ using solidity::util::h256; ExecutionResult PureInterpreter::operator()(ExpressionStatement const& _expressionStatement) { - EvaluationResult res = evaluate(_expressionStatement.expression, 0); - if (auto* terminated = std::get_if(&res)) + EvaluationResult result = evaluate(_expressionStatement.expression, 0); + if (auto* terminated = std::get_if(&result)) return *terminated; return ExecutionOk{ControlFlowState::Default}; } @@ -54,11 +54,11 @@ ExecutionResult PureInterpreter::operator()(ExpressionStatement const& _expressi ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) { solAssert(_assignment.value); - EvaluationResult evalRes = evaluate(*_assignment.value, _assignment.variableNames.size()); - if (auto* terminated = std::get_if(&evalRes)) + EvaluationResult evalResult = evaluate(*_assignment.value, _assignment.variableNames.size()); + if (auto* terminated = std::get_if(&evalResult)) return *terminated; - std::vector const& values = std::move(std::get(evalRes).values); + std::vector const& values = std::move(std::get(evalResult).values); for (size_t i = 0; i < values.size(); ++i) { YulName varName = _assignment.variableNames.at(i).name; @@ -73,10 +73,10 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat std::vector values; if (_declaration.value) { - EvaluationResult evalRes = evaluate(*_declaration.value, _declaration.variables.size()); - if (auto* terminated = std::get_if(&evalRes)) + EvaluationResult evalResult = evaluate(*_declaration.value, _declaration.variables.size()); + if (auto* terminated = std::get_if(&evalResult)) return *terminated; - values = std::move(std::get(evalRes).values); + values = std::move(std::get(evalResult).values); } else { @@ -97,11 +97,11 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat ExecutionResult PureInterpreter::operator()(If const& _if) { solAssert(_if.condition); - EvaluationResult conditionRes = evaluate(*_if.condition, 1); - if (auto* terminated = std::get_if(&conditionRes)) + EvaluationResult conditionResult = evaluate(*_if.condition, 1); + if (auto* terminated = std::get_if(&conditionResult)) return *terminated; - if (std::get(conditionRes).values.at(0) != 0) + if (std::get(conditionResult).values.at(0) != 0) return (*this)(_if.body); return ExecutionOk{ControlFlowState::Default}; } @@ -111,25 +111,25 @@ ExecutionResult PureInterpreter::operator()(Switch const& _switch) solAssert(_switch.expression); solAssert(!_switch.cases.empty()); - EvaluationResult expressionRes = evaluate(*_switch.expression, 1); - if (auto* terminated = std::get_if(&expressionRes)) + EvaluationResult expressionResult = evaluate(*_switch.expression, 1); + if (auto* terminated = std::get_if(&expressionResult)) return *terminated; - u256 val = std::get(expressionRes).values.at(0); - for (auto const& c: _switch.cases) + u256 expressionValue = std::get(expressionResult).values.at(0); + for (auto const& currentCase: _switch.cases) { bool caseMatched = false; // Default case has to be last. - if (!c.value) caseMatched = true; + if (!currentCase.value) caseMatched = true; else { - EvaluationResult caseRes = evaluate(*c.value, 1); - if (auto* terminated = std::get_if(&caseRes)) + EvaluationResult caseResult = evaluate(*currentCase.value, 1); + if (auto* terminated = std::get_if(&caseResult)) return *terminated; - caseMatched = std::get(caseRes).values.at(0) == val; + caseMatched = std::get(caseResult).values.at(0) == expressionValue; } if (caseMatched) - return (*this)(c.body); + return (*this)(currentCase.body); } return ExecutionOk{ControlFlowState::Default}; } @@ -147,17 +147,17 @@ ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) ScopeGuard g([this]{ leaveScope(); }); { - ExecutionResult execRes = execute(_forLoop.pre.statements); - if (execRes == ExecutionResult(ExecutionOk{ControlFlowState::Leave})) - return execRes; + ExecutionResult preResult = execute(_forLoop.pre.statements); + if (preResult == ExecutionResult(ExecutionOk{ControlFlowState::Leave})) + return preResult; } while (true) { { - EvaluationResult conditionRes = evaluate(*_forLoop.condition, 1); - if (auto* terminated = std::get_if(&conditionRes)) + EvaluationResult conditionResult = evaluate(*_forLoop.condition, 1); + if (auto* terminated = std::get_if(&conditionResult)) return *terminated; - if (std::get(conditionRes).values.at(0) == 0) + if (std::get(conditionResult).values.at(0) == 0) break; } @@ -168,24 +168,24 @@ ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) return *terminated; { - ExecutionResult bodyRes = (*this)(_forLoop.body); + ExecutionResult bodyResult = (*this)(_forLoop.body); if ( - std::holds_alternative(bodyRes) || - bodyRes == ExecutionResult(ExecutionOk{ControlFlowState::Leave}) + std::holds_alternative(bodyResult) || + bodyResult == ExecutionResult(ExecutionOk{ControlFlowState::Leave}) ) - return bodyRes; + return bodyResult; - if (bodyRes == ExecutionResult(ExecutionOk{ControlFlowState::Break})) + if (bodyResult == ExecutionResult(ExecutionOk{ControlFlowState::Break})) return ExecutionOk{ControlFlowState::Default}; } { - ExecutionResult postRes = (*this)(_forLoop.post); + ExecutionResult postResult = (*this)(_forLoop.post); if ( - std::holds_alternative(postRes) || - postRes == ExecutionResult(ExecutionOk{ControlFlowState::Leave}) + std::holds_alternative(postResult) || + postResult == ExecutionResult(ExecutionOk{ControlFlowState::Leave}) ) - return postRes; + return postResult; } } return ExecutionOk{ControlFlowState::Default}; @@ -225,11 +225,11 @@ ExecutionResult PureInterpreter::execute(std::vector const& _statemen return ExecutionOk{ControlFlowState::Default}; } -ExecutionResult PureInterpreter::visit(Statement const& _st) +ExecutionResult PureInterpreter::visit(Statement const& _statement) { if (auto terminated = incrementStatementStep()) return *terminated; - return std::visit(*this, _st); + return std::visit(*this, _statement); } EvaluationResult PureInterpreter::operator()(Literal const& _literal) @@ -244,13 +244,13 @@ EvaluationResult PureInterpreter::operator()(Identifier const& _identifier) return EvaluationOk(it->second); } -EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) +EvaluationResult PureInterpreter::operator()(FunctionCall const& _functionCall) { std::vector> const* literalArguments = nullptr; - if (BuiltinFunction const* builtin = m_dialect.builtin(_funCall.functionName.name)) + if (BuiltinFunction const* builtin = m_dialect.builtin(_functionCall.functionName.name)) if (!builtin->literalArguments.empty()) literalArguments = &builtin->literalArguments; - EvaluationResult argsRes = evaluateArgs(_funCall.arguments, literalArguments); + EvaluationResult argsRes = evaluateArgs(_functionCall.arguments, literalArguments); if (auto* terminated = std::get_if(&argsRes)) return *terminated; @@ -258,73 +258,73 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _funCall) if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) { - if (BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) + if (BuiltinFunctionForEVM const* builtinFunction = dialect->builtin(_functionCall.functionName.name)) { PureEVMInstructionInterpreter interpreter(dialect->evmVersion()); - return interpreter.evalBuiltin(*fun, _funCall.arguments, argsValues); + return interpreter.evalBuiltin(*builtinFunction, _functionCall.arguments, argsValues); } } - FunctionDefinition const& fun = m_scope->getFunction(_funCall.functionName.name); + FunctionDefinition const& functionDefinition = m_scope->getFunction(_functionCall.functionName.name); - yulAssert(argsValues.size() == fun.parameters.size()); + yulAssert(argsValues.size() == functionDefinition.parameters.size()); VariableValuesMap variables; - for (size_t i = 0; i < fun.parameters.size(); ++i) - variables[fun.parameters.at(i).name] = argsValues.at(i); - for (size_t i = 0; i < fun.returnVariables.size(); ++i) - variables[fun.returnVariables.at(i).name] = 0; + for (size_t i = 0; i < functionDefinition.parameters.size(); ++i) + variables[functionDefinition.parameters.at(i).name] = argsValues.at(i); + for (size_t i = 0; i < functionDefinition.returnVariables.size(); ++i) + variables[functionDefinition.returnVariables.at(i).name] = 0; std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); - if (auto terminated = m_state.addTrace(fun, argsValues)) + if (auto terminated = m_state.addTrace(functionDefinition, argsValues)) return *terminated; - ExecutionResult funcBodyRes = (*interpreter)(fun.body); - if (auto* terminated = std::get_if(&funcBodyRes)) + ExecutionResult functionBodyResult = (*interpreter)(functionDefinition.body); + if (auto* terminated = std::get_if(&functionBodyResult)) return *terminated; std::vector returnedValues; - returnedValues.reserve(fun.returnVariables.size()); - for (auto const& retVar: fun.returnVariables) + returnedValues.reserve(functionDefinition.returnVariables.size()); + for (auto const& retVar: functionDefinition.returnVariables) returnedValues.emplace_back(interpreter->valueOfVariable(retVar.name)); - if (auto terminated = m_state.addTrace(fun, returnedValues)) + if (auto terminated = m_state.addTrace(functionDefinition, returnedValues)) return *terminated; return EvaluationOk(std::move(returnedValues)); } -EvaluationResult PureInterpreter::visit(Expression const& _st) +EvaluationResult PureInterpreter::visit(Expression const& _expression) { if (auto terminated = incrementExpressionStep()) return *terminated; - return std::visit(*this, _st); + return std::visit(*this, _expression); } EvaluationResult PureInterpreter::evaluate(Expression const& _expression, size_t _numReturnVars) { - EvaluationResult res = visit(_expression); - if (auto* resOk = std::get_if(&res)) + EvaluationResult result = visit(_expression); + if (auto* resOk = std::get_if(&result)) yulAssert(resOk->values.size() == _numReturnVars); - return res; + return result; } EvaluationResult PureInterpreter::evaluateArgs( - std::vector const& _expr, + std::vector const& _arguments, std::vector> const* _literalArguments ) { - std::vector values(_expr.size()); + std::vector values(_arguments.size()); /// Function arguments are evaluated in reverse. - for (size_t i = _expr.size(); i-- > 0; ) + for (size_t i = _arguments.size(); i-- > 0; ) { - auto const& expr = _expr[i]; + auto const& currentArgument = _arguments[i]; bool isLiteral = _literalArguments && _literalArguments->at(i); if (!isLiteral) { - EvaluationResult exprRes = evaluate(expr, 1); + EvaluationResult exprRes = evaluate(currentArgument, 1); if (auto* terminated = std::get_if(&exprRes)) return *terminated; std::vector const& exprValues = std::get(exprRes).values; @@ -332,10 +332,10 @@ EvaluationResult PureInterpreter::evaluateArgs( } else { - if (std::get(expr).value.unlimited()) + if (std::get(currentArgument).value.unlimited()) return UnlimitedLiteralEncountered(); else - values[i] = std::get(expr).value.value(); + values[i] = std::get(currentArgument).value.value(); } } return EvaluationOk(std::move(values)); diff --git a/libyul/interpreter/PureInterpreter.h b/libyul/interpreter/PureInterpreter.h index 42233c31cbb6..eb9f9dba4b05 100644 --- a/libyul/interpreter/PureInterpreter.h +++ b/libyul/interpreter/PureInterpreter.h @@ -88,15 +88,15 @@ class PureInterpreter /// Will not alter the scope. ExecutionResult execute(std::vector const& _statements); - ExecutionResult visit(Statement const& _st); + ExecutionResult visit(Statement const& _statement); // Expression visit methods EvaluationResult operator()(Literal const&); EvaluationResult operator()(Identifier const&); - EvaluationResult operator()(FunctionCall const& _funCall); + EvaluationResult operator()(FunctionCall const& _functionCall); - EvaluationResult visit(Expression const& _st); + EvaluationResult visit(Expression const& _expression); u256 valueOfVariable(YulName _name) const { return m_variables.at(_name); } VariableValuesMap const& allVariables() const { return m_variables; } @@ -119,7 +119,7 @@ class PureInterpreter /// Evaluates the given expression from right to left and /// stores it in m_value. EvaluationResult evaluateArgs( - std::vector const& _expr, + std::vector const& _arguments, std::vector> const* _literalArguments ); diff --git a/libyul/interpreter/PureInterpreterState.cpp b/libyul/interpreter/PureInterpreterState.cpp index 193111d1cd7b..8949ab62399a 100644 --- a/libyul/interpreter/PureInterpreterState.cpp +++ b/libyul/interpreter/PureInterpreterState.cpp @@ -37,15 +37,15 @@ void PureInterpreterState::dumpTraces(std::ostream& _out) const _out << "Call trace:\n"; std::vector stackTrace; - auto print_values = [&](std::vector const& vec) + auto print_values = [&](std::vector const& values) { bool isFirst = true; - for (auto x: vec) + for (u256 value: values) { if (!isFirst) _out << ", "; isFirst = false; - _out << x; + _out << value; } }; diff --git a/libyul/interpreter/Results.h b/libyul/interpreter/Results.h index a535ba773ef7..6fa89c4f5f78 100644 --- a/libyul/interpreter/Results.h +++ b/libyul/interpreter/Results.h @@ -104,8 +104,8 @@ struct EvaluationOk { } - explicit EvaluationOk(u256 _x): - values{_x} + explicit EvaluationOk(u256 _value): + values{_value} { } diff --git a/libyul/interpreter/Scope.cpp b/libyul/interpreter/Scope.cpp index 77d638a2d48b..33343c7fd094 100644 --- a/libyul/interpreter/Scope.cpp +++ b/libyul/interpreter/Scope.cpp @@ -36,8 +36,8 @@ Scope* Scope::getSubscope(Block const& _block) Scope* subscope = it->second.get(); for (auto const& statement: _block.statements) - if (auto const* funDef = std::get_if(&statement)) - subscope->m_definedFunctions.emplace(funDef->name, *funDef); + if (auto const* functionDefinition = std::get_if(&statement)) + subscope->m_definedFunctions.emplace(functionDefinition->name, *functionDefinition); return subscope; } diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index 5e87ba50b827..38675edc7df8 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -109,12 +109,12 @@ std::string YulPureInterpreterTest::interpret() const interpreter::Scope* subscope = rootScope.getSubscope(block); PureInterpreter interpreter(state, dialect, *subscope, 0); - ExecutionResult res = interpreter.execute(block.statements); + ExecutionResult result = interpreter.execute(block.statements); VariableValuesMap const& outerMostVariables = interpreter.allVariables(); dumpExecutionData( resultStream, - res, + result, state, outerMostVariables ); @@ -124,13 +124,13 @@ std::string YulPureInterpreterTest::interpret() const void YulPureInterpreterTest::dumpExecutionData( std::ostream& _stream, - interpreter::ExecutionResult _res, + interpreter::ExecutionResult _result, interpreter::PureInterpreterState const& _state, VariableValuesMap const& _outerMostVariables ) const { _stream << "Execution result: "; - dumpExecutionResult(_stream, _res); + dumpExecutionResult(_stream, _result); _stream << std::endl; _stream << "Outer most variable values:" << std::endl; @@ -140,7 +140,7 @@ void YulPureInterpreterTest::dumpExecutionData( _state.dumpTraces(_stream); } -void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, interpreter::ExecutionResult _res) const +void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, interpreter::ExecutionResult _result) const { _stream << std::visit(GenericVisitor { [&](ExecutionOk) { return "ExecutionOk"; }, @@ -155,7 +155,7 @@ void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, interpre [&](TraceLimitReached) { return "TraceLimitReached"; } }, terminated); } - }, _res); + }, _result); } void YulPureInterpreterTest::dumpVariables( diff --git a/test/libyul/YulPureInterpreterTest.h b/test/libyul/YulPureInterpreterTest.h index 463a0705b0ed..e941df7fdd0f 100644 --- a/test/libyul/YulPureInterpreterTest.h +++ b/test/libyul/YulPureInterpreterTest.h @@ -50,11 +50,11 @@ class YulPureInterpreterTest: public solidity::frontend::test::EVMVersionRestric std::string interpret() const; void dumpExecutionData( std::ostream& _stream, - interpreter::ExecutionResult _res, + interpreter::ExecutionResult _result, interpreter::PureInterpreterState const& _state, interpreter::VariableValuesMap const& _outerMostVariables ) const; - void dumpExecutionResult(std::ostream& _stream, interpreter::ExecutionResult _res) const; + void dumpExecutionResult(std::ostream& _stream, interpreter::ExecutionResult _result) const; void dumpVariables(std::ostream& _stream, interpreter::VariableValuesMap const& _variables) const; void dumpValue(std::ostream& _stream, u256 _value) const; From fba9c0acf5388b6253cdfbc38b3aeba269502d83 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Tue, 15 Oct 2024 01:05:07 +0700 Subject: [PATCH 088/101] Move pure_instructions test generator into test comment --- .../pure_instructions/.generate-test.py | 184 ------------ .../pure_instructions/add.yul | 277 ++++++++++++----- .../pure_instructions/addmod.yul | 277 ++++++++++++----- .../pure_instructions/and.yul | 277 ++++++++++++----- .../pure_instructions/byte.yul | 247 ++++++++++++---- .../pure_instructions/div.yul | 277 ++++++++++++----- .../pure_instructions/eq.yul | 278 +++++++++++++----- .../pure_instructions/exp.yul | 277 ++++++++++++----- .../pure_instructions/gt.yul | 277 ++++++++++++----- .../pure_instructions/iszero.yul | 171 ++++++++++- .../pure_instructions/lt.yul | 277 ++++++++++++----- .../pure_instructions/mod.yul | 277 ++++++++++++----- .../pure_instructions/mul.yul | 277 ++++++++++++----- .../pure_instructions/mulmod.yul | 277 ++++++++++++----- .../pure_instructions/not.yul | 171 ++++++++++- .../pure_instructions/or.yul | 277 ++++++++++++----- .../pure_instructions/sar.yul | 277 ++++++++++++----- .../pure_instructions/sdiv.yul | 277 ++++++++++++----- .../pure_instructions/sgt.yul | 277 ++++++++++++----- .../pure_instructions/shl.yul | 277 ++++++++++++----- .../pure_instructions/shr.yul | 277 ++++++++++++----- .../pure_instructions/signextend.yul | 277 ++++++++++++----- .../pure_instructions/slt.yul | 277 ++++++++++++----- .../pure_instructions/smod.yul | 277 ++++++++++++----- .../pure_instructions/sub.yul | 277 ++++++++++++----- .../pure_instructions/xor.yul | 277 ++++++++++++----- 26 files changed, 5106 insertions(+), 1762 deletions(-) delete mode 100644 test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py b/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py deleted file mode 100644 index 4a526d96e319..000000000000 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/.generate-test.py +++ /dev/null @@ -1,184 +0,0 @@ -# pyright: strict - -from itertools import product -import random -import os - -from typing import Callable, Iterable, Union - -os.chdir(os.path.dirname(os.path.abspath(__file__))) - -random.seed(20240823) - -MX = 2**256 - - -def u256(num: int): - return int(num) % MX - - -def u2s(num: int): - return int(num) - MX if (int(num) >> 255) > 0 else int(num) - - -def gen_test( - fn_name: str, - *, - param_cnt: int, - calc: Callable[[tuple[int, ...]], int], - test_numbers: Union[Iterable[int], None] = None, - evm_version: Union[str, None] = None, -): - print("Generating test for", fn_name) - - src: list[str] = [] - src.append("{") - src.append( - """ - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } -""" - ) - - if test_numbers is None: - if param_cnt == 1: - test_numbers = [ - 0, - 1, - 2, - 3, - MX - 1, - MX - 2, - MX - 3, - random.randrange(MX), - random.randrange(MX), - random.randrange(MX), - random.randrange(MX), - ] - else: - test_numbers = [ - 0, - 1, - 2, - MX - 1, - MX - 2, - random.randrange(MX), - random.randrange(MX), - random.randrange(MX), - ] - - param_set = list(product(test_numbers, repeat=param_cnt)) - - for p in param_set: - res = u256(calc(p)) - # printing hex to save space - src.append(f" check({fn_name}({', '.join(hex(i) for i in p)}), {hex(res)})") - src.append("}") - - src.append("// ====") - src.append("// maxTraceSize: 0") - if evm_version is not None: - src.append(f"// EVMVersion: {evm_version}") - - with open(fn_name + ".yul", "w", encoding="utf-8") as f: - print("\n".join(src), file=f) - - -def main(): - gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) - gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) - gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) - gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) - gen_test("sdiv", param_cnt=2, calc=signed_div) - gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) - gen_test("smod", param_cnt=2, calc=signed_mod) - gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) - gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) - gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) - gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) - gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) - gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) - gen_test("eq", param_cnt=2, calc=lambda p: p[0] == p[1]) - gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) - gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) - gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) - gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) - gen_test( - "byte", - param_cnt=2, - test_numbers=[ - random.randrange(MX), - random.randrange(MX), - random.randrange(MX), - random.randrange(1, 32), - random.randrange(1, 32), - random.randrange(1, 32), - 0, - ], - calc=lambda p: 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF, - ) - gen_test( - "shl", - evm_version=">=constantinople", - param_cnt=2, - calc=lambda p: p[1] << p[0] if p[0] < 32 else 0, - ) - gen_test( - "shr", evm_version=">=constantinople", param_cnt=2, calc=lambda p: p[1] >> p[0] - ) - gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) - gen_test( - "addmod", - param_cnt=3, - test_numbers=[random.randrange(0, MX) for _ in range(3)] + [0], - calc=lambda p: (p[0] + p[1]) % p[2] if p[2] != 0 else 0, - ) - gen_test( - "mulmod", - param_cnt=3, - test_numbers=[random.randrange(0, MX) for _ in range(3)] + [0], - calc=lambda p: (p[0] * p[1]) % p[2] if p[2] != 0 else 0, - ) - gen_test("signextend", param_cnt=2, calc=signextend) - - -def signed_div(p: tuple[int, ...]): - (a, b) = u2s(p[0]), u2s(p[1]) - if b == 0: - return 0 - res = abs(a) // abs(b) - if (a < 0) != (b < 0): - res = -res - return res - - -def signed_mod(p: tuple[int, ...]): - (a, b) = u2s(p[0]), u2s(p[1]) - if b == 0: - return 0 - res = abs(a) % abs(b) - if a < 0: - res = -res - return res - - -def sar(p: tuple[int, ...]): - (sh, val) = p - high_bit = val >> 255 - val >>= sh - val |= u256(-high_bit) << max(0, 255 - sh) - return val - - -def signextend(p: tuple[int, ...]): - (byte_pos, val) = p - byte_pos = min(byte_pos, 32) - mask_shift = byte_pos * 8 + 8 - high_bit = (val >> (mask_shift - 1)) & 1 - if high_bit: - return val | (u256(-1) << mask_shift) - return val & ((1 << mask_shift) - 1) - - -if __name__ == "__main__": - main() diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul index 492d8522a108..77b06e9cf73c 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/add.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(add(0x0, 0x0), 0x0) - check(add(0x0, 0x1), 0x1) - check(add(0x0, 0x2), 0x2) - check(add(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(add(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(add(0x0, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e) - check(add(0x0, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb) - check(add(0x0, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574) - check(add(0x1, 0x0), 0x1) - check(add(0x1, 0x1), 0x2) - check(add(0x1, 0x2), 0x3) - check(add(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(add(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(add(0x1, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398f) - check(add(0x1, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efc) - check(add(0x1, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e575) - check(add(0x2, 0x0), 0x2) - check(add(0x2, 0x1), 0x3) - check(add(0x2, 0x2), 0x4) - check(add(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(add(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(add(0x2, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b33990) - check(add(0x2, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efd) - check(add(0x2, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e576) - check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) - check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) - check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) - check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398d) - check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efa) - check(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e573) - check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) - check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) - check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) - check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398c) - check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1ef9) - check(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e572) - check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x0), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e) - check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x1), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398f) - check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x2), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b33990) - check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398d) - check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398c) - check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x638a6e388cf11081b2e62616b8e3be4be4c12052e95614e3b93cdd8fcf66731c) - check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x5d3c3368d3cf1ddc8a0e4036f8c137f37e47783e6633e6b6deff48a54e0d5889) - check(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x7fb80915e27333205ab37631d761b147aef85386ae437f3bc7162eaebf7b1f02) - check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x0), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb) - check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x1), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efc) - check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x2), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efd) - check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efa) - check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1ef9) - check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x5d3c3368d3cf1ddc8a0e4036f8c137f37e47783e6633e6b6deff48a54e0d5889) - check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x56edf8991aad2b3761365a57389eb19b17cdd029e311b88a04c1b3baccb43df6) - check(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x7969ce462951407b31db9052173f2aef487eab722b21510eecd899c43e22046f) - check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x0), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574) - check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x1), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e575) - check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x2), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e576) - check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e573) - check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e572) - check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x7fb80915e27333205ab37631d761b147aef85386ae437f3bc7162eaebf7b1f02) - check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x7969ce462951407b31db9052173f2aef487eab722b21510eecd899c43e22046f) - check(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x9be5a3f337f555bf0280c64cf5dfa443792f86ba7330e993d4ef7fcdaf8fcae8) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(add(0x0, 0x0), 0x0) + checkEq(add(0x0, 0x1), 0x1) + checkEq(add(0x0, 0x2), 0x2) + checkEq(add(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(add(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(add(0x0, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e) + checkEq(add(0x0, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb) + checkEq(add(0x0, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574) + checkEq(add(0x1, 0x0), 0x1) + checkEq(add(0x1, 0x1), 0x2) + checkEq(add(0x1, 0x2), 0x3) + checkEq(add(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(add(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(add(0x1, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398f) + checkEq(add(0x1, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efc) + checkEq(add(0x1, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e575) + checkEq(add(0x2, 0x0), 0x2) + checkEq(add(0x2, 0x1), 0x3) + checkEq(add(0x2, 0x2), 0x4) + checkEq(add(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(add(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(add(0x2, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b33990) + checkEq(add(0x2, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efd) + checkEq(add(0x2, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e576) + checkEq(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + checkEq(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) + checkEq(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + checkEq(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398d) + checkEq(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efa) + checkEq(add(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e573) + checkEq(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + checkEq(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + checkEq(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + checkEq(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398c) + checkEq(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1ef9) + checkEq(add(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e572) + checkEq(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x0), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e) + checkEq(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x1), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398f) + checkEq(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x2), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b33990) + checkEq(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398d) + checkEq(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398c) + checkEq(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x638a6e388cf11081b2e62616b8e3be4be4c12052e95614e3b93cdd8fcf66731c) + checkEq(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x5d3c3368d3cf1ddc8a0e4036f8c137f37e47783e6633e6b6deff48a54e0d5889) + checkEq(add(0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x7fb80915e27333205ab37631d761b147aef85386ae437f3bc7162eaebf7b1f02) + checkEq(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x0), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb) + checkEq(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x1), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efc) + checkEq(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x2), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efd) + checkEq(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efa) + checkEq(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1ef9) + checkEq(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x5d3c3368d3cf1ddc8a0e4036f8c137f37e47783e6633e6b6deff48a54e0d5889) + checkEq(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x56edf8991aad2b3761365a57389eb19b17cdd029e311b88a04c1b3baccb43df6) + checkEq(add(0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x7969ce462951407b31db9052173f2aef487eab722b21510eecd899c43e22046f) + checkEq(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x0), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574) + checkEq(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x1), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e575) + checkEq(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x2), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e576) + checkEq(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e573) + checkEq(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e572) + checkEq(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x31c5371c46788840d973130b5c71df25f260902974ab0a71dc9e6ec7e7b3398e), 0x7fb80915e27333205ab37631d761b147aef85386ae437f3bc7162eaebf7b1f02) + checkEq(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x2b76fc4c8d56959bb09b2d2b9c4f58cd8be6e814f188dc450260d9dd665a1efb), 0x7969ce462951407b31db9052173f2aef487eab722b21510eecd899c43e22046f) + checkEq(add(0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574, 0x4df2d1f99bfaaadf814063267aefd221bc97c35d399874c9ea77bfe6d7c7e574), 0x9be5a3f337f555bf0280c64cf5dfa443792f86ba7330e993d4ef7fcdaf8fcae8) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul index d82d8dd2503f..98b2bfdc1d63 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/addmod.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x0) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x65d1cf826d6464457ae01220a0b5fdf6b37c83bec35900b77d52b314abe9e47e) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x369f68bf83db6415dd647089401beb7bbe37d9e8ea95ec53050df3454fd8ba3f) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0), 0x0) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x32c0ed0fcae805766b9849917b7ea7f8606d2e93dcddad9076fbd6f717139e56) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x696055cf4ec3698c48fcba1abb9a93741ea5087cc77399e37c09ca3c66ec5895) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0), 0x0) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x61f353d2b47105a60913eb28dc18ba7355b1d869b5a0c1f4ef4096c67324c895) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0xc7c5235521d569eb83f3fd497cceb86a092e5c2878f9c2ac6c9349db1f0ead13) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0), 0x0) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x0) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) - check(addmod(0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0, 0x0), 0x0) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x32c0ed0fcae805766b9849917b7ea7f8606d2e93dcddad9076fbd6f717139e56) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x696055cf4ec3698c48fcba1abb9a93741ea5087cc77399e37c09ca3c66ec5895) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0), 0x0) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x6581da1f95d00aecd7309322f6fd4ff0c0da5d27b9bb5b20edf7adee2e273cac) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x0) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x9c2142df19ab6f02b49503ac37193b6c7f123710a4514773f305a1337dfff6eb) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0), 0x0) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x94b440e27f590b1c74ac34ba5797626bb61f06fd927e6f85663c6dbd8a3866eb) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x2f3266c2e989002f9d7ba197609a127af544a9d5d8c314647844bfcf5c112a3f) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0), 0x0) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x32c0ed0fcae805766b9849917b7ea7f8606d2e93dcddad9076fbd6f717139e56) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x0) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a) - check(addmod(0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0, 0x0), 0x0) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x61f353d2b47105a60913eb28dc18ba7355b1d869b5a0c1f4ef4096c67324c895) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0xc7c5235521d569eb83f3fd497cceb86a092e5c2878f9c2ac6c9349db1f0ead13) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0), 0x0) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x94b440e27f590b1c74ac34ba5797626bb61f06fd927e6f85663c6dbd8a3866eb) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x2f3266c2e989002f9d7ba197609a127af544a9d5d8c314647844bfcf5c112a3f) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0), 0x0) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x2b53eb133095a1902baf7a9f9bfccef79779fe80cb0ad5a1ea32a381234c0e56) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x5e64cd85d312005f3af7432ec13424f5ea8953abb18628c8f0897f9eb822547e) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x0) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0), 0x0) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x61f353d2b47105a60913eb28dc18ba7355b1d869b5a0c1f4ef4096c67324c895) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x2f3266c2e989002f9d7ba197609a127af544a9d5d8c314647844bfcf5c112a3f) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x0) - check(addmod(0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0, 0x0), 0x0) - check(addmod(0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x0) - check(addmod(0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) - check(addmod(0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4) - check(addmod(0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4, 0x0), 0x0) - check(addmod(0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x32c0ed0fcae805766b9849917b7ea7f8606d2e93dcddad9076fbd6f717139e56) - check(addmod(0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x0) - check(addmod(0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a) - check(addmod(0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a, 0x0), 0x0) - check(addmod(0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x61f353d2b47105a60913eb28dc18ba7355b1d869b5a0c1f4ef4096c67324c895) - check(addmod(0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x2f3266c2e989002f9d7ba197609a127af544a9d5d8c314647844bfcf5c112a3f) - check(addmod(0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x0) - check(addmod(0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69, 0x0), 0x0) - check(addmod(0x0, 0x0, 0x9892bc92384c69bbe6785bb21c34a5ef13e9b252a036ae47f44e8a0bc2fd82d4), 0x0) - check(addmod(0x0, 0x0, 0xcb53a9a203346f325210a54397b34de77456e0e67d145bd86b4a6102da11212a), 0x0) - check(addmod(0x0, 0x0, 0xfa861064ecbd6f61ef8c46daf84d6062699b8abc55d7703ce38f20d236224b69), 0x0) - check(addmod(0x0, 0x0, 0x0), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x0) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0xe1a9b9f1388a813deee43e2ae1eaf63d095398f17d3fa26e6d0a2e7c83d0e08) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x477b5e7b39240975dafc6cded0d12525798037e87adc18634564fe3f9fee21e) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x0), 0x0) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x70d4dcf89c45409ef7721f1570f57b1e84a9cc78be9fd1373685173e41e8704) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x88b889e995139d59e267f8a786a4134fe0832522c8b44677b0b7b5d6e71e89c) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x0), 0x0) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x1ecdc9ab7857d465fe0234e63d434e5e1b7dc9888e1a4450ef4675381f9503a0) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x23bdaf3d9c9204baed7e366f68689292bcc01bf43d6e0c31a2b27f1fcff710f) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x0), 0x0) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x0, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x0) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x0, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x70d4dcf89c45409ef7721f1570f57b1e84a9cc78be9fd1373685173e41e8704) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x0, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x23bdaf3d9c9204baed7e366f68689292bcc01bf43d6e0c31a2b27f1fcff710f) + checkEq(addmod(0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x0, 0x0), 0x0) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x70d4dcf89c45409ef7721f1570f57b1e84a9cc78be9fd1373685173e41e8704) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x88b889e995139d59e267f8a786a4134fe0832522c8b44677b0b7b5d6e71e89c) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x0), 0x0) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x9b22427d1685353c35dfaa0468ff3820d7ab6dabde8a72b9a8f57d7047abdac2) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x0) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0xc9f5b557f103313de9d384703c77017a4786125d168c748c1c0a6d6e2e4ef1a) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x0), 0x0) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x65519d1a79d61afa297ae7f71ab392bc9f08e396f175809a5058e27c5f4c69fd) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x64fadaabf881989ef4e9c2381e3b80bd23c3092e8b463a460e0536b7172778d) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x0), 0x0) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x0, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x0, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x0) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x0, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x64fadaabf881989ef4e9c2381e3b80bd23c3092e8b463a460e0536b7172778d) + checkEq(addmod(0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x0, 0x0), 0x0) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x1ecdc9ab7857d465fe0234e63d434e5e1b7dc9888e1a4450ef4675381f9503a0) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x23bdaf3d9c9204baed7e366f68689292bcc01bf43d6e0c31a2b27f1fcff710f) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x0), 0x0) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x65519d1a79d61afa297ae7f71ab392bc9f08e396f175809a5058e27c5f4c69fd) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x64fadaabf881989ef4e9c2381e3b80bd23c3092e8b463a460e0536b7172778d) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x0), 0x0) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x2f80f7b7dd2700b81d1625e9cc67ed586666598204608e7af7bc478876ecf938) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x2f80f7b7dd2700b81d1625e9cc67ed586666598204608e7af7bc478876ecf938) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x0) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x0), 0x0) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x0, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x0, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x0, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x0) + checkEq(addmod(0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x0, 0x0), 0x0) + checkEq(addmod(0x0, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x0) + checkEq(addmod(0x0, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x70d4dcf89c45409ef7721f1570f57b1e84a9cc78be9fd1373685173e41e8704) + checkEq(addmod(0x0, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x23bdaf3d9c9204baed7e366f68689292bcc01bf43d6e0c31a2b27f1fcff710f) + checkEq(addmod(0x0, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27, 0x0), 0x0) + checkEq(addmod(0x0, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61) + checkEq(addmod(0x0, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x0) + checkEq(addmod(0x0, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x64fadaabf881989ef4e9c2381e3b80bd23c3092e8b463a460e0536b7172778d) + checkEq(addmod(0x0, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61, 0x0), 0x0) + checkEq(addmod(0x0, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c) + checkEq(addmod(0x0, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c) + checkEq(addmod(0x0, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x0) + checkEq(addmod(0x0, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c, 0x0), 0x0) + checkEq(addmod(0x0, 0x0, 0xefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c4fa04f27), 0x0) + checkEq(addmod(0x0, 0x0, 0x4d91213e8b429a9e1aefd502347f9c106bd5b6d5ef45395cd47abeb823d5ed61), 0x0) + checkEq(addmod(0x0, 0x0, 0x17c07bdbee93805c0e8b12f4e633f6ac33332cc10230473d7bde23c43b767c9c), 0x0) + checkEq(addmod(0x0, 0x0, 0x0), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul index 677b8e924e1c..b826fa58b047 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/and.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(and(0x0, 0x0), 0x0) - check(and(0x0, 0x1), 0x0) - check(and(0x0, 0x2), 0x0) - check(and(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(and(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(and(0x0, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0x0) - check(and(0x0, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0x0) - check(and(0x0, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0x0) - check(and(0x1, 0x0), 0x0) - check(and(0x1, 0x1), 0x1) - check(and(0x1, 0x2), 0x0) - check(and(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(and(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(and(0x1, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0x0) - check(and(0x1, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0x1) - check(and(0x1, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0x1) - check(and(0x2, 0x0), 0x0) - check(and(0x2, 0x1), 0x0) - check(and(0x2, 0x2), 0x2) - check(and(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) - check(and(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) - check(and(0x2, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0x2) - check(and(0x2, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0x0) - check(and(0x2, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0x2) - check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) - check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x2) - check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) - check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) - check(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) - check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) - check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x2) - check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) - check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da70) - check(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44ba) - check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0x0), 0x0) - check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0x1), 0x0) - check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0x2), 0x2) - check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) - check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) - check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) - check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xc3400802848010df4642206021051440870162a506200c1c0911383c44039050) - check(and(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0x8842088480815896109824c024810a628e04220806000d1e4891327d001c0012) - check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0x0), 0x0) - check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0x1), 0x1) - check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0x2), 0x0) - check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) - check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da70) - check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xc3400802848010df4642206021051440870162a506200c1c0911383c44039050) - check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) - check(and(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa0d40c20808a10960020204820310044867833404610ec1c0a31f0be02c04031) - check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0x0), 0x0) - check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0x1), 0x1) - check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0x2), 0x2) - check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) - check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44ba) - check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0x8842088480815896109824c024810a628e04220806000d1e4891327d001c0012) - check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xa0d40c20808a10960020204820310044867833404610ec1c0a31f0be02c04031) - check(and(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(and(0x0, 0x0), 0x0) + checkEq(and(0x0, 0x1), 0x0) + checkEq(and(0x0, 0x2), 0x0) + checkEq(and(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(and(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(and(0x0, 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701), 0x0) + checkEq(and(0x0, 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be), 0x0) + checkEq(and(0x0, 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d), 0x0) + checkEq(and(0x1, 0x0), 0x0) + checkEq(and(0x1, 0x1), 0x1) + checkEq(and(0x1, 0x2), 0x0) + checkEq(and(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(and(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(and(0x1, 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701), 0x1) + checkEq(and(0x1, 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be), 0x0) + checkEq(and(0x1, 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d), 0x1) + checkEq(and(0x2, 0x0), 0x0) + checkEq(and(0x2, 0x1), 0x0) + checkEq(and(0x2, 0x2), 0x2) + checkEq(and(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) + checkEq(and(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) + checkEq(and(0x2, 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701), 0x0) + checkEq(and(0x2, 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be), 0x2) + checkEq(and(0x2, 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d), 0x0) + checkEq(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) + checkEq(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x2) + checkEq(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701), 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701) + checkEq(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be), 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be) + checkEq(and(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d), 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d) + checkEq(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + checkEq(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x2) + checkEq(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701), 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044700) + checkEq(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be), 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be) + checkEq(and(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d), 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6c) + checkEq(and(0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701, 0x0), 0x0) + checkEq(and(0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701, 0x1), 0x1) + checkEq(and(0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701, 0x2), 0x0) + checkEq(and(0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701) + checkEq(and(0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044700) + checkEq(and(0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701, 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701), 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701) + checkEq(and(0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701, 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be), 0x5a08a003a0488c9c036514000016ad28302208090612c2549b10c390aa000400) + checkEq(and(0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701, 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d), 0x52042013014a849801241020825e6d1120e3002b24323a649b1d42a148040301) + checkEq(and(0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be, 0x0), 0x0) + checkEq(and(0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be, 0x1), 0x0) + checkEq(and(0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be, 0x2), 0x2) + checkEq(and(0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be) + checkEq(and(0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be) + checkEq(and(0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be, 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701), 0x5a08a003a0488c9c036514000016ad28302208090612c2549b10c390aa000400) + checkEq(and(0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be, 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be), 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be) + checkEq(and(0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be, 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d), 0x76012407005c8498212c120b01162d00202a1319c49206c49f9052880c42302c) + checkEq(and(0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d, 0x0), 0x0) + checkEq(and(0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d, 0x1), 0x1) + checkEq(and(0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d, 0x2), 0x0) + checkEq(and(0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d) + checkEq(and(0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6c) + checkEq(and(0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d, 0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701), 0x52042013014a849801241020825e6d1120e3002b24323a649b1d42a148040301) + checkEq(and(0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d, 0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be), 0x76012407005c8498212c120b01162d00202a1319c49206c49f9052880c42302c) + checkEq(and(0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d, 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d), 0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul index 2c5f014fb312..92e48d709132 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/byte.yul @@ -1,57 +1,198 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x0) - check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x0) - check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x0) - check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x16), 0x0) - check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x9), 0x0) - check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x1f), 0x0) - check(byte(0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748, 0x0), 0x0) - check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x0) - check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x0) - check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x0) - check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x16), 0x0) - check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x9), 0x0) - check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x1f), 0x0) - check(byte(0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855, 0x0), 0x0) - check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x0) - check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x0) - check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x0) - check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x16), 0x0) - check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x9), 0x0) - check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x1f), 0x0) - check(byte(0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2, 0x0), 0x0) - check(byte(0x16, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x3f) - check(byte(0x16, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x94) - check(byte(0x16, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x86) - check(byte(0x16, 0x16), 0x0) - check(byte(0x16, 0x9), 0x0) - check(byte(0x16, 0x1f), 0x0) - check(byte(0x16, 0x0), 0x0) - check(byte(0x9, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0xb6) - check(byte(0x9, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x46) - check(byte(0x9, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0x21) - check(byte(0x9, 0x16), 0x0) - check(byte(0x9, 0x9), 0x0) - check(byte(0x9, 0x1f), 0x0) - check(byte(0x9, 0x0), 0x0) - check(byte(0x1f, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x48) - check(byte(0x1f, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x55) - check(byte(0x1f, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0xd2) - check(byte(0x1f, 0x16), 0x16) - check(byte(0x1f, 0x9), 0x9) - check(byte(0x1f, 0x1f), 0x1f) - check(byte(0x1f, 0x0), 0x0) - check(byte(0x0, 0x18f76fcc2c24df8c0b6177329e34167b9a0fe7f2f333f87ac1a6b66c94df748), 0x1) - check(byte(0x0, 0x276fd280818d7e858e46f4e43dc70433dff8afb24f559451edaecbb103873855), 0x27) - check(byte(0x0, 0xc9d108de536b39631e21aa81c0f3e02c2df5e49ec7628625147361ceba089ed2), 0xc9) - check(byte(0x0, 0x16), 0x0) - check(byte(0x0, 0x9), 0x0) - check(byte(0x0, 0x1f), 0x0) - check(byte(0x0, 0x0), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(byte(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x0) + checkEq(byte(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x0) + checkEq(byte(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x0) + checkEq(byte(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0xd), 0x0) + checkEq(byte(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x10), 0x0) + checkEq(byte(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x17), 0x0) + checkEq(byte(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x0), 0x0) + checkEq(byte(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x0) + checkEq(byte(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x0) + checkEq(byte(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x0) + checkEq(byte(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0xd), 0x0) + checkEq(byte(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x10), 0x0) + checkEq(byte(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x17), 0x0) + checkEq(byte(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x0), 0x0) + checkEq(byte(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x0) + checkEq(byte(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x0) + checkEq(byte(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x0) + checkEq(byte(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0xd), 0x0) + checkEq(byte(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x10), 0x0) + checkEq(byte(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x17), 0x0) + checkEq(byte(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x0), 0x0) + checkEq(byte(0xd, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0xf5) + checkEq(byte(0xd, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x9a) + checkEq(byte(0xd, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xbc) + checkEq(byte(0xd, 0xd), 0x0) + checkEq(byte(0xd, 0x10), 0x0) + checkEq(byte(0xd, 0x17), 0x0) + checkEq(byte(0xd, 0x0), 0x0) + checkEq(byte(0x10, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x2b) + checkEq(byte(0x10, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x5e) + checkEq(byte(0x10, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x8d) + checkEq(byte(0x10, 0xd), 0x0) + checkEq(byte(0x10, 0x10), 0x0) + checkEq(byte(0x10, 0x17), 0x0) + checkEq(byte(0x10, 0x0), 0x0) + checkEq(byte(0x17, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x3) + checkEq(byte(0x17, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x89) + checkEq(byte(0x17, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xb3) + checkEq(byte(0x17, 0xd), 0x0) + checkEq(byte(0x17, 0x10), 0x0) + checkEq(byte(0x17, 0x17), 0x0) + checkEq(byte(0x17, 0x0), 0x0) + checkEq(byte(0x0, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x82) + checkEq(byte(0x0, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x2f) + checkEq(byte(0x0, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xdb) + checkEq(byte(0x0, 0xd), 0x0) + checkEq(byte(0x0, 0x10), 0x0) + checkEq(byte(0x0, 0x17), 0x0) + checkEq(byte(0x0, 0x0), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul index c301946a8c4f..43aebb2ac0b8 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/div.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(div(0x0, 0x0), 0x0) - check(div(0x0, 0x1), 0x0) - check(div(0x0, 0x2), 0x0) - check(div(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(div(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(div(0x0, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) - check(div(0x0, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x0) - check(div(0x0, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) - check(div(0x1, 0x0), 0x0) - check(div(0x1, 0x1), 0x1) - check(div(0x1, 0x2), 0x0) - check(div(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(div(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(div(0x1, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) - check(div(0x1, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x0) - check(div(0x1, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) - check(div(0x2, 0x0), 0x0) - check(div(0x2, 0x1), 0x2) - check(div(0x2, 0x2), 0x1) - check(div(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(div(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(div(0x2, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) - check(div(0x2, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x0) - check(div(0x2, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) - check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x2) - check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x3) - check(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x1) - check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x2) - check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x3) - check(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x1) - check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x0), 0x0) - check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x1), 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629) - check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x2), 0x2d65c95bfa430883b5d982e4abaef484c97ce7141ba0bfc76e65fc591f542b14) - check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x1) - check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x1) - check(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) - check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x0), 0x0) - check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x1), 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765) - check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x2), 0x28b52e8dc6c55df2aad8686e2ae031899ab24eb525514acf34b0ad89679d93b2) - check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) - check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x1) - check(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) - check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x0), 0x0) - check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x1), 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9) - check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x2), 0x7f7fef2ec891ae92afc5e7a659b3dd36646809a80cfbdb4bb30c8dfb5554d674) - check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x2) - check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x3) - check(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x1) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(div(0x0, 0x0), 0x0) + checkEq(div(0x0, 0x1), 0x0) + checkEq(div(0x0, 0x2), 0x0) + checkEq(div(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(div(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(div(0x0, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) + checkEq(div(0x0, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x0) + checkEq(div(0x0, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) + checkEq(div(0x1, 0x0), 0x0) + checkEq(div(0x1, 0x1), 0x1) + checkEq(div(0x1, 0x2), 0x0) + checkEq(div(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(div(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(div(0x1, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) + checkEq(div(0x1, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x0) + checkEq(div(0x1, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) + checkEq(div(0x2, 0x0), 0x0) + checkEq(div(0x2, 0x1), 0x2) + checkEq(div(0x2, 0x2), 0x1) + checkEq(div(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(div(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(div(0x2, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) + checkEq(div(0x2, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x0) + checkEq(div(0x2, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) + checkEq(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x2) + checkEq(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x3) + checkEq(div(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x1) + checkEq(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x2) + checkEq(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x3) + checkEq(div(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x1) + checkEq(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x0), 0x0) + checkEq(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x1), 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629) + checkEq(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x2), 0x2d65c95bfa430883b5d982e4abaef484c97ce7141ba0bfc76e65fc591f542b14) + checkEq(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x1) + checkEq(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x1) + checkEq(div(0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) + checkEq(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x0), 0x0) + checkEq(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x1), 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765) + checkEq(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x2), 0x28b52e8dc6c55df2aad8686e2ae031899ab24eb525514acf34b0ad89679d93b2) + checkEq(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x0) + checkEq(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x1) + checkEq(div(0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x0) + checkEq(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x0), 0x0) + checkEq(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x1), 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9) + checkEq(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x2), 0x7f7fef2ec891ae92afc5e7a659b3dd36646809a80cfbdb4bb30c8dfb5554d674) + checkEq(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x5acb92b7f48611076bb305c9575de90992f9ce2837417f8edccbf8b23ea85629), 0x2) + checkEq(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0x516a5d1b8d8abbe555b0d0dc55c0631335649d6a4aa2959e69615b12cf3b2765), 0x3) + checkEq(div(0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9, 0xfeffde5d91235d255f8bcf4cb367ba6cc8d0135019f7b69766191bf6aaa9ace9), 0x1) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul index dc7e7bcc5f55..c7e953ba73e9 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/eq.yul @@ -1,72 +1,216 @@ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res + +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ { + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(eq(0x0, 0x0), 0x1) - check(eq(0x0, 0x1), 0x0) - check(eq(0x0, 0x2), 0x0) - check(eq(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(eq(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(eq(0x0, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) - check(eq(0x0, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) - check(eq(0x0, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) - check(eq(0x1, 0x0), 0x0) - check(eq(0x1, 0x1), 0x1) - check(eq(0x1, 0x2), 0x0) - check(eq(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(eq(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(eq(0x1, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) - check(eq(0x1, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) - check(eq(0x1, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) - check(eq(0x2, 0x0), 0x0) - check(eq(0x2, 0x1), 0x0) - check(eq(0x2, 0x2), 0x1) - check(eq(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(eq(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(eq(0x2, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) - check(eq(0x2, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) - check(eq(0x2, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) - check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) - check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) - check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) - check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) - check(eq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) - check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) - check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) - check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) - check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) - check(eq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) - check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0x0), 0x0) - check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0x1), 0x0) - check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0x2), 0x0) - check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x1) - check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) - check(eq(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) - check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0x0), 0x0) - check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0x1), 0x0) - check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0x2), 0x0) - check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) - check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x1) - check(eq(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) - check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0x0), 0x0) - check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0x1), 0x0) - check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0x2), 0x0) - check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) - check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) - check(eq(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258, 0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x1) + checkEq(0x0, 0x0) + checkNe(0x0, 0x1) + checkNe(0x0, 0x2) + checkNe(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkNe(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkNe(0x0, 0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f) + checkNe(0x0, 0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc) + checkNe(0x0, 0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8) + checkNe(0x1, 0x0) + checkEq(0x1, 0x1) + checkNe(0x1, 0x2) + checkNe(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkNe(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkNe(0x1, 0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f) + checkNe(0x1, 0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc) + checkNe(0x1, 0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8) + checkNe(0x2, 0x0) + checkNe(0x2, 0x1) + checkEq(0x2, 0x2) + checkNe(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkNe(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkNe(0x2, 0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f) + checkNe(0x2, 0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc) + checkNe(0x2, 0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8) + checkNe(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0) + checkNe(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1) + checkNe(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2) + checkEq(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkNe(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkNe(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f) + checkNe(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc) + checkNe(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8) + checkNe(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0) + checkNe(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1) + checkNe(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2) + checkNe(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkNe(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f) + checkNe(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc) + checkNe(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8) + checkNe(0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f, 0x0) + checkNe(0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f, 0x1) + checkNe(0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f, 0x2) + checkNe(0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkNe(0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f, 0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f) + checkNe(0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f, 0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc) + checkNe(0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f, 0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8) + checkNe(0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc, 0x0) + checkNe(0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc, 0x1) + checkNe(0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc, 0x2) + checkNe(0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkNe(0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkNe(0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc, 0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f) + checkEq(0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc, 0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc) + checkNe(0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc, 0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8) + checkNe(0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8, 0x0) + checkNe(0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8, 0x1) + checkNe(0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8, 0x2) + checkNe(0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkNe(0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkNe(0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8, 0x4f7218eddecb8254db4b4e76f7edcda856a8326b856ead7a1a85e549ff5db77f) + checkNe(0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8, 0x5dd7522ae5df15f9664b2dc63a6ca004b7cef39e265256dc9e91781271dd91cc) + checkEq(0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8, 0xfad9354730603f623a4b629845d8cb8017b2556d5da0eda73e6533a1143468c8) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul index a492c6c5c636..3288d2e296d6 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/exp.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(exp(0x0, 0x0), 0x1) - check(exp(0x0, 0x1), 0x0) - check(exp(0x0, 0x2), 0x0) - check(exp(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(exp(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(exp(0x0, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) - check(exp(0x0, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) - check(exp(0x0, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) - check(exp(0x1, 0x0), 0x1) - check(exp(0x1, 0x1), 0x1) - check(exp(0x1, 0x2), 0x1) - check(exp(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(exp(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(exp(0x1, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x1) - check(exp(0x1, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x1) - check(exp(0x1, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x1) - check(exp(0x2, 0x0), 0x1) - check(exp(0x2, 0x1), 0x2) - check(exp(0x2, 0x2), 0x4) - check(exp(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(exp(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(exp(0x2, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) - check(exp(0x2, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) - check(exp(0x2, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) - check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x1) - check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) - check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x1) - check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x1) - check(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x1) - check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x4) - check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) - check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) - check(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) - check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x0), 0x1) - check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x1), 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a) - check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x2), 0xb17aeaa2a9c8f5f1d46aa1515d5f3e230f509fe7ca6ba039c0fbd6be278690a4) - check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) - check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) - check(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) - check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x0), 0x1) - check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x1), 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc) - check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x2), 0xdf116dc43f6b4886976bf644b66644ab5cad4ed96cb72a36bc0486d46be8c210) - check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) - check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) - check(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) - check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x0), 0x1) - check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x1), 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693) - check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x2), 0x669ad199e78968258dc1ae2be39498fa8658b5dc6a931db517a3255a0fabd869) - check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x6b794c2d72683939f9b9e84d6b481559bde3d5c30350d1411657dbe7df2b179b) - check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xf0208681cb5ff5bf36ad1452abc978c11b97dfb52228b3e6ec0de61afa3f37d9) - check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x8f8682f8609105950657f517a2f2c8c36a009c7e8d8d1d26f7333c24d3061ec9) - check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x7f34de7e2347950ac013638f82b3943c35e8a7950b6fe59a29d5f12c839f44f1) - check(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x78a7112f259370251244c8bc2d31c0666e71009f1fc5bb97852fd11f93eb310b) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(exp(0x0, 0x0), 0x1) + checkEq(exp(0x0, 0x1), 0x0) + checkEq(exp(0x0, 0x2), 0x0) + checkEq(exp(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(exp(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(exp(0x0, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) + checkEq(exp(0x0, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) + checkEq(exp(0x0, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) + checkEq(exp(0x1, 0x0), 0x1) + checkEq(exp(0x1, 0x1), 0x1) + checkEq(exp(0x1, 0x2), 0x1) + checkEq(exp(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(exp(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(exp(0x1, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x1) + checkEq(exp(0x1, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x1) + checkEq(exp(0x1, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x1) + checkEq(exp(0x2, 0x0), 0x1) + checkEq(exp(0x2, 0x1), 0x2) + checkEq(exp(0x2, 0x2), 0x4) + checkEq(exp(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(exp(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(exp(0x2, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) + checkEq(exp(0x2, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) + checkEq(exp(0x2, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) + checkEq(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x1) + checkEq(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) + checkEq(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x1) + checkEq(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x1) + checkEq(exp(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x1) + checkEq(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x4) + checkEq(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) + checkEq(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) + checkEq(exp(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) + checkEq(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x0), 0x1) + checkEq(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x1), 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a) + checkEq(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x2), 0xb17aeaa2a9c8f5f1d46aa1515d5f3e230f509fe7ca6ba039c0fbd6be278690a4) + checkEq(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) + checkEq(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) + checkEq(exp(0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) + checkEq(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x0), 0x1) + checkEq(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x1), 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc) + checkEq(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x2), 0xdf116dc43f6b4886976bf644b66644ab5cad4ed96cb72a36bc0486d46be8c210) + checkEq(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x0) + checkEq(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x0) + checkEq(exp(0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x0) + checkEq(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x0), 0x1) + checkEq(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x1), 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693) + checkEq(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x2), 0x669ad199e78968258dc1ae2be39498fa8658b5dc6a931db517a3255a0fabd869) + checkEq(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x6b794c2d72683939f9b9e84d6b481559bde3d5c30350d1411657dbe7df2b179b) + checkEq(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xf0208681cb5ff5bf36ad1452abc978c11b97dfb52228b3e6ec0de61afa3f37d9) + checkEq(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x4e79328d056b56683d768137954334511588e1ab216fd4709f3ebca8dd65019a), 0x8f8682f8609105950657f517a2f2c8c36a009c7e8d8d1d26f7333c24d3061ec9) + checkEq(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x9660c1b5529940890a08f75090686376a43a659478af54ad84036a2b1742c9bc), 0x7f34de7e2347950ac013638f82b3943c35e8a7950b6fe59a29d5f12c839f44f1) + checkEq(exp(0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693, 0x1d4fcee76bd41d8000746c1c28cb2eadcbf4dfc7f1fedb0a69cb220fbe207693), 0x78a7112f259370251244c8bc2d31c0666e71009f1fc5bb97852fd11f93eb310b) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul index 1da16455a860..a3de92ecdc9e 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/gt.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(gt(0x0, 0x0), 0x0) - check(gt(0x0, 0x1), 0x0) - check(gt(0x0, 0x2), 0x0) - check(gt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(gt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(gt(0x0, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) - check(gt(0x0, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) - check(gt(0x0, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) - check(gt(0x1, 0x0), 0x1) - check(gt(0x1, 0x1), 0x0) - check(gt(0x1, 0x2), 0x0) - check(gt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(gt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(gt(0x1, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) - check(gt(0x1, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) - check(gt(0x1, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) - check(gt(0x2, 0x0), 0x1) - check(gt(0x2, 0x1), 0x1) - check(gt(0x2, 0x2), 0x0) - check(gt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(gt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(gt(0x2, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) - check(gt(0x2, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) - check(gt(0x2, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) - check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x1) - check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) - check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) - check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x1) - check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x1) - check(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) - check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x1) - check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x1) - check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x1) - check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x1) - check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x1) - check(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) - check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x0), 0x1) - check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x1), 0x1) - check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x2), 0x1) - check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) - check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) - check(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) - check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x0), 0x1) - check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x1), 0x1) - check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x2), 0x1) - check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x1) - check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) - check(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) - check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x0), 0x1) - check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x1), 0x1) - check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x2), 0x1) - check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) - check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) - check(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(gt(0x0, 0x0), 0x0) + checkEq(gt(0x0, 0x1), 0x0) + checkEq(gt(0x0, 0x2), 0x0) + checkEq(gt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(gt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(gt(0x0, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) + checkEq(gt(0x0, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + checkEq(gt(0x0, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) + checkEq(gt(0x1, 0x0), 0x1) + checkEq(gt(0x1, 0x1), 0x0) + checkEq(gt(0x1, 0x2), 0x0) + checkEq(gt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(gt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(gt(0x1, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) + checkEq(gt(0x1, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + checkEq(gt(0x1, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) + checkEq(gt(0x2, 0x0), 0x1) + checkEq(gt(0x2, 0x1), 0x1) + checkEq(gt(0x2, 0x2), 0x0) + checkEq(gt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(gt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(gt(0x2, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) + checkEq(gt(0x2, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + checkEq(gt(0x2, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) + checkEq(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x1) + checkEq(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) + checkEq(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) + checkEq(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x1) + checkEq(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x1) + checkEq(gt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) + checkEq(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x1) + checkEq(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x1) + checkEq(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x1) + checkEq(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x1) + checkEq(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x1) + checkEq(gt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) + checkEq(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x0), 0x1) + checkEq(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x1), 0x1) + checkEq(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x2), 0x1) + checkEq(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) + checkEq(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + checkEq(gt(0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) + checkEq(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x0), 0x1) + checkEq(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x1), 0x1) + checkEq(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x2), 0x1) + checkEq(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x1) + checkEq(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + checkEq(gt(0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x1) + checkEq(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x0), 0x1) + checkEq(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x1), 0x1) + checkEq(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x2), 0x1) + checkEq(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x669fa82c2a1943c7444d775b04a3cb87af6eae8e06150438f3b1c5c6db8ba6a4), 0x0) + checkEq(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x7ded92de25172b3ad3c114eb1c8d4a195a9ef32570710d93c182726e5bc76c94), 0x0) + checkEq(gt(0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb, 0x5bd730f3009bdcfe88996a42a2540782725d483b430e9ad5eab0ecd721a3b2bb), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul index 4dd535dd9003..a201a241a49e 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/iszero.yul @@ -1,19 +1,160 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(iszero(0x0), 0x1) - check(iszero(0x1), 0x0) - check(iszero(0x2), 0x0) - check(iszero(0x3), 0x0) - check(iszero(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(iszero(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(iszero(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd), 0x0) - check(iszero(0xdc91451b4d11884662ecce3baf532f24813b65c6e9ff858cb3269bf73ce701a9), 0x0) - check(iszero(0x5a1caa33a14b8f9c03f754609a5eef3932e3c82f2632fb74bb1dc3f5ea044701), 0x0) - check(iszero(0xfe8be50fa47cacbcb36d160b4116bdaef12e1b99ce9ec6d4df90d398aecb34be), 0x0) - check(iszero(0x77652457195e8499212c1a3b87ff6d112cfb377bf4b33eec9f9d7ea95c763b6d), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(iszero(0x0), 0x1) + checkEq(iszero(0x1), 0x0) + checkEq(iszero(0x2), 0x0) + checkEq(iszero(0x3), 0x0) + checkEq(iszero(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(iszero(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(iszero(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd), 0x0) + checkEq(iszero(0xa9e614c47e6777a0de9ccd00457cc20a5810dc64c0f499184a38466d61dca890), 0x0) + checkEq(iszero(0x8c6ccdffb1381f9138dcd4556cf958ee8631c9e70503f72a353cec34455e0f40), 0x0) + checkEq(iszero(0x3f6a583db5987fc749490dfe2d871942995e19867b15d9841aff774e5268d258), 0x0) + checkEq(iszero(0xdc91451b4d11884662ecce3baf532f24813b65c6e9ff858cb3269bf73ce701a9), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul index 3427690e5f75..1d78a507641e 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/lt.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(lt(0x0, 0x0), 0x0) - check(lt(0x0, 0x1), 0x1) - check(lt(0x0, 0x2), 0x1) - check(lt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(lt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(lt(0x0, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) - check(lt(0x0, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x1) - check(lt(0x0, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) - check(lt(0x1, 0x0), 0x0) - check(lt(0x1, 0x1), 0x0) - check(lt(0x1, 0x2), 0x1) - check(lt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(lt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(lt(0x1, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) - check(lt(0x1, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x1) - check(lt(0x1, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) - check(lt(0x2, 0x0), 0x0) - check(lt(0x2, 0x1), 0x0) - check(lt(0x2, 0x2), 0x0) - check(lt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(lt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(lt(0x2, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) - check(lt(0x2, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x1) - check(lt(0x2, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) - check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) - check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) - check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x0) - check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) - check(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) - check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) - check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) - check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x0) - check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) - check(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) - check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x0), 0x0) - check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x1), 0x0) - check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x2), 0x0) - check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x0) - check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) - check(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) - check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x0), 0x0) - check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x1), 0x0) - check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x2), 0x0) - check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) - check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) - check(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) - check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x0), 0x0) - check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x1), 0x0) - check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x2), 0x0) - check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) - check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) - check(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(lt(0x0, 0x0), 0x0) + checkEq(lt(0x0, 0x1), 0x1) + checkEq(lt(0x0, 0x2), 0x1) + checkEq(lt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(lt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(lt(0x0, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) + checkEq(lt(0x0, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x1) + checkEq(lt(0x0, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) + checkEq(lt(0x1, 0x0), 0x0) + checkEq(lt(0x1, 0x1), 0x0) + checkEq(lt(0x1, 0x2), 0x1) + checkEq(lt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(lt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(lt(0x1, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) + checkEq(lt(0x1, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x1) + checkEq(lt(0x1, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) + checkEq(lt(0x2, 0x0), 0x0) + checkEq(lt(0x2, 0x1), 0x0) + checkEq(lt(0x2, 0x2), 0x0) + checkEq(lt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(lt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(lt(0x2, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) + checkEq(lt(0x2, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x1) + checkEq(lt(0x2, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) + checkEq(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + checkEq(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + checkEq(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x0) + checkEq(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) + checkEq(lt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) + checkEq(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + checkEq(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + checkEq(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x0) + checkEq(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) + checkEq(lt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) + checkEq(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x0), 0x0) + checkEq(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x1), 0x0) + checkEq(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x2), 0x0) + checkEq(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x0) + checkEq(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) + checkEq(lt(0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) + checkEq(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x0), 0x0) + checkEq(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x1), 0x0) + checkEq(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x2), 0x0) + checkEq(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) + checkEq(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) + checkEq(lt(0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x1) + checkEq(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x0), 0x0) + checkEq(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x1), 0x0) + checkEq(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x2), 0x0) + checkEq(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0xae19640f021de5090eeadd850aeeae859a06c5d88963f273287de022ca85d145), 0x1) + checkEq(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x152157ed731b1ce9eb9bc7be7ab3990a6a35c553715200196b0c17c558ed0658), 0x0) + checkEq(lt(0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b, 0x2a8f6ec8110a734f8851187a986caa2020da16c031e270b19d0de0edbacacb3b), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul index 2a912548a1a0..b3ed3a05128e 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mod.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(mod(0x0, 0x0), 0x0) - check(mod(0x0, 0x1), 0x0) - check(mod(0x0, 0x2), 0x0) - check(mod(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(mod(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(mod(0x0, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x0) - check(mod(0x0, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x0) - check(mod(0x0, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x0) - check(mod(0x1, 0x0), 0x0) - check(mod(0x1, 0x1), 0x0) - check(mod(0x1, 0x2), 0x1) - check(mod(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(mod(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(mod(0x1, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x1) - check(mod(0x1, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x1) - check(mod(0x1, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x1) - check(mod(0x2, 0x0), 0x0) - check(mod(0x2, 0x1), 0x0) - check(mod(0x2, 0x2), 0x0) - check(mod(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) - check(mod(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) - check(mod(0x2, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x2) - check(mod(0x2, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x2) - check(mod(0x2, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x2) - check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) - check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) - check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x3bf102f6117471a23f1fd0f25e36c48659661437efe1d3792957359d9ade119) - check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x732b22cd113ddfb8d9052370a100ab70cf1fa5bd01890b58d6bf2227eeaf12d) - check(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x795dbec8994a98a257d2e5526a6147d04e8ba050dbab7e31f323d2e59481e88) - check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) - check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) - check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x3bf102f6117471a23f1fd0f25e36c48659661437efe1d3792957359d9ade118) - check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x732b22cd113ddfb8d9052370a100ab70cf1fa5bd01890b58d6bf2227eeaf12c) - check(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x795dbec8994a98a257d2e5526a6147d04e8ba050dbab7e31f323d2e59481e87) - check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x0), 0x0) - check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x1), 0x0) - check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x2), 0x1) - check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1) - check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1) - check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x0) - check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x2c1fc3e0e95b6a35cb650d70202cdf5e3a39990b89aa63098d8b271fafce35f) - check(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1) - check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x0), 0x0) - check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x1), 0x0) - check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x2), 0x0) - check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) - check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) - check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) - check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x0) - check(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) - check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x0), 0x0) - check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x1), 0x0) - check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x2), 0x1) - check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d) - check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d) - check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x28c33963b7a7a8aba4294566241935e264a0d2343b41723d8e08297f8684f0ac) - check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x43c5f3d0fac4c76b8e8e696ae6f63da3cd66ae0ec4bc37d5827cc47cb710799) - check(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(mod(0x0, 0x0), 0x0) + checkEq(mod(0x0, 0x1), 0x0) + checkEq(mod(0x0, 0x2), 0x0) + checkEq(mod(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(mod(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(mod(0x0, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x0) + checkEq(mod(0x0, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x0) + checkEq(mod(0x0, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x0) + checkEq(mod(0x1, 0x0), 0x0) + checkEq(mod(0x1, 0x1), 0x0) + checkEq(mod(0x1, 0x2), 0x1) + checkEq(mod(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(mod(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(mod(0x1, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x1) + checkEq(mod(0x1, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x1) + checkEq(mod(0x1, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x1) + checkEq(mod(0x2, 0x0), 0x0) + checkEq(mod(0x2, 0x1), 0x0) + checkEq(mod(0x2, 0x2), 0x0) + checkEq(mod(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) + checkEq(mod(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) + checkEq(mod(0x2, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x2) + checkEq(mod(0x2, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x2) + checkEq(mod(0x2, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x2) + checkEq(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + checkEq(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) + checkEq(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x3bf102f6117471a23f1fd0f25e36c48659661437efe1d3792957359d9ade119) + checkEq(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x732b22cd113ddfb8d9052370a100ab70cf1fa5bd01890b58d6bf2227eeaf12d) + checkEq(mod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x795dbec8994a98a257d2e5526a6147d04e8ba050dbab7e31f323d2e59481e88) + checkEq(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + checkEq(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + checkEq(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x3bf102f6117471a23f1fd0f25e36c48659661437efe1d3792957359d9ade118) + checkEq(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x732b22cd113ddfb8d9052370a100ab70cf1fa5bd01890b58d6bf2227eeaf12c) + checkEq(mod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x795dbec8994a98a257d2e5526a6147d04e8ba050dbab7e31f323d2e59481e87) + checkEq(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x0), 0x0) + checkEq(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x1), 0x0) + checkEq(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x2), 0x1) + checkEq(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1) + checkEq(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1) + checkEq(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x0) + checkEq(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x2c1fc3e0e95b6a35cb650d70202cdf5e3a39990b89aa63098d8b271fafce35f) + checkEq(mod(0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1) + checkEq(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x0), 0x0) + checkEq(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x1), 0x0) + checkEq(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x2), 0x0) + checkEq(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) + checkEq(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) + checkEq(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) + checkEq(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x0) + checkEq(mod(0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426) + checkEq(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x0), 0x0) + checkEq(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x1), 0x0) + checkEq(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x2), 0x1) + checkEq(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d) + checkEq(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d) + checkEq(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x2a0ad2a2c526c97ba4ad007d79af6df3ef119a74c02afb216791c21bb10dafd1), 0x28c33963b7a7a8aba4294566241935e264a0d2343b41723d8e08297f8684f0ac) + checkEq(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0xd184776e785b0f2c2a78fe227e43554ae7a004c028571a59a3dafe33cb04426), 0x43c5f3d0fac4c76b8e8e696ae6f63da3cd66ae0ec4bc37d5827cc47cb710799) + checkEq(mod(0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d, 0x52ce0c067cce722748d645e39dc8a3d653b26ca8fb6c6d5ef599eb9b3792a07d), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul index 2bb51c2bcdfa..7f06de1c57c0 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mul.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(mul(0x0, 0x0), 0x0) - check(mul(0x0, 0x1), 0x0) - check(mul(0x0, 0x2), 0x0) - check(mul(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(mul(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(mul(0x0, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x0) - check(mul(0x0, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x0) - check(mul(0x0, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x0) - check(mul(0x1, 0x0), 0x0) - check(mul(0x1, 0x1), 0x1) - check(mul(0x1, 0x2), 0x2) - check(mul(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(mul(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(mul(0x1, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a) - check(mul(0x1, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4) - check(mul(0x1, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16) - check(mul(0x2, 0x0), 0x0) - check(mul(0x2, 0x1), 0x2) - check(mul(0x2, 0x2), 0x4) - check(mul(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(mul(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) - check(mul(0x2, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0xb20876cdcf7b2d6bc6d0eece4ef9f8030aade0af57846dea12e23725d4e106f4) - check(mul(0x2, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x328d50f6f6022108b3ca926e011be58e75a8bf8ad9e39ea26d94a99fec577d68) - check(mul(0x2, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x6bc1f5f0b1d04e000899c7ae9f19a91c2b747c79e74ce5fedd36b8b2466db62c) - check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) - check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x26fbc4991842694a1c978898d88303fe7aa90fa8543dc90af68ee46d158f7c86) - check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x66b9578484feef7ba61ab6c8ff720d38c52ba03a930e30aec935ab3009d4414c) - check(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0xca1f0507a717d8fffbb31c28b0732b71ea45c1c30c598d009164a3a6dcc924ea) - check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) - check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) - check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4) - check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x4df789323084d294392f1131b10607fcf5521f50a87b9215ed1dc8da2b1ef90c) - check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0xcd72af0909fddef74c356d91fee41a718a574075261c615d926b566013a88298) - check(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x943e0a0f4e2fb1fff766385160e656e3d48b838618b31a0122c9474db99249d4) - check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x0), 0x0) - check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x1), 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a) - check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x2), 0xb20876cdcf7b2d6bc6d0eece4ef9f8030aade0af57846dea12e23725d4e106f4) - check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x26fbc4991842694a1c978898d88303fe7aa90fa8543dc90af68ee46d158f7c86) - check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4df789323084d294392f1131b10607fcf5521f50a87b9215ed1dc8da2b1ef90c) - check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x5e212ad86e15d56a8b8dc59640978d62434da71e22e251daa07794f656461624) - check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x72b7563189e6fb81a6e0c7e6ac6ae5cf9f65d32c803940a15b56442faa2efdc8) - check(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x2c78a699a972d189ec393219bb4f65066d56fdf47055c43b7095704dcfe0aa7c) - check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x0), 0x0) - check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x1), 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4) - check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x2), 0x328d50f6f6022108b3ca926e011be58e75a8bf8ad9e39ea26d94a99fec577d68) - check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x66b9578484feef7ba61ab6c8ff720d38c52ba03a930e30aec935ab3009d4414c) - check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xcd72af0909fddef74c356d91fee41a718a574075261c615d926b566013a88298) - check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x72b7563189e6fb81a6e0c7e6ac6ae5cf9f65d32c803940a15b56442faa2efdc8) - check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x55fa1bc0326d6284b14f80cb3633885cd52b77b32521d9e1a0aca1138e87ae90) - check(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0xaaaa01c250e883022bf70da9614aa53fd00e10bbbc7bb19e3b31165769de5f78) - check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x0), 0x0) - check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x1), 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16) - check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x2), 0x6bc1f5f0b1d04e000899c7ae9f19a91c2b747c79e74ce5fedd36b8b2466db62c) - check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xca1f0507a717d8fffbb31c28b0732b71ea45c1c30c598d009164a3a6dcc924ea) - check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x943e0a0f4e2fb1fff766385160e656e3d48b838618b31a0122c9474db99249d4) - check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x2c78a699a972d189ec393219bb4f65066d56fdf47055c43b7095704dcfe0aa7c) - check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0xaaaa01c250e883022bf70da9614aa53fd00e10bbbc7bb19e3b31165769de5f78) - check(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0xd9d221a1c3d2f657ff36ba234d8aff13efcc67f6767406e1231830f52cc6a5e4) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(mul(0x0, 0x0), 0x0) + checkEq(mul(0x0, 0x1), 0x0) + checkEq(mul(0x0, 0x2), 0x0) + checkEq(mul(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(mul(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(mul(0x0, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x0) + checkEq(mul(0x0, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x0) + checkEq(mul(0x0, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x0) + checkEq(mul(0x1, 0x0), 0x0) + checkEq(mul(0x1, 0x1), 0x1) + checkEq(mul(0x1, 0x2), 0x2) + checkEq(mul(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(mul(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(mul(0x1, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a) + checkEq(mul(0x1, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4) + checkEq(mul(0x1, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16) + checkEq(mul(0x2, 0x0), 0x0) + checkEq(mul(0x2, 0x1), 0x2) + checkEq(mul(0x2, 0x2), 0x4) + checkEq(mul(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(mul(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + checkEq(mul(0x2, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0xb20876cdcf7b2d6bc6d0eece4ef9f8030aade0af57846dea12e23725d4e106f4) + checkEq(mul(0x2, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x328d50f6f6022108b3ca926e011be58e75a8bf8ad9e39ea26d94a99fec577d68) + checkEq(mul(0x2, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x6bc1f5f0b1d04e000899c7ae9f19a91c2b747c79e74ce5fedd36b8b2466db62c) + checkEq(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) + checkEq(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x26fbc4991842694a1c978898d88303fe7aa90fa8543dc90af68ee46d158f7c86) + checkEq(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x66b9578484feef7ba61ab6c8ff720d38c52ba03a930e30aec935ab3009d4414c) + checkEq(mul(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0xca1f0507a717d8fffbb31c28b0732b71ea45c1c30c598d009164a3a6dcc924ea) + checkEq(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + checkEq(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) + checkEq(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4) + checkEq(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x4df789323084d294392f1131b10607fcf5521f50a87b9215ed1dc8da2b1ef90c) + checkEq(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0xcd72af0909fddef74c356d91fee41a718a574075261c615d926b566013a88298) + checkEq(mul(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x943e0a0f4e2fb1fff766385160e656e3d48b838618b31a0122c9474db99249d4) + checkEq(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x0), 0x0) + checkEq(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x1), 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a) + checkEq(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x2), 0xb20876cdcf7b2d6bc6d0eece4ef9f8030aade0af57846dea12e23725d4e106f4) + checkEq(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x26fbc4991842694a1c978898d88303fe7aa90fa8543dc90af68ee46d158f7c86) + checkEq(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4df789323084d294392f1131b10607fcf5521f50a87b9215ed1dc8da2b1ef90c) + checkEq(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x5e212ad86e15d56a8b8dc59640978d62434da71e22e251daa07794f656461624) + checkEq(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x72b7563189e6fb81a6e0c7e6ac6ae5cf9f65d32c803940a15b56442faa2efdc8) + checkEq(mul(0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0x2c78a699a972d189ec393219bb4f65066d56fdf47055c43b7095704dcfe0aa7c) + checkEq(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x0), 0x0) + checkEq(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x1), 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4) + checkEq(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x2), 0x328d50f6f6022108b3ca926e011be58e75a8bf8ad9e39ea26d94a99fec577d68) + checkEq(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x66b9578484feef7ba61ab6c8ff720d38c52ba03a930e30aec935ab3009d4414c) + checkEq(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xcd72af0909fddef74c356d91fee41a718a574075261c615d926b566013a88298) + checkEq(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x72b7563189e6fb81a6e0c7e6ac6ae5cf9f65d32c803940a15b56442faa2efdc8) + checkEq(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0x55fa1bc0326d6284b14f80cb3633885cd52b77b32521d9e1a0aca1138e87ae90) + checkEq(mul(0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0xaaaa01c250e883022bf70da9614aa53fd00e10bbbc7bb19e3b31165769de5f78) + checkEq(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x0), 0x0) + checkEq(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x1), 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16) + checkEq(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x2), 0x6bc1f5f0b1d04e000899c7ae9f19a91c2b747c79e74ce5fedd36b8b2466db62c) + checkEq(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xca1f0507a717d8fffbb31c28b0732b71ea45c1c30c598d009164a3a6dcc924ea) + checkEq(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x943e0a0f4e2fb1fff766385160e656e3d48b838618b31a0122c9474db99249d4) + checkEq(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0xd9043b66e7bd96b5e3687767277cfc018556f057abc236f509711b92ea70837a), 0x2c78a699a972d189ec393219bb4f65066d56fdf47055c43b7095704dcfe0aa7c) + checkEq(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x9946a87b7b01108459e54937008df2c73ad45fc56cf1cf5136ca54cff62bbeb4), 0xaaaa01c250e883022bf70da9614aa53fd00e10bbbc7bb19e3b31165769de5f78) + checkEq(mul(0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16, 0x35e0faf858e82700044ce3d74f8cd48e15ba3e3cf3a672ff6e9b5c592336db16), 0xd9d221a1c3d2f657ff36ba234d8aff13efcc67f6767406e1231830f52cc6a5e4) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul index d5887ae81993..7736bcc276d5 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/mulmod.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x168054808d0b4226e2f7d20f66d64728fd7734583dd36b66d7966a085cbcfda0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x14fc3916121454e5ab8985b6c8045fd2a9c752dc8d0cd64706cfc963b8627024) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x53239a8c18c5fa9453f5afe8c7ecf59e5b7dbb4a7aa4c2f9edd7dd4838eeb0de) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x424eb1213861699d29b2da1027f6aea380d49af89b36be4d470a68b72e34cc2c) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0, 0x0), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x53239a8c18c5fa9453f5afe8c7ecf59e5b7dbb4a7aa4c2f9edd7dd4838eeb0de) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x521eb72d6d9a85f5f224d67f52fd342fd66eebe8fe610d679833992645442e8) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x4cf32ce1ebb97062a7f1962bbb5a94a4509467560ad9267ba07dfd126496b44d) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0xedca0f5f035e9b37e93b80abedf46b7ef6c3083be21e6fd53a25f57a0e040384) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0, 0x0), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x424eb1213861699d29b2da1027f6aea380d49af89b36be4d470a68b72e34cc2c) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0xedca0f5f035e9b37e93b80abedf46b7ef6c3083be21e6fd53a25f57a0e040384) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x434c7978cc53f57ae0e7c10a07575970cdc89ca7874438066521ef135520988d) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x2180c8bb61f74bb31ea694c77ab5b96436c5bf60c350cb227f0f4e194e678d31) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0, 0x0), 0x0) - check(mulmod(0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac, 0x0), 0x0) - check(mulmod(0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118, 0x0), 0x0) - check(mulmod(0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9, 0x0), 0x0) - check(mulmod(0x0, 0x0, 0xf85d65623840a7b39dd45dac05a309059516f59b8a046e896e1a0ed8e4724cac), 0x0) - check(mulmod(0x0, 0x0, 0x4d0e09c4149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118), 0x0) - check(mulmod(0x0, 0x0, 0x58ec5eb8c27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb9), 0x0) - check(mulmod(0x0, 0x0, 0x0), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0xc076c544b658b9d6433b79099ab9c4c7976555fdec509370b531aa7e28aeddcf) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x12756ffcb72a0531763804b77c2da3fe0e3b14730ad1afae666f4f2b869d629) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x0), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x70b529595cd9a1b371790b5c7beacc40b501d82593a2190546eb66ce891015a) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x0), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x3b3d831ad300110bf8379e6722d718a5ba80ab4afc07d13b032b210e6afcac45) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x0), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x0, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x0, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x0, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x0, 0x0), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x70b529595cd9a1b371790b5c7beacc40b501d82593a2190546eb66ce891015a) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x0), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x10bb2b36f81271b8cb131c23524e86ba668d4c82d4ee6ef2c68fd0e096d26e09) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0xcbe26ab4785bd7f90f7d61625b3b6e743a80f512e6052ca8e637cfdf517530) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x0), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x9fcfbcf2c672d5e341133c2e4e5c35997c85db652854dda117de560ba058659) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x0), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x0, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x0, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x0, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x0, 0x0), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x3b3d831ad300110bf8379e6722d718a5ba80ab4afc07d13b032b210e6afcac45) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x0), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x9fcfbcf2c672d5e341133c2e4e5c35997c85db652854dda117de560ba058659) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x0), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x369336d99c45a673f35d496d007849c4402bce437c8086a327910a164256f41) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x8088cc58bec941a7296a95574cf1226bba8ace6e98e83077cbc0e407f2172708) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x0), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x0, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x0, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x0, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x0, 0x0), 0x0) + checkEq(mulmod(0x0, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0x0, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0x0, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0x0, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824, 0x0), 0x0) + checkEq(mulmod(0x0, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0x0, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0x0, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0x0, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29, 0x0), 0x0) + checkEq(mulmod(0x0, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0x0, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0x0, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0x0, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9, 0x0), 0x0) + checkEq(mulmod(0x0, 0x0, 0x149b1d571568ae031cb636085e0b262218434cb40a6b1a0645e34118b6318824), 0x0) + checkEq(mulmod(0x0, 0x0, 0xc27553129f2f5e3d6fda36b027315d930e590b0d3a74a7a11cd03cb98a695d29), 0x0) + checkEq(mulmod(0x0, 0x0, 0xe561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4efd9c6b9), 0x0) + checkEq(mulmod(0x0, 0x0, 0x0), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul index 71caf36036cb..e151d1723e62 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/not.yul @@ -1,19 +1,160 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(not(0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(not(0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(not(0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) - check(not(0x3), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) - check(not(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(not(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(not(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd), 0x2) - check(not(0xb9caa39ea86683d4e096bd6edd32ae3ead3c1b3a5c0c9ff6aaf9f46e9859aa7e), 0x46355c6157997c2b1f69429122cd51c152c3e4c5a3f3600955060b9167a65581) - check(not(0xe4fe151407cfb034d8ec5ae737b2fb264e0b4084b976fa07648d31ec1b1bedcb), 0x1b01eaebf8304fcb2713a518c84d04d9b1f4bf7b468905f89b72ce13e4e41234) - check(not(0xd6bfc8a63b534b270ddfd63ce081db9109bc4355465b6a40b200b01fac47eb4e), 0x29403759c4acb4d8f22029c31f7e246ef643bcaab9a495bf4dff4fe053b814b1) - check(not(0xe40000700672cffea275f0f1a48f6096ffb97924fa63024f6d5411b5a529a84d), 0x1bffff8ff98d30015d8a0f0e5b709f69004686db059cfdb092abee4a5ad657b2) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(not(0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(not(0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(not(0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + checkEq(not(0x3), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + checkEq(not(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(not(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(not(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd), 0x2) + checkEq(not(0xb9caa39ea86683d4e096bd6edd32ae3ead3c1b3a5c0c9ff6aaf9f46e9859aa7e), 0x46355c6157997c2b1f69429122cd51c152c3e4c5a3f3600955060b9167a65581) + checkEq(not(0xe4fe151407cfb034d8ec5ae737b2fb264e0b4084b976fa07648d31ec1b1bedcb), 0x1b01eaebf8304fcb2713a518c84d04d9b1f4bf7b468905f89b72ce13e4e41234) + checkEq(not(0xd6bfc8a63b534b270ddfd63ce081db9109bc4355465b6a40b200b01fac47eb4e), 0x29403759c4acb4d8f22029c31f7e246ef643bcaab9a495bf4dff4fe053b814b1) + checkEq(not(0xe40000700672cffea275f0f1a48f6096ffb97924fa63024f6d5411b5a529a84d), 0x1bffff8ff98d30015d8a0f0e5b709f69004686db059cfdb092abee4a5ad657b2) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul index a06bdde66a2d..1f5569c79d69 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/or.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(or(0x0, 0x0), 0x0) - check(or(0x0, 0x1), 0x1) - check(or(0x0, 0x2), 0x2) - check(or(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(or(0x0, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) - check(or(0x0, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) - check(or(0x0, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) - check(or(0x1, 0x0), 0x1) - check(or(0x1, 0x1), 0x1) - check(or(0x1, 0x2), 0x3) - check(or(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0x1, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) - check(or(0x1, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b53) - check(or(0x1, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cff) - check(or(0x2, 0x0), 0x2) - check(or(0x2, 0x1), 0x3) - check(or(0x2, 0x2), 0x2) - check(or(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(or(0x2, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f3) - check(or(0x2, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) - check(or(0x2, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) - check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x0), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) - check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) - check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x2), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f3) - check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) - check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0xbb5dfd12555ffe715f4e766f7ffed9fb9bfffbee9ff6bfb7f18e9ebeeffb9bf3) - check(or(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x7addff63f69ee6e55f5eedef7fdffbfef3b77fee9ff46bd5f1fe0cfccf8fdeff) - check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x0), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) - check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x1), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b53) - check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x2), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) - check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0xbb5dfd12555ffe715f4e766f7ffed9fb9bfffbee9ff6bfb7f18e9ebeeffb9bf3) - check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) - check(or(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0xf1dd7773f7df7eb54f1ebfe17fff6bb7fb7bf7ae8f76fdf7f0fe96eaef7f5ffe) - check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x0), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) - check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x1), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cff) - check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x2), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) - check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x7addff63f69ee6e55f5eedef7fdffbfef3b77fee9ff46bd5f1fe0cfccf8fdeff) - check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0xf1dd7773f7df7eb54f1ebfe17fff6bb7fb7bf7ae8f76fdf7f0fe96eaef7f5ffe) - check(or(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(or(0x0, 0x0), 0x0) + checkEq(or(0x0, 0x1), 0x1) + checkEq(or(0x0, 0x2), 0x2) + checkEq(or(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(or(0x0, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) + checkEq(or(0x0, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) + checkEq(or(0x0, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) + checkEq(or(0x1, 0x0), 0x1) + checkEq(or(0x1, 0x1), 0x1) + checkEq(or(0x1, 0x2), 0x3) + checkEq(or(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0x1, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9157) + checkEq(or(0x1, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) + checkEq(or(0x1, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) + checkEq(or(0x2, 0x0), 0x2) + checkEq(or(0x2, 0x1), 0x3) + checkEq(or(0x2, 0x2), 0x2) + checkEq(or(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(or(0x2, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) + checkEq(or(0x2, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da73) + checkEq(or(0x2, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) + checkEq(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0x0), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) + checkEq(or(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0x1), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9157) + checkEq(or(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0x2), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) + checkEq(or(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(or(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156) + checkEq(or(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xeffeddf694cfdfdf7efbb4fcedbfdfff8f7f77ff47f7ef5e6fbffaffdedfdb77) + checkEq(or(0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xebde4ea6be8ffcff7fff7efee5fd5f66cfff77fffe74ff5f5bf9feffe7ffd5ff) + checkEq(or(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0x0), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) + checkEq(or(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0x1), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) + checkEq(or(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0x2), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da73) + checkEq(or(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xeffeddf694cfdfdf7efbb4fcedbfdfff8f7f77ff47f7ef5e6fbffaffdedfdb77) + checkEq(or(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71) + checkEq(or(0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xeff69ff6aecb7bff57feeeea2df79effcffd73edffb3fd1f7ff7feff7fffdefb) + checkEq(or(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0x0), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) + checkEq(or(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0x1), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) + checkEq(or(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0x2), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) + checkEq(or(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(or(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xcb4a48869485dcdf7edb34f4e58d5f628f0766bf06640f5e49993a7dc41f9156), 0xebde4ea6be8ffcff7fff7efee5fd5f66cfff77fffe74ff5f5bf9feffe7ffd5ff) + checkEq(or(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xe7f49d7284ca13df4662a068293794dd877973e547b3ec1c2f37f8be5ec3da71), 0xeff69ff6aecb7bff57feeeea2df79effcffd73edffb3fd1f7ff7feff7fffdefb) + checkEq(or(0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb, 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb), 0xa8d60ea4aa8b78b611bc6eca24f10a66cefc3348fe10fd1f5af1f6ff23fc44bb) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul index 89821bab93dd..115febf17373 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sar.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(sar(0x0, 0x0), 0x0) - check(sar(0x0, 0x1), 0x1) - check(sar(0x0, 0x2), 0x2) - check(sar(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(sar(0x0, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb) - check(sar(0x0, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979) - check(sar(0x0, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c) - check(sar(0x1, 0x0), 0x0) - check(sar(0x1, 0x1), 0x0) - check(sar(0x1, 0x2), 0x1) - check(sar(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x1, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xe4a4b0b5ab81acc1193f45fa3d9f041e96aa99e28af4d1a9c6e6ead742ce3465) - check(sar(0x1, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x2ee4bc6eb8ef0d1c046a2da9c70e398fe0999af96de414d753adc956885e3cbc) - check(sar(0x1, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x3e08e31677e058c595c611f22023507bfa4715f195e5e0a4acdcd494f86c46ce) - check(sar(0x2, 0x0), 0x0) - check(sar(0x2, 0x1), 0x0) - check(sar(0x2, 0x2), 0x0) - check(sar(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x2, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xf252585ad5c0d6608c9fa2fd1ecf820f4b554cf1457a68d4e373756ba1671a32) - check(sar(0x2, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x17725e375c77868e023516d4e3871cc7f04ccd7cb6f20a6ba9d6e4ab442f1e5e) - check(sar(0x2, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x1f04718b3bf02c62cae308f91011a83dfd238af8caf2f052566e6a4a7c362367) - check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) - check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) - check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x0) - check(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) - check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) - check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) - check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x0) - check(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) - check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0x0), 0x0) - check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0x1), 0x0) - check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0x2), 0x0) - check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x0) - check(sar(0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) - check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0x0), 0x0) - check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0x1), 0x0) - check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0x2), 0x0) - check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x0) - check(sar(0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) - check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x0), 0x0) - check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x1), 0x0) - check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x2), 0x0) - check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0xc949616b57035982327e8bf47b3e083d2d5533c515e9a3538dcdd5ae859c68cb), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x5dc978dd71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc7979), 0x0) - check(sar(0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c, 0x7c11c62cefc0b18b2b8c23e44046a0f7f48e2be32bcbc14959b9a929f0d88d9c), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(sar(0x0, 0x0), 0x0) + checkEq(sar(0x0, 0x1), 0x1) + checkEq(sar(0x0, 0x2), 0x2) + checkEq(sar(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(sar(0x0, 0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c), 0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c) + checkEq(sar(0x0, 0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758), 0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758) + checkEq(sar(0x0, 0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913), 0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913) + checkEq(sar(0x1, 0x0), 0x0) + checkEq(sar(0x1, 0x1), 0x0) + checkEq(sar(0x1, 0x2), 0x1) + checkEq(sar(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x1, 0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c), 0x15b97d6f69214434baad8bd67bf15f6dadd8983470540b3ca5bcf275551b8a06) + checkEq(sar(0x1, 0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758), 0x10bca86d0177840526d76e1424734179948fcc171f4e8f1fe801586f28221bac) + checkEq(sar(0x1, 0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913), 0x38ef0d1c046a2da9c70e398fe0999af96de414d753adc956885e3cbc8d8a6c89) + checkEq(sar(0x2, 0x0), 0x0) + checkEq(sar(0x2, 0x1), 0x0) + checkEq(sar(0x2, 0x2), 0x0) + checkEq(sar(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x2, 0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c), 0xadcbeb7b490a21a5d56c5eb3df8afb6d6ec4c1a382a059e52de793aaa8dc503) + checkEq(sar(0x2, 0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758), 0x85e543680bbc202936bb70a1239a0bcca47e60b8fa7478ff400ac3794110dd6) + checkEq(sar(0x2, 0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913), 0x1c77868e023516d4e3871cc7f04ccd7cb6f20a6ba9d6e4ab442f1e5e46c53644) + checkEq(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + checkEq(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + checkEq(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c), 0x0) + checkEq(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758), 0x0) + checkEq(sar(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913), 0x0) + checkEq(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + checkEq(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + checkEq(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c), 0x0) + checkEq(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758), 0x0) + checkEq(sar(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913), 0x0) + checkEq(sar(0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c, 0x0), 0x0) + checkEq(sar(0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c, 0x1), 0x0) + checkEq(sar(0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c, 0x2), 0x0) + checkEq(sar(0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c, 0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c), 0x0) + checkEq(sar(0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c, 0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758), 0x0) + checkEq(sar(0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c, 0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913), 0x0) + checkEq(sar(0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758, 0x0), 0x0) + checkEq(sar(0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758, 0x1), 0x0) + checkEq(sar(0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758, 0x2), 0x0) + checkEq(sar(0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758, 0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c), 0x0) + checkEq(sar(0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758, 0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758), 0x0) + checkEq(sar(0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758, 0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913), 0x0) + checkEq(sar(0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913, 0x0), 0x0) + checkEq(sar(0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913, 0x1), 0x0) + checkEq(sar(0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913, 0x2), 0x0) + checkEq(sar(0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sar(0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913, 0x2b72faded2428869755b17acf7e2bedb5bb13068e0a816794b79e4eaaa37140c), 0x0) + checkEq(sar(0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913, 0x217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de50443758), 0x0) + checkEq(sar(0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913, 0x71de1a3808d45b538e1c731fc13335f2dbc829aea75b92ad10bc79791b14d913), 0x0) } // ==== // EVMVersion: >=constantinople diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul index 241fe9a19099..654f0800ecb0 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sdiv.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(sdiv(0x0, 0x0), 0x0) - check(sdiv(0x0, 0x1), 0x0) - check(sdiv(0x0, 0x2), 0x0) - check(sdiv(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(sdiv(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(sdiv(0x0, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) - check(sdiv(0x0, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) - check(sdiv(0x0, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) - check(sdiv(0x1, 0x0), 0x0) - check(sdiv(0x1, 0x1), 0x1) - check(sdiv(0x1, 0x2), 0x0) - check(sdiv(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sdiv(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(sdiv(0x1, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) - check(sdiv(0x1, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) - check(sdiv(0x1, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) - check(sdiv(0x2, 0x0), 0x0) - check(sdiv(0x2, 0x1), 0x2) - check(sdiv(0x2, 0x2), 0x1) - check(sdiv(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(sdiv(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sdiv(0x2, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) - check(sdiv(0x2, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) - check(sdiv(0x2, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) - check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) - check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) - check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) - check(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) - check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) - check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) - check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) - check(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) - check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x0), 0x0) - check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x1), 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8) - check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x2), 0xc6fff557944126ae170ad7e402c64834d1755bc187ba8328981f335a04647b64) - check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x72001550d77db2a3d1ea5037fa736f965d15487cf08af9aecfc1994bf7370938) - check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x39000aa86bbed951e8f5281bfd39b7cb2e8aa43e78457cd767e0cca5fb9b849c) - check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x1) - check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) - check(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x116) - check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x0), 0x0) - check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x1), 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6) - check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x2), 0xc6a4459992f1746943c22cb0393cb9b6b3e38d5163e6d588c031b4c128bec7b) - check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xe72b774ccda1d172d787ba69f8d868c929838e55d383254ee7f9c967dae8270a) - check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xf395bba666d0e8b96bc3dd34fc6c346494c1c72ae9c192a773fce4b3ed741385) - check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) - check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x1) - check(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc4) - check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x0), 0x0) - check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x1), 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5) - check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x2), 0xffcb9810fc2988f075d60661a3640ea695fd3d2b5129a44cab4d81b977c159f3) - check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x68cfde07acee1f1453f33cb937e2b2d40585a95dacb766a964fc8d107d4c1b) - check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x3467ef03d6770f8a29f99e5c9bf1596a02c2d4aed65bb354b27e46883ea60d) - check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) - check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) - check(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x1) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(sdiv(0x0, 0x0), 0x0) + checkEq(sdiv(0x0, 0x1), 0x0) + checkEq(sdiv(0x0, 0x2), 0x0) + checkEq(sdiv(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(sdiv(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(sdiv(0x0, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + checkEq(sdiv(0x0, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + checkEq(sdiv(0x0, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) + checkEq(sdiv(0x1, 0x0), 0x0) + checkEq(sdiv(0x1, 0x1), 0x1) + checkEq(sdiv(0x1, 0x2), 0x0) + checkEq(sdiv(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sdiv(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(sdiv(0x1, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + checkEq(sdiv(0x1, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + checkEq(sdiv(0x1, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) + checkEq(sdiv(0x2, 0x0), 0x0) + checkEq(sdiv(0x2, 0x1), 0x2) + checkEq(sdiv(0x2, 0x2), 0x1) + checkEq(sdiv(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(sdiv(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sdiv(0x2, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + checkEq(sdiv(0x2, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + checkEq(sdiv(0x2, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) + checkEq(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + checkEq(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + checkEq(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + checkEq(sdiv(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) + checkEq(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) + checkEq(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + checkEq(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + checkEq(sdiv(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x0) + checkEq(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x0), 0x0) + checkEq(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x1), 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8) + checkEq(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x2), 0xc6fff557944126ae170ad7e402c64834d1755bc187ba8328981f335a04647b64) + checkEq(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x72001550d77db2a3d1ea5037fa736f965d15487cf08af9aecfc1994bf7370938) + checkEq(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x39000aa86bbed951e8f5281bfd39b7cb2e8aa43e78457cd767e0cca5fb9b849c) + checkEq(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x1) + checkEq(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + checkEq(sdiv(0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x116) + checkEq(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x0), 0x0) + checkEq(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x1), 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6) + checkEq(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x2), 0xc6a4459992f1746943c22cb0393cb9b6b3e38d5163e6d588c031b4c128bec7b) + checkEq(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xe72b774ccda1d172d787ba69f8d868c929838e55d383254ee7f9c967dae8270a) + checkEq(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xf395bba666d0e8b96bc3dd34fc6c346494c1c72ae9c192a773fce4b3ed741385) + checkEq(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + checkEq(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x1) + checkEq(sdiv(0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc4) + checkEq(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x0), 0x0) + checkEq(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x1), 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5) + checkEq(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x2), 0xffcb9810fc2988f075d60661a3640ea695fd3d2b5129a44cab4d81b977c159f3) + checkEq(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x68cfde07acee1f1453f33cb937e2b2d40585a95dacb766a964fc8d107d4c1b) + checkEq(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x3467ef03d6770f8a29f99e5c9bf1596a02c2d4aed65bb354b27e46883ea60d) + checkEq(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x8dffeaaf28824d5c2e15afc8058c9069a2eab7830f750651303e66b408c8f6c8), 0x0) + checkEq(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0x18d488b3325e2e8d2878459607279736d67c71aa2c7cdab1180636982517d8f6), 0x0) + checkEq(sdiv(0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5, 0xff973021f85311e0ebac0cc346c81d4d2bfa7a56a2534899569b0372ef82b3e5), 0x1) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul index 56b422946402..407e01147ebc 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sgt.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(sgt(0x0, 0x0), 0x0) - check(sgt(0x0, 0x1), 0x0) - check(sgt(0x0, 0x2), 0x0) - check(sgt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(sgt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(sgt(0x0, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) - check(sgt(0x0, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) - check(sgt(0x0, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) - check(sgt(0x1, 0x0), 0x1) - check(sgt(0x1, 0x1), 0x0) - check(sgt(0x1, 0x2), 0x0) - check(sgt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(sgt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(sgt(0x1, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) - check(sgt(0x1, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) - check(sgt(0x1, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) - check(sgt(0x2, 0x0), 0x1) - check(sgt(0x2, 0x1), 0x1) - check(sgt(0x2, 0x2), 0x0) - check(sgt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(sgt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(sgt(0x2, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) - check(sgt(0x2, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) - check(sgt(0x2, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) - check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) - check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) - check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) - check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) - check(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) - check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) - check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) - check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) - check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) - check(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) - check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x0), 0x0) - check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x1), 0x0) - check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x2), 0x0) - check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x0) - check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) - check(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) - check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x0), 0x1) - check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x1), 0x1) - check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x2), 0x1) - check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) - check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) - check(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) - check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x0), 0x1) - check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x1), 0x1) - check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x2), 0x1) - check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) - check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x1) - check(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(sgt(0x0, 0x0), 0x0) + checkEq(sgt(0x0, 0x1), 0x0) + checkEq(sgt(0x0, 0x2), 0x0) + checkEq(sgt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(sgt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(sgt(0x0, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + checkEq(sgt(0x0, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + checkEq(sgt(0x0, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + checkEq(sgt(0x1, 0x0), 0x1) + checkEq(sgt(0x1, 0x1), 0x0) + checkEq(sgt(0x1, 0x2), 0x0) + checkEq(sgt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(sgt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(sgt(0x1, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + checkEq(sgt(0x1, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + checkEq(sgt(0x1, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + checkEq(sgt(0x2, 0x0), 0x1) + checkEq(sgt(0x2, 0x1), 0x1) + checkEq(sgt(0x2, 0x2), 0x0) + checkEq(sgt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(sgt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(sgt(0x2, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + checkEq(sgt(0x2, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + checkEq(sgt(0x2, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + checkEq(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + checkEq(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + checkEq(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + checkEq(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + checkEq(sgt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + checkEq(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + checkEq(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + checkEq(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + checkEq(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + checkEq(sgt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + checkEq(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x0), 0x0) + checkEq(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x1), 0x0) + checkEq(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x2), 0x0) + checkEq(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x0) + checkEq(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + checkEq(sgt(0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + checkEq(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x0), 0x1) + checkEq(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x1), 0x1) + checkEq(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x2), 0x1) + checkEq(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + checkEq(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x0) + checkEq(sgt(0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) + checkEq(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x0), 0x1) + checkEq(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x1), 0x1) + checkEq(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x2), 0x1) + checkEq(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0xc1a8f6ade2306920f87bbaa51747608772d5c66c1d9944c8326ae9262279fcb4), 0x1) + checkEq(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x79a6410ddb1ec06466e380d4d2e2ae4a66c4c6ba06c270868274d037ac6cf53), 0x1) + checkEq(sgt(0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445, 0x7c4c8a3d9eb0f7dc6a89d59dfd710f4ef6fd7a9eea21020eebd16cb1baa50445), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul index d1c4c1a99ad2..8c253824c0b3 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/shl.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(shl(0x0, 0x0), 0x0) - check(shl(0x0, 0x1), 0x1) - check(shl(0x0, 0x2), 0x2) - check(shl(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(shl(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(shl(0x0, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9) - check(shl(0x0, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a) - check(shl(0x0, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951) - check(shl(0x1, 0x0), 0x0) - check(shl(0x1, 0x1), 0x2) - check(shl(0x1, 0x2), 0x4) - check(shl(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(shl(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) - check(shl(0x1, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0xc5f180d19556f397126a43965fdc0465af1d2d7a32c3d3d4fd2e386d2f96fd2) - check(shl(0x1, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0xc64b6e35896bfda7e82d9d3f3931aadbaf2221b8d6d0f1dddecff225c89556d4) - check(shl(0x1, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x61eeb35c944b39051996f7eb6d90f18dfcdf8b5aeddd2c1b58440be727f7b2a2) - check(shl(0x2, 0x0), 0x0) - check(shl(0x2, 0x1), 0x4) - check(shl(0x2, 0x2), 0x8) - check(shl(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) - check(shl(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8) - check(shl(0x2, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x18be301a32aade72e24d4872cbfb808cb5e3a5af46587a7a9fa5c70da5f2dfa4) - check(shl(0x2, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x8c96dc6b12d7fb4fd05b3a7e726355b75e444371ada1e3bbbd9fe44b912aada8) - check(shl(0x2, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0xc3dd66b92896720a332defd6db21e31bf9bf16b5dbba5836b08817ce4fef6544) - check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) - check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) - check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x0) - check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x0) - check(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) - check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) - check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) - check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x0) - check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x0) - check(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) - check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0x0), 0x0) - check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0x1), 0x0) - check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0x2), 0x0) - check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x0) - check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x0) - check(shl(0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) - check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0x0), 0x0) - check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0x1), 0x0) - check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0x2), 0x0) - check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x0) - check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x0) - check(shl(0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) - check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0x0), 0x0) - check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0x1), 0x0) - check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0x2), 0x0) - check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0x62f8c068caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9), 0x0) - check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0x6325b71ac4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6a), 0x0) - check(shl(0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951, 0xb0f759ae4a259c828ccb7bf5b6c878c6fe6fc5ad76ee960dac2205f393fbd951), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(shl(0x0, 0x0), 0x0) + checkEq(shl(0x0, 0x1), 0x1) + checkEq(shl(0x0, 0x2), 0x2) + checkEq(shl(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(shl(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(shl(0x0, 0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba), 0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba) + checkEq(shl(0x0, 0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f), 0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f) + checkEq(shl(0x0, 0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863), 0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863) + checkEq(shl(0x1, 0x0), 0x0) + checkEq(shl(0x1, 0x1), 0x2) + checkEq(shl(0x1, 0x2), 0x4) + checkEq(shl(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(shl(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + checkEq(shl(0x1, 0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba), 0x5834d6cd929bee9151121e73d19dae933163068af78568cff0e1a522bfa98374) + checkEq(shl(0x1, 0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f), 0xdb5d9762070e70aaef02b24a031eedf985849bf1816c2ee653c682cf7341fcfe) + checkEq(shl(0x1, 0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863), 0x19556f397126a43965fdc0465af1d2d7a32c3d3d4fd2e386d2f96fd3ea6550c6) + checkEq(shl(0x2, 0x0), 0x0) + checkEq(shl(0x2, 0x1), 0x4) + checkEq(shl(0x2, 0x2), 0x8) + checkEq(shl(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + checkEq(shl(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8) + checkEq(shl(0x2, 0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba), 0xb069ad9b2537dd22a2243ce7a33b5d2662c60d15ef0ad19fe1c34a457f5306e8) + checkEq(shl(0x2, 0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f), 0xb6bb2ec40e1ce155de056494063ddbf30b0937e302d85dcca78d059ee683f9fc) + checkEq(shl(0x2, 0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863), 0x32aade72e24d4872cbfb808cb5e3a5af46587a7a9fa5c70da5f2dfa7d4caa18c) + checkEq(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + checkEq(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + checkEq(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba), 0x0) + checkEq(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f), 0x0) + checkEq(shl(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863), 0x0) + checkEq(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + checkEq(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + checkEq(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba), 0x0) + checkEq(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f), 0x0) + checkEq(shl(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863), 0x0) + checkEq(shl(0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba, 0x0), 0x0) + checkEq(shl(0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba, 0x1), 0x0) + checkEq(shl(0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba, 0x2), 0x0) + checkEq(shl(0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(shl(0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(shl(0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba, 0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba), 0x0) + checkEq(shl(0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba, 0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f), 0x0) + checkEq(shl(0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba, 0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863), 0x0) + checkEq(shl(0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f, 0x0), 0x0) + checkEq(shl(0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f, 0x1), 0x0) + checkEq(shl(0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f, 0x2), 0x0) + checkEq(shl(0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(shl(0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(shl(0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f, 0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba), 0x0) + checkEq(shl(0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f, 0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f), 0x0) + checkEq(shl(0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f, 0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863), 0x0) + checkEq(shl(0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863, 0x0), 0x0) + checkEq(shl(0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863, 0x1), 0x0) + checkEq(shl(0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863, 0x2), 0x0) + checkEq(shl(0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(shl(0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(shl(0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863, 0xac1a6b66c94df748a8890f39e8ced74998b183457bc2b467f870d2915fd4c1ba), 0x0) + checkEq(shl(0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863, 0xedaecbb10387385577815925018f76fcc2c24df8c0b6177329e34167b9a0fe7f), 0x0) + checkEq(shl(0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863, 0x8caab79cb893521cb2fee0232d78e96bd1961e9ea7e971c3697cb7e9f532a863), 0x0) } // ==== // EVMVersion: >=constantinople diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul index db36f407876b..40f56ce7f12e 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/shr.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(shr(0x0, 0x0), 0x0) - check(shr(0x0, 0x1), 0x1) - check(shr(0x0, 0x2), 0x2) - check(shr(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(shr(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(shr(0x0, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0) - check(shr(0x0, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb) - check(shr(0x0, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de) - check(shr(0x1, 0x0), 0x0) - check(shr(0x1, 0x1), 0x0) - check(shr(0x1, 0x2), 0x1) - check(shr(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(shr(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(shr(0x1, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x5a47af7f111d77bb1a7a6583d1476c2b3f3cc7deab46e216f81e27c7e3f22ce8) - check(shr(0x1, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x713f359d1c4bb8d3f7302983742ecfbc35e96e24141be8670e1e468da869f5f5) - check(shr(0x1, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x28b8533510bca86d0177840526d76e1424734179948fcc171f4e8f1fe801586f) - check(shr(0x2, 0x0), 0x0) - check(shr(0x2, 0x1), 0x0) - check(shr(0x2, 0x2), 0x0) - check(shr(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(shr(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(shr(0x2, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x2d23d7bf888ebbdd8d3d32c1e8a3b6159f9e63ef55a3710b7c0f13e3f1f91674) - check(shr(0x2, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x389f9ace8e25dc69fb9814c1ba1767de1af4b7120a0df433870f2346d434fafa) - check(shr(0x2, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x145c299a885e543680bbc202936bb70a1239a0bcca47e60b8fa7478ff400ac37) - check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) - check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) - check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x0) - check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x0) - check(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) - check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) - check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) - check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x0) - check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x0) - check(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) - check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0x0), 0x0) - check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0x1), 0x0) - check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0x2), 0x0) - check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x0) - check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x0) - check(shr(0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) - check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0x0), 0x0) - check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0x1), 0x0) - check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0x2), 0x0) - check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x0) - check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x0) - check(shr(0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) - check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0x0), 0x0) - check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0x1), 0x0) - check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0x2), 0x0) - check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0xb48f5efe223aef7634f4cb07a28ed8567e798fbd568dc42df03c4f8fc7e459d0), 0x0) - check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0xe27e6b3a389771a7ee605306e85d9f786bd2dc482837d0ce1c3c8d1b50d3ebeb), 0x0) - check(shr(0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de, 0x5170a66a217950da02ef080a4daedc2848e682f3291f982e3e9d1e3fd002b0de), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(shr(0x0, 0x0), 0x0) + checkEq(shr(0x0, 0x1), 0x1) + checkEq(shr(0x0, 0x2), 0x2) + checkEq(shr(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(shr(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(shr(0x0, 0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d), 0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d) + checkEq(shr(0x0, 0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0), 0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0) + checkEq(shr(0x0, 0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75), 0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75) + checkEq(shr(0x1, 0x0), 0x0) + checkEq(shr(0x1, 0x1), 0x0) + checkEq(shr(0x1, 0x2), 0x1) + checkEq(shr(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(shr(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(shr(0x1, 0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d), 0x665809d52b46f8ab64ce7bc1a04879f061f3bee18b337ae254d951548d3370ae) + checkEq(shr(0x1, 0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0), 0x625aff69fa0b674fce4c6ab6ebc8886e35b43c7777b3fc89722555b56ab68b68) + checkEq(shr(0x1, 0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75), 0x51f2fab4b166256dff7d9e5ae41958927b6f8fb5c4876e96c274b1cb46b6be3a) + checkEq(shr(0x2, 0x0), 0x0) + checkEq(shr(0x2, 0x1), 0x0) + checkEq(shr(0x2, 0x2), 0x0) + checkEq(shr(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(shr(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(shr(0x2, 0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d), 0x332c04ea95a37c55b2673de0d0243cf830f9df70c599bd712a6ca8aa4699b857) + checkEq(shr(0x2, 0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0), 0x312d7fb4fd05b3a7e726355b75e444371ada1e3bbbd9fe44b912aadab55b45b4) + checkEq(shr(0x2, 0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75), 0x28f97d5a58b312b6ffbecf2d720cac493db7c7dae243b74b613a58e5a35b5f1d) + checkEq(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + checkEq(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x0) + checkEq(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d), 0x0) + checkEq(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0), 0x0) + checkEq(shr(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75), 0x0) + checkEq(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + checkEq(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + checkEq(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d), 0x0) + checkEq(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0), 0x0) + checkEq(shr(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75), 0x0) + checkEq(shr(0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d, 0x0), 0x0) + checkEq(shr(0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d, 0x1), 0x0) + checkEq(shr(0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d, 0x2), 0x0) + checkEq(shr(0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(shr(0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(shr(0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d, 0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d), 0x0) + checkEq(shr(0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d, 0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0), 0x0) + checkEq(shr(0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d, 0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75), 0x0) + checkEq(shr(0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0, 0x0), 0x0) + checkEq(shr(0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0, 0x1), 0x0) + checkEq(shr(0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0, 0x2), 0x0) + checkEq(shr(0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(shr(0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(shr(0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0, 0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d), 0x0) + checkEq(shr(0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0, 0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0), 0x0) + checkEq(shr(0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0, 0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75), 0x0) + checkEq(shr(0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75, 0x0), 0x0) + checkEq(shr(0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75, 0x1), 0x0) + checkEq(shr(0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75, 0x2), 0x0) + checkEq(shr(0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(shr(0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(shr(0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75, 0xccb013aa568df156c99cf7834090f3e0c3e77dc31666f5c4a9b2a2a91a66e15d), 0x0) + checkEq(shr(0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75, 0xc4b5fed3f416ce9f9c98d56dd79110dc6b6878eeef67f912e44aab6ad56d16d0), 0x0) + checkEq(shr(0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75, 0xa3e5f56962cc4adbfefb3cb5c832b124f6df1f6b890edd2d84e963968d6d7c75), 0x0) } // ==== // EVMVersion: >=constantinople diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul index e295a0c6ae97..f95136533745 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/signextend.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(signextend(0x0, 0x0), 0x0) - check(signextend(0x0, 0x1), 0x1) - check(signextend(0x0, 0x2), 0x2) - check(signextend(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(signextend(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(signextend(0x0, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb4) - check(signextend(0x0, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a) - check(signextend(0x0, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb5) - check(signextend(0x1, 0x0), 0x0) - check(signextend(0x1, 0x1), 0x1) - check(signextend(0x1, 0x2), 0x2) - check(signextend(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(signextend(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(signextend(0x1, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x47b4) - check(signextend(0x1, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x308a) - check(signextend(0x1, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbdb5) - check(signextend(0x2, 0x0), 0x0) - check(signextend(0x2, 0x1), 0x1) - check(signextend(0x2, 0x2), 0x2) - check(signextend(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(signextend(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(signextend(0x2, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffff347b4) - check(signextend(0x2, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc2308a) - check(signextend(0x2, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x6bdb5) - check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) - check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x2) - check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4) - check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a) - check(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5) - check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x1) - check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x2) - check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4) - check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a) - check(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5) - check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x0), 0x0) - check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x1), 0x1) - check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x2), 0x2) - check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4) - check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a) - check(signextend(0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5) - check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x0), 0x0) - check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x1), 0x1) - check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x2), 0x2) - check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4) - check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a) - check(signextend(0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5) - check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x0), 0x0) - check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x1), 0x1) - check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x2), 0x2) - check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4), 0x6855c4590e561bd51e79061b0952b669a42287b819f7736eb72de8dc03f347b4) - check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a), 0x61138948e40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a) - check(signextend(0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5, 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5), 0x36b4781b870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(signextend(0x0, 0x0), 0x0) + checkEq(signextend(0x0, 0x1), 0x1) + checkEq(signextend(0x0, 0x2), 0x2) + checkEq(signextend(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(signextend(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(signextend(0x0, 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe4) + checkEq(signextend(0x0, 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa9) + checkEq(signextend(0x0, 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c), 0x1c) + checkEq(signextend(0x1, 0x0), 0x0) + checkEq(signextend(0x1, 0x1), 0x1) + checkEq(signextend(0x1, 0x2), 0x2) + checkEq(signextend(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(signextend(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(signextend(0x1, 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9de4) + checkEq(signextend(0x1, 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffea9) + checkEq(signextend(0x1, 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c), 0x351c) + checkEq(signextend(0x2, 0x0), 0x0) + checkEq(signextend(0x2, 0x1), 0x1) + checkEq(signextend(0x2, 0x2), 0x2) + checkEq(signextend(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(signextend(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(signextend(0x2, 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4), 0x799de4) + checkEq(signextend(0x2, 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9bfea9) + checkEq(signextend(0x2, 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe8351c) + checkEq(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) + checkEq(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x2) + checkEq(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4), 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4) + checkEq(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9), 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9) + checkEq(signextend(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c), 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c) + checkEq(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x1) + checkEq(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x2) + checkEq(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4), 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4) + checkEq(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9), 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9) + checkEq(signextend(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c), 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c) + checkEq(signextend(0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4, 0x0), 0x0) + checkEq(signextend(0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4, 0x1), 0x1) + checkEq(signextend(0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4, 0x2), 0x2) + checkEq(signextend(0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(signextend(0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(signextend(0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4, 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4), 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4) + checkEq(signextend(0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4, 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9), 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9) + checkEq(signextend(0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4, 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c), 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c) + checkEq(signextend(0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9, 0x0), 0x0) + checkEq(signextend(0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9, 0x1), 0x1) + checkEq(signextend(0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9, 0x2), 0x2) + checkEq(signextend(0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(signextend(0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(signextend(0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9, 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4), 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4) + checkEq(signextend(0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9, 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9), 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9) + checkEq(signextend(0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9, 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c), 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c) + checkEq(signextend(0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c, 0x0), 0x0) + checkEq(signextend(0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c, 0x1), 0x1) + checkEq(signextend(0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c, 0x2), 0x2) + checkEq(signextend(0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(signextend(0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(signextend(0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c, 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4), 0xe40817554fc48fd1ffd4c0d2a6faff424e33da38076f97530ec2308a88799de4) + checkEq(signextend(0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c, 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9), 0x870310da5481b23fe98b33115c6e598ebc74621803b9bc766b06bdb5d49bfea9) + checkEq(signextend(0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c, 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c), 0xc77c95974d4cc4050131a4ab988f12dda46426db9462061a84c9431fa7e8351c) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul index 499a7ffbb861..d8dfc00da4ca 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/slt.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(slt(0x0, 0x0), 0x0) - check(slt(0x0, 0x1), 0x1) - check(slt(0x0, 0x2), 0x1) - check(slt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(slt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(slt(0x0, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) - check(slt(0x0, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) - check(slt(0x0, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) - check(slt(0x1, 0x0), 0x0) - check(slt(0x1, 0x1), 0x0) - check(slt(0x1, 0x2), 0x1) - check(slt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(slt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(slt(0x1, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) - check(slt(0x1, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) - check(slt(0x1, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) - check(slt(0x2, 0x0), 0x0) - check(slt(0x2, 0x1), 0x0) - check(slt(0x2, 0x2), 0x0) - check(slt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(slt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(slt(0x2, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) - check(slt(0x2, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) - check(slt(0x2, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) - check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x1) - check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) - check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) - check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) - check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) - check(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) - check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x1) - check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x1) - check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x1) - check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) - check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) - check(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) - check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x0), 0x1) - check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x1), 0x1) - check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x2), 0x1) - check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) - check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) - check(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) - check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x0), 0x0) - check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x1), 0x0) - check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x2), 0x0) - check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) - check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x0) - check(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) - check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x0), 0x1) - check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x1), 0x1) - check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x2), 0x1) - check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x1) - check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) - check(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(slt(0x0, 0x0), 0x0) + checkEq(slt(0x0, 0x1), 0x1) + checkEq(slt(0x0, 0x2), 0x1) + checkEq(slt(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(slt(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(slt(0x0, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + checkEq(slt(0x0, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + checkEq(slt(0x0, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + checkEq(slt(0x1, 0x0), 0x0) + checkEq(slt(0x1, 0x1), 0x0) + checkEq(slt(0x1, 0x2), 0x1) + checkEq(slt(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(slt(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(slt(0x1, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + checkEq(slt(0x1, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + checkEq(slt(0x1, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + checkEq(slt(0x2, 0x0), 0x0) + checkEq(slt(0x2, 0x1), 0x0) + checkEq(slt(0x2, 0x2), 0x0) + checkEq(slt(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(slt(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(slt(0x2, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + checkEq(slt(0x2, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + checkEq(slt(0x2, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + checkEq(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x1) + checkEq(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x1) + checkEq(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0x1) + checkEq(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + checkEq(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + checkEq(slt(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + checkEq(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x1) + checkEq(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x1) + checkEq(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x1) + checkEq(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + checkEq(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + checkEq(slt(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + checkEq(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x0), 0x1) + checkEq(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x1), 0x1) + checkEq(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x2), 0x1) + checkEq(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + checkEq(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + checkEq(slt(0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + checkEq(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x0), 0x0) + checkEq(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x1), 0x0) + checkEq(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x2), 0x0) + checkEq(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x0) + checkEq(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x0) + checkEq(slt(0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) + checkEq(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x0), 0x1) + checkEq(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x1), 0x1) + checkEq(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x2), 0x1) + checkEq(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0xcf8e0b6a32221ec616462752880c68a4b3b33f6a6af80fb7234a28d6cc36d2ec), 0x1) + checkEq(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x1f7753c55d4e1c43cb26e2a041a5a57387662f1b81f96e44760b719db8cb6f36), 0x1) + checkEq(slt(0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324, 0x981bfaba9a12b4198e7e38eb9588204d3e7d9ab8be73735dc4bf52431847d324), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul index fa2afc4e679a..4fd98d761864 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/smod.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(smod(0x0, 0x0), 0x0) - check(smod(0x0, 0x1), 0x0) - check(smod(0x0, 0x2), 0x0) - check(smod(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(smod(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(smod(0x0, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x0) - check(smod(0x0, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x0) - check(smod(0x0, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x0) - check(smod(0x1, 0x0), 0x0) - check(smod(0x1, 0x1), 0x0) - check(smod(0x1, 0x2), 0x1) - check(smod(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(smod(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(smod(0x1, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x1) - check(smod(0x1, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x1) - check(smod(0x1, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x1) - check(smod(0x2, 0x0), 0x0) - check(smod(0x2, 0x1), 0x0) - check(smod(0x2, 0x2), 0x0) - check(smod(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(smod(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(smod(0x2, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x2) - check(smod(0x2, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x2) - check(smod(0x2, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x2) - check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) - check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) - check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) - check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) - check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) - check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0x0), 0x0) - check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0x1), 0x0) - check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0x2), 0x0) - check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x0) - check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e) - check(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e) - check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0x0), 0x0) - check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0x1), 0x0) - check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0x2), 0x0) - check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x2de0e2b2148d4fdfbb10ae6c22e13021868ba21254f722574111f1417d6dd8a) - check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x0) - check(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c) - check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0x0), 0x0) - check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0x1), 0x0) - check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0xf8f140d5a8fce565089e7a9fe349aa55884d0a49d71044525e82d52c31eeea37) - check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xfd8fdd6d1200102f72369fc103780e7f09a5662debf102681fdcfaac94e2cdd1) - check(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(smod(0x0, 0x0), 0x0) + checkEq(smod(0x0, 0x1), 0x0) + checkEq(smod(0x0, 0x2), 0x0) + checkEq(smod(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(smod(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(smod(0x0, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x0) + checkEq(smod(0x0, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x0) + checkEq(smod(0x0, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x0) + checkEq(smod(0x1, 0x0), 0x0) + checkEq(smod(0x1, 0x1), 0x0) + checkEq(smod(0x1, 0x2), 0x1) + checkEq(smod(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(smod(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(smod(0x1, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x1) + checkEq(smod(0x1, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x1) + checkEq(smod(0x1, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x1) + checkEq(smod(0x2, 0x0), 0x0) + checkEq(smod(0x2, 0x1), 0x0) + checkEq(smod(0x2, 0x2), 0x0) + checkEq(smod(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(smod(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(smod(0x2, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x2) + checkEq(smod(0x2, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x2) + checkEq(smod(0x2, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x2) + checkEq(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0x0) + checkEq(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0x0) + checkEq(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(smod(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0x0) + checkEq(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0x0) + checkEq(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0x0) + checkEq(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(smod(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0x0), 0x0) + checkEq(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0x1), 0x0) + checkEq(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0x2), 0x0) + checkEq(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x0) + checkEq(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e) + checkEq(smod(0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e) + checkEq(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0x0), 0x0) + checkEq(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0x1), 0x0) + checkEq(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0x2), 0x0) + checkEq(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0x2de0e2b2148d4fdfbb10ae6c22e13021868ba21254f722574111f1417d6dd8a) + checkEq(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0x0) + checkEq(smod(0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c) + checkEq(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0x0), 0x0) + checkEq(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0x1), 0x0) + checkEq(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xf36a4794a14e2cd68371e3b89319f21ceee3ff1d3504113508f36b07d3eab25e), 0xf8f140d5a8fce565089e7a9fe349aa55884d0a49d71044525e82d52c31eeea37) + checkEq(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xf73c6967ffaa827783f272e2f1420e52984bb03f04b60f06b1db40c43ec2b2c), 0xfd8fdd6d1200102f72369fc103780e7f09a5662debf102681fdcfaac94e2cdd1) + checkEq(smod(0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9, 0xa0d935e612201f42a0bbb4abe8ff4920108904164a2cbcc59d2ac262fd59cac9), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul index 91eabfd6d22d..ccc2da8c7069 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/sub.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(sub(0x0, 0x0), 0x0) - check(sub(0x0, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sub(0x0, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(sub(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(sub(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) - check(sub(0x0, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e84) - check(sub(0x0, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd6) - check(sub(0x0, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9de) - check(sub(0x1, 0x0), 0x1) - check(sub(0x1, 0x1), 0x0) - check(sub(0x1, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sub(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) - check(sub(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x3) - check(sub(0x1, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e85) - check(sub(0x1, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd7) - check(sub(0x1, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9df) - check(sub(0x2, 0x0), 0x2) - check(sub(0x2, 0x1), 0x1) - check(sub(0x2, 0x2), 0x0) - check(sub(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x3) - check(sub(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4) - check(sub(0x2, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e86) - check(sub(0x2, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd8) - check(sub(0x2, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9e0) - check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) - check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e83) - check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd5) - check(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9dd) - check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) - check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) - check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e82) - check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd4) - check(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9dc) - check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x0), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c) - check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x1), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17b) - check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x2), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17a) - check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17d) - check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17e) - check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0x0) - check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0x228806570f98613dae80c1017cf27cdee2891468b68f92e6e004d07cb67cef52) - check(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x9566d2426a939b57cfabe27acfe34dc5e5537cf2e39944bdb0597528c809db5a) - check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x0), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a) - check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x1), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd40229) - check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x2), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd40228) - check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022b) - check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022c) - check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xdd77f9a8f0679ec2517f3efe830d83211d76eb9749706d191ffb2f83498310ae) - check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0x0) - check(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x72decbeb5afb3a1a212b217952f0d0e702ca688a2d09b1d6d054a4ac118cec08) - check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x0), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622) - check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x1), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471621) - check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x2), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471620) - check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471623) - check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471624) - check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0x6a992dbd956c64a830541d85301cb23a1aac830d1c66bb424fa68ad737f624a6) - check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0x8d213414a504c5e5ded4de86ad0f2f18fd359775d2f64e292fab5b53ee7313f8) - check(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(sub(0x0, 0x0), 0x0) + checkEq(sub(0x0, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sub(0x0, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(sub(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(sub(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2) + checkEq(sub(0x0, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e84) + checkEq(sub(0x0, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd6) + checkEq(sub(0x0, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9de) + checkEq(sub(0x1, 0x0), 0x1) + checkEq(sub(0x1, 0x1), 0x0) + checkEq(sub(0x1, 0x2), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sub(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2) + checkEq(sub(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x3) + checkEq(sub(0x1, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e85) + checkEq(sub(0x1, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd7) + checkEq(sub(0x1, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9df) + checkEq(sub(0x2, 0x0), 0x2) + checkEq(sub(0x2, 0x1), 0x1) + checkEq(sub(0x2, 0x2), 0x0) + checkEq(sub(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x3) + checkEq(sub(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x4) + checkEq(sub(0x2, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e86) + checkEq(sub(0x2, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd8) + checkEq(sub(0x2, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9e0) + checkEq(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + checkEq(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e83) + checkEq(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd5) + checkEq(sub(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9dd) + checkEq(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + checkEq(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + checkEq(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xd0681363049e176333ffae5ed5a5b2f077e305311faf79e69cb4f3c4ecaf0e82) + checkEq(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0xf2f019ba143678a0e2806f6052982fcf5a6c1999d63f0ccd7cb9c441a32bfdd4) + checkEq(sub(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x65cee5a56f31b2bb03ab90d9a58900b65d3682240348bea44d0e68edb4b8e9dc) + checkEq(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x0), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c) + checkEq(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x1), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17b) + checkEq(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x2), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17a) + checkEq(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17d) + checkEq(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17e) + checkEq(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0x0) + checkEq(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0x228806570f98613dae80c1017cf27cdee2891468b68f92e6e004d07cb67cef52) + checkEq(sub(0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x9566d2426a939b57cfabe27acfe34dc5e5537cf2e39944bdb0597528c809db5a) + checkEq(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x0), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a) + checkEq(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x1), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd40229) + checkEq(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x2), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd40228) + checkEq(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022b) + checkEq(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022c) + checkEq(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0xdd77f9a8f0679ec2517f3efe830d83211d76eb9749706d191ffb2f83498310ae) + checkEq(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0x0) + checkEq(sub(0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x72decbeb5afb3a1a212b217952f0d0e702ca688a2d09b1d6d054a4ac118cec08) + checkEq(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x0), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622) + checkEq(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x1), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471621) + checkEq(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x2), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471620) + checkEq(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471623) + checkEq(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471624) + checkEq(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x2f97ec9cfb61e89ccc0051a12a5a4d0f881cfacee0508619634b0c3b1350f17c), 0x6a992dbd956c64a830541d85301cb23a1aac830d1c66bb424fa68ad737f624a6) + checkEq(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0xd0fe645ebc9875f1d7f909fad67d030a593e66629c0f33283463bbe5cd4022a), 0x8d213414a504c5e5ded4de86ad0f2f18fd359775d2f64e292fab5b53ee7313f8) + checkEq(sub(0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622, 0x9a311a5a90ce4d44fc546f265a76ff49a2c97ddbfcb7415bb2f197124b471622), 0x0) } // ==== // maxTraceSize: 0 diff --git a/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul b/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul index de9872b308a4..f7a2fd90cbbc 100644 --- a/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul +++ b/test/libyul/yulPureInterpreterTests/pure_instructions/xor.yul @@ -1,72 +1,213 @@ -{ +/* +# pyright: strict +from itertools import product +from random import seed, randrange +import os +from typing import Callable, Iterable, Union + +MX = 2**256 +generator_file_content = ['/*'] + list(map(lambda line: line.rstrip(), open(__file__, "r").readlines())) + ['*' + '/'] + +def rand_int(n: int, start: int, end: Union[int, None] = None) -> list[int]: + return [randrange(start, end) for _ in range(n)] + +def u256(num: int): + return int(num) % MX + +def u2s(num: int): + return int(num) - MX if (int(num) >> 255) > 0 else int(num) + +def gen_test( + fn_name: str, + *, + param_cnt: int, + calc: Callable[[tuple[int, ...]], int], + test_numbers: Union[Iterable[int], None] = None, + evm_version: Union[str, None] = None, + setup: str = " function checkEq(a, b)\n { if eq(a, b) { leave } revert(0, 0) }", + format_case: Callable[ + [str, tuple[int, ...], int], str + ] = lambda fn_name, params, res: f"checkEq({fn_name}({', '.join(hex(i) for i in params)}), {hex(res)})", +): + print("Generating test for", fn_name) + if test_numbers is None: + if param_cnt == 1: + test_numbers = [0, 1, 2, 3] + [MX - 1, MX - 2, MX - 3] + rand_int(4, MX) + else: + test_numbers = [0, 1, 2] + [MX - 1, MX - 2] + rand_int(3, MX) + + src: list[str] = [] + src.extend(generator_file_content) + src.append("{") + src.append(f"{setup}") + for params in product(test_numbers, repeat=param_cnt): + res = u256(calc(params)) + src.append(f" {format_case(fn_name, params, res)}") + src.append("}") + + src.append("// ====") + src.append("// maxTraceSize: 0") + if evm_version is not None: + src.append(f"// EVMVersion: {evm_version}") + + with open(fn_name + ".yul", "w", encoding="utf-8") as f: + print("\n".join(src), file=f) + +def signed_div(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) // abs(b) + if (a < 0) != (b < 0): + res = -res + return res - function check(a, b) - { if iszero(eq(a, b)) { revert(0, 0) } } - - check(xor(0x0, 0x0), 0x0) - check(xor(0x0, 0x1), 0x1) - check(xor(0x0, 0x2), 0x2) - check(xor(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(xor(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(xor(0x0, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea) - check(xor(0x0, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f) - check(xor(0x0, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a) - check(xor(0x1, 0x0), 0x1) - check(xor(0x1, 0x1), 0x0) - check(xor(0x1, 0x2), 0x3) - check(xor(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(xor(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(xor(0x1, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63eb) - check(xor(0x1, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43e) - check(xor(0x1, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82b) - check(xor(0x2, 0x0), 0x2) - check(xor(0x2, 0x1), 0x3) - check(xor(0x2, 0x2), 0x0) - check(xor(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) - check(xor(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) - check(xor(0x2, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63e8) - check(xor(0x2, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43d) - check(xor(0x2, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf828) - check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) - check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) - check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) - check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x7dea1e8624891ec6074d85f1ac0a80b1d4ddd9a56f9935fcde0810809c029c15) - check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0xd0a99270ccd90226c167cdb767654d8ba12321f5a4ec95764b1f2dfd304d0bc0) - check(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x243f36f7257b26334d71056c8a43dfe9720231bc14326b4c295817806e1407d5) - check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) - check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) - check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) - check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) - check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) - check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x7dea1e8624891ec6074d85f1ac0a80b1d4ddd9a56f9935fcde0810809c029c14) - check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0xd0a99270ccd90226c167cdb767654d8ba12321f5a4ec95764b1f2dfd304d0bc1) - check(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x243f36f7257b26334d71056c8a43dfe9720231bc14326b4c295817806e1407d4) - check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x0), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea) - check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x1), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63eb) - check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x2), 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63e8) - check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x7dea1e8624891ec6074d85f1ac0a80b1d4ddd9a56f9935fcde0810809c029c15) - check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x7dea1e8624891ec6074d85f1ac0a80b1d4ddd9a56f9935fcde0810809c029c14) - check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x0) - check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0xad438cf6e8501ce0c62a4846cb6fcd3a75fef850cb75a08a95173d7dac4f97d5) - check(xor(0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x59d5287101f238f54a3c809d26495f58a6dfe8197bab5eb0f7500700f2169bc0) - check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x0), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f) - check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x1), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43e) - check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x2), 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43d) - check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xd0a99270ccd90226c167cdb767654d8ba12321f5a4ec95764b1f2dfd304d0bc0) - check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xd0a99270ccd90226c167cdb767654d8ba12321f5a4ec95764b1f2dfd304d0bc1) - check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0xad438cf6e8501ce0c62a4846cb6fcd3a75fef850cb75a08a95173d7dac4f97d5) - check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0x0) - check(xor(0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0xf496a487e9a224158c16c8dbed269262d3211049b0defe3a62473a7d5e590c15) - check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x0), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a) - check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x1), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82b) - check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x2), 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf828) - check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x243f36f7257b26334d71056c8a43dfe9720231bc14326b4c295817806e1407d5) - check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x243f36f7257b26334d71056c8a43dfe9720231bc14326b4c295817806e1407d4) - check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x8215e179db76e139f8b27a0e53f57f4e2b22265a9066ca0321f7ef7f63fd63ea), 0x59d5287101f238f54a3c809d26495f58a6dfe8197bab5eb0f7500700f2169bc0) - check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0x2f566d8f3326fdd93e983248989ab2745edcde0a5b136a89b4e0d202cfb2f43f), 0xf496a487e9a224158c16c8dbed269262d3211049b0defe3a62473a7d5e590c15) - check(xor(0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a, 0xdbc0c908da84d9ccb28efa9375bc20168dfdce43ebcd94b3d6a7e87f91ebf82a), 0x0) +def signed_mod(p: tuple[int, ...]): + (a, b) = u2s(p[0]), u2s(p[1]) + if b == 0: + return 0 + res = abs(a) % abs(b) + if a < 0: + res = -res + return res + +def byte(p: tuple[int, ...]): + return 0 if p[0] >= 32 else (p[1] >> (8 * (31 - p[0]))) & 0xFF + +def shl(p: tuple[int, ...]): + return p[1] << p[0] if p[0] < 32 else 0 + +def shr(p: tuple[int, ...]): + return p[1] >> p[0] + +def sar(p: tuple[int, ...]): + (sh, val) = p + high_bit = val >> 255 + val >>= sh + val |= u256(-high_bit) << max(0, 255 - sh) + return val + +def signextend(p: tuple[int, ...]): + (byte_pos, val) = p + byte_pos = min(byte_pos, 32) + mask_shift = byte_pos * 8 + 8 + high_bit = (val >> (mask_shift - 1)) & 1 + if high_bit: + return val | (u256(-1) << mask_shift) + return val & ((1 << mask_shift) - 1) + +def addmod(p: tuple[int, ...]): + return (p[0] + p[1]) % p[2] if p[2] != 0 else 0 + +def mulmod(p: tuple[int, ...]): + return (p[0] * p[1]) % p[2] if p[2] != 0 else 0 + +seed(20240823) +os.chdir(os.path.dirname(os.path.abspath(__file__))) +gen_test("add", param_cnt=2, calc=lambda p: p[0] + p[1]) +gen_test("mul", param_cnt=2, calc=lambda p: p[0] * p[1]) +gen_test("sub", param_cnt=2, calc=lambda p: p[0] - p[1]) +gen_test("div", param_cnt=2, calc=lambda p: p[0] // p[1] if p[1] != 0 else 0) +gen_test("sdiv", param_cnt=2, calc=signed_div) +gen_test("mod", param_cnt=2, calc=lambda p: p[0] % p[1] if p[1] != 0 else 0) +gen_test("smod", param_cnt=2, calc=signed_mod) +gen_test("exp", param_cnt=2, calc=lambda p: pow(p[0], p[1], MX)) +gen_test("not", param_cnt=1, calc=lambda p: ~p[0]) +gen_test("lt", param_cnt=2, calc=lambda p: p[0] < p[1]) +gen_test("gt", param_cnt=2, calc=lambda p: p[0] > p[1]) +gen_test("slt", param_cnt=2, calc=lambda p: u2s(p[0]) < u2s(p[1])) +gen_test("sgt", param_cnt=2, calc=lambda p: u2s(p[0]) > u2s(p[1])) +gen_test("iszero", param_cnt=1, calc=lambda p: p[0] == 0) +gen_test("and", param_cnt=2, calc=lambda p: p[0] & p[1]) +gen_test("or", param_cnt=2, calc=lambda p: p[0] | p[1]) +gen_test("xor", param_cnt=2, calc=lambda p: p[0] ^ p[1]) +gen_test("byte", param_cnt=2, test_numbers=rand_int(3, MX) + rand_int(3, 1, 32) + [0], calc=byte) +gen_test("shl", evm_version=">=constantinople", param_cnt=2, calc=shl) +gen_test("shr", evm_version=">=constantinople", param_cnt=2, calc=shr) +gen_test("sar", evm_version=">=constantinople", param_cnt=2, calc=sar) +gen_test("addmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=addmod) +gen_test("mulmod", param_cnt=3, test_numbers=rand_int(3, MX) + [0], calc=mulmod) +gen_test("signextend", param_cnt=2, calc=signextend) +# The other uses `eq` to test. We need to test `eq` a bit differently. +gen_test( + "eq", + param_cnt=2, + calc=lambda p: p[0] == p[1], + setup= """ function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + function checkNe(a, b) + { if eq(a, b) { revert(0, 0) } } +""", + format_case=lambda _, params, res: f"{"checkEq" if res == 1 else "checkNe"}({hex(params[0])}, {hex(params[1])})" +) +*/ +{ + function checkEq(a, b) + { if eq(a, b) { leave } revert(0, 0) } + checkEq(xor(0x0, 0x0), 0x0) + checkEq(xor(0x0, 0x1), 0x1) + checkEq(xor(0x0, 0x2), 0x2) + checkEq(xor(0x0, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(xor(0x0, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(xor(0x0, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) + checkEq(xor(0x0, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) + checkEq(xor(0x0, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) + checkEq(xor(0x1, 0x0), 0x1) + checkEq(xor(0x1, 0x1), 0x0) + checkEq(xor(0x1, 0x2), 0x3) + checkEq(xor(0x1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(xor(0x1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(xor(0x1, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f0) + checkEq(xor(0x1, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b53) + checkEq(xor(0x1, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cff) + checkEq(xor(0x2, 0x0), 0x2) + checkEq(xor(0x2, 0x1), 0x3) + checkEq(xor(0x2, 0x2), 0x0) + checkEq(xor(0x2, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + checkEq(xor(0x2, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + checkEq(xor(0x2, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f3) + checkEq(xor(0x2, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b50) + checkEq(xor(0x2, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfc) + checkEq(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x0), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x1), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd) + checkEq(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x0) + checkEq(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x1) + checkEq(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0xc5f303ffaff31b9ea0b19b9090b926b56e69a511682bd4ee2e75f74b327d7d0e) + checkEq(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x6ea2beedaaa8c1ceb8f9cddea801f64ef5861cdb728d6b484f796975dc86e4ad) + checkEq(xor(0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x9f22c89c1961b95bf3e5523e86229c490cccca71f0db962b1f01fb9730f0a301) + checkEq(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x0), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe) + checkEq(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x1), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) + checkEq(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x2), 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc) + checkEq(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x1) + checkEq(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x0) + checkEq(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0xc5f303ffaff31b9ea0b19b9090b926b56e69a511682bd4ee2e75f74b327d7d0f) + checkEq(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x6ea2beedaaa8c1ceb8f9cddea801f64ef5861cdb728d6b484f796975dc86e4ac) + checkEq(xor(0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x9f22c89c1961b95bf3e5523e86229c490cccca71f0db962b1f01fb9730f0a300) + checkEq(xor(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x0), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1) + checkEq(xor(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x1), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f0) + checkEq(xor(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x2), 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f3) + checkEq(xor(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0xc5f303ffaff31b9ea0b19b9090b926b56e69a511682bd4ee2e75f74b327d7d0e) + checkEq(xor(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0xc5f303ffaff31b9ea0b19b9090b926b56e69a511682bd4ee2e75f74b327d7d0f) + checkEq(xor(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x0) + checkEq(xor(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0xab51bd12055bda501848564e38b8d0fb9befb9ca1aa6bfa6610c9e3eeefb99a3) + checkEq(xor(0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x5ad1cb63b692a2c55354c9ae169bbafc62a56f6098f042c531740cdc028dde0f) + checkEq(xor(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x0), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52) + checkEq(xor(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x1), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b53) + checkEq(xor(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x2), 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b50) + checkEq(xor(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x6ea2beedaaa8c1ceb8f9cddea801f64ef5861cdb728d6b484f796975dc86e4ad) + checkEq(xor(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x6ea2beedaaa8c1ceb8f9cddea801f64ef5861cdb728d6b484f796975dc86e4ac) + checkEq(xor(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0xab51bd12055bda501848564e38b8d0fb9befb9ca1aa6bfa6610c9e3eeefb99a3) + checkEq(xor(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0x0) + checkEq(xor(0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0xf1807671b3c978954b1c9fe02e236a07f94ad6aa8256fd63507892e2ec7647ac) + checkEq(xor(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x0), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe) + checkEq(xor(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x1), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cff) + checkEq(xor(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x2), 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfc) + checkEq(xor(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff), 0x9f22c89c1961b95bf3e5523e86229c490cccca71f0db962b1f01fb9730f0a301) + checkEq(xor(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe), 0x9f22c89c1961b95bf3e5523e86229c490cccca71f0db962b1f01fb9730f0a300) + checkEq(xor(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x3a0cfc00500ce4615f4e646f6f46d94a91965aee97d42b11d18a08b4cd8282f1), 0x5ad1cb63b692a2c55354c9ae169bbafc62a56f6098f042c531740cdc028dde0f) + checkEq(xor(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x915d411255573e314706322157fe09b10a79e3248d7294b7b086968a23791b52), 0xf1807671b3c978954b1c9fe02e236a07f94ad6aa8256fd63507892e2ec7647ac) + checkEq(xor(0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe, 0x60dd3763e69e46a40c1aadc179dd63b6f333358e0f2469d4e0fe0468cf0f5cfe), 0x0) } // ==== // maxTraceSize: 0 From 9b8ab443ce8b7dc40109dbeafb72788d9e4952dd Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 22:02:58 +0700 Subject: [PATCH 089/101] Add DATALOADN to PureEVMInstructionInterpreter --- libyul/interpreter/PureEVMInstructionInterpreter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp index fb8b6f28595a..e6cd91c3e8a8 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -184,6 +184,7 @@ EvaluationResult PureEVMInstructionInterpreter::eval( case Instruction::TSTORE: return ImpureBuiltinEncountered(); // --------------- calls --------------- + case Instruction::DATALOADN: case Instruction::CREATE: case Instruction::CREATE2: case Instruction::CALL: From 15cbd51290d8a95d91c806a6cf2450d87ce67e3a Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 22:20:31 +0700 Subject: [PATCH 090/101] Adapt to new EOF changes --- .../interpreter/PureEVMInstructionInterpreter.cpp | 2 +- libyul/interpreter/PureInterpreter.cpp | 14 +++++++++----- test/libyul/YulPureInterpreterTest.cpp | 5 ++++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp index e6cd91c3e8a8..4ebb63dc37e0 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -285,7 +285,7 @@ EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( if (_builtinFunction.instruction) return eval(*_builtinFunction.instruction, _evaluatedArguments); - std::string functionName = _builtinFunction.name.str(); + std::string const& functionName = _builtinFunction.name; bool isVerbatim = boost::starts_with(functionName, "verbatim"); if (isVerbatim) return ImpureBuiltinEncountered(); diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index 7442f7cafd84..1217436b54ef 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -247,9 +247,12 @@ EvaluationResult PureInterpreter::operator()(Identifier const& _identifier) EvaluationResult PureInterpreter::operator()(FunctionCall const& _functionCall) { std::vector> const* literalArguments = nullptr; - if (BuiltinFunction const* builtin = m_dialect.builtin(_functionCall.functionName.name)) - if (!builtin->literalArguments.empty()) - literalArguments = &builtin->literalArguments; + if (std::optional builtinHandle = m_dialect.findBuiltin(_functionCall.functionName.name.str())) + if ( + auto const& args = m_dialect.builtin(*builtinHandle).literalArguments; + !args.empty() + ) + literalArguments = &args; EvaluationResult argsRes = evaluateArgs(_functionCall.arguments, literalArguments); if (auto* terminated = std::get_if(&argsRes)) return *terminated; @@ -258,10 +261,11 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _functionCall) if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) { - if (BuiltinFunctionForEVM const* builtinFunction = dialect->builtin(_functionCall.functionName.name)) + if (std::optional builtinHandle = dialect->findBuiltin(_functionCall.functionName.name.str())) { + auto const& function = dialect->builtin(*builtinHandle); PureEVMInstructionInterpreter interpreter(dialect->evmVersion()); - return interpreter.evalBuiltin(*builtinFunction, _functionCall.arguments, argsValues); + return interpreter.evalBuiltin(function, _functionCall.arguments, argsValues); } } diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index 38675edc7df8..78978c44c3c7 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -104,7 +104,10 @@ std::string YulPureInterpreterTest::interpret() const Block const& block = m_ast->root(); PureInterpreterState state{m_config}; - Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects(solidity::test::CommonOptions::get().evmVersion()); + Dialect const& dialect = EVMDialect::strictAssemblyForEVMObjects( + solidity::test::CommonOptions::get().evmVersion(), + solidity::test::CommonOptions::get().eofVersion() + ); interpreter::Scope rootScope; interpreter::Scope* subscope = rootScope.getSubscope(block); From b068bc4233adbcc0b356cd0a7f4a1e016bb6e4c9 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 23:10:03 +0700 Subject: [PATCH 091/101] Use boost::outcome --- libyul/interpreter/PureInterpreter.cpp | 108 +++++++------------- libyul/interpreter/PureInterpreter.h | 4 +- libyul/interpreter/PureInterpreterState.cpp | 1 - libyul/interpreter/PureInterpreterState.h | 9 +- libyul/interpreter/Results.h | 5 +- test/libyul/YulPureInterpreterTest.cpp | 27 +++-- 6 files changed, 61 insertions(+), 93 deletions(-) diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index 1217436b54ef..3af5683f41ef 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -33,32 +33,25 @@ #include #include - -#include -#include - using namespace solidity; using namespace solidity::yul; using namespace solidity::yul::interpreter; +namespace outcome = BOOST_OUTCOME_V2_NAMESPACE; using solidity::util::h256; ExecutionResult PureInterpreter::operator()(ExpressionStatement const& _expressionStatement) { - EvaluationResult result = evaluate(_expressionStatement.expression, 0); - if (auto* terminated = std::get_if(&result)) - return *terminated; + BOOST_OUTCOME_TRY(evaluate(_expressionStatement.expression, 0)); return ExecutionOk{ControlFlowState::Default}; } ExecutionResult PureInterpreter::operator()(Assignment const& _assignment) { solAssert(_assignment.value); - EvaluationResult evalResult = evaluate(*_assignment.value, _assignment.variableNames.size()); - if (auto* terminated = std::get_if(&evalResult)) - return *terminated; + BOOST_OUTCOME_TRY(EvaluationOk evalResult, evaluate(*_assignment.value, _assignment.variableNames.size())); - std::vector const& values = std::move(std::get(evalResult).values); + std::vector const& values = std::move(evalResult.values); for (size_t i = 0; i < values.size(); ++i) { YulName varName = _assignment.variableNames.at(i).name; @@ -73,10 +66,8 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat std::vector values; if (_declaration.value) { - EvaluationResult evalResult = evaluate(*_declaration.value, _declaration.variables.size()); - if (auto* terminated = std::get_if(&evalResult)) - return *terminated; - values = std::move(std::get(evalResult).values); + BOOST_OUTCOME_TRY(EvaluationOk evalResult, evaluate(*_declaration.value, _declaration.variables.size())); + values = std::move(evalResult.values); } else { @@ -97,11 +88,9 @@ ExecutionResult PureInterpreter::operator()(VariableDeclaration const& _declarat ExecutionResult PureInterpreter::operator()(If const& _if) { solAssert(_if.condition); - EvaluationResult conditionResult = evaluate(*_if.condition, 1); - if (auto* terminated = std::get_if(&conditionResult)) - return *terminated; + BOOST_OUTCOME_TRY(EvaluationOk conditionResult, evaluate(*_if.condition, 1)); - if (std::get(conditionResult).values.at(0) != 0) + if (conditionResult.values.at(0) != 0) return (*this)(_if.body); return ExecutionOk{ControlFlowState::Default}; } @@ -111,11 +100,9 @@ ExecutionResult PureInterpreter::operator()(Switch const& _switch) solAssert(_switch.expression); solAssert(!_switch.cases.empty()); - EvaluationResult expressionResult = evaluate(*_switch.expression, 1); - if (auto* terminated = std::get_if(&expressionResult)) - return *terminated; + BOOST_OUTCOME_TRY(EvaluationOk expressionResult, evaluate(*_switch.expression, 1)); - u256 expressionValue = std::get(expressionResult).values.at(0); + u256 expressionValue = expressionResult.values.at(0); for (auto const& currentCase: _switch.cases) { bool caseMatched = false; @@ -123,10 +110,8 @@ ExecutionResult PureInterpreter::operator()(Switch const& _switch) if (!currentCase.value) caseMatched = true; else { - EvaluationResult caseResult = evaluate(*currentCase.value, 1); - if (auto* terminated = std::get_if(&caseResult)) - return *terminated; - caseMatched = std::get(caseResult).values.at(0) == expressionValue; + BOOST_OUTCOME_TRY(EvaluationOk caseResult, evaluate(*currentCase.value, 1)); + caseMatched = caseResult.values.at(0) == expressionValue; } if (caseMatched) return (*this)(currentCase.body); @@ -154,37 +139,30 @@ ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) while (true) { { - EvaluationResult conditionResult = evaluate(*_forLoop.condition, 1); - if (auto* terminated = std::get_if(&conditionResult)) - return *terminated; - if (std::get(conditionResult).values.at(0) == 0) + BOOST_OUTCOME_TRY(EvaluationOk conditionResult, evaluate(*_forLoop.condition, 1)); + if (conditionResult.values.at(0) == 0) break; } // Increment step for each loop iteration for loops with // an empty body and post blocks to prevent a deadlock. if (_forLoop.body.statements.size() == 0 && _forLoop.post.statements.size() == 0) - if (auto terminated = incrementStatementStep()) - return *terminated; + { + BOOST_OUTCOME_TRY(incrementStatementStep()); + } { - ExecutionResult bodyResult = (*this)(_forLoop.body); - if ( - std::holds_alternative(bodyResult) || - bodyResult == ExecutionResult(ExecutionOk{ControlFlowState::Leave}) - ) + BOOST_OUTCOME_TRY(ExecutionOk bodyResult, (*this)(_forLoop.body)); + if (bodyResult == ExecutionOk{ControlFlowState::Leave}) return bodyResult; - if (bodyResult == ExecutionResult(ExecutionOk{ControlFlowState::Break})) + if (bodyResult == ExecutionOk{ControlFlowState::Break}) return ExecutionOk{ControlFlowState::Default}; } { - ExecutionResult postResult = (*this)(_forLoop.post); - if ( - std::holds_alternative(postResult) || - postResult == ExecutionResult(ExecutionOk{ControlFlowState::Leave}) - ) + BOOST_OUTCOME_TRY(ExecutionOk postResult, (*this)(_forLoop.post)); + if (postResult == ExecutionOk{ControlFlowState::Leave}) return postResult; } } @@ -227,8 +205,7 @@ ExecutionResult PureInterpreter::execute(std::vector const& _statemen ExecutionResult PureInterpreter::visit(Statement const& _statement) { - if (auto terminated = incrementStatementStep()) - return *terminated; + BOOST_OUTCOME_TRY(incrementStatementStep()); return std::visit(*this, _statement); } @@ -253,11 +230,9 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _functionCall) !args.empty() ) literalArguments = &args; - EvaluationResult argsRes = evaluateArgs(_functionCall.arguments, literalArguments); - if (auto* terminated = std::get_if(&argsRes)) - return *terminated; + BOOST_OUTCOME_TRY(EvaluationOk argsRes, evaluateArgs(_functionCall.arguments, literalArguments)); - std::vector argsValues = std::move(std::get(argsRes).values); + std::vector const& argsValues = argsRes.values; if (EVMDialect const* dialect = dynamic_cast(&m_dialect)) { @@ -280,37 +255,30 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _functionCall) std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); - if (auto terminated = m_state.addTrace(functionDefinition, argsValues)) - return *terminated; + BOOST_OUTCOME_TRY(m_state.addTrace(functionDefinition, argsValues)); - ExecutionResult functionBodyResult = (*interpreter)(functionDefinition.body); - if (auto* terminated = std::get_if(&functionBodyResult)) - return *terminated; + BOOST_OUTCOME_TRY((*interpreter)(functionDefinition.body)); std::vector returnedValues; returnedValues.reserve(functionDefinition.returnVariables.size()); for (auto const& retVar: functionDefinition.returnVariables) returnedValues.emplace_back(interpreter->valueOfVariable(retVar.name)); - if (auto terminated = m_state.addTrace(functionDefinition, returnedValues)) - return *terminated; + BOOST_OUTCOME_TRY(m_state.addTrace(functionDefinition, returnedValues)); return EvaluationOk(std::move(returnedValues)); } EvaluationResult PureInterpreter::visit(Expression const& _expression) { - if (auto terminated = incrementExpressionStep()) - return *terminated; + BOOST_OUTCOME_TRY(incrementExpressionStep()); return std::visit(*this, _expression); } EvaluationResult PureInterpreter::evaluate(Expression const& _expression, size_t _numReturnVars) { - EvaluationResult result = visit(_expression); - if (auto* resOk = std::get_if(&result)) - yulAssert(resOk->values.size() == _numReturnVars); - + BOOST_OUTCOME_TRY(EvaluationOk result, visit(_expression)); + yulAssert(result.values.size() == _numReturnVars); return result; } @@ -328,10 +296,8 @@ EvaluationResult PureInterpreter::evaluateArgs( bool isLiteral = _literalArguments && _literalArguments->at(i); if (!isLiteral) { - EvaluationResult exprRes = evaluate(currentArgument, 1); - if (auto* terminated = std::get_if(&exprRes)) - return *terminated; - std::vector const& exprValues = std::get(exprRes).values; + BOOST_OUTCOME_TRY(EvaluationOk exprRes, evaluate(currentArgument, 1)); + std::vector const& exprValues = exprRes.values; values[i] = exprValues.at(0); } else @@ -357,7 +323,7 @@ void PureInterpreter::leaveScope() yulAssert(m_scope); } -std::optional PureInterpreter::incrementStatementStep() +outcome::result PureInterpreter::incrementStatementStep() { m_state.numSteps++; if (m_state.config.maxSteps > 0 && m_state.numSteps >= m_state.config.maxSteps) @@ -370,13 +336,13 @@ std::optional PureInterpreter::incrementStatementStep() // Reset m_expressionNestingLevel, preparing for new expression. m_expressionNestingLevel = 0; - return std::nullopt; + return outcome::success(); } -std::optional PureInterpreter::incrementExpressionStep() +outcome::result PureInterpreter::incrementExpressionStep() { m_expressionNestingLevel++; if (m_state.config.maxExprNesting > 0 && m_expressionNestingLevel > m_state.config.maxExprNesting) return ExpressionNestingLimitReached(); - return std::nullopt; + return outcome::success(); } diff --git a/libyul/interpreter/PureInterpreter.h b/libyul/interpreter/PureInterpreter.h index eb9f9dba4b05..a4fbb23e46f1 100644 --- a/libyul/interpreter/PureInterpreter.h +++ b/libyul/interpreter/PureInterpreter.h @@ -128,12 +128,12 @@ class PureInterpreter /// Increment interpreter step count, returning StepLimitReached if step /// limit is reached. - std::optional incrementStatementStep(); + BOOST_OUTCOME_V2_NAMESPACE::result incrementStatementStep(); /// Increment evaluation count, returning ExpressionNestingLimitReached if /// the nesting level is beyond the upper bound configured in the /// interpreter state. - std::optional incrementExpressionStep(); + BOOST_OUTCOME_V2_NAMESPACE::result incrementExpressionStep(); Dialect const& m_dialect; PureInterpreterState& m_state; diff --git a/libyul/interpreter/PureInterpreterState.cpp b/libyul/interpreter/PureInterpreterState.cpp index 8949ab62399a..5905d6c157a8 100644 --- a/libyul/interpreter/PureInterpreterState.cpp +++ b/libyul/interpreter/PureInterpreterState.cpp @@ -25,7 +25,6 @@ #include #include -#include using namespace solidity::yul::interpreter; diff --git a/libyul/interpreter/PureInterpreterState.h b/libyul/interpreter/PureInterpreterState.h index 282accfeea8f..26e5bfb453ae 100644 --- a/libyul/interpreter/PureInterpreterState.h +++ b/libyul/interpreter/PureInterpreterState.h @@ -27,6 +27,7 @@ #include #include #include +#include namespace solidity::yul::interpreter { @@ -82,13 +83,15 @@ struct PureInterpreterState /// Will do nothing if config.maxTraceSize == 0 /// - the log entry will not be constructed in this case template - std::optional addTrace(Args const&... _args) + BOOST_OUTCOME_V2_NAMESPACE::result addTrace(Args const&... _args) { - if (config.maxTraceSize == 0) return std::nullopt; + namespace outcome = BOOST_OUTCOME_V2_NAMESPACE; + + if (config.maxTraceSize == 0) return outcome::success(); if (traces.size() > config.maxTraceSize) return TraceLimitReached(); traces.emplace_back(std::in_place_type, _args...); - return std::nullopt; + return outcome::success(); } void dumpTraces(std::ostream& _out) const; diff --git a/libyul/interpreter/Results.h b/libyul/interpreter/Results.h index 6fa89c4f5f78..9b9304cd3c31 100644 --- a/libyul/interpreter/Results.h +++ b/libyul/interpreter/Results.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include @@ -118,7 +119,7 @@ struct EvaluationOk } }; -using ExecutionResult = std::variant; -using EvaluationResult = std::variant; +using ExecutionResult = BOOST_OUTCOME_V2_NAMESPACE::result; +using EvaluationResult = BOOST_OUTCOME_V2_NAMESPACE::result; } diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index 78978c44c3c7..577bc6f59715 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -145,20 +145,19 @@ void YulPureInterpreterTest::dumpExecutionData( void YulPureInterpreterTest::dumpExecutionResult(std::ostream& _stream, interpreter::ExecutionResult _result) const { - _stream << std::visit(GenericVisitor { - [&](ExecutionOk) { return "ExecutionOk"; }, - [&](ExecutionTerminated terminated) { - return std::visit(GenericVisitor{ - [&](ExplicitlyTerminated) { return "ExplicitlyTerminated"; }, - [&](StepLimitReached) { return "StepLimitReached"; }, - [&](RecursionDepthLimitReached) { return "RecursionDepthLimitReached"; }, - [&](ExpressionNestingLimitReached) { return "ExpressionNestingLimitReached"; }, - [&](ImpureBuiltinEncountered) { return "ImpureBuiltinEncountered"; }, - [&](UnlimitedLiteralEncountered) { return "UnlimitedLiteralEncountered"; }, - [&](TraceLimitReached) { return "TraceLimitReached"; } - }, terminated); - } - }, _result); + if (_result) { + _stream << "ExecutionOk"; + } else { + _stream << std::visit(GenericVisitor { + [&](ExplicitlyTerminated) { return "ExplicitlyTerminated"; }, + [&](StepLimitReached) { return "StepLimitReached"; }, + [&](RecursionDepthLimitReached) { return "RecursionDepthLimitReached"; }, + [&](ExpressionNestingLimitReached) { return "ExpressionNestingLimitReached"; }, + [&](ImpureBuiltinEncountered) { return "ImpureBuiltinEncountered"; }, + [&](UnlimitedLiteralEncountered) { return "UnlimitedLiteralEncountered"; }, + [&](TraceLimitReached) { return "TraceLimitReached"; } + }, _result.error()); + } } void YulPureInterpreterTest::dumpVariables( From 7980df8188b2643c397dad13a45777267d3bf022 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 23:15:16 +0700 Subject: [PATCH 092/101] Change makeInterpreterCopy to allocate on stack --- libyul/interpreter/PureInterpreter.cpp | 6 +++--- libyul/interpreter/PureInterpreter.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index 3af5683f41ef..621633b72148 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -253,16 +253,16 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _functionCall) for (size_t i = 0; i < functionDefinition.returnVariables.size(); ++i) variables[functionDefinition.returnVariables.at(i).name] = 0; - std::unique_ptr interpreter = makeInterpreterCopy(std::move(variables)); + PureInterpreter interpreter = makeInterpreterCopy(std::move(variables)); BOOST_OUTCOME_TRY(m_state.addTrace(functionDefinition, argsValues)); - BOOST_OUTCOME_TRY((*interpreter)(functionDefinition.body)); + BOOST_OUTCOME_TRY(interpreter(functionDefinition.body)); std::vector returnedValues; returnedValues.reserve(functionDefinition.returnVariables.size()); for (auto const& retVar: functionDefinition.returnVariables) - returnedValues.emplace_back(interpreter->valueOfVariable(retVar.name)); + returnedValues.emplace_back(interpreter.valueOfVariable(retVar.name)); BOOST_OUTCOME_TRY(m_state.addTrace(functionDefinition, returnedValues)); diff --git a/libyul/interpreter/PureInterpreter.h b/libyul/interpreter/PureInterpreter.h index a4fbb23e46f1..c775535d1308 100644 --- a/libyul/interpreter/PureInterpreter.h +++ b/libyul/interpreter/PureInterpreter.h @@ -102,9 +102,9 @@ class PureInterpreter VariableValuesMap const& allVariables() const { return m_variables; } protected: - std::unique_ptr makeInterpreterCopy(VariableValuesMap _variables = {}) const + PureInterpreter makeInterpreterCopy(VariableValuesMap _variables = {}) const { - return std::make_unique( + return PureInterpreter( m_state, m_dialect, *m_scope, From bd0164964514e3c6a01c61fa4a237cdd202bfb80 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 23:17:23 +0700 Subject: [PATCH 093/101] Replace hardcoded builtin with ImpureBuiltinEncountered error --- .../PureEVMInstructionInterpreter.cpp | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp index 4ebb63dc37e0..e5d8efbf8777 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -285,24 +285,6 @@ EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( if (_builtinFunction.instruction) return eval(*_builtinFunction.instruction, _evaluatedArguments); - std::string const& functionName = _builtinFunction.name; - bool isVerbatim = boost::starts_with(functionName, "verbatim"); - if (isVerbatim) - return ImpureBuiltinEncountered(); - - static std::set const NON_INSTRUCTION_BUILTIN_NAME = { - "datasize", - "dataoffset", - "datacopy", - "memoryguard", - "loadimmutable", - "setimmutable", - "linkersymbol" - }; - if (NON_INSTRUCTION_BUILTIN_NAME.count(functionName)) - return ImpureBuiltinEncountered(); - - yulAssert(false, "Unknown builtin: " + functionName); - return EvaluationOk(0); + return ImpureBuiltinEncountered(); } From 014f66e2a19f2bb2907ef7d16d991daafb8d867f Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 23:29:07 +0700 Subject: [PATCH 094/101] Make PureEVMInstructionInterpreter just a function --- .../PureEVMInstructionInterpreter.cpp | 27 ++++++--------- .../PureEVMInstructionInterpreter.h | 33 ++++--------------- libyul/interpreter/PureInterpreter.cpp | 3 +- 3 files changed, 18 insertions(+), 45 deletions(-) diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp index e5d8efbf8777..cc34078c49f7 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -41,22 +41,26 @@ using namespace solidity::evmasm; using namespace solidity::yul; using namespace solidity::yul::interpreter; +namespace solidity::yul::interpreter::PureEVMInstructionInterpreter { + using solidity::util::h160; using solidity::util::h256; -EvaluationResult PureEVMInstructionInterpreter::eval( - evmasm::Instruction _instruction, +EvaluationResult eval( + langutil::EVMVersion _evmVersion, + BuiltinFunctionForEVM const& _builtinFunction, std::vector const& _arguments ) { - using namespace solidity::evmasm; - using evmasm::Instruction; + if (!_builtinFunction.instruction) + return ImpureBuiltinEncountered(); + evmasm::Instruction instruction = *_builtinFunction.instruction; - auto info = instructionInfo(_instruction, m_evmVersion); + auto info = instructionInfo(instruction, _evmVersion); yulAssert(static_cast(info.args) == _arguments.size()); auto const& arg = _arguments; - switch (_instruction) + switch (instruction) { case Instruction::STOP: return ExplicitlyTerminated(); @@ -276,15 +280,4 @@ EvaluationResult PureEVMInstructionInterpreter::eval( util::unreachable(); } -EvaluationResult PureEVMInstructionInterpreter::evalBuiltin( - BuiltinFunctionForEVM const& _builtinFunction, - std::vector const& /* _arguments */, // This was required to execute some builtin. - std::vector const& _evaluatedArguments -) -{ - if (_builtinFunction.instruction) - return eval(*_builtinFunction.instruction, _evaluatedArguments); - - return ImpureBuiltinEncountered(); } - diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.h b/libyul/interpreter/PureEVMInstructionInterpreter.h index 859523b1becd..a4a941076856 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.h +++ b/libyul/interpreter/PureEVMInstructionInterpreter.h @@ -45,32 +45,13 @@ class YulString; struct BuiltinFunctionForEVM; } -namespace solidity::yul::interpreter +namespace solidity::yul::interpreter::PureEVMInstructionInterpreter { -/** - * Interprets EVM instructions based on the current state without side-effect. - */ -class PureEVMInstructionInterpreter -{ -public: - explicit PureEVMInstructionInterpreter(langutil::EVMVersion _evmVersion): - m_evmVersion(_evmVersion) - {} - - /// Evaluate instruction - EvaluationResult eval(evmasm::Instruction _instruction, std::vector const& _arguments); +EvaluationResult eval( + langutil::EVMVersion _evmVersion, + BuiltinFunctionForEVM const& _builtinFunction, + std::vector const& _arguments +); - /// Evaluate builtin function - EvaluationResult evalBuiltin( - BuiltinFunctionForEVM const& _builtinFunction, - std::vector const& _arguments, - std::vector const& _evaluatedArguments - ); - -private: - - langutil::EVMVersion m_evmVersion; -}; - -} // solidity::yul::test +} diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index 621633b72148..575102fdfb9c 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -239,8 +239,7 @@ EvaluationResult PureInterpreter::operator()(FunctionCall const& _functionCall) if (std::optional builtinHandle = dialect->findBuiltin(_functionCall.functionName.name.str())) { auto const& function = dialect->builtin(*builtinHandle); - PureEVMInstructionInterpreter interpreter(dialect->evmVersion()); - return interpreter.evalBuiltin(function, _functionCall.arguments, argsValues); + return PureEVMInstructionInterpreter::eval(dialect->evmVersion(), function, argsValues); } } From 282718e0e0c5ec9cbb818550a2fb5062bd8f32cf Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 23:35:04 +0700 Subject: [PATCH 095/101] Return UnlimitedLiteralEncountered early --- libyul/interpreter/PureInterpreter.cpp | 24 ++++--------------- libyul/interpreter/PureInterpreter.h | 5 +--- .../impure_instructions/memoryguard.yul | 2 +- 3 files changed, 7 insertions(+), 24 deletions(-) diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index 575102fdfb9c..64b4a9ae4228 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -223,14 +223,13 @@ EvaluationResult PureInterpreter::operator()(Identifier const& _identifier) EvaluationResult PureInterpreter::operator()(FunctionCall const& _functionCall) { - std::vector> const* literalArguments = nullptr; if (std::optional builtinHandle = m_dialect.findBuiltin(_functionCall.functionName.name.str())) if ( auto const& args = m_dialect.builtin(*builtinHandle).literalArguments; !args.empty() ) - literalArguments = &args; - BOOST_OUTCOME_TRY(EvaluationOk argsRes, evaluateArgs(_functionCall.arguments, literalArguments)); + return UnlimitedLiteralEncountered(); + BOOST_OUTCOME_TRY(EvaluationOk argsRes, evaluateArgs(_functionCall.arguments)); std::vector const& argsValues = argsRes.values; @@ -282,8 +281,7 @@ EvaluationResult PureInterpreter::evaluate(Expression const& _expression, size_t } EvaluationResult PureInterpreter::evaluateArgs( - std::vector const& _arguments, - std::vector> const* _literalArguments + std::vector const& _arguments ) { std::vector values(_arguments.size()); @@ -292,20 +290,8 @@ EvaluationResult PureInterpreter::evaluateArgs( for (size_t i = _arguments.size(); i-- > 0; ) { auto const& currentArgument = _arguments[i]; - bool isLiteral = _literalArguments && _literalArguments->at(i); - if (!isLiteral) - { - BOOST_OUTCOME_TRY(EvaluationOk exprRes, evaluate(currentArgument, 1)); - std::vector const& exprValues = exprRes.values; - values[i] = exprValues.at(0); - } - else - { - if (std::get(currentArgument).value.unlimited()) - return UnlimitedLiteralEncountered(); - else - values[i] = std::get(currentArgument).value.value(); - } + BOOST_OUTCOME_TRY(EvaluationOk exprRes, evaluate(currentArgument, 1)); + values[i] = exprRes.values.at(0); } return EvaluationOk(std::move(values)); } diff --git a/libyul/interpreter/PureInterpreter.h b/libyul/interpreter/PureInterpreter.h index c775535d1308..517a199d52c2 100644 --- a/libyul/interpreter/PureInterpreter.h +++ b/libyul/interpreter/PureInterpreter.h @@ -118,10 +118,7 @@ class PureInterpreter /// Evaluates the given expression from right to left and /// stores it in m_value. - EvaluationResult evaluateArgs( - std::vector const& _arguments, - std::vector> const* _literalArguments - ); + EvaluationResult evaluateArgs(std::vector const& _arguments); void enterScope(Block const& _block); void leaveScope(); diff --git a/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul b/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul index e3f6bc5d5d78..968f91706559 100644 --- a/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul +++ b/test/libyul/yulPureInterpreterTests/impure_instructions/memoryguard.yul @@ -7,7 +7,7 @@ object "obj" { } } // ---- -// Execution result: ImpureBuiltinEncountered +// Execution result: UnlimitedLiteralEncountered // Outer most variable values: // x = 1 // From 6b7fd780d20a1b95f7838c0880bc0e8f7b11c5d9 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 23:39:45 +0700 Subject: [PATCH 096/101] Default initialization for fields --- libyul/interpreter/PureInterpreter.h | 4 ++-- libyul/interpreter/PureInterpreterState.h | 8 ++++---- libyul/interpreter/Results.h | 2 +- libyul/interpreter/Scope.h | 11 ++++------- 4 files changed, 11 insertions(+), 14 deletions(-) diff --git a/libyul/interpreter/PureInterpreter.h b/libyul/interpreter/PureInterpreter.h index 517a199d52c2..59c9d640da36 100644 --- a/libyul/interpreter/PureInterpreter.h +++ b/libyul/interpreter/PureInterpreter.h @@ -138,8 +138,8 @@ class PureInterpreter VariableValuesMap m_variables; Scope* m_scope; - size_t const m_recursionDepth = 0; - unsigned m_expressionNestingLevel = 0; + size_t const m_recursionDepth{}; + unsigned m_expressionNestingLevel{}; }; } diff --git a/libyul/interpreter/PureInterpreterState.h b/libyul/interpreter/PureInterpreterState.h index 26e5bfb453ae..61f88c5d7afe 100644 --- a/libyul/interpreter/PureInterpreterState.h +++ b/libyul/interpreter/PureInterpreterState.h @@ -65,11 +65,11 @@ using LogTraceEntry = std::variant; struct PureInterpreterConfig { // set to 0 to disable tracing - size_t maxTraceSize = 0; + size_t maxTraceSize{}; - size_t maxSteps = 0; - size_t maxExprNesting = 0; - size_t maxRecursionDepth = 0; + size_t maxSteps{}; + size_t maxExprNesting{}; + size_t maxRecursionDepth{}; }; struct PureInterpreterState diff --git a/libyul/interpreter/Results.h b/libyul/interpreter/Results.h index 9b9304cd3c31..bc09cd20ffb1 100644 --- a/libyul/interpreter/Results.h +++ b/libyul/interpreter/Results.h @@ -83,7 +83,7 @@ enum class ControlFlowState struct ExecutionOk { - ControlFlowState state; + ControlFlowState state{}; bool operator==(ExecutionOk other) const { diff --git a/libyul/interpreter/Scope.h b/libyul/interpreter/Scope.h index bf7df5dc1094..9d988cc9c2e9 100644 --- a/libyul/interpreter/Scope.h +++ b/libyul/interpreter/Scope.h @@ -37,9 +37,6 @@ class Scope { public: Scope(Scope* const _parent = nullptr): - m_definedFunctions(), - m_declaredVariables(), - m_subScopes(), m_parent(_parent) {} @@ -59,10 +56,10 @@ class Scope FunctionDefinition const& getFunction(YulName const& _functionName) const; private: - std::map m_definedFunctions; - std::vector m_declaredVariables; - std::map> m_subScopes; - Scope* const m_parent; + std::map m_definedFunctions{}; + std::vector m_declaredVariables{}; + std::map> m_subScopes{}; + Scope* const m_parent{}; }; } From a5eeeded5499cbc401757e91cf8697fe44cb0a2c Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 23:45:24 +0700 Subject: [PATCH 097/101] Move function initialization part of scope to scope's constructor --- libyul/interpreter/Scope.cpp | 19 +++++++++++-------- libyul/interpreter/Scope.h | 2 ++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/libyul/interpreter/Scope.cpp b/libyul/interpreter/Scope.cpp index 33343c7fd094..7258c23ebf60 100644 --- a/libyul/interpreter/Scope.cpp +++ b/libyul/interpreter/Scope.cpp @@ -26,20 +26,23 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::yul::interpreter; +Scope::Scope(Scope* const _parent, Block const& _block) + : m_parent(_parent) +{ + for (auto const& statement: _block.statements) + if (auto const* functionDefinition = std::get_if(&statement)) + m_definedFunctions.emplace(functionDefinition->name, *functionDefinition); +} + Scope* Scope::getSubscope(Block const& _block) { auto [it, isNew] = m_subScopes.try_emplace(&_block, nullptr); if (!isNew) return it->second.get(); - it->second = std::make_unique(this); - Scope* subscope = it->second.get(); - - for (auto const& statement: _block.statements) - if (auto const* functionDefinition = std::get_if(&statement)) - subscope->m_definedFunctions.emplace(functionDefinition->name, *functionDefinition); - - return subscope; + auto& subScope = it->second; + subScope = std::make_unique(this, _block); + return subScope.get(); } void Scope::addDeclaredVariable(YulName const& _name) diff --git a/libyul/interpreter/Scope.h b/libyul/interpreter/Scope.h index 9d988cc9c2e9..200071a5cebe 100644 --- a/libyul/interpreter/Scope.h +++ b/libyul/interpreter/Scope.h @@ -40,6 +40,8 @@ class Scope m_parent(_parent) {} + Scope(Scope* const _parent, Block const& _block); + Scope* parent() const { return m_parent; From 407daf4fa5167f247cc821117ef55ab6ad0c2eb1 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 23:47:15 +0700 Subject: [PATCH 098/101] Rename getSubscope -> createSubscope --- libyul/interpreter/PureInterpreter.cpp | 2 +- libyul/interpreter/Scope.cpp | 2 +- libyul/interpreter/Scope.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index 64b4a9ae4228..b763c0bccf2d 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -298,7 +298,7 @@ EvaluationResult PureInterpreter::evaluateArgs( void PureInterpreter::enterScope(Block const& _block) { - m_scope = m_scope->getSubscope(_block); + m_scope = m_scope->createSubscope(_block); } void PureInterpreter::leaveScope() diff --git a/libyul/interpreter/Scope.cpp b/libyul/interpreter/Scope.cpp index 7258c23ebf60..dfdca51a9ff9 100644 --- a/libyul/interpreter/Scope.cpp +++ b/libyul/interpreter/Scope.cpp @@ -34,7 +34,7 @@ Scope::Scope(Scope* const _parent, Block const& _block) m_definedFunctions.emplace(functionDefinition->name, *functionDefinition); } -Scope* Scope::getSubscope(Block const& _block) +Scope* Scope::createSubscope(Block const& _block) { auto [it, isNew] = m_subScopes.try_emplace(&_block, nullptr); if (!isNew) diff --git a/libyul/interpreter/Scope.h b/libyul/interpreter/Scope.h index 200071a5cebe..d1a5d275be42 100644 --- a/libyul/interpreter/Scope.h +++ b/libyul/interpreter/Scope.h @@ -47,7 +47,7 @@ class Scope return m_parent; } - Scope* getSubscope(Block const& _block); + Scope* createSubscope(Block const& _block); void addDeclaredVariable(YulName const& _name); From 1ac52aa9d8d1ebf2cc4ab34752b7e645f9d5e674 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 23:47:24 +0700 Subject: [PATCH 099/101] Initialize test subscope with block in test suite --- test/libyul/YulPureInterpreterTest.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/libyul/YulPureInterpreterTest.cpp b/test/libyul/YulPureInterpreterTest.cpp index 577bc6f59715..ff0bdf43d6b9 100644 --- a/test/libyul/YulPureInterpreterTest.cpp +++ b/test/libyul/YulPureInterpreterTest.cpp @@ -108,10 +108,9 @@ std::string YulPureInterpreterTest::interpret() const solidity::test::CommonOptions::get().evmVersion(), solidity::test::CommonOptions::get().eofVersion() ); - interpreter::Scope rootScope; - interpreter::Scope* subscope = rootScope.getSubscope(block); + interpreter::Scope rootScope(nullptr, block); - PureInterpreter interpreter(state, dialect, *subscope, 0); + PureInterpreter interpreter(state, dialect, rootScope, 0); ExecutionResult result = interpreter.execute(block.statements); VariableValuesMap const& outerMostVariables = interpreter.allVariables(); From 101cb6bee87f24d3e8d1fa9727480f0ecc6aebb4 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Thu, 24 Oct 2024 23:50:51 +0700 Subject: [PATCH 100/101] Remove operator== of Terminated outcome --- libyul/interpreter/PureInterpreter.cpp | 8 ++++---- libyul/interpreter/Results.h | 23 +++++++---------------- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index b763c0bccf2d..7ccee7d9ee55 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -132,8 +132,8 @@ ExecutionResult PureInterpreter::operator()(ForLoop const& _forLoop) ScopeGuard g([this]{ leaveScope(); }); { - ExecutionResult preResult = execute(_forLoop.pre.statements); - if (preResult == ExecutionResult(ExecutionOk{ControlFlowState::Leave})) + BOOST_OUTCOME_TRY(ExecutionOk preResult, execute(_forLoop.pre.statements)); + if (preResult == ExecutionOk{ControlFlowState::Leave}) return preResult; } while (true) @@ -196,8 +196,8 @@ ExecutionResult PureInterpreter::execute(std::vector const& _statemen { for (auto const& statement: _statements) { - ExecutionResult statementRes = visit(statement); - if (statementRes != ExecutionResult(ExecutionOk{ControlFlowState::Default})) + BOOST_OUTCOME_TRY(ExecutionOk statementRes, visit(statement)); + if (statementRes != ExecutionOk{ControlFlowState::Default}) return statementRes; } return ExecutionOk{ControlFlowState::Default}; diff --git a/libyul/interpreter/Results.h b/libyul/interpreter/Results.h index bc09cd20ffb1..3f1a87415f4c 100644 --- a/libyul/interpreter/Results.h +++ b/libyul/interpreter/Results.h @@ -26,43 +26,34 @@ namespace solidity::yul::interpreter { -template -class ExecutionTerminatedCommon +class ExplicitlyTerminated { -public: - bool operator==(T) const { return true; } - bool operator!=(T) const { return false; } }; -class ExplicitlyTerminated : public ExecutionTerminatedCommon +class StepLimitReached { }; -class StepLimitReached : public ExecutionTerminatedCommon +class RecursionDepthLimitReached { }; -class RecursionDepthLimitReached : public ExecutionTerminatedCommon +class ExpressionNestingLimitReached { }; -class ExpressionNestingLimitReached : public ExecutionTerminatedCommon +class ImpureBuiltinEncountered { }; -class ImpureBuiltinEncountered : public ExecutionTerminatedCommon +class UnlimitedLiteralEncountered { }; -class UnlimitedLiteralEncountered : public ExecutionTerminatedCommon +class TraceLimitReached { }; -class TraceLimitReached: public ExecutionTerminatedCommon -{ -}; - - using ExecutionTerminated = std::variant< ExplicitlyTerminated, StepLimitReached, From 559124e15693c06144623df807cffc66d137b2f7 Mon Sep 17 00:00:00 2001 From: Tran Quang Loc Date: Fri, 25 Oct 2024 00:00:28 +0700 Subject: [PATCH 101/101] Remove unused imports --- .../interpreter/PureEVMInstructionInterpreter.cpp | 13 +------------ libyul/interpreter/PureEVMInstructionInterpreter.h | 5 ----- libyul/interpreter/PureInterpreter.cpp | 4 ++++ libyul/interpreter/PureInterpreter.h | 11 ----------- 4 files changed, 5 insertions(+), 28 deletions(-) diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.cpp b/libyul/interpreter/PureEVMInstructionInterpreter.cpp index cc34078c49f7..ba3f32ab532f 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.cpp +++ b/libyul/interpreter/PureEVMInstructionInterpreter.cpp @@ -21,20 +21,9 @@ #include -#include - #include -#include -#include - -#include -#include - -#include -#include -#include -#include +#include using namespace solidity; using namespace solidity::evmasm; diff --git a/libyul/interpreter/PureEVMInstructionInterpreter.h b/libyul/interpreter/PureEVMInstructionInterpreter.h index a4a941076856..6b9ace35fabe 100644 --- a/libyul/interpreter/PureEVMInstructionInterpreter.h +++ b/libyul/interpreter/PureEVMInstructionInterpreter.h @@ -21,13 +21,8 @@ #pragma once -#include - #include -#include -#include -#include #include #include diff --git a/libyul/interpreter/PureInterpreter.cpp b/libyul/interpreter/PureInterpreter.cpp index 7ccee7d9ee55..076bbccb8dd1 100644 --- a/libyul/interpreter/PureInterpreter.cpp +++ b/libyul/interpreter/PureInterpreter.cpp @@ -30,9 +30,13 @@ #include +#include +#include #include #include +#include + using namespace solidity; using namespace solidity::yul; using namespace solidity::yul::interpreter; diff --git a/libyul/interpreter/PureInterpreter.h b/libyul/interpreter/PureInterpreter.h index 59c9d640da36..12eff2fce76b 100644 --- a/libyul/interpreter/PureInterpreter.h +++ b/libyul/interpreter/PureInterpreter.h @@ -27,17 +27,6 @@ #include #include -#include -#include - -#include - -#include -#include - -#include - -#include namespace solidity::yul {