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

45
libevmjit/CMakeLists.txt

@ -1,26 +1,27 @@
set(TARGET_NAME evmjit) set(TARGET_NAME evmjit)
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})
@ -62,7 +63,7 @@ endif()
if(${EVMJIT_VERSION_MAJOR} EQUAL 0) if(${EVMJIT_VERSION_MAJOR} EQUAL 0)
set(EVMJIT_SOVERSION "0.${EVMJIT_VERSION_MINOR}") set(EVMJIT_SOVERSION "0.${EVMJIT_VERSION_MINOR}")
else() else()
set(EVMJIT_SOVERSION ${EVMJIT_VERSION_MAJOR}) set(EVMJIT_SOVERSION ${EVMJIT_VERSION_MAJOR})
endif() 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})") 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) 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} VERSION ${EVMJIT_VERSION} SOVERSION ${EVMJIT_SOVERSION}
FOLDER "libs") 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; 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

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