Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

Commit

Permalink
interpreter: Simplify exception usage
Browse files Browse the repository at this point in the history
Instead of using complex exception types from Aleth, throw EVMC status code in simple cases.
  • Loading branch information
chfast committed Oct 30, 2019
1 parent 5c76154 commit fb584c0
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 57 deletions.
42 changes: 7 additions & 35 deletions libaleth-interpreter/VM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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]));
Expand Down
16 changes: 8 additions & 8 deletions libaleth-interpreter/VM.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint64_t> m_beginSubs;
std::vector<uint64_t> m_jumpDests;
Expand Down
25 changes: 11 additions & 14 deletions libaleth-interpreter/VMCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down

0 comments on commit fb584c0

Please sign in to comment.