Browse Source

Merge ExecutionContext and Runtime classes

cl-refactor
Paweł Bylica 10 years ago
parent
commit
c56858f498
  1. 4
      libevmjit-cpp/JitVM.cpp
  2. 1
      libevmjit-cpp/JitVM.h
  3. 1
      libevmjit/Array.cpp
  4. 2
      libevmjit/CMakeLists.txt
  5. 4
      libevmjit/Common.h
  6. 18
      libevmjit/ExecutionContext.cpp
  7. 41
      libevmjit/ExecutionContext.h
  8. 27
      libevmjit/ExecutionEngine.cpp
  9. 22
      libevmjit/ExecutionEngine.h
  10. 1
      libevmjit/Memory.cpp
  11. 30
      libevmjit/Runtime.h
  12. 1
      libevmjit/Stack.cpp
  13. 15
      libevmjit/interface.cpp

4
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.codeSize = _ext.code.size();
m_data.codeHash = eth2llvm(sha3(_ext.code)); m_data.codeHash = eth2llvm(sha3(_ext.code));
auto env = reinterpret_cast<Env*>(&_ext); m_context.init(m_data, reinterpret_cast<Env*>(&_ext));
auto exitCode = jit::ExecutionEngine::run(m_context, &m_data, env); auto exitCode = jit::ExecutionEngine::run(m_context);
switch (exitCode) switch (exitCode)
{ {
case ReturnCode::Suicide: case ReturnCode::Suicide:

1
libevmjit-cpp/JitVM.h

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <libevm/VMFace.h> #include <libevm/VMFace.h>
#include <evmjit/libevmjit/ExecutionContext.h>
#include <evmjit/libevmjit/ExecutionEngine.h> #include <evmjit/libevmjit/ExecutionEngine.h>
namespace dev namespace dev

1
libevmjit/Array.cpp

@ -6,7 +6,6 @@
#include "preprocessor/llvm_includes_end.h" #include "preprocessor/llvm_includes_end.h"
#include "RuntimeManager.h" #include "RuntimeManager.h"
#include "Runtime.h"
#include "Utils.h" #include "Utils.h"
#include <set> // DEBUG only #include <set> // DEBUG only

2
libevmjit/CMakeLists.txt

@ -11,6 +11,7 @@ set(SOURCES
${EVMJIT_INCLUDE_DIR}/evmjit/DataTypes.h ${EVMJIT_INCLUDE_DIR}/evmjit/DataTypes.h
Endianness.cpp Endianness.h Endianness.cpp Endianness.h
ExecStats.cpp ExecStats.h ExecStats.cpp ExecStats.h
ExecutionContext.cpp ExecutionContext.h
ExecutionEngine.cpp ExecutionEngine.h ExecutionEngine.cpp ExecutionEngine.h
Ext.cpp Ext.h Ext.cpp Ext.h
GasMeter.cpp GasMeter.h GasMeter.cpp GasMeter.h
@ -19,7 +20,6 @@ set(SOURCES
JIT.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT.h JIT.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT.h
Memory.cpp Memory.h Memory.cpp Memory.h
Optimizer.cpp Optimizer.h Optimizer.cpp Optimizer.h
Runtime.cpp Runtime.h
RuntimeData.h RuntimeData.h
RuntimeManager.cpp RuntimeManager.h RuntimeManager.cpp RuntimeManager.h
Stack.cpp Stack.h Stack.cpp Stack.h

4
libevmjit/Common.h

@ -4,8 +4,8 @@
#include <cstdint> #include <cstdint>
#ifdef _MSC_VER #ifdef _MSC_VER
#define EXPORT __declspec(dllexport) #define EXPORT __declspec(dllexport)
#define _ALLOW_KEYWORD_MACROS #define _ALLOW_KEYWORD_MACROS
#define noexcept throw() #define noexcept throw()
#else #else
#define EXPORT #define EXPORT

18
libevmjit/Runtime.cpp → libevmjit/ExecutionContext.cpp

@ -1,29 +1,20 @@
#include "Runtime.h" #include "ExecutionContext.h"
#include <cassert> #include <cassert>
namespace dev namespace dev
{ {
namespace eth namespace evmjit
{
namespace jit
{
void Runtime::init(RuntimeData* _data, Env* _env)
{ {
m_data = _data;
m_env = _env;
}
extern "C" void ext_free(void* _data) noexcept; extern "C" void ext_free(void* _data) noexcept;
Runtime::~Runtime() ExecutionContext::~ExecutionContext()
{ {
if (m_memData) if (m_memData)
ext_free(m_memData); // Use helper free to check memory leaks 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 data = m_data->callData;
auto size = static_cast<size_t>(m_data->callDataSize); auto size = static_cast<size_t>(m_data->callDataSize);
@ -40,4 +31,3 @@ bytes_ref Runtime::getReturnData() const
} }
} }
}

41
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;
};
}
}

27
libevmjit/ExecutionEngine.cpp

@ -19,8 +19,8 @@
#include <llvm/Support/ManagedStatic.h> #include <llvm/Support/ManagedStatic.h>
#include "preprocessor/llvm_includes_end.h" #include "preprocessor/llvm_includes_end.h"
#include "ExecutionContext.h"
#include "evmjit/JIT.h" #include "evmjit/JIT.h"
#include "Runtime.h"
#include "Compiler.h" #include "Compiler.h"
#include "Optimizer.h" #include "Optimizer.h"
#include "Cache.h" #include "Cache.h"
@ -38,9 +38,9 @@ using evmjit::JIT;
namespace 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 size = sizeof(_hash);
static const auto hexChars = "0123456789abcdef"; 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 ExecutionEngine::get(); // FIXME
std::unique_ptr<ExecStats> listener{new ExecStats}; std::unique_ptr<ExecStats> listener{new ExecStats};
listener->stateChanged(ExecState::Started); listener->stateChanged(ExecState::Started);
auto code = _context.code();
auto codeSize = _context.codeSize();
auto codeHash = _context.codeHash();
static StatsCollector statsCollector; static StatsCollector statsCollector;
auto mainFuncName = codeHash(_data->codeHash); auto mainFuncName = hash2str(codeHash);
_context.m_runtime.init(_data, _env);
// TODO: Remove cast // TODO: Remove cast
auto entryFuncPtr = (EntryFuncPtr) JIT::getCode(_data->codeHash); auto entryFuncPtr = (EntryFuncPtr) JIT::getCode(codeHash);
if (!entryFuncPtr) if (!entryFuncPtr)
{ {
auto module = Cache::getObject(mainFuncName); auto module = Cache::getObject(mainFuncName);
if (!module) if (!module)
{ {
listener->stateChanged(ExecState::Compilation); listener->stateChanged(ExecState::Compilation);
assert(_data->code || !_data->codeSize); //TODO: Is it good idea to execute empty code? assert(code || !codeSize); //TODO: Is it good idea to execute empty code?
module = Compiler{{}}.compile(_data->code, _data->code + _data->codeSize, mainFuncName); module = Compiler{{}}.compile(code, code + codeSize, mainFuncName);
if (g_optimize) if (g_optimize)
{ {
@ -183,15 +184,15 @@ ReturnCode ExecutionEngine::run(ExecutionContext& _context, RuntimeData* _data,
entryFuncPtr = (EntryFuncPtr)g_ee->getFunctionAddress(mainFuncName); entryFuncPtr = (EntryFuncPtr)g_ee->getFunctionAddress(mainFuncName);
if (!CHECK(entryFuncPtr)) if (!CHECK(entryFuncPtr))
return ReturnCode::LLVMLinkError; return ReturnCode::LLVMLinkError;
JIT::mapCode(_data->codeHash, (void*)entryFuncPtr); // FIXME: Remove cast JIT::mapCode(codeHash, (void*)entryFuncPtr); // FIXME: Remove cast
} }
listener->stateChanged(ExecState::Execution); listener->stateChanged(ExecState::Execution);
auto returnCode = entryFuncPtr(&_context.m_runtime); auto returnCode = entryFuncPtr(&_context);
listener->stateChanged(ExecState::Return); listener->stateChanged(ExecState::Return);
if (returnCode == ReturnCode::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); listener->stateChanged(ExecState::Finished);

22
libevmjit/ExecutionEngine.h

@ -1,15 +1,20 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include "Common.h"
#include "Runtime.h"
namespace dev namespace dev
{ {
namespace evmjit
{
class ExecutionContext;
}
namespace eth namespace eth
{ {
namespace jit namespace jit
{ {
using namespace evmjit; // FIXME
enum class ExecState enum class ExecState
{ {
@ -38,26 +43,13 @@ public:
virtual void stateChanged(ExecState) {} 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 class ExecutionEngine
{ {
public: public:
ExecutionEngine(ExecutionEngine const&) = delete; ExecutionEngine(ExecutionEngine const&) = delete;
ExecutionEngine& operator=(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: private:
ExecutionEngine(); ExecutionEngine();

1
libevmjit/Memory.cpp

@ -5,7 +5,6 @@
#include "preprocessor/llvm_includes_end.h" #include "preprocessor/llvm_includes_end.h"
#include "Type.h" #include "Type.h"
#include "Runtime.h"
#include "GasMeter.h" #include "GasMeter.h"
#include "Endianness.h" #include "Endianness.h"
#include "RuntimeManager.h" #include "RuntimeManager.h"

30
libevmjit/Runtime.h

@ -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;
};
}
}
}

1
libevmjit/Stack.cpp

@ -5,7 +5,6 @@
#include "preprocessor/llvm_includes_end.h" #include "preprocessor/llvm_includes_end.h"
#include "RuntimeManager.h" #include "RuntimeManager.h"
#include "Runtime.h"
#include "Utils.h" #include "Utils.h"
#include <set> // DEBUG only #include <set> // DEBUG only

15
libevmjit/interface.cpp

@ -1,14 +1,18 @@
#include "ExecutionEngine.h" #include "ExecutionEngine.h"
#include "ExecutionContext.h"
extern "C" extern "C"
{ {
using namespace dev::eth::jit; 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 // 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 EXPORT void evmjit_destroy(ExecutionContext* _context) noexcept
@ -16,14 +20,11 @@ EXPORT void evmjit_destroy(ExecutionContext* _context) noexcept
delete _context; 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<int>(ReturnCode::UnexpectedException);
try try
{ {
auto returnCode = ExecutionEngine::run(*_context, _data, _env); auto returnCode = ExecutionEngine::run(*_context);
return static_cast<int>(returnCode); return static_cast<int>(returnCode);
} }
catch(...) catch(...)

Loading…
Cancel
Save