Browse Source

Fallback to interpreter VM in case of JIT requirements unmet

cl-refactor
Paweł Bylica 10 years ago
parent
commit
1b449d357e
  1. 28
      libevmjit-cpp/JitVM.cpp
  2. 4
      libevmjit-cpp/JitVM.h
  3. 24
      libevmjit/Common.h

28
libevmjit-cpp/JitVM.cpp

@ -1,6 +1,7 @@
#include "JitVM.h"
#include <libevm/VM.h>
#include <libevm/VMFactory.h>
#include <evmjit/libevmjit/ExecutionEngine.h>
#include "Utils.h"
@ -9,22 +10,25 @@ namespace dev
namespace eth
{
bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t)
bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _step)
{
using namespace jit;
if (m_gas > std::numeric_limits<decltype(m_data.gas)>::max())
BOOST_THROW_EXCEPTION(OutOfGas()); // Do not accept requests with gas > 2^63 (int64 max) // TODO: Return "not accepted" exception to allow interpreted handle that
if (_ext.gasPrice > std::numeric_limits<decltype(m_data.gasPrice)>::max())
BOOST_THROW_EXCEPTION(OutOfGas());
if (_ext.currentBlock.number > std::numeric_limits<decltype(m_data.number)>::max())
BOOST_THROW_EXCEPTION(OutOfGas());
if (_ext.currentBlock.timestamp > std::numeric_limits<decltype(m_data.timestamp)>::max())
BOOST_THROW_EXCEPTION(OutOfGas());
auto rejected = false;
rejected |= m_gas > std::numeric_limits<decltype(m_data.gas)>::max(); // Do not accept requests with gas > 2^63 (int64 max)
rejected |= _ext.gasPrice > std::numeric_limits<decltype(m_data.gasPrice)>::max();
rejected |= _ext.currentBlock.number > std::numeric_limits<decltype(m_data.number)>::max();
rejected |= _ext.currentBlock.timestamp > std::numeric_limits<decltype(m_data.timestamp)>::max();
if (rejected)
{
UNTESTED;
std::cerr << "Rejected\n";
VMFactory::setKind(VMKind::Interpreter);
m_fallbackVM = VMFactory::create(m_gas);
VMFactory::setKind(VMKind::JIT);
return m_fallbackVM->go(_ext, _onOp, _step);
}
m_data.gas = static_cast<decltype(m_data.gas)>(m_gas);
m_data.gasPrice = static_cast<decltype(m_data.gasPrice)>(_ext.gasPrice);

4
libevmjit-cpp/JitVM.h

@ -12,15 +12,13 @@ class JitVM: public VMFace
{
virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final;
enum Kind: bool { Interpreter, JIT };
static std::unique_ptr<VMFace> create(Kind, u256 _gas = 0);
private:
friend class VMFactory;
explicit JitVM(u256 _gas = 0) : VMFace(_gas) {}
jit::RuntimeData m_data;
jit::ExecutionEngine m_engine;
std::unique_ptr<VMFace> m_fallbackVM; ///< VM used in case of input data rejected by JIT
};

24
libevmjit/Common.h

@ -25,20 +25,24 @@ struct NoteChannel {}; // FIXME: Use some log library?
enum class ReturnCode
{
Stop = 0,
Return = 1,
// Success codes
Stop = 0,
Return = 1,
Suicide = 2,
OutOfGas = -1,
BadJumpDestination = -2,
StackTooSmall = -3,
BadInstruction = -4,
// Standard error codes
OutOfGas = -1,
StackTooSmall = -2,
BadJumpDestination = -3,
BadInstruction = -4,
Rejected = -5, ///< Input data (code, gas, block info, etc.) does not meet JIT requirement and execution request has been rejected
LLVMConfigError = -5,
LLVMCompileError = -6,
LLVMLinkError = -7,
// Internal error codes
LLVMConfigError = -101,
LLVMCompileError = -102,
LLVMLinkError = -103,
UnexpectedException = -8,
UnexpectedException = -111,
};
/// Representation of 256-bit value binary compatible with LLVM i256

Loading…
Cancel
Save