From c0b0700540d3a8da1c6f6029d4250787c499feca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 28 Oct 2019 10:03:51 +0100 Subject: [PATCH] interpreter: Simplify exception usage Instead of using complex exception types from Aleth, throw EVMC status code in simple cases. --- libaleth-interpreter/VM.cpp | 42 ++++++-------------------------- libaleth-interpreter/VM.h | 16 ++++++------ libaleth-interpreter/VMCalls.cpp | 25 +++++++++---------- 3 files changed, 26 insertions(+), 57 deletions(-) diff --git a/libaleth-interpreter/VM.cpp b/libaleth-interpreter/VM.cpp index 567a8a253a9..37e66252c0e 100644 --- a/libaleth-interpreter/VM.cpp +++ b/libaleth-interpreter/VM.cpp @@ -39,44 +39,16 @@ evmc_result execute(evmc_vm* _instance, evmc_host_context* _context, evmc_revisi result.status_code = EVMC_SUCCESS; result.gas_left = vm->m_io_gas; } + catch (evmc_status_code statusCode) + { + result.status_code = statusCode; + } catch (dev::eth::RevertInstruction& ex) { result.status_code = EVMC_REVERT; result.gas_left = vm->m_io_gas; output = ex.output(); // This moves the output from the exception! } - catch (dev::eth::InvalidInstruction const&) - { - result.status_code = EVMC_INVALID_INSTRUCTION; - } - catch (dev::eth::BadInstruction const&) - { - result.status_code = EVMC_UNDEFINED_INSTRUCTION; - } - catch (dev::eth::OutOfStack const&) - { - result.status_code = EVMC_STACK_OVERFLOW; - } - catch (dev::eth::StackUnderflow const&) - { - result.status_code = EVMC_STACK_UNDERFLOW; - } - catch (dev::eth::BufferOverrun const&) - { - result.status_code = EVMC_INVALID_MEMORY_ACCESS; - } - catch (dev::eth::OutOfGas const&) - { - result.status_code = EVMC_OUT_OF_GAS; - } - catch (dev::eth::BadJumpDestination const&) - { - result.status_code = EVMC_BAD_JUMP_DESTINATION; - } - catch (dev::eth::DisallowedStateChange const&) - { - result.status_code = EVMC_STATIC_MODE_VIOLATION; - } catch (dev::eth::VMException const&) { result.status_code = EVMC_FAILURE; @@ -163,10 +135,10 @@ void VM::adjustStack(int _required, int _change) // adjust stack and check bounds if (m_stackEnd < m_SP + _required) - throwBadStack(_required, _change); + throwBadStack(_required); m_SPP -= _change; if (m_SPP < m_stack) - throwBadStack(_required, _change); + throwBadStack(_required); } uint64_t VM::gasForMem(intx::uint512 const& _size) @@ -1004,7 +976,7 @@ void VM::interpretCases() throwBadInstruction(); intx::uint512 const endOfAccess = intx::uint512(m_SP[1]) + intx::uint512(m_SP[2]); if (m_returnData.size() < endOfAccess) - throwBufferOverrun(endOfAccess); + throwBufferOverrun(); m_copyMemSize = toInt63(m_SP[2]); updateMem(memNeed(m_SP[0], m_SP[2])); diff --git a/libaleth-interpreter/VM.h b/libaleth-interpreter/VM.h index cff682f46a2..9b68b35be4d 100644 --- a/libaleth-interpreter/VM.h +++ b/libaleth-interpreter/VM.h @@ -119,14 +119,14 @@ class VM const evmc_tx_context& getTxContext(); - void throwOutOfGas(); - void throwInvalidInstruction(); - void throwBadInstruction(); - void throwBadJumpDestination(); - void throwBadStack(int _removed, int _added); - void throwRevertInstruction(owning_bytes_ref&& _output); - void throwDisallowedStateChange(); - void throwBufferOverrun(intx::uint512 const& _enfOfAccess); + static void throwOutOfGas(); + static void throwInvalidInstruction(); + static void throwBadInstruction(); + static void throwBadJumpDestination(); + void throwBadStack(int _removed); + static void throwRevertInstruction(owning_bytes_ref&& _output); + static void throwDisallowedStateChange(); + static void throwBufferOverrun(); std::vector m_beginSubs; std::vector m_jumpDests; diff --git a/libaleth-interpreter/VMCalls.cpp b/libaleth-interpreter/VMCalls.cpp index 56a98c42494..a53faebf73a 100644 --- a/libaleth-interpreter/VMCalls.cpp +++ b/libaleth-interpreter/VMCalls.cpp @@ -27,39 +27,38 @@ void VM::copyDataToMemory(bytesConstRef _data, intx::uint256*_sp) void VM::throwOutOfGas() { - BOOST_THROW_EXCEPTION(OutOfGas()); + throw EVMC_OUT_OF_GAS; } void VM::throwInvalidInstruction() { - BOOST_THROW_EXCEPTION(InvalidInstruction()); + throw EVMC_INVALID_INSTRUCTION; } void VM::throwBadInstruction() { - BOOST_THROW_EXCEPTION(BadInstruction()); + throw EVMC_UNDEFINED_INSTRUCTION; } void VM::throwBadJumpDestination() { - BOOST_THROW_EXCEPTION(BadJumpDestination()); + throw EVMC_BAD_JUMP_DESTINATION; } void VM::throwDisallowedStateChange() { - BOOST_THROW_EXCEPTION(DisallowedStateChange()); + throw EVMC_STATIC_MODE_VIOLATION; } // throwBadStack is called from fetchInstruction() -> adjustStack() // its the only exception that can happen before ON_OP() log is done for an opcode case in VM.cpp // so the call to m_onFail is needed here -void VM::throwBadStack(int _required, int _change) +void VM::throwBadStack(int _required) { - bigint size = m_stackEnd - m_SPP; - if (size < _required) - BOOST_THROW_EXCEPTION(StackUnderflow() << RequirementError((bigint)_required, size)); + if (m_stackEnd - m_SPP < _required) + throw EVMC_STACK_UNDERFLOW; else - BOOST_THROW_EXCEPTION(OutOfStack() << RequirementError((bigint)_change, size)); + throw EVMC_STACK_OVERFLOW; } void VM::throwRevertInstruction(owning_bytes_ref&& _output) @@ -69,11 +68,9 @@ void VM::throwRevertInstruction(owning_bytes_ref&& _output) throw RevertInstruction(std::move(_output)); } -void VM::throwBufferOverrun(intx::uint512 const& _endOfAccess) +void VM::throwBufferOverrun() { - BOOST_THROW_EXCEPTION( - BufferOverrun() << RequirementError( - bigint(std::string("0x") + intx::hex(_endOfAccess)), bigint(m_returnData.size()))); + throw EVMC_INVALID_MEMORY_ACCESS; } int64_t VM::verifyJumpDest(intx::uint256 const& _dest, bool _throw)