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

41
evmjit/libevmjit/CMakeLists.txt

@ -3,26 +3,27 @@ set(TARGET_NAME evmjit)
get_filename_component(EVMJIT_INCLUDE_DIR ../include ABSOLUTE) 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
Arith256.cpp Arith256.h JIT-c.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT-c.h
Array.cpp Array.h Arith256.cpp Arith256.h
BasicBlock.cpp BasicBlock.h Array.cpp Array.h
Cache.cpp Cache.h BasicBlock.cpp BasicBlock.h
Common.h Cache.cpp Cache.h
Compiler.cpp Compiler.h Common.h
CompilerHelper.cpp CompilerHelper.h Compiler.cpp Compiler.h
Endianness.cpp Endianness.h CompilerHelper.cpp CompilerHelper.h
ExecStats.cpp ExecStats.h Endianness.cpp Endianness.h
Ext.cpp Ext.h ExecStats.cpp ExecStats.h
GasMeter.cpp GasMeter.h Ext.cpp Ext.h
Instruction.cpp Instruction.h GasMeter.cpp GasMeter.h
interface.cpp interface.h Instruction.cpp Instruction.h
Memory.cpp Memory.h #interface.cpp interface.h
Optimizer.cpp Optimizer.h Memory.cpp Memory.h
RuntimeManager.cpp RuntimeManager.h Optimizer.cpp Optimizer.h
Stack.cpp Stack.h RuntimeManager.cpp RuntimeManager.h
Type.cpp Type.h Stack.cpp Stack.h
Utils.cpp Utils.h Type.cpp Type.h
Utils.cpp Utils.h
) )
source_group("" FILES ${SOURCES}) source_group("" FILES ${SOURCES})

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