Browse Source

Subtree merge: ethereum/evmjit into ethereum/cpp-ethereum.

Merge commit '373dc98fb16bfcd99a2e3c4e21dfbf6fa8fe1729' into evmjit_cmake

Conflicts:
	evmjit/include/evmjit/JIT.h
	evmjit/libevmjit/CMakeLists.txt
	evmjit/libevmjit/JIT.cpp
	evmjit/libevmjit/RuntimeManager.cpp
	evmjit/libevmjit/interface.cpp
cl-refactor
Paweł Bylica 10 years ago
parent
commit
622c8be1e7
  1. 9
      evmjit/README.md
  2. 66
      evmjit/include/evmjit/JIT-c.h
  3. 2
      evmjit/include/evmjit/JIT.h
  4. 3
      evmjit/libevmjit/CMakeLists.txt
  5. 48
      evmjit/libevmjit/JIT-c.cpp
  6. 2
      evmjit/libevmjit/JIT.cpp
  7. 2
      evmjit/libevmjit/RuntimeManager.cpp
  8. 34
      evmjit/libevmjit/interface.cpp
  9. 13
      evmjit/libevmjit/interface.h

9
evmjit/README.md

@ -33,11 +33,4 @@ Ask me.
## Options ## Options
Options to evmjit library can be passed by environmental variables, e.g. `EVMJIT_CACHE=0 testeth --jit`. Options to evmjit library can be passed by environmental variable, e.g. `EVMJIT="-help" testeth --jit`.
Option | Default value | Description
------------- | ------------- | ----------------------------------------------
EVMJIT_CACHE | 1 | Enables on disk cache for compiled EVM objects
EVMJIT_DUMP | 0 | Dumps generated LLVM module to standard output

66
evmjit/include/evmjit/JIT-c.h

@ -0,0 +1,66 @@
#include "stdint.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct evmjit_i256
{
uint64_t words[4];
} evmjit_i256;
typedef struct evmjit_runtime_data
{
int64_t gas;
int64_t gasPrice;
char const* callData;
uint64_t callDataSize;
evmjit_i256 address;
evmjit_i256 caller;
evmjit_i256 origin;
evmjit_i256 callValue;
evmjit_i256 coinBase;
evmjit_i256 difficulty;
evmjit_i256 gasLimit;
uint64_t number;
int64_t timestamp;
char const* code;
uint64_t codeSize;
evmjit_i256 codeHash;
} evmjit_runtime_data;
typedef enum evmjit_return_code
{
// Success codes
Stop = 0,
Return = 1,
Suicide = 2,
// Standard error codes
OutOfGas = -1,
StackUnderflow = -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
// Internal error codes
LLVMError = -101,
UnexpectedException = -111
} evmjit_return_code;
typedef struct evmjit_context evmjit_context;
evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env);
evmjit_return_code evmjit_exec(evmjit_context* _context);
void evmjit_destroy(evmjit_context* _context);
inline char const* evmjit_get_output(evmjit_runtime_data* _data) { return _data->callData; }
inline uint64_t evmjit_get_output_size(evmjit_runtime_data* _data) { return _data->callDataSize; }
#ifdef __cplusplus
}
#endif

2
evmjit/include/evmjit/JIT.h

@ -121,7 +121,7 @@ public:
ExecutionContext(RuntimeData& _data, Env* _env) { init(_data, _env); } ExecutionContext(RuntimeData& _data, Env* _env) { init(_data, _env); }
ExecutionContext(ExecutionContext const&) = delete; ExecutionContext(ExecutionContext const&) = delete;
ExecutionContext& operator=(ExecutionContext const&) = delete; ExecutionContext& operator=(ExecutionContext const&) = delete;
EXPORT ~ExecutionContext(); EXPORT ~ExecutionContext() noexcept;
void init(RuntimeData& _data, Env* _env) { m_data = &_data; m_env = _env; } void init(RuntimeData& _data, Env* _env) { m_data = &_data; m_env = _env; }

3
evmjit/libevmjit/CMakeLists.txt

@ -4,6 +4,7 @@ get_filename_component(EVMJIT_INCLUDE_DIR ../include ABSOLUTE)
set(SOURCES set(SOURCES
JIT.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT.h JIT.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT.h
JIT-c.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT-c.h
Arith256.cpp Arith256.h Arith256.cpp Arith256.h
Array.cpp Array.h Array.cpp Array.h
BasicBlock.cpp BasicBlock.h BasicBlock.cpp BasicBlock.h
@ -16,7 +17,7 @@ set(SOURCES
Ext.cpp Ext.h Ext.cpp Ext.h
GasMeter.cpp GasMeter.h GasMeter.cpp GasMeter.h
Instruction.cpp Instruction.h Instruction.cpp Instruction.h
interface.cpp interface.h #interface.cpp interface.h
Memory.cpp Memory.h Memory.cpp Memory.h
Optimizer.cpp Optimizer.h Optimizer.cpp Optimizer.h
RuntimeManager.cpp RuntimeManager.h RuntimeManager.cpp RuntimeManager.h

48
evmjit/libevmjit/JIT-c.cpp

@ -0,0 +1,48 @@
#include <evmjit/JIT-c.h>
#include <cassert>
#include <evmjit/JIT.h>
extern "C"
{
using namespace dev::evmjit;
EXPORT evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env)
{
auto data = reinterpret_cast<RuntimeData*>(_data);
auto env = reinterpret_cast<Env*>(_env);
assert(!data && "Pointer to runtime data must not be null");
if (!data)
return nullptr;
// TODO: Make sure ExecutionEngine constructor does not throw + make JIT/ExecutionEngine interface all nothrow
auto context = new(std::nothrow) ExecutionContext{*data, env};
return reinterpret_cast<evmjit_context*>(context);
}
EXPORT void evmjit_destroy(evmjit_context* _context)
{
auto context = reinterpret_cast<ExecutionContext*>(_context);
delete context;
}
EXPORT evmjit_return_code evmjit_exec(evmjit_context* _context)
{
auto context = reinterpret_cast<ExecutionContext*>(_context);
assert(!context && "Invalid context");
if (!context)
return UnexpectedException;
try
{
auto returnCode = JIT::exec(*context);
return static_cast<evmjit_return_code>(returnCode);
}
catch(...)
{
return UnexpectedException;
}
}
}

2
evmjit/libevmjit/JIT.cpp

@ -227,7 +227,7 @@ ReturnCode JIT::exec(ExecutionContext& _context)
extern "C" void ext_free(void* _data) noexcept; extern "C" void ext_free(void* _data) noexcept;
ExecutionContext::~ExecutionContext() ExecutionContext::~ExecutionContext() noexcept
{ {
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

2
evmjit/libevmjit/RuntimeManager.cpp

@ -77,7 +77,7 @@ llvm::Twine getName(RuntimeData::Index _index)
case RuntimeData::Difficulty: return "block.difficulty"; case RuntimeData::Difficulty: return "block.difficulty";
case RuntimeData::GasLimit: return "block.gaslimit"; case RuntimeData::GasLimit: return "block.gaslimit";
case RuntimeData::Number: return "block.number"; case RuntimeData::Number: return "block.number";
case RuntimeData::Timestamp: return "block.timestamp()"; case RuntimeData::Timestamp: return "block.timestamp";
case RuntimeData::Code: return "code.ptr"; case RuntimeData::Code: return "code.ptr";
case RuntimeData::CodeSize: return "code.size"; case RuntimeData::CodeSize: return "code.size";
} }

34
evmjit/libevmjit/interface.cpp

@ -1,34 +0,0 @@
#include "evmjit/JIT.h"
extern "C"
{
using namespace dev::evmjit;
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{*_data, _env};
}
EXPORT void evmjit_destroy(ExecutionContext* _context) noexcept
{
delete _context;
}
EXPORT int evmjit_run(ExecutionContext* _context) noexcept
{
try
{
auto returnCode = JIT::exec(*_context);
return static_cast<int>(returnCode);
}
catch(...)
{
return static_cast<int>(ReturnCode::UnexpectedException);
}
}
}

13
evmjit/libevmjit/interface.h

@ -1,13 +0,0 @@
#ifdef __cplusplus
extern "C" {
#endif
void* evmjit_create();
int evmjit_run(void* _jit, void* _data, void* _env);
void evmjit_destroy(void* _jit);
#ifdef __cplusplus
}
#endif
Loading…
Cancel
Save