Browse Source

Change JIT C interface. Create ExecutionEngine on heap to allow one-pass copy of return data.

cl-refactor
Paweł Bylica 10 years ago
parent
commit
1990dde405
  1. 1
      libevmjit/Runtime.cpp
  2. 2
      libevmjit/RuntimeData.h
  3. 42
      libevmjit/interface.cpp
  4. 13
      libevmjit/interface.h

1
libevmjit/Runtime.cpp

@ -26,6 +26,7 @@ bytes_ref Runtime::getReturnData() const
if (data < m_memory.data() || data >= m_memory.data() + m_memory.size() || size == 0)
{
assert(size == 0); // data can be an invalid pointer only if size is 0
m_data.callData = nullptr;
return {};
}

2
libevmjit/RuntimeData.h

@ -47,7 +47,7 @@ struct RuntimeData
i256 difficulty;
i256 gasLimit;
uint64_t number = 0;
uint64_t timestamp = 0;
int64_t timestamp = 0;
byte const* code = nullptr;
uint64_t codeSize = 0;
};

42
libevmjit/interface.cpp

@ -1,34 +1,36 @@
#include "interface.h"
#include <cstring>
#include "ExecutionEngine.h"
extern "C"
{
evmjit_result evmjit_run(void* _data, void* _env)
{
using namespace dev::eth::jit;
using namespace dev::eth::jit;
auto data = static_cast<RuntimeData*>(_data);
void* evmjit_create() noexcept
{
return new(std::nothrow) ExecutionEngine;
}
ExecutionEngine engine;
void evmjit_destroy(ExecutionEngine* _engine) noexcept
{
delete _engine;
}
auto codePtr = data->code;
auto codeSize = data->codeSize;
bytes bytecode;
bytecode.insert(bytecode.end(), codePtr, codePtr + codeSize);
int evmjit_run(ExecutionEngine* _engine, RuntimeData* _data, Env* _env) noexcept
{
try
{
auto codePtr = _data->code;
auto codeSize = _data->codeSize;
bytes bytecode;
bytecode.insert(bytecode.end(), codePtr, codePtr + codeSize);
auto returnCode = engine.run(bytecode, data, static_cast<Env*>(_env));
evmjit_result result = {static_cast<int32_t>(returnCode), 0, nullptr};
if (returnCode == ReturnCode::Return && std::get<0>(engine.returnData))
auto returnCode = _engine->run(bytecode, _data, _env);
return static_cast<int>(returnCode);
}
catch(...)
{
// TODO: Optimized returning data. Allocating memory on client side by callback function might be a good idea
result.returnDataSize = std::get<1>(engine.returnData);
result.returnData = std::malloc(result.returnDataSize);
std::memcpy(result.returnData, std::get<0>(engine.returnData), result.returnDataSize);
return static_cast<int>(ReturnCode::UnexpectedException);
}
return result;
}
}

13
libevmjit/interface.h

@ -1,19 +1,12 @@
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct evmjit_result
{
int32_t returnCode;
uint64_t returnDataSize;
void* returnData;
void* evmjit_create();
int evmjit_run(void* _jit, void* _data, void* _env);
void evmjit_destroy(void* _jit);
} evmjit_result;
evmjit_result evmjit_run(void* _data, void* _env);
#ifdef __cplusplus
}

Loading…
Cancel
Save