Browse Source

New C interface in JIT-c.h header matching the C++ interface in JIT.h.

cl-refactor
Paweł Bylica 10 years ago
parent
commit
a0ce7f83dc
  1. 66
      include/evmjit/JIT-c.h
  2. 2
      include/evmjit/JIT.h
  3. 45
      libevmjit/CMakeLists.txt
  4. 48
      libevmjit/JIT-c.cpp
  5. 2
      libevmjit/JIT.cpp
  6. 34
      libevmjit/interface.cpp
  7. 13
      libevmjit/interface.h

66
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
include/evmjit/JIT.h

@ -121,7 +121,7 @@ public:
ExecutionContext(RuntimeData& _data, Env* _env) { init(_data, _env); }
ExecutionContext(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; }

45
libevmjit/CMakeLists.txt

@ -1,26 +1,27 @@
set(TARGET_NAME evmjit)
set(SOURCES
JIT.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT.h
Arith256.cpp Arith256.h
Array.cpp Array.h
BasicBlock.cpp BasicBlock.h
Cache.cpp Cache.h
Common.h
Compiler.cpp Compiler.h
CompilerHelper.cpp CompilerHelper.h
Endianness.cpp Endianness.h
ExecStats.cpp ExecStats.h
Ext.cpp Ext.h
GasMeter.cpp GasMeter.h
Instruction.cpp Instruction.h
interface.cpp interface.h
Memory.cpp Memory.h
Optimizer.cpp Optimizer.h
RuntimeManager.cpp RuntimeManager.h
Stack.cpp Stack.h
Type.cpp Type.h
Utils.cpp Utils.h
JIT.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT.h
JIT-c.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT-c.h
Arith256.cpp Arith256.h
Array.cpp Array.h
BasicBlock.cpp BasicBlock.h
Cache.cpp Cache.h
Common.h
Compiler.cpp Compiler.h
CompilerHelper.cpp CompilerHelper.h
Endianness.cpp Endianness.h
ExecStats.cpp ExecStats.h
Ext.cpp Ext.h
GasMeter.cpp GasMeter.h
Instruction.cpp Instruction.h
#interface.cpp interface.h
Memory.cpp Memory.h
Optimizer.cpp Optimizer.h
RuntimeManager.cpp RuntimeManager.h
Stack.cpp Stack.h
Type.cpp Type.h
Utils.cpp Utils.h
)
source_group("" FILES ${SOURCES})
@ -62,7 +63,7 @@ endif()
if(${EVMJIT_VERSION_MAJOR} EQUAL 0)
set(EVMJIT_SOVERSION "0.${EVMJIT_VERSION_MINOR}")
else()
else()
set(EVMJIT_SOVERSION ${EVMJIT_VERSION_MAJOR})
endif()
@ -73,7 +74,7 @@ configure_file(BuildInfo.h.in ${CMAKE_CURRENT_BINARY_DIR}/gen/BuildInfo.gen.h)
message(STATUS "EVM JIT version: ${EVMJIT_VERSION_MAJOR}.${EVMJIT_VERSION_MINOR}.${EVMJIT_VERSION_PATCH} ${EVMJIT_VERSION_PRERELEASE} (${EVMJIT_VERSION_FULL})")
add_library(${TARGET_NAME} SHARED ${SOURCES} gen/BuildInfo.gen.h)
set_target_properties(${TARGET_NAME} PROPERTIES
set_target_properties(${TARGET_NAME} PROPERTIES
VERSION ${EVMJIT_VERSION} SOVERSION ${EVMJIT_SOVERSION}
FOLDER "libs")

48
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
libevmjit/JIT.cpp

@ -227,7 +227,7 @@ ReturnCode JIT::exec(ExecutionContext& _context)
extern "C" void ext_free(void* _data) noexcept;
ExecutionContext::~ExecutionContext()
ExecutionContext::~ExecutionContext() noexcept
{
if (m_memData)
ext_free(m_memData); // Use helper free to check memory leaks

34
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
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