From c56858f4989f8c953c45a8d28b4e698b6bf4e288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 15 May 2015 15:22:37 +0200 Subject: [PATCH] Merge ExecutionContext and Runtime classes --- libevmjit-cpp/JitVM.cpp | 4 +- libevmjit-cpp/JitVM.h | 1 + libevmjit/Array.cpp | 1 - libevmjit/CMakeLists.txt | 2 +- libevmjit/Common.h | 4 +- .../{Runtime.cpp => ExecutionContext.cpp} | 18 ++------ libevmjit/ExecutionContext.h | 41 +++++++++++++++++++ libevmjit/ExecutionEngine.cpp | 27 ++++++------ libevmjit/ExecutionEngine.h | 22 ++++------ libevmjit/Memory.cpp | 1 - libevmjit/Runtime.h | 30 -------------- libevmjit/Stack.cpp | 1 - libevmjit/interface.cpp | 15 +++---- 13 files changed, 80 insertions(+), 87 deletions(-) rename libevmjit/{Runtime.cpp => ExecutionContext.cpp} (70%) create mode 100644 libevmjit/ExecutionContext.h delete mode 100644 libevmjit/Runtime.h diff --git a/libevmjit-cpp/JitVM.cpp b/libevmjit-cpp/JitVM.cpp index 85109ebbc..e44628c67 100644 --- a/libevmjit-cpp/JitVM.cpp +++ b/libevmjit-cpp/JitVM.cpp @@ -54,8 +54,8 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _step) m_data.codeSize = _ext.code.size(); m_data.codeHash = eth2llvm(sha3(_ext.code)); - auto env = reinterpret_cast(&_ext); - auto exitCode = jit::ExecutionEngine::run(m_context, &m_data, env); + m_context.init(m_data, reinterpret_cast(&_ext)); + auto exitCode = jit::ExecutionEngine::run(m_context); switch (exitCode) { case ReturnCode::Suicide: diff --git a/libevmjit-cpp/JitVM.h b/libevmjit-cpp/JitVM.h index 4bd4a7bbf..aad379a75 100644 --- a/libevmjit-cpp/JitVM.h +++ b/libevmjit-cpp/JitVM.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include namespace dev diff --git a/libevmjit/Array.cpp b/libevmjit/Array.cpp index b3d3cc0bb..a76776c69 100644 --- a/libevmjit/Array.cpp +++ b/libevmjit/Array.cpp @@ -6,7 +6,6 @@ #include "preprocessor/llvm_includes_end.h" #include "RuntimeManager.h" -#include "Runtime.h" #include "Utils.h" #include // DEBUG only diff --git a/libevmjit/CMakeLists.txt b/libevmjit/CMakeLists.txt index 4b15d52ac..324ad6717 100644 --- a/libevmjit/CMakeLists.txt +++ b/libevmjit/CMakeLists.txt @@ -11,6 +11,7 @@ set(SOURCES ${EVMJIT_INCLUDE_DIR}/evmjit/DataTypes.h Endianness.cpp Endianness.h ExecStats.cpp ExecStats.h + ExecutionContext.cpp ExecutionContext.h ExecutionEngine.cpp ExecutionEngine.h Ext.cpp Ext.h GasMeter.cpp GasMeter.h @@ -19,7 +20,6 @@ set(SOURCES JIT.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT.h Memory.cpp Memory.h Optimizer.cpp Optimizer.h - Runtime.cpp Runtime.h RuntimeData.h RuntimeManager.cpp RuntimeManager.h Stack.cpp Stack.h diff --git a/libevmjit/Common.h b/libevmjit/Common.h index b519614fe..e99308174 100644 --- a/libevmjit/Common.h +++ b/libevmjit/Common.h @@ -4,8 +4,8 @@ #include #ifdef _MSC_VER -#define EXPORT __declspec(dllexport) -#define _ALLOW_KEYWORD_MACROS +#define EXPORT __declspec(dllexport) +#define _ALLOW_KEYWORD_MACROS #define noexcept throw() #else #define EXPORT diff --git a/libevmjit/Runtime.cpp b/libevmjit/ExecutionContext.cpp similarity index 70% rename from libevmjit/Runtime.cpp rename to libevmjit/ExecutionContext.cpp index 7e9a7d52e..fab6fad87 100644 --- a/libevmjit/Runtime.cpp +++ b/libevmjit/ExecutionContext.cpp @@ -1,29 +1,20 @@ -#include "Runtime.h" - +#include "ExecutionContext.h" #include namespace dev { -namespace eth -{ -namespace jit -{ - -void Runtime::init(RuntimeData* _data, Env* _env) +namespace evmjit { - m_data = _data; - m_env = _env; -} extern "C" void ext_free(void* _data) noexcept; -Runtime::~Runtime() +ExecutionContext::~ExecutionContext() { if (m_memData) ext_free(m_memData); // Use helper free to check memory leaks } -bytes_ref Runtime::getReturnData() const +bytes_ref ExecutionContext::getReturnData() const { auto data = m_data->callData; auto size = static_cast(m_data->callDataSize); @@ -40,4 +31,3 @@ bytes_ref Runtime::getReturnData() const } } -} diff --git a/libevmjit/ExecutionContext.h b/libevmjit/ExecutionContext.h new file mode 100644 index 000000000..6d40e2819 --- /dev/null +++ b/libevmjit/ExecutionContext.h @@ -0,0 +1,41 @@ +#pragma once + +#include "RuntimeData.h" + +namespace dev +{ +namespace evmjit +{ + using namespace eth::jit; // FIXME + +class ExecutionContext +{ +public: + ExecutionContext() = default; + ExecutionContext(RuntimeData& _data, Env* _env) { init(_data, _env); } + ExecutionContext(ExecutionContext const&) = delete; + ExecutionContext& operator=(ExecutionContext const&) = delete; + EXPORT ~ExecutionContext(); + + void init(RuntimeData& _data, Env* _env) { m_data = &_data; m_env = _env; } + + byte const* code() const { return m_data->code; } + uint64_t codeSize() const { return m_data->codeSize; } + h256 const& codeHash() const { return m_data->codeHash; } + + bytes_ref getReturnData() const; + +private: + RuntimeData* m_data = nullptr; ///< Pointer to data. Expected by compiled contract. + Env* m_env = nullptr; ///< Pointer to environment proxy. Expected by compiled contract. + byte* m_memData = nullptr; + uint64_t m_memSize = 0; + uint64_t m_memCap = 0; + +public: + /// Reference to returned data (RETURN opcode used) + bytes_ref returnData; +}; + +} +} diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 741a7d764..a96ac700c 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -19,8 +19,8 @@ #include #include "preprocessor/llvm_includes_end.h" +#include "ExecutionContext.h" #include "evmjit/JIT.h" -#include "Runtime.h" #include "Compiler.h" #include "Optimizer.h" #include "Cache.h" @@ -38,9 +38,9 @@ using evmjit::JIT; namespace { -using EntryFuncPtr = ReturnCode(*)(Runtime*); +using EntryFuncPtr = ReturnCode(*)(ExecutionContext*); -std::string codeHash(i256 const& _hash) +std::string hash2str(i256 const& _hash) { static const auto size = sizeof(_hash); static const auto hexChars = "0123456789abcdef"; @@ -142,30 +142,31 @@ ExecutionEngine::ExecutionEngine() } -ReturnCode ExecutionEngine::run(ExecutionContext& _context, RuntimeData* _data, Env* _env) +ReturnCode ExecutionEngine::run(ExecutionContext& _context) { ExecutionEngine::get(); // FIXME std::unique_ptr listener{new ExecStats}; listener->stateChanged(ExecState::Started); - + auto code = _context.code(); + auto codeSize = _context.codeSize(); + auto codeHash = _context.codeHash(); static StatsCollector statsCollector; - auto mainFuncName = codeHash(_data->codeHash); - _context.m_runtime.init(_data, _env); + auto mainFuncName = hash2str(codeHash); // TODO: Remove cast - auto entryFuncPtr = (EntryFuncPtr) JIT::getCode(_data->codeHash); + auto entryFuncPtr = (EntryFuncPtr) JIT::getCode(codeHash); if (!entryFuncPtr) { auto module = Cache::getObject(mainFuncName); if (!module) { listener->stateChanged(ExecState::Compilation); - assert(_data->code || !_data->codeSize); //TODO: Is it good idea to execute empty code? - module = Compiler{{}}.compile(_data->code, _data->code + _data->codeSize, mainFuncName); + assert(code || !codeSize); //TODO: Is it good idea to execute empty code? + module = Compiler{{}}.compile(code, code + codeSize, mainFuncName); if (g_optimize) { @@ -183,15 +184,15 @@ ReturnCode ExecutionEngine::run(ExecutionContext& _context, RuntimeData* _data, entryFuncPtr = (EntryFuncPtr)g_ee->getFunctionAddress(mainFuncName); if (!CHECK(entryFuncPtr)) return ReturnCode::LLVMLinkError; - JIT::mapCode(_data->codeHash, (void*)entryFuncPtr); // FIXME: Remove cast + JIT::mapCode(codeHash, (void*)entryFuncPtr); // FIXME: Remove cast } listener->stateChanged(ExecState::Execution); - auto returnCode = entryFuncPtr(&_context.m_runtime); + auto returnCode = entryFuncPtr(&_context); listener->stateChanged(ExecState::Return); if (returnCode == ReturnCode::Return) - _context.returnData = _context.m_runtime.getReturnData(); // Save reference to return data + _context.returnData = _context.getReturnData(); // Save reference to return data listener->stateChanged(ExecState::Finished); diff --git a/libevmjit/ExecutionEngine.h b/libevmjit/ExecutionEngine.h index c380b6cb5..5c689403c 100644 --- a/libevmjit/ExecutionEngine.h +++ b/libevmjit/ExecutionEngine.h @@ -1,15 +1,20 @@ #pragma once #include +#include "Common.h" -#include "Runtime.h" namespace dev { +namespace evmjit +{ + class ExecutionContext; +} namespace eth { namespace jit { + using namespace evmjit; // FIXME enum class ExecState { @@ -38,26 +43,13 @@ public: virtual void stateChanged(ExecState) {} }; -class ExecutionContext -{ -public: - ExecutionContext() = default; - ExecutionContext(ExecutionContext const&) = delete; - ExecutionContext& operator=(ExecutionContext const&) = delete; - - /// Reference to returned data (RETURN opcode used) - bytes_ref returnData; - - Runtime m_runtime; -}; - class ExecutionEngine { public: ExecutionEngine(ExecutionEngine const&) = delete; ExecutionEngine& operator=(ExecutionEngine const&) = delete; - EXPORT static ReturnCode run(ExecutionContext& _context, RuntimeData* _data, Env* _env); + EXPORT static ReturnCode run(ExecutionContext& _context); private: ExecutionEngine(); diff --git a/libevmjit/Memory.cpp b/libevmjit/Memory.cpp index 6d5b72024..fdf5a6b98 100644 --- a/libevmjit/Memory.cpp +++ b/libevmjit/Memory.cpp @@ -5,7 +5,6 @@ #include "preprocessor/llvm_includes_end.h" #include "Type.h" -#include "Runtime.h" #include "GasMeter.h" #include "Endianness.h" #include "RuntimeManager.h" diff --git a/libevmjit/Runtime.h b/libevmjit/Runtime.h deleted file mode 100644 index 895128a59..000000000 --- a/libevmjit/Runtime.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "RuntimeData.h" - -namespace dev -{ -namespace eth -{ -namespace jit -{ - -class Runtime -{ -public: - void init(RuntimeData* _data, Env* _env); - EXPORT ~Runtime(); - - bytes_ref getReturnData() const; - -private: - RuntimeData* m_data = nullptr; ///< Pointer to data. Expected by compiled contract. - Env* m_env = nullptr; ///< Pointer to environment proxy. Expected by compiled contract. - byte* m_memData = nullptr; - uint64_t m_memSize = 0; - uint64_t m_memCap = 0; -}; - -} -} -} diff --git a/libevmjit/Stack.cpp b/libevmjit/Stack.cpp index b47567f17..b7b8f25b1 100644 --- a/libevmjit/Stack.cpp +++ b/libevmjit/Stack.cpp @@ -5,7 +5,6 @@ #include "preprocessor/llvm_includes_end.h" #include "RuntimeManager.h" -#include "Runtime.h" #include "Utils.h" #include // DEBUG only diff --git a/libevmjit/interface.cpp b/libevmjit/interface.cpp index bc9d98474..18b36cd7f 100644 --- a/libevmjit/interface.cpp +++ b/libevmjit/interface.cpp @@ -1,14 +1,18 @@ #include "ExecutionEngine.h" +#include "ExecutionContext.h" extern "C" { using namespace dev::eth::jit; -EXPORT void* evmjit_create() noexcept +EXPORT void* evmjit_create(RuntimeData* _data, Env* _env) noexcept { + if (!_data) + return nullptr; + // TODO: Make sure ExecutionEngine constructor does not throw + make JIT/ExecutionEngine interface all nothrow - return new(std::nothrow) ExecutionContext; + return new(std::nothrow) ExecutionContext{*_data, _env}; } EXPORT void evmjit_destroy(ExecutionContext* _context) noexcept @@ -16,14 +20,11 @@ EXPORT void evmjit_destroy(ExecutionContext* _context) noexcept delete _context; } -EXPORT int evmjit_run(ExecutionContext* _context, RuntimeData* _data, Env* _env) noexcept +EXPORT int evmjit_run(ExecutionContext* _context) noexcept { - if (!_context || !_data) - return static_cast(ReturnCode::UnexpectedException); - try { - auto returnCode = ExecutionEngine::run(*_context, _data, _env); + auto returnCode = ExecutionEngine::run(*_context); return static_cast(returnCode); } catch(...)