Paweł Bylica
10 years ago
7 changed files with 139 additions and 71 deletions
@ -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 |
@ -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; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -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); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
} |
|
@ -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…
Reference in new issue