Browse Source

Merge ExecutionContext and Runtime classes

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

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

1
evmjit/libevmjit-cpp/JitVM.h

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

1
evmjit/libevmjit/Array.cpp

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

2
evmjit/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

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

@ -1,29 +1,20 @@
#include "Runtime.h"
#include "ExecutionContext.h"
#include <cassert>
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<size_t>(m_data->callDataSize);
@ -40,4 +31,3 @@ bytes_ref Runtime::getReturnData() const
}
}
}

41
evmjit/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
evmjit/libevmjit/ExecutionEngine.cpp

@ -19,8 +19,8 @@
#include <llvm/Support/ManagedStatic.h>
#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<ExecStats> 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);

22
evmjit/libevmjit/ExecutionEngine.h

@ -1,15 +1,20 @@
#pragma once
#include <memory>
#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();

1
evmjit/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"

30
evmjit/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
evmjit/libevmjit/Stack.cpp

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

15
evmjit/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<int>(ReturnCode::UnexpectedException);
try
{
auto returnCode = ExecutionEngine::run(*_context, _data, _env);
auto returnCode = ExecutionEngine::run(*_context);
return static_cast<int>(returnCode);
}
catch(...)

Loading…
Cancel
Save