From 1b449d357e36c73bcde5394282c343a92ef5024c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 29 Jan 2015 16:20:22 +0100 Subject: [PATCH] Fallback to interpreter VM in case of JIT requirements unmet --- libevmjit-cpp/JitVM.cpp | 28 ++++++++++++++++------------ libevmjit-cpp/JitVM.h | 4 +--- libevmjit/Common.h | 24 ++++++++++++++---------- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/libevmjit-cpp/JitVM.cpp b/libevmjit-cpp/JitVM.cpp index 613b5031c..e3bb09099 100644 --- a/libevmjit-cpp/JitVM.cpp +++ b/libevmjit-cpp/JitVM.cpp @@ -1,6 +1,7 @@ #include "JitVM.h" #include +#include #include #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::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::max()) - BOOST_THROW_EXCEPTION(OutOfGas()); - - if (_ext.currentBlock.number > std::numeric_limits::max()) - BOOST_THROW_EXCEPTION(OutOfGas()); - - if (_ext.currentBlock.timestamp > std::numeric_limits::max()) - BOOST_THROW_EXCEPTION(OutOfGas()); + auto rejected = false; + rejected |= m_gas > std::numeric_limits::max(); // Do not accept requests with gas > 2^63 (int64 max) + rejected |= _ext.gasPrice > std::numeric_limits::max(); + rejected |= _ext.currentBlock.number > std::numeric_limits::max(); + rejected |= _ext.currentBlock.timestamp > std::numeric_limits::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(m_gas); m_data.gasPrice = static_cast(_ext.gasPrice); diff --git a/libevmjit-cpp/JitVM.h b/libevmjit-cpp/JitVM.h index 90855127e..58caa3648 100644 --- a/libevmjit-cpp/JitVM.h +++ b/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 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 m_fallbackVM; ///< VM used in case of input data rejected by JIT }; diff --git a/libevmjit/Common.h b/libevmjit/Common.h index 7383b9f93..e485148fb 100644 --- a/libevmjit/Common.h +++ b/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