From 1861843a24d1a4aa62e20a3cfdab383131a4ebfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 14 Jan 2015 09:08:17 +0100 Subject: [PATCH] EVM JIT called from Go, env_sha3 callback works --- libevmjit/CMakeLists.txt | 3 +- libevmjit/ExecutionEngine.cpp | 2 +- libevmjit/interface.cpp | 63 ++++++++++++++++++++++++++ libevmjit/{interface.c => interface.h} | 17 ++++++- 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 libevmjit/interface.cpp rename libevmjit/{interface.c => interface.h} (87%) diff --git a/libevmjit/CMakeLists.txt b/libevmjit/CMakeLists.txt index 7c35169a7..28b501ee3 100644 --- a/libevmjit/CMakeLists.txt +++ b/libevmjit/CMakeLists.txt @@ -10,7 +10,8 @@ if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set_source_files_properties(Cache.cpp PROPERTIES COMPILE_FLAGS -fno-rtti) endif () -add_library(${TARGET_NAME} ${SOURCES} ${HEADERS}) +link_directories(/usr/lib/llvm-3.5/lib) +add_library(${TARGET_NAME} SHARED ${SOURCES} ${HEADERS}) set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "libs") include_directories(${LLVM_INCLUDE_DIRS}) diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 7e99932c3..71142fbee 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -49,7 +49,7 @@ ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime) std::string codeHash(bytes const& _code) { - std::array binHash; + std::array binHash; env_sha3(_code.data(), _code.size(), &binHash); std::ostringstream os; diff --git a/libevmjit/interface.cpp b/libevmjit/interface.cpp new file mode 100644 index 000000000..ec7d07b33 --- /dev/null +++ b/libevmjit/interface.cpp @@ -0,0 +1,63 @@ +#include "interface.h" +#include +#include "ExecutionEngine.h" + +extern "C" +{ + +int evmjit_run() +{ + using namespace dev::eth::jit; + + ExecutionEngine engine; + u256 gas = 100000; + + bytes bytecode = { 0x60, 0x01 }; + + // Create random runtime data + RuntimeData data; + data.set(RuntimeData::Gas, gas); + data.set(RuntimeData::Address, 0); + data.set(RuntimeData::Caller, 0); + data.set(RuntimeData::Origin, 0); + data.set(RuntimeData::CallValue, 0xabcd); + data.set(RuntimeData::CallDataSize, 3); + data.set(RuntimeData::GasPrice, 1003); + data.set(RuntimeData::CoinBase, 0); + data.set(RuntimeData::TimeStamp, 1005); + data.set(RuntimeData::Number, 1006); + data.set(RuntimeData::Difficulty, 16); + data.set(RuntimeData::GasLimit, 1008); + data.set(RuntimeData::CodeSize, bytecode.size()); + data.callData = (uint8_t*)"abc"; + data.code = bytecode.data(); + + // BROKEN: env_* functions must be implemented & RuntimeData struct created + // TODO: Do not compile module again + auto result = engine.run(bytecode, &data, nullptr); + return static_cast(result); +} + +// Runtime callback functions - implementations must be provided by external language (Go, C++, Python) +void evm_jit_rt_sload(evm_jit_rt* _rt, i256* _index, i256* _ret); +void evm_jit_rt_sstore(evm_jit_rt* _rt, i256* _index, i256* _value); +void evm_jit_rt_balance(evm_jit_rt* _rt, h256* _address, i256* _ret); +// And so on... + +evm_jit* evm_jit_create(evm_jit_rt*) +{ + printf("EVM JIT create"); + + int* a = nullptr; + *a = 1; + + return nullptr; +} + +evm_jit_return_code evm_jit_execute(evm_jit* _jit); + +void evm_jit_get_return_data(evm_jit* _jit, char* _return_data_offset, size_t* _return_data_size); + +void evm_jit_destroy(evm_jit* _jit); + +} diff --git a/libevmjit/interface.c b/libevmjit/interface.h similarity index 87% rename from libevmjit/interface.c rename to libevmjit/interface.h index 47589578b..0e3076283 100644 --- a/libevmjit/interface.c +++ b/libevmjit/interface.h @@ -1,4 +1,10 @@ -#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int evmjit_run(); // JIT object opaque type typedef struct evm_jit evm_jit; @@ -9,6 +15,11 @@ typedef int evm_jit_return_code; // Host-endian 256-bit integer type typedef struct i256 i256; +struct h256 +{ + char b[33]; +}; + // Big-endian right aligned 256-bit hash typedef struct h256 h256; @@ -28,3 +39,7 @@ evm_jit_return_code evm_jit_execute(evm_jit* _jit); void evm_jit_get_return_data(evm_jit* _jit, char* _return_data_offset, size_t* _return_data_size); void evm_jit_destroy(evm_jit* _jit); + +#ifdef __cplusplus +} +#endif